mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 13:48:55 +00:00
774 lines
18 KiB
C
774 lines
18 KiB
C
/*-
|
|
* Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr>
|
|
*
|
|
* ifs.c: modified iterated functions system for goom.
|
|
*
|
|
* 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:
|
|
* 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX).
|
|
* 11-Apr-2002: jeko@ios-software.com: 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 "goom_config.h"
|
|
|
|
#ifdef HAVE_MMX
|
|
#include "mmx.h"
|
|
#endif
|
|
|
|
#include "goom_graphic.h"
|
|
#include "ifs.h"
|
|
#include "goom_tools.h"
|
|
|
|
typedef struct _ifsPoint
|
|
{
|
|
gint32 x, y;
|
|
}
|
|
IFSPoint;
|
|
|
|
|
|
#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
|
|
|
|
#define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff))
|
|
#define NRAND(n) ((int) (LRAND() % (n)))
|
|
|
|
#if RAND_MAX < 0x10000
|
|
#define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f)
|
|
#else
|
|
#define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */
|
|
#endif
|
|
|
|
/*****************************************************/
|
|
|
|
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;
|
|
};
|
|
|
|
typedef struct _IFS_DATA
|
|
{
|
|
FRACTAL *Root;
|
|
FRACTAL *Cur_F;
|
|
|
|
/* Used by the Trace recursive method */
|
|
IFSPoint *Buf;
|
|
int Cur_Pt;
|
|
int initalized;
|
|
} IfsData;
|
|
|
|
|
|
/*****************************************************/
|
|
|
|
static DBL
|
|
Gauss_Rand (PluginInfo * goomInfo, 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 (PluginInfo * goomInfo, 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 (PluginInfo * goomInfo, FRACTAL * F, SIMI * Cur, int i)
|
|
{
|
|
while (i--) {
|
|
Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
|
|
Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
|
|
Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0);
|
|
Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0);
|
|
Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_PI / 180.0);
|
|
Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_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);
|
|
}
|
|
|
|
/***************************************************************/
|
|
|
|
static void
|
|
init_ifs (PluginInfo * goomInfo, IfsData * data)
|
|
{
|
|
int i;
|
|
FRACTAL *Fractal;
|
|
int width = goomInfo->screen.width;
|
|
int height = goomInfo->screen.height;
|
|
|
|
if (data->Root == NULL) {
|
|
data->Root = (FRACTAL *) malloc (sizeof (FRACTAL));
|
|
if (data->Root == NULL)
|
|
return;
|
|
data->Root->Buffer1 = (IFSPoint *) NULL;
|
|
data->Root->Buffer2 = (IFSPoint *) NULL;
|
|
}
|
|
Fractal = data->Root;
|
|
|
|
free_ifs_buffers (Fractal);
|
|
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
|
|
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 (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI);
|
|
}
|
|
|
|
|
|
/***************************************************************/
|
|
|
|
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, IfsData * data)
|
|
{
|
|
F_PT x, y, i;
|
|
SIMI *Cur;
|
|
|
|
Cur = data->Cur_F->Components;
|
|
for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) {
|
|
Transform (Cur, xo, yo, &x, &y);
|
|
|
|
data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX + 1) /* /(UNIT*2) */ );
|
|
data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX + 1) /* /(UNIT*2) */ );
|
|
data->Buf++;
|
|
|
|
data->Cur_Pt++;
|
|
|
|
if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) {
|
|
F->Depth--;
|
|
Trace (F, x, y, data);
|
|
F->Depth++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
Draw_Fractal (IfsData * data)
|
|
{
|
|
FRACTAL *F = data->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);
|
|
}
|
|
|
|
|
|
data->Cur_Pt = 0;
|
|
data->Cur_F = F;
|
|
data->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, data);
|
|
}
|
|
}
|
|
|
|
/* Erase previous */
|
|
|
|
F->Cur_Pt = data->Cur_Pt;
|
|
data->Buf = F->Buffer1;
|
|
F->Buffer1 = F->Buffer2;
|
|
F->Buffer2 = data->Buf;
|
|
}
|
|
|
|
|
|
static IFSPoint *
|
|
draw_ifs (PluginInfo * goomInfo, int *nbpt, IfsData * data)
|
|
{
|
|
int i;
|
|
DBL u, uu, v, vv, u0, u1, u2, u3;
|
|
SIMI *S, *S1, *S2, *S3, *S4;
|
|
FRACTAL *F;
|
|
|
|
if (data->Root == NULL)
|
|
return NULL;
|
|
F = data->Root;
|
|
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;
|
|
}
|
|
|
|
Draw_Fractal (data);
|
|
|
|
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 (goomInfo, F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi);
|
|
|
|
Random_Simis (goomInfo, F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi);
|
|
|
|
F->Count = 0;
|
|
} else
|
|
F->Count++;
|
|
|
|
F->Col++;
|
|
|
|
(*nbpt) = data->Cur_Pt;
|
|
return F->Buffer2;
|
|
}
|
|
|
|
|
|
/***************************************************************/
|
|
|
|
static void
|
|
release_ifs (IfsData * data)
|
|
{
|
|
if (data->Root != NULL) {
|
|
free_ifs (data->Root);
|
|
(void) free ((void *) data->Root);
|
|
data->Root = (FRACTAL *) NULL;
|
|
}
|
|
}
|
|
|
|
#define RAND() goom_random(goomInfo->gRandom)
|
|
|
|
static void
|
|
ifs_update (PluginInfo * goomInfo, Pixel * data, Pixel * back, int increment,
|
|
IfsData * fx_data)
|
|
{
|
|
static unsigned 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 = 0;
|
|
IFSPoint *points;
|
|
int i;
|
|
|
|
unsigned int couleursl = couleur;
|
|
int width = goomInfo->screen.width;
|
|
int height = goomInfo->screen.height;
|
|
|
|
cycle++;
|
|
if (cycle >= 80)
|
|
cycle = 0;
|
|
|
|
if (cycle < 40)
|
|
cycle10 = cycle / 10;
|
|
else
|
|
cycle10 = 7 - cycle / 10;
|
|
|
|
{
|
|
unsigned char *tmp = (unsigned char *) &couleursl;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
*tmp = (*tmp) >> cycle10;
|
|
tmp++;
|
|
}
|
|
}
|
|
|
|
points = draw_ifs (goomInfo, &nbpt, fx_data);
|
|
nbpt--;
|
|
|
|
#ifdef HAVE_MMX
|
|
movd_m2r (couleursl, mm1);
|
|
punpckldq_r2r (mm1, mm1);
|
|
for (i = 0; i < nbpt; i += increment) {
|
|
int x = points[i].x;
|
|
int y = points[i].y;
|
|
|
|
if ((x < width) && (y < height) && (x > 0) && (y > 0)) {
|
|
int pos = x + (y * width);
|
|
|
|
movd_m2r (back[pos], mm0);
|
|
paddusb_r2r (mm1, mm0);
|
|
movd_r2m (mm0, data[pos]);
|
|
}
|
|
}
|
|
emms (); /*__asm__ __volatile__ ("emms");*/
|
|
#else
|
|
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);
|
|
int tra = 0, i = 0;
|
|
unsigned char *bra = (unsigned char *) &back[pos];
|
|
unsigned char *dra = (unsigned char *) &data[pos];
|
|
unsigned char *cra = (unsigned char *) &couleursl;
|
|
|
|
for (; i < 4; i++) {
|
|
tra = *cra;
|
|
tra += *bra;
|
|
if (tra > 255)
|
|
tra = 255;
|
|
*dra = tra;
|
|
++dra;
|
|
++cra;
|
|
++bra;
|
|
}
|
|
}
|
|
}
|
|
#endif /*MMX*/
|
|
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));
|
|
}
|
|
|
|
/** VISUAL_FX WRAPPER FOR IFS */
|
|
|
|
static void
|
|
ifs_vfx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
|
|
PluginInfo * goomInfo)
|
|
{
|
|
|
|
IfsData *data = (IfsData *) _this->fx_data;
|
|
|
|
if (!data->initalized) {
|
|
data->initalized = 1;
|
|
init_ifs (goomInfo, data);
|
|
}
|
|
ifs_update (goomInfo, dest, src, goomInfo->update.ifs_incr, data);
|
|
/*TODO: trouver meilleur soluce pour increment (mettre le code de gestion de l'ifs dans ce fichier: ifs_vfx_apply) */
|
|
}
|
|
|
|
static void
|
|
ifs_vfx_init (VisualFX * _this, PluginInfo * info)
|
|
{
|
|
|
|
IfsData *data = (IfsData *) malloc (sizeof (IfsData));
|
|
|
|
data->Root = (FRACTAL *) NULL;
|
|
data->initalized = 0;
|
|
_this->fx_data = data;
|
|
}
|
|
|
|
static void
|
|
ifs_vfx_free (VisualFX * _this)
|
|
{
|
|
IfsData *data = (IfsData *) _this->fx_data;
|
|
|
|
release_ifs (data);
|
|
free (data);
|
|
}
|
|
|
|
void
|
|
ifs_visualfx_create (VisualFX * vfx)
|
|
{
|
|
|
|
vfx->init = ifs_vfx_init;
|
|
vfx->free = ifs_vfx_free;
|
|
vfx->apply = ifs_vfx_apply;
|
|
vfx->fx_data = NULL;
|
|
vfx->params = NULL;
|
|
}
|