1 /* Goom Project
2 * Copyright (C) <2003> Jean-Christophe Hoelt <jeko@free.fr>
3 *
4 * goom_core.c:Contains the core of goom's work.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #ifdef HAVE_INTTYPES_H
32 #include <inttypes.h>
33 #endif
34
35 #include "goom.h"
36 #include "goom_tools.h"
37 #include "goom_filters.h"
38 #include "lines.h"
39 #include "ifs.h"
40 #include "tentacle3d.h"
41
42 #include "sound_tester.h"
43 #include "goom_plugin_info.h"
44 #include "goom_fx.h"
45
46 /* #define VERBOSE */
47
48 #define STOP_SPEED 128
49 /* TODO: put that as variable in PluginInfo */
50 #define TIME_BTW_CHG 300
51
52 static void choose_a_goom_line (PluginInfo * goomInfo, float *param1,
53 float *param2, int *couleur, int *mode, float *amplitude, int far);
54
55 static void
init_buffers(PluginInfo * goomInfo,int buffsize)56 init_buffers (PluginInfo * goomInfo, int buffsize)
57 {
58 goomInfo->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
59 memset (goomInfo->pixel, 0, buffsize * sizeof (guint32) + 128);
60 goomInfo->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128);
61 memset (goomInfo->back, 0, buffsize * sizeof (guint32) + 128);
62 goomInfo->conv = (Pixel *) malloc (buffsize * sizeof (guint32) + 128);
63 memset (goomInfo->conv, 0, buffsize * sizeof (guint32) + 128);
64
65 goomInfo->outputBuf = goomInfo->conv;
66
67 goomInfo->p1 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->pixel)) / 128) * 128);
68 goomInfo->p2 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->back)) / 128) * 128);
69 }
70
71 /**************************
72 * INIT *
73 **************************/
74 PluginInfo *
goom_init(guint32 resx,guint32 resy)75 goom_init (guint32 resx, guint32 resy)
76 {
77 PluginInfo *goomInfo = (PluginInfo *) malloc (sizeof (PluginInfo));
78
79 #ifdef VERBOSE
80 printf ("GOOM: init (%d, %d);\n", resx, resy);
81 #endif
82
83 plugin_info_init (goomInfo, 4);
84
85 goomInfo->screen.width = resx;
86 goomInfo->screen.height = resy;
87 goomInfo->screen.size = resx * resy;
88
89 init_buffers (goomInfo, goomInfo->screen.size);
90 goomInfo->gRandom = goom_random_init ((uintptr_t) goomInfo->pixel);
91
92 goomInfo->cycle = 0;
93
94 flying_star_create (&goomInfo->star_fx);
95 goomInfo->star_fx.init (&goomInfo->star_fx, goomInfo);
96
97 zoomFilterVisualFXWrapper_create (&goomInfo->zoomFilter_fx);
98 goomInfo->zoomFilter_fx.init (&goomInfo->zoomFilter_fx, goomInfo);
99
100 tentacle_fx_create (&goomInfo->tentacles_fx);
101 goomInfo->tentacles_fx.init (&goomInfo->tentacles_fx, goomInfo);
102
103 convolve_create (&goomInfo->convolve_fx);
104 goomInfo->convolve_fx.init (&goomInfo->convolve_fx, goomInfo);
105
106 plugin_info_add_visual (goomInfo, 0, &goomInfo->zoomFilter_fx);
107 plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx);
108 plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx);
109 plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx);
110
111 ifs_visualfx_create (&goomInfo->ifs_fx);
112 goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
113
114 goomInfo->gmline1 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
115 GML_HLINE, goomInfo->screen.height, GML_BLACK,
116 GML_CIRCLE, 0.4f * (float) goomInfo->screen.height, GML_VERT);
117 goomInfo->gmline2 = goom_lines_init (goomInfo, resx, goomInfo->screen.height,
118 GML_HLINE, 0, GML_BLACK,
119 GML_CIRCLE, 0.2f * (float) goomInfo->screen.height, GML_RED);
120
121 /* goom_set_main_script(goomInfo, goomInfo->main_script_str); */
122
123 return goomInfo;
124 }
125
126
127
128 void
goom_set_resolution(PluginInfo * goomInfo,guint32 resx,guint32 resy)129 goom_set_resolution (PluginInfo * goomInfo, guint32 resx, guint32 resy)
130 {
131 free (goomInfo->pixel);
132 free (goomInfo->back);
133 free (goomInfo->conv);
134
135 goomInfo->screen.width = resx;
136 goomInfo->screen.height = resy;
137 goomInfo->screen.size = resx * resy;
138
139 init_buffers (goomInfo, goomInfo->screen.size);
140
141 /* init_ifs (goomInfo, resx, goomInfo->screen.height); */
142 goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
143 goomInfo->ifs_fx.init (&goomInfo->ifs_fx, goomInfo);
144
145 goom_lines_set_res (goomInfo->gmline1, resx, goomInfo->screen.height);
146 goom_lines_set_res (goomInfo->gmline2, resx, goomInfo->screen.height);
147 }
148
149 int
goom_set_screenbuffer(PluginInfo * goomInfo,void * buffer)150 goom_set_screenbuffer (PluginInfo * goomInfo, void *buffer)
151 {
152 goomInfo->outputBuf = (Pixel *) buffer;
153 return 1;
154 }
155
156 /********************************************
157 * UPDATE *
158 ********************************************
159
160 * WARNING: this is a 600 lines function ! (21-11-2003)
161 */
162 guint32 *
goom_update(PluginInfo * goomInfo,gint16 data[2][512],int forceMode,float fps)163 goom_update (PluginInfo * goomInfo, gint16 data[2][512], int forceMode,
164 float fps)
165 {
166 Pixel *return_val;
167 guint32 pointWidth;
168 guint32 pointHeight;
169 int i;
170 float largfactor; /* elargissement de l'intervalle d'�volution des points */
171 Pixel *tmp;
172
173 ZoomFilterData *pzfd;
174
175 /* test if the config has changed, update it if so */
176 pointWidth = (goomInfo->screen.width * 2) / 5;
177 pointHeight = ((goomInfo->screen.height) * 2) / 5;
178
179 /* ! etude du signal ... */
180 evaluate_sound (data, &(goomInfo->sound));
181
182 /* goom_execute_main_script(goomInfo); */
183
184 /* ! calcul du deplacement des petits points ... */
185 largfactor =
186 goomInfo->sound.speedvar / 150.0f + goomInfo->sound.volume / 1.5f;
187
188 if (largfactor > 1.5f)
189 largfactor = 1.5f;
190
191 goomInfo->update.decay_ifs--;
192 if (goomInfo->update.decay_ifs > 0)
193 goomInfo->update.ifs_incr += 2;
194 if (goomInfo->update.decay_ifs == 0)
195 goomInfo->update.ifs_incr = 0;
196
197 if (goomInfo->update.recay_ifs) {
198 goomInfo->update.ifs_incr -= 2;
199 goomInfo->update.recay_ifs--;
200 if ((goomInfo->update.recay_ifs == 0) && (goomInfo->update.ifs_incr <= 0))
201 goomInfo->update.ifs_incr = 1;
202 }
203
204 if (goomInfo->update.ifs_incr > 0)
205 goomInfo->ifs_fx.apply (&goomInfo->ifs_fx, goomInfo->p2, goomInfo->p1,
206 goomInfo);
207
208 if (goomInfo->curGState->drawPoints) {
209 for (i = 1; i * 15 <= goomInfo->sound.speedvar * 80.0f + 15; i++) {
210 goomInfo->update.loopvar += goomInfo->sound.speedvar * 50 + 1;
211
212 pointFilter (goomInfo, goomInfo->p1,
213 YELLOW,
214 ((pointWidth - 6.0f) * largfactor + 5.0f),
215 ((pointHeight - 6.0f) * largfactor + 5.0f),
216 i * 152.0f, 128.0f, goomInfo->update.loopvar + i * 2032);
217 pointFilter (goomInfo, goomInfo->p1, ORANGE,
218 ((pointWidth / 2) * largfactor) / i + 10.0f * i,
219 ((pointHeight / 2) * largfactor) / i + 10.0f * i,
220 96.0f, i * 80.0f, goomInfo->update.loopvar / i);
221 pointFilter (goomInfo, goomInfo->p1, VIOLET,
222 ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
223 ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i,
224 i + 122.0f, 134.0f, goomInfo->update.loopvar / i);
225 pointFilter (goomInfo, goomInfo->p1, BLACK,
226 ((pointHeight / 3) * largfactor + 20.0f),
227 ((pointHeight / 3) * largfactor + 20.0f),
228 58.0f, i * 66.0f, goomInfo->update.loopvar / i);
229 pointFilter (goomInfo, goomInfo->p1, WHITE,
230 (pointHeight * largfactor + 10.0f * i) / i,
231 (pointHeight * largfactor + 10.0f * i) / i,
232 66.0f, 74.0f, goomInfo->update.loopvar + i * 500);
233 }
234 }
235
236 /* par d�faut pas de changement de zoom */
237 pzfd = NULL;
238
239 /*
240 * Test forceMode
241 */
242 #ifdef VERBOSE
243 if (forceMode != 0) {
244 printf ("forcemode = %d\n", forceMode);
245 }
246 #endif
247
248
249 /* diminuer de 1 le temps de lockage */
250 /* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */
251 /* changement d'etat du plugin juste apres un autre changement d'etat. oki */
252 if (--goomInfo->update.lockvar < 0)
253 goomInfo->update.lockvar = 0;
254
255 /* on verifie qu'il ne se pas un truc interressant avec le son. */
256 if ((goomInfo->sound.timeSinceLastGoom == 0)
257 || (forceMode > 0)
258 || (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG)) {
259
260 /* changement eventuel de mode */
261 if (goom_irand (goomInfo->gRandom, 16) == 0)
262 switch (goom_irand (goomInfo->gRandom, 34)) {
263 case 0:
264 case 10:
265 goomInfo->update.zoomFilterData.hypercosEffect =
266 goom_irand (goomInfo->gRandom, 2);
267 case 13:
268 case 20:
269 case 21:
270 goomInfo->update.zoomFilterData.mode = WAVE_MODE;
271 goomInfo->update.zoomFilterData.reverse = 0;
272 goomInfo->update.zoomFilterData.waveEffect =
273 (goom_irand (goomInfo->gRandom, 3) == 0);
274 if (goom_irand (goomInfo->gRandom, 2))
275 goomInfo->update.zoomFilterData.vitesse =
276 (goomInfo->update.zoomFilterData.vitesse + 127) >> 1;
277 break;
278 case 1:
279 case 11:
280 goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
281 goomInfo->update.zoomFilterData.waveEffect = 0;
282 goomInfo->update.zoomFilterData.hypercosEffect = 0;
283 break;
284 case 2:
285 case 12:
286 goomInfo->update.zoomFilterData.mode = AMULETTE_MODE;
287 goomInfo->update.zoomFilterData.waveEffect = 0;
288 goomInfo->update.zoomFilterData.hypercosEffect = 0;
289 break;
290 case 3:
291 goomInfo->update.zoomFilterData.mode = WATER_MODE;
292 goomInfo->update.zoomFilterData.waveEffect = 0;
293 goomInfo->update.zoomFilterData.hypercosEffect = 0;
294 break;
295 case 4:
296 case 14:
297 goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
298 goomInfo->update.zoomFilterData.waveEffect = 0;
299 goomInfo->update.zoomFilterData.hypercosEffect = 0;
300 break;
301 case 5:
302 case 15:
303 case 22:
304 goomInfo->update.zoomFilterData.mode = HYPERCOS1_MODE;
305 goomInfo->update.zoomFilterData.waveEffect = 0;
306 goomInfo->update.zoomFilterData.hypercosEffect =
307 (goom_irand (goomInfo->gRandom, 3) == 0);
308 break;
309 case 6:
310 case 16:
311 goomInfo->update.zoomFilterData.mode = HYPERCOS2_MODE;
312 goomInfo->update.zoomFilterData.waveEffect = 0;
313 goomInfo->update.zoomFilterData.hypercosEffect = 0;
314 break;
315 case 7:
316 case 17:
317 goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE;
318 goomInfo->update.zoomFilterData.waveEffect =
319 (goom_irand (goomInfo->gRandom, 4) == 0);
320 goomInfo->update.zoomFilterData.hypercosEffect =
321 goom_irand (goomInfo->gRandom, 2);
322 break;
323 case 8:
324 case 18:
325 case 19:
326 goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE;
327 goomInfo->update.zoomFilterData.waveEffect = 1;
328 goomInfo->update.zoomFilterData.hypercosEffect = 1;
329 break;
330 case 29:
331 case 30:
332 goomInfo->update.zoomFilterData.mode = YONLY_MODE;
333 break;
334 case 31:
335 case 32:
336 case 33:
337 goomInfo->update.zoomFilterData.mode = SPEEDWAY_MODE;
338 break;
339 default:
340 goomInfo->update.zoomFilterData.mode = NORMAL_MODE;
341 goomInfo->update.zoomFilterData.waveEffect = 0;
342 goomInfo->update.zoomFilterData.hypercosEffect = 0;
343 }
344 }
345
346 /* tout ceci ne sera fait qu'en cas de non-blocage */
347 if (goomInfo->update.lockvar == 0) {
348 /* reperage de goom (acceleration forte de l'acceleration du volume) */
349 /* -> coup de boost de la vitesse si besoin.. */
350 if (goomInfo->sound.timeSinceLastGoom == 0) {
351
352 int i;
353
354 goomInfo->update.goomvar++;
355
356 /* SELECTION OF THE GOOM STATE */
357 if ((!goomInfo->update.stateSelectionBlocker)
358 && (goom_irand (goomInfo->gRandom, 3))) {
359 goomInfo->update.stateSelectionRnd =
360 goom_irand (goomInfo->gRandom, goomInfo->statesRangeMax);
361 goomInfo->update.stateSelectionBlocker = 3;
362 } else if (goomInfo->update.stateSelectionBlocker)
363 goomInfo->update.stateSelectionBlocker--;
364
365 for (i = 0; i < goomInfo->statesNumber; i++)
366 if ((goomInfo->update.stateSelectionRnd >= goomInfo->states[i].rangemin)
367 && (goomInfo->update.stateSelectionRnd <=
368 goomInfo->states[i].rangemax))
369 goomInfo->curGState = &(goomInfo->states[i]);
370
371 if ((goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr <= 0)) {
372 goomInfo->update.recay_ifs = 5;
373 goomInfo->update.ifs_incr = 11;
374 }
375
376 if ((!goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr > 0)
377 && (goomInfo->update.decay_ifs <= 0))
378 goomInfo->update.decay_ifs = 100;
379
380 if (!goomInfo->curGState->drawScope)
381 goomInfo->update.stop_lines = 0xf000 & 5;
382
383 if (!goomInfo->curGState->drawScope) {
384 goomInfo->update.stop_lines = 0;
385 goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
386 }
387
388 /* if (goomInfo->update.goomvar % 1 == 0) */
389 {
390 guint32 vtmp;
391 guint32 newvit;
392
393 goomInfo->update.lockvar = 50;
394 newvit =
395 STOP_SPEED + 1 -
396 ((float) 3.5f * log10 (goomInfo->sound.speedvar * 60 + 1));
397 /* retablir le zoom avant.. */
398 if ((goomInfo->update.zoomFilterData.reverse)
399 && (!(goomInfo->cycle % 13)) && (rand () % 5 == 0)) {
400 goomInfo->update.zoomFilterData.reverse = 0;
401 goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 2;
402 goomInfo->update.lockvar = 75;
403 }
404 if (goom_irand (goomInfo->gRandom, 10) == 0) {
405 goomInfo->update.zoomFilterData.reverse = 1;
406 goomInfo->update.lockvar = 100;
407 }
408
409 if (goom_irand (goomInfo->gRandom, 10) == 0)
410 goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
411 if (goom_irand (goomInfo->gRandom, 12) == 0)
412 goomInfo->update.zoomFilterData.vitesse = STOP_SPEED + 1;
413
414 /* changement de milieu.. */
415 switch (goom_irand (goomInfo->gRandom, 25)) {
416 case 0:
417 case 3:
418 case 6:
419 goomInfo->update.zoomFilterData.middleY =
420 goomInfo->screen.height - 1;
421 goomInfo->update.zoomFilterData.middleX =
422 goomInfo->screen.width / 2;
423 break;
424 case 1:
425 case 4:
426 goomInfo->update.zoomFilterData.middleX =
427 goomInfo->screen.width - 1;
428 break;
429 case 2:
430 case 5:
431 goomInfo->update.zoomFilterData.middleX = 1;
432 break;
433 default:
434 goomInfo->update.zoomFilterData.middleY =
435 goomInfo->screen.height / 2;
436 goomInfo->update.zoomFilterData.middleX =
437 goomInfo->screen.width / 2;
438 }
439
440 if ((goomInfo->update.zoomFilterData.mode == WATER_MODE)
441 || (goomInfo->update.zoomFilterData.mode == YONLY_MODE)
442 || (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE)) {
443 goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2;
444 goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height / 2;
445 }
446
447 switch (vtmp = (goom_irand (goomInfo->gRandom, 15))) {
448 case 0:
449 goomInfo->update.zoomFilterData.vPlaneEffect =
450 goom_irand (goomInfo->gRandom, 3)
451 - goom_irand (goomInfo->gRandom, 3);
452 goomInfo->update.zoomFilterData.hPlaneEffect =
453 goom_irand (goomInfo->gRandom, 3)
454 - goom_irand (goomInfo->gRandom, 3);
455 break;
456 case 3:
457 goomInfo->update.zoomFilterData.vPlaneEffect = 0;
458 goomInfo->update.zoomFilterData.hPlaneEffect =
459 goom_irand (goomInfo->gRandom, 8)
460 - goom_irand (goomInfo->gRandom, 8);
461 break;
462 case 4:
463 case 5:
464 case 6:
465 case 7:
466 goomInfo->update.zoomFilterData.vPlaneEffect =
467 goom_irand (goomInfo->gRandom, 5)
468 - goom_irand (goomInfo->gRandom, 5);
469 goomInfo->update.zoomFilterData.hPlaneEffect =
470 -goomInfo->update.zoomFilterData.vPlaneEffect;
471 break;
472 case 8:
473 goomInfo->update.zoomFilterData.hPlaneEffect =
474 5 + goom_irand (goomInfo->gRandom, 8);
475 goomInfo->update.zoomFilterData.vPlaneEffect =
476 -goomInfo->update.zoomFilterData.hPlaneEffect;
477 break;
478 case 9:
479 goomInfo->update.zoomFilterData.vPlaneEffect =
480 5 + goom_irand (goomInfo->gRandom, 8);
481 goomInfo->update.zoomFilterData.hPlaneEffect =
482 -goomInfo->update.zoomFilterData.hPlaneEffect;
483 break;
484 case 13:
485 goomInfo->update.zoomFilterData.hPlaneEffect = 0;
486 goomInfo->update.zoomFilterData.vPlaneEffect =
487 goom_irand (goomInfo->gRandom, 10)
488 - goom_irand (goomInfo->gRandom, 10);
489 break;
490 case 14:
491 goomInfo->update.zoomFilterData.hPlaneEffect =
492 goom_irand (goomInfo->gRandom, 10)
493 - goom_irand (goomInfo->gRandom, 10);
494 goomInfo->update.zoomFilterData.vPlaneEffect =
495 goom_irand (goomInfo->gRandom, 10)
496 - goom_irand (goomInfo->gRandom, 10);
497 break;
498 default:
499 if (vtmp < 10) {
500 goomInfo->update.zoomFilterData.vPlaneEffect = 0;
501 goomInfo->update.zoomFilterData.hPlaneEffect = 0;
502 }
503 }
504
505 if (goom_irand (goomInfo->gRandom, 5) != 0)
506 goomInfo->update.zoomFilterData.noisify = 0;
507 else {
508 goomInfo->update.zoomFilterData.noisify =
509 goom_irand (goomInfo->gRandom, 2) + 1;
510 goomInfo->update.lockvar *= 2;
511 }
512
513 if (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE) {
514 goomInfo->update.zoomFilterData.vPlaneEffect = 0;
515 goomInfo->update.zoomFilterData.hPlaneEffect = 0;
516 goomInfo->update.zoomFilterData.noisify = 0;
517 }
518
519 if ((goomInfo->update.zoomFilterData.middleX == 1)
520 || (goomInfo->update.zoomFilterData.middleX ==
521 (signed int) goomInfo->screen.width - 1)) {
522 goomInfo->update.zoomFilterData.vPlaneEffect = 0;
523 if (goom_irand (goomInfo->gRandom, 2))
524 goomInfo->update.zoomFilterData.hPlaneEffect = 0;
525 }
526
527 if ((signed int) newvit < goomInfo->update.zoomFilterData.vitesse) { /* on accelere */
528 pzfd = &goomInfo->update.zoomFilterData;
529 if (((newvit < STOP_SPEED - 7) &&
530 (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 6) &&
531 (goomInfo->cycle % 3 == 0))
532 || (goom_irand (goomInfo->gRandom, 40) == 0)) {
533 goomInfo->update.zoomFilterData.vitesse =
534 STOP_SPEED - goom_irand (goomInfo->gRandom, 2)
535 + goom_irand (goomInfo->gRandom, 2);
536 goomInfo->update.zoomFilterData.reverse =
537 !goomInfo->update.zoomFilterData.reverse;
538 } else {
539 goomInfo->update.zoomFilterData.vitesse =
540 (newvit + goomInfo->update.zoomFilterData.vitesse * 7) / 8;
541 }
542 goomInfo->update.lockvar += 50;
543 }
544 }
545
546 if (goomInfo->update.lockvar > 150) {
547 goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
548 goomInfo->update.switchMult = 1.0f;
549 }
550 }
551 /* mode mega-lent */
552 if (goom_irand (goomInfo->gRandom, 700) == 0) {
553 /*
554 * printf ("coup du sort...\n") ;
555 */
556 pzfd = &goomInfo->update.zoomFilterData;
557 goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1;
558 goomInfo->update.zoomFilterData.pertedec = 8;
559 goomInfo->update.zoomFilterData.sqrtperte = 16;
560 goomInfo->update.goomvar = 1;
561 goomInfo->update.lockvar += 50;
562 goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
563 goomInfo->update.switchMult = 1.0f;
564 }
565 }
566
567 /*
568 * gros frein si la musique est calme
569 */
570 if ((goomInfo->sound.speedvar < 0.01f)
571 && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 4)
572 && (goomInfo->cycle % 16 == 0)) {
573 pzfd = &goomInfo->update.zoomFilterData;
574 goomInfo->update.zoomFilterData.vitesse += 3;
575 goomInfo->update.zoomFilterData.pertedec = 8;
576 goomInfo->update.zoomFilterData.sqrtperte = 16;
577 goomInfo->update.goomvar = 0;
578 }
579
580 /*
581 * baisser regulierement la vitesse...
582 */
583 if ((goomInfo->cycle % 73 == 0)
584 && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 5)) {
585 pzfd = &goomInfo->update.zoomFilterData;
586 goomInfo->update.zoomFilterData.vitesse++;
587 }
588
589 /*
590 * arreter de decr�menter au bout d'un certain temps
591 */
592 if ((goomInfo->cycle % 101 == 0)
593 && (goomInfo->update.zoomFilterData.pertedec == 7)) {
594 pzfd = &goomInfo->update.zoomFilterData;
595 goomInfo->update.zoomFilterData.pertedec = 8;
596 goomInfo->update.zoomFilterData.sqrtperte = 16;
597 }
598
599 /*
600 * Permet de forcer un effet.
601 */
602 if ((forceMode > 0) && (forceMode <= NB_FX)) {
603 pzfd = &goomInfo->update.zoomFilterData;
604 pzfd->mode = forceMode - 1;
605 }
606
607 if (forceMode == -1) {
608 pzfd = NULL;
609 }
610
611 /*
612 * Changement d'effet de zoom !
613 */
614 if (pzfd != NULL) {
615 int dif;
616
617 goomInfo->update.cyclesSinceLastChange = 0;
618
619 goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount;
620
621 dif =
622 goomInfo->update.zoomFilterData.vitesse -
623 goomInfo->update.previousZoomSpeed;
624 if (dif < 0)
625 dif = -dif;
626
627 if (dif > 2) {
628 goomInfo->update.switchIncr *= (dif + 2) / 2;
629 }
630 goomInfo->update.previousZoomSpeed =
631 goomInfo->update.zoomFilterData.vitesse;
632 goomInfo->update.switchMult = 1.0f;
633
634 if (((goomInfo->sound.timeSinceLastGoom == 0)
635 && (goomInfo->sound.totalgoom < 2)) || (forceMode > 0)) {
636 goomInfo->update.switchIncr = 0;
637 goomInfo->update.switchMult = goomInfo->update.switchMultAmount;
638 }
639 } else {
640 if (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG) {
641 pzfd = &goomInfo->update.zoomFilterData;
642 goomInfo->update.cyclesSinceLastChange = 0;
643 } else
644 goomInfo->update.cyclesSinceLastChange++;
645 }
646
647 #ifdef VERBOSE
648 if (pzfd) {
649 printf ("GOOM: pzfd->mode = %d\n", pzfd->mode);
650 }
651 #endif
652
653 /* Zoom here ! */
654 zoomFilterFastRGB (goomInfo, goomInfo->p1, goomInfo->p2, pzfd,
655 goomInfo->screen.width, goomInfo->screen.height,
656 goomInfo->update.switchIncr, goomInfo->update.switchMult);
657
658 /*
659 * Affichage tentacule
660 */
661
662 goomInfo->tentacles_fx.apply (&goomInfo->tentacles_fx, goomInfo->p1,
663 goomInfo->p2, goomInfo);
664 goomInfo->star_fx.apply (&goomInfo->star_fx, goomInfo->p2, goomInfo->p1,
665 goomInfo);
666
667 /*
668 * Gestion du Scope
669 */
670
671 /*
672 * arret demande
673 */
674 if ((goomInfo->update.stop_lines & 0xf000)
675 || (!goomInfo->curGState->drawScope)) {
676 float param1 = 0, param2 = 0, amplitude;
677 int couleur;
678 int mode;
679
680 choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur, &mode, &litude,
681 1);
682 couleur = GML_BLACK;
683
684 goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur);
685 goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur);
686 goomInfo->update.stop_lines &= 0x0fff;
687 }
688
689 /*
690 * arret aleatore.. changement de mode de ligne..
691 */
692 if (goomInfo->update.lineMode != goomInfo->update.drawLinesDuration) {
693 goomInfo->update.lineMode--;
694 if (goomInfo->update.lineMode == -1)
695 goomInfo->update.lineMode = 0;
696 } else if ((goomInfo->cycle % 80 == 0)
697 && (goom_irand (goomInfo->gRandom, 5) == 0) && goomInfo->update.lineMode)
698 goomInfo->update.lineMode--;
699
700 if ((goomInfo->cycle % 120 == 0)
701 && (goom_irand (goomInfo->gRandom, 4) == 0)
702 && (goomInfo->curGState->drawScope)) {
703 if (goomInfo->update.lineMode == 0)
704 goomInfo->update.lineMode = goomInfo->update.drawLinesDuration;
705 else if (goomInfo->update.lineMode == goomInfo->update.drawLinesDuration) {
706 float param1, param2, amplitude;
707 int couleur1, couleur2;
708 int mode;
709
710 goomInfo->update.lineMode--;
711 choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur1,
712 &mode, &litude, goomInfo->update.stop_lines);
713
714 couleur2 = 5 - couleur1;
715 if (goomInfo->update.stop_lines) {
716 goomInfo->update.stop_lines--;
717 if (goom_irand (goomInfo->gRandom, 2))
718 couleur2 = couleur1 = GML_BLACK;
719 }
720
721 goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
722 couleur1);
723 goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
724 couleur2);
725 }
726 }
727
728 /*
729 * si on est dans un goom : afficher les lignes...
730 */
731 if ((goomInfo->update.lineMode != 0)
732 || (goomInfo->sound.timeSinceLastGoom < 5)) {
733 goomInfo->gmline2->power = goomInfo->gmline1->power;
734
735 goom_lines_draw (goomInfo, goomInfo->gmline1, data[0], goomInfo->p2);
736 goom_lines_draw (goomInfo, goomInfo->gmline2, data[1], goomInfo->p2);
737
738 if (((goomInfo->cycle % 121) == 9)
739 && (goom_irand (goomInfo->gRandom, 3) == 1)
740 && ((goomInfo->update.lineMode == 0)
741 || (goomInfo->update.lineMode ==
742 goomInfo->update.drawLinesDuration))) {
743 float param1, param2, amplitude;
744 int couleur1, couleur2;
745 int mode;
746
747 choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur1,
748 &mode, &litude, goomInfo->update.stop_lines);
749 couleur2 = 5 - couleur1;
750
751 if (goomInfo->update.stop_lines) {
752 goomInfo->update.stop_lines--;
753 if (goom_irand (goomInfo->gRandom, 2))
754 couleur2 = couleur1 = GML_BLACK;
755 }
756 goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude,
757 couleur1);
758 goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude,
759 couleur2);
760 }
761 }
762
763 return_val = goomInfo->p1;
764 tmp = goomInfo->p1;
765 goomInfo->p1 = goomInfo->p2;
766 goomInfo->p2 = tmp;
767
768 /* affichage et swappage des buffers.. */
769 goomInfo->cycle++;
770
771 goomInfo->convolve_fx.apply (&goomInfo->convolve_fx, return_val,
772 goomInfo->outputBuf, goomInfo);
773
774 return (guint32 *) goomInfo->outputBuf;
775 }
776
777 /****************************************
778 * CLOSE *
779 ****************************************/
780 void
goom_close(PluginInfo * goomInfo)781 goom_close (PluginInfo * goomInfo)
782 {
783 if (goomInfo->pixel != NULL)
784 free (goomInfo->pixel);
785 if (goomInfo->back != NULL)
786 free (goomInfo->back);
787 if (goomInfo->conv != NULL)
788 free (goomInfo->conv);
789
790 goomInfo->pixel = goomInfo->back = NULL;
791 goomInfo->conv = NULL;
792 goom_random_free (goomInfo->gRandom);
793 goom_lines_free (&goomInfo->gmline1);
794 goom_lines_free (&goomInfo->gmline2);
795
796 /* release_ifs (); */
797 goomInfo->ifs_fx.free (&goomInfo->ifs_fx);
798 goomInfo->convolve_fx.free (&goomInfo->convolve_fx);
799 goomInfo->star_fx.free (&goomInfo->star_fx);
800 goomInfo->tentacles_fx.free (&goomInfo->tentacles_fx);
801 goomInfo->zoomFilter_fx.free (&goomInfo->zoomFilter_fx);
802
803 plugin_info_free (goomInfo);
804 free (goomInfo);
805 }
806
807
808 /* *** */
809 void
choose_a_goom_line(PluginInfo * goomInfo,float * param1,float * param2,int * couleur,int * mode,float * amplitude,int far)810 choose_a_goom_line (PluginInfo * goomInfo, float *param1, float *param2,
811 int *couleur, int *mode, float *amplitude, int far)
812 {
813 *mode = goom_irand (goomInfo->gRandom, 3);
814 *amplitude = 1.0f;
815 switch (*mode) {
816 case GML_CIRCLE:
817 if (far) {
818 *param1 = *param2 = 0.47f;
819 *amplitude = 0.8f;
820 break;
821 }
822 if (goom_irand (goomInfo->gRandom, 3) == 0) {
823 *param1 = *param2 = 0;
824 *amplitude = 3.0f;
825 } else if (goom_irand (goomInfo->gRandom, 2)) {
826 *param1 = 0.40f * goomInfo->screen.height;
827 *param2 = 0.22f * goomInfo->screen.height;
828 } else {
829 *param1 = *param2 = goomInfo->screen.height * 0.35;
830 }
831 break;
832 case GML_HLINE:
833 if (goom_irand (goomInfo->gRandom, 4) || far) {
834 *param1 = goomInfo->screen.height / 7;
835 *param2 = 6.0f * goomInfo->screen.height / 7.0f;
836 } else {
837 *param1 = *param2 = goomInfo->screen.height / 2.0f;
838 *amplitude = 2.0f;
839 }
840 break;
841 case GML_VLINE:
842 if (goom_irand (goomInfo->gRandom, 3) || far) {
843 *param1 = goomInfo->screen.width / 7.0f;
844 *param2 = 6.0f * goomInfo->screen.width / 7.0f;
845 } else {
846 *param1 = *param2 = goomInfo->screen.width / 2.0f;
847 *amplitude = 1.5f;
848 }
849 break;
850 default:
851 *param1 = *param2 = 0;
852 break;
853 }
854
855 *couleur = goom_irand (goomInfo->gRandom, 6);
856 }
857