/* Libvisual-plugins - Standard plugins for libvisual * * Copyright (C) 2000, 2001 Remi Arquier * * Authors: Remi Arquier * Dennis Smit * * $Id: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "def.h" #include "struct.h" #include "distorsion.h" #include "draw.h" #include "jess.h" #include "analyser.h" #include "analyser_struct.h" #include "renderer.h" #include "pal.h" void draw_mode(JessPrivate *priv, int mode) { switch (priv->lys.montee) { case NON: /* bruit calme */ if (priv->conteur.courbe <= 255 - 35) /* le bruit calme revient */ priv->conteur.courbe += 32; /* on fait re-apparaitre la courbe */ if (mode == 0) courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,0); else if (mode == 1) l2_grilles_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0, priv->conteur.angle2 / 30, 200, 130); else if (mode == 2) burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130, priv->conteur.burn_mode); else if ((mode == 3) && (priv->conteur.k3 > 700)) /* mode 3 */ burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0, priv->conteur.angle / 30, 200, 130, priv->conteur.burn_mode); else if (mode == 4) /* mode ligne */ { super_spectral_balls(priv, priv->pixel); courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,1); } else if (mode == 6) super_spectral(priv, priv->pixel); else if (mode == 5) /* mode stars */ stars_manage(priv, priv->pixel, MANAGE, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130); break; case OUI: /* bruit modere */ priv->conteur.courbe = 0; if (mode == 0) grille_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0, priv->conteur.angle / 30, 100, -priv->lys.E_moyen*20 + 130); else if (mode == 1) l2_grilles_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0, priv->conteur.angle2 / 30, 200, -priv->lys.E_moyen * 20 + 130); else if (mode == 2) burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130, priv->conteur.burn_mode); else if ((mode == 3) && (priv->conteur.k3 > 700)) /* mode 3 */ burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle / 200, 0, priv->conteur.angle / 30, 200, 130, priv->conteur.burn_mode); else if (mode == 4) /* mode ligne */ { super_spectral_balls (priv, priv->pixel); courbes (priv, priv->pixel, priv->pcm_data, priv->conteur.courbe,1); } else if (mode == 6) super_spectral (priv, priv->pixel); else if (mode == 5) /* mode stars */ stars_manage (priv, priv->pixel, MANAGE, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130); break; } priv->conteur.k3 += 10; if (priv->conteur.k3 < 300) /* Ici c'est les boules qui se barrent */ burn_3d (priv, priv->pixel, priv->pcm_data, priv->conteur.angle2 / 200, 0, priv->conteur.angle2 / 200, 200, -50 + 3 * priv->conteur.k3, priv->conteur.burn_mode); fusee(priv, priv->pixel, MANAGE); on_beat(priv, priv->lys.beat); on_reprise(priv); } void *renderer (JessPrivate *priv) { ips (priv); manage_dynamic_and_states_open(priv); render_deformation(priv, priv->conteur.blur_mode); render_blur(priv, 0); draw_mode(priv, priv->conteur.draw_mode); copy_and_fade(priv, DEDT_FACTOR * priv->lys.dEdt_moyen); if (priv->conteur.analyser == 1) { analyser (priv, priv->pixel); } manage_states_close(priv); return NULL; } void manage_dynamic_and_states_open(JessPrivate *priv) { priv->conteur.general++; priv->conteur.k2++; priv->conteur.last_flash++; priv->conteur.angle += priv->conteur.dt * 50; priv->conteur.v_angle2 = 0.97 * priv->conteur.v_angle2 ; priv->conteur.angle2 += priv->conteur.v_angle2 * priv->conteur.dt ; detect_beat(priv); if (priv->lys.dEdt_moyen > 0) priv->lys.montee = OUI; if ((priv->lys.montee == OUI) && (priv->lys.beat == OUI)) priv->lys.reprise = OUI ; } void manage_states_close(JessPrivate *priv) { priv->lys.beat = NON ; priv->lys.montee = NON; priv->lys.reprise = NON; } void on_beat(JessPrivate *priv, int beat) { if (priv->lys.beat == OUI) { fusee(priv, priv->pixel,NEW); /* on fou des etoiles */ priv->conteur.k1 += 4; /* vitesse a l angle 2 */ priv->conteur.v_angle2 += (visual_random_context_int (priv->rcontext) % 2 - 0.5) * 16 * 32; if (priv->conteur.draw_mode == 3) priv->conteur.k3 = 0; if (priv->conteur.draw_mode == 5) stars_manage(priv, priv->pixel, NEW, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130); } } void on_reprise(JessPrivate *priv) { uint32_t j; uint8_t *pix = priv->pixel; if (priv->lys.reprise == OUI) { if (priv->conteur.last_flash > 5 * priv->conteur.fps) { if (priv->conteur.draw_mode == 5) stars_manage(priv, priv->pixel, NEW_SESSION, priv->conteur.angle2 / 400, 0, priv->conteur.angle2 / 60, 200, 130); pix = priv->pixel; for (j = 0; j < priv->resy * priv->pitch; j++) *(pix++) = 250; if (priv->conteur.freeze_mode == NON) { priv->conteur.burn_mode = visual_random_context_int(priv->rcontext) % 4; priv->conteur.draw_mode = visual_random_context_int(priv->rcontext) % 7; priv->conteur.blur_mode = visual_random_context_int(priv->rcontext) % 5 ; if (priv->conteur.draw_mode==2) priv->conteur.blur_mode=0; random_palette(priv); } priv->conteur.last_flash = 0; } else { /* il y a eu un flash y a pas longtemps, donc on fait juste des etoiles */ /* on change de mode blur */ if ((priv->conteur.freeze_mode == 0) && (priv->conteur.mix_reprise >5) && (priv->conteur.draw_mode!=2)) { priv->conteur.blur_mode = visual_random_context_int(priv->rcontext) % 5 ; } } } } void copy_and_fade(JessPrivate *priv, float factor) { uint32_t j; uint8_t *pix, *buf; buf = priv->buffer; pix = priv->pixel; if(priv->video == 8) { fade(factor, priv->dim); for (j = 0; j < priv->resy * priv->resx; j++) { *(buf++) = priv->dim[*(pix++)]; } } else { fade(cos(0.125*factor)*factor*2, priv->dimR); fade(cos(0.25*factor)*factor*2, priv->dimG); fade(cos(0.5*factor)*factor*2, priv->dimB); /* FIXME MMX TARGET */ for (j = 0; j < priv->resy * priv->resx; j++) { *(buf++) = priv->dimR[*(pix++)]; *(buf++) = priv->dimG[*(pix++)]; *(buf++) = priv->dimB[*(pix++)]; buf++; pix++; } } } void fade(float variable, uint8_t * dim) { uint32_t aux2,j ; float aux; aux = 1-exp(-fabs(variable)); if (aux>1) aux=1; if (aux<0) aux=0; for (j= 0; j < 256; j++) { aux2 = (uint8_t) ((float) j * 0.245 * aux); if (aux2>255) aux2=255; if (aux2<0) aux2=0; dim[j]= aux2; } } void render_deformation(JessPrivate *priv, int defmode) { uint32_t bmax; uint32_t *tab1 = NULL, *tab2, *tab3, *tab4, i; uint8_t *pix = priv->pixel, *buf = priv->buffer, *aux; /**************** BUFFER DEFORMATION ****************/ if (priv->video == 8) { buf = priv->buffer; tab1 = priv->table1; tab2 = priv->table2; tab3 = priv->table3; tab4 = priv->table4; bmax = priv->resx * priv->resy + (uint32_t) priv->pixel; switch(defmode) { case 0: memcpy(priv->pixel, priv->buffer, priv->resx * priv->resy); break; case 1: for (pix = priv->pixel; pix < (uint8_t *) bmax ; pix++) *pix = *(priv->buffer + *(tab1++)) ; break; case 2: for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++) *pix = *(priv->buffer + *(tab2++)) ; break; case 3: for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++) *pix = *(priv->buffer + *(tab3++)) ; break; case 4: for (pix = priv->pixel; pix < (uint8_t *) bmax; pix++) *pix = *(priv->buffer + *(tab4++)) ; break; default: break; } } else { pix = priv->pixel; bmax = priv->resx * priv->resy; switch(defmode) { case 0: memcpy(priv->pixel, priv->buffer, priv->pitch * priv->resy); return; break; case 1: tab1 = priv->table1; break; case 2: tab1 = priv->table2; break; case 3: tab1 = priv->table3; break; case 4: tab1 = priv->table4; break; default: break; } for (i = 0; i < priv->resy * priv->resx; i++) { aux = (uint8_t *) ((*(tab1) << 2 ) + (uint32_t) priv->buffer); *(pix++) = *(aux++) ; *(pix++) = *(aux++); *(pix++) = *(aux); pix++; tab1++; } } } void render_blur(JessPrivate *priv, int blur) { /***************** Annotation par Karl Soulabaille: ***/ /* Quel est la valeur d'initialisation de pix ? */ /* (d'ou le segfault) */ /* j'ai mis pixel par defaut... */ VisCPU *cpucaps = visual_cpu_get_caps (); uint8_t *pix = priv->pixel; uint32_t bmax,pitch_4; pix = priv->pixel; if (priv->pixel == NULL) return; /* FIXME MMX 8 BIT VERSION */ /* Annotation par Karl Soulabaille: */ /* Il y avait des overflows sur les boucles (indice supérieur trop élevé de 1) */ if (priv->video == 8) { if (cpucaps->hasMMX == 1) { bmax = priv->resx * (priv->resy-1) + (uint32_t) priv->pixel; #ifdef VISUAL_ARCH_X86 __asm __volatile ("\n\t pxor %%mm6, %%mm6" ::: "mm6"); for (pix = priv->pixel; pix < (uint8_t *) bmax-1; pix += 8) { __asm __volatile ("\n\t movq %[pix1], %%mm0" "\n\t movq %[pix2], %%mm1" "\n\t movq %[pix3], %%mm2" "\n\t paddb %%mm0, %%mm1" "\n\t movq %[pix4], %%mm3" "\n\t paddb %%mm2, %%mm1" "\n\t paddb %%mm3, %%mm1" "\n\t movq %%mm1, %[pix1]" :: [pix1] "m" (*pix) , [pix2] "m" (*(pix + 1)) , [pix3] "m" (*(pix + priv->resx)) , [pix4] "m" (*(pix + priv->resx + 1)) : "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"); } __asm __volatile ("\n\t emms"); #endif } else { for (pix = priv->pixel; pix < (uint8_t *) bmax-1; pix++) *pix += *(pix+1) + *(pix+ priv->resx) + *(pix+ priv->resx+1); } } else { pitch_4 = priv->pitch+4; bmax = priv->pitch*(priv->resy-1) + (uint32_t) priv->pixel; if (cpucaps->hasMMX == 1) { #ifdef VISUAL_ARCH_X86 __asm __volatile ("\n\t pxor %%mm6, %%mm6" ::: "mm6"); for (pix = priv->pixel; pix < (uint8_t *) bmax-4; ) { __asm __volatile ("\n\t movq %[pix1], %%mm0" "\n\t movq %[pix2], %%mm1" "\n\t movq %[pix3], %%mm2" "\n\t paddb %%mm0, %%mm1" "\n\t movq %[pix4], %%mm3" "\n\t paddb %%mm2, %%mm1" "\n\t paddb %%mm3, %%mm1" "\n\t movq %%mm1, %[pix1]" :: [pix1] "m" (*pix) , [pix2] "m" (*(pix + 4)) , [pix3] "m" (*(pix + priv->pitch)) , [pix4] "m" (*(pix + pitch_4)) : "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"); pix += 8; } __asm __volatile ("\n\t emms"); #endif } else { for (pix = priv->pixel; pix < (uint8_t *) bmax-4; ) { *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4); pix++; *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4); pix++; *pix += *(pix + 4) + *(pix + priv->pitch) + *(pix + pitch_4); pix += 2; } } } }