bonjour à tous,
je suis sur un projet de jeu pokémon en C/SDL. Je me suis basé sur un tuto trouvé sur Internet en y ajoutant du "mapping en 3 couches".

fmap.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#include <string.h>//pour pouvoir utiliser memset et strcmp
#include "fmap.h"
 
 
 
 
 
Map* ChargerMap(const char* couche1, const char* couche2, const char* couche3, const char* image_corr, const char* tileset, const char* tileprop, int largeur_tile, int hauteur_tile, int hauteur_fenetre, int largeur_fenetre)
{
    int i,j;
    Map* res;
    SDL_Surface *schema1, *schema2, *schema3, *corr;
    Uint32 pix;
 
    res = malloc(sizeof(Map));
    res->LARGEUR_TILE = largeur_tile;
    res->HAUTEUR_TILE = hauteur_tile;
    res->tileset = LoadImage32(tileset,1);  // charge le tileset en VRAM pour meilleur vitesse de Blit.
    schema1 = LoadImage32(couche1, 0);
    schema2 = LoadImage32(couche2, 0);
    schema3 = LoadImage32(couche3, 0);
    corr = LoadImage32(image_corr,0);
 
    if (res->tileset == NULL || res->schema1 == NULL || res->schema2 == NULL || res->schema3 == NULL || corr == NULL)
    {
        fprintf(stderr, "error %s", SDL_GetError());
        exit(EXIT_FAILURE);
    }
 
    res->nbtiles = (res->tileset->w / largeur_tile) * (res->tileset->h / hauteur_tile);// =>nb de tiles sur le tileset
    /* TODO (sylvain#1#): voir pour ajouter propriété pour gérer collision */
    res->props = ChargerProps(tileprop, res->nbtiles);//charge tableau avec les propriétés
    CalculerSDLRects(res->props, res->nbtiles, res->tileset->w / largeur_tile, largeur_tile, hauteur_tile);
    res->nbtiles_largeur_monde = schema1->w;
    res->nbtiles_hauteur_monde = schema1->h;
 
            //couche 1
    res->schema1 = malloc(schema1->w * sizeof(char*));
    for(i=0; i<schema1->w; i++)
    {
        res->schema1[i] = malloc(schema1->h * sizeof(char));
        for(j=0; j<schema1->h; j++)
        {
            pix = GetPixel32(schema1,i,j);
            res->schema1[i][j] = LocatePixInCorr(corr,pix);
        }
    }
            //couche 2
    res->schema2 = malloc(schema2->w * sizeof(char*));
    for(i=0; i<schema2->w; i++)
    {
        res->schema2[i] = malloc(schema2->h * sizeof(char));
        for(j=0; j<schema2->h; j++)
        {
            pix = GetPixel32(schema2,i,j);
            res->schema2[i][j] = LocatePixInCorr(corr,pix);
        }
    }
            //couche 3
    res->schema3 = malloc(schema3->w * sizeof(char*));
    for(i=0; i<schema3->w; i++)
    {
        res->schema3[i] = malloc(schema3->h * sizeof(char));
        for(j=0; j<schema3->h; j++)
        {
            pix = GetPixel32(schema3,i,j);
            res->schema3[i][j] = LocatePixInCorr(corr,pix);
        }
    }
 
 
    SDL_FreeSurface(schema1);
    SDL_FreeSurface(schema2);
    SDL_FreeSurface(schema3);
    SDL_FreeSurface(corr);
    res->largeur_fenetre = largeur_fenetre;
    res->hauteur_fenetre = hauteur_fenetre;
    res->xscroll = 0;
    res->yscroll = 0;
    return res;
}
 
 
 
TileProp* ChargerProps(const char* tileprop, int nombre_props)
{
    char buf[500];
    FILE* F;
    int i;
    int useless;
    TileProp* res = calloc(nombre_props,sizeof(TileProp)); // alloue et met tout a 0.
    F = fopen(tileprop,"r");
    if (F==NULL)
    {
        printf("fichier %s introuvable !!\n",tileprop);
        exit(-1);
    }
    for(i=0; i<nombre_props; i++)
    {
        fscanf(F,"%d %s",&useless,buf);//on met le n° de tile dans useless (qu'on utilise pas) et la "propriété" dans buf
 
        if (strcmp(buf,"mur")==0)//on compare la propriété lue avec mur, si c'est la même on renvoie 0
            res[i].mur = 1;
 
        if(strcmp(buf, "vide")==0)
            res[i].vide = 1;
    }
    fclose(F);
    return res;
}
 
 
 
char LocatePixInCorr(SDL_Surface* corr, Uint32 pix)
{
    int i,j;
    for(j=0; j<corr->h; j++)
        for(i=0; i<corr->w; i++)
            if (GetPixel32(corr,i,j)==pix)
                return (char)(j*corr->w + i);
    return 0;
}
 
 
 
void CalculerSDLRects(TileProp* tabprops, int nombre_props, int nombre_tiles_largeur, int largeur_tile, int hauteur_tile)
{
    int i;
    for(i=0; i<nombre_props; i++)
    {
        tabprops[i].R.w = largeur_tile;
        tabprops[i].R.h = hauteur_tile;
        tabprops[i].R.x = largeur_tile*(i%nombre_tiles_largeur);
        tabprops[i].R.y = hauteur_tile*(i/nombre_tiles_largeur);
    }
}
 
 
 
Perso* ChargerPerso(const char* sprite, int x, int y, int w, int h)
{
    Perso* p;
 
    p = malloc(sizeof(Perso));
    p->sprite = SDL_LoadBMP(sprite);
    if (p->sprite == NULL)
    {
        fprintf(stderr, "error %s", SDL_GetError());
        exit(EXIT_FAILURE);
    }
 
    p->R.x = x;
    p->R.y = y;
    p->R.w = w;
    p->R.h = h;
 
    return p;
}
 
 
 
Perso* Deplace(Input* in, Map* carte, Perso* perso, int LARGEUR_TILE, int HAUTEUR_TILE)//deplace le perso
{
    switch(in->key[SDLK_LAST])
    {
        case SDLK_UP:
            if (CollisionDecor(carte, perso, 0) == 0);//pas de collision
            {
                perso->R.y+=HAUTEUR_TILE;
            }
            break;
 
        case SDLK_DOWN:
            if (CollisionDecor(carte, perso, 1) == 0);//pas de collision
            {
                perso->R.y-=HAUTEUR_TILE;
            }
            break;
 
        case SDLK_LEFT:
            if (CollisionDecor(carte, perso, 2) == 0);//pas de collision
            {
                perso->R.x-=LARGEUR_TILE;
            }
            break;
 
        case SDLK_RIGHT:
            if (CollisionDecor(carte, perso, 3) == 0);//pas de collision
            {
                perso->R.x+=LARGEUR_TILE;
            }
            break;
 
        default:
            break;
    }
    return perso;
}
 
 
 
int CollisionDecor(Map* carte, Perso* perso, char dir)
{
    int xmin, xmax, ymin, ymax, i, j, indicetile;
 
    xmin = perso->R.x / carte->LARGEUR_TILE;
    ymin = perso->R.y / carte->HAUTEUR_TILE;
    xmax = (perso->R.x + perso->R.w -1) / carte->LARGEUR_TILE;
    ymax = (perso->R.y + perso->R.h -1) / carte->HAUTEUR_TILE;
 
    if (xmin<0 || ymin<0 || xmax>=carte->nbtiles_largeur_monde || ymax>=carte->nbtiles_hauteur_monde)//si on cherche a sortir du monde on renvoie "collision"
        return 1;// collision
 
 
    for(i=xmin; i<=xmax; i++) //la double boucle parcours les tiles sur lequel se situe le perso
    {
        for(j=ymin; j<=ymax; j++)
        {
            indicetile = carte->schema2[i][j];
            if (carte->props[indicetile].mur)
                return 1;//collision
        }
    }
    return 0;//pas de collision
}
 
 
 
int FocusScrollCenter(Map* carte, Perso* perso)
{
    carte->xscroll = perso->R.x + perso->R.w/2 - carte->largeur_fenetre/2;
    carte->yscroll = perso->R.y + perso->R.h/2 - carte->hauteur_fenetre/2;
    ClampScroll(carte);
    return 0;
}
 
 
 
void ClampScroll(Map* m)
{
    if (m->xscroll<0)
        m->xscroll=0;
 
    if (m->yscroll<0)
        m->yscroll=0;
 
    if (m->xscroll>m->nbtiles_largeur_monde*m->LARGEUR_TILE-m->largeur_fenetre-1)
        m->xscroll=m->nbtiles_largeur_monde*m->LARGEUR_TILE-m->largeur_fenetre-1;
 
    if (m->yscroll>m->nbtiles_hauteur_monde*m->HAUTEUR_TILE-m->hauteur_fenetre-1)
        m->yscroll=m->nbtiles_hauteur_monde*m->HAUTEUR_TILE-m->hauteur_fenetre-1;
}
 
 
 
int AfficherMap(Map* m, SDL_Surface* screen, Perso* perso)
{
    int i,j;
    SDL_Rect Rect_dest;
    int numero_tile;
    int minx,maxx,miny,maxy;
    minx = m->xscroll / m->LARGEUR_TILE;
    miny = m->yscroll / m->HAUTEUR_TILE;
    maxx = (m->xscroll + m->largeur_fenetre)/m->LARGEUR_TILE;
    maxy = (m->yscroll + m->hauteur_fenetre)/m->HAUTEUR_TILE;
    /*calcule position fenetre de scrolling sur map*/
 
 
 
 
            //1ère couche
    for(i=minx; i<maxx; i++) //on parle en tiles
    {
        for(j=miny; j<maxy; j++)
        {
            Rect_dest.x = i*m->LARGEUR_TILE - m->xscroll;
            Rect_dest.y = j*m->HAUTEUR_TILE - m->yscroll;
            numero_tile = m->schema1[i][j];
            SDL_BlitSurface(m->tileset, &(m->props[numero_tile].R), screen, &Rect_dest);
        }
    }
 
 
            //2ème couche
     for(i=minx; i<maxx; i++) //on parle en tiles
    {
        for(j=miny; j<maxy; j++)
        {
            Rect_dest.x = i*m->LARGEUR_TILE - m->xscroll;
            Rect_dest.y = j*m->HAUTEUR_TILE - m->yscroll;
            numero_tile = m->schema2[i][j];
            SDL_BlitSurface(m->tileset, &(m->props[numero_tile].R), screen, &Rect_dest);
        }
    }
 
            //personnage
    AfficherPerso(perso, screen, m->xscroll, m->yscroll);
 
 
            //3ème couche
     for(i=minx; i<=maxx; i++) //on parle en tiles
    {
        for(j=miny; j<=maxy; j++)
        {
            Rect_dest.x = i*m->LARGEUR_TILE - m->xscroll;
            Rect_dest.y = j*m->HAUTEUR_TILE - m->yscroll;
            numero_tile = m->schema3[i][j];
 
            SDL_BlitSurface(m->tileset, &(m->props[numero_tile].R), screen, &Rect_dest);
        }
    }
 
    return 0;
}
 
 
 
void AfficherPerso(Perso* perso, SDL_Surface* screen, int xscroll, int yscroll)
 
{
	//Perso positionsurecran = *perso;
	perso->R.x -= xscroll;
	perso->R.y -= yscroll;
    SDL_SetColorKey(perso->sprite, SDL_SRCCOLORKEY, SDL_MapRGB(perso->sprite->format, 238, 104, 189));//fond transparent
    SDL_BlitSurface(perso->sprite, NULL, screen, &perso->R);
 
	//SDL_FillRect(screen, &positionsurecran, 0x00FF00);
}
 
 
 
int LibererMap(Map* m, Perso* perso)
{
    int i;
    for(i=0; i<m->nbtiles_hauteur_monde; i++)
    {
 
        free(m->schema1[i]);
        free(m->schema2[i]);
        free(m->schema3[i]);
    }
    free(m->schema1);
    free(m->schema2);
    free(m->schema3);
    free(m->props);
    free(m);
    free(perso);
    return 0;
}
fmap.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#ifndef _FMAP_H
#define _FMAP_H
 
#include "utils.h"
 
typedef struct//TileProp
{
	SDL_Rect R;
	char mur;
	char vide;
	// tout ce que vous voulez...
} TileProp;
 
typedef struct//Map
{
	int LARGEUR_TILE,HAUTEUR_TILE;
	int nbtiles;
	TileProp* props;
	SDL_Surface* tileset;
	unsigned char **schema1, **schema2, **schema3;
	int nbtiles_largeur_monde,nbtiles_hauteur_monde;
	int xscroll,yscroll;
	int largeur_fenetre,hauteur_fenetre;
} Map;
 
 
 
Map* ChargerMap(const char* couche1, const char* couche2, const char* couche3, const char* image_corr, const char* tileset, const char* tileprop, int largeur_tile, int hauteur_tile, int hauteur_fenetre, int largeur_fenetre);
 
 
 
TileProp* ChargerProps(const char* tileprop, int nombre_props);
 
 
 
char LocatePixInCorr(SDL_Surface* corr, Uint32 pix);
 
 
 
void CalculerSDLRects(TileProp* tabprops, int nombre_props, int nombre_tiles_largeur, int largeur_tile, int hauteur_tile);
 
 
 
Perso* ChargerPerso(const char* sprite, int x, int y, int w, int h);
 
 
 
Perso* Deplace(Input* in, Map* carte, Perso* perso, int LARGEUR_TILE, int HAUTEUR_TILE);//deplace le perso
 
 
 
int CollisionDecor(Map* carte, Perso* perso, char dir);
 
 
 
int FocusScrollCenter(Map* carte, Perso* perso);
 
 
 
void ClampScroll(Map* m);
 
 
 
int AfficherMap(Map* m, SDL_Surface* screen, Perso* perso);
 
 
 
void AfficherPerso(Perso* perso, SDL_Surface* screen, int xscroll, int yscroll);
 
 
 
int LibererMap(Map* m, Perso* perso);
 
 
 
#endif

main.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#include "fmap.h"
 
 
 
 
 
 
 
int main(int argc,char** argv)
{
	SDL_Surface* screen;
	Map* carte;
	Perso* perso;
	Input in;
	int LARGEUR_TILE, HAUTEUR_TILE;
	LARGEUR_TILE = 16;
	HAUTEUR_TILE = 16;
	memset(&in, 0, sizeof(in));
	SDL_Init(SDL_INIT_VIDEO);
 
	carte = ChargerMap("1 schema bourg en vol.bmp","2 schema bourg en vol.bmp","3 schema bourg en vol.bmp","corr bourg en vol.bmp", "tileset bourg en vol.bmp","tileprop1.txt", LARGEUR_TILE, HAUTEUR_TILE, 800, 600);
 
	screen = SDL_SetVideoMode(carte->largeur_fenetre, carte->hauteur_fenetre, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
 
	perso = ChargerPerso("perso.bmp", 128, 224, 16, 21);
	while(!in.key[SDLK_ESCAPE]&& !in.quit)
	{
		UpdateEvents(&in);
		Deplace(&in, carte, perso, LARGEUR_TILE, HAUTEUR_TILE);//deplace si possible le perso
		FocusScrollCenter(carte, perso);//calcule la position de fenetre de scrolling pour que le perso soit toujours au centre
		AfficherMap(carte, screen, perso);//affiche la map et le perso
		SDL_Flip(screen);
	}
	LibererMap(carte, perso);
	SDL_Quit();
	return EXIT_SUCCESS;
}


utils.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#include "utils.h"
 
void UpdateEvents(Input* in)
{
	SDL_Event event;
	while(SDL_PollEvent(&event))
	{
		switch (event.type)
		{
			case SDL_KEYDOWN:
				in->key[event.key.keysym.sym]=1;
				break;
 
			case SDL_KEYUP:
				in->key[event.key.keysym.sym]=0;
				break;
 
			case SDL_QUIT:
				in->quit = 1;
				break;
 
			default:
				break;
		}
	}
}
 
 
 
SDL_Surface* LoadImage32(const char* fichier_image,int vram)
{
	SDL_Surface* image_result;
	SDL_Surface* image_ram = SDL_LoadBMP(fichier_image);	// charge l'image dans image_ram en RAM
	if (image_ram==NULL)
	{
		printf("Image %s introuvable !! \n",fichier_image);
		SDL_Quit();
		exit(-1);
	}
	image_result = NULL;
	if (vram)
		image_result=SDL_CreateRGBSurface(SDL_HWSURFACE, image_ram->w, image_ram->h, 32, 0, 0, 0, 0);  // cree une image en VRAM
	if (image_result==NULL)
		vram = 0;
	if (!vram)
		image_result=SDL_CreateRGBSurface(SDL_SWSURFACE, image_ram->w, image_ram->h, 32, 0, 0, 0, 0);  // cree une image en RAM
	SDL_BlitSurface(image_ram,NULL,image_result,NULL);	// copie l'image image_ram de moins de 32 bits vers image_result qui fait 32 bits
	SDL_FreeSurface(image_ram);      // supprime la surface image_ram : inutile maintenant --> libere la mémoire
	return image_result;
}
 
 
 
Uint32 GetPixel32(SDL_Surface* image,int i,int j)
{
	if (i<0 || i>image->w-1 || j<0 || j>image->h-1)
		return 0;
	return ((Uint32*)(image->pixels))[j*(image->pitch/4)+i];   // lecture directe des pixels
}


utils.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#ifndef _UTILS_H
#define _UTILS_H
 
#include <SDL.h>
 
 
 
typedef struct
{
	int key[SDLK_LAST];
	char quit;
} Input;
 
 
typedef struct
{
    SDL_Rect R;
    SDL_Surface* sprite;
} Perso;
 
 
void UpdateEvents(Input* in);
 
SDL_Surface* LoadImage32(const char* fichier_image,int vram);
 
Uint32 GetPixel32(SDL_Surface* image,int i,int j);
 
#endif
Mais le problème, c'est que venu le moment de compilé j'ai une erreur de segmentation que je n'arrive pas à trouver...

Cela fait déjà plusieurs jours que je tente de la trouver en relisant le code car je ne sais pas utiliser le débuggeur (gdb).

Si quelqu'un avait l'infini gentillesse, bonté ou générosité de m'aider en débuggant mon code et me dire comment il s'y est pris ça serait sympa car là je commence un peu à désespérer...