/* 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 "def.h" #include "draw.h" #include "struct.h" #include "analyser_struct.h" #include "pal.h" #include "draw_low_level.h" #include "projection.h" #include "jess.h" /*******************************************************************/ /**************** ANALYSER *****************************************/ /*******************************************************************/ void analyser(JessPrivate *priv, uint8_t * buffer) { int i ; droite (priv, buffer, -priv->xres2, 0, -priv->xres2+10, 0, 30); for (i = -priv->xres2 ; i<-priv->xres2+5 ; i++) { droite (priv, buffer, i, 0, i,(int)(priv->lys.E_moyen*2000) , 250); droite (priv, buffer, i+5, 0, i+5, (int)(priv->lys.dEdt_moyen*25000) , 230); droite (priv, buffer, i+10, 0, i+10, (int)(priv->lys.dEdt*25000) , 200); } } /*******************************************************************/ /**************** FUSEES *******************************************/ /*******************************************************************/ void fusee(JessPrivate *priv, uint8_t * buffer, int new) { int i; int x=0,y=0; float factor ; if (new == NEW) /* on creer une nouvelle fusee*/ { i=0; while (priv->life[i] > 0) { i++; if (i == FUSEE_MAX+1) return; } priv->xi[i] = visual_random_context_int(priv->rcontext) % priv->resx - priv->xres2; priv->yi[i] = -visual_random_context_int(priv->rcontext) % priv->yres2; priv->life[i] = FUSEE_VIE; /* on donne la vie max*/ } else /* on gere les autres */ { for(i = 0 ; i< FUSEE_MAX; i++) { if (priv->life[i] > 0) /* si elle est vivante */ { factor = priv->life[i] / FUSEE_VIE; x = priv->xi[i] * factor; y = priv->yi[i] * factor; priv->life[i]--; ball (priv, buffer, x, y, (int) FUSEE_RAYON * factor, FUSEE_COLOR); } } } } /*******************************************************************/ /**************** SUPER SPECTRAL ***********************************/ /*******************************************************************/ void super_spectral_balls(JessPrivate *priv, uint8_t * buffer) { int i,j; float dt = priv->conteur.dt; int resx = priv->resx; int resy = priv->resy; int xres2 = priv->xres2; int yres2 = priv->yres2; for(i=0; i < 256 ;i++) /* pour chaque frequence */ { if (priv->lys.dbeat[i] == NEW) /*creation d'une nouvelle ligne */ { priv->lys.dbeat[i] = MANAGE; j=0; while (priv->lifev[i][j] > 0) { j++; if (j == LINE_MAX+1) goto quit; /* pas de place desole */ } /* initialisation de la ligne */ priv->lifev[i][j] = LINE_VIE; priv->vx[i][j] = RESFACTXF( 0.025*((float) i - 128.0) * 32 +0* (1-(float)visual_random_context_int(priv->rcontext)/RAND_MAX) ); priv->vy[i][j] = RESFACTYF( (10+i)*i*priv->lys.Ed_moyen[i]*5000*( (float)j+1)/4); priv->x[i][j] = RESFACTXF( 2*(i - 128) ) +((float)j*(i-128))/2; priv->y[i][j] = 0*RESFACTXF( yres2/2-(float)((i-128)*(i-128))/256) -20*j ; } quit:; /* pas de nouvelle ligne */ for (j=0 ; j < LINE_MAX ; j++) { if (priv->lifev[i][j] > 0) { priv->vy[i][j] += -0.5*dt*1024; priv->x[i][j] += priv->vx[i][j] * dt; priv->y[i][j] += priv->vy[i][j] * dt; boule(priv, buffer, (int) priv->x[i][j], (int) priv->y[i][j], 5, 250*(LINE_VIE-priv->lifev[i][j])/LINE_VIE); if ((priv->y[i][j] < resy) &&(priv->y[i][j] > -resy) ) /*oui !*/ { if (i>128) droite (priv, buffer, priv->xres2, (int) priv->y[i][j] / 32, (int) priv->x[i][j], (int) priv->y[i][j], 50 * (LINE_VIE-priv->lifev[i][j]) / LINE_VIE); else droite (priv, buffer, -xres2, (int) priv->y[i][j] / 32, (int) priv->x[i][j], (int) priv->y[i][j], 50 * (LINE_VIE-priv->lifev[i][j])/LINE_VIE); } priv->lifev[i][j]--; } } } } /*******************************************************************/ /**************** SUPER SPECTRAL ***********************************/ /*******************************************************************/ void super_spectral(JessPrivate *priv, uint8_t * buffer) { int i,j; float nx,ny; float taille,dt = priv->conteur.dt; int resx = priv->resx; int resy = priv->resy; int yres2 = priv->yres2; for(i=0; i < 256 ;i++) /* pour chaque frequence */ { if (priv->lys.dbeat[i] == NEW) /*creation d'une nouvelle ligne */ { priv->lys.dbeat[i] = MANAGE; j=0; while (priv->lifet[i][j] > 0) { j++; if (j == LINE_MAX+1) goto quit; /* pas de place desole */ } /* initialisation de la ligne */ priv->lifet[i][j] = LINE_VIE; priv->ssvx[i][j] = 0*RESFACTXF( 0.025*((float) i - 128.0) * 32 + (float)visual_random_context_int(priv->rcontext)/RAND_MAX*60 ); priv->ssvy[i][j] = 0*RESFACTYF( 64 +(float)visual_random_context_int(priv->rcontext)/RAND_MAX*64); priv->ssx[i][j] = RESFACTXF( 2*(i - 128) ) +((float)j*(i-128))/2; priv->ssy[i][j] = 0*RESFACTXF( yres2/2-(float)((i-128)*(i-128))/256) -20*j+60 ; priv->sstheta[i][j] = 0; priv->ssomega[i][j] = (10+i)*i*priv->lys.Ed_moyen[i]*32; } quit:; /* pas de nouvelle ligne */ for (j=0 ; j < LINE_MAX ; j++) if (priv->lifet[i][j] > 0) { priv->sstheta[i][j] += priv->ssomega[i][j]*dt; priv->ssvy[i][j] += -0.5*dt*1024*0; priv->ssx[i][j] += priv->ssvx[i][j] * dt; priv->ssy[i][j] += priv->ssvy[i][j] * dt; taille = RESFACTXF(70) * (0+2*(LINE_VIE-priv->lifet[i][j]))/LINE_VIE*(j+1)/6; nx = taille*sin(priv->sstheta[i][j]); ny = taille*cos(priv->sstheta[i][j]); droite (priv, buffer, (int) priv->ssx[i][j]+nx , (int) priv->ssy[i][j]+ny, (int) priv->ssx[i][j], (int) priv->ssy[i][j], 50*(LINE_VIE-priv->lifet[i][j])/LINE_VIE); if (priv->video ==8) cercle (priv, buffer, (int) priv->ssx[i][j]+nx, (int) priv->ssy[i][j]+ny, 3*j, 150*(LINE_VIE-priv->lifet[i][j])/LINE_VIE); else cercle_32 (priv, buffer, (int) priv->ssx[i][j]+nx, (int) priv->ssy[i][j]+ny, 3*j, 150*(LINE_VIE-priv->lifet[i][j])/LINE_VIE); priv->lifet[i][j]--; } } } /*******************************************************************/ /**************** GRANDE GRILLE ************************************/ /*******************************************************************/ void grille_3d (JessPrivate *priv, uint8_t * buffer, short data[2][512], float alpha, float beta, float gamma, int persp, int dist_cam) { float x, y, z, xres2 = (float) (priv->resx >> 1); short ax = 0, ay = 0, ix, iy, i, j, nb_x, nb_y; uint8_t color; int resx = priv->resx; int resy = priv->resy; nb_x = 32; nb_y = 32; for (i = 0; i < nb_x; i++) { /* Optimisation par Karl Soulabaille. Factorisation et expressions communes. */ for (j = 0; j < nb_y; j++) { x = RESFACTXF ((i - ((float) nb_x) / 2) * 10); y = RESFACTYF ((j - ((float) nb_y) / 2) * 10); if (j >= 16) { z = RESFACTXF ((float) (data[0][i + nb_x * (j - 16)]) / 256); color = data[0][i + nb_x * (j - 16)] / 512 + 100; } else { z = RESFACTXF ((float) (data[1][i + nb_x * j]) / 256); color = (data[1][i + nb_x * j]) / 512 + 100; } rotation_3d (&x, &y, &z, alpha, beta, gamma); perspective (&x, &y, &z, persp, dist_cam); if (x >= xres2) { x = xres2 - 1; color = 0; } if (x <= -xres2) { x = -xres2 + 1; color = 0; } if (y >= priv->yres2) { y = priv->yres2 - 1; color = 0; } if (y <= -priv->yres2) { y = -priv->yres2 + 1; color = 0; } ix = (int) x; iy = (int) y; if (j != 0) droite (priv, buffer, ix, iy, ax, ay, color); ax = ix; ay = iy; } } } /*******************************************************************/ /**************** 2 GRILLES JUMELLES *******************************/ /*******************************************************************/ void l2_grilles_3d (JessPrivate *priv, uint8_t * buffer, short data[2][512], float alpha, float beta, float gamma, int persp, int dist_cam) { float x, y, z, xres4 = (float) (priv->resx >> 2); short ax = 0, ay = 0, ix, iy, i, j, nb_x, nb_y; int tx[16][16], ty[16][16]; uint8_t color[16][16]; int resx = priv->resx; int resy = priv->resy; nb_x = 16; nb_y = 16; for (i = 0; i < nb_x; i++) { /* Optimisation par Karl Soulabaille. Factorisation de calcul & expression commune */ x = RESFACTXF ((i - ((float) nb_x / 2)) * 15); for (j = 0; j < nb_y; j++) { y = RESFACTYF ((j - ((float) nb_y / 2)) * 15); z = abs(RESFACTXF ((float) (data[1][i + nb_x * j]) / 256)); color[i][j] = data[1][i + nb_x * j] / 512 + 100; rotation_3d (&x, &y, &z, alpha, beta, gamma); perspective (&x, &y, &z, persp, dist_cam); ix = (int) x; iy = (int) y; tx[i][j] = ix; ty[i][j] = iy; if (j != 0) { droite (priv, buffer, ix - xres4, iy, ax - xres4, ay, color[i][j]); droite (priv, buffer, ix + xres4, iy, ax + xres4, ay, color[i][j]); } ax = ix; ay = iy; } } } /*******************************************************************/ /**************** BURN 3D ******************************************/ /*******************************************************************/ void burn_3d (JessPrivate *priv, uint8_t * buffer, short data[2][512], float alpha, float beta, float gamma, int persp, int dist_cam, int mode) { float x,y,z,xres2 = (float) (priv->resx >> 1), yres2 = (float) (priv->resy >> 1); short ix, iy, i, j, nb_x, nb_y, color, taille; /* Variable temporaire pour la factorisation de constantes */ float temp1, temp2, temp3, temp3b, temp4, temp4b, temp5,temp6,temp7,temp8,temp9; int resx = priv->resx; int resy = priv->resy; nb_x = 12; nb_y = 12; /* 4 cas: */ switch(mode) { case 0: temp1 = 2*PI/nb_x*cos(alpha); temp2 = 2*PI/nb_y; for (i = 0 ; i< nb_x ; i++) { temp3 = (float)((int)(i*i)); for (j = 0 ; j= xres2 || x <= -xres2 || y >= yres2 || y <= -yres2)) { ix = (int) x; iy = (int) y; color = ((int)(float)(100+0.4*z)); if (color<0) color = 0; taille = color/8; boule (priv, buffer, ix, iy, taille, color); } } } break; case 1: temp1 = PI/(nb_x*nb_x*nb_x)*fabs(priv->lys.dEdt_moyen*5000); temp6 = 2*PI/nb_y; for (i = 0 ; i< nb_x ; i++) { temp3 = (float)(i*i*i); temp4 = sin((i+1)*PI/nb_x); temp5 = 5*alpha*2*PI/nb_x*i; temp3b = temp3*temp1; temp4b = temp4*temp1; for (j = 0 ; jlys.dEdt_moyen*1000)); rotation_3d (&x, &y, &z, alpha, beta, gamma); perspective (&x, &y, &z, persp, dist_cam); if (!(x >= xres2 || x <= -xres2 || y >= yres2 || y <= -yres2)) { ix = (int) x; iy = (int) y; color = ((int)(float)(100+0.4*z)); if (color<0) color = 0; taille = color/8; boule (priv, buffer, ix, iy, taille, color); } } } break; case 2: temp5 = 2*PI/(5*nb_x); temp6 = 2*PI/nb_y; for (i = 0 ; i< nb_x ; i++) { temp1 = sin((i+1)*PI/nb_x); temp2 = temp5 * -i; for (j = 0 ; jlys.dEdt_moyen*1000 ); rotation_3d (&x, &y, &z, alpha, beta, gamma); perspective (&x, &y, &z, persp, dist_cam); if (!(x >= xres2 || x <= -xres2 || y >= yres2 || y <= -yres2)) { ix = (int) x; iy = (int) y; color = ((int)(float)(100+0.4*z)); if (color<0) color = 0; taille = color/8; boule (priv, buffer, ix, iy, taille, color); } } } break; case 3: temp5 = 25; temp6 = ((float)(-2))*PI/(10*nb_x); temp8 = (float)(2)*PI/nb_y; temp9 = 10*alpha; for (i = 0 ; i< nb_x ; i++) { temp5 += 25; temp7 = -i*temp6; for (j = 0 ; j= xres2 || x <= -xres2 || y >= yres2 || y <= -yres2)) { ix = (int) x; iy = (int) y; color = ((int)(float)(100+0.4*z)); if (color<0) color = 0; taille = color/8; boule (priv, buffer, ix, iy, taille, color); } } } break; } } /*******************************************************************/ /**************** STARS MORPH **************************************/ /*******************************************************************/ void stars_create_state(JessPrivate *priv, float pos[3][STARS_MAX], int mode) { int i,j,sq=sqrt(STARS_MAX); float fsq = (float) sq; switch(mode) { case 0: for(i=0 ; i< STARS_MAX; i++) { for(j=0; j<3 ; j++) { pos[j][i] = 0; } } break; case 1: for(i=0 ; i< STARS_MAX; i++) { for(j=0; j<3 ; j++) { pos[j][i] = ((float)visual_random_context_int(priv->rcontext)/RAND_MAX-0.5); } } break; case 2: for(j=0 ; j< sq; j++) { for(i=0 ; i< sq; i++) { pos[0][i + j*sq] = (i - fsq/2)*2/fsq; pos[1][i + j*sq] = (j - fsq/2)*2/fsq; pos[2][i + j*sq] = 0; } } break; case 3: for(j=0 ; j< sq; j++) { for(i=0 ; i< sq; i++) { pos[0][i + j*sq] = sin((i+1)*PI/fsq); pos[1][i + j*sq] = sin(-i*2*PI/(10*fsq)+ j*2*PI/fsq) ; pos[2][i + j*sq] = cos(j*2*PI/fsq) ; } } break; } } void stars_manage(JessPrivate *priv, uint8_t *buffer, int new, float alpha, float beta, float gamma, int persp, int dist_cam) { float x[STARS_MAX], y[STARS_MAX], z[STARS_MAX], xres2 = (float) (priv->resx >> 1), yres2 = (float) (priv->resy >> 1); float x_t, y_t, z_t; float mult; int ix, iy, i, color, taille; if (new == NEW_SESSION) /* explosion */ { priv->smmorpheur = 0; priv->smselect = 1; stars_create_state(priv, priv->smpos[0], 0); stars_create_state(priv, priv->smpos[1], 1); } else if(new == NEW) /* on creer une nouvelle forme */ { mult = 1; if ((visual_random_context_int(priv->rcontext)%3)==0) mult = 4; for(i = 0 ; i< STARS_MAX; i++) { priv->smpos[priv->smselect][0][i]= mult*x[i]; priv->smpos[priv->smselect][1][i]= mult*y[i]; priv->smpos[priv->smselect][2][i]= mult*z[i]; } priv->smselect = 1 - priv->smselect; stars_create_state(priv, priv->smpos[priv->smselect], visual_random_context_int(priv->rcontext)%2+1); } else /* on gere */ { priv->smmorpheur += ( 2 * (float)priv->smselect - 1) * MORPH_SPEED * priv->conteur.dt; if (priv->smmorpheur > 1) priv->smmorpheur = 1; else if (priv->smmorpheur < 0) priv->smmorpheur = 0; for(i = 0 ; i< STARS_MAX; i++) { x[i] =(priv->smpos[1][0][i] * priv->smmorpheur + (1-priv->smmorpheur) * priv->smpos[0][0][i]); y[i] =(priv->smpos[1][1][i] * priv->smmorpheur + (1-priv->smmorpheur) * priv->smpos[0][1][i]); z[i] =(priv->smpos[1][2][i] * priv->smmorpheur + (1-priv->smmorpheur) * priv->smpos[0][2][i]); x_t = 250 * x[i]; y_t = 250 * y[i]; z_t = 250 * z[i]; rotation_3d (&x_t, &y_t, &z_t, alpha, beta, gamma); perspective (&x_t, &y_t, &z_t, persp, dist_cam); if ((int)x_t >= xres2 || (int)x_t <= -xres2 || (int)y_t >= yres2 || (int)y_t <= -yres2 || z_t >2*dist_cam) return; ix = (int) x_t; iy = (int) y_t; color = ((int)(float)(100+0.4*z_t)); if (color<0) color = 0; taille = color/8; droite(priv, buffer,ix,iy, xres2/2 ,-yres2 , color/8); boule (priv, buffer, ix, iy, taille, color); } } } /*******************************************************************/ /**************** OSCILLO ******************************************/ /*******************************************************************/ uint8_t couleur (JessPrivate *priv, short x) { int resx = priv->resx; float xf = (float) x, resx2f = (float) resx / 2; return (uint8_t) ((float) -(xf - resx2f) * (xf + resx2f) * 150 / (resx2f * resx2f)); } void courbes (JessPrivate *priv, uint8_t * buffer, short data[2][512], uint8_t color, int type) { int j, i, x1, y1, x2=0, y2=0; int r; int resx = priv->resx; int resy = priv->resy; #define RAYON 100 switch (type) { case 0: for (i = 0; i < resx - 1 && i < 511; i++) { j = i - 256; droite (priv, buffer, j, data[0][i] / (256) + resy / 6, j + 1, data[0][i + 1] / (256) + resy / 6, couleur (priv, j)); droite (priv, buffer, j, data[1][i] / (256) - resy / 6, j + 1, data[1][i + 1] / (256) - resy / 6, couleur (priv, j)); } break; case 1: r = data[0][255] >> 8; x2 = (RAYON+r) * cos (255*2*PI/256); y2 = (RAYON+r) * sin (255*2*PI/256); for (i = 0; i < 256 ;i++) { r = data[0][i] >> 8; x1 = (RAYON+r) * cos (i*2*PI/256); y1 = (RAYON+r) * sin( i*2*PI/256); droite(priv, buffer,x1,y1,x2,y2,100); x2 = x1; y2 = y1; } break; default: break; } } /*******************************************************************/ /**************** SINUS_RECT ***************************************/ /*******************************************************************/ void sinus_rect (JessPrivate *priv, uint8_t * buffer, int k) { int resx = priv->resx; int resy = priv->resy; float fk = k; ball (priv, buffer, RESFACTXF (250 * cos (fk / 25)), RESFACTYF (100 * sin (2 * fk / 25)), RESFACTXF (100), 200); ball (priv, buffer, RESFACTXF (-250 * cos (fk / 25)), RESFACTYF (100 * sin (2 * fk / 25)), RESFACTXF (100), 200); }