3
* Copyright (C) Remigiusz Dybka 2009 <remigiusz.dybka@gmail.com>
5
Zaz is free software: you can redistribute it and/or modify it
6
under the terms of the GNU General Public License as published by the
7
Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
10
Zaz is distributed in the hope that it will be useful, but
11
WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
See the GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License along
16
with this program. If not, see <http://www.gnu.org/licenses/>.
21
#include "textureloader.h"
22
#include "lineeditor.h"
30
GameLoop::GameLoop(Scenes::Settings *settings, SDL_Surface *surf, GLuint *gameTextures, uint startLevel, uint randomSeed)
31
: Scene(settings, surf), score(0), lastscore(0), currentLevelName(startLevel), randomSeed((uint)time(0)), gameTextures(gameTextures),
32
showMenu(false), gameOver(false), showPauseMenu(false), continueGame(false), showLifeLostMenu(false), pwned(false), hiScore(false), game(0),
33
logoTexture(LoadTexture ("logo.png")),screenShotTexture(0), pwnedr(0), editor(settings->get("lastHighscoreName", ""), 60, 50, 16),
34
livesLeft(nLives), livesLeftInReplay(nLives)
43
ss << "level" << f << ".lvl";
45
std::ifstream inph(settings->getCFilename(ss.str()));
48
levelNames.push_back(settings->getCFilename(ss.str()));
57
pauseMenu.Add(new GenericMenuItem(_("End game"), pauseMenuEndGameHandler, this));
58
pauseMenu.Add(new GenericMenuItem(_("Continue"), pauseMenuContinueHandler, this));
60
pauseMenu.SetDimensions(30, 40, 40);
62
nextLevelMenu.Add(new GenericMenuItem(_("Next level"), nextLevelMenuNextLevelHandler, this));
63
nextLevelMenu.Add(new GenericMenuItem(_("End game"), pauseMenuEndGameHandler, this));
64
nextLevelMenu.Add(new GenericMenuItem(_("View replay"), nextLevelMenuViewReplayHandler, this));
65
nextLevelMenu.Add(new GenericMenuItem(_("Export video"), nextLevelMenuExportVideoHandler, this));
67
nextLevelMenu.SetDimensions(30, 40, 40);
69
gameOverMenu.Add(new GenericMenuItem(_("Back to main menu"), pauseMenuEndGameHandler, this));
70
gameOverMenu.Add(new GenericMenuItem(_("Restart game"), gameOverMenuRestartHandler, this));
71
gameOverMenu.Add(new GenericMenuItem(_("View replay"), nextLevelMenuViewReplayHandler, this));
72
gameOverMenu.Add(new GenericMenuItem(_("Export video"), nextLevelMenuExportVideoHandler, this));
74
gameOverMenu.SetDimensions(30, 40, 40);
76
lifeLostMenu.Add(new GenericMenuItem(_("Retry level"), lifeLostMenuRetryLevelHandler, this));
77
lifeLostMenu.Add(new GenericMenuItem(_("End game"), pauseMenuEndGameHandler, this));
78
lifeLostMenu.Add(new GenericMenuItem(_("View replay"), nextLevelMenuViewReplayHandler, this));
79
lifeLostMenu.Add(new GenericMenuItem(_("Export video"), nextLevelMenuExportVideoHandler, this));
81
lifeLostMenu.SetDimensions(30, 40, 40);
86
tempRecording << " "; // braindead !!!
90
void GameLoop::ClearGame()
101
void gameOverMenuRestartHandler(void *ptr)
103
GameLoop *p = (GameLoop*)ptr;
105
p->currentLevelName = 0;
109
void GameLoop::ViewReplay()
115
level = new Level(levelNames[currentLevelName].c_str());
116
game = new Game(settings, surface, *level, gameTextures, randomSeed, livesLeftInReplay, lastscore);
121
void lifeLostMenuRetryLevelHandler(void *ptr)
123
GameLoop *p = (GameLoop*)ptr;
124
p->showLifeLostMenu = false;
127
void GameLoop::NextLevel()
133
void nextLevelMenuNextLevelHandler(void *ptr)
135
GameLoop *p = (GameLoop*)ptr;
139
void nextLevelMenuViewReplayHandler(void *ptr)
141
GameLoop *p = (GameLoop*)ptr;
145
void GameLoop::ExportReplay()
149
level = new Level(levelNames[currentLevelName].c_str());
152
game = new Game(settings, surface, *level, gameTextures, randomSeed, livesLeftInReplay, lastscore);
156
tm *t = localtime( &theTime );
160
string exportpath = ".";
163
TCHAR path[MAX_PATH];
164
if (SUCCEEDED(SHGetFolderPath(NULL,
174
sprintf(datebuff, "%04d-%02d-%02d", 1900 + t->tm_year, t->tm_mon + 1, t->tm_mday);
176
sprintf(tempbuff, "%s%szaz-%s.ogv", exportpath.c_str(), SEPARATOR, datebuff);
181
ifstream inph(tempbuff);
188
sprintf(tempbuff, "%s%szaz-%s-%d.ogv", exportpath.c_str(), SEPARATOR, datebuff, f);
193
string exportphname = tempbuff;
195
game->Export(exportphname, rec, 4);
199
void nextLevelMenuExportVideoHandler(void *ptr)
201
GameLoop *p = (GameLoop*)ptr;
205
void pauseMenuContinueHandler(void *ptr)
207
GameLoop *p = (GameLoop*)ptr;
208
p->continueGame = true;
209
p->showPauseMenu = false;
212
void pauseMenuEndGameHandler(void *ptr)
214
GameLoop *p = (GameLoop*)ptr;
219
GameLoop::~GameLoop()
221
if (screenShotTexture)
222
glDeleteTextures(1, &screenShotTexture);
224
glDeleteTextures(1, &logoTexture);
228
void GameLoop::GLSetup()
230
SDL_ShowCursor(SDL_ENABLE);
231
SDL_WM_GrabInput(SDL_GRAB_OFF);
233
int width = surface->w;
234
int height = surface->h;
236
// float ratio = (float) width / (float) height;
238
/* Our shading model--Gouraud (smooth). */
239
glShadeModel( GL_SMOOTH );
242
glCullFace( GL_BACK );
243
glFrontFace( GL_CCW );
244
glEnable( GL_CULL_FACE );
245
glEnable(GL_DEPTH_TEST);
246
glEnable( GL_ALPHA_TEST );
247
glAlphaFunc(GL_GREATER, 0.0);
248
glEnable(GL_LINE_SMOOTH);
251
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
253
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
254
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
255
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
257
glClearColor( .1f, .1f, .7f, 1.0f );
258
glViewport( 0, 0, width, height);
259
glMatrixMode( GL_PROJECTION );
262
vwidth = 100 * (640.0/480.0);
263
vleft = (100 - vwidth) / 2;
266
glOrtho(vleft, vwidth + vleft, 0, 100, -100, 100);
267
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
270
void GameLoop::Logic(ulong frame)
274
if (events.keyDown.size() > 0)
275
for (vector<SDLKey>::iterator i = events.keyDown.begin(); i != events.keyDown.end(); ++i)
277
if (*i == SDLK_ESCAPE)
279
if (!showPauseMenu && !hiScore)
283
else if (showPauseMenu)
286
showPauseMenu = false;
296
if (*i == SDLK_RETURN || *i == SDLK_KP_ENTER)
298
hiScores.SubmitHiScore(HiScoreEntry(score, editor.txt, level->name));
299
settings->set("lastHighscoreName", editor.txt);
301
SDL_EnableUNICODE(SDL_DISABLE);
305
double mx = (vwidth * events.mouseX) + vleft;
306
double my = vheight - (vheight * events.mouseY);
309
if (events.buttDown[0])
312
if (showLifeLostMenu)
313
lifeLostMenu.Logic(mx, my, click);
316
pauseMenu.Logic(mx, my, click);
319
nextLevelMenu.Logic(mx, my, click);
322
gameOverMenu.Logic(mx, my, click);
333
editor.Logic(events);
336
if (!showLifeLostMenu && !showMenu && !gameOver && !showPauseMenu && !hiScore)
341
level = new Level(levelNames[currentLevelName].c_str());
342
randomSeed = (uint)time(0);
343
tempRecording.clear();
344
tempRecording.seekp(0);
345
game = new Game(settings, surface, *level, gameTextures, randomSeed, livesLeft, score);
351
game->escaped = false;
352
game->Record(tempRecording, pausedFrame);
353
continueGame = false;
354
GenScreenShotTexture();
359
livesLeftInReplay = livesLeft;
360
game->Record(tempRecording, 0);
361
GenScreenShotTexture();
367
showPauseMenu = true;
368
pausedFrame = game->getLastLogicFrame();
376
livesLeft = game->lives;
379
cfgs << "level" << (currentLevelName + 1) << "_completed";
381
settings->setb(cfgs.str(), true);
383
if (currentLevelName < levelNames.size() - 1)
387
else // pwned the game !!!
391
if (hiScores.GoodEnough (score))
394
SDL_EnableUNICODE(SDL_ENABLE);
397
GenScreenShotTexture();
399
recording = tempRecording.str();
405
livesLeft = (int)game->lives;
410
showLifeLostMenu = true;
411
recording = tempRecording.str();
416
if (hiScores.GoodEnough (score))
418
SDL_EnableUNICODE(SDL_ENABLE);
423
recording = tempRecording.str();
432
void GameLoop::CenterMsg(string msg, double y, FTFont *font)
435
FTBBox b = font->BBox(msg.c_str());
436
double tw = b.Upper().X() / 5;
437
glTranslated((100 - tw) / 2, y, 5);
438
glScaled(0.2, 0.2, 0.2);
440
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
441
font->Render(msg.c_str());
442
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
446
void GameLoop::Render(ulong frame)
448
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
449
glColor3f(1.0, 1.0, 1.0);
450
glMatrixMode( GL_MODELVIEW );
453
if (screenShotTexture != 0)
455
// render level background
457
glTranslatef(0.0, 0.0, -5);
458
glEnable(GL_TEXTURE_2D);
459
glBindTexture(GL_TEXTURE_2D, screenShotTexture);
462
glVertex3d(vleft, 100, 0);
464
glVertex3d(vleft, 0, 0);
466
glVertex3d(vleft + vwidth, 0, 0);
468
glVertex3d(vleft + vwidth, 100, 0);
470
glDisable(GL_TEXTURE_2D);
474
if (showLifeLostMenu)
476
lifeLostMenu.Render();
478
glColor3d(1.0, 1.0, 1.0);
481
sprintf(msgscore, _("Lives left: %d"), livesLeft);
482
CenterMsg(msgscore, 50, font);
484
sprintf(msgscore, _("Current score: %05d"), score);
486
CenterMsg(msgscore, 45, font);
492
string msg = _("Game paused");
493
glColor3d(1.0, 0.0, 0.0);
495
CenterMsg(msg, 45, font);
500
nextLevelMenu.Render();
504
glColor3d(1.0, 1.0, 1.0);
505
CenterMsg(_("Level cleared"), 50, font);
508
sprintf(msgscore, _("Current score: %05d"), score);
510
CenterMsg(msgscore, 45, font);
514
if (gameOver && !hiScore)
516
gameOverMenu.Render();
519
string msg = _("Game Over");
521
glColor3d(1.0, 0.0, 0.0);
523
CenterMsg(msg, 50, font);
525
sprintf(msgscore, _("Score: %05d"), score);
526
glColor3d(1.0, 1.0, 1.0);
527
CenterMsg(msgscore, 45, font);
530
if (pwned && !hiScore)
532
glColor3d(1.0, 1.0, 1.0);
533
CenterMsg(_("Congratulations !!! You just pwned"), 90, font3);
538
glEnable(GL_TEXTURE_2D);
539
glTranslated(15 + 30 * cos(pwnedr), 90, 5);
540
glBindTexture(GL_TEXTURE_2D, logoTexture);
546
glVertex3d(0, -1, 0);
548
glVertex3d(1, -1, 0);
552
glDisable(GL_TEXTURE_2D);
557
glColor3d(1.0, 1.0, 1.0);
558
CenterMsg(_("You have a new hi score"), 65, font);
559
CenterMsg(_("please enter your name"), 60, font);
564
void GameLoop::GenScreenShotTexture()
566
if (screenShotTexture)
568
glDeleteTextures(1, &screenShotTexture);
571
unsigned char *pixels;
576
pixels = (unsigned char *)malloc(3 * surface->w * surface->h);
577
temp = (unsigned char *)malloc(3 * screenShotTextureSize * screenShotTextureSize);
579
glReadPixels(0, 0, surface->w, surface->h,
580
GL_RGB, GL_UNSIGNED_BYTE, pixels);
582
double sx = (double)surface->w / (double)screenShotTextureSize;
583
double sy = (double)surface->h / (double)screenShotTextureSize;
585
for (uint y = 0; y < screenShotTextureSize; ++y)
586
for (uint x = 0; x < screenShotTextureSize; ++x)
588
uint yy = (uint)iround(double(y) * sy);
589
uint xx = (uint)iround(double(x) * sx);
590
unsigned char *p = pixels + (((surface->h - 1) - yy) * 3 * surface->w) + (xx * 3);
591
unsigned char *pt = temp + (y * 3 * screenShotTextureSize) + (x * 3);
593
unsigned char r = p[0];
594
unsigned char g = p[1];
595
unsigned char b = p[2];
597
int newcol = (((int)r + (int)g + (int)b) / 3) - 10;
601
unsigned char nc = (unsigned char)newcol;
608
glGenTextures( 1, &screenShotTexture);
610
glBindTexture( GL_TEXTURE_2D, screenShotTexture);
612
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
613
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
615
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
616
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
618
glTexImage2D( GL_TEXTURE_2D, 0, 3, screenShotTextureSize, screenShotTextureSize, 0,
619
GL_RGB, GL_UNSIGNED_BYTE, temp);