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