1 /***************************************************************************
2 mainmenu.cpp - The game's main menu
3 -------------------
4 begin : Tue Aug 12 2003
5 copyright : (C) 2003 by Gabor Torok
6 email : cctorok@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 #include "common/constants.h"
18 #include "mainmenu.h"
19 #include "render/renderlib.h"
20 #include "sdlhandler.h"
21 #include "scourge.h"
22 #include "text.h"
23 #include "partyeditor.h"
24 #include "gui/window.h"
25 #include "gui/label.h"
26 #include "gui/button.h"
27 #include "gui/scrollinglabel.h"
28 #include "gui/progress.h"
29 #include "shapepalette.h"
30 #include "savegamedialog.h"
31 #include "freetype/fontmgr.h"
32 #include "sound.h"
33 #include "texteffect.h"
34
35 using namespace std;
36
37 // ###### MS Visual C++ specific ######
38 #if defined(_MSC_VER) && defined(_DEBUG)
39 # define new DEBUG_NEW
40 # undef THIS_FILE
41 static char THIS_FILE[] = __FILE__;
42 #endif
43
44 #define LOGO_DELTA 0.05f
45 #define LOGO_ROT_POS 30.0f
46 #define LOGO_ROT_NEG 0
47 #define LOGO_ZOOM 0.8f
48
49 #define LOGO_SPRITE_DELTA 1.0f
50 //#define PI 3.14159f
51
52 #define WATER_HEIGHT 130
53
54 #define MENU_ITEM_WIDTH 256
55 #define MENU_ITEM_HEIGHT 32
56 #define MENU_ITEM_ZOOM 1.5f
57 #define MENU_ITEM_PARTICLE_ZOOM 1.1f
58 #define MAX_PARTICLE_LIFE 50
59
60 bool eventsEnabled = false;
61
62 const char *MainMenu::menuText[] = {
63 N_( "New Game" ),
64 N_( "Continue Game" ),
65 // N_( "Multiplayer Game" ), ...skip multiplayer for now
66 N_( "Options" ),
67 N_( "About S.c.o.u.r.g.e." ),
68 N_( "Quit" ),
69 ""
70 };
71
72 int activeMenuItem = -1;
73
74 const int MainMenu::values[] = {
75 NEW_GAME, CONTINUE_GAME,
76 // MULTIPLAYER, ...skip multiplayer for now
77 OPTIONS, ABOUT, QUIT, 0
78 };
79
80 Texture slide;
81
MainMenu(Scourge * scourge)82 MainMenu::MainMenu( Scourge *scourge ) {
83 this->scourge = scourge;
84 this->cloudCount = 30;
85 this->lastMenuTick = 0;
86 this->savegameDialog = new SavegameDialog( scourge );
87 for ( int i = 0; i < cloudCount; i++ ) {
88 cloud[i].x = Util::dice( scourge->getSDLHandler()->getScreen()->w );
89 cloud[i].y = Util::dice( 50 );
90 cloud[i].w = Util::pickOne( 200, 254 );
91 cloud[i].h = Util::pickOne( 100, 127 );
92 cloud[i].speed = Util::pickOne( 1, 2 );
93 }
94
95 //logoRot = -scourge->getShapePalette()->logo->h;
96 logoRot = -173;
97 logoRotDelta = LOGO_DELTA;
98 logoTicks = 0;
99 logoTicksDelta = 50;
100 logoSpriteCount = 0;
101 candleFlameX = candleFlameY = 0;
102 slideMode = false;
103
104 top = ( scourge->getSDLHandler()->getScreen()->h - 600 ) / 2;
105 openingTop = scourge->getSDLHandler()->getScreen()->h / 2;
106 musicStarted = false;
107 lastTick = 0;
108 lastTickMenu = 0;
109 initTextures = false;
110
111 starCount = 200;
112 for ( int i = 0; i < starCount; i++ ) {
113 star[i].x = Util::dice( scourge->getSDLHandler()->getScreen()->w );
114 star[i].y = Util::pickOne( top, top + 599 - WATER_HEIGHT - 160 );
115 }
116 // The new style gui
117 int w = 250;
118 int h = 120;
119 newGameConfirm = new Window( scourge->getSDLHandler(),
120 ( scourge->getSDLHandler()->getScreen()->w / 2 ) - ( w / 2 ),
121 ( scourge->getSDLHandler()->getScreen()->h / 2 ) - ( h / 2 ),
122 w, h,
123 _( "New Game Confirmation" ),
124 scourge->getShapePalette()->getGuiTexture(), false );
125 newGameConfirmOK = newGameConfirm->createButton( 40, 55, 110, 75, Constants::getMessage( Constants::OK_LABEL ) );
126 newGameConfirmCancel = newGameConfirm->createButton( 140, 55, 210, 75, Constants::getMessage( Constants::CANCEL_LABEL ) );
127 newGameConfirm->createLabel( 20, 20, Constants::getMessage( Constants::DELETE_OLD_SAVED_GAME ) );
128 newGameConfirm->setVisible( false );
129 newGameConfirm->setModal( true );
130
131 partyEditor = NULL;
132
133 // about dialog
134 w = 500;
135 h = 350;
136 aboutDialog = new Window( scourge->getSDLHandler(),
137 ( scourge->getSDLHandler()->getScreen()->w / 2 ) - ( w / 2 ),
138 ( scourge->getSDLHandler()->getScreen()->h / 2 ) - ( h / 2 ),
139 w, h,
140 _( "About S.c.o.u.r.g.e." ),
141 scourge->getShapePalette()->getGuiTexture(), true );
142 aboutText = new ScrollingLabel( 8, 0,
143 w - 18,
144 h - 65,
145 scourge->getShapePalette()->getAboutText() );
146 aboutDialog->addWidget( aboutText );
147 aboutOK = aboutDialog->createButton( ( w / 2 ) - 40,
148 ( h - 55 ),
149 ( w / 2 ) + 40,
150 ( h - 35 ),
151 Constants::getMessage( Constants::OK_LABEL ) );
152 aboutDialog->setVisible( false );
153
154
155 progress = new Progress( scourge->getSDLHandler(),
156 scourge->getSession()->getShapePalette()->getProgressTexture(),
157 scourge->getSession()->getShapePalette()->getProgressHighlightTexture(),
158 100, false, false );
159 }
160
~MainMenu()161 MainMenu::~MainMenu() {
162 for ( unsigned int i = 0; i < textEffects.size(); i++ ) {
163 TextEffect *textEffect = textEffects[i];
164 delete textEffect;
165 }
166 textEffects.clear();
167 delete partyEditor;
168 delete savegameDialog;
169 delete newGameConfirm;
170 delete aboutDialog;
171 delete progress;
172 }
173
174 /// Draws the whole main menu view.
175
drawView()176 void MainMenu::drawView() {
177 int tickNow = SDL_GetTicks();
178 if ( ( tickNow - lastMenuTick ) < 15 ) SDL_Delay( 15 - ( tickNow - lastMenuTick ) );
179 lastMenuTick = SDL_GetTicks();
180
181 if ( !slideMode ) {
182 glDisable( GL_CULL_FACE );
183
184 drawStars();
185
186 glDisable( GL_TEXTURE_2D );
187 glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
188
189 drawBackdrop();
190
191 glEnable( GL_TEXTURE_2D );
192
193 // create a stencil for the water
194 glDisable( GL_DEPTH_TEST );
195 glColorMask( 0, 0, 0, 0 );
196
197 if ( scourge->getUserConfiguration()->getStencilbuf() && scourge->getUserConfiguration()->getStencilBufInitialized() ) {
198 glEnable( GL_STENCIL_TEST );
199 glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
200 glStencilFunc( GL_ALWAYS, 1, 1 );
201 }
202
203 drawWater();
204
205 // Use the stencil to draw
206 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
207 glEnable( GL_DEPTH_TEST );
208
209 if ( scourge->getUserConfiguration()->getStencilbuf() && scourge->getUserConfiguration()->getStencilBufInitialized() ) {
210 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
211 glStencilFunc( GL_EQUAL, 1, 0xffffffff ); // draw if stencil==1
212 }
213
214 drawClouds( false, true );
215
216 glDisable( GL_STENCIL_TEST );
217
218 // draw the blended water
219 glEnable( GL_BLEND );
220 glDepthMask( GL_FALSE );
221 glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_COLOR );
222 drawWater();
223 glDepthMask( GL_TRUE );
224 glDisable( GL_BLEND );
225
226 glDisable( GL_DEPTH_TEST );
227
228 drawClouds( true, false );
229
230 glDisable( GL_TEXTURE_2D );
231 glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
232 glDisable( GL_DEPTH_TEST );
233
234 drawScourge();
235
236 glEnable( GL_TEXTURE_2D );
237 glEnable( GL_DEPTH_TEST );
238
239 drawMenu();
240 }
241
242 // draw the boards
243 if ( openingTop > 0 ) {
244 glPushMatrix();
245 glColor3f( 1, 1, 1 );
246
247 // float TILE_W = 510 / 2.0f;
248 float TILE_W = 256.0f;
249 float TILE_H = 256.0f;
250 glEnable( GL_TEXTURE_2D );
251 Texture const& yellow = scourge->getShapePalette()->getNamedTexture( "menu" );
252
253 glPushMatrix();
254 glLoadIdentity();
255 glTranslatef( 0, openingTop, 0 );
256 yellow.glBind();
257 glBegin( GL_TRIANGLE_STRIP );
258 glTexCoord2f( 0, scourge->getSDLHandler()->getScreen()->h / TILE_H );
259 glVertex2i( 0, 0 );
260 glTexCoord2f( scourge->getSDLHandler()->getScreen()->w / TILE_W, scourge->getSDLHandler()->getScreen()->h / TILE_H );
261 glVertex2i( scourge->getSDLHandler()->getScreen()->w, 0 );
262 glTexCoord2f( 0, 0 );
263 glVertex2i( 0, -scourge->getSDLHandler()->getScreen()->h / 2 );
264 glTexCoord2f( scourge->getSDLHandler()->getScreen()->w / TILE_W, 0 );
265 glVertex2i( scourge->getSDLHandler()->getScreen()->w, -scourge->getSDLHandler()->getScreen()->h / 2 );
266 glEnd();
267 glPopMatrix();
268
269 glPushMatrix();
270 glLoadIdentity();
271 glTranslatef( 0, scourge->getSDLHandler()->getScreen()->h - openingTop, 0 );
272 yellow.glBind();
273 glBegin( GL_TRIANGLE_STRIP );
274 glTexCoord2f( 0, 0 );
275 glVertex2i( 0, 0 );
276 glTexCoord2f( scourge->getSDLHandler()->getScreen()->w / TILE_W, 0 );
277 glVertex2i( scourge->getSDLHandler()->getScreen()->w, 0 );
278 glTexCoord2f( 0, scourge->getSDLHandler()->getScreen()->h / TILE_H );
279 glVertex2i( 0, scourge->getSDLHandler()->getScreen()->h / 2 );
280 glTexCoord2f( scourge->getSDLHandler()->getScreen()->w / TILE_W, scourge->getSDLHandler()->getScreen()->h / TILE_H );
281 glVertex2i( scourge->getSDLHandler()->getScreen()->w, scourge->getSDLHandler()->getScreen()->h / 2 );
282 glEnd();
283 glPopMatrix();
284 glDisable( GL_TEXTURE_2D );
285
286 for ( int i = 0; i < 2; i++ ) {
287 glLoadIdentity();
288 glTranslatef( 0, ( i == 0 ? openingTop : scourge->getSDLHandler()->getScreen()->h - openingTop ), 0 );
289 glColor4f( 1, 0.7f, 0, 1 );
290 glBegin( GL_LINES );
291 glVertex2i( 0, 0 );
292 glVertex2i( scourge->getSDLHandler()->getScreen()->w, 0 );
293 glEnd();
294 }
295
296 if ( slideMode ) {
297 int w = scourge->getSDLHandler()->getScreen()->w;
298 int h = ( scourge->getSDLHandler()->getScreen()->w / 2 ) - 1;
299
300 glEnable( GL_TEXTURE_2D );
301 //glPushMatrix();
302 glLoadIdentity();
303 glTranslatef( 0, openingTop + 1, 0 );
304 slide.glBind();
305 glBegin( GL_TRIANGLE_STRIP );
306 glTexCoord2f( 0, 0 );
307 glVertex3f( 0, 0, 0 );
308 glTexCoord2f( 1, 0 );
309 glVertex3f( w, 0, 0 );
310 glTexCoord2f( 0, 1 );
311 glVertex3f( 0, h, 0 );
312 glTexCoord2f( 1, 1 );
313 glVertex3f( w, h, 0 );
314 glEnd();
315 //glPopMatrix();
316 glDisable( GL_TEXTURE_2D );
317 } else {
318 glLoadIdentity();
319 glTranslatef( 10, scourge->getSDLHandler()->getScreen()->h - openingTop + 12, 0 );
320 char version[100];
321 snprintf( version, 100, _( "Scourge version %s" ), SCOURGE_VERSION );
322 scourge->getSDLHandler()->setFontType( Constants::SCOURGE_DEFAULT_FONT );
323 scourge->getSDLHandler()->texPrint( 0, 0, version );
324 glColor3f( 0.8f, 0.75f, 0.65f );
325 int y = 14;
326 scourge->getSDLHandler()->texPrint( 0, y, _( "Optionally compiled modules:" ) );
327 y += 14;
328 #ifdef HAVE_SDL_NET
329 scourge->getSDLHandler()->texPrint( 0, y, _( "[Network]" ) );
330 y += 14;
331 #endif
332 #ifdef HAVE_SDL_MIXER
333 scourge->getSDLHandler()->texPrint( 0, y, _( "[Sound]" ) );
334 y += 14;
335 #endif
336 glPopMatrix();
337
338 if ( openingTop > top && scourge->getSession()->isDataInitialized() ) {
339 Uint32 t = SDL_GetTicks();
340 if ( t - lastTick > 40 ) {
341 int d = ( scourge->getSDLHandler()->getScreen()->h - openingTop ) / 20;
342 openingTop -= ( 10 + static_cast<int>( d * 1.2 ) );
343 if ( openingTop < top ) openingTop = top;
344 lastTick = t;
345 }
346 }
347 }
348 }
349
350 if ( openingTop <= top ) {
351 drawLogo();
352 if ( !musicStarted ) {
353 scourge->getSession()->getSound()->playMusicMenu();
354 musicStarted = true;
355 }
356 }
357
358 // initialize universe (nice how this is hidden here...)
359 scourge->getSession()->initData();
360 }
361
362 /// Draws the loading screen if still loading data.
363
drawAfter()364 void MainMenu::drawAfter() {
365 if ( strlen( getUpdate() ) ) {
366 glPushMatrix();
367
368 /*
369 glLoadIdentity();
370 glEnable( GL_BLEND );
371 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
372 glDisable( GL_TEXTURE_2D );
373 glColor4f( 0, 0, 0, 0.75f );
374 glBegin( GL_QUADS );
375 glVertex3f( 0, 0, 0 );
376 glVertex3f( 0, scourge->getScreenHeight(), 0 );
377 glVertex3f( scourge->getScreenWidth(), scourge->getScreenHeight(), 0 );
378 glVertex3f( scourge->getScreenWidth(), 0, 0 );
379 glEnd();
380 glEnable( GL_TEXTURE_2D );
381 glDisable( GL_BLEND );
382 */
383
384 glLoadIdentity();
385 glTranslatef( 10, scourge->getSDLHandler()->getScreen()->h - openingTop + 12, 0 );
386 int y = 70;
387 int x = 100;
388 float maxStatus = ( scourge->getScreenWidth() - 200 ) / 20.0f;
389 glColor3f( 0.8f, 0.75f, 0.65f );
390 if ( getUpdateTotal() > -1 ) {
391 scourge->getSDLHandler()->
392 texPrint( x, y - 3, "%s: %d%%",
393 getUpdate(),
394 static_cast<int>( ( getUpdateValue() + 1 ) / ( getUpdateTotal() / 100.0f ) ) );
395 glTranslatef( x + 150, y - 15, 0 );
396
397 progress->updateStatusLight( NULL,
398 static_cast<int>( ( getUpdateValue() + 1 ) / ( getUpdateTotal() / maxStatus ) ),
399 static_cast<int>( maxStatus ) );
400 } else {
401 scourge->getSDLHandler()->texPrint( x, y - 3, getUpdate() );
402 }
403 glPopMatrix();
404 }
405 eventsEnabled = scourge->getSession()->isDataInitialized();
406 if ( eventsEnabled ) scourge->getSDLHandler()->setCursorMode( Constants::CURSOR_NORMAL );
407 else scourge->getSDLHandler()->setCursorMode( Constants::CURSOR_FORBIDDEN );
408 }
409
show()410 void MainMenu::show() {
411 //logoRot = -scourge->getShapePalette()->logo->h;
412 logoRot = -173;
413 setValue( -1 );
414 }
415
hide()416 void MainMenu::hide() {
417 musicStarted = false;
418 }
419
420 /// Draws the menu.
421
drawMenu()422 void MainMenu::drawMenu() {
423
424 if ( textEffects.empty() && openingTop <= top ) {
425 int x = 50;
426 int y = top + 230;
427 for ( int i = 0; strlen( menuText[i] ); i++ ) {
428 TextEffect *textEffect = new TextEffect( scourge, x - 40, y - 20, _( menuText[i] ) );
429 textEffects.push_back( textEffect );
430 y += 50;
431 }
432 }
433
434 glDisable( GL_STENCIL_TEST );
435 glDisable( GL_SCISSOR_TEST );
436 glDisable( GL_CULL_FACE );
437 glDisable( GL_DEPTH_TEST );
438
439 for ( int i = 0; i < static_cast<int>( textEffects.size() ); i++ ) {
440 if ( this->scourge->getSession()->getPreferences()->getFlaky() == false ) {
441 TextEffect *textEffect = textEffects[i];
442 textEffect->setActive( i == activeMenuItem );
443 textEffect->draw();
444 } else {
445 glDisable( GL_DEPTH_TEST );
446 scourge->getSDLHandler()->setFontType( Constants::SCOURGE_LARGE_FONT );
447 if ( i == activeMenuItem ) {
448 glColor4f( 1, 1, 0, 1 );
449 } else {
450 glColor4f( 1, 1, 1, 1 );
451 }
452 scourge->getSDLHandler()->texPrint( 50, top + 230 + ( i * 50 ), _( menuText[i] ) );
453 scourge->getSDLHandler()->setFontType( Constants::SCOURGE_DEFAULT_FONT );
454 glEnable( GL_DEPTH_TEST );
455 }
456 }
457 }
458
459 /// Draws the logo in the upper left.
460
drawLogo()461 void MainMenu::drawLogo() {
462
463 glEnable( GL_BLEND );
464 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
465 glEnable( GL_TEXTURE_2D );
466
467 //Draw the Scourge logo
468 glPushMatrix();
469 glLoadIdentity();
470 glTranslatef( 70, logoRot, 0 );
471 // float w = scourge->getShapePalette()->logo->w;
472 // float h = scourge->getShapePalette()->logo->h;
473 float w = 352.0f;
474 float h = 173.0f;
475 glColor4f( 1, 1, 1, 1 );
476 scourge->getShapePalette()->logo_texture.glBind();
477
478 glBegin( GL_TRIANGLE_STRIP );
479 glTexCoord2f( 0.0f, 0.0f );
480 glVertex3f( 0, 0, 0 );
481 glTexCoord2f( 1.0f, 0.0f );
482 glVertex3f( w, 0, 0 );
483 glTexCoord2f( 0.0f, 1.0f );
484 glVertex3f( 0, h, 0 );
485 glTexCoord2f( 1.0f, 1.0f );
486 glVertex3f( w, h, 0 );
487 glEnd();
488 glPopMatrix();
489
490 for ( int i = 0; i < 2; i++ ) {
491 glPushMatrix();
492 glLoadIdentity();
493 // glTranslatef( ( !i ? 100 :
494 // 70 + scourge->getShapePalette()->logo->w - 30 -
495 // scourge->getShapePalette()->chain->w ),
496 // logoRot - scourge->getShapePalette()->chain->h, 0 );
497 // float w = scourge->getShapePalette()->chain->w;
498 // float h = scourge->getShapePalette()->chain->h;
499 glTranslatef( ( !i ? 100 : 70 + 352 - 30 - 32 ), logoRot - 256, 0 );
500 float w = 32.0f;
501 float h = 256.0f;
502 glColor4f( 1, 1, 1, 1 );
503 scourge->getShapePalette()->chain_texture.glBind();
504
505 glBegin( GL_TRIANGLE_STRIP );
506 glTexCoord2f( 0.0f, 0.0f );
507 glVertex3f( 0, 0, 0 );
508 glTexCoord2f( 1.0f, 0.0f );
509 glVertex3f( w, 0, 0 );
510 glTexCoord2f( 0.0f, 1.0f );
511 glVertex3f( 0, h, 0 );
512 glTexCoord2f( 1.0f, 1.0f );
513 glVertex3f( w, h, 0 );
514 glEnd();
515 glPopMatrix();
516 }
517
518 GLint t = SDL_GetTicks();
519 if ( t - logoTicks > logoTicksDelta ) {
520 if ( logoRot < 120 - ( ( 1024 - scourge->getScreenHeight() ) / 4 ) ) {
521 logoTicks = t;
522 logoRot += 8;
523 }
524 candleFlameX = scourge->getSDLHandler()->getScreen()->w - 215 + Util::dice( 4 ) - 4;
525 candleFlameY = top + 385 + Util::dice( 4 ) - 4;
526 }
527
528 glBlendFunc( GL_SRC_COLOR, GL_ONE );
529
530 scourge->getShapePalette()->candle.glBind();
531 glColor4f( 0.7f, 0.7f, 0.3f, 0.5f );
532 glPushMatrix();
533 glLoadIdentity();
534 glTranslatef( candleFlameX, candleFlameY, 0 );
535 w = 64;
536 h = 64;
537
538 glBegin( GL_TRIANGLE_STRIP );
539 glTexCoord2f( 0.0f, 0.0f );
540 glVertex3f( 0, 0, 0 );
541 glTexCoord2f( 1.0f, 0.0f );
542 glVertex3f( w, 0, 0 );
543 glTexCoord2f( 0.0f, 1.0f );
544 glVertex3f( 0, h, 0 );
545 glTexCoord2f( 1.0f, 1.0f );
546 glVertex3f( w, h, 0 );
547 glEnd();
548 glPopMatrix();
549
550 glDisable( GL_TEXTURE_2D );
551 glDisable( GL_BLEND );
552 }
553
554 /// Draws the stars.
555
drawStars()556 void MainMenu::drawStars() {
557 glDisable( GL_TEXTURE_2D );
558 for ( int i = 0; i < starCount; i++ ) {
559 glPushMatrix();
560 glLoadIdentity();
561 glTranslatef( star[i].x, star[i].y, -200 );
562 glColor3f( Util::roll( 0.2f, 0.99f ),
563 Util::roll( 0.2f, 0.99f ),
564 Util::roll( 0.2f, 0.99f ) );
565 int n = 1;
566 glBegin( GL_TRIANGLE_STRIP );
567 glVertex2d( 0, 0 );
568 glVertex2d( n, 0 );
569 glVertex2d( 0, n );
570 glVertex2d( n, n );
571 glEnd();
572 glPopMatrix();
573 }
574 glEnable( GL_TEXTURE_2D );
575
576 }
577
578 /// Draws the scourge (the house entrance to the right).
579
drawScourge()580 void MainMenu::drawScourge() {
581
582 glEnable( GL_BLEND );
583 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
584 glEnable( GL_TEXTURE_2D );
585
586 float w = 554; //scourge->getShapePalette()->scourge->w;
587 float h = 600; //scourge->getShapePalette()->scourge->h;
588
589 //Draw the scourge
590 glPushMatrix();
591 glLoadIdentity();
592 glTranslatef( scourge->getSDLHandler()->getScreen()->w - w, top, 0 );
593 glColor4f( 1, 1, 1, 1 );
594 scourge->getShapePalette()->getNamedTexture( "scourge" ).glBind();
595
596 glBegin( GL_TRIANGLE_STRIP );
597 glTexCoord2f( 0.005f, 0.005f );
598 glVertex3f( 0, 0, 0 );
599 glTexCoord2f( 0.995f, 0.005f );
600 glVertex3f( w, 0, 0 );
601 glTexCoord2f( 0.005f, 0.995f );
602 glVertex3f( 0, h, 0 );
603 glTexCoord2f( 0.995f, 0.995f );
604 glVertex3f( w, h, 0 );
605 glEnd();
606 glPopMatrix();
607
608 glDisable( GL_TEXTURE_2D );
609 glDisable( GL_BLEND );
610 }
611
612 /// Draws the mountains in the back.
613
drawBackdrop()614 void MainMenu::drawBackdrop() {
615 glEnable( GL_BLEND );
616 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
617 glEnable( GL_TEXTURE_2D );
618
619 // float w = scourge->getShapePalette()->scourgeBackdrop->w;
620 float w = scourge->getSDLHandler()->getScreen()->w;
621 //float h = scourge->getShapePalette()->scourgeBackdrop->h;
622 float h = 256.0f;
623
624 //Draw the backdrop image
625 glPushMatrix();
626 glLoadIdentity();
627 glTranslatef( 0, top + ( 600 - WATER_HEIGHT - h ), 0 );
628 glColor4f( 1, 1, 1, 1 );
629 scourge->getShapePalette()->scourgeBackdrop_texture.glBind();
630
631 glBegin( GL_TRIANGLE_STRIP );
632 glTexCoord2f( 0.0f, 0.0f );
633 glVertex3f( 0, 0, 0 );
634 glTexCoord2f( 1.0f, 0.0f );
635 glVertex3f( w, 0, 0 );
636 glTexCoord2f( 0.0f, 1.0f );
637 glVertex3f( 0, h, 0 );
638 glTexCoord2f( 1.0f, 1.0f );
639 glVertex3f( w, h, 0 );
640 glEnd();
641 glPopMatrix();
642
643 glDisable( GL_TEXTURE_2D );
644 glDisable( GL_BLEND );
645
646 }
647
648 /// Draws the clouds.
649
drawClouds(bool moveClouds,bool flipped)650 void MainMenu::drawClouds( bool moveClouds, bool flipped ) {
651 // draw clouds
652 float w, h;
653
654 glEnable( GL_TEXTURE_2D );
655 glEnable( GL_BLEND );
656 glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ONE );
657
658 scourge->getShapePalette()->cloud.glBind();
659
660 for ( int i = 0; i < cloudCount; i++ ) {
661 w = cloud[i].w;
662 h = cloud[i].h;
663 glPushMatrix();
664 glTranslatef( cloud[i].x,
665 top + ( flipped ? 600 - ( cloud[i].y + h / 2.0 ) : cloud[i].y + 130 ),
666 0 );
667
668 glBegin( GL_TRIANGLE_STRIP );
669 if ( flipped ) {
670 glColor4f( 0.1f, 0.1f, 0.3f, 0.5f );
671 } else {
672 glColor4f( 1, 1, 1, 1 );
673 }
674 glTexCoord2f( 0.0f, ( flipped ? 1.0f : 0.0f ) );
675 glVertex3f( 0, 0, 0 );
676
677 if ( flipped ) {
678 glColor4f( 0.1f, 0.1f, 0.3f, 0.5f );
679 } else {
680 glColor4f( 1, 1, 1, 1 );
681 }
682 glTexCoord2f( 1.0f, ( flipped ? 1.0f : 0.0f ) );
683 glVertex3f( w, 0, 0 );
684
685 glColor4f( 1, 0.3f, 0, 0.5f );
686 glTexCoord2f( 0.0f, ( flipped ? 0.0f : 1.0f ) );
687 glVertex3f( 0, ( flipped ? h / 2.0 : h ), 0 );
688
689 glColor4f( 1, 0.3f, 0, 0.5f );
690 glTexCoord2f( 1.0f, ( flipped ? 0.0f : 1.0f ) );
691 glVertex3f( w, ( flipped ? h / 2.0 : h ), 0 );
692 glEnd();
693 glPopMatrix();
694
695 if ( moveClouds ) {
696 cloud[i].x += cloud[i].speed;
697 if ( cloud[i].x >= scourge->getSDLHandler()->getScreen()->w ) {
698 cloud[i].x = -cloud[i].w;
699 }
700 }
701 }
702 glDisable( GL_BLEND );
703 glDisable( GL_TEXTURE_2D );
704 }
705
706 /// Draws the water.
707
drawWater()708 void MainMenu::drawWater() {
709 float w, h;
710 // draw the water
711 glPushMatrix();
712 w = scourge->getSDLHandler()->getScreen()->w;
713 h = WATER_HEIGHT;
714 glLoadIdentity();
715 glTranslatef( 0, top + ( 600 - h ), 0 );
716 glDisable( GL_TEXTURE_2D );
717 // glDisable( GL_LIGHTING );
718 //glEnable( GL_BLEND );
719 //glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ONE );
720
721 glBegin( GL_TRIANGLE_STRIP );
722 glColor4f( 0, 0, 0.1f, 1 );
723 glVertex3f( 0, 0, 0 );
724 glColor4f( 0, 0, 0.1f, 1 );
725 glVertex3f( w, 0, 0 );
726 glColor4f( 0, 0.1f, 0.4f, 1 );
727 glVertex3f( 0, h, 0 );
728 glColor4f( 0, 0.1f, 0.4f, 1 );
729 glVertex3f( w, h, 0 );
730 glEnd();
731 //glDisable( GL_BLEND );
732 glPopMatrix();
733 }
734
handleEvent(Widget * widget,SDL_Event * event)735 bool MainMenu::handleEvent( Widget *widget, SDL_Event *event ) {
736
737 if ( !eventsEnabled ) return false;
738
739 if ( aboutDialog->isVisible() ) {
740 if ( widget == aboutOK || widget == aboutDialog->closeButton ) {
741 aboutDialog->setVisible( false );
742 }
743 return false;
744 }
745
746 // if ( scourge->getMultiplayerDialog()->isVisible() ) {
747 // scourge->getMultiplayerDialog()->handleEvent( widget, event );
748 // if ( !scourge->getMultiplayerDialog()->isVisible() ) {
749 // if ( scourge->getMultiplayerDialog()->getValue() == MultiplayerDialog::START_SERVER ) {
750 // value = MULTIPLAYER_START;
751 // return true;
752 // } else if ( scourge->getMultiplayerDialog()->getValue() == MultiplayerDialog::JOIN_SERVER ) {
753 // if ( !( strlen( scourge->getMultiplayerDialog()->getServerName() ) &&
754 // strlen( scourge->getMultiplayerDialog()->getServerPort() ) &&
755 // strlen( scourge->getMultiplayerDialog()->getUserName() ) ) ) {
756 // scourge->showMessageDialog( Constants::getMessage( Constants::JOIN_SERVER_ERROR ) );
757 // } else {
758 // value = MULTIPLAYER_START;
759 // return true;
760 // }
761 // }
762 // }
763 // return false;
764 // }
765
766 return false;
767 }
768
handleEvent(SDL_Event * event)769 bool MainMenu::handleEvent( SDL_Event *event ) {
770
771 if ( !eventsEnabled ) return false;
772
773 if ( aboutDialog->isVisible() ) {
774 return false;
775 }
776
777 if ( scourge->getSaveDialog()->getWindow()->isVisible() ) {
778 return false;
779 }
780
781 if ( savegameDialog->getWindow()->isVisible() ) {
782 // savegameDialog->handleEvent( NULL, event );
783 return false;
784 }
785
786 if ( scourge->getOptionsMenu()->isVisible() ) {
787 // scourge->getOptionsMenu()->handleEvent( event );
788 return false;
789 }
790
791 if ( scourge->getMultiplayerDialog()->isVisible() ) {
792 // scourge->getMultiplayerDialog()->handleEvent( event );
793 return false;
794 }
795
796 if ( partyEditor && partyEditor->isVisible() ) {
797 // partyEditor->handleEvent( NULL, event );
798 return false;
799 }
800
801 /*
802 // esc to close new game confirmation (doesn't work)
803 if((event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) &&
804 newGameConfirm->isVisible() &&
805 event->key.keysym.sym == SDLK_ESCAPE) {
806 newGameConfirm->setVisible( false );
807 return false;
808 }
809 */
810
811 switch ( event->type ) {
812 //case SDL_KEYDOWN:
813 case SDL_KEYUP:
814 switch ( event->key.keysym.sym ) {
815 case SDLK_1: value = NEW_GAME; showPartyEditor(); return false;
816 case SDLK_2: value = CONTINUE_GAME; scourge->getSaveDialog()->show( false ); return false;
817 case SDLK_3: value = MULTIPLAYER; return true;
818 case SDLK_4: value = OPTIONS; return true;
819 case SDLK_5: value = ABOUT; return true;
820 case SDLK_6: case SDLK_ESCAPE: value = QUIT; return true;
821 case SDLK_7: value = EDITOR; return true;
822 default: break;
823 }
824 //break;
825 //case SDL_KEYUP:
826 if ( event->key.keysym.sym == '8' ) {
827 Scourge::blendA++; if ( Scourge::blendA >= 11 ) Scourge::blendA = 0;
828 fprintf( stderr, "blend: a=%d b=%d\n", Scourge::blendA, Scourge::blendB );
829 } else if ( event->key.keysym.sym == '9' ) {
830 Scourge::blendB++; if ( Scourge::blendB >= 11 ) Scourge::blendB = 0;
831 fprintf( stderr, "blend: a=%d b=%d\n", Scourge::blendA, Scourge::blendB );
832 }
833 break;
834 case SDL_MOUSEMOTION:
835 case SDL_MOUSEBUTTONUP:
836 if ( event->motion.x >= 50 && event->motion.x < 400 ) {
837 if ( this->scourge->getSession()->getPreferences()->getFlaky() == false ) {
838 activeMenuItem = ( event->motion.y - ( top + 240 ) ) / 50;
839 } else {
840 activeMenuItem = ( event->motion.y - ( top + 230 + SDLHandler::fontInfos[ Constants::SCOURGE_LARGE_FONT ]->yoffset ) ) / 50;
841 }
842 }
843 if ( event->button.button != SDL_BUTTON_LEFT ) return false;
844 if ( event->type == SDL_MOUSEBUTTONUP && activeMenuItem > -1 && activeMenuItem < static_cast<int>( textEffects.size() ) ) {
845 value = values[activeMenuItem];
846 if ( value == ABOUT ) {
847 aboutDialog->setVisible( true );
848 //value = ABOUT;
849 return false;
850 } else if ( value == NEW_GAME ) {
851 showPartyEditor();
852 return false;
853 } else if ( value == CONTINUE_GAME ) {
854 scourge->getSaveDialog()->show( false );
855 return false;
856 } else {
857 return true;
858 }
859 }
860 break;
861 default: break;
862 }
863 return false;
864 }
865
866 /// Returns the selected menu entry.
867
getValue()868 int MainMenu::getValue() {
869 return value;
870 }
871
showNewGameConfirmationDialog()872 void MainMenu::showNewGameConfirmationDialog() {
873 newGameConfirm->setVisible( true );
874 }
875
showSavegameDialog(bool inSaveMode)876 void MainMenu::showSavegameDialog( bool inSaveMode ) {
877 savegameDialog->show( inSaveMode );
878 }
879
showPartyEditor()880 void MainMenu::showPartyEditor() {
881 if ( !partyEditor ) partyEditor = new PartyEditor( scourge );
882 partyEditor->setVisible( true );
883 }
884
createParty(Creature ** pc,int * partySize)885 void MainMenu::createParty( Creature **pc, int *partySize ) {
886 if ( !partyEditor ) partyEditor = new PartyEditor( scourge );
887 partyEditor->createParty( pc, partySize );
888 }
889
createWanderingHero(int level)890 RenderedCreature *MainMenu::createWanderingHero( int level ) {
891 if ( !partyEditor ) partyEditor = new PartyEditor( scourge );
892 return partyEditor->createWanderingHero( level );
893 }
894
setSlideMode(bool b)895 void MainMenu::setSlideMode( bool b ) {
896 slideMode = b;
897
898 if ( slideMode ) {
899 openingTop = ( scourge->getSDLHandler()->getScreenHeight() / 2 ) - ( scourge->getSDLHandler()->getScreenWidth() / 4 );
900 slide = scourge->getShapePalette()->getRandomSlide();
901
902 } else {
903 openingTop = scourge->getSDLHandler()->getScreenHeight() / 2;
904 }
905 }