/xbmc/visualizations/Goom/goom2k4-0/src/ifs.c

http://github.com/xbmc/xbmc · C · 763 lines · 582 code · 128 blank · 53 comment · 105 complexity · b556e953f921192dff125eb2780725d5 MD5 · raw file

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