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