1 /* ************************************************************************* *
2 SDL-Ball - DX-Ball/Breakout remake with openGL and SDL for Linux
3 Copyright (C) 2008 Jimmy Christensen ( dusted at dusted dot dk )
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * ************************************************************************* */
18
19 class powerupLoaderClass {
20 public:
21 //most common
22 string chances[4];
23 int powerups;
24 int powerupsGiven;
25 string evilPowerups;
26
powerupLoaderClass()27 powerupLoaderClass() {
28 int chance=-1;
29 powerups=0;
30 powerupsGiven=0;
31 string line;
32
33 //Which powerups are evil?
34 evilPowerups = "2H37"; //P
35
36 ifstream powerFile(useTheme("/powerups.txt",setting.lvlTheme).data());
37 if(!powerFile.is_open())
38 {
39 cout << " Could not open 'powerups.txt'"<<endl;
40 var.quit=1;
41 return;
42 }
43
44 while(!powerFile.eof())
45 {
46 getline(powerFile, line);
47 if(line.compare("Most:")==0)
48 {
49 chance=0;
50 } else if(line.compare("More:")==0)
51 {
52 chance=1;
53 } else if(line.compare("Less:")==0)
54 {
55 chance=2;
56 } else if(line.compare("Least:")==0)
57 {
58 chance=3;
59 } else {
60 //No matches, either its a comment or a powerup.
61 if(line.compare(0,2,"//")!=0 && line.compare("")!=0)
62 {
63 chances[chance] += line[0];
64 powerups++;
65 }
66 }
67
68 }
69 }
70
selectRandomPowerup()71 char selectRandomPowerup()
72 {
73 int i = rand()%100;
74 powerupsGiven++;
75 if(i < 1) //1% of powerups are from this class
76 {
77 i=rand()%chances[3].length();
78 return(chances[3][i]);
79 } else if(i < 11) //10% of powerups are from this class
80 {
81 i=rand()%chances[2].length();
82 return(chances[2][i]);
83 } else if(i < 41) //30% of powerups are from this class
84 {
85 i=rand()%chances[1].length();
86 return(chances[1][i]);
87 } else { //Rest of the powerups are from this class
88 i=rand()%chances[0].length();
89 return(chances[0][i]);
90 }
91 }
92
randomPowerup(char p)93 char randomPowerup(char p)
94 {
95 int i;
96 //First, decide if we are going to put a powerup in the brick. (based on p)
97 i=rand()%100;
98 if(p=='Q') //100% chance of evil
99 {
100 return(randomEvilPowerup());
101 } else if(p=='K') //100% chance
102 {
103 return(selectRandomPowerup());
104 } else if(p=='N' && i < 1) //1%
105 {
106 return(selectRandomPowerup());
107 } else if(p=='M' && i < 2) //2%
108 {
109 return(selectRandomPowerup());
110 } else if(p=='L' && i < 5) //5%
111 {
112 return(selectRandomPowerup());
113 } else if(p=='J' && i < 10) //10%
114 {
115 return(selectRandomPowerup());
116 }
117
118 //Return no powerup or return the specified.
119 if(p=='K' || p=='N' || p=='M' || p=='L' || p=='J')
120 {
121 return('0');
122 } else {
123 return(p);
124 }
125
126 }
127
randomEvilPowerup()128 char randomEvilPowerup()
129 {
130 int i=rand()%evilPowerups.length();
131 return(evilPowerups[i]);
132 }
133
134 };
135
loadlevel(string file,brick bricks[],int level)136 void loadlevel(string file, brick bricks[] ,int level)
137 {
138 ifstream levelfile(file.data());
139 if(!levelfile.is_open())
140 {
141 cout << " Could not open " << file << endl;
142 var.quit=1;
143 return;
144 }
145 string line;
146 int levelread=0,brick=0,ch=0;
147 var.numlevels=0;
148 var.scrollInfo.drop = 0;
149
150
151 while(!levelfile.eof())
152 {
153 getline(levelfile,line);
154 //Har vi fundet start?
155 if(levelread == 0)
156 {
157 //Nej, er det nu?
158 if(line.substr(0,11) == "** Start **")
159 {
160 levelread++;
161 }
162 } else if(levelread == 1)
163 {
164 //Do the level stop now?
165 if(line.substr(0,10) == "** Stop **")
166 {
167 levelread=0;
168 var.numlevels++;
169 brick=0;
170 } else { //Reading data from level
171
172 if(var.numlevels == level)
173 {
174 if(line[0] == '>')
175 {
176 if(line.substr(0,6) == "> down")
177 {
178 var.scrollInfo.dropspeed = atol( line.substr(7,line.length()).data() );
179 var.scrollInfo.drop = 1;
180 }
181 } else {
182 while(line[ch] != 0)
183 {
184 bricks[brick].powerup = line[ch];
185 bricks[brick].type = line[ch+1];
186
187 if(bricks[brick].type == 'D')
188 {
189 char rgb[3][5];
190
191 sprintf(rgb[0], "0x%c%c", line[ch+2], line[ch+3]);
192 sprintf(rgb[1], "0x%c%c", line[ch+4], line[ch+5]);
193 sprintf(rgb[2], "0x%c%c", line[ch+6], line[ch+7]);
194
195 bricks[brick].tex.prop.glTexColorInfo[0] = 0.003921569*strtol(rgb[0], NULL, 16);
196 bricks[brick].tex.prop.glTexColorInfo[1] = 0.003921569*strtol(rgb[1], NULL, 16);
197 bricks[brick].tex.prop.glTexColorInfo[2] = 0.003921569*strtol(rgb[2], NULL, 16);
198
199 bricks[brick].tex.prop.glParColorInfo[0] = 0.003921569*strtol(rgb[0], NULL, 16);
200 bricks[brick].tex.prop.glParColorInfo[1] = 0.003921569*strtol(rgb[1], NULL, 16);
201 bricks[brick].tex.prop.glParColorInfo[2] = 0.003921569*strtol(rgb[2], NULL, 16);
202
203 bricks[brick].tex.prop.glTexColorInfo[3] = 1.0;
204 ch +=6;
205 }
206 //cout << "Level: " << levelnum << " brick: " << brick << " Powerup: " << line[ch] << " Type: " << line[ch+1]<<"\n";
207
208 brick++;
209 ch +=2;
210 }
211 ch=0;
212 } //Not a command
213 } //denne level settes op
214 }
215 }
216 }
217 cout << "Read " << var.numlevels << " levels from '"<< file <<"'" << endl;
218 levelfile.close();
219 }
220
initlevels(brick bricks[],textureClass texLvl[])221 void initlevels(brick bricks[], textureClass texLvl[])
222 {
223 int brick;
224 powerupLoaderClass powerupLoader;
225
226 //Temp storage for custom colors
227 GLfloat tempCol[4], tempParCol[3];
228
229 //Set dem op
230 int row,i;
231 i=0;
232
233 for(row=0;row<23;row++)
234 {
235
236 for(brick=0;brick < 26; brick++)
237 {
238
239 bricks[i].posx = -1.54 + (GLfloat)brick*0.1232;
240 bricks[i].posy = 0.95+ ((GLfloat)row*0.07)*-1;
241
242 if(bricks[i].type != '0')
243 {
244 bricks[i].active=1;
245 bricks[i].collide=1;
246 bricks[i].isdyingnormally=0;
247 bricks[i].isexploding=0;
248 bricks[i].reflect=1;
249
250 bricks[i].fade=1.0;
251 bricks[i].fadespeed=2.0;
252 bricks[i].zoom=1.0;
253 bricks[i].zoomspeed=4.0;
254 bricks[i].width=0.0616;
255 bricks[i].height=0.035;
256
257 bricks[i].score=11;
258 bricks[i].destroytowin=1;
259 bricks[i].hitsLeft=1;
260
261 bricks[i].powerup = powerupLoader.randomPowerup(bricks[i].powerup);
262
263 bricks[i].bricknum=brick;
264
265 bricks[i].row=row;
266 updated_nbrick[row][brick] = i; // This brick is active
267 //cout<<"Brick:"<< nbrick[row][brick]<<endl;
268 } else {
269 bricks[i].score=0;
270 bricks[i].destroytowin=0;
271 bricks[i].active=0;
272 updated_nbrick[row][brick]=-1;
273 // cout<<"Brick:"<< nbrick[row][brick]<<endl;
274 }
275
276
277
278
279 if(bricks[i].type == '1')
280 {
281 bricks[i].tex=texLvl[6];
282 bricks[i].opacity=texLvl[6].prop.glTexColorInfo[3];
283 } else if(bricks[i].type == '2')
284 {
285 bricks[i].tex=texLvl[7];
286 bricks[i].opacity=texLvl[7].prop.glTexColorInfo[3];
287 }else if(bricks[i].type == '3')
288 {
289 bricks[i].powerup = '0';
290 bricks[i].tex= texLvl[2];
291 bricks[i].opacity=texLvl[2].prop.glTexColorInfo[3];
292 bricks[i].score=30;
293 bricks[i].destroytowin=0;
294 } else if(bricks[i].type == '4')
295 {
296 bricks[i].tex=texLvl[4]; //glass texture
297 bricks[i].hitsLeft = 2; //takes two hits to kill
298 bricks[i].opacity=texLvl[4].prop.glTexColorInfo[3];
299 } else if(bricks[i].type == '5')
300 {
301 bricks[i].tex=texLvl[8];
302 bricks[i].opacity=texLvl[8].prop.glTexColorInfo[3];
303
304
305 } else if(bricks[i].type == '6')
306 {
307 bricks[i].tex=texLvl[9];
308 bricks[i].opacity=texLvl[9].prop.glTexColorInfo[3];
309
310
311 } else if(bricks[i].type == '7')
312 {
313 bricks[i].tex=texLvl[10];
314 bricks[i].opacity=texLvl[10].prop.glTexColorInfo[3];
315
316
317 } else if(bricks[i].type == '8')
318 {
319 bricks[i].tex=texLvl[11];
320 bricks[i].opacity=texLvl[11].prop.glTexColorInfo[3];
321
322 } else if(bricks[i].type == '9')
323 {
324 bricks[i].tex=texLvl[5]; //invisible texture
325 bricks[i].tex.frame=1;
326 bricks[i].hitsLeft = 3; //takes 3 to kill
327 bricks[i].opacity=texLvl[5].prop.glTexColorInfo[3];
328
329 } else if(bricks[i].type == 'A')
330 {
331 bricks[i].tex=texLvl[12];
332 bricks[i].opacity=texLvl[12].prop.glTexColorInfo[3];
333 } else if(bricks[i].type == 'B')
334 {
335 bricks[i].tex=texLvl[0];
336 bricks[i].opacity=texLvl[0].prop.glTexColorInfo[3];
337 } else if(bricks[i].type == 'C')
338 {
339 bricks[i].tex=texLvl[3];
340 bricks[i].opacity=texLvl[3].prop.glTexColorInfo[3];
341 bricks[i].powerup = powerupLoader.randomEvilPowerup();
342 } else if(bricks[i].type == 'D') //type D get colors applied by loadlevel.
343 {
344 //Hold the colors while applying texture props
345 memcpy(tempCol, bricks[i].tex.prop.glTexColorInfo, sizeof(tempCol));
346 memcpy(tempParCol, bricks[i].tex.prop.glParColorInfo, sizeof(tempParCol));
347
348 bricks[i].tex = texLvl[1];
349
350 //Put pack the colors
351 memcpy(bricks[i].tex.prop.glTexColorInfo,tempCol, sizeof(tempCol));
352 memcpy(bricks[i].tex.prop.glParColorInfo,tempParCol,sizeof(tempParCol));
353
354 bricks[i].opacity = tempCol[3];
355
356 }
357
358 i++;
359 }
360 }
361 // cout << "Powerups given to this level: " << powerupLoader.powerupsGiven << endl;
362 }
363