blob: 5438e31b4824f34308a9706419dc189c90c7cd44 [file] [log] [blame]
Bastien Noceraa7bc7482008-02-23 01:51:37 +00001/*-
2 * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr>
3 *
Stefan Kost6eb6d5b2008-10-28 06:50:57 +00004 * ifs.c: modified iterated functions system for goom.
5 *
Bastien Noceraa7bc7482008-02-23 01:51:37 +00006 * Permission to use, copy, modify, and distribute this software and its
7 * documentation for any purpose and without fee is hereby granted,
8 * provided that the above copyright notice appear in all copies and that
9 * both that copyright notice and this permission notice appear in
10 * supporting documentation.
11 *
12 * This file is provided AS IS with no warranties of any kind. The author
13 * shall have no liability with respect to the infringement of copyrights,
14 * trade secrets or any patents by this file or any part thereof. In no
15 * event will the author be liable for any lost revenue or profits or
16 * other special, indirect and consequential damages.
17 *
18 * If this mode is weird and you have an old MetroX server, it is buggy.
19 * There is a free SuSE-enhanced MetroX X server that is fine.
20 *
21 * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing."
22 *
23 * Revision History:
24 * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX).
25 * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added)
26 * 01-Nov-2000: Allocation checks
27 * 10-May-1997: jwz@jwz.org: turned into a standalone program.
28 * Made it render into an offscreen bitmap and then copy
29 * that onto the screen, to reduce flicker.
30 */
31
32/* #ifdef STANDALONE */
33
34#include <math.h>
35#include <stdlib.h>
36#include <stdio.h>
37
38#include "goom_config.h"
39
40#ifdef HAVE_MMX
41#include "mmx.h"
42#endif
43
44#include "goom_graphic.h"
45#include "ifs.h"
46#include "goom_tools.h"
47
48typedef struct _ifsPoint
49{
50 gint32 x, y;
51}
52IFSPoint;
53
54
55#define MODE_ifs
56
57#define PROGCLASS "IFS"
58
59#define HACK_INIT init_ifs
60#define HACK_DRAW draw_ifs
61
62#define ifs_opts xlockmore_opts
63
64#define DEFAULTS "*delay: 20000 \n" \
65"*ncolors: 100 \n"
66
67#define SMOOTH_COLORS
68
69#define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff))
70#define NRAND(n) ((int) (LRAND() % (n)))
71
72#if RAND_MAX < 0x10000
73#define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f)
74#else
75#define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */
76#endif
77
78/*****************************************************/
79
80typedef float DBL;
81typedef int F_PT;
82
83/* typedef float F_PT; */
84
85/*****************************************************/
86
87#define FIX 12
88#define UNIT ( 1<<FIX )
89#define MAX_SIMI 6
90
91#define MAX_DEPTH_2 10
92#define MAX_DEPTH_3 6
93#define MAX_DEPTH_4 4
94#define MAX_DEPTH_5 2
95
96/* PREVIOUS VALUE
97#define MAX_SIMI 6
98
99 * settings for a PC 120Mhz... *
100#define MAX_DEPTH_2 10
101#define MAX_DEPTH_3 6
102#define MAX_DEPTH_4 4
103#define MAX_DEPTH_5 3
104*/
105
106#define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) )
107
108typedef struct Similitude_Struct SIMI;
109typedef struct Fractal_Struct FRACTAL;
110
111struct Similitude_Struct
112{
113
114 DBL c_x, c_y;
115 DBL r, r2, A, A2;
116 F_PT Ct, St, Ct2, St2;
117 F_PT Cx, Cy;
118 F_PT R, R2;
119};
120
121
122struct Fractal_Struct
123{
124
125 int Nb_Simi;
126 SIMI Components[5 * MAX_SIMI];
127 int Depth, Col;
128 int Count, Speed;
129 int Width, Height, Lx, Ly;
130 DBL r_mean, dr_mean, dr2_mean;
131 int Cur_Pt, Max_Pt;
132
133 IFSPoint *Buffer1, *Buffer2;
134};
135
136typedef struct _IFS_DATA
137{
138 FRACTAL *Root;
139 FRACTAL *Cur_F;
140
141 /* Used by the Trace recursive method */
142 IFSPoint *Buf;
143 int Cur_Pt;
144 int initalized;
145} IfsData;
146
147
148/*****************************************************/
149
150static DBL
151Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
152{
153 DBL y;
154
155 y = (DBL) LRAND () / MAXRAND;
156 y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
157 if (NRAND (2))
158 return (c + y);
159 return (c - y);
160}
161
162static DBL
163Half_Gauss_Rand (PluginInfo * goomInfo, DBL c, DBL A, DBL S)
164{
165 DBL y;
166
167 y = (DBL) LRAND () / MAXRAND;
168 y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S));
169 return (c + y);
170}
171
172static void
173Random_Simis (PluginInfo * goomInfo, FRACTAL * F, SIMI * Cur, int i)
174{
175 while (i--) {
176 Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
177 Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0);
178 Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0);
179 Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0);
David Schleef7b898172010-12-30 14:20:52 -0800180 Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_PI / 180.0);
181 Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (G_PI / 180.0);
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000182 Cur++;
183 }
184}
185
186static void
187free_ifs_buffers (FRACTAL * Fractal)
188{
189 if (Fractal->Buffer1 != NULL) {
190 (void) free ((void *) Fractal->Buffer1);
191 Fractal->Buffer1 = (IFSPoint *) NULL;
192 }
193 if (Fractal->Buffer2 != NULL) {
194 (void) free ((void *) Fractal->Buffer2);
195 Fractal->Buffer2 = (IFSPoint *) NULL;
196 }
197}
198
199
200static void
201free_ifs (FRACTAL * Fractal)
202{
203 free_ifs_buffers (Fractal);
204}
205
206/***************************************************************/
207
208static void
209init_ifs (PluginInfo * goomInfo, IfsData * data)
210{
211 int i;
212 FRACTAL *Fractal;
213 int width = goomInfo->screen.width;
214 int height = goomInfo->screen.height;
215
216 if (data->Root == NULL) {
217 data->Root = (FRACTAL *) malloc (sizeof (FRACTAL));
218 if (data->Root == NULL)
219 return;
220 data->Root->Buffer1 = (IFSPoint *) NULL;
221 data->Root->Buffer2 = (IFSPoint *) NULL;
222 }
223 Fractal = data->Root;
224
225 free_ifs_buffers (Fractal);
226
227 i = (NRAND (4)) + 2; /* Number of centers */
228 switch (i) {
229 case 3:
230 Fractal->Depth = MAX_DEPTH_3;
231 Fractal->r_mean = .6;
232 Fractal->dr_mean = .4;
233 Fractal->dr2_mean = .3;
234 break;
235
236 case 4:
237 Fractal->Depth = MAX_DEPTH_4;
238 Fractal->r_mean = .5;
239 Fractal->dr_mean = .4;
240 Fractal->dr2_mean = .3;
241 break;
242
243 case 5:
244 Fractal->Depth = MAX_DEPTH_5;
245 Fractal->r_mean = .5;
246 Fractal->dr_mean = .4;
247 Fractal->dr2_mean = .3;
248 break;
249
250 default:
251 case 2:
252 Fractal->Depth = MAX_DEPTH_2;
253 Fractal->r_mean = .7;
254 Fractal->dr_mean = .3;
255 Fractal->dr2_mean = .4;
256 break;
257 }
258 Fractal->Nb_Simi = i;
259 Fractal->Max_Pt = Fractal->Nb_Simi - 1;
260 for (i = 0; i <= Fractal->Depth + 2; ++i)
261 Fractal->Max_Pt *= Fractal->Nb_Simi;
262
263 if ((Fractal->Buffer1 = (IFSPoint *) calloc (Fractal->Max_Pt,
264 sizeof (IFSPoint))) == NULL) {
265 free_ifs (Fractal);
266 return;
267 }
268 if ((Fractal->Buffer2 = (IFSPoint *) calloc (Fractal->Max_Pt,
269 sizeof (IFSPoint))) == NULL) {
270 free_ifs (Fractal);
271 return;
272 }
273
274 Fractal->Speed = 6;
275 Fractal->Width = width; /* modif by JeKo */
276 Fractal->Height = height; /* modif by JeKo */
277 Fractal->Cur_Pt = 0;
278 Fractal->Count = 0;
279 Fractal->Lx = (Fractal->Width - 1) / 2;
280 Fractal->Ly = (Fractal->Height - 1) / 2;
281 Fractal->Col = rand () % (width * height); /* modif by JeKo */
282
283 Random_Simis (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI);
284}
285
286
287/***************************************************************/
288
289static inline void
290Transform (SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y)
291{
292 F_PT xx, yy;
293
294 xo = xo - Simi->Cx;
295 xo = (xo * Simi->R) >> FIX; /* / UNIT; */
296 yo = yo - Simi->Cy;
297 yo = (yo * Simi->R) >> FIX; /* / UNIT; */
298
299 xx = xo - Simi->Cx;
300 xx = (xx * Simi->R2) >> FIX; /* / UNIT; */
301 yy = -yo - Simi->Cy;
302 yy = (yy * Simi->R2) >> FIX; /* / UNIT; */
303
304 *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2)
305 >> FIX /* / UNIT */ ) + Simi->Cx;
306 *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2)
307 >> FIX /* / UNIT */ ) + Simi->Cy;
308}
309
310/***************************************************************/
311
312static void
313Trace (FRACTAL * F, F_PT xo, F_PT yo, IfsData * data)
314{
315 F_PT x, y, i;
316 SIMI *Cur;
317
318 Cur = data->Cur_F->Components;
319 for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) {
320 Transform (Cur, xo, yo, &x, &y);
321
322 data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX + 1) /* /(UNIT*2) */ );
323 data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX + 1) /* /(UNIT*2) */ );
324 data->Buf++;
325
326 data->Cur_Pt++;
327
328 if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) {
329 F->Depth--;
330 Trace (F, x, y, data);
331 F->Depth++;
332 }
333 }
334}
335
336static void
337Draw_Fractal (IfsData * data)
338{
339 FRACTAL *F = data->Root;
340 int i, j;
341 F_PT x, y, xo, yo;
342 SIMI *Cur, *Simi;
343
344 for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
345 Cur->Cx = DBL_To_F_PT (Cur->c_x);
346 Cur->Cy = DBL_To_F_PT (Cur->c_y);
347
348 Cur->Ct = DBL_To_F_PT (cos (Cur->A));
349 Cur->St = DBL_To_F_PT (sin (Cur->A));
350 Cur->Ct2 = DBL_To_F_PT (cos (Cur->A2));
351 Cur->St2 = DBL_To_F_PT (sin (Cur->A2));
352
353 Cur->R = DBL_To_F_PT (Cur->r);
354 Cur->R2 = DBL_To_F_PT (Cur->r2);
355 }
356
357
358 data->Cur_Pt = 0;
359 data->Cur_F = F;
360 data->Buf = F->Buffer2;
361 for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) {
362 xo = Cur->Cx;
363 yo = Cur->Cy;
364 for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) {
365 if (Simi == Cur)
366 continue;
367 Transform (Simi, xo, yo, &x, &y);
368 Trace (F, x, y, data);
369 }
370 }
371
372 /* Erase previous */
373
374 F->Cur_Pt = data->Cur_Pt;
375 data->Buf = F->Buffer1;
376 F->Buffer1 = F->Buffer2;
377 F->Buffer2 = data->Buf;
378}
379
380
381static IFSPoint *
382draw_ifs (PluginInfo * goomInfo, int *nbpt, IfsData * data)
383{
384 int i;
385 DBL u, uu, v, vv, u0, u1, u2, u3;
386 SIMI *S, *S1, *S2, *S3, *S4;
387 FRACTAL *F;
388
389 if (data->Root == NULL)
390 return NULL;
391 F = data->Root;
392 if (F->Buffer1 == NULL)
393 return NULL;
394
395 u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0;
396 uu = u * u;
397 v = 1.0 - u;
398 vv = v * v;
399 u0 = vv * v;
400 u1 = 3.0 * vv * u;
401 u2 = 3.0 * v * uu;
402 u3 = u * uu;
403
404 S = F->Components;
405 S1 = S + F->Nb_Simi;
406 S2 = S1 + F->Nb_Simi;
407 S3 = S2 + F->Nb_Simi;
408 S4 = S3 + F->Nb_Simi;
409
410 for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
411 S->c_x = u0 * S1->c_x + u1 * S2->c_x + u2 * S3->c_x + u3 * S4->c_x;
412 S->c_y = u0 * S1->c_y + u1 * S2->c_y + u2 * S3->c_y + u3 * S4->c_y;
413 S->r = u0 * S1->r + u1 * S2->r + u2 * S3->r + u3 * S4->r;
414 S->r2 = u0 * S1->r2 + u1 * S2->r2 + u2 * S3->r2 + u3 * S4->r2;
415 S->A = u0 * S1->A + u1 * S2->A + u2 * S3->A + u3 * S4->A;
416 S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2;
417 }
418
419 Draw_Fractal (data);
420
421 if (F->Count >= 1000 / F->Speed) {
422 S = F->Components;
423 S1 = S + F->Nb_Simi;
424 S2 = S1 + F->Nb_Simi;
425 S3 = S2 + F->Nb_Simi;
426 S4 = S3 + F->Nb_Simi;
427
428 for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) {
429 S2->c_x = 2.0 * S4->c_x - S3->c_x;
430 S2->c_y = 2.0 * S4->c_y - S3->c_y;
431 S2->r = 2.0 * S4->r - S3->r;
432 S2->r2 = 2.0 * S4->r2 - S3->r2;
433 S2->A = 2.0 * S4->A - S3->A;
434 S2->A2 = 2.0 * S4->A2 - S3->A2;
435
436 *S1 = *S4;
437 }
438 Random_Simis (goomInfo, F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi);
439
440 Random_Simis (goomInfo, F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi);
441
442 F->Count = 0;
443 } else
444 F->Count++;
445
446 F->Col++;
447
448 (*nbpt) = data->Cur_Pt;
449 return F->Buffer2;
450}
451
452
453/***************************************************************/
454
455static void
456release_ifs (IfsData * data)
457{
458 if (data->Root != NULL) {
459 free_ifs (data->Root);
460 (void) free ((void *) data->Root);
461 data->Root = (FRACTAL *) NULL;
462 }
463}
464
465#define RAND() goom_random(goomInfo->gRandom)
466
467static void
468ifs_update (PluginInfo * goomInfo, Pixel * data, Pixel * back, int increment,
469 IfsData * fx_data)
470{
Jan Schmidtc34fa142008-02-26 10:09:38 +0000471 static unsigned int couleur = 0xc0c0c0c0;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000472 static int v[4] = { 2, 4, 3, 2 };
473 static int col[4] = { 2, 4, 3, 2 };
474
475#define MOD_MER 0
476#define MOD_FEU 1
477#define MOD_MERVER 2
478 static int mode = MOD_MERVER;
479 static int justChanged = 0;
480 static int cycle = 0;
481 int cycle10;
482
Bastien Nocerae8ef50a2008-02-23 02:38:03 +0000483 int nbpt = 0;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000484 IFSPoint *points;
485 int i;
486
Jan Schmidtc34fa142008-02-26 10:09:38 +0000487 unsigned int couleursl = couleur;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000488 int width = goomInfo->screen.width;
489 int height = goomInfo->screen.height;
490
491 cycle++;
492 if (cycle >= 80)
493 cycle = 0;
494
495 if (cycle < 40)
496 cycle10 = cycle / 10;
497 else
498 cycle10 = 7 - cycle / 10;
499
500 {
501 unsigned char *tmp = (unsigned char *) &couleursl;
502
503 for (i = 0; i < 4; i++) {
504 *tmp = (*tmp) >> cycle10;
505 tmp++;
506 }
507 }
508
509 points = draw_ifs (goomInfo, &nbpt, fx_data);
510 nbpt--;
511
512#ifdef HAVE_MMX
513 movd_m2r (couleursl, mm1);
514 punpckldq_r2r (mm1, mm1);
515 for (i = 0; i < nbpt; i += increment) {
516 int x = points[i].x;
517 int y = points[i].y;
518
519 if ((x < width) && (y < height) && (x > 0) && (y > 0)) {
520 int pos = x + (y * width);
521
522 movd_m2r (back[pos], mm0);
523 paddusb_r2r (mm1, mm0);
524 movd_r2m (mm0, data[pos]);
525 }
526 }
527 emms (); /*__asm__ __volatile__ ("emms");*/
528#else
529 for (i = 0; i < nbpt; i += increment) {
530 int x = (int) points[i].x & 0x7fffffff;
531 int y = (int) points[i].y & 0x7fffffff;
532
533 if ((x < width) && (y < height)) {
534 int pos = x + (int) (y * width);
535 int tra = 0, i = 0;
536 unsigned char *bra = (unsigned char *) &back[pos];
537 unsigned char *dra = (unsigned char *) &data[pos];
538 unsigned char *cra = (unsigned char *) &couleursl;
539
540 for (; i < 4; i++) {
541 tra = *cra;
542 tra += *bra;
543 if (tra > 255)
544 tra = 255;
545 *dra = tra;
546 ++dra;
547 ++cra;
548 ++bra;
549 }
550 }
551 }
552#endif /*MMX*/
553 justChanged--;
554
555 col[ALPHA] = couleur >> (ALPHA * 8) & 0xff;
556 col[BLEU] = couleur >> (BLEU * 8) & 0xff;
557 col[VERT] = couleur >> (VERT * 8) & 0xff;
558 col[ROUGE] = couleur >> (ROUGE * 8) & 0xff;
559
560 if (mode == MOD_MER) {
561 col[BLEU] += v[BLEU];
562 if (col[BLEU] > 255) {
563 col[BLEU] = 255;
564 v[BLEU] = -(RAND () % 4) - 1;
565 }
566 if (col[BLEU] < 32) {
567 col[BLEU] = 32;
568 v[BLEU] = (RAND () % 4) + 1;
569 }
570
571 col[VERT] += v[VERT];
572 if (col[VERT] > 200) {
573 col[VERT] = 200;
574 v[VERT] = -(RAND () % 3) - 2;
575 }
576 if (col[VERT] > col[BLEU]) {
577 col[VERT] = col[BLEU];
578 v[VERT] = v[BLEU];
579 }
580 if (col[VERT] < 32) {
581 col[VERT] = 32;
582 v[VERT] = (RAND () % 3) + 2;
583 }
584
585 col[ROUGE] += v[ROUGE];
586 if (col[ROUGE] > 64) {
587 col[ROUGE] = 64;
588 v[ROUGE] = -(RAND () % 4) - 1;
589 }
590 if (col[ROUGE] < 0) {
591 col[ROUGE] = 0;
592 v[ROUGE] = (RAND () % 4) + 1;
593 }
594
595 col[ALPHA] += v[ALPHA];
596 if (col[ALPHA] > 0) {
597 col[ALPHA] = 0;
598 v[ALPHA] = -(RAND () % 4) - 1;
599 }
600 if (col[ALPHA] < 0) {
601 col[ALPHA] = 0;
602 v[ALPHA] = (RAND () % 4) + 1;
603 }
604
605 if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
606 && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
607 && (RAND () % 20 == 0)) && (justChanged < 0)) {
Sanjay NM36140cc2014-09-18 17:08:37 +0530608 mode = (RAND () % 3) ? MOD_FEU : MOD_MERVER;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000609 justChanged = 250;
610 }
611 } else if (mode == MOD_MERVER) {
612 col[BLEU] += v[BLEU];
613 if (col[BLEU] > 128) {
614 col[BLEU] = 128;
615 v[BLEU] = -(RAND () % 4) - 1;
616 }
617 if (col[BLEU] < 16) {
618 col[BLEU] = 16;
619 v[BLEU] = (RAND () % 4) + 1;
620 }
621
622 col[VERT] += v[VERT];
623 if (col[VERT] > 200) {
624 col[VERT] = 200;
625 v[VERT] = -(RAND () % 3) - 2;
626 }
627 if (col[VERT] > col[ALPHA]) {
628 col[VERT] = col[ALPHA];
629 v[VERT] = v[ALPHA];
630 }
631 if (col[VERT] < 32) {
632 col[VERT] = 32;
633 v[VERT] = (RAND () % 3) + 2;
634 }
635
636 col[ROUGE] += v[ROUGE];
637 if (col[ROUGE] > 128) {
638 col[ROUGE] = 128;
639 v[ROUGE] = -(RAND () % 4) - 1;
640 }
641 if (col[ROUGE] < 0) {
642 col[ROUGE] = 0;
643 v[ROUGE] = (RAND () % 4) + 1;
644 }
645
646 col[ALPHA] += v[ALPHA];
647 if (col[ALPHA] > 255) {
648 col[ALPHA] = 255;
649 v[ALPHA] = -(RAND () % 4) - 1;
650 }
651 if (col[ALPHA] < 0) {
652 col[ALPHA] = 0;
653 v[ALPHA] = (RAND () % 4) + 1;
654 }
655
656 if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40)
657 && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64)
658 && (RAND () % 20 == 0)) && (justChanged < 0)) {
Sanjay NM36140cc2014-09-18 17:08:37 +0530659 mode = (RAND () % 3) ? MOD_FEU : MOD_MER;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000660 justChanged = 250;
661 }
662 } else if (mode == MOD_FEU) {
663
664 col[BLEU] += v[BLEU];
665 if (col[BLEU] > 64) {
666 col[BLEU] = 64;
667 v[BLEU] = -(RAND () % 4) - 1;
668 }
669 if (col[BLEU] < 0) {
670 col[BLEU] = 0;
671 v[BLEU] = (RAND () % 4) + 1;
672 }
673
674 col[VERT] += v[VERT];
675 if (col[VERT] > 200) {
676 col[VERT] = 200;
677 v[VERT] = -(RAND () % 3) - 2;
678 }
679 if (col[VERT] > col[ROUGE] + 20) {
680 col[VERT] = col[ROUGE] + 20;
681 v[VERT] = -(RAND () % 3) - 2;
682 v[ROUGE] = (RAND () % 4) + 1;
683 v[BLEU] = (RAND () % 4) + 1;
684 }
685 if (col[VERT] < 0) {
686 col[VERT] = 0;
687 v[VERT] = (RAND () % 3) + 2;
688 }
689
690 col[ROUGE] += v[ROUGE];
691 if (col[ROUGE] > 255) {
692 col[ROUGE] = 255;
693 v[ROUGE] = -(RAND () % 4) - 1;
694 }
695 if (col[ROUGE] > col[VERT] + 40) {
696 col[ROUGE] = col[VERT] + 40;
697 v[ROUGE] = -(RAND () % 4) - 1;
698 }
699 if (col[ROUGE] < 0) {
700 col[ROUGE] = 0;
701 v[ROUGE] = (RAND () % 4) + 1;
702 }
703
704 col[ALPHA] += v[ALPHA];
705 if (col[ALPHA] > 0) {
706 col[ALPHA] = 0;
707 v[ALPHA] = -(RAND () % 4) - 1;
708 }
709 if (col[ALPHA] < 0) {
710 col[ALPHA] = 0;
711 v[ALPHA] = (RAND () % 4) + 1;
712 }
713
714 if (((col[ROUGE] < 64) && (col[VERT] > 32) && (col[VERT] < col[BLEU])
715 && (col[BLEU] > 32)
716 && (RAND () % 20 == 0)) && (justChanged < 0)) {
Sanjay NM36140cc2014-09-18 17:08:37 +0530717 mode = (RAND () % 2) ? MOD_MER : MOD_MERVER;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000718 justChanged = 250;
719 }
720 }
721
722 couleur = (col[ALPHA] << (ALPHA * 8))
723 | (col[BLEU] << (BLEU * 8))
724 | (col[VERT] << (VERT * 8))
725 | (col[ROUGE] << (ROUGE * 8));
726}
727
728/** VISUAL_FX WRAPPER FOR IFS */
729
730static void
731ifs_vfx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
732 PluginInfo * goomInfo)
733{
734
735 IfsData *data = (IfsData *) _this->fx_data;
736
737 if (!data->initalized) {
738 data->initalized = 1;
739 init_ifs (goomInfo, data);
740 }
741 ifs_update (goomInfo, dest, src, goomInfo->update.ifs_incr, data);
742 /*TODO: trouver meilleur soluce pour increment (mettre le code de gestion de l'ifs dans ce fichier: ifs_vfx_apply) */
743}
744
745static void
746ifs_vfx_init (VisualFX * _this, PluginInfo * info)
747{
748
749 IfsData *data = (IfsData *) malloc (sizeof (IfsData));
750
751 data->Root = (FRACTAL *) NULL;
752 data->initalized = 0;
753 _this->fx_data = data;
754}
755
756static void
757ifs_vfx_free (VisualFX * _this)
758{
759 IfsData *data = (IfsData *) _this->fx_data;
760
761 release_ifs (data);
762 free (data);
763}
764
Benjamin Ottec2846f62010-03-21 17:23:43 +0100765void
766ifs_visualfx_create (VisualFX * vfx)
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000767{
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000768
Benjamin Ottec2846f62010-03-21 17:23:43 +0100769 vfx->init = ifs_vfx_init;
770 vfx->free = ifs_vfx_free;
771 vfx->apply = ifs_vfx_apply;
772 vfx->fx_data = NULL;
773 vfx->params = NULL;
Bastien Noceraa7bc7482008-02-23 01:51:37 +0000774}