Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add Goom to the libmythtv visualisations.

- currently OpenGL video only (VDPAU and Direct3D to follow).
- 2 versions will be listed in the OSD menu - both use the display
resolution for initial sizing but Goom will max out at 600x400 and Goom
HD at 1200x800.
  • Loading branch information...
commit ded61bd8dfede35ddfb3ec8621770b2e414932d2 1 parent 1bf85b6
Mark Kendall authored
Showing with 4,637 additions and 0 deletions.
  1. +12 −0 mythtv/libs/libmythtv/libmythtv.pro
  2. +178 −0 mythtv/libs/libmythtv/visualisations/goom/drawmethods.h
  3. +748 −0 mythtv/libs/libmythtv/visualisations/goom/filters.c
  4. +54 −0 mythtv/libs/libmythtv/visualisations/goom/filters.h
  5. +952 −0 mythtv/libs/libmythtv/visualisations/goom/goom_core.c
  6. +19 −0 mythtv/libs/libmythtv/visualisations/goom/goom_core.h
  7. +37 −0 mythtv/libs/libmythtv/visualisations/goom/goom_tools.h
  8. +39 −0 mythtv/libs/libmythtv/visualisations/goom/goomconfig.h
  9. +30 −0 mythtv/libs/libmythtv/visualisations/goom/graphic.c
  10. +24 −0 mythtv/libs/libmythtv/visualisations/goom/graphic.h
  11. +549 −0 mythtv/libs/libmythtv/visualisations/goom/ifs.c
  12. +33 −0 mythtv/libs/libmythtv/visualisations/goom/ifs.h
  13. +268 −0 mythtv/libs/libmythtv/visualisations/goom/ifs_display.c
  14. +247 −0 mythtv/libs/libmythtv/visualisations/goom/lines.c
  15. +69 −0 mythtv/libs/libmythtv/visualisations/goom/lines.h
  16. +26 −0 mythtv/libs/libmythtv/visualisations/goom/mathtools.h
  17. +15 −0 mythtv/libs/libmythtv/visualisations/goom/mmx.h
  18. +203 −0 mythtv/libs/libmythtv/visualisations/goom/mythgoom.cpp
  19. +34 −0 mythtv/libs/libmythtv/visualisations/goom/mythgoom.h
  20. +133 −0 mythtv/libs/libmythtv/visualisations/goom/surf3d.c
  21. +37 −0 mythtv/libs/libmythtv/visualisations/goom/surf3d.h
  22. +19 −0 mythtv/libs/libmythtv/visualisations/goom/surface.c
  23. +16 −0 mythtv/libs/libmythtv/visualisations/goom/surface.h
  24. +223 −0 mythtv/libs/libmythtv/visualisations/goom/tentacle3d.c
  25. +8 −0 mythtv/libs/libmythtv/visualisations/goom/tentacle3d.h
  26. +59 −0 mythtv/libs/libmythtv/visualisations/goom/v3d.h
  27. +158 −0 mythtv/libs/libmythtv/visualisations/goom/zoom_filter_mmx.c
  28. +267 −0 mythtv/libs/libmythtv/visualisations/goom/zoom_filter_xmmx.c
  29. +158 −0 mythtv/libs/libmythtv/visualisations/videovisualgoom.cpp
  30. +22 −0 mythtv/libs/libmythtv/visualisations/videovisualgoom.h
View
12 mythtv/libs/libmythtv/libmythtv.pro
@@ -350,6 +350,18 @@ using_frontend {
SOURCES += videocolourspace.cpp
SOURCES += videovisual.cpp
+ using_opengl {
+ # Goom
+ HEADERS += goom/filters.h goom/goomconfig.h goom/goom_core.h goom/graphic.h
+ HEADERS += goom/ifs.h goom/lines.h goom/drawmethods.h
+ HEADERS += goom/mmx.h goom/mathtools.h goom/tentacle3d.h goom/v3d.h
+ HEADERS += videovisualgoom.h
+ SOURCES += goom/filters.c goom/goom_core.c goom/graphic.c goom/tentacle3d.c
+ SOURCES += goom/ifs.c goom/ifs_display.c goom/lines.c goom/surf3d.c
+ SOURCES += goom/zoom_filter_mmx.c goom/zoom_filter_xmmx.c
+ SOURCES += videovisualgoom.cpp
+ }
+
using_libfftw3 {
DEFINES += FFTW3_SUPPORT
HEADERS += videovisualspectrum.h
View
178 mythtv/libs/libmythtv/visualisations/goom/drawmethods.h
@@ -0,0 +1,178 @@
+#ifndef _DRAWMETHODS_H
+#define _DRAWMETHODS_H
+
+#include "goomconfig.h"
+
+#define DRAWMETHOD_NORMAL(adr,col) {*(adr) = (col);}
+
+#ifdef MMX
+#include "mmx.h"
+
+#define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
+{\
+movd_m2r (_backbuf, mm0); \
+paddusb_m2r (_col, mm0); \
+movd_r2m (mm0, _out); \
+}
+
+#else
+#define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
+{\
+ int tra=0,i=0;\
+ unsigned char *bra = (unsigned char*)&(_backbuf);\
+ unsigned char *dra = (unsigned char*)&(_out);\
+ unsigned char *cra = (unsigned char*)&(_col);\
+ for (;i<4;i++) {\
+ tra = *cra;\
+ tra += *bra;\
+ if (tra>255) tra=255;\
+ *dra = tra;\
+ ++dra;++cra;++bra;\
+ }\
+}
+#endif
+
+#define DRAWMETHOD_OR(adr,col) {*(adr)|=(col);}
+
+#ifdef MMX
+#define DRAWMETHOD_DONE() {__asm__ __volatile__ ("emms");}
+#else
+#define DRAWMETHOD_DONE() {}
+#endif
+
+#ifndef DRAWMETHOD
+#define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
+
+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; // am, tmp;
+ int *p;
+
+
+ if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny) || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
+ return;
+
+ 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++;
+ }
+ 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;
+ }
+ 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--;
+ }
+ 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;
+ }
+ y += dy;
+ }
+ return;
+ }
+ }
+}
+#endif
+
+#endif
View
748 mythtv/libs/libmythtv/visualisations/goom/filters.c
@@ -0,0 +1,748 @@
+/* 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>
+#include <inttypes.h>
+
+#ifdef MMX
+#define USE_ASM
+#endif
+#ifdef POWERPC
+#define USE_ASM
+#endif
+
+#define EFFECT_DISTORS 4
+#define EFFECT_DISTORS_SL 2
+
+extern volatile guint32 resolx;
+extern volatile guint32 c_resoly;
+
+void c_zoom (unsigned int *expix1, unsigned int *expix2, unsigned int prevX, unsigned int prevY, signed int *brutS, signed int *brutD);
+
+#ifdef MMX
+
+void zoom_filter_xmmx (int prevX, int prevY, unsigned int *expix1, unsigned int *expix2, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+int zoom_filter_xmmx_supported ();
+void zoom_filter_mmx (int prevX, int prevY, unsigned int *expix1, unsigned int *expix2, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]);
+int zoom_filter_mmx_supported ();
+
+static int zf_use_xmmx = 0;
+static int zf_use_mmx = 0;
+
+static void select_zoom_filter () {
+ static int firsttime = 1;
+ if (firsttime){
+ if (zoom_filter_xmmx_supported()) {
+ zf_use_xmmx = 1;
+ printf ("Extended MMX detected. Using the fastest method !\n");
+ }
+ else if (zoom_filter_mmx_supported()) {
+ zf_use_mmx = 1;
+ printf ("MMX detected. Using fast method !\n");
+ }
+ else {
+ printf ("Too bad ! No MMX detected.\n");
+ }
+ firsttime = 0;
+ }
+}
+
+#else /* MMX */
+
+static void select_zoom_filter () {
+ static int firsttime = 1;
+ if (firsttime) {
+ printf ("No MMX support compiled in\n");
+ firsttime = 0;
+ }
+}
+
+#endif /* MMX */
+
+
+guint32 mmx_zoom_size;
+
+#ifdef USE_ASM
+
+#ifdef POWERPC
+#include "altivec.h"
+extern unsigned int useAltivec;
+extern const 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]);
+
+#endif /* PowerPC */
+
+#endif /* ASM */
+
+
+unsigned int *coeffs = 0, *freecoeffs = 0;
+
+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)
+
+// TODO : virer
+guint32 *expix1 = 0; // pointeur exporte vers p1
+guint32 *expix2 = 0; // pointeur exporte vers p2
+// fin TODO
+
+guint32 zoom_width;
+
+unsigned int prevX = 0, prevY = 0;
+
+static int sintable[0x10000];
+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
+#define ShiftRight(_x,_s) (((_x)<0) ? -(-(_x)>>(_s)) : ((_x)>>(_s)))
+
+/** modif d'optim by Jeko : precalcul des 4 coefs résultant des 2 pos */
+int precalCoef[16][16];
+
+/* Prototypes to keep gcc from spewing warnings */
+void generatePrecalCoef (void);
+void calculatePXandPY (int x, int y, int *px, int *py);
+void setPixelRGB (Uint * buffer, Uint x, Uint y, Color c);
+void setPixelRGB_ (Uint * buffer, Uint x, Color c);
+inline void getPixelRGB (Uint * buffer, Uint x, Uint y, Color * c);
+void getPixelRGB_ (Uint * buffer, Uint x, Color * c);
+
+void
+generatePrecalCoef ()
+{
+ static int firstime = 1;
+
+ if (firstime) {
+ int coefh, coefv;
+
+ firstime = 0;
+
+ for (coefh = 0; coefh < 16; coefh++) {
+
+ 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 >= (int)c_resoly)
+ yy = c_resoly - 1;
+
+ *px = (x << 4) + firedec[yy] + (wave / 10);
+ *py = (y << 4) + 132 - ((vitesse < 131) ? vitesse : 130);
+
+ 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;
+ 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) (dist * 0xffff + 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) (dist * 0xffff * EFFECT_DISTORS)], 6);
+ fvitesse>>=10;///=1024;
+ break;
+ case CRYSTAL_BALL_MODE:
+ fvitesse += (dist >> (10-EFFECT_DISTORS_SL));
+ break;
+ case AMULETTE_MODE:
+ fvitesse -= (dist >> (4 - EFFECT_DISTORS_SL));
+ break;
+ case SCRUNCH_MODE:
+ fvitesse -= (dist >> (10 - EFFECT_DISTORS_SL));
+ 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;
+ case YONLY_MODE:
+ fvitesse *= 1024 + ShiftRight (sintable[vy & 0xffff], 6);
+ fvitesse >>= 10;
+ break;
+ case SPEEDWAY_MODE:
+ fvitesse -= (ShiftRight(vy,10-EFFECT_DISTORS_SL));
+ 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
+
+ buffer[y * resolx + x] =
+ (c.b << (BLEU * 8)) | (c.v << (VERT * 8)) | (c.r << (ROUGE * 8));
+}
+
+
+/*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
+
+ buffer[x] = (c.r << (ROUGE * 8)) | (c.v << (VERT * 8)) | c.b << (BLEU * 8);
+}
+
+
+
+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
+
+ /* 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;
+}
+
+
+/*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 (unsigned int *expix1, unsigned int *expix2, unsigned int prevX, unsigned int prevY, signed int *brutS, signed int *brutD)
+{
+ int myPos, myPos2;
+ Color couleur;
+// unsigned int coefv, coefh;
+
+ unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC;
+
+ int bufsize = prevX * prevY * 2;
+ int bufwidth = prevX;
+
+ expix1[0]=expix1[prevX-1]=expix1[prevX*prevY-1]=expix1[prevX*prevY-prevX]=0;
+
+ 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 (px < 0)
+ px = 0;
+ if (py < 0)
+ py = 0;
+
+ pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC));
+ // coef en modulo 15
+ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK];
+
+ if ((py >= (int)ay) || (px >= (int)ax)) {
+ pos = coeffs = 0;
+ }
+
+ 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
+void setAsmUse (int useIt);
+int getAsmUse (void);
+
+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;
+
+#define INTERLACE_INCR 16
+#define INTERLACE_ADD 9
+#define INTERLACE_AND 0xf
+ static int interlace_start = -2;
+
+ 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;
+ }
+
+ if (interlace_start != -2)
+ zf = NULL;
+
+ /** 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;
+ }
+
+ /* Silence a gcc warning */
+ (void)pertedec;
+
+ /** generation d'un effet **/
+ if (firstTime || zf) {
+
+ // generation d'une table de sinus
+ if (firstTime) {
+ unsigned short us;
+ int yofs;
+
+ firstTime = 0;
+ generatePrecalCoef ();
+ select_zoom_filter ();
+
+ freebrutS = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int));
+ brutS = (signed int *) ((1 + ((uintptr_t) (freebrutS)) / 128) * 128);
+
+ freebrutD = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int));
+ brutD = (signed int *) ((1 + ((uintptr_t) (freebrutD)) / 128) * 128);
+
+ freebrutT = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int));
+ brutT = (signed int *) ((1 + ((uintptr_t) (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 * sin ((double) us * 360 / (sizeof (sintable) / sizeof (sintable[0]) - 1) * 3.141592 / 180) + .5);
+ }
+
+ {
+ 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 += 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;
+ }
+ }
+ }
+
+ interlace_start = 0;
+ }
+ // generation du buffer de trans
+ if (interlace_start==-1) {
+
+ /* 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);
+ }
+ buffratio = 0;
+ }
+
+ if (interlace_start==-1) {
+ signed int * tmp;
+ tmp = brutD;
+ brutD=brutT;
+ brutT=tmp;
+ tmp = freebrutD;
+ freebrutD=freebrutT;
+ freebrutT=tmp;
+ interlace_start = -2;
+ }
+
+ if (interlace_start>=0) {
+ int maxEnd = (interlace_start+INTERLACE_INCR);
+ /* creation de la nouvelle destination */
+ for (y = (Uint)interlace_start; (y < (Uint)prevY) && (y < (Uint)maxEnd); y++) {
+ Uint premul_y_prevX = y * prevX * 2;
+ for (x = 0; x < prevX; x++) {
+ int px, py;
+
+ calculatePXandPY (x, y, &px, &py);
+
+ brutT[premul_y_prevX] = px;
+ brutT[premul_y_prevX + 1] = py;
+ premul_y_prevX += 2;
+ }
+ }
+ interlace_start += INTERLACE_INCR;
+ if (y >= prevY-1) interlace_start = -1;
+ }
+
+ 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
+ if (zf_use_xmmx)
+ zoom_filter_xmmx (prevX, prevY,expix1, expix2,
+ brutS, brutD, buffratio, precalCoef);
+ else if (zf_use_mmx)
+ zoom_filter_mmx (prevX, prevY,expix1, expix2,
+ brutS, brutD, buffratio, precalCoef);
+ else c_zoom (expix1, expix2, prevX, prevY, brutS, brutD);
+#endif
+
+#ifdef POWERPC
+ if (useAltivec)
+{
+ ppc_zoom (expix1, expix2, prevX, prevY, brutS, brutD, buffratio,precalCoef);
+}
+ else
+ ppc_zoom (expix1, expix2, prevX, prevY, brutS, brutD, buffratio,precalCoef);
+#endif
+#else
+ c_zoom (expix1, expix2, prevX, prevY, brutS, brutD);
+#endif
+}
+
+void
+pointFilter (Uint * pix1, Color c, float t1, float t2, float t3, float t4, Uint cycle)
+{
+ Uint x = (Uint) ((int) (resolx/2) + (int) (t1 * cos ((float) cycle / t3)));
+ Uint y = (Uint) ((int) (c_resoly/2) + (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);
+ }
+}
View
54 mythtv/libs/libmythtv/visualisations/goom/filters.h
@@ -0,0 +1,54 @@
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include "goomconfig.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
+#define YONLY_MODE 8
+#define SPEEDWAY_MODE 9
+
+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);
+
+#define SIN_MUL 1
+#define SIN_ADD 2
+
+#endif
View
952 mythtv/libs/libmythtv/visualisations/goom/goom_core.c
@@ -0,0 +1,952 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../config.h"
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <inttypes.h>
+
+#include "goom_core.h"
+#include "goom_tools.h"
+#include "filters.h"
+#include "lines.h"
+#include "ifs.h"
+#include "tentacle3d.h"
+//#include "gfontlib.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;
+
+typedef struct {
+ int drawIFS;
+ int drawPoints;
+ int drawTentacle;
+
+ int drawScope;
+ int farScope;
+
+ int rangemin;
+ int rangemax;
+} GoomState;
+
+#define STATES_NB 8
+#define STATES_RANGEMAX 510
+GoomState states[STATES_NB] = {
+ {1,0,0,1,4, 000, 100},
+ {1,0,0,1,1, 101, 140}, // turned on drawScope
+ {1,0,0,1,2, 141, 200},
+ {0,1,0,1,2, 201, 260},
+ {0,1,0,1,0, 261, 330},
+ {0,1,1,1,4, 331, 400},
+ {0,0,1,1,5, 401, 450}, // turned on drawScope
+ {0,0,1,1,1, 451, 510}
+};
+
+GoomState *curGState = states+4;
+
+guint32 resolx, resoly, buffsize, c_black_height = 0, 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, float *amplitude, int far);
+
+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 ();
+ srand ((uintptr_t) pixel);
+ if (!rand_tab) rand_tab = (int *) malloc (NB_RAND * sizeof(int)) ;
+ rand_pos = 1 ;
+ while (rand_pos != 0) rand_tab [rand_pos++] = rand () ;
+
+ cycle = 0;
+
+ p1 = (guint32 *) ((1 + ((uintptr_t) (pixel)) / 128) * 128);
+ p2 = (guint32 *) ((1 + ((uintptr_t) (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);
+
+// gfont_load ();
+
+ tentacle_new ();
+}
+
+
+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);
+ memset (pixel, 0, buffsize * sizeof (guint32) + 128);
+ back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
+ memset (back, 0, buffsize * sizeof (guint32) + 128);
+ p1 = (guint32 *) ((1 + ((uintptr_t) (pixel)) / 128) * 128);
+ p2 = (guint32 *) ((1 + ((uintptr_t) (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 abiggoom = 0; // un big 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 80
+ 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
+ static int accelvar=0; // acceleration des particules
+ int i;
+ float largfactor; // elargissement de l'intervalle d'évolution
+ static int stop_lines = 0;
+
+ // 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 (29.0f/30.0f)
+#define SWITCHINCR 0x7f
+ static float switchMult = 1.0f;
+ static int switchIncr = SWITCHINCR;
+
+ 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];
+ }
+
+ i = accelvar;
+ accelvar = incvar / 1000;
+
+ if (speedvar > 5) {
+ accelvar--;
+ if (speedvar > 20)
+ accelvar--;
+ if (speedvar > 40)
+ speedvar = 40;
+ }
+ accelvar--;
+
+ i = accelvar - i;
+ if (i<0) i=-i;
+
+ speedvar += (speedvar + i/2);
+ speedvar /= 2;
+ if ((speedvar) && (cycle%9==0)) {
+ speedvar -= 1;
+ }
+ if ((speedvar) && (cycle%5==0)) {
+ speedvar = (speedvar*7)/8;
+ }
+
+ if (speedvar < 0)
+ speedvar = 0;
+ if (speedvar > 50)
+ speedvar = 50;
+
+
+ /* ! calcul du deplacement des petits points ... */
+
+ largfactor = ((float) speedvar / 40.0f + (float) incvar / 50000.0f) / 1.5f;
+ if (largfactor > 1.5f)
+ largfactor = 1.5f;
+
+ decay_ifs--;
+ if (decay_ifs > 0)
+ ifs_incr += 2;
+ if (decay_ifs == 0)
+ ifs_incr = 0;
+
+
+ if (recay_ifs) {
+ ifs_incr -= 2;
+ recay_ifs--;
+ if ((recay_ifs == 0)&&(ifs_incr<=0))
+ ifs_incr = 1;
+ }
+
+ if (ifs_incr > 0)
+ ifs_update (p1 + c_offset, p2 + c_offset, resolx, c_resoly, ifs_incr);
+
+ if (curGState->drawPoints) {
+ for (i = 1; i * 15 <= speedvar + 15; i++) {
+ loopvar += speedvar*2/3 + 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;
+
+ // temps du goom
+ if (--abiggoom < 0)
+ abiggoom = 0;
+
+ if ((!abiggoom) && (speedvar > 4) && (goomlimit > 4) &&
+ ((accelvar > goomlimit*9/8+7)||(accelvar < -goomlimit*9/8-7))) {
+ int size,i;
+ static int couleur =
+ (0xc0<<(ROUGE*8))
+ |(0xc0<<(VERT*8))
+ |(0xf0<<(BLEU*8))
+ |(0xf0<<(ALPHA*8));
+ abiggoom = 100;
+ size = resolx*c_resoly;
+ for (i=0;i<size;i++)
+ (p1+c_offset)[i] = (~(p1+c_offset)[i]) | couleur;
+ }
+
+ // 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.
+
+ // changement eventuel de mode
+ if (iRAND(16) == 0)
+ switch (iRAND (32)) {
+ 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 = 0;
+ zfd.hypercosEffect = 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:
+ case 22:
+ 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;
+ case 29:
+ case 30:
+ zfd.mode = YONLY_MODE;
+ break;
+ case 31:
+ case 32:
+ zfd.mode = SPEEDWAY_MODE;
+ 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)) {
+ static int rndn = 0 ,i;
+ static int blocker = 0;
+ goomvar++;
+
+ /* SELECTION OF THE GOOM STATE */
+ if ((!blocker)&&(iRAND(3))) {
+ rndn = iRAND(STATES_RANGEMAX);
+ blocker = 3;
+ }
+ else if (blocker) blocker--;
+
+ for (i=0;i<STATES_NB;i++)
+ if ((rndn >= states[i].rangemin)
+ && (rndn <= states[i].rangemax))
+ curGState = states+i;
+
+ if ((curGState->drawIFS) && (ifs_incr<=0)) {
+ recay_ifs = 5;
+ ifs_incr = 11;
+ }
+
+ if ((!curGState->drawIFS) && (ifs_incr>0) && (decay_ifs<=0))
+ decay_ifs = 100;
+
+ if (!curGState->drawScope)
+ stop_lines = 0xf000 & 5;
+
+ if (!curGState->drawScope) {
+ stop_lines = 0;
+ lineMode = DRAWLINES;
+ }
+
+ // if (goomvar % 1 == 0)
+ {
+ guint32 vtmp;
+ guint32 newvit;
+
+ lockvar = 50;
+ newvit = STOP_SPEED + 1 - ((float)4.0f * log10(speedvar+1));
+ // 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.mode == YONLY_MODE)
+ || (zfd.mode == AMULETTE_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 (2) + 1;
+ lockvar *= 2;
+ }
+
+ if (zfd.mode == AMULETTE_MODE) {
+ zfd.vPlaneEffect = 0;
+ zfd.hPlaneEffect = 0;
+ zfd.noisify = 0;
+ }
+
+ if ((zfd.middleX == 1) || (zfd.middleX == (int)resolx - 1)) {
+ zfd.vPlaneEffect = 0;
+ zfd.hPlaneEffect = iRAND (2) ? 0 : zfd.hPlaneEffect;
+ }
+
+ if (newvit < (guint32)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 * 7) / 8;
+ }
+ lockvar += 50;
+ }
+ }
+
+ if (lockvar > 150) {
+ switchIncr = SWITCHINCR;
+ switchMult = 1.0f;
+ }
+ }
+ // mode mega-lent
+ if (iRAND (700) == 0) {
+ 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)) {
+ pzfd = &zfd;
+ zfd.vitesse += 3;
+ zfd.pertedec = 8;
+ zfd.sqrtperte = 16;
+ goomvar = 0;
+ }
+
+ /*
+ * baisser regulierement la vitesse...
+ */
+ if ((cycle % 73 == 0) && (zfd.vitesse < STOP_SPEED - 5)) {
+ 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;
+ }
+
+ /*
+ * Permet de forcer un effet.
+ */
+ if ((forceMode > 0) && (forceMode <= NB_FX)) {
+ pzfd = &zfd;
+ pzfd->mode = forceMode - 1;
+ }
+
+ if (forceMode == -1) {
+ pzfd = NULL;
+ }
+
+ /*
+ * Changement d'effet de zoom !
+ */
+ 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
+
+ // Zoom here !
+ zoomFilterFastRGB (p1 + c_offset, p2 + c_offset, pzfd, resolx, c_resoly, switchIncr, switchMult);
+
+ /*
+ * Affichage tentacule
+ */
+
+ if (goomlimit!=0)
+ tentacle_update((gint32*)(p2 + c_offset), (gint32*)(p1 + c_offset), resolx, c_resoly, data, (float)accelvar/goomlimit, curGState->drawTentacle);
+ else
+ tentacle_update((gint32*)(p2 + c_offset), (gint32*)(p1 + c_offset), resolx, c_resoly, data,0.0f, curGState->drawTentacle);
+
+/*
+ {
+ static char title[1024];
+ static int displayTitle = 0;
+ char text[255];
+
+ if (fps > 0) {
+ int i;
+ if (speedvar>0) {
+ for (i=0;i<speedvar;i++)
+ text[i]='*';
+ text[i]=0;
+ goom_draw_text (p1 + c_offset,resolx,c_resoly, 10, 50, text, 1.0f, 0);
+ }
+ if (accelvar>0) {
+ for (i=0;i<accelvar;i++) {
+ if (i==goomlimit)
+ text[i]='o';
+ else
+ text[i]='*';
+ }
+ text[i]=0;
+ goom_draw_text (p1 + c_offset,resolx,c_resoly, 10, 62, text, 1.0f, 0);
+ }
+ if (agoom==20)
+ goom_draw_text (p1 + c_offset,resolx,c_resoly,10, 80, "GOOM",1.0f, 0);
+ else if (agoom)
+ goom_draw_text (p1 + c_offset,resolx,c_resoly,10, 80, "goom",1.0f, 0);
+ if (abiggoom==200)
+ goom_draw_text (p1 + c_offset,resolx,c_resoly,10, 100, "BGOOM",1.0f, 0);
+ else if (abiggoom)
+ goom_draw_text (p1 + c_offset,resolx,c_resoly,10, 100, "bgoom",1.0f, 0);
+ }
+
+ update_message (message);
+
+ if (fps > 0) {
+ sprintf (text, "%2.f fps", fps);
+ goom_draw_text (p1 + c_offset,resolx,c_resoly, 10, 24, text, 1, 0);
+ }
+
+ if (songTitle != NULL) {
+ sprintf (title, songTitle); // la flemme d'inclure string.h :)
+ displayTitle = 200;
+ }
+
+ if (displayTitle) {
+ goom_draw_text (p1 + c_offset,resolx,c_resoly, resolx / 2, c_resoly / 2 + 7, title, ((float) (190 - displayTitle) / 10.0f), 1);
+ displayTitle--;
+ if (displayTitle < 4)
+ goom_draw_text (p2 + c_offset,resolx,c_resoly, resolx / 2, c_resoly / 2 + 7, title, ((float) (190 - displayTitle) / 10.0f), 1);
+ }
+ }
+*/
+
+ /*
+ * arret demande
+ */
+ if ((stop_lines & 0xf000)||(!curGState->drawScope)) {
+ float param1, param2, amplitude;
+ int couleur;
+ int mode;
+
+ choose_a_goom_line (&param1, &param2, &couleur, &mode, &amplitude,1);
+ couleur = GML_BLACK;
+
+ goom_lines_switch_to (gmline1, mode, param1, amplitude, couleur);
+ goom_lines_switch_to (gmline2, mode, param2, amplitude, couleur);
+ stop_lines &= 0x0fff;
+ }
+
+ /*
+ * arret aleatore.. changement de mode de ligne..
+ */
+ if (lineMode != DRAWLINES) {
+ lineMode--;
+ if (lineMode == -1)
+ lineMode = 0;
+ }
+ else
+ if ((cycle%80==0)&&(iRAND(5)==0)&&lineMode)
+ lineMode--;
+
+ if ((cycle % 120 == 0)
+ && (iRAND (4) == 0)
+ && (curGState->drawScope)) {
+ if (lineMode == 0)
+ lineMode = DRAWLINES;
+ else if (lineMode == DRAWLINES) {
+ float param1, param2, amplitude;
+ int couleur1,couleur2;
+ int mode;
+
+ lineMode--;
+ choose_a_goom_line (&param1, &param2, &couleur1, &mode, &amplitude,stop_lines);
+
+ couleur2 = 5-couleur1;
+ if (stop_lines) {
+ stop_lines--;
+ if (iRAND(2))
+ couleur2=couleur1 = GML_BLACK;
+ }
+
+ goom_lines_switch_to (gmline1, mode, param1, amplitude, couleur1);
+ goom_lines_switch_to (gmline2, mode, param2, amplitude, couleur2);
+ }
+ }
+
+ /*
+ * si on est dans un goom : afficher les lignes...
+ */
+ if ((lineMode != 0) || (agoom > 15)) {
+ gmline2->power = gmline1->power;
+
+ goom_lines_draw (gmline1, data[0], p2 + c_offset);
+ goom_lines_draw (gmline2, data[1], p2 + c_offset);
+
+ if (((cycle % 121) == 9) && (iRAND (3) == 1)
+ && ((lineMode == 0) || (lineMode == DRAWLINES))) {
+ float param1, param2, amplitude;
+ int couleur1,couleur2;
+ int mode;
+
+ choose_a_goom_line (&param1, &param2, &couleur1, &mode, &amplitude, stop_lines);
+ couleur2 = 5-couleur1;
+
+ if (stop_lines) {
+ stop_lines--;
+ if (iRAND(2))
+ couleur2=couleur1 = GML_BLACK;
+ }
+ goom_lines_switch_to (gmline1, mode, param1, amplitude, couleur1);
+ goom_lines_switch_to (gmline2, mode, param2, amplitude, couleur2);
+ }
+ }
+
+ return_val = p1;
+ tmp = p1;
+ p1 = p2;
+ p2 = tmp;
+
+ // affichage et swappage des buffers..
+ cycle++;
+
+ // toute les 2 secondes : vérifier si le taux de goom est correct
+ // et le modifier sinon..
+ if (!(cycle % 64)) {
+ if (speedvar<1)
+ goomlimit /= 2;
+ if (totalgoom > 4) {
+ goomlimit++;
+ }
+ if (totalgoom > 7) {
+ goomlimit*=4/3;
+ goomlimit+=2;
+ }
+ if ((totalgoom == 0) && (goomlimit > 1))
+ goomlimit--;
+ if ((totalgoom == 1) && (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);
+ tentacle_free();
+}
+
+
+void choose_a_goom_line (float *param1, float *param2, int *couleur, int *mode, float *amplitude, int far) {
+ *mode = iRAND (3);
+ *amplitude = 1.0f;
+ switch (*mode) {
+ case GML_CIRCLE:
+ if (far) {
+ *param1 = *param2 = 0.47f;
+ *amplitude = 0.8f;
+ break;
+ }
+ if (iRAND (3) == 0) {
+ *param1 = *param2 = 0;
+ *amplitude = 3.0f;
+ }
+ else if (iRAND (2)) {
+ *param1 = 0.40f * c_resoly;
+ *param2 = 0.22f * c_resoly;
+ }
+ else {
+ *param1 = *param2 = c_resoly * 0.35;
+ }
+ break;
+ case GML_HLINE:
+ if (iRAND (4) || far) {
+ *param1 = c_resoly / 7;
+ *param2 = 6.0f * c_resoly / 7.0f;
+ }
+ else {
+ *param1 = *param2 = c_resoly / 2.0f;
+ *amplitude = 2.0f;
+ }
+ break;
+ case GML_VLINE:
+ if (iRAND (3) || far) {
+ *param1 = resolx / 7.0f;
+ *param2 = 6.0f * resolx / 7.0f;
+ }
+ else {
+ *param1 = *param2 = resolx / 2.0f;
+ *amplitude = 1.5f;
+ }
+ break;
+ }
+
+ *couleur = iRAND (6);
+}
+
+/*
+void goom_set_font (int ***chars, int *width, int *height) {
+ if (chars == NULL)
+ return ;
+}
+*/
+
+/*
+void update_message (char *message) {
+
+ static int nbl;
+ static char msg2 [0x800];
+ static int affiche = 0;
+ static int longueur;
+ int fin = 0;
+
+ if (message) {
+ int i=1,j=0;
+ sprintf (msg2,message);
+ for (j=0;msg2[j];j++)
+ if (msg2[j]=='\n')
+ i++;
+ nbl = i;
+ affiche = resoly + nbl * 25 + 105;
+ longueur = strlen (msg2);
+ }
+ if (affiche) {
+ int i = 0;
+ char *msg=malloc(longueur+1);
+ char *ptr = msg;
+ int pos;
+ float ecart;
+ message = msg;
+ sprintf (msg,msg2);
+
+ while (!fin) {
+ while (1) {
+ if (*ptr == 0) {
+ fin = 1;
+ break;
+ }
+ if (*ptr == '\n') {
+ *ptr = 0;
+ break;
+ }
+ ++ptr;
+ }
+ pos = affiche - (nbl-i)*25;
+ pos += 6.0*(cos((double)pos/20.0));
+ pos -= 80;
+ ecart = (1.0+2.0*sin((double)pos/20.0));
+ if ((fin) && (2 * pos < (int)resoly))
+ pos = (int)resoly / 2;
+ pos += 7;
+
+ goom_draw_text(p1 + c_offset,resolx,c_resoly, resolx/2, pos, message, ecart, 1);
+ message = ++ptr;
+ i++;
+ }
+ affiche --;
+ free (msg);
+ }
+}
+*/
View
19 mythtv/libs/libmythtv/visualisations/goom/goom_core.h
@@ -0,0 +1,19 @@
+#ifndef _GOOMCORE_H
+#define _GOOMCORE_H
+
+#include "goomconfig.h"
+
+#define NB_FX 10
+
+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);
+
+#endif
View
37 mythtv/libs/libmythtv/visualisations/goom/goom_tools.h
@@ -0,0 +1,37 @@
+#ifndef _GOOMTOOLS_H
+#define _GOOMTOOLS_H
+
+#if !defined( M_PI )
+ #define M_PI 3.14159265358979323846
+#endif
+
+#define NB_RAND 0x10000
+
+/* in graphic.c */
+extern int *rand_tab;
+static 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 () ;
+
+
+static inline int RAND() {
+ ++rand_pos;
+ return rand_tab[rand_pos];
+}
+
+#define RAND_CLOSE()\
+ free (rand_tab);\
+ rand_tab = 0;
+
+
+//#define iRAND(i) ((guint32)((float)i * RAND()/RAND_MAX))
+#define iRAND(i) (RAND()%i)
+
+//inline unsigned int RAND(void);
+//inline unsigned int iRAND(int i);
+
+#endif
View
39 mythtv/libs/libmythtv/visualisations/goom/goomconfig.h
@@ -0,0 +1,39 @@
+
+//#define VERSION "1.9.2"
+//#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
+
+//#define POWERPC
+
+//#define HAVE_ATHLON
+
+//#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
View
30 mythtv/libs/libmythtv/visualisations/goom/graphic.c
@@ -0,0 +1,30 @@
+#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;
+/*
+inline unsigned int RAND(void)
+{
+ rand_pos++;
+ return rand_tab[rand_pos];
+}
+
+inline unsigned int iRAND(int i)
+{
+ rand_pos++;
+ return (rand_tab[rand_pos])%i;
+}
+*/
View
24 mythtv/libs/libmythtv/visualisations/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 */
View
549 mythtv/libs/libmythtv/visualisations/goom/ifs.c
@@ -0,0 +1,549 @@
+/* -*- 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
+
+#include "goom_tools.h"
+
+#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
+
+#define MAX_DEPTH_2 10
+#define MAX_DEPTH_3 6
+#define MAX_DEPTH_4 4
+#define MAX_DEPTH_5 2
+
+/* PREVIOUS VALUE
+#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) >> FIX; // / UNIT;
+ yo = yo - Simi->Cy;
+ yo = (yo * Simi->R) >> FIX; // / UNIT;
+
+ xx = xo - Simi->Cx;
+ xx = (xx * Simi->R2) >> FIX; // / UNIT;
+ yy = -yo - Simi->Cy;
+ yy = (yy * Simi->R2) >> FIX; // / UNIT;
+
+ *x =
+ ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2)
+ >> FIX /* / UNIT */ ) + Simi->Cx;
+ *y =
+ ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2)
+ >> FIX /* / 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) >> (FIX+1) /* /(UNIT*2) */ );
+ Buf->y = F->Ly - ((y * F->Ly) >> (FIX+1) /* /(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