#include #include #include "goom_core.h" #include "goom_tools.h" #include "filters.h" #include "lines.h" /*#define VERBOSE */ #ifdef VERBOSE #include #endif #define STOP_SPEED 128 /**-----------------------------------------------------** ** SHARED DATA ** **-----------------------------------------------------**/ static guint32 *pixel; static guint32 *back; static guint32 *p1, *p2, *tmp; static guint32 cycle; guint32 resolx, resoly, buffsize; void goom_init (guint32 resx, guint32 resy) { #ifdef VERBOSE printf ("GOOM: init (%d, %d);\n", resx, resy); #endif resolx = resx; resoly = resy; buffsize = resx * resy; pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); RAND_INIT (GPOINTER_TO_INT (pixel)); cycle = 0; p1 = (void *) (((unsigned long) pixel + 0x7f) & (~0x7f)); p2 = (void *) (((unsigned long) back + 0x7f) & (~0x7f)); } void goom_set_resolution (guint32 resx, guint32 resy) { free (pixel); free (back); 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 = (void *) (((unsigned long) pixel + 0x7f) & (~0x7f)); p2 = (void *) (((unsigned long) back + 0x7f) & (~0x7f)); } guint32 * goom_update (gint16 data[2][512]) { 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 */ static int lineMode = 0; /* l'effet lineaire a dessiner */ 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 char goomlimit = 2; /* sensibilité du goom */ static ZoomFilterData zfd = { 128, 8, 16, 1, 1, 0, WAVE_MODE, 0, 0, 0 }; ZoomFilterData *pzfd; /* test if the config has changed, update it if so */ pointWidth = (resolx * 2) / 5; pointHeight = (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; for (i = 1; i * 15 <= speedvar + 15; i++) { loopvar += speedvar + 1; pointFilter (p1, YELLOW, ((pointWidth - 6.0f) * largfactor + 5.0f), ((pointHeight - 6.0f) * largfactor + 5.0f), i * 152.0f, 128.0f, loopvar + i * 2032); pointFilter (p1, ORANGE, ((pointWidth / 2) * largfactor) / i + 10.0f * i, ((pointHeight / 2) * largfactor) / i + 10.0f * i, 96.0f, i * 80.0f, loopvar / i); pointFilter (p1, 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, BLACK, ((pointHeight / 3) * largfactor + 20.0f), ((pointHeight / 3) * largfactor + 20.0f), 58.0f, i * 66.0f, loopvar / i); pointFilter (p1, 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; /* 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)) { /* UN GOOM !!! YAHOO ! */ totalgoom++; agoom = 20; /* mais pdt 20 cycles, il n'y en aura plus. */ lineMode = (lineMode + 1) % 20; /* Tous les 10 gooms on change de mode lineaire */ /* changement eventuel de mode */ switch (iRAND (10)) { case 0: case 1: case 2: zfd.mode = WAVE_MODE; zfd.vitesse = STOP_SPEED - 1; zfd.reverse = 0; break; case 3: case 4: zfd.mode = CRYSTAL_BALL_MODE; break; case 5: zfd.mode = AMULETTE_MODE; break; case 6: zfd.mode = WATER_MODE; break; case 7: zfd.mode = SCRUNCH_MODE; break; default: zfd.mode = NORMAL_MODE; } } /* 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; newvit = STOP_SPEED - speedvar / 2; /* retablir le zoom avant.. */ if ((zfd.reverse) && (!(cycle % 12)) && (rand () % 3 == 0)) { zfd.reverse = 0; zfd.vitesse = STOP_SPEED - 2; lockvar = 50; } if (iRAND (10) == 0) { zfd.reverse = 1; lockvar = 100; } /* changement de milieu.. */ switch (iRAND (20)) { case 0: zfd.middleY = resoly - 1; zfd.middleX = resolx / 2; break; case 1: zfd.middleX = resolx - 1; break; case 2: zfd.middleX = 1; break; default: zfd.middleY = resoly / 2; zfd.middleX = resolx / 2; } if (zfd.mode == WATER_MODE) { zfd.middleX = resolx / 2; zfd.middleY = resoly / 2; } switch (vtmp = (iRAND (27))) { case 0: zfd.vPlaneEffect = iRAND (3); zfd.vPlaneEffect -= iRAND (3); zfd.hPlaneEffect = iRAND (3); zfd.hPlaneEffect -= iRAND (3); break; case 3: zfd.vPlaneEffect = 0; zfd.hPlaneEffect = iRAND (8); zfd.hPlaneEffect -= iRAND (8); break; case 4: case 5: case 6: case 7: zfd.vPlaneEffect = iRAND (5); zfd.vPlaneEffect -= 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); zfd.vPlaneEffect -= iRAND (10); break; default: if (vtmp < 10) { zfd.vPlaneEffect = 0; zfd.hPlaneEffect = 0; } } if (iRAND (3) != 0) zfd.noisify = 0; else { zfd.noisify = iRAND (3) + 2; lockvar *= 3; } 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 - 1; zfd.reverse = !zfd.reverse; } else { zfd.vitesse = (newvit + zfd.vitesse * 4) / 5; } lockvar += 50; } } } /* mode mega-lent */ if (iRAND (1000) == 0) { /* printf ("coup du sort...\n") ; */ pzfd = &zfd; zfd.vitesse = STOP_SPEED - 1; zfd.pertedec = 8; zfd.sqrtperte = 16; goomvar = 1; lockvar += 70; } } /* 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; } #ifdef VERBOSE if (pzfd) { printf ("GOOM: pzfd->mode = %d\n", pzfd->mode); } #endif /* Zoom here ! */ zoomFilterFastRGB (p1, p2, pzfd, resolx, resoly); /* si on est dans un goom : afficher les lignes... */ if (agoom > 15) goom_lines (data, ((zfd.middleX == resolx / 2) && (zfd.middleY == resoly / 2) && (zfd.mode != WATER_MODE)) ? (lineMode / 10) : 0, p2, agoom - 15); 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 (); }