mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 13:18:52 +00:00
411 lines
12 KiB
C
411 lines
12 KiB
C
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#include <glib.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "goom_core.h"
|
|
#include "goom_tools.h"
|
|
#include "filters.h"
|
|
#include "lines.h"
|
|
|
|
/*#define VERBOSE */
|
|
|
|
#ifdef VERBOSE
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#define STOP_SPEED 128
|
|
|
|
void
|
|
goom_init (GoomData * goomdata, guint32 resx, guint32 resy)
|
|
{
|
|
#ifdef VERBOSE
|
|
printf ("GOOM: init (%d, %d);\n", resx, resy);
|
|
#endif
|
|
goomdata->resolx = 0;
|
|
goomdata->resoly = 0;
|
|
goomdata->buffsize = 0;
|
|
|
|
goomdata->pixel = NULL;
|
|
goomdata->back = NULL;
|
|
goomdata->p1 = NULL;
|
|
goomdata->p2 = NULL;
|
|
|
|
goom_set_resolution (goomdata, resx, resy);
|
|
RAND_INIT (goomdata, GPOINTER_TO_INT (goomdata->pixel));
|
|
goomdata->cycle = 0;
|
|
|
|
|
|
goomdata->goomlimit = 2; /* sensibilité du goom */
|
|
goomdata->zfd = zoomFilterNew ();
|
|
goomdata->lockvar = 0; /* pour empecher de nouveaux changements */
|
|
goomdata->goomvar = 0; /* boucle des gooms */
|
|
goomdata->totalgoom = 0; /* nombre de gooms par seconds */
|
|
goomdata->agoom = 0; /* un goom a eu lieu.. */
|
|
goomdata->loopvar = 0; /* mouvement des points */
|
|
goomdata->speedvar = 0; /* vitesse des particules */
|
|
goomdata->lineMode = 0; /* l'effet lineaire a dessiner */
|
|
}
|
|
|
|
void
|
|
goom_set_resolution (GoomData * goomdata, guint32 resx, guint32 resy)
|
|
{
|
|
guint32 buffsize = resx * resy;
|
|
|
|
if ((goomdata->resolx == resx) && (goomdata->resoly == resy))
|
|
return;
|
|
|
|
if (goomdata->buffsize < buffsize) {
|
|
if (goomdata->pixel)
|
|
free (goomdata->pixel);
|
|
if (goomdata->back)
|
|
free (goomdata->back);
|
|
goomdata->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
|
|
goomdata->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
|
|
goomdata->buffsize = buffsize;
|
|
|
|
goomdata->p1 = (void *) (((guintptr) goomdata->pixel + 0x7f) & (~0x7f));
|
|
goomdata->p2 = (void *) (((guintptr) goomdata->back + 0x7f) & (~0x7f));
|
|
}
|
|
|
|
goomdata->resolx = resx;
|
|
goomdata->resoly = resy;
|
|
|
|
memset (goomdata->pixel, 0, buffsize * sizeof (guint32) + 128);
|
|
memset (goomdata->back, 0, buffsize * sizeof (guint32) + 128);
|
|
}
|
|
|
|
guint32 *
|
|
goom_update (GoomData * goomdata, gint16 data[2][512])
|
|
{
|
|
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 */
|
|
int zfd_update = 0;
|
|
int resolx = goomdata->resolx;
|
|
int resoly = goomdata->resoly;
|
|
ZoomFilterData *pzfd = goomdata->zfd;
|
|
guint32 *tmp;
|
|
|
|
/* 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 (goomdata->speedvar > 5) {
|
|
accelvar--;
|
|
if (goomdata->speedvar > 20)
|
|
accelvar--;
|
|
if (goomdata->speedvar > 40)
|
|
goomdata->speedvar = 40;
|
|
}
|
|
accelvar--;
|
|
goomdata->speedvar += accelvar;
|
|
|
|
if (goomdata->speedvar < 0)
|
|
goomdata->speedvar = 0;
|
|
if (goomdata->speedvar > 40)
|
|
goomdata->speedvar = 40;
|
|
|
|
|
|
/* ! calcul du deplacement des petits points ... */
|
|
|
|
largfactor =
|
|
((float) goomdata->speedvar / 40.0f + (float) incvar / 50000.0f) / 1.5f;
|
|
if (largfactor > 1.5f)
|
|
largfactor = 1.5f;
|
|
|
|
for (i = 1; i * 15 <= goomdata->speedvar + 15; i++) {
|
|
goomdata->loopvar += goomdata->speedvar + 1;
|
|
|
|
pointFilter (goomdata,
|
|
YELLOW,
|
|
((pointWidth - 6.0f) * largfactor + 5.0f),
|
|
((pointHeight - 6.0f) * largfactor + 5.0f),
|
|
i * 152.0f, 128.0f, goomdata->loopvar + i * 2032);
|
|
pointFilter (goomdata, ORANGE,
|
|
((pointWidth / 2) * largfactor) / i + 10.0f * i,
|
|
((pointHeight / 2) * largfactor) / i + 10.0f * i,
|
|
96.0f, i * 80.0f, goomdata->loopvar / i);
|
|
pointFilter (goomdata, VIOLET,
|
|
((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
|
|
((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
|
|
i + 122.0f, 134.0f, goomdata->loopvar / i);
|
|
pointFilter (goomdata, BLACK,
|
|
((pointHeight / 3) * largfactor + 20.0f),
|
|
((pointHeight / 3) * largfactor + 20.0f),
|
|
58.0f, i * 66.0f, goomdata->loopvar / i);
|
|
pointFilter (goomdata, WHITE,
|
|
(pointHeight * largfactor + 10.0f * i) / i,
|
|
(pointHeight * largfactor + 10.0f * i) / i,
|
|
66.0f, 74.0f, goomdata->loopvar + i * 500);
|
|
}
|
|
|
|
/* 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 (--goomdata->lockvar < 0)
|
|
goomdata->lockvar = 0;
|
|
|
|
/* temps du goom */
|
|
if (--goomdata->agoom < 0)
|
|
goomdata->agoom = 0;
|
|
|
|
/* on verifie qu'il ne se pas un truc interressant avec le son. */
|
|
if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
|
|
/* UN GOOM !!! YAHOO ! */
|
|
goomdata->totalgoom++;
|
|
goomdata->agoom = 20; /* mais pdt 20 cycles, il n'y en aura plus. */
|
|
goomdata->lineMode = (goomdata->lineMode + 1) % 20; /* Tous les 10 gooms on change de mode lineaire */
|
|
|
|
/* changement eventuel de mode */
|
|
switch (iRAND (goomdata, 10)) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
pzfd->mode = WAVE_MODE;
|
|
pzfd->vitesse = STOP_SPEED - 1;
|
|
pzfd->reverse = 0;
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
pzfd->mode = CRYSTAL_BALL_MODE;
|
|
break;
|
|
case 5:
|
|
pzfd->mode = AMULETTE_MODE;
|
|
break;
|
|
case 6:
|
|
pzfd->mode = WATER_MODE;
|
|
break;
|
|
case 7:
|
|
pzfd->mode = SCRUNCH_MODE;
|
|
break;
|
|
default:
|
|
pzfd->mode = NORMAL_MODE;
|
|
}
|
|
}
|
|
|
|
/* tout ceci ne sera fait qu'en cas de non-blocage */
|
|
if (goomdata->lockvar == 0) {
|
|
/* reperage de goom (acceleration forte de l'acceleration du volume) */
|
|
/* -> coup de boost de la vitesse si besoin.. */
|
|
if ((accelvar > goomdata->goomlimit) || (accelvar < -goomdata->goomlimit)) {
|
|
goomdata->goomvar++;
|
|
/*if (goomvar % 1 == 0) */
|
|
{
|
|
guint32 vtmp;
|
|
guint32 newvit;
|
|
|
|
newvit = STOP_SPEED - goomdata->speedvar / 2;
|
|
/* retablir le zoom avant.. */
|
|
if ((pzfd->reverse) && (!(goomdata->cycle % 12)) && (rand () % 3 == 0)) {
|
|
pzfd->reverse = 0;
|
|
pzfd->vitesse = STOP_SPEED - 2;
|
|
goomdata->lockvar = 50;
|
|
}
|
|
if (iRAND (goomdata, 10) == 0) {
|
|
pzfd->reverse = 1;
|
|
goomdata->lockvar = 100;
|
|
}
|
|
|
|
/* changement de milieu.. */
|
|
switch (iRAND (goomdata, 20)) {
|
|
case 0:
|
|
pzfd->middleY = resoly - 1;
|
|
pzfd->middleX = resolx / 2;
|
|
break;
|
|
case 1:
|
|
pzfd->middleX = resolx - 1;
|
|
break;
|
|
case 2:
|
|
pzfd->middleX = 1;
|
|
break;
|
|
default:
|
|
pzfd->middleY = resoly / 2;
|
|
pzfd->middleX = resolx / 2;
|
|
}
|
|
|
|
if (pzfd->mode == WATER_MODE) {
|
|
pzfd->middleX = resolx / 2;
|
|
pzfd->middleY = resoly / 2;
|
|
}
|
|
|
|
switch (vtmp = (iRAND (goomdata, 27))) {
|
|
case 0:
|
|
pzfd->vPlaneEffect = iRAND (goomdata, 3);
|
|
pzfd->vPlaneEffect -= iRAND (goomdata, 3);
|
|
pzfd->hPlaneEffect = iRAND (goomdata, 3);
|
|
pzfd->hPlaneEffect -= iRAND (goomdata, 3);
|
|
break;
|
|
case 3:
|
|
pzfd->vPlaneEffect = 0;
|
|
pzfd->hPlaneEffect = iRAND (goomdata, 8);
|
|
pzfd->hPlaneEffect -= iRAND (goomdata, 8);
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
pzfd->vPlaneEffect = iRAND (goomdata, 5);
|
|
pzfd->vPlaneEffect -= iRAND (goomdata, 5);
|
|
pzfd->hPlaneEffect = -pzfd->vPlaneEffect;
|
|
break;
|
|
case 8:
|
|
pzfd->hPlaneEffect = 5 + iRAND (goomdata, 8);
|
|
pzfd->vPlaneEffect = -pzfd->hPlaneEffect;
|
|
break;
|
|
case 9:
|
|
pzfd->vPlaneEffect = 5 + iRAND (goomdata, 8);
|
|
pzfd->hPlaneEffect = -pzfd->hPlaneEffect;
|
|
break;
|
|
case 13:
|
|
pzfd->hPlaneEffect = 0;
|
|
pzfd->vPlaneEffect = iRAND (goomdata, 10);
|
|
pzfd->vPlaneEffect -= iRAND (goomdata, 10);
|
|
break;
|
|
default:
|
|
if (vtmp < 10) {
|
|
pzfd->vPlaneEffect = 0;
|
|
pzfd->hPlaneEffect = 0;
|
|
}
|
|
}
|
|
|
|
if (iRAND (goomdata, 3) != 0)
|
|
pzfd->noisify = 0;
|
|
else {
|
|
pzfd->noisify = iRAND (goomdata, 3) + 2;
|
|
goomdata->lockvar *= 3;
|
|
}
|
|
|
|
if (pzfd->mode == AMULETTE_MODE) {
|
|
pzfd->vPlaneEffect = 0;
|
|
pzfd->hPlaneEffect = 0;
|
|
pzfd->noisify = 0;
|
|
}
|
|
|
|
if ((pzfd->middleX == 1) || (pzfd->middleX == resolx - 1)) {
|
|
pzfd->vPlaneEffect = 0;
|
|
pzfd->hPlaneEffect = iRAND (goomdata, 2) ? 0 : pzfd->hPlaneEffect;
|
|
}
|
|
|
|
if (newvit < pzfd->vitesse) { /* on accelere */
|
|
zfd_update = 1;
|
|
if (((newvit < STOP_SPEED - 7) &&
|
|
(pzfd->vitesse < STOP_SPEED - 6) &&
|
|
(goomdata->cycle % 3 == 0)) || (iRAND (goomdata, 40) == 0)) {
|
|
pzfd->vitesse = STOP_SPEED - 1;
|
|
pzfd->reverse = !pzfd->reverse;
|
|
} else {
|
|
pzfd->vitesse = (newvit + pzfd->vitesse * 4) / 5;
|
|
}
|
|
goomdata->lockvar += 50;
|
|
}
|
|
}
|
|
}
|
|
/* mode mega-lent */
|
|
if (iRAND (goomdata, 1000) == 0) {
|
|
/*
|
|
printf ("coup du sort...\n") ;
|
|
*/
|
|
zfd_update = 1;
|
|
pzfd->vitesse = STOP_SPEED - 1;
|
|
pzfd->pertedec = 8;
|
|
pzfd->sqrtperte = 16;
|
|
goomdata->goomvar = 1;
|
|
goomdata->lockvar += 70;
|
|
}
|
|
}
|
|
|
|
/* gros frein si la musique est calme */
|
|
if ((goomdata->speedvar < 1) && (pzfd->vitesse < STOP_SPEED - 4)
|
|
&& (goomdata->cycle % 16 == 0)) {
|
|
/*
|
|
printf ("++slow part... %i\n", zfd.vitesse) ;
|
|
*/
|
|
zfd_update = 1;
|
|
pzfd->vitesse += 3;
|
|
pzfd->pertedec = 8;
|
|
pzfd->sqrtperte = 16;
|
|
goomdata->goomvar = 0;
|
|
/*
|
|
printf ("--slow part... %i\n", zfd.vitesse) ;
|
|
*/
|
|
}
|
|
|
|
/* baisser regulierement la vitesse... */
|
|
if ((goomdata->cycle % 73 == 0) && (pzfd->vitesse < STOP_SPEED - 5)) {
|
|
/*
|
|
printf ("slow down...\n") ;
|
|
*/
|
|
zfd_update = 1;
|
|
pzfd->vitesse++;
|
|
}
|
|
|
|
/* arreter de decrémenter au bout d'un certain temps */
|
|
if ((goomdata->cycle % 101 == 0) && (pzfd->pertedec == 7)) {
|
|
zfd_update = 1;
|
|
pzfd->pertedec = 8;
|
|
pzfd->sqrtperte = 16;
|
|
}
|
|
|
|
/* Zoom here ! */
|
|
zoomFilterFastRGB (goomdata, pzfd, zfd_update);
|
|
|
|
/* si on est dans un goom : afficher les lignes... */
|
|
if (goomdata->agoom > 15)
|
|
goom_lines (goomdata, data, ((pzfd->middleX == resolx / 2)
|
|
&& (pzfd->middleY == resoly / 2)
|
|
&& (pzfd->mode != WATER_MODE))
|
|
? (goomdata->lineMode / 10) : 0, goomdata->p2, goomdata->agoom - 15);
|
|
|
|
return_val = goomdata->p2;
|
|
tmp = goomdata->p1;
|
|
goomdata->p1 = goomdata->p2;
|
|
goomdata->p2 = tmp;
|
|
|
|
/* affichage et swappage des buffers.. */
|
|
goomdata->cycle++;
|
|
|
|
/* tous les 100 cycles : vérifier si le taux de goom est correct */
|
|
/* et le modifier sinon.. */
|
|
if (!(goomdata->cycle % 100)) {
|
|
if (goomdata->totalgoom > 15) {
|
|
/* printf ("less gooms\n") ; */
|
|
goomdata->goomlimit++;
|
|
} else {
|
|
if ((goomdata->totalgoom == 0) && (goomdata->goomlimit > 1))
|
|
goomdata->goomlimit--;
|
|
}
|
|
goomdata->totalgoom = 0;
|
|
}
|
|
return return_val;
|
|
}
|
|
|
|
void
|
|
goom_close (GoomData * goomdata)
|
|
{
|
|
if (goomdata->pixel != NULL)
|
|
free (goomdata->pixel);
|
|
if (goomdata->back != NULL)
|
|
free (goomdata->back);
|
|
if (goomdata->zfd != NULL) {
|
|
zoomFilterDestroy (goomdata->zfd);
|
|
goomdata->zfd = NULL;
|
|
}
|
|
goomdata->pixel = goomdata->back = NULL;
|
|
RAND_CLOSE (goomdata);
|
|
}
|