File: fct.c

package info (click to toggle)
dossizola 1.0-9
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,524 kB
  • ctags: 450
  • sloc: ansic: 2,048; sh: 332; makefile: 75
file content (277 lines) | stat: -rw-r--r-- 10,266 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#include <SDL/SDL.h>
#include "isola.h"

// ****************************************************************************
// ********************************** Alea ************************************
// ****************************************************************************
int Alea (short min, short max)
{
	return (unsigned short)rand() * (max - min) / 65536 + min;
}


// ****************************************************************************
// ****************************** ImageErreur *********************************
// ****************************************************************************
void ImageErreur (char *image)
{
	// Affiche un message d'erreur et quitte le programme
	fprintf (stderr, "Impossible de charger l'image %s (%s)\n", image, SDL_GetError ());
	exit (1);
}


// ****************************************************************************
// ****************************** Case2Coord **********************************
// ****************************************************************************
int Case2CoordX (int x, GRILLE grille)
{
	// Renvoit l'abscisse �cran du coin haut gauche de la case
	return grille.x1 + x * grille.tc;
}

int Case2CoordY (int y, GRILLE grille)
{
	// Renvoit l'abscisse �cran du coin haut gauche de la case
	return grille.y1 + y * grille.tc;
}


// ****************************************************************************
// ****************************** Clic2Case ***********************************
// ****************************************************************************
int Clic2CaseX (int x, GRILLE grille)
{
	// Renvoit l'abscisse de la case cliqu�e ou -1 si en dehors de la grille
	if (x >= grille.x1 && x < grille.x2)
		return (x - grille.x1 - 1) / grille.tc;
	else
		return -1;
}

int Clic2CaseY (int y, GRILLE grille)
{
	// Renvoit l'ordonn�e de la case cliqu�e ou -1 si en dehors de la grille
	if (y >= grille.y1 && y <= grille.y2)
		return (y - grille.y1 - 1) / grille.tc;
	else
		return -1;
}


// ****************************************************************************
// ******************************* Attendre_FPS *******************************
// ****************************************************************************
void Attendre_FPS (void)
{
	static int temps = 0;				// Moment du dernier appel de cette fonction
	
	// Marque une pause pour synchroniser l'affichage sur la vitesse choisie pour que
	// le temps entre 2 appels de cette fonction soit de: 1000 ms / Frames Par Seconde
	while (SDL_GetTicks() < temps + 1000 / FPS);
	
	temps = SDL_GetTicks ();			// Moment o� cette fonction se termine
}


// ****************************************************************************
// ********************************* Dans_Rect ********************************
// ****************************************************************************
BOOL Dans_Rect (int x, int y, SDL_Rect rect)
{
	if (x >= rect.x && x <= (rect.x + rect.w) && y >= rect.y && y <= (rect.y + rect.h))
		return OUI;
	else
		return NON;
}


// ****************************************************************************
// ************************** Afficher_Caractere ******************************
// ****************************************************************************
void Afficher_Caractere (int x, int y, char c, POLICE police, SDL_Surface *ecran)
{
	SDL_Rect dest;

	// Place le rectangle sur la bonne image du caract�re � afficher
	if (c >= 'A' && c <= 'Z') police.rect.x = (c - 'A') * police.rect.w;
	else if (c >= 'a' && c <= 'z') police.rect.x = (c - 'a') * police.rect.w;
	else if (c >= '0' && c <= '9') police.rect.x = (c - '0' + 26) * police.rect.w;
	else if (c == ':') police.rect.x = 36 * police.rect.w;
	else return;

	// Position sur l'�cran
	dest.x = x;
	dest.y = y;
	dest.w = police.rect.w;
	dest.h = police.rect.h;

	// Copie le caract�re et met � jour
	SDL_BlitSurface (police.img, &police.rect, ecran, &dest);
	SDL_UpdateRects (ecran, 1, &dest);
}


// ****************************************************************************
// **************************** Afficher_Chaine *******************************
// ****************************************************************************
BOOL Afficher_Chaine (int x, int y, int vitesse, char chaine[], POLICE police, SDL_Surface *ecran, SDL_Surface *back)
{
	SDL_Rect dest = {0, 0, police.rect.w, police.rect.h};
	SDL_Event evt;
	int xDep, yDep, xDest, yDest;
	int c;
	int frame;

	// Parcours la chaine de caract�re et affiche les caract�res un par un en
	// les faisant glisser de l'un des bord de l'�cran
	for (c = 0; chaine[c] != '\0'; c ++)
	{
		// Choisit al�atoirement le bord de l'�cran et sa position dessus
		switch (Alea (0, 2))
		{
			case 0:	xDep = Alea (0, ecran->w - police.rect.w);
					yDep = Alea (0, 2) ? 0 : ecran->h - police.rect.h;
					break;
			case 1:	xDep = Alea (0, 2) ? 0 : ecran->w - police.rect.w;
					yDep = Alea (0, ecran->h - police.rect.h);
					break;
			default:	xDep = yDep = 0;
		}
		
		xDest = x + c * police.rect.w;
		yDest = y;
		
		// Fait glisser le caract�re du bord de l'�cran vers sa position finale
		if (vitesse > 0)
		for (frame = 0; frame <= vitesse; frame ++)
		{
			// Quitte sur un appui sur la touche [ESC]
			if (SDL_PollEvent (&evt) && evt.type == SDL_KEYDOWN && evt.key.keysym.sym == SDLK_ESCAPE) return OUI;
		
			// Efface l'ancienne position
			SDL_BlitSurface (back, &dest, ecran, &dest);
			
			// Affiche le caract�re au bon endroit
			Afficher_Caractere (xDep + ((xDest - xDep) * frame) / vitesse, yDep + ((yDest - yDep) * frame) / vitesse, chaine[c], police, ecran);
			SDL_UpdateRects (ecran, 1, &dest);
			
			// Fait la moyenne pour savoir o� doit �tre affich� le caract�re
			dest.x = xDep + ((xDest - xDep) * frame) / vitesse;
			dest.y = yDep + ((yDest - yDep) * frame) / vitesse;
			Attendre_FPS ();
		}

		// Affiche le caract�re � sa position finale
		Afficher_Caractere (xDest, yDest, chaine[c], police, ecran);
		Afficher_Caractere (xDest, yDest, chaine[c], police, back);
	}
	
	return NON;
}


// ****************************************************************************
// ******************************* Questionner ********************************
// ****************************************************************************
BOOL Questionner (char ch[], POLICE police1, POLICE police2, POLICE police3, SDL_Surface *ecran)
{
	SDL_Surface *save, *noire;
	SDL_Event evt;
	SDL_Rect box;			// Rect de copie de la "boite de dialogue"
	SDL_Rect oui, non;		// Rects de cliquage des boutons OUI et NON
	
	// Rect de la boite de dialogue du message
	box.w = police1.rect.w * (strlen (ch) + 3);
	box.h = police1.rect.h * 5;
	box.x = (ecran->w - box.w) / 2;
	box.y = (ecran->h - box.h) / 2 + police1.rect.h / 3;
	
	// Cr�e une surface pour sauvegarder la partie de l'�cran qui sera recouverte par le message
	save = SDL_CreateRGBSurface (SDL_SWSURFACE, box.w, box.h, 32, 0, 0, 0, 0);
	SDL_BlitSurface (ecran, &box, save, NULL);
	
	// Cr�e une surface noire semi-transparente qui servira � assombrir une partie de l'�cran
	if (!(noire = SDL_DisplayFormat (save)))
	{ 	fprintf (stderr, "Impossible de cr�er un back buffer (%s)\n", SDL_GetError ());
		SDL_FreeSurface (save);
		SDL_FreeSurface (noire);
		exit (1);
	}
	SDL_FillRect (noire, NULL, SDL_MapRGB (noire->format, 0, 0, 0));
	SDL_SetAlpha (noire, SDL_SRCALPHA, 255 - 128);
	
	// Assombrit l'�cran et met � jour
	SDL_BlitSurface (noire, NULL, ecran, &box);
	SDL_UpdateRects (ecran, 1, &box);
	SDL_FreeSurface (noire);
	
	// Rects des boutons OUI et NON
	oui.w = strlen (TXT_OUI) * police3.rect.w;
	oui.h = police3.rect.h;
	oui.x = ecran->w / 2 + police3.rect.w;
	oui.y = ecran->h / 2 + police3.rect.h;
	
	non.w = strlen (TXT_NON) * police2.rect.w;
	non.h = police2.rect.h;
	non.x = ecran->w / 2 - non.w - police2.rect.w;
	non.y = ecran->h / 2 + police2.rect.h;
	
	// Affiche le texte de la question et les textes des boutons OUI et NON
	Afficher_Chaine ((ecran->w - strlen (ch) * police1.rect.w) / 2, ecran->h / 2 - police1.rect.h, 0, ch, police1, ecran, ecran);
	Afficher_Chaine (oui.x, oui.y, 0, TXT_OUI, police2, ecran, ecran);
	Afficher_Chaine (non.x, non.y, 0, TXT_NON, police3, ecran, ecran);
	
	while (1)
	if (SDL_PollEvent (&evt))
	{	
		// Anulle sur un appui de la touche [ESC], ou un clic sur NON
		if ((evt.type == SDL_KEYDOWN && evt.key.keysym.sym == SDLK_ESCAPE) || (evt.type == SDL_MOUSEBUTTONDOWN && evt.button.button == 1 && Dans_Rect (evt.button.x, evt.button.y, non)))
		{	SDL_BlitSurface (save, NULL, ecran, &box);
			SDL_UpdateRects (ecran, 1, &box);
			SDL_FreeSurface (save);
			return NON;
		}
		
		// Retourne OUI � la fonction ayant pos� cette question
		if (evt.type == SDL_MOUSEBUTTONDOWN && evt.button.button == 1 && Dans_Rect (evt.button.x, evt.button.y, oui))
		{	SDL_BlitSurface (save, NULL, ecran, &box);
			SDL_UpdateRects (ecran, 1, &box);
			SDL_FreeSurface (save);
			return OUI;
		}
	}
}


// ****************************************************************************
// ******************************** Informer **********************************
// ****************************************************************************
BOOL Informer (char ch[], POLICE police, SDL_Surface *ecran)
{
	SDL_Rect box;			// Rect de copie de la "boite de dialogue"
	SDL_Surface *noire;
	
	// Rect de la boite de dialogue du message
	box.w = police.rect.w * (strlen (ch) + 3);
	box.h = police.rect.h * 3;
	box.x = (ecran->w - box.w) / 2;
	box.y = (ecran->h - box.h) / 2;
	
	// Cr�e une surface noire semi-transparente qui servira � assombrir une partie de l'�cran
	if (!(noire = SDL_CreateRGBSurface (SDL_SWSURFACE, box.w, box.h, 32, 0, 0, 0, 0)))
	{ 	fprintf (stderr, "Impossible de cr�er une surface (%s)\n", SDL_GetError ());
		SDL_FreeSurface (noire);
		exit (1);
	}
	SDL_FillRect (noire, NULL, SDL_MapRGB (noire->format, 0, 0, 0));
	SDL_SetAlpha (noire, SDL_SRCALPHA, 255 - 128);
	
	// Assombrit l'�cran et met � jour
	SDL_BlitSurface (noire, NULL, ecran, &box);
	SDL_UpdateRects (ecran, 1, &box);
	SDL_FreeSurface (noire);
	
	// Affiche le texte de la question et les textes des boutons OUI et NON
	Afficher_Chaine ((ecran->w - strlen (ch) * police.rect.w) / 2, (ecran->h - police.rect.h) / 2, 0, ch, police, ecran, ecran);
}