1 /* Libvisual-plugins - Standard plugins for libvisual
2 *
3 * Copyright (C) 2000, 2001 Remi Arquier <arquier@crans.org>
4 *
5 * Authors: Remi Arquier <arquier@crans.org>
6 * Dennis Smit <ds@nerds-incorporated.org>
7 *
8 * $Id: renderer.c,v 1.11 2006/02/05 18:47:26 synap Exp $
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <math.h>
29 #include <string.h>
30
31 #include "def.h"
32 #include "struct.h"
33 #include "distorsion.h"
34 #include "draw.h"
35 #include "jess.h"
36 #include "analyser.h"
37 #include "analyser_struct.h"
38 #include "renderer.h"
39 #include "pal.h"
40
draw_mode(JessPrivate * priv,int mode)41 void draw_mode(JessPrivate *priv, int mode)
42 {
43 switch (priv->lys.montee)
44 {
45 case NON: /* bruit calme */
46 if (priv->conteur.courbe <= 255 - 35) /* le bruit calme revient */
47 priv->conteur.courbe += 32; /* on fait re-apparaitre la courbe */
48
49 if (mode == 0)
50 courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,0);
51 else if (mode == 1)
52 l2_grilles_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0,
53 priv->conteur.angle2 / 30, 200, 130);
54 else if (mode == 2)
55 burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 400, 0,
56 priv->conteur.angle2 / 60, 200, 130, priv->conteur.burn_mode);
57 else if ((mode == 3) && (priv->conteur.k3 > 700)) /* mode 3 */
58 burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0,
59 priv->conteur.angle / 30, 200, 130, priv->conteur.burn_mode);
60 else if (mode == 4) /* mode ligne */
61 {
62 super_spectral_balls(priv, priv->pixel);
63 courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,1);
64 }
65 else if (mode == 6)
66 super_spectral(priv, priv->pixel);
67
68 else if (mode == 5) /* mode stars */
69 stars_manage(priv, priv->pixel, MANAGE, priv->conteur.angle2 / 400, 0,
70 priv->conteur.angle2 / 60, 200, 130);
71 break;
72
73 case OUI: /* bruit modere */
74 priv->conteur.courbe = 0;
75 if (mode == 0)
76 grille_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0, priv->conteur.angle / 30,
77 100, -priv->lys.E_moyen*20 + 130);
78 else if (mode == 1)
79 l2_grilles_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0,
80 priv->conteur.angle2 / 30, 200, -priv->lys.E_moyen * 20 + 130);
81 else if (mode == 2)
82 burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 400, 0,
83 priv->conteur.angle2 / 60, 200, 130, priv->conteur.burn_mode);
84 else if ((mode == 3) && (priv->conteur.k3 > 700)) /* mode 3 */
85 burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0,
86 priv->conteur.angle / 30, 200, 130, priv->conteur.burn_mode);
87 else if (mode == 4) /* mode ligne */
88 {
89 super_spectral_balls (priv, priv->pixel);
90 courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,1);
91 }
92 else if (mode == 6)
93 super_spectral (priv, priv->pixel);
94 else if (mode == 5) /* mode stars */
95 stars_manage (priv, priv->pixel, MANAGE, priv->conteur.angle2 / 400, 0,
96 priv->conteur.angle2 / 60, 200, 130);
97 break;
98 }
99
100 priv->conteur.k3 += 10;
101 if (priv->conteur.k3 < 300) /* Ici c'est les boules qui se barrent */
102 burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0,
103 priv->conteur.angle2 / 200, 200, -50 + 3 * priv->conteur.k3, priv->conteur.burn_mode);
104
105 fusee(priv, priv->pixel, MANAGE);
106
107 on_beat(priv, priv->lys.beat);
108
109 on_reprise(priv);
110 }
111
renderer(JessPrivate * priv)112 void *renderer (JessPrivate *priv)
113 {
114 ips (priv);
115
116 manage_dynamic_and_states_open(priv);
117
118 render_deformation(priv, priv->conteur.blur_mode);
119
120 render_blur(priv, 0);
121
122 draw_mode(priv, priv->conteur.draw_mode);
123
124 copy_and_fade(priv, DEDT_FACTOR * priv->lys.dEdt_moyen);
125
126 if (priv->conteur.analyser == 1) {
127 analyser (priv, priv->pixel);
128 }
129
130 manage_states_close(priv);
131
132 return NULL;
133 }
134
manage_dynamic_and_states_open(JessPrivate * priv)135 void manage_dynamic_and_states_open(JessPrivate *priv)
136 {
137 priv->conteur.general++;
138 priv->conteur.k2++;
139 priv->conteur.last_flash++;
140
141 priv->conteur.angle += priv->conteur.dt * 50;
142
143 priv->conteur.v_angle2 = 0.97 * priv->conteur.v_angle2 ;
144 priv->conteur.angle2 += priv->conteur.v_angle2 * priv->conteur.dt ;
145
146 detect_beat(priv);
147
148 if (priv->lys.dEdt_moyen > 0)
149 priv->lys.montee = OUI;
150
151 if ((priv->lys.montee == OUI) && (priv->lys.beat == OUI))
152 priv->lys.reprise = OUI ;
153
154 }
155
manage_states_close(JessPrivate * priv)156 void manage_states_close(JessPrivate *priv)
157 {
158 priv->lys.beat = NON ;
159 priv->lys.montee = NON;
160 priv->lys.reprise = NON;
161 }
162
on_beat(JessPrivate * priv,int beat)163 void on_beat(JessPrivate *priv, int beat)
164 {
165 if (priv->lys.beat == OUI)
166 {
167
168 fusee(priv, priv->pixel,NEW);
169
170 /* on fou des etoiles */
171 priv->conteur.k1 += 4;
172
173 /* vitesse a l angle 2 */
174 priv->conteur.v_angle2 += (visual_random_context_int (priv->rcontext) % 2 - 0.5) * 16 * 32;
175
176 if (priv->conteur.draw_mode == 3)
177 priv->conteur.k3 = 0;
178
179 if (priv->conteur.draw_mode == 5)
180 stars_manage(priv, priv->pixel, NEW, priv->conteur.angle2 / 400, 0,
181 priv->conteur.angle2 / 60, 200, 130);
182 }
183 }
184
on_reprise(JessPrivate * priv)185 void on_reprise(JessPrivate *priv)
186 {
187 uint32_t j;
188 uint8_t *pix = priv->pixel;
189
190 if (priv->lys.reprise == OUI) {
191 if (priv->conteur.last_flash > 5 * priv->conteur.fps) {
192 if (priv->conteur.draw_mode == 5)
193 stars_manage(priv, priv->pixel, NEW_SESSION, priv->conteur.angle2 / 400, 0,
194 priv->conteur.angle2 / 60, 200, 130);
195
196 pix = priv->pixel;
197 for (j = 0; j < priv->resy * priv->pitch; j++)
198 *(pix++) = 250;
199
200 if (priv->conteur.freeze_mode == NON) {
201 priv->conteur.burn_mode = visual_random_context_int(priv->rcontext) % 4;
202
203 priv->conteur.draw_mode = visual_random_context_int(priv->rcontext) % 7;
204
205 priv->conteur.blur_mode = visual_random_context_int(priv->rcontext) % 5 ;
206 if (priv->conteur.draw_mode==2)
207 priv->conteur.blur_mode=0;
208
209 random_palette(priv);
210 }
211 priv->conteur.last_flash = 0;
212 } else {
213 /* il y a eu un flash y a pas longtemps, donc on fait juste des etoiles */
214 /* on change de mode blur */
215 if ((priv->conteur.freeze_mode == 0) && (priv->conteur.mix_reprise >5) && (priv->conteur.draw_mode!=2)) {
216 priv->conteur.blur_mode = visual_random_context_int(priv->rcontext) % 5 ;
217 }
218 }
219 }
220 }
221
copy_and_fade(JessPrivate * priv,float factor)222 void copy_and_fade(JessPrivate *priv, float factor)
223 {
224 uint32_t j;
225 uint8_t *pix, *buf;
226
227 buf = priv->buffer;
228 pix = priv->pixel;
229
230 if(priv->video == 8)
231 {
232 fade(factor, priv->dim);
233
234 for (j = 0; j < priv->resy * priv->resx; j++)
235 {
236 *(buf++) = priv->dim[*(pix++)];
237 }
238 }
239 else
240 {
241 fade(cos(0.125*factor)*factor*2, priv->dimR);
242 fade(cos(0.25*factor)*factor*2, priv->dimG);
243 fade(cos(0.5*factor)*factor*2, priv->dimB);
244
245 for (j = 0; j < priv->resy * priv->resx; j++)
246 {
247 *(buf++) = priv->dimR[*(pix++)];
248 *(buf++) = priv->dimG[*(pix++)];
249 *(buf++) = priv->dimB[*(pix++)];
250
251 buf++;
252 pix++;
253 }
254 }
255 }
256
257
fade(float variable,uint8_t * dim)258 void fade(float variable, uint8_t * dim)
259 {
260 uint32_t aux2,j ;
261 float aux;
262
263 aux = 1-exp(-fabs(variable));
264
265 if (aux>1)
266 aux=1;
267 if (aux<0)
268 aux=0;
269
270 for (j= 0; j < 256; j++)
271 {
272 aux2 = (uint8_t) ((float) j * 0.245 * aux);
273
274 if (aux2>255)
275 aux2=255;
276 if (aux2<0)
277 aux2=0;
278
279 dim[j]= aux2;
280 }
281 }
282
render_deformation(JessPrivate * priv,int defmode)283 void render_deformation(JessPrivate *priv, int defmode)
284 {
285 uint32_t bmax;
286 uint32_t *tab1 = NULL, *tab2, *tab3, *tab4, i;
287 uint8_t *pix = priv->pixel, *buf = priv->buffer, *aux;
288
289 /**************** BUFFER DEFORMATION ****************/
290 if (priv->video == 8)
291 {
292 buf = priv->buffer;
293 tab1 = priv->table1;
294 tab2 = priv->table2;
295 tab3 = priv->table3;
296 tab4 = priv->table4;
297 bmax = priv->resx * priv->resy + (uint32_t) priv->pixel;
298
299 switch(defmode)
300 {
301 case 0:
302 visual_mem_copy(priv->pixel, priv->buffer, priv->resx * priv->resy);
303 break;
304 case 1:
305 for (pix = priv->pixel; pix < (uint8_t *) bmax ; pix++)
306 *pix = *(priv->buffer + *(tab1++)) ;
307 break;
308 case 2:
309 for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++)
310 *pix = *(priv->buffer + *(tab2++)) ;
311 break;
312 case 3:
313 for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++)
314 *pix = *(priv->buffer + *(tab3++)) ;
315 break;
316 case 4:
317 for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++)
318 *pix = *(priv->buffer + *(tab4++)) ;
319 break;
320 default:
321
322 break;
323 }
324 }
325 else
326 {
327 pix = priv->pixel;
328
329 bmax = priv->resx * priv->resy;
330 switch(defmode)
331 {
332 case 0:
333 visual_mem_copy(priv->pixel, priv->buffer, priv->pitch * priv->resy);
334 return;
335 break;
336 case 1:
337 tab1 = priv->table1;
338 break;
339 case 2:
340 tab1 = priv->table2;
341 break;
342 case 3:
343 tab1 = priv->table3;
344 break;
345 case 4:
346 tab1 = priv->table4;
347 break;
348
349 default:
350
351 break;
352 }
353 for (i = 0; i < priv->resy * priv->resx; i++)
354 {
355 aux = (uint8_t *) ((*(tab1) << 2 ) + (uint32_t) priv->buffer);
356 *(pix++) = *(aux++) ;
357 *(pix++) = *(aux++);
358 *(pix++) = *(aux);
359
360 pix++;
361
362 tab1++;
363 }
364 }
365 }
366
render_blur(JessPrivate * priv,int blur)367 void render_blur(JessPrivate *priv, int blur)
368 {
369
370 /***************** Annotation par Karl Soulabaille: ***/
371 /* Quel est la valeur d'initialisation de pix ? */
372 /* (d'ou le segfault) */
373 /* j'ai mis pixel par defaut... */
374
375 uint8_t *pix = priv->pixel;
376 uint32_t bmax,pitch_4;
377
378 pix = priv->pixel;
379 if (priv->pixel == NULL)
380 return;
381
382
383 /* FIXME MMX 8 BIT VERSION */
384
385 /* Annotation par Karl Soulabaille: */
386 /* Il y avait des overflows sur les boucles (indice sup�rieur trop �lev� de 1) */
387 if (priv->video == 8)
388 {
389 if (visual_cpu_get_mmx ()) {
390 bmax = priv->resx * (priv->resy-1) + (uint32_t) priv->pixel;
391 #if defined(VISUAL_ARCH_X86) || defined(VISUAL_ARCH_X86_64)
392 __asm __volatile
393 ("\n\t pxor %%mm6, %%mm6"
394 ::);
395
396 for (pix = priv->pixel; pix < (uint8_t *) bmax-1; pix += 8)
397 {
398 __asm __volatile
399 ("\n\t movq %[pix1], %%mm0"
400 "\n\t movq %[pix2], %%mm1"
401 "\n\t movq %[pix3], %%mm2"
402 "\n\t paddb %%mm0, %%mm1"
403 "\n\t movq %[pix4], %%mm3"
404 "\n\t paddb %%mm2, %%mm1"
405 "\n\t paddb %%mm3, %%mm1"
406 "\n\t movq %%mm1, %[pix1]"
407 :: [pix1] "m" (*pix)
408 , [pix2] "m" (*(pix + 1))
409 , [pix3] "m" (*(pix + priv->resx))
410 , [pix4] "m" (*(pix + priv->resx + 1)));
411
412 }
413
414 __asm __volatile
415 ("\n\t emms");
416
417 #endif
418 } else {
419 for (pix = priv->pixel; pix < (uint8_t *) bmax-1; pix++)
420 *pix += *(pix+1) + *(pix+ priv->resx) + *(pix+ priv->resx+1);
421 }
422 }
423 else
424 {
425 pitch_4 = priv->pitch+4;
426 bmax = priv->pitch*(priv->resy-1) + (uint32_t) priv->pixel;
427
428 if (visual_cpu_get_mmx ()) {
429 #if defined(VISUAL_ARCH_X86) || defined(VISUAL_ARCH_X86_64)
430 __asm __volatile
431 ("\n\t pxor %%mm6, %%mm6"
432 ::);
433
434 for (pix = priv->pixel; pix < (uint8_t *) bmax-4; )
435 {
436 __asm __volatile
437 ("\n\t movq %[pix1], %%mm0"
438 "\n\t movq %[pix2], %%mm1"
439 "\n\t movq %[pix3], %%mm2"
440 "\n\t paddb %%mm0, %%mm1"
441 "\n\t movq %[pix4], %%mm3"
442 "\n\t paddb %%mm2, %%mm1"
443 "\n\t paddb %%mm3, %%mm1"
444 "\n\t movq %%mm1, %[pix1]"
445 :: [pix1] "m" (*pix)
446 , [pix2] "m" (*(pix + 4))
447 , [pix3] "m" (*(pix + priv->pitch))
448 , [pix4] "m" (*(pix + pitch_4)));
449
450 pix += 8;
451 }
452
453 __asm __volatile
454 ("\n\t emms");
455
456 #endif
457 } else {
458 for (pix = priv->pixel; pix < (uint8_t *) bmax-4; )
459 {
460 *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4);
461 pix++;
462 *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4);
463 pix++;
464 *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4);
465 pix += 2;
466 }
467 }
468 }
469 }
470
471