Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * apt-get install libsdl1.2-dev (ubuntu)
- * gcc plasma.c -o plasma -Wall -lSDL
- *
- * n'importe quelle touche ou la croix pour quitter
- */
- #include <SDL/SDL.h>
- #include <malloc.h>
- #include <math.h>
- #define LARGEUR 500
- #define HAUTEUR 500
- #define PI 3.14159265359
- #define STEP 1000
- #define COEF 1000
- double distance (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
- // trigonometrie de ~15/16 ans : calcul de l'hypothenuse
- unsigned int i = x1 - x2, j = y1 - y2;
- return sqrt(i*i+j*j);
- }
- int main (void) {
- SDL_Surface *screen;
- SDL_Event event;
- unsigned int x,y,t=0;
- unsigned long c, hlarg=LARGEUR/2, hhaut=HAUTEUR/2;
- unsigned long pal[1024];
- double f1, f2, f3, deg = PI/180;
- double *_sin = calloc(360*STEP,sizeof(double)), *_cos = calloc(360*STEP,sizeof(double));
- if (!_sin || !_cos) return -1; // au cas ou malloc se chie dessus, pas la peine d'aller plus loin
- unsigned int step = 360 * STEP;
- double *func1 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
- double *func2 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
- double *func3 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
- if (!func1 || !func2 || !func3) return -2;
- // on initialise la sdl et le mode gfx
- SDL_Init(SDL_INIT_VIDEO);
- screen = SDL_SetVideoMode(LARGEUR, HAUTEUR, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
- // sine/cosine tables pre-computation
- for (x=0; x<360*STEP; x++) {
- _sin[x] = floor(sin(x*PI/180/STEP)*STEP)/STEP;
- _cos[x] = floor(cos(x*PI/180/STEP)*STEP)/STEP;
- }
- // colors palette
- for (x=0; x<1024; x++) {
- pal[x] = (unsigned long)(
- ((unsigned char)(96+95*sin(x*0.6*deg))) << 16 |
- ((unsigned char)(128+127*sin(x*0.5*deg))) << 8 |
- ((unsigned char)(192+63*cos(x*0.1*deg)))
- );
- }
- // precalcul des images en memoire (optimisation)
- for (x=0; x<LARGEUR*4;x++) {
- for (y=0;y<HAUTEUR*4;y++) {
- func1[y*LARGEUR*4+x] = sin(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 0.3);
- func2[y*LARGEUR*4+x] = cos(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 0.7);
- func3[y*LARGEUR*4+x] = cos(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 1.1);
- }
- }
- // la boucle principale
- while (1) {
- if (SDL_PollEvent(&event)) // on check le clavier, si on presse une touche on sort
- if ((event.type == SDL_QUIT) || (event.type == SDL_KEYDOWN))
- break;
- if (SDL_MUSTLOCK(screen)) // on lock la surface si necessaire
- SDL_LockSurface(screen);
- for (y=0;y<HAUTEUR;y++) { // la routine principale, on balaye l'ecran, pour chaque pixel on calcule son index dans la palette
- for (x=0;x<LARGEUR;x++) {
- // nos fonctions trigo horribles et consomatrices de cycles
- f1 = func1[((y+(int)(HAUTEUR + hhaut * _sin[t%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR + LARGEUR * _sin[(t<<1)%step]))];
- f2 = func2[((y+(int)(HAUTEUR+HAUTEUR*_cos[(t<<2)%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR+hlarg*_sin[(t*3)%step]))];
- f3 = func3[((y+(int)(HAUTEUR+hhaut*_cos[(t<<1)%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR+hlarg*_cos[(t)%step]))];
- // on somme et fait la moyenne des trois fonctions point a point, et on "anime" en ajoutant t, le tout donne l'indice dans la palette de couleurs
- c = pal[((unsigned char)(512 + 512 * ((f1+f2+f3)/3))+t)%1024];
- // putpixel
- *(unsigned long *)(screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel) = c;
- }
- }
- if (SDL_MUSTLOCK(screen)) // si c'etait necessaire de lock on unlock la surface prete pour affichage maintenant
- SDL_UnlockSurface(screen);
- t += STEP;
- SDL_UpdateRect(screen,0,0,0,0); // on update l'affichage
- SDL_Delay(20);
- }
- // on quitte proprement
- SDL_Quit();
- free (_cos);
- free (_sin);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement