| /*- |
| * 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; |
| } |