/*!\file functionSdl.c * * \author SOUPLET Antoine * \version 1.0 * \date 13-01-2012 * * \brief Fichier regroupant les fonctions traitant de la gestion des événements, ou de la SDL en général * */ #include "functionAdd.h" #include "functionSdl.h" #include #include #include "lSystem.h" #include #include "drawGeo.h" #include #include #include #include "drawFractal.h" //Attente d'un événement après le dessin des fractales de type L-System, et traitement de celui-ci void waitEventLSystem(Lsystem* lsyst_lSystem) { SDL_Event ev_event;//Evénement SDL int* pi_quitPrg;//Pointeur vers un entier permettant de quitter le programme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) int i_action;//Entier correspondant à la valeur de retour de la fonction switchKeyDownLSystem pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg=0; d_pitch=100; while(!*pi_quitPrg) { SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=3; break; case SDL_KEYDOWN: i_action=switchKeyDownLSystem(lsyst_lSystem, ev_event, d_pitch, pi_quitPrg); if(i_action) { if(i_action==2){ free(lsyst_lSystem->pc_tabFinal); infoWindowLsystem(lsyst_lSystem, "en cours"); lsyst_lSystem->pc_tabFinal=createFinalArray(lsyst_lSystem->ppc_rules,lsyst_lSystem->pc_tabVariable,*lsyst_lSystem->pi_indice); } drawFractalSystem(lsyst_lSystem); } break; } } freeLsystem(lsyst_lSystem); free(pi_quitPrg); } //Attente d'un événement après le dessin de la fractales de Mandelbrot, et traitement de celui-ci void waitEventMandelbrot(SDL_Surface *surf_screen, double *pd_zoom, Point* ppoint_pInit, int* pi_nbIter, int* pi_numGradient) { SDL_Event ev_event;//Evénement SDL int* pi_quitPrg;//Pointeur vers un entier permettant de quitter le programme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg=0; while (!*pi_quitPrg) { SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=1; break; case SDL_KEYDOWN: d_pitch=(0.5/(*pd_zoom)); if(switchKeyDown(surf_screen, ev_event, ppoint_pInit, pd_zoom, d_pitch, pi_quitPrg, pi_nbIter, pi_numGradient, pi_nbIter)){ drawFractalM(surf_screen,pd_zoom, ppoint_pInit,pi_nbIter, pi_numGradient); } break; default:{} } } free(pi_nbIter); free(pi_numGradient); SDL_FreeSurface(surf_screen); free(pd_zoom); free(ppoint_pInit); free(pi_quitPrg); } //Attente d'un évènement après le dessin des fractales de type Julia, et traitement de celui-ci void waitEventJulia(SDL_Surface *surf_screen, double *pd_zoom, Point *ppoint_pInit, Point *ppoint_coeffC, int* pi_nbIter, int* pi_numGradient, int* pi_reverse) { SDL_Event ev_event;//Evénement SDL int *pi_quitPrg;//Pointeur vers un entier permettant de quitter le programme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg=0; while (!*pi_quitPrg) { SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=1; break; case SDL_KEYDOWN: d_pitch=0.5/(*pd_zoom); if(switchKeyDown(surf_screen, ev_event, ppoint_pInit, pd_zoom, d_pitch, pi_quitPrg, pi_nbIter, pi_numGradient, pi_reverse)){ drawFractalJ(surf_screen,pd_zoom,ppoint_pInit, ppoint_coeffC, pi_nbIter, pi_numGradient, pi_reverse); } break; default:{} } } free(pi_nbIter); free(pi_numGradient); SDL_FreeSurface(surf_screen); free(pd_zoom); free(ppoint_pInit); free(ppoint_coeffC); free(pi_quitPrg); } //Attente d'un évènement après le dessin des fractales de type Julia en temps réel, et traitement de celui-ci void waitEventJulia2(SDL_Surface *surf_screen, double* pd_zoom, Point *ppoint_pInit, Point *ppoint_coeffC, int* pi_nbIter, int* pi_numGradient, int* pi_reverse) { SDL_Event ev_event;//Evénement SDL int *pi_quitPrg;//Pointeur vers un entier permettant de quitter le programme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg=0; while (!*pi_quitPrg) { while(SDL_PollEvent(&ev_event)) { } SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=3; break; case SDL_MOUSEMOTION: pointSetValues(ppoint_coeffC, ev_event.motion.x/(double)surf_screen->w, ev_event.motion.y/(double)surf_screen->h); drawFractalJ(surf_screen,pd_zoom,ppoint_pInit, ppoint_coeffC, pi_nbIter, pi_numGradient,pi_reverse); break; case SDL_KEYDOWN: d_pitch=0.5/(*pd_zoom); if(switchKeyDown(surf_screen,ev_event, ppoint_pInit, pd_zoom, d_pitch, pi_quitPrg, pi_nbIter, pi_numGradient, pi_reverse)) { drawFractalJ(surf_screen,pd_zoom,ppoint_pInit, ppoint_coeffC, pi_nbIter, pi_numGradient,pi_reverse); } break; default:{} } } SDL_FreeSurface(surf_screen); free(pd_zoom); free(ppoint_pInit); free(ppoint_coeffC); free(pi_quitPrg); } //Attente d'un événement après le dessin des fractales de type Ifs, et traitement de celui-ci void waitEventIFS(Ifs *ifs_ifs) { SDL_Event ev_event;//Evénement SDL int* pi_quitPrg;//Pointeur vers un entier permettant de quitter le pogramme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg =0; d_pitch=100.0/(*(ifs_ifs->pd_zoom)); while (!*pi_quitPrg) { SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=1; break; case SDL_KEYDOWN: d_pitch=100.0/(*(ifs_ifs->pd_zoom)); if(switchKeyDownIfs(ifs_ifs, ev_event, d_pitch, pi_quitPrg)){ drawFractalIfs(ifs_ifs); } break; default:{} } } freeIfs(ifs_ifs); free(pi_quitPrg); } //Attente d'un événement après le dessin des fractales de type Flame, et traitement de celui-ci void waitEventFlame(Flame *flame_flame) { SDL_Event ev_event;//Evénement SDL int* pi_quitPrg;//Pointeur vers un entier permettant de quitter le programme double d_pitch;//Réel permettant le décalage de la fractale (et donc le déplacement) pi_quitPrg=myMalloc(sizeof(int*)); *pi_quitPrg =0; d_pitch=100.0/(*(flame_flame->pd_zoom)); while (!*pi_quitPrg) { SDL_WaitEvent(&ev_event); switch (ev_event.type) { case SDL_QUIT: *pi_quitPrg=3; break; case SDL_KEYDOWN: d_pitch=100.0/(*(flame_flame->pd_zoom)); if(switchKeyDownFlame(flame_flame, ev_event, d_pitch, pi_quitPrg)) { drawFractalFlame(flame_flame); } break; default: { } } } freeFlame(flame_flame); free(pi_quitPrg); } //Gère les événements liés aux fractales de Mandelbrot et de Julia, en association avec la fonction switchKeyDown2 int switchKeyDown(SDL_Surface *surf_screen, SDL_Event ev_event, Point* ppoint_pInit, double* pd_zoom, double d_pitch, int* pi_quitPrg, int* pi_nbIter, int* pi_numGradient, int* pi_reverse) { switch (ev_event.key.keysym.sym) { case SDLK_PAGEUP: multiplyZoom(pd_zoom, 2.0); break; case SDLK_PAGEDOWN: multiplyZoom(pd_zoom, 0.5); break; case SDLK_UP: moveUp(ppoint_pInit, d_pitch); break; case SDLK_DOWN: moveDown(ppoint_pInit, d_pitch); break; case SDLK_RIGHT: moveRight(ppoint_pInit, d_pitch); break; case SDLK_LEFT: moveLeft(ppoint_pInit, d_pitch); break; case SDLK_c: if(*pi_reverse) { *pi_reverse=0; } else if(*pi_reverse==0){ *pi_reverse=1; } break; default: return(switchKeyDown2(surf_screen, ev_event, ppoint_pInit, pd_zoom, d_pitch, pi_quitPrg, pi_nbIter, pi_numGradient)); } return (1); } //Gère les événements liés aux fractales de Mandelbrot et de Julia, en association avec la fonction switchKeyDown int switchKeyDown2(SDL_Surface *surf_screen, SDL_Event ev_event, Point* ppoint_pInit, double* pd_zoom, double d_pitch, int* pi_quitPrg, int* pi_nbIter, int* pi_numGradient) { switch (ev_event.key.keysym.sym) { case SDLK_ESCAPE: *pi_quitPrg=1; return (0); break; case SDLK_KP_PLUS: *pi_nbIter=*pi_nbIter*1.4; break; case SDLK_KP_MINUS: *pi_nbIter=*pi_nbIter/1.4+1; break; case SDLK_SPACE: *pi_numGradient = (*pi_numGradient+1)%5+1; break; case SDLK_F5: takeScreenShot(surf_screen); return (3); break; default: return(0); } return (1); } //Gère les événements liés aux fractales de type L-System, en association avec la fonction switchKeyDownLSystem int switchKeyDownLSystem(Lsystem* lsyst_lSystem, SDL_Event ev_event, double d_pitch, int* pi_quitPrg) { switch (ev_event.key.keysym.sym) { case SDLK_PAGEDOWN: multiplyZoom(lsyst_lSystem->pd_zoom, 0.5); break; case SDLK_PAGEUP: multiplyZoom(lsyst_lSystem->pd_zoom, 2.0); break; case SDLK_UP: moveUp(lsyst_lSystem->ppoint_pInit, d_pitch); break; case SDLK_DOWN: moveDown(lsyst_lSystem->ppoint_pInit, d_pitch); break; case SDLK_RIGHT: moveRight(lsyst_lSystem->ppoint_pInit, d_pitch); break; case SDLK_LEFT: moveLeft(lsyst_lSystem->ppoint_pInit, d_pitch); break; default: return (switchKeyDownLSystem2(lsyst_lSystem, ev_event, d_pitch, pi_quitPrg)); } return (1); } //Gère les événements liés aux fractales de type L-System, en association avec la fonction switchKeyDownLSystem int switchKeyDownLSystem2(Lsystem* lsyst_lSystem, SDL_Event ev_event, double d_pitch, int* pi_quitPrg) { switch (ev_event.key.keysym.sym) { case SDLK_ESCAPE: *pi_quitPrg=1; return (0); break; case SDLK_F5: takeScreenShot(lsyst_lSystem->surf_screen); break; case SDLK_KP_PLUS: (*lsyst_lSystem->pi_indice)++; return (2); break; case SDLK_KP_MINUS: if(*lsyst_lSystem->pi_indice !=0) { (*lsyst_lSystem->pi_indice)--; } return (2); break; default: return (0); } return (1); } //Gère les événements liés aux fractales de type Ifs, en association avec les fonctions switchKeyDownIfs2 et switchKeyDownIfsFlame int switchKeyDownIfs(Ifs *ifs_ifs, SDL_Event ev_event, double d_pitch, int* pi_quitPrg) { switch (ev_event.key.keysym.sym) { case SDLK_ESCAPE: *pi_quitPrg=1; return (0); break; case SDLK_SPACE: if(ifs_ifs->i_currentColor<8) { ifs_ifs->i_currentColor++; } else { ifs_ifs->i_currentColor=0; } return 2; case SDLK_c: if(ifs_ifs->i_functionMode) { ifs_ifs->i_functionMode=0; } else { ifs_ifs->i_functionMode=1; } return (2); default: return (switchKeyDownIfs2(ifs_ifs, ev_event, pi_quitPrg, d_pitch)); } return (1); } //Gère les événements liés aux fractales de type Ifs ou Flame int switchKeyDownIfsFlame(SDL_Surface* surf_screen, SDL_Event ev_event, Point* ppoint_pitch, double* pd_zoom, double d_pitch, int* pi_quitPrg) { switch (ev_event.key.keysym.sym) { case SDLK_PAGEUP: multiplyZoom(pd_zoom, 2.0); break; case SDLK_PAGEDOWN: multiplyZoom(pd_zoom, 0.5); break; case SDLK_UP: moveUp(ppoint_pitch, d_pitch); break; case SDLK_DOWN: moveDown(ppoint_pitch, d_pitch); break; case SDLK_RIGHT: moveRight(ppoint_pitch, d_pitch); break; case SDLK_LEFT: moveLeft(ppoint_pitch, d_pitch); break; case SDLK_F5: takeScreenShot(surf_screen); return (3); break; default: return (0); } return (1); } //Gère les événements liés aux fractales de type Ifs, en association avec les fonctions switchKeyDownIfs et switchKeyDownIfsFlame int switchKeyDownIfs2(Ifs* ifs_ifs, SDL_Event ev_event, int* pi_quitPrg, double d_pitch) { SDLMod mod_press;//Permet de savoir si une touche est enfoncée mod_press= SDL_GetModState(); switch (ev_event.key.keysym.sym) { case SDLK_KP_PLUS: if (ev_event.key.keysym.sym == SDLK_KP_PLUS && (mod_press & KMOD_CTRL)) { if(ifs_ifs->d_light < 1.0) { ifs_ifs->d_light=ifs_ifs->d_light+0.1; return (2); } else return (0); } else { ifs_ifs->i_nbPoint=ifs_ifs->i_nbPoint*2; ifs_ifs->i_lockScreen=1; drawFractalIfs(ifs_ifs); return (0); } break; case SDLK_KP_MINUS: if (ev_event.key.keysym.sym == SDLK_KP_MINUS && (mod_press & KMOD_CTRL)) { if(ifs_ifs->d_light > 0.1) { ifs_ifs->d_light=ifs_ifs->d_light-0.1; } else return (0); } else { ifs_ifs->i_nbPoint=ifs_ifs->i_nbPoint/2; } break; default: return (switchKeyDownIfsFlame(ifs_ifs->surf_screen, ev_event, ifs_ifs->ppoint_pitch, ifs_ifs->pd_zoom, d_pitch, pi_quitPrg)); } return (1); } //Gère les événements liés aux fractales de type Flame, en association avec les fonctions switchKeyDownFlame2 et switchKeyDownIfsFlame int switchKeyDownFlame(Flame *flame_flame, SDL_Event ev_event, double d_pitch, int* pi_quitPrg) { switch (ev_event.key.keysym.sym){ case SDLK_ESCAPE: *pi_quitPrg=1; return (0); case SDLK_SPACE: if(flame_flame->i_currentColor<8) { flame_flame->i_currentColor++; } else { flame_flame->i_currentColor=0; } return (2); break; case SDLK_c: if(flame_flame->i_functionMode) { flame_flame->i_functionMode=0; } else { flame_flame->i_functionMode=1; } return (2); default: return (switchKeyDownFlame2(flame_flame, ev_event, pi_quitPrg, d_pitch)); } return (1); } //Gère les événements liés aux fractales de type Flame, en association avec les fonctions switchKeyDownFlame et switchKeyDownIfsFlame int switchKeyDownFlame2(Flame* flame_flame, SDL_Event ev_event, int* pi_quitPrg, double d_pitch) { SDLMod mod_press;//Permet de savoir si une touche est enfoncée mod_press = SDL_GetModState(); switch (ev_event.key.keysym.sym) { case SDLK_KP_PLUS: if (ev_event.key.keysym.sym == SDLK_KP_PLUS && (mod_press & KMOD_CTRL)) { if(flame_flame->d_light < 1.0) { flame_flame->d_light=flame_flame->d_light+0.1; return (2); } else return (0); } else { flame_flame->i_nbPoint=flame_flame->i_nbPoint*2; flame_flame->i_lockScreen=1; drawFractalFlame(flame_flame); return (0); } break; case SDLK_KP_MINUS: if (ev_event.key.keysym.sym == SDLK_KP_MINUS && (mod_press & KMOD_CTRL)) { if(flame_flame->d_light > 0.1) { flame_flame->d_light=flame_flame->d_light-0.1; } else return (0); } else { flame_flame->i_nbPoint=flame_flame->i_nbPoint/2; } break; default: return (switchKeyDownIfsFlame(flame_flame->surf_screen, ev_event, flame_flame->ppoint_pitch, flame_flame->pd_zoom, d_pitch, pi_quitPrg)); } return (1); } //Modifie le point initial de la fractale de telle sorte que l'on se déplace vers le haut void moveUp(Point* ppoint_pInit, double d_pitch) { (*ppoint_pInit).y=(*ppoint_pInit).y + d_pitch; } //Modifie le point initial de la fractale de telle sorte que l'on se déplace vers le bas void moveDown(Point* ppoint_pInit, double d_pitch) { (*ppoint_pInit).y=(*ppoint_pInit).y - d_pitch; } //Modifie le point initial de la fractale de telle sorte que l'on se déplace vers la gauche void moveLeft(Point* ppoint_pInit, double d_pitch) { (*ppoint_pInit).x=(*ppoint_pInit).x + d_pitch; } //Modifie le point initial de la fractale de telle sorte que l'on se déplace vers la droite void moveRight(Point* ppoint_pInit, double d_pitch) { (*ppoint_pInit).x=(*ppoint_pInit).x - d_pitch; } //Modifie la valeur du pointeur vers le zoom associé à la fractale void multiplyZoom(double *pd_zoom, double d_coeff) { *pd_zoom = *pd_zoom * d_coeff +0.0001; } //Modifie le titre de la fenêtre void infoWindowIfs(Ifs *ifs_ifs, int i_nbIter) { char c_title[300];//Chaine de caractère correspondant au titre de la fenêtre int i_rate;//Entier correspondant au pourcentage de calcul de la fractale Ifs i_rate=(i_nbIter+1)*100/(ifs_ifs->i_nbPoint); sprintf(c_title, "Fractale IFS : %s : Zoom x%f / %d x %d / %d points calculés / %d%% - ", ifs_ifs->pc_fileName, *(ifs_ifs->pd_zoom), ifs_ifs->surf_screen->w, ifs_ifs->surf_screen->h,ifs_ifs->i_nbPoint, i_rate); SDL_WM_SetCaption(c_title, NULL); } //Modifie le titre de la fenêtre void infoWindowFlame(Flame *flame_flame, int i_nbIter) { char c_title[300];//Chaine de caractère correspondant au titre de la fenêtre int i_rate;//Entier correspondant au pourcentage de calcul de la fractale Flame i_rate=(i_nbIter+1)*100/(flame_flame->i_nbPoint); sprintf(c_title, "Fractale Flame : %s : Zoom x%f / %d x %d / %d points calculés / %d%% - ", flame_flame->pc_fileName, *(flame_flame->pd_zoom), flame_flame->surf_screen->w, flame_flame->surf_screen->h, flame_flame->i_nbPoint, i_rate); SDL_WM_SetCaption(c_title, NULL); } //Modifie le titre de la fenêtre void infoWindowFlameChoice(Flame *flame_flame, int i_nbIter) { char c_title[300];//Chaine de caractère correspondant au titre de la fenêtre int i_rate;//Entier correspondant au pourcentage de calcul de la fractale Flame i_rate=(i_nbIter+1)*100/(flame_flame->i_nbPoint); sprintf(c_title, "Fractale Flame : Zoom x%f / %d x %d / %d points calculés / %d%% - ", *(flame_flame->pd_zoom), flame_flame->surf_screen->w, flame_flame->surf_screen->h, flame_flame->i_nbPoint, i_rate); SDL_WM_SetCaption(c_title, NULL); } //Modifie le titre de la fenêtre void infoWindow(char* pc_fractalName, SDL_Surface* surf_screen, double* pd_zoom, int* pi_nbIter, char* pc_status) { char c_title[300];//Chaine de caractère correspondant au titre de la fenêtre sprintf(c_title, "Fractale %s : Zoom x%f / %d x %d / %d itérations / état : %s - ", pc_fractalName, *pd_zoom, surf_screen->w, surf_screen->h, *pi_nbIter, pc_status); SDL_WM_SetCaption(c_title, NULL); } //Modifie le titre de la fenêtre void infoWindowLsystem(Lsystem *lsyst_lSystem, char* pc_status) { char c_title[300];//Chaine de caractère correspondant au titre de la fenêtre sprintf(c_title, "Fractale L-System : %s : Zoom x%f / %d x %d / état : %s - ",lsyst_lSystem->pc_fileName, *lsyst_lSystem->pd_zoom, lsyst_lSystem->surf_screen->w, lsyst_lSystem->surf_screen->h, pc_status); SDL_WM_SetCaption(c_title, NULL); } //Prends un screenshot et enregistre l'image dans le dossier /screenshots/ void takeScreenShot(SDL_Surface* surf_screen) { int i_cpt;//Entier permettant d'incrémenter le numéro du screenshots tant que le numéro existe déjà dans le dossier /screnshots/screen char* pc_fileName;//Une chaine de caractère représentant le nom du fichier char* pc_first;//Une chaine de caractère représentant le path du fichier char* pc_last;//Une chaine de caractère représentant l'extention du fichier pc_first="./screenshots/screen"; pc_last=".bmp"; pc_fileName=myMalloc(sizeof(char)*25); *pc_fileName='\0'; i_cpt=1; sprintf(pc_fileName, "%s%d%s", pc_first, i_cpt, pc_last); while(fopen(pc_fileName, "r")) { i_cpt++; sprintf(pc_fileName, "%s%d%s", pc_first, i_cpt, pc_last); } sprintf(pc_fileName, "%s%d%s", pc_first, i_cpt, pc_last); SDL_SaveBMP (surf_screen, pc_fileName); free(pc_fileName); }