b9f0ea47b177facf02f3f40e13c45651586e7493
[supertux.git] / src / level.c
1 //
2 // C Implementation: level
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2003
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include "globals.h"
17 #include "setup.h"
18 #include "screen.h"
19 #include "level.h"
20
21 /* Load data for this level: */
22
23 void loadlevel(st_level* plevel, char *subset, int level)
24 {
25   int y;
26   FILE * fi;
27   char str[80];
28   char * filename;
29   char * line;
30
31   /* Load data file: */
32
33   filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset));
34   sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
35   fi = fopen(filename, "r");
36   if (fi == NULL)
37     {
38       perror(filename);
39       st_shutdown();
40       free(filename);
41       exit(-1);
42     }
43   free(filename);
44
45
46   /* Load header info: */
47
48
49   /* (Level title) */
50   fgets(str, 20, fi);
51   strcpy(plevel->name, str);
52   plevel->name[strlen(plevel->name)-1] = '\0';
53
54   /* (Level theme) */
55   fgets(str, 20, fi);
56   strcpy(plevel->theme, str);
57   plevel->theme[strlen(plevel->theme)-1] = '\0';
58
59
60
61   /* (Time to beat level) */
62   fgets(str, 10, fi);
63   plevel->time_left = atoi(str);
64
65   /* (Song file for this level) */
66   fgets(str, sizeof(plevel->song_title), fi);
67   strcpy(plevel->song_title, str);
68   plevel->song_title[strlen(plevel->song_title)-1] = '\0';
69
70   /* (Level background image) */
71   fgets(str, sizeof(plevel->bkgd_image), fi);
72   strcpy(plevel->bkgd_image, str);
73   plevel->bkgd_image[strlen(plevel->bkgd_image)-1] = '\0';
74
75   /* (Level background color) */
76   fgets(str, 10, fi);
77   plevel->bkgd_red = atoi(str);
78   fgets(str, 10, fi);
79   plevel->bkgd_green= atoi(str);
80   fgets(str, 10, fi);
81   plevel->bkgd_blue = atoi(str);
82
83   /* (Level width) */
84   fgets(str, 10, fi);
85   plevel->width = atoi(str);
86
87
88   /* Allocate some space for the line-reading! */
89
90   line = (char *) malloc(sizeof(char) * (plevel->width + 5));
91   if (line == NULL)
92     {
93       fprintf(stderr, "Couldn't allocate space to load level data!");
94       fclose(fi);
95       exit(1);
96     }
97
98
99   /* Load the level lines: */
100
101   for (y = 0; y < 15; y++)
102     {
103       if(fgets(line, plevel->width + 5, fi) == NULL)
104         {
105           fprintf(stderr, "Level %s isn't complete!\n",plevel->name);
106           free(line);
107           fclose(fi);
108           exit(1);
109         }
110       line[strlen(line) - 1] = '\0';
111       plevel->tiles[y] = strdup(line);
112     }
113
114   free(line);
115   fclose(fi);
116
117 }
118
119 /* Save data for level: */
120
121 void savelevel(st_level* plevel, char * subset, int level)
122 {
123   FILE * fi;
124   char * filename;
125   int y;
126   char str[80];
127
128   /* Save data file: */
129
130   filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset));
131   sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
132   fi = fopen(filename, "w");
133   if (fi == NULL)
134     {
135       perror(filename);
136       st_shutdown();
137       free(filename);
138       exit(-1);
139     }
140   free(filename);
141
142   fputs(plevel->name, fi);
143   fputs("\n", fi);
144   fputs(plevel->theme, fi);
145   fputs("\n", fi);
146   sprintf(str, "%d\n", plevel->time_left);      /* time */
147   fputs(str, fi);
148   fputs(plevel->song_title, fi);        /* song filename */
149   fputs("\n",fi);
150   fputs(plevel->bkgd_image, fi);        /* background image */  
151   sprintf(str, "\n%d\n", plevel->bkgd_red);     /* red background color */
152   fputs(str, fi);
153   sprintf(str, "%d\n", plevel->bkgd_green);     /* green background color */
154   fputs(str, fi);
155   sprintf(str, "%d\n", plevel->bkgd_blue);      /* blue background color */
156   fputs(str, fi);
157   sprintf(str, "%d\n", plevel->width);  /* level width */
158   fputs(str, fi);
159
160   for(y = 0; y < 15; ++y)
161     {
162       fputs(plevel->tiles[y], fi);
163       fputs("\n", fi);
164     }
165
166   fclose(fi);
167 }
168
169
170 /* Unload data for this level: */
171
172 void unloadlevel(st_level* plevel)
173 {
174   free(plevel->tiles);
175   plevel->name[0] = '\0';
176   plevel->theme[0] = '\0';
177   plevel->song_title[0] = '\0';
178   plevel->bkgd_image[0] = '\0';
179 }
180
181 /* Load graphics: */
182
183 void loadlevelgfx(st_level *plevel)
184 {
185
186   load_level_image(&img_brick[0],plevel->theme,"brick0.png", IGNORE_ALPHA);
187   load_level_image(&img_brick[1],plevel->theme,"brick1.png", IGNORE_ALPHA);
188
189   load_level_image(&img_solid[0],plevel->theme,"solid0.png", USE_ALPHA);
190   load_level_image(&img_solid[1],plevel->theme,"solid1.png", USE_ALPHA);
191   load_level_image(&img_solid[2],plevel->theme,"solid2.png", USE_ALPHA);
192   load_level_image(&img_solid[3],plevel->theme,"solid3.png", USE_ALPHA);
193
194   load_level_image(&img_bkgd_tile[0][0],plevel->theme,"bkgd-00.png", USE_ALPHA);
195   load_level_image(&img_bkgd_tile[0][1],plevel->theme,"bkgd-01.png", USE_ALPHA);
196   load_level_image(&img_bkgd_tile[0][2],plevel->theme,"bkgd-02.png", USE_ALPHA);
197   load_level_image(&img_bkgd_tile[0][3],plevel->theme,"bkgd-03.png", USE_ALPHA);
198
199   load_level_image(&img_bkgd_tile[1][0],plevel->theme,"bkgd-10.png", USE_ALPHA);
200   load_level_image(&img_bkgd_tile[1][1],plevel->theme,"bkgd-11.png", USE_ALPHA);
201   load_level_image(&img_bkgd_tile[1][2],plevel->theme,"bkgd-12.png", USE_ALPHA);
202   load_level_image(&img_bkgd_tile[1][3],plevel->theme,"bkgd-13.png", USE_ALPHA);
203
204   if(strcmp(plevel->bkgd_image,"") != 0)
205     {
206       char fname[1024];
207       snprintf(fname, 1024, "%s/background/%s", st_dir, plevel->bkgd_image);
208       if(!faccessible(fname))
209         snprintf(fname, 1024, "%s/images/background/%s", DATA_PREFIX, plevel->bkgd_image);
210       texture_load(&img_bkgd, fname, IGNORE_ALPHA);
211       printf("%s",fname);
212     }
213 }
214
215 /* Free graphics data for this level: */
216
217 void unloadlevelgfx(void)
218 {
219   int i;
220
221   for (i = 0; i < 2; i++)
222     {
223       texture_free(&img_brick[i]);
224     }
225   for (i = 0; i < 4; i++)
226     {
227       texture_free(&img_solid[i]);
228       texture_free(&img_bkgd_tile[0][i]);
229       texture_free(&img_bkgd_tile[1][i]);
230     }
231   texture_free(&img_bkgd);
232 }
233
234 /* Load a level-specific graphic... */
235
236 void load_level_image(texture_type* ptexture, char* theme, char * file, int use_alpha)
237 {
238   char fname[1024];
239
240   snprintf(fname, 1024, "%s/themes/%s/%s", st_dir, theme, file);
241   if(!faccessible(fname))
242     snprintf(fname, 1024, "%s/images/themes/%s/%s", DATA_PREFIX, theme, file);
243
244   texture_load(ptexture, fname, use_alpha);
245 }
246
247 /* Edit a piece of the map! */
248
249 void level_change(st_level* plevel, float x, float y, unsigned char c)
250 {
251   int xx, yy;
252
253   yy = ((int)y / 32);
254   xx = ((int)x / 32);
255
256   if (yy >= 0 && yy < 15 && xx >= 0 && xx <= plevel->width)
257     plevel->tiles[yy][xx] = c;
258 }
259