morpion/graphics.c

472 lines
11 KiB
C
Raw Permalink Blame History

#include "graphics.h"
#include "police.h"
#define EN_LOCAL
#ifdef SDL_TTF_OK
#include <SDL_ttf.h>
#include <SDL/SDL_ttf.h>
#define POLICE_NAME "verdana.ttf"
TTF_Font *police[256];
int verdana_ok = 0;
#endif
int WIDTH;
int HEIGHT;
SDL_Surface * SDL_screen;
int __init_graphics_is_already_called = 0;
int SDL_AFFICHE_AUTO = 1;
#define MAX_WIDTH 1920
#define MAX_HEIGHT 1080
void init_graphics(int W, int H) {
if ((W>10) && (W<MAX_WIDTH ))
WIDTH = W;
else WIDTH = 600;
if ((H>10) && (H<MAX_HEIGHT))
HEIGHT = H;
else HEIGHT = 400;
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);
}
SDL_EnableKeyRepeat(1,0);
SDL_WM_SetCaption("Morpion !!",NULL);
__init_graphics_is_already_called = 25;
printf("Fenetre de %d x %d\n",WIDTH,HEIGHT);
#ifdef SDL_TTF_OK
printf("SDL_ttf OK, ");
TTF_Init();
police[10] = TTF_OpenFont(POLICE_NAME, 10);
if (police[10]) {
verdana_ok=1; printf("police %s OK : affichage graphique OK.\n",POLICE_NAME);
}
else {
verdana_ok = 0; printf("police %s absente : affichage dans la console.\n",POLICE_NAME);
}
#else
printf("SDL_ttf absent : affichage dans la console.\n");
#endif
fill_screen(black);
affiche_auto_on();
affiche_all();
}
void affiche_auto_on () {
SDL_AFFICHE_AUTO = 1;
}
void affiche_auto_off() {
SDL_AFFICHE_AUTO = 0;
}
void affiche_all() {
SDL_Event event;
if (SDL_PollEvent(&event))
if (event.type == SDL_QUIT)
exit(0);
if (__init_graphics_is_already_called == 25)
SDL_Flip(SDL_screen);
else {
init_graphics(380,80);
write_text("init_graphics() n'a pas <20>t<EFBFBD> appel<65>e.");
write_text("");
write_text(" Cliquer pour terminer.");
fprintf(stderr,"init_graphics() n'a pas <20>t<EFBFBD> appel<65>e.\n");
fprintf(stderr,"Cliquer pour terminer.\n");
wait_clic();
exit(1);
}
}
void synchro() { affiche_all(); }
couleur couleur_RGB(int r, int g, int b) {
couleur C;
return ((r%256)<<16) + ((g%256)<<8) + (b%256);
return C;
}
point get_mouse() {
point dep;
dep.x = dep.y = -1;
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
exit(0);
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE : exit(0);
default : break;
}
}
if (event.type == SDL_MOUSEMOTION)
{
dep.x = event.motion.x;
dep.y = event.motion.y;
}
}
return dep;
}
void wait_escape() {
int display = 1;
SDL_Event event;
point p;
p.x = WIDTH/2 - 170;
p.y = 25;
aff_pol("Appuyer sur Echap pour terminer",20,p,gris);
affiche_all();
while (SDL_WaitEvent(&event) && display) {
if (event.type == SDL_QUIT) exit(0);
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_ESCAPE : display=0; break;
default : break;
}
}
}
#ifdef SDL_TTF_OK
int i;
if (verdana_ok) for (i=0;i<256;i++) if (police[i]) TTF_CloseFont(police[i]);
TTF_Quit();
#endif
SDL_Quit();
}
point wait_clic() {
int encore = 1;
point P;
SDL_Event event;
P.x = 0;
P.y = 0;
#ifdef EN_LOCAL
#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) {
if ((event.type == SDL_MOUSEBUTTONDOWN) && (event.button.button == SDL_BUTTON_LEFT)) {
encore=0;
P.x = event.button.x;
P.y = HEIGHT-event.button.y;
}
if (event.type == SDL_MOUSEMOTION) {
#ifdef EN_LOCAL
#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);
}
if (event.type == SDL_QUIT) exit(0);
}
#ifdef EN_LOCAL
#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);
return P;
}
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 dans_ecran(int x, int y) {
if (x<0) return 0;
if (x>=WIDTH) return 0;
if (y<0) return 0;
if (y>=HEIGHT) return 0;
return 1;
}
#define add_pix(x,y,color) if (dans_ecran((x),(y))) *((couleur *)SDL_screen->pixels + (HEIGHT-(y)-1) * WIDTH + (x)) = (color)
void draw_pixel(point p, couleur color) {
add_pix(p.x,p.y,color);
if (SDL_AFFICHE_AUTO) affiche_all();
}
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();
}
void draw_big_line(point p1, point p2, couleur color) {
draw_line(p1, p2, color);
p1.x = p1.x-1;p2.x = p2.x-1;
draw_line(p1, p2, color);
p1.x = p1.x+2;p2.x = p2.x+2;
draw_line(p1, p2, color);
p1.x = p1.x-1;p2.x = p2.x-1;
p1.y = p1.y-1;p2.y = p2.y-1;
draw_line(p1, p2, color);
p1.y = p1.y+2;p2.y = p2.y+2;
draw_line(p1, p2, color);
}
void draw_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++) add_pix(i,ymin,color);
for (i=xmin;i<=xmax;i++) add_pix(i,ymax,color);
for (j=ymin;j<=ymax;j++) add_pix(xmin,j,color);
for (j=ymin;j<=ymax;j++) add_pix(xmax,j,color);
if (SDL_AFFICHE_AUTO) affiche_all();
}
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();
}
void draw_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;
dy = sqrt(rr - dx*dx);
j = centre.y + dy;
add_pix(i,j,color);
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);
i = centre.x - dx;
add_pix(i,j,color);
}
if (SDL_AFFICHE_AUTO) affiche_all();
}
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();
}
void draw_square(point p, int taille, couleur color) {
point p1 = {p.x-taille/2, p.y-taille/2}, p2 = {p.x+taille/2, p.y+taille/2};
draw_rectangle(p1, p2, color);
}
void draw_fill_square(point p, int taille, couleur color) {
point p1 = {p.x-taille/2, p.y-taille/2}, p2 = {p.x+taille/2, p.y+taille/2};
draw_fill_rectangle(p1, p2, color);
}
void draw_cross(point p, int taille, couleur color) {
point p1 = {p.x-taille/2, p.y-taille/2}, p2 = {p.x+taille/2, p.y+taille/2};
point p3 = {p.x-taille/2, p.y+taille/2}, p4 = {p.x+taille/2, p.y-taille/2};
draw_line(p1, p2, color);
draw_line(p3, p4, color);
}
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;
if (premiere_fois) {
TTF_Init(); for (i=0;i<256;i++) police[i] = NULL; premiere_fois = 0;
}
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));
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);
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
}
void aff_int(int n, int taille, point p, couleur C) {
char s[32];
sprintf(s,"%d",n);
aff_pol(s,taille,p,C);
}
void attendre(int millisecondes) { SDL_Delay(millisecondes); }
float alea_float() {
static int init_alea = 1;
if (init_alea) srand(time(NULL));
init_alea = 0;
return (float)rand() / (float)RAND_MAX;
}
int alea_int(int N) { return (int)(N*alea_float()); }
void write_text(char *a_ecrire) {
#ifdef SDL_TTF_OK
static char s[256];
static int fin = 0;
static int premier = 1;
static point position;
if (premier) {
position.x = 10;
position.y = HEIGHT;
premier = 0;
}
if (verdana_ok)
{
// printf("verd\n");
if (a_ecrire) {
if (fin+strlen(a_ecrire) > 256) {
fprintf(stderr,"Chaine de caract<63>re trop longue\n");
return;
}
strcat(s+fin,a_ecrire);
// printf("a_ecr : #%s#\n",s);
aff_pol(s,20,position,blanc);
fin += strlen(a_ecrire);
s[fin] = '\0';
}
else {
position.y -= 20;
fin = 0;
s[fin] = '\0';
}
}
else {
if (a_ecrire) {
printf("%s",a_ecrire);
fflush(stdout);
}
else printf("\n");
}
#else
if (a_ecrire) {printf("%s",a_ecrire); fflush(stdout);}
else printf("\n");
#endif
}