// 3.4 Attend que l'utilisateur clique sur le bouton gauche // Renvoie les coordonnées du point cliqué // Instruction bloquante POINT wait_clic() { int encore = 1; POINT P; SDL_Event event; P.x = 0; P.y = 0; #ifdef EN_LOCAL // A ne mettre que si on est en local, sur les ordi des étudiants, c'est trop lent #ifdef SDL_TTF_OK POINT E,F; char S[16]; E.x = WIDTH - 55; E.y = 15; F.x = WIDTH; F.y = 0; #endif #endif while (SDL_WaitEvent(&event) && encore) { /* Si l'utilisateur clique avec la souris */ if ((event.type == SDL_MOUSEBUTTONDOWN) && (event.button.button == SDL_BUTTON_LEFT)) { encore=0; P.x = event.button.x; P.y = HEIGHT-event.button.y; } /* Si l'utilisateur déplace la souris */ if (event.type == SDL_MOUSEMOTION) { #ifdef EN_LOCAL // A ne mettre que si on est en local, sur les ordi des étudiants, c'est trop lent #ifdef SDL_TTF_OK if (police[10]) { draw_fill_rectangle(E,F,noir); sprintf(S,"%4d %4d",event.motion.x,HEIGHT - event.motion.y); aff_pol(S,10,E,gris); affiche_all(); } #endif #endif printf("%cEn attente de clic ... %4d %4d %c",13,event.motion.x,HEIGHT - event.motion.y,13); fflush(stdout); } /* Si l'utilisateur a demandé à fermer la fenêtre, on quitte */ if (event.type == SDL_QUIT) exit(0); } #ifdef EN_LOCAL // A ne mettre que si on est en local, sur les ordi des étudiants, c'est trop lent #ifdef SDL_TTF_OK aff_pol(S,10,E,noir); //draw_fill_rectangle(E,F,jaune); affiche_all(); #endif #endif printf("%cClic en %4d %4d \n",13,P.x,P.y); ___MOUSE_POSITION = P; return P; }
// 3.5 Attend que l'on clique et renvoie dans button le bouton cliqué : // *button vaut soit 'G' (pour Gauche), soit 'M' (pour milieu), // soit 'D' (pour Droit) en fonction du bouton cliqué // Instruction bloquante POINT wait_clic_GMD(char *button) { int encore = 1; POINT P; SDL_Event event; P.x = 0; P.y = 0; #ifdef SDL_TTF_OK POINT E,F; char S[16]; E.x = WIDTH - 55; E.y = 15; F.x = WIDTH; F.y = 0; #endif affiche_all(); printf("Cliquer dans la fenêtre..."); while (SDL_WaitEvent(&event) && encore) { /* Si l'utilisateur a demandé à fermer la fenêtre, on quitte */ if (event.type == SDL_QUIT) exit(0); /* Si l'utilisateur a cliqué avec la souris */ if ((event.type == SDL_MOUSEBUTTONDOWN)) { #ifdef SDL_TTF_OK if (!police[10]) { draw_fill_rectangle(E,F,noir); sprintf(S,"%4d %4d",event.motion.x,HEIGHT - event.motion.y); aff_pol(S,10,E,gris); affiche_all(); } #endif printf("%cCliquer dans la fenêtre ... %4d %4d %c",13,event.motion.x,HEIGHT - event.motion.y,13); fflush(stdout); encore=0; P.x = event.button.x; P.y = HEIGHT-event.button.y; if (event.button.button == SDL_BUTTON_LEFT) *button = 'G'; if (event.button.button == SDL_BUTTON_MIDDLE) *button = 'M'; if (event.button.button == SDL_BUTTON_RIGHT) *button = 'D'; } } #ifdef SDL_TTF_OK draw_fill_rectangle(E,F,noir); #endif printf("Clic '%c' en %4d %4d \n",*button,P.x,P.y); ___MOUSE_POSITION = P; return P; }
void afficheTexte(char* texte, POINT HG, COULEUR c) { //Affiche du texte centré et de taille dynamique int taille = 0, longeur = strlen(texte); if (longeur <= 13) { HG.x += (13 - longeur)*6; taille = 25; } else if (longeur <= 20) { HG.x += (20 - longeur)*2; taille = 20; } else if (longeur <= 25) { HG.x += (25 - longeur)/3; taille = 15; } else if (longeur <= 30) { HG.x += (30 - longeur)/5; taille = 10; } else { HG.x += (40 - longeur)/10; taille = 12; } aff_pol(texte, taille, HG, c); affiche_all(); }
void afficheBoutonExpert() { POINT bg; bg.x = 0; bg.y = 600; affiche_image("../data/img/menu2.bmp",bg,1100,600); affiche_all(); attendre(150); }
void afficheMenu() { affiche_auto_off(); POINT bg; bg.x = 0; bg.y = 600; affiche_image("../data/img/menu.bmp",bg,1100,600); affiche_all(); }
// 4.1 Remplissage de tout l'écran void fill_screen(COULEUR color) { int i,j; for (i=0;i<WIDTH;i++) for (j=0;j<HEIGHT;j++) *((COULEUR *)SDL_screen->pixels + (HEIGHT-j-1) * WIDTH + i) = color; if (SDL_AFFICHE_AUTO) affiche_all(); }
int main () { int i; struct balle B[4]; struct traits T; init_graphics (1020,700); for (i=0 ; i<4 ; i++) B[i] = init_balle(i); T = init_traits(); affiche_auto_off(); while(1) { // On affiche affiche_legende(); affiche_traits(T); for (i=0 ; i<4 ; i++) affiche_balle(B[i]); affiche_all(); // On efface efface_traits(T); for (i=0 ; i<4 ; i++) efface_balle(B[i]); // On modifie T = modifie_traits(T); for (i=0 ; i<4 ; i++) B[i] = deplace_balle(B[i],T); } wait_escape(); exit(0); }
// 4.8.4 Dessine un quart de cercle en bas à gauche void draw_circle_BG(POINT centre, int rayon, COULEUR color) { POINT min, max; int i,j; float dx, dy, rr; min.x = centre.x - rayon; max.x = centre.x; min.y = centre.y - rayon; max.y = centre.y; rr = rayon*rayon; for (i=min.x;i<=max.x;i++) { dx = i - centre.x; dy = sqrt(rr - dx*dx); j = centre.y - dy; add_pix(i,j,color); } for (j=min.y;j<=max.y;j++) { dy = j - centre.y; dx = sqrt(rr - dy*dy); i = centre.x - dx; add_pix(i,j,color); } if (SDL_AFFICHE_AUTO) affiche_all(); }
void draw_fill_triangle(POINT p1, POINT p2, POINT p3, COULEUR color) { float a12, b12, a23, b23, a31, b31; float s1, s2, s3; // La droite passant par les point pi et pj // a pour équation : y = aij x + bij a12 = (p1.y-p2.y)/(float)(p1.x-p2.x); b12 = p1.y - a12*p1.x; a23 = (p2.y-p3.y)/(float)(p2.x-p3.x); b23 = p2.y - a23*p2.x; a31 = (p3.y-p1.y)/(float)(p3.x-p1.x); b31 = p3.y - a31*p3.x; // Le signe de sk détermine de quel coté pk est de la droite [pi,pj] s3 = p3.y - (a12*p3.x + b12); s1 = p1.y - (a23*p1.x + b23); s2 = p2.y - (a31*p2.x + b31); int minx, maxx, miny, maxy; minx = min3(p1.x,p2.x,p3.x); maxx = max3(p1.x,p2.x,p3.x); miny = min3(p1.y,p2.y,p3.y); maxy = max3(p1.y,p2.y,p3.y); int i,j; int ok; for (i=minx;i<maxx;i++) for (j=miny;j<maxy;j++) { ok = 1; // On vérifie que le point (i,j) est du bon coté // des 3 droites du triangle if (s3 * (j - (a12*i + b12)) < 0) ok = 0; if (s1 * (j - (a23*i + b23)) < 0) ok = 0; if (s2 * (j - (a31*i + b31)) < 0) ok = 0; if (ok) add_pix(i,j,color); } if (SDL_AFFICHE_AUTO) affiche_all(); }
// 4.10 Dessine un triangle void draw_triangle(POINT p1, POINT p2, POINT p3, COULEUR color) { draw_line(p1,p2,color); draw_line(p2,p3,color); draw_line(p3,p1,color); if (SDL_AFFICHE_AUTO) affiche_all(); }
// 3.3 Attend que l'on tape Echap et quitte // Instruction bloquante void wait_escape() { int display = 1; SDL_Event event; POINT p; char *texte = "Appuyer sur Echap pour terminer"; int taille = 20; p.x = WIDTH/2 - largeur_texte(texte,taille)/2; p.y = hauteur_texte(texte,taille); aff_pol(texte,taille,p,gris); affiche_all(); while (SDL_WaitEvent(&event) && display) { /* Si l'utilisateur a demandé à fermer la fenêtre, on quitte */ if (event.type == SDL_QUIT) exit(0); /* Si l'utilisateur a appuyé sur une touche */ if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { case SDLK_ESCAPE : display=0; break; default : break; } } } /* Fermeture de la police */ #ifdef SDL_TTF_OK int i; if (police_ok) for (i=0;i<256;i++) if (police[i]) TTF_CloseFont(police[i]); TTF_Quit(); #endif SDL_Quit(); }
void afficheCarte() { POINT bg; bg.x = 0; bg.y = 600; affiche_image("../data/img/map.bmp",bg,1100,600); colorierSommets(); //affiche un cercle sur tous les sommets affiche_all(); }
void afficheBoutonRecommencer() { POINT P1 = {730,530}; POINT P2 = {860,580}; draw_fill_rectangle(P1,P2,couleur_RGB(38,196,236)); draw_rectangle(P1,P2,black); P1.x = 737; P1.y = 566; aff_pol("RECOMMENCER",15,P1,noir); affiche_all(); }
// ################## // 4. DESSIN D'OBJETS // ################## void affiche_image(char *nomfic, POINT bg, int w, int h) { SDL_Surface *image = NULL; SDL_Rect rect; rect.x = bg.x; rect.y = HEIGHT-bg.y; rect.w = w; rect.h = h; image = SDL_LoadBMP(nomfic); if (image == NULL) fprintf(stderr,"Impossible charger l'image : %s\n",nomfic); /* On blitte par-dessus l'écran */ SDL_BlitSurface(image, NULL, SDL_screen, &rect); if (SDL_AFFICHE_AUTO) affiche_all(); }
void afficheBoutonRecommencerSombre() { POINT P1 = {730,530}; POINT P2 = {860,580}; draw_fill_rectangle(P1,P2,couleur_RGB(25,180,220)); draw_rectangle(P1,P2,black); P1.x = 737; P1.y = 566; aff_pol("RECOMMENCER",15,P1,noir); affiche_all(); attendre(150); }
// 4.5 Dessine un rectangle rempli // Les deux points sont deux points quelconques // non adjacents du rectangle void draw_fill_rectangle(POINT p1, POINT p2, COULEUR color) { int xmin, xmax; int ymin, ymax; int i,j; if (p1.x < p2.x) {xmin=p1.x; xmax=p2.x;} else{xmin=p2.x; xmax=p1.x;} if (p1.y < p2.y) {ymin=p1.y; ymax=p2.y;} else{ymin=p2.y; ymax=p1.y;} for (i=xmin;i<=xmax;i++) for (j=ymin;j<=ymax;j++) add_pix(i,j,color); if (SDL_AFFICHE_AUTO) affiche_all(); }
int clicSommet(POINT clic, COULEUR c) { //renvoie l'indice du sommet cliqué et -1 sinon int i; for (i = 0; i < V; i++) { if (clic.x < points[i].x + 5 && clic.x > points[i].x - 5 && clic.y < points[i].y + 5 && clic.y > points[i].y - 5) { draw_fill_circle(points[i],5,c); affiche_all(); return i; } } return -1; }
// 2.1 Initialisation de la fenêtre sur laquelle on dessine // W et H sont la largeur et la hauteur désirée. // La variable globale SDL_screen est initialisée void init_graphics(int W, int H) { // Initialisation d'une taille raisonnable if ((W>10) && (W<MAX_WIDTH )) WIDTH = W; else WIDTH = 640; if ((H>10) && (H<MAX_HEIGHT)) HEIGHT = H; else HEIGHT = 480; // Initialisation de la SDL_surface SDL_Init(SDL_INIT_VIDEO); SDL_screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE|SDL_DOUBLEBUF); if ( SDL_screen == NULL ) { fprintf(stderr, "Impossible de passer en %dx%d en 32 bits: %s\n", WIDTH, HEIGHT, SDL_GetError()); exit(1); } WIDTH = SDL_screen->w; HEIGHT = SDL_screen->h; printf("Ecran de %d x %d\n",WIDTH,HEIGHT); // Supprime le curseur de la souris dans la fenêtre // SDL_ShowCursor(SDL_DISABLE); // Autorise la prise en compte de répétition lors d'un appui // long sur une touche SDL_EnableKeyRepeat(1,0); // Le titre de la fenêtre SDL_WM_SetCaption("UVSQ -- Machines Virtuelles",NULL); __init_graphics_is_already_called = 25; #ifdef SDL_TTF_OK printf("SDL_ttf OK, "); // Ouverture de la police TTF_Init(); police[10] = TTF_OpenFont(POLICE_NAME, 10); if (police[10]) {police_ok=1; printf("police %s OK : affichage graphique OK.\n",POLICE_NAME);} else {police_ok = 0; printf("police %s absente : affichage dans la console.\n",POLICE_NAME);} #else printf("SDL_ttf absent : affichage dans la console.\n"); #endif // Remplit la fenêtre de noir fill_screen(noir); affiche_auto_on(); affiche_all(); }
// 5.1 Affiche du texte avec // Le texte est passé dans l'argument "a_ecrire" // la police est celle définie par la constante POLICE_NAME // dans graphics.c // la taille est passée en argument // l'argument p de type POINT est le point en haut à gauche // à partir duquel le texte s'affiche // la COULEUR C passée en argument est la couleur d'affichage // Nécessite l'installation de SDL_ttf.h void aff_pol(char *a_ecrire, int taille, POINT p, COULEUR C) { #ifdef SDL_TTF_OK int i; SDL_Color color; SDL_Surface *texte = NULL; SDL_Rect position; static int premiere_fois = 1; static TTF_Font *police[256]; // TTF_Font *pol; int style; // Initialisation de la police (n'est fait qu'une seule fois pour les tailles < 256) if (premiere_fois) { TTF_Init(); for (i=0;i<256;i++) police[i] = NULL; premiere_fois = 0; ___pol = NULL;} if (___pol) style = TTF_GetFontStyle(___pol); else style = NORMAL; if (taille>=256) ___pol = TTF_OpenFont(POLICE_NAME, taille); else { if (police[taille]==NULL) police[taille] = TTF_OpenFont(POLICE_NAME, taille); ___pol = police[taille]; } SDL_GetRGB(C,SDL_screen->format,&(color.r),&(color.g),&(color.b)); TTF_SetFontStyle(___pol,style); // ___pol = pol; /* Ecriture du texte dans la SDL_Surface "texte" en mode Blended (optimal) */ if (___pol) texte = TTF_RenderText_Blended(___pol, a_ecrire, color); else texte = NULL; if (texte) { position.x = p.x; position.y = HEIGHT - p.y; SDL_BlitSurface(texte, NULL, SDL_screen, &position); /* Blit du texte par-dessus */ if (SDL_AFFICHE_AUTO) affiche_all(); SDL_FreeSurface(texte); } else printf("%s\n",a_ecrire); /* if (SDL_AFFICHE_AUTO) affiche_all(); if (police) TTF_CloseFont(police); TTF_Quit(); if (texte) SDL_FreeSurface(texte); */ #else taille = 0; p.x = p.y = 0; C = 0; printf("%s\n",a_ecrire); #endif }
// 4.3 Dessine un segment void draw_line(POINT p1, POINT p2, COULEUR color) { int xmin, xmax; int ymin, ymax; int i,j; float a,b,ii,jj; if (p1.x < p2.x) {xmin=p1.x; xmax=p2.x;} else{xmin=p2.x; xmax=p1.x;} if (p1.y < p2.y) {ymin=p1.y; ymax=p2.y;} else{ymin=p2.y; ymax=p1.y;} if (xmin==xmax) for (j=ymin;j<=ymax;j++) add_pix(xmin,j,color); if (ymin==ymax) for (i=xmin;i<=xmax;i++) add_pix(i,ymin,color); // La variation la plus grande est en x if ((xmax-xmin >= ymax-ymin) && (ymax-ymin>0)) { a = (float)(p1.y-p2.y) / ((float)(p1.x-p2.x)); b = p1.y - a*p1.x; for (i=xmin;i<=xmax;i++) { jj = a*i+b; j = jj; if (((jj-j) > 0.5) && (j < HEIGHT-1)) j++; add_pix(i,j,color); } } // La variation la plus grande est en y if ((ymax-ymin > xmax-xmin) && (xmax-xmin>0)) { a = (float)(p1.y-p2.y) / ((float)(p1.x-p2.x)); b = p1.y - a*p1.x; for (j=ymin;j<=ymax;j++) { ii = (j-b)/a; i = ii; if (((ii-i) > 0.5) && (i < WIDTH-1)) i++; add_pix(i,j,color); } } if (SDL_AFFICHE_AUTO) affiche_all(); }
// 4.7 Dessine un cercle rempli void draw_fill_circle(POINT centre, int rayon, COULEUR color) { POINT min, max; int i,j; float dx, dy, rr; min.x = centre.x - rayon; max.x = centre.x + rayon; min.y = centre.y - rayon; max.y = centre.y + rayon; rr = rayon*rayon; for (i=min.x;i<=max.x;i++) { dx = i - centre.x; for (j=min.y;j<=max.y;j++) { dy = j - centre.y; if (dx*dx + dy*dy <= rr) add_pix(i,j,color); } } if (SDL_AFFICHE_AUTO) affiche_all(); }
// 4.9 Dessine une ellipse remplie // Les arguments F1 et F2 sont les focales et r est // la somme des distances à chacun des points focaux void draw_fill_ellipse(POINT F1, POINT F2, int r, COULEUR color) { int i,j; int dx, fx; int dy, fy; float d, d1, d2; d = (F1.x-F2.x)*(F1.x-F2.x) + (F1.y-F2.y)*(F1.y-F2.y); d = sqrt(d); if (F1.x<F2.x) {dx = F1.x - d - r; fx = F2.x + d + r;} else {dx = F2.x - d - r; fx = F1.x + d + r;} if (F1.y<F2.y) {dy = F1.y - d - r; fy = F2.y + d + r;} else {dy = F2.y - d - r; fy = F1.y + d + r;} for (i=dx;i<=fx;i++) for (j=dy;j<=fy;j++) if (dans_ecran(i,j)) { d1 = (i-F1.x)*(i-F1.x) + (j-F1.y)*(j-F1.y); d1 = sqrt(d1); d2 = (i-F2.x)*(i-F2.x) + (j-F2.y)*(j-F2.y); d2 = sqrt(d2); if (d1+d2 < d+r) add_pix(i,j,color); } if (SDL_AFFICHE_AUTO) affiche_all(); }
// La fonction synchro est la fonction historique void synchro() { affiche_all(); }
// 4.2 Affichage un pixel void draw_pixel(POINT p, COULEUR color) { add_pix(p.x,p.y,color); if (SDL_AFFICHE_AUTO) affiche_all(); }