Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 1 | /*- |
| 2 | * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr> |
| 3 | * |
Stefan Kost | 6eb6d5b | 2008-10-28 06:50:57 +0000 | [diff] [blame] | 4 | * ifs.c: modified iterated functions system for goom. |
| 5 | * |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 6 | * 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 | |
| 48 | typedef struct _ifsPoint |
| 49 | { |
| 50 | gint32 x, y; |
| 51 | } |
| 52 | IFSPoint; |
| 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 | |
| 80 | typedef float DBL; |
| 81 | typedef 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 | |
| 108 | typedef struct Similitude_Struct SIMI; |
| 109 | typedef struct Fractal_Struct FRACTAL; |
| 110 | |
| 111 | struct 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 | |
| 122 | struct 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 | |
| 136 | typedef 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 | |
| 150 | static DBL |
| 151 | Gauss_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 | |
| 162 | static DBL |
| 163 | Half_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 | |
| 172 | static void |
| 173 | Random_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 Schleef | 7b89817 | 2010-12-30 14:20:52 -0800 | [diff] [blame] | 180 | 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 Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 182 | Cur++; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | static void |
| 187 | free_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 | |
| 200 | static void |
| 201 | free_ifs (FRACTAL * Fractal) |
| 202 | { |
| 203 | free_ifs_buffers (Fractal); |
| 204 | } |
| 205 | |
| 206 | /***************************************************************/ |
| 207 | |
| 208 | static void |
| 209 | init_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 | |
| 289 | static inline void |
| 290 | Transform (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 | |
| 312 | static void |
| 313 | Trace (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 | |
| 336 | static void |
| 337 | Draw_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 | |
| 381 | static IFSPoint * |
| 382 | draw_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 | |
| 455 | static void |
| 456 | release_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 | |
| 467 | static void |
| 468 | ifs_update (PluginInfo * goomInfo, Pixel * data, Pixel * back, int increment, |
| 469 | IfsData * fx_data) |
| 470 | { |
Jan Schmidt | c34fa14 | 2008-02-26 10:09:38 +0000 | [diff] [blame] | 471 | static unsigned int couleur = 0xc0c0c0c0; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 472 | 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 Nocera | e8ef50a | 2008-02-23 02:38:03 +0000 | [diff] [blame] | 483 | int nbpt = 0; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 484 | IFSPoint *points; |
| 485 | int i; |
| 486 | |
Jan Schmidt | c34fa14 | 2008-02-26 10:09:38 +0000 | [diff] [blame] | 487 | unsigned int couleursl = couleur; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 488 | 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 NM | 36140cc | 2014-09-18 17:08:37 +0530 | [diff] [blame] | 608 | mode = (RAND () % 3) ? MOD_FEU : MOD_MERVER; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 609 | 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 NM | 36140cc | 2014-09-18 17:08:37 +0530 | [diff] [blame] | 659 | mode = (RAND () % 3) ? MOD_FEU : MOD_MER; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 660 | 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 NM | 36140cc | 2014-09-18 17:08:37 +0530 | [diff] [blame] | 717 | mode = (RAND () % 2) ? MOD_MER : MOD_MERVER; |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 718 | 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 | |
| 730 | static void |
| 731 | ifs_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 | |
| 745 | static void |
| 746 | ifs_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 | |
| 756 | static void |
| 757 | ifs_vfx_free (VisualFX * _this) |
| 758 | { |
| 759 | IfsData *data = (IfsData *) _this->fx_data; |
| 760 | |
| 761 | release_ifs (data); |
| 762 | free (data); |
| 763 | } |
| 764 | |
Benjamin Otte | c2846f6 | 2010-03-21 17:23:43 +0100 | [diff] [blame] | 765 | void |
| 766 | ifs_visualfx_create (VisualFX * vfx) |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 767 | { |
Bastien Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 768 | |
Benjamin Otte | c2846f6 | 2010-03-21 17:23:43 +0100 | [diff] [blame] | 769 | 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 Nocera | a7bc748 | 2008-02-23 01:51:37 +0000 | [diff] [blame] | 774 | } |