~ubuntu-branches/ubuntu/quantal/zaz/quantal

« back to all changes in this revision

Viewing changes to src/game.cpp

  • Committer: Package Import Robot
  • Author(s): Miriam Ruiz
  • Date: 2011-11-16 02:28:10 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111116022810-d3tehh974q280vit
Tags: 1.0.0~dfsg1-1
* New Upstream Release
* Upgraded Standards-Version from 3.8.3 to 3.9.2
* New homepage: http://phuzzboxmedia.com/index.php/games/open-sourced-zaz
* Refreshed patches
* Moved package to DebSrc 3

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include "game.h"
20
20
 
21
21
#ifdef WIN32
 
22
#include <windows.h>
22
23
#include <shlobj.h>
23
24
#include <shlwapi.h>
24
25
#endif
35
36
Sample *sfx_extraball;
36
37
Sample *sfx_extralife;
37
38
Sample *sfx_timebonus;
 
39
Sample *sfx_newcolor;
 
40
Sample *sfx_failedlevel;
 
41
 
 
42
BallDesc BallDescriptions[] =
 
43
{
 
44
    {"balls1.png", 255, 0, 0, 1},
 
45
    {"balls1.png", 255, 255, 255, 0},
 
46
    {"balls1.png", 0, 170, 0, 2},
 
47
    {"balls1.png", 0, 0, 255, 3},
 
48
    {"balls1.png", 255, 0, 255, 4},
 
49
    {"balls1.png", 255, 255, 0, 5},
 
50
    {"balls1.png", 30, 30, 30, 0},
 
51
    {"balls1.png", 189, 108, 28, 6},
 
52
    {"balls2.png", 255, 0, 0, 1},
 
53
    {"balls2.png", 255, 255, 255, 0},
 
54
    {"balls2.png", 0, 170, 0, 2},
 
55
    {"balls2.png", 0, 0, 255, 3},
 
56
    {"balls2.png", 255, 0, 255, 4},
 
57
    {"balls2.png", 255, 255, 0, 5},
 
58
    {"balls2.png", 30, 30, 30, 0},
 
59
    {"balls2.png", 189, 108, 28, 6}
 
60
};
38
61
 
39
62
Mixer *mix;
40
63
int sfxVol;
41
64
int musicVol;
42
65
 
43
 
Game::Game(Scenes::Settings *settings, SDL_Surface *surf, Level &level, GLuint *textures, uint randomSeed, uint lives, int score, bool fromEditor)
44
 
        : Scene(settings, surf), settings(settings), surface(surf),
 
66
Game::Game(SDL_Surface *surf, Level &level, GLuint *textures, uint randomSeed, uint lives, int score, bool fromEditor, bool alwaysAccuracy, bool survivalMode)
 
67
        : Scene(surf), surface(surf),
45
68
        dying(false), randomSeed(randomSeed), randomSeedSet(false), finishCountdown(false), level(level),
46
 
        editor(fromEditor), ownTextures(false), gameOver(false), escaped(false), lives(lives), displayExtraLife(false), extraLifeLastScore(0), score(score),
47
 
        stopTimer(false), timeBonus(false), timeBonusSecondsAdded(0)
 
69
        editor(fromEditor), ownTextures(false), lives(lives), displayExtraLife(false), extraLifeLastScore(0),
 
70
        stopTimer(false), timeBonus(false), timeBonusSecondsAdded(0), renderingForThumb(false), survival(survivalMode), dyingSound(false), score(score), gameOver(false), escaped(false)
48
71
{
49
72
    if (textures == NULL)
50
73
    {
51
 
        // load the textures
52
 
        ballText[0] = LoadTexture("balls1.png");
53
 
        ballText[1] = LoadTexture("balls2.png");
54
 
        ballText[2] = LoadTexture("balls3.png");
55
 
        ballText[3] = LoadTexture("balls4.png");
56
 
        ballText[4] = LoadTexture("balls5.png");
57
 
        ballText[5] = LoadTexture("balls6.png");
58
 
        ballText[6] = LoadTexture("balls7.png");
59
 
        ballText[7] = LoadTexture("balls8.png");
60
 
 
61
 
        ballText[8] = LoadTexture("bonus1.png");
62
 
        ballText[9] = LoadTexture("bonus2.png");
63
 
        ballText[10] = LoadTexture("bonus3.png");
64
 
        ballText[11] = LoadTexture("bonus4.png");
65
 
        ballText[12] = LoadTexture("bonus5.png");
66
 
        ballText[13] = LoadTexture("explosion.png");
67
 
 
 
74
        bool useColourHints = settings.getb("colourHints", false);
 
75
 
 
76
        for (int b = 0; b < 16; b++)
 
77
        {
 
78
            BallDesc bd = BallDescriptions[b];
 
79
            ballText[b] = LoadBallsTexture(bd.fileName, bd.r, bd.g, bd.b, useColourHints?bd.overlay:0);
 
80
        }
 
81
 
 
82
        ballText[16] = LoadTexture("bonus1.png");
 
83
        ballText[17] = LoadTexture("bonus2.png");
 
84
        ballText[18] = LoadTexture("bonus3.png");
 
85
        ballText[19] = LoadTexture("bonus4.png");
 
86
        ballText[20] = LoadTexture("bonus5.png");
 
87
        ballText[21] = LoadTexture("explosion.png");
68
88
        ownTextures = true;
69
89
    }
70
90
    else
71
91
    {
72
 
        for (int f = 0; f < 14; f++)
 
92
        for (int f = 0; f < 22; f++)
73
93
            ballText[f] = textures[f];
74
94
    }
75
95
 
82
102
    {
83
103
        try
84
104
        {
85
 
            music = (Sample *)new Scenes::StreamingOggSample(getRandomMusic());
 
105
            try
 
106
            {
 
107
                music = (Sample *)new Scenes::StreamingOggSample(level.musicFilename);
 
108
            }
 
109
            catch (Error e)
 
110
            {
 
111
                music = (Sample *)new Scenes::StreamingOggSample(getRandomMusic());
 
112
            }
86
113
        }
87
114
        catch (Error e)
88
115
        {
102
129
    sfx_extraball = (Sample *)new Scenes::OggSample("extraball.ogg");
103
130
    sfx_extralife = (Sample *)new Scenes::OggSample("extralife.ogg");
104
131
    sfx_timebonus = (Sample *)new Scenes::WaveSample("timebonus.wav");
 
132
    sfx_newcolor = (Sample *)new Scenes::OggSample("newcolor.ogg");
 
133
    sfx_failedlevel = (Sample *)new Scenes::OggSample("failedlevel.ogg");
105
134
 
106
135
    // create paths
107
136
    nPaths = level.paths.size() - 1;
109
138
    ballPaths = new BallPath*[nPaths + 1];
110
139
    for (int b = 0; b < nPaths; ++b)
111
140
    {
112
 
        ballPaths[b] = new BallPath(level.paths[b + 1], ballText, &mix, false);
113
 
        ballPaths[b]->state.ballsToDraw = level.ballsToDraw;
 
141
        Bezier nb = level.paths[b + 1];
 
142
 
 
143
        if (level.mirrorX)
 
144
        {
 
145
            for (uint p = 0; p < nb.points.size(); p++)
 
146
            {
 
147
                nb.points[p].x = 50.0 + (50.0 - nb.points[p].x);
 
148
                nb.points[p].cx = 50.0 + (50.0 - nb.points[p].cx);
 
149
            }
 
150
        }
 
151
 
 
152
        if (level.mirrorY)
 
153
        {
 
154
            for (uint p = 0; p < nb.points.size(); p++)
 
155
            {
 
156
                nb.points[p].y = 50.0 + (50.0 - nb.points[p].y);
 
157
                nb.points[p].cy = 50.0 + (50.0 - nb.points[p].cy);
 
158
            }
 
159
        }
 
160
 
 
161
        ballPaths[b] = new BallPath(nb, ballText, &mix, false, level.ballSizes[b]);
 
162
        ballPaths[b]->state.ballsToDraw = level.ballsToDraw[b];
114
163
        ballPaths[b]->state.colors = level.colors;
115
 
        ballPaths[b]->state.feedRate = 1;
116
 
        ballPaths[b]->state.ballsFromStart = level.ballsFromStart;
 
164
        ballPaths[b]->state.lastColors = level.colors;
 
165
        ballPaths[b]->state.feedRate = level.startFeedRates[b];
 
166
        ballPaths[b]->state.startFeedRate = level.startFeedRates[b];
 
167
        ballPaths[b]->state.ballsFromStart = level.ballsFromStart[b];
 
168
        ballPaths[b]->state.kidsMode = level.kidsMode;
 
169
        ballPaths[b]->state.bonusFrequency = level.bonusFrequency;
 
170
 
 
171
        if (survival)
 
172
        {
 
173
            ballPaths[b]->state.colors = survivalColorsStart;
 
174
            ballPaths[b]->state.lastColors = survivalColorsStart;
 
175
            ballPaths[b]->state.survival = survival;
 
176
        }
117
177
    }
118
178
 
119
179
    ballPaths[nPaths] = 0;
120
180
 
121
181
    // create the player
122
 
    pl = new Player(level.paths[0], ballPaths, level.loop, level.invert);
 
182
    Bezier nb = level.paths[0];
 
183
 
 
184
    if (level.mirrorX)
 
185
    {
 
186
        for (uint p = 0; p < nb.points.size(); p++)
 
187
        {
 
188
            nb.points[p].x = 50.0 + (50.0 - nb.points[p].x);
 
189
            nb.points[p].cx = 50.0 + (50.0 - nb.points[p].cx);
 
190
        }
 
191
    }
 
192
 
 
193
    if (level.mirrorY)
 
194
    {
 
195
        for (uint p = 0; p < nb.points.size(); p++)
 
196
        {
 
197
            nb.points[p].y = 50.0 + (50.0 - nb.points[p].y);
 
198
            nb.points[p].cy = 50.0 + (50.0 - nb.points[p].cy);
 
199
        }
 
200
    }
 
201
 
 
202
    bool inv = level.invert;
 
203
 
 
204
    if (level.mirrorX && !level.mirrorY)
 
205
    {
 
206
        inv = !inv;
 
207
    }
 
208
 
 
209
    if (level.mirrorY && !level.mirrorX)
 
210
    {
 
211
        inv = !inv;
 
212
    }
 
213
 
 
214
    pl = new Player(nb, ballPaths, level.loop, inv, fromEditor, level.kidsMode || alwaysAccuracy);
123
215
    dying = false;
124
216
 
125
 
    sfxVol = atoi(settings->get("sfxVolume", "50").c_str());
126
 
    musicVol = atoi(settings->get("musicVolume", "50").c_str());
 
217
    sfxVol = atoi(settings.get("sfxVolume", "50").c_str());
 
218
    musicVol = atoi(settings.get("musicVolume", "50").c_str());
127
219
 
128
220
    displayLevelName = true;
129
221
    levelNameDisplayTime = levelNameDisplayTimeout;
130
222
 
131
223
    extraLifeLastScore = (score/pointsForNewLife) * pointsForNewLife;
 
224
 
 
225
    level.LoadTex();
 
226
 
 
227
    // create an empty cursor
 
228
 
 
229
    Uint8 cursdata[] = {0, 0, 0, 0, 0, 0, 0, 0};
132
230
}
133
231
 
134
232
const string Game::getRandomMusic()
136
234
    char phname[1024];
137
235
    int maxM = 0;
138
236
 
 
237
    phname[0] = 0;
 
238
 
139
239
    for (int f = 1; f < 100; f++)
140
240
    {
141
241
        sprintf(phname, "mus%d.ogg", f);
142
242
 
143
 
        ifstream inph(settings->getCFilename (phname));
 
243
        ifstream inph(settings.getCFilename (phname));
144
244
        if (inph)
145
245
            maxM=f;
146
246
    }
151
251
    }
152
252
    else
153
253
    {
154
 
        ERR("No music files installed");
 
254
        //ERR("No music files installed");
 
255
        *phname='\0';
155
256
    }
156
257
    return string(phname);
157
258
}
170
271
        glDeleteTextures(14, ballText);
171
272
 
172
273
    delete pl;
 
274
 
 
275
    level.FreeTex();
173
276
}
174
277
 
175
278
void Game::Logic(ulong frame)
205
308
                    escaped = true;
206
309
                }
207
310
 
 
311
                /*                if (*i == SDLK_F1)
 
312
                                {
 
313
                                    ballPaths[0]->state.ballOut = true;
 
314
 
 
315
                                    return;
 
316
                                }
 
317
 
 
318
                                if (*i == SDLK_F2)
 
319
                                {
 
320
                                    gameOver = false;
 
321
                                    quit = true;
 
322
                                    return;
 
323
                                }
 
324
                */
208
325
                if (*i == SDLK_F12)
209
326
                {
210
327
                    time_t theTime;
216
333
                    string exportpath = ".";
217
334
 
218
335
#ifdef WIN32
219
 
                    TCHAR path[MAX_PATH];
220
 
                    if (SUCCEEDED(SHGetFolderPath(NULL,
221
 
                                                  CSIDL_PERSONAL,
222
 
                                                  NULL,
223
 
                                                  0,
224
 
                                                  path)))
 
336
                    wchar_t path[MAX_PATH];
 
337
                    if (SUCCEEDED(SHGetFolderPathW(NULL,
 
338
                                                   CSIDL_PERSONAL,
 
339
                                                   NULL,
 
340
                                                   0,
 
341
                                                   path)))
225
342
                    {
226
 
                        exportpath = path;
 
343
                        char utfpath[MAX_PATH];
 
344
                        WideCharToMultiByte(CP_UTF8, 0, path, -1, utfpath, MAX_PATH, NULL, NULL);
 
345
 
 
346
                        exportpath = string(utfpath);
227
347
                    }
228
348
#endif
229
349
 
234
354
                    int f = 1;
235
355
                    while (!ok)
236
356
                    {
 
357
#ifdef WIN32
 
358
                        ifstream inph(Settings::W32_GetFileName(tempbuff).c_str());
 
359
#else
237
360
                        ifstream inph(tempbuff);
 
361
#endif
238
362
                        if (!inph)
239
363
                        {
240
364
                            ok = true;
247
371
                    }
248
372
 
249
373
                    string exportphname = tempbuff;
250
 
                    cout << exportphname << endl;
 
374
//                    cout << exportphname << endl;
251
375
                    Screenshot(exportphname);
 
376
                    if (editor)
 
377
                    {
 
378
                        renderingForThumb = true;
 
379
                        pl->alwaysAccuracy = false;
 
380
                        pl->drawPath = false;
 
381
                    }
252
382
                }
253
383
            }
254
384
    }
255
385
 
256
386
    pl->Logic(events);
257
387
 
258
 
    if (editor)
 
388
    if (editor && !renderingForThumb)
259
389
    {
260
390
        for (int p = 0; p < nPaths; ++p)
261
391
        {
281
411
        return;
282
412
    }
283
413
 
284
 
 
285
414
    for (int b = 0; b < nPaths; ++b)
286
415
    {
287
416
        ballPaths[b]->Logic();
288
417
    }
289
418
 
290
419
    // adjust the feedrate
291
 
    for (int p = 0; p < nPaths; ++p)
292
 
    {
293
 
        if (ballPaths[p]->state.ballsToDraw != -1)
294
 
        {
295
 
            double fs = level.startFeedRate;
296
 
            double fe = level.endFeedRate;
297
 
 
298
 
            double bd = ballPaths[p]->state.ballsToDraw;
299
 
            double b2d = level.ballsToDraw;
300
 
 
301
 
            bd = b2d - bd;
302
 
 
303
 
            ballPaths[p]->state.feedRate = fs + (bd / b2d) * (fe - fs);
304
 
        }
 
420
    if (!survival)
 
421
    {
 
422
        for (int p = 0; p < nPaths; ++p)
 
423
        {
 
424
            if (ballPaths[p]->state.ballsToDraw != -1)
 
425
            {
 
426
                double fs = level.startFeedRates[p];
 
427
                double fe = level.endFeedRates[p];
 
428
 
 
429
                double bd = ballPaths[p]->state.ballsToDraw - ballPaths[p]->state.ballsFromStart;
 
430
                double b2d = level.ballsToDraw[p] - level.ballsFromStart[p];
 
431
 
 
432
                if (bd < 0)
 
433
                    bd = 0.0;
 
434
 
 
435
                bd = b2d - bd;
 
436
 
 
437
                ballPaths[p]->state.feedRate = fs + (bd / b2d) * (fe - fs);
 
438
            }
 
439
        }
 
440
    }
 
441
    else
 
442
    {
 
443
        for (int b = 0; b < nPaths; ++b)
 
444
        {
 
445
            ballPaths[b]->state.ballsToDraw = 1;
 
446
            ballPaths[b]->state.colors = survivalColorsStart + (levelSeconds / survivalNewColorTimeout);
 
447
            if (ballPaths[b]->state.colors >= NBALLCOLORS)
 
448
                ballPaths[b]->state.colors = NBALLCOLORS;
 
449
 
 
450
            ballPaths[b]->state.feedRate = ballPaths[b]->state.startFeedRate + (ballPaths[b]->state.colors - survivalColorsStart);
 
451
 
 
452
            ballPaths[b]->state.feedRate = ballPaths[b]->state.feedRate + ((double(levelSeconds) - ((ballPaths[b]->state.colors - survivalColorsStart) * survivalNewColorTimeout * 1.4)) / double(survivalNewColorTimeout) * 1.8);
 
453
        }
 
454
    }
 
455
 
 
456
    // fix new color sfx
 
457
    if (ballPaths[0]->state.lastColors != ballPaths[0]->state.colors)
 
458
    {
 
459
        mixer->EnqueueSample (sfx_newcolor, sfxVol, 0, false);
 
460
        ballPaths[0]->state.lastColors = ballPaths[0]->state.colors;
305
461
    }
306
462
 
307
463
    // load the score
317
473
    if (score < 0)
318
474
        score = 0;
319
475
 
320
 
 
321
476
    // fix extra life
322
 
    if ((score - extraLifeLastScore) > pointsForNewLife)
323
 
    {
324
 
        extraLifeLastScore = (score/pointsForNewLife) * pointsForNewLife;
325
 
        lives++;
326
 
 
327
 
        extraLifeDisplayTime = extraLifeDisplayTimeout;
328
 
        displayExtraLife = true;
329
 
 
330
 
        mixer->EnqueueSample (sfx_extralife, sfxVol, 0, false);
331
 
    }
 
477
    if (!survival)
 
478
        if ((score > extraLifeLastScore) && ((score - extraLifeLastScore) > (int)pointsForNewLife))
 
479
        {
 
480
            extraLifeLastScore = (score/pointsForNewLife) * pointsForNewLife;
 
481
            lives++;
 
482
 
 
483
            extraLifeDisplayTime = extraLifeDisplayTimeout;
 
484
            displayExtraLife = true;
 
485
 
 
486
            mixer->EnqueueSample (sfx_extralife, sfxVol, 0, false);
 
487
        }
332
488
 
333
489
    if (displayExtraLife)
334
490
    {
335
491
        extraLifeDisplayTime--;
336
492
 
337
 
        if (extraLifeDisplayTime < 0)
 
493
        if (extraLifeDisplayTime <= 0)
338
494
            displayExtraLife = false;
339
495
    }
340
496
 
402
558
    if (dying)
403
559
    {
404
560
        for (int p = 0; p < nPaths; ++p)
 
561
        {
405
562
            ballPaths[p]->state.feedRate = 50;
 
563
            ballPaths[p]->state.bonusPause = false;
 
564
            ballPaths[p]->state.bonusSlow = false;
 
565
        }
 
566
 
 
567
        if (!dyingSound)
 
568
        {
 
569
            mixer->EnqueueSample (sfx_failedlevel, sfxVol, 0, false);
 
570
            dyingSound = true;
 
571
        }
406
572
    }
407
573
 
408
574
    bool dead = dying;
409
575
    for (int p = 0; p < nPaths; ++p)
410
576
    {
411
 
        if (ballPaths[0]->balls.size() != 0)
 
577
        if (ballPaths[p]->balls.size() != 0)
412
578
            dead = false;
413
579
    }
414
580
 
445
611
            finishCountdown = true;
446
612
        }
447
613
 
448
 
        if (levelSeconds < level.time)
 
614
        if (levelSeconds + timeBonusSecondsAdded < level.time)
449
615
        {
450
616
            timeBonus = true;
451
 
            levelSeconds++;
 
617
//            levelSeconds++;
452
618
            timeBonusSecondsAdded++;
453
619
            score+=timeBonusScorePerSecond;
454
 
            if (levelSeconds%4 == 0)
 
620
            if (timeBonusSecondsAdded%4 == 0)
455
621
                mixer->EnqueueSample (sfx_timebonus, sfxVol, 0, false);
456
622
        }
457
623
 
458
 
        if (levelSeconds >= level.time)
 
624
        if (timeBonusSecondsAdded + levelSeconds >= level.time)
459
625
            finishedTimer--;
460
626
 
461
627
        if (finishedTimer < 0)
472
638
        if (levelNameDisplayTime <= 0)
473
639
            displayLevelName = false;
474
640
    }
 
641
 
 
642
    /*SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
 
643
    SDL_WarpMouse(surface->w / 2, surface->h / 2);
 
644
    SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);*/
475
645
}
476
646
 
477
647
void Game::Render(ulong frame)
482
652
    glMatrixMode( GL_MODELVIEW );
483
653
    glLoadIdentity( );
484
654
 
 
655
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
656
 
485
657
    // render level background
 
658
    XY tl(0,0);
 
659
    XY tr(1,0);
 
660
    XY bl(0,1);
 
661
    XY br(1,1);
 
662
 
 
663
    if (level.mirrorX)
 
664
    {
 
665
        XY t = tl;
 
666
        tl = tr;
 
667
        tr = t;
 
668
 
 
669
        t = bl;
 
670
        bl = br;
 
671
        br = t;
 
672
    }
 
673
 
 
674
    if (level.mirrorY)
 
675
    {
 
676
        XY t = tl;
 
677
        tl = bl;
 
678
        bl = t;
 
679
 
 
680
        t = br;
 
681
        br = tr;
 
682
        tr = t;
 
683
    }
 
684
 
486
685
    glPushMatrix();
487
686
    glTranslatef(0.0, 0.0, -5);
488
687
    glEnable(GL_TEXTURE_2D);
489
688
    glBindTexture(GL_TEXTURE_2D, level.backgroundTex);
490
689
    glBegin(GL_QUADS);
491
 
    glTexCoord2d(0, 0);
 
690
    glTexCoord2d(tl.x, tl.y);
492
691
    glVertex3d(vleft, 100, 0);
493
 
    glTexCoord2d(0, 1);
 
692
    glTexCoord2d(bl.x, bl.y);
494
693
    glVertex3d(vleft, 0, 0);
495
 
    glTexCoord2d(1, 1);
 
694
    glTexCoord2d(br.x, br.y);
496
695
    glVertex3d(vleft + vwidth, 0, 0);
497
 
    glTexCoord2d(1, 0);
 
696
    glTexCoord2d(tr.x, tr.y);
498
697
    glVertex3d(vleft + vwidth, 100, 0);
499
698
 
500
699
    glEnd();
501
700
    glDisable(GL_TEXTURE_2D);
502
701
    glPopMatrix();
503
702
 
504
 
    glLoadIdentity( );
505
 
 
506
 
    for (int b = 0; b < nPaths; ++b)
507
 
    {
508
 
        ballPaths[b]->Render();
509
 
    }
 
703
    for (int b = 0; b < nPaths; ++b)
 
704
    {
 
705
        ballPaths[b]->Render(true, false, true, false);
 
706
    }
 
707
 
 
708
    glLoadIdentity();
 
709
    // render overlay
 
710
    if (level.overlayTex)
 
711
    {
 
712
        glPushMatrix();
 
713
        glTranslatef(0.0, 0.0, 1.5);
 
714
        glEnable(GL_TEXTURE_2D);
 
715
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
716
        glBindTexture(GL_TEXTURE_2D, level.overlayTex);
 
717
        glColor4f(1.0, 1.0, 1.0, 1.0);
 
718
        glBegin(GL_QUADS);
 
719
 
 
720
        glTexCoord2d(tl.x, tl.y);
 
721
        glVertex3d(vleft, 100, 0);
 
722
        glTexCoord2d(bl.x, bl.y);
 
723
        glVertex3d(vleft, 0, 0);
 
724
        glTexCoord2d(br.x, br.y);
 
725
        glVertex3d(vleft + vwidth, 0, 0);
 
726
        glTexCoord2d(tr.x, tr.y);
 
727
        glVertex3d(vleft + vwidth, 100, 0);
 
728
        glEnd();
 
729
        glDisable(GL_TEXTURE_2D);
 
730
        glPopMatrix();
 
731
    }
 
732
 
 
733
    glLoadIdentity();
 
734
    for (int b = 0; b < nPaths; ++b)
 
735
    {
 
736
        ballPaths[b]->Render(true, false, false, true);
 
737
    }
 
738
 
 
739
    glLoadIdentity();
 
740
    for (int b = 0; b < nPaths; ++b)
 
741
    {
 
742
        ballPaths[b]->Render(false, true);
 
743
    }
 
744
 
510
745
    pl->Render();
511
746
 
512
 
    glLoadIdentity();
513
747
    // render score
514
 
    if (!editor)
 
748
    glLoadIdentity( );
 
749
    if (!editor && !renderingForThumb)
515
750
    {
516
751
        glColor3f(1.0, 1.0, 1.0);
517
752
        glPushMatrix();
519
754
        glScaled(0.2, 0.2, 0.2);
520
755
 
521
756
        char scoretxt[256];
522
 
        sprintf(scoretxt, "%05d", score);
 
757
        sprintf(scoretxt, "%06d", score);
523
758
 
524
759
        font3->Render(scoretxt);
525
760
        glPopMatrix();
526
761
    }
527
762
 
 
763
    if (editor && !renderingForThumb)
 
764
    {
 
765
        for (int b = 0; b < nPaths; ++b)
 
766
        {
 
767
            glPushMatrix();
 
768
            glPointSize(2.5);
 
769
            glColor3f(0.0, 0.0, 0.0);
 
770
            glBegin(GL_POINTS);
 
771
 
 
772
            for (std::vector<PathStep>::iterator i = ballPaths[b]->ballPath.begin(); i != ballPaths[b]->ballPath.end(); ++i)
 
773
                glVertex3d(i->x, i->y, 0.0);
 
774
 
 
775
            glEnd();
 
776
            glPopMatrix();
 
777
        }
 
778
    }
 
779
 
528
780
    // render lives
529
 
    if (!editor)
 
781
    if (!survival && !editor && !renderingForThumb)
530
782
        for (uint l = 0; l < lives; l++)
531
783
        {
532
784
            glPushMatrix();
546
798
            glVertex3d(0.5, 0.5, 0);
547
799
            glEnd();
548
800
            glDisable(GL_TEXTURE_2D);
549
 
 
550
801
            glPopMatrix();
551
802
        }
552
803
 
559
810
        double tw = b.Upper().X() / 5;
560
811
 
561
812
        glTranslated((100 - tw) / 2, 50, 50);
 
813
        if (timeBonus) // make sure extra life does not blend with time bonus
 
814
            glTranslated(0.0, 10.0, 0);
 
815
 
562
816
        glScaled(0.2, 0.2, 0.2);
563
817
 
564
818
        double alpha = 1.0;
572
826
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
573
827
        font->Render(extraLifeTxt);
574
828
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
575
 
 
576
 
        glPopMatrix();
577
829
    };
578
830
 
579
831
    // render level name
580
 
    if (!editor)
 
832
    if (!editor && !renderingForThumb)
581
833
        if (displayLevelName)
582
834
        {
583
835
            glLoadIdentity( );
584
 
            glPushMatrix();
585
836
 
586
837
            FTBBox b = font->BBox(gettext(level.name.c_str()));
587
838
            double tw = b.Upper().X() / 5;
601
852
            font->Render(gettext(level.name.c_str()));
602
853
            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
603
854
 
604
 
            glPopMatrix();
605
855
        }
606
856
 
607
857
    // time
608
858
    char tbuff[256];
609
 
    sprintf(tbuff, "%02d:%02d", levelSeconds/60, levelSeconds%60);
 
859
    if (!survival)
 
860
    {
 
861
        sprintf(tbuff, "%02d:%02d / %02d:%02d ", levelSeconds/60, levelSeconds%60, level.time/60, level.time%60);
 
862
    }
 
863
    else
 
864
    {
 
865
        sprintf(tbuff, "%02d:%02d", levelSeconds/60, levelSeconds%60);
 
866
    }
 
867
 
610
868
    glLoadIdentity( );
611
 
    glPushMatrix();
612
869
 
613
870
    FTBBox b = font3->BBox(tbuff);
614
871
    double tw = b.Upper().X() / 5;
615
872
    glTranslated((100 - tw) / 2, 95, 50);
616
873
    glScaled(0.2, 0.2, 0.2);
 
874
    glColor4d(1.0, 1.0, 1.0, 1.0);
617
875
 
618
 
    if (!editor)
 
876
    if (!editor && !renderingForThumb)
619
877
        font3->Render(tbuff);
620
878
 
621
879
    if (timeBonus) // we're adding time bonus !
624
882
 
625
883
        sprintf(buff, _("Time Bonus ! (%d sec * %d = %d)"), timeBonusSecondsAdded, timeBonusScorePerSecond,
626
884
                timeBonusScorePerSecond * timeBonusSecondsAdded);
 
885
 
627
886
        glLoadIdentity( );
628
 
        FTBBox b = font3->BBox(buff);
 
887
        FTBBox b = font->BBox(buff);
629
888
        double tw = b.Upper().X() / 5;
630
889
 
631
890
        glTranslated((100 - tw) / 2, 50, 50);
634
893
        glColor4d(1.0, 0.0, 0.0, 1.0);
635
894
 
636
895
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
637
 
        font3->Render(buff);
 
896
        font->Render(buff);
638
897
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
639
898
 
640
 
        glPopMatrix();
641
899
    }
642
900
 
 
901
    if (renderingForThumb)
 
902
    {
 
903
        renderingForThumb = false;
 
904
        pl->drawPath = false;
 
905
    }
643
906
}
644
907
 
645
908
void Game::GLSetup()
646
909
{
647
910
    if ((mode == RUN) || (mode == RECORD))
648
911
    {
649
 
        SDL_ShowCursor(SDL_DISABLE);
650
912
        SDL_WM_GrabInput(SDL_GRAB_ON);
651
913
    }
652
914
 
697
959
    mixer->DisposeSample(sfx_extraball);
698
960
    mixer->DisposeSample(sfx_extralife);
699
961
    mixer->DisposeSample(sfx_timebonus);
 
962
    mixer->DisposeSample(sfx_newcolor);
 
963
    mixer->DisposeSample(sfx_failedlevel);
 
964
 
700
965
 
701
966
    if (!editor)
702
967
        if (music)