PageRenderTime 75ms CodeModel.GetById 9ms app.highlight 58ms RepoModel.GetById 1ms app.codeStats 1ms

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

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