1 /*
2 Copyright (C) 2005 Matthias Braun <matze@braunis.de>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include <config.h>
19
20 #include <stdexcept>
21 #include <sstream>
22 #include <iostream>
23 #include <iomanip>
24 #include <typeinfo>
25 #include <physfs.h>
26 #include <stdio.h>
27 #include <time.h>
28
29 #include "gui/TextureManager.hpp"
30 #include "gui/ComponentLoader.hpp"
31 #include "gui/Component.hpp"
32 #include "gui/Event.hpp"
33 #include "gui/Desktop.hpp"
34 #include "gui/Button.hpp"
35 #include "gui/callback/Callback.hpp"
36
37 #include "gui_interface/shared_globals.h"
38 #include "lincity/lin-city.h"
39 #include "lincity/fileutil.h"
40
41 #include "CheckButton.hpp"
42
43 #include "MainMenu.hpp"
44 #include "Util.hpp"
45 #include "Config.hpp"
46 #include "Sound.hpp"
47 #include "GameView.hpp"
48 #include "MainLincity.hpp"
49 #include "readdir.hpp"
50
51 #include "tinygettext/gettext.hpp"
52
53 extern void new_city(int *originx, int *originy, int random_village);
54
MainMenu()55 MainMenu::MainMenu()
56 {
57 loadMainMenu();
58 switchMenu(mainMenu.get());
59 baseName = "";
60 lastClickTick = 0;
61 doubleClickButtonName = "";
62 }
63
~MainMenu()64 MainMenu::~MainMenu()
65 {
66 }
67
68 void
loadMainMenu()69 MainMenu::loadMainMenu()
70 {
71 if(mainMenu.get() == 0) {
72 mainMenu.reset(loadGUIFile("gui/mainmenu.xml"));
73
74 // connect signals
75 Button* quitButton = getButton(*mainMenu, "QuitButton");
76 quitButton->clicked.connect(
77 makeCallback(*this, &MainMenu::quitButtonClicked));
78 Button* continueButton = getButton(*mainMenu, "ContinueButton");
79 continueButton->clicked.connect(
80 makeCallback(*this, &MainMenu::continueButtonClicked));
81 Button* newGameButton = getButton(*mainMenu, "NewGameButton");
82 newGameButton->clicked.connect(
83 makeCallback(*this, &MainMenu::newGameButtonClicked));
84 Button* loadGameButton = getButton(*mainMenu, "LoadButton");
85 loadGameButton->clicked.connect(
86 makeCallback(*this, &MainMenu::loadGameButtonClicked));
87 Button* saveGameButton = getButton(*mainMenu, "SaveButton");
88 saveGameButton->clicked.connect(
89 makeCallback(*this, &MainMenu::saveGameButtonClicked));
90 Button* creditsButton = getButton(*mainMenu, "CreditsButton");
91 creditsButton->clicked.connect(
92 makeCallback(*this, &MainMenu::creditsButtonClicked));
93 Button* optionsButton = getButton(*mainMenu, "OptionsButton");
94 optionsButton->clicked.connect(
95 makeCallback(*this, &MainMenu::optionsButtonClicked));
96
97 }
98
99 mainMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
100 }
101
fillNewGameMenu()102 void MainMenu::fillNewGameMenu()
103 {
104 const std::string buttonNames[]={"File0","File1","File2","File3","File4","File5"};
105
106 char **files= PHYSFS_enumerateFiles("opening");
107
108 char **fptr=files;
109
110 fileMap.clear();
111
112 for(int i=0;i<6;i++)
113 {
114 CheckButton *button=getCheckButton(*newGameMenu.get(),buttonNames[i]);
115
116 button->clicked.connect(makeCallback(*this,&MainMenu::selectLoadGameButtonClicked));
117 while(*fptr)
118 {
119 if(std::string(*fptr).find(".scn")!=std::string::npos)
120 break;
121 fptr++;
122 }
123 if(*fptr)
124 {
125 std::string f=*fptr;
126 if(f.length()>5){
127 f=f.substr(0,f.length()-4); // truncate .scn
128 }
129 // save real name
130 fileMap.insert(std::pair<std::string, std::string>(buttonNames[i], f ));
131 // use translated name for caption
132 button->setCaptionText(_(f.c_str()));
133 fptr++;
134 }
135 else
136 button->setCaptionText("");
137 }
138 PHYSFS_freeList(files);
139 return;
140 /* Is there a better way to add filenames to the directory? */
141 _("good_times");
142 _("bad_times");
143 _("Beach");
144 _("extreme_arid");
145 _("extreme_wetland");
146 }
147
fillLoadMenu(bool save)148 void MainMenu::fillLoadMenu( bool save /*= false*/ )
149 {
150 const std::string buttonNames[]={"File0","File1","File2","File3","File4","File5"};
151
152 char** rc = PHYSFS_enumerateFiles("/");
153
154 char* curfile;
155 CheckButton *button;
156
157 for(int i=0;i<6;i++) {
158 char* recentfile = NULL;
159 PHYSFS_sint64 t = 0;
160
161 std::stringstream filestart;
162 filestart << i+1 << "_";
163 if( save ){
164 button = getCheckButton(*saveGameMenu.get(),buttonNames[i]);
165 } else {
166 button = getCheckButton(*loadGameMenu.get(),buttonNames[i]);
167 }
168 //make sure Button is connected only once
169 button->clicked.clear();
170 if( save )
171 button->clicked.connect(makeCallback(*this,&MainMenu::selectSaveGameButtonClicked));
172 else {
173 button->clicked.connect(makeCallback(*this,&MainMenu::selectLoadGameButtonClicked));
174 }
175 for(char** i = rc; *i != 0; i++){
176 curfile = *i;
177 if(std::string( curfile ).find( filestart.str() ) == 0 ) {
178 // && !( curfile->d_type & DT_DIR ) ) is not portable. So
179 // don't create a directoy named 2_ in a savegame-directory or
180 // you can no longer load from slot 2.
181 if (t == 0) {
182 recentfile = curfile;
183 t = PHYSFS_getLastModTime(recentfile);
184 } else {
185 if (PHYSFS_getLastModTime(curfile) > t) {
186 #ifdef DEBUG
187 fprintf(stderr," %s is more recent than previous %s\n",
188 curfile, recentfile);
189 #endif
190 recentfile = curfile;
191 t = PHYSFS_getLastModTime(recentfile);
192 }
193 }
194 }
195 }
196 #ifdef DEBUG
197 fprintf(stderr,"Most recent file: %s\n\n",recentfile);
198 #endif
199
200 if(t != 0) {
201 std::string f= recentfile;
202 button->setCaptionText(f);
203 } else {
204 button->setCaptionText(_("empty"));
205 }
206 }
207 }
208
209 void
loadNewGameMenu()210 MainMenu::loadNewGameMenu()
211 {
212 if(newGameMenu.get() == 0) {
213 newGameMenu.reset(loadGUIFile("gui/newgame.xml"));
214
215 // connect signals
216 Button* startButton = getButton(*newGameMenu, "StartButton");
217 startButton->clicked.connect(
218 makeCallback(*this, &MainMenu::newGameStartButtonClicked));
219 Button* backButton = getButton(*newGameMenu, "BackButton");
220 backButton->clicked.connect(
221 makeCallback(*this, &MainMenu::newGameBackButtonClicked));
222 Button* startBareButton = getButton(*newGameMenu, "StartBareButton");
223 startBareButton->clicked.connect(
224 makeCallback(*this, &MainMenu::newGameStartBareButtonClicked));
225 Button* startVillageButton = getButton(*newGameMenu, "StartVillageButton");
226 startVillageButton->clicked.connect(
227 makeCallback(*this, &MainMenu::newGameStartVillageClicked));
228 fillNewGameMenu();
229 }
230
231 newGameMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
232 }
233
234 void
loadCreditsMenu()235 MainMenu::loadCreditsMenu()
236 {
237 if(creditsMenu.get() == 0) {
238 creditsMenu.reset(loadGUIFile("gui/credits.xml"));
239 Button* backButton = getButton(*creditsMenu, "BackButton");
240 backButton->clicked.connect(
241 makeCallback(*this, &MainMenu::creditsBackButtonClicked));
242 }
243
244 creditsMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
245 }
246
247 void
loadOptionsMenu()248 MainMenu::loadOptionsMenu()
249 {
250 if(optionsMenu.get() == 0) {
251 optionsMenu.reset(loadGUIFile("gui/options.xml"));
252 CheckButton* currentCheckButton = getCheckButton(*optionsMenu, "BackgroundMusic");
253 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
254 currentCheckButton = getCheckButton(*optionsMenu, "SoundFX");
255 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
256 currentCheckButton = getCheckButton(*optionsMenu, "Fullscreen");
257 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
258 currentCheckButton = getCheckButton(*optionsMenu, "MusicVolumePlus");
259 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
260 currentCheckButton = getCheckButton(*optionsMenu, "MusicVolumeMinus");
261 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
262 currentCheckButton = getCheckButton(*optionsMenu, "FXVolumePlus");
263 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
264 currentCheckButton = getCheckButton(*optionsMenu, "FXVolumeMinus");
265 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
266 currentCheckButton = getCheckButton(*optionsMenu, "TrackPrev");
267 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
268 currentCheckButton = getCheckButton(*optionsMenu, "TrackNext");
269 currentCheckButton->clicked.connect( makeCallback(*this, &MainMenu::optionsMenuButtonClicked));
270
271 Button* currentButton = getButton(*optionsMenu, "BackButton");
272 currentButton->clicked.connect( makeCallback(*this, &MainMenu::creditsBackButtonClicked));
273 }
274 //adjust checkbutton-states
275 if( getConfig()->musicEnabled ){
276 getCheckButton(*optionsMenu, "BackgroundMusic")->check();
277 } else {
278 getCheckButton(*optionsMenu, "BackgroundMusic")->uncheck();
279 }
280 if( getConfig()->soundEnabled ){
281 getCheckButton(*optionsMenu, "SoundFX")->check();
282 } else {
283 getCheckButton(*optionsMenu, "SoundFX")->uncheck();
284 }
285 if( getConfig()->useFullScreen ){
286 getCheckButton(*optionsMenu, "Fullscreen")->check();
287 } else {
288 getCheckButton(*optionsMenu, "Fullscreen")->uncheck();
289 }
290 //current background track
291 musicParagraph = getParagraph( *optionsMenu, "musicParagraph");
292 musicParagraph->setText(getConfig()->playSongName);
293
294 optionsMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
295 }
296
297 void
loadLoadGameMenu()298 MainMenu::loadLoadGameMenu()
299 {
300 if(loadGameMenu.get() == 0) {
301 loadGameMenu.reset(loadGUIFile("gui/loadgame.xml"));
302
303 // connect signals
304 Button* loadButton = getButton(*loadGameMenu, "LoadButton");
305 loadButton->clicked.connect(
306 makeCallback(*this, &MainMenu::loadGameLoadButtonClicked));
307 Button* backButton = getButton(*loadGameMenu, "BackButton");
308 backButton->clicked.connect(
309 makeCallback(*this, &MainMenu::loadGameBackButtonClicked));
310 }
311
312 // fill in file-names into slots
313 fillLoadMenu();
314 loadGameMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
315 }
316
317 void
loadSaveGameMenu()318 MainMenu::loadSaveGameMenu()
319 {
320 if(saveGameMenu.get() == 0) {
321 saveGameMenu.reset(loadGUIFile("gui/savegame.xml"));
322
323 // connect signals
324 Button* saveButton = getButton(*saveGameMenu, "SaveButton");
325 saveButton->clicked.connect(
326 makeCallback(*this, &MainMenu::loadGameSaveButtonClicked));
327 Button* backButton = getButton(*saveGameMenu, "BackButton");
328 backButton->clicked.connect(
329 makeCallback(*this, &MainMenu::loadGameBackButtonClicked));
330 // fill in file-names into slots
331 fillLoadMenu( true );
332 }
333
334 saveGameMenu->resize(SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h);
335 }
336
337
338 void
selectLoadGameButtonClicked(CheckButton * button,int i)339 MainMenu::selectLoadGameButtonClicked(CheckButton* button, int i){
340 selectLoadSaveGameButtonClicked( button , i, false );
341 }
342
343 void
selectSaveGameButtonClicked(CheckButton * button,int i)344 MainMenu::selectSaveGameButtonClicked(CheckButton* button, int i){
345 selectLoadSaveGameButtonClicked( button , i, true );
346 }
347
348 void
selectLoadSaveGameButtonClicked(CheckButton * button,int,bool save)349 MainMenu::selectLoadSaveGameButtonClicked(CheckButton* button , int, bool save )
350 {
351 std::string fc=button->getCaptionText();
352 if( newGameMenu.get()==currentMenu ) {
353 std::map<std::string, std::string>::iterator iter;
354 iter = fileMap.find( button->getName() );
355 if( iter != fileMap.end() ){
356 fc = iter->second;
357 }
358 }
359
360 std::string file="";
361
362 /* I guess this should be the proper way of selecting in the menu.
363 Everytime we check a new button the last one gets unchecked.
364 If the button checked is an empty one, nothing should be opened
365 Could be done the other way around: the first time an existing item
366 is selected in the menu, an empty one could never be checked again.
367 Anyway I don't think both should be checked, when an empty is checked
368 after an existing one.
369 */
370
371 const std::string bs[]={"File0","File1","File2","File3","File4","File5",""};
372 for(int i=0;std::string(bs[i]).length();i++) {
373 CheckButton *b=getCheckButton(*currentMenu,bs[i]);
374 if(b->getName()!=button->getName()){
375 b->uncheck();
376 } else {
377 b->check();
378 }
379 }
380
381 if( !fc.length()) {
382 mFilename = "";
383 return;
384 }
385
386 baseName = fc;
387 if(newGameMenu.get()==currentMenu ) {
388 file=std::string("opening/")+fc+".scn";
389 } else {
390 file=fc;
391 }
392
393 mFilename="";
394 if(newGameMenu.get()!=currentMenu) {
395 slotNr = 1 + atoi(
396 const_cast<char*>(button->getName().substr(4).c_str()) );
397 if( file.length() == 0){
398 mFilename = "";
399 return;
400 }
401 }
402
403 mFilename+=file;
404 Uint32 now = SDL_GetTicks();
405
406 //doubleclick on Filename loads File
407 if( ( fc == doubleClickButtonName ) && ( !save ) &&
408 ( now - lastClickTick < doubleClickTime ) ) {
409
410 lastClickTick = 0;
411 doubleClickButtonName = "";
412 if( newGameMenu.get() == currentMenu ) {
413 //load scenario
414 newGameStartButtonClicked( 0 );
415 } else {
416 //load game
417 loadGameLoadButtonClicked( 0 );
418 }
419 } else {
420 lastClickTick = now;
421 doubleClickButtonName = fc;
422 }
423 }
424
optionsMenuButtonClicked(CheckButton * button,int)425 void MainMenu::optionsMenuButtonClicked( CheckButton* button, int ){
426 std::string buttonName = button->getName();
427 if( buttonName == "BackgroundMusic"){
428 getSound()->playSound("Click");
429 getSound()->enableMusic( !getConfig()->musicEnabled );
430 } else if( buttonName == "MusicVolumePlus"){
431 int newVolume = getConfig()->musicVolume + 5;
432 if( newVolume > 100 ){
433 newVolume = 100;
434 }
435 if( getConfig()->musicVolume != newVolume ){
436 getSound()->setMusicVolume( newVolume );
437 getSound()->playSound("Click");
438 }
439 } else if( buttonName == "MusicVolumeMinus"){
440 int newVolume = getConfig()->musicVolume -5;
441 if( newVolume < 0 ){
442 newVolume = 0;
443 }
444 if( getConfig()->musicVolume != newVolume ){
445 getSound()->setMusicVolume( newVolume );
446 getSound()->playSound("Click");
447 }
448 } else if( buttonName == "SoundFX"){
449 getConfig()->soundEnabled = !getConfig()->soundEnabled;
450 getSound()->playSound("Click");
451 } else if( buttonName == "FXVolumePlus"){
452 int newVolume = getConfig()->soundVolume + 5;
453 if( newVolume > 100 ){
454 newVolume = 100;
455 }
456 if( getConfig()->soundVolume != newVolume ){
457 getSound()->setSoundVolume( newVolume );
458 getSound()->playSound("Click");
459 }
460 } else if( buttonName == "FXVolumeMinus"){
461 int newVolume = getConfig()->soundVolume - 5;
462 if( newVolume < 0 ){
463 newVolume = 0;
464 }
465 if( getConfig()->soundVolume != newVolume ){
466 getSound()->setSoundVolume( newVolume );
467 getSound()->playSound("Click");
468 }
469 } else if( buttonName == "Fullscreen"){
470 getSound()->playSound("Click");
471 getConfig()->useFullScreen = !getConfig()->useFullScreen;
472 if( getConfig()->restartOnChangeScreen ){
473 quitState = RESTART;
474 running = false;
475 } else {
476 initVideo(getConfig()->videoX, getConfig()->videoY);
477 loadOptionsMenu();
478 }
479 } else if( buttonName == "TrackPrev"){
480 changeTrack(false);
481 } else if( buttonName == "TrackNext"){
482 changeTrack(true);
483 } else {
484 std::cerr << "MainMenu::optionsMenuButtonClicked " << buttonName << " unknown Button!\n";
485 }
486 }
487
488 void
changeTrack(bool next)489 MainMenu::changeTrack( bool next)
490 {
491 std::string filename;
492 std::string directory = "music/";
493 std::string fullname;
494 std::string currentname = getConfig()->playSongName;
495 std::string prevname = currentname;
496 std::string nextname = currentname;
497
498 bool hit = false;
499
500 char **files= PHYSFS_enumerateFiles(directory.c_str());
501 char **fptr=files;
502 while(*fptr)
503 {
504 fullname = directory;
505 fullname.append( *fptr );
506 filename.assign( *fptr );
507
508 if(!PHYSFS_isDirectory(fullname.c_str())){
509 if( filename == currentname ){
510 hit = true;
511 } else if ( !hit ){
512 prevname = filename;
513 } else {
514 nextname = filename;
515 break;
516 }
517 }
518 fptr++;
519 }
520 PHYSFS_freeList(files);
521
522 if(next){
523 if( nextname != currentname){
524 getSound()->playSound("Click");
525 getSound()->playMusic(nextname);
526 }
527 } else {
528 if( prevname != currentname){
529 getSound()->playSound("Click");
530 getSound()->playMusic(prevname);
531 }
532 }
533 musicParagraph->setText(getConfig()->playSongName);
534 }
535 void
quitButtonClicked(Button *)536 MainMenu::quitButtonClicked(Button* )
537 {
538 getSound()->playSound( "Click" );
539 quitState = QUIT;
540 running = false;
541 }
542
543 void
switchMenu(Component * newMenu)544 MainMenu::switchMenu(Component* newMenu)
545 {
546 currentMenu = dynamic_cast<Desktop*> (newMenu);
547 if(!currentMenu)
548 throw std::runtime_error("Menu Component is not a Desktop");
549 }
550
551 void
creditsButtonClicked(Button *)552 MainMenu::creditsButtonClicked(Button* )
553 {
554 getSound()->playSound( "Click" );
555 loadCreditsMenu();
556 switchMenu(creditsMenu.get());
557 }
558
559 void
optionsButtonClicked(Button *)560 MainMenu::optionsButtonClicked(Button* )
561 {
562 getSound()->playSound( "Click" );
563 loadOptionsMenu();
564 switchMenu(optionsMenu.get());
565 }
566
567 void
continueButtonClicked(Button *)568 MainMenu::continueButtonClicked(Button* )
569 {
570 getSound()->playSound( "Click" );
571 quitState = INGAME;
572 running = false;
573 }
574
575 void
newGameButtonClicked(Button *)576 MainMenu::newGameButtonClicked(Button* )
577 {
578 getSound()->playSound( "Click" );
579 loadNewGameMenu();
580 switchMenu(newGameMenu.get());
581 }
582
583 void
loadGameButtonClicked(Button *)584 MainMenu::loadGameButtonClicked(Button* )
585 {
586 getSound()->playSound( "Click" );
587 loadLoadGameMenu();
588 switchMenu(loadGameMenu.get());
589 }
590
591 void
saveGameButtonClicked(Button *)592 MainMenu::saveGameButtonClicked(Button* )
593 {
594 getSound()->playSound( "Click" );
595 loadSaveGameMenu();
596 switchMenu(saveGameMenu.get());
597 }
598
599 void
creditsBackButtonClicked(Button *)600 MainMenu::creditsBackButtonClicked(Button* )
601 {
602 getSound()->playSound("Click");
603 loadMainMenu();
604 switchMenu(mainMenu.get());
605 }
606
607 void
newGameStartButtonClicked(Button *)608 MainMenu::newGameStartButtonClicked(Button* )
609 {
610 getSound()->playSound( "Click" );
611 if( loadCityNG( mFilename ) ){
612 strcpy (given_scene, baseName.c_str());
613 quitState = INGAME;
614 running = false;
615 }
616 mFilename = "empty"; //don't erase scenarios later
617 }
618
619 void
newGameStartBareButtonClicked(Button *)620 MainMenu::newGameStartBareButtonClicked(Button* )
621 {
622 getSound()->playSound( "Click" );
623 new_city( &main_screen_originx, &main_screen_originy, 0 );
624 GameView* gv = getGameView();
625 if( gv ){ gv->readOrigin(); }
626 quitState = INGAME;
627 running = false;
628 }
629
630 void
newGameStartVillageClicked(Button *)631 MainMenu::newGameStartVillageClicked(Button* )
632 {
633 getSound()->playSound( "Click" );
634 new_city( &main_screen_originx, &main_screen_originy, 1 );
635 GameView* gv = getGameView();
636 if( gv ){ gv->readOrigin(); }
637 quitState = INGAME;
638 running = false;
639 }
640
641 void
newGameBackButtonClicked(Button *)642 MainMenu::newGameBackButtonClicked(Button* )
643 {
644 getSound()->playSound( "Click" );
645 loadMainMenu();
646 switchMenu(mainMenu.get());
647 }
648
649 void
loadGameBackButtonClicked(Button *)650 MainMenu::loadGameBackButtonClicked(Button* )
651 {
652 getSound()->playSound( "Click" );
653 loadMainMenu();
654 switchMenu(mainMenu.get());
655 }
656
657 void
gotoMainMenu()658 MainMenu::gotoMainMenu()
659 {
660 getSound()->playSound( "Click" );
661 loadMainMenu();
662 switchMenu(mainMenu.get());
663 }
664
665 void
loadGameLoadButtonClicked(Button *)666 MainMenu::loadGameLoadButtonClicked(Button *)
667 {
668 getSound()->playSound( "Click" );
669 if( loadCityNG( mFilename ) ){
670 quitState = INGAME;
671 running = false;
672 }
673 }
674
675 void
loadGameSaveButtonClicked(Button *)676 MainMenu::loadGameSaveButtonClicked(Button *)
677 {
678 getSound()->playSound( "Click" );
679 if( file_exists( const_cast<char*>(mFilename.c_str()) ) ){
680 std::cout << "remove( " << mFilename << ")\n";
681 remove( mFilename.c_str() );
682 }
683 /* Build filename */
684 std::stringstream newStart;
685 newStart << slotNr << "_Y";
686 newStart << std::setfill('0') << std::setw(5);
687 fprintf(stderr,"total_time %i\n",total_time);
688 newStart << total_time/1200;
689 newStart << "_Tech";
690 newStart << std::setfill('0') << std::setw(3);
691 newStart << tech_level/10000;
692 newStart << "_Cash";
693 if (total_money >= 0)
694 newStart << "+";
695 else
696 newStart << "-";
697 newStart << std::setfill('0') << std::setw(3);
698 int money = abs(total_money);
699 if (money > 1000000000)
700 newStart << money/1000000000 << "G";
701 else if (money > 1000000)
702 newStart << money/1000000 << "M";
703 else if(money > 1000)
704 newStart << money/1000 << "K";
705 else
706 newStart << money/1 << "_";
707
708 newStart << "_P";
709 newStart << std::setfill('0') << std::setw(5);
710 newStart << housed_population + people_pool;
711 std::string newFilename( newStart.str() );
712 saveCityNG( newFilename );
713 fillLoadMenu( true );
714 }
715
716
717 MainState
run()718 MainMenu::run()
719 {
720 SDL_Event event;
721 running = true;
722 quitState = QUIT;
723 Uint32 ticks = SDL_GetTicks();
724
725 int frame = 0;
726 while(running) {
727 while(SDL_PollEvent(&event)) {
728 switch(event.type) {
729 case SDL_VIDEORESIZE:
730 initVideo(event.resize.w, event.resize.h);
731 currentMenu->resize(event.resize.w, event.resize.h);
732 break;
733 case SDL_MOUSEMOTION:
734 case SDL_MOUSEBUTTONUP:
735 case SDL_MOUSEBUTTONDOWN:
736 case SDL_KEYDOWN:{
737 Event gui_event(event);
738 currentMenu->event(gui_event);
739 break;
740 }
741 case SDL_KEYUP: {
742 Event gui_event(event);
743 //In menu ESC as well as ^c exits the game.
744 //might come in handy if video-mode is not working as expected.
745 if( ( gui_event.keysym.sym == SDLK_ESCAPE ) ||
746 ( gui_event.keysym.sym == SDLK_c && ( gui_event.keysym.mod & KMOD_CTRL) ) ){
747 running = false;
748 quitState = QUIT;
749 break;
750 }
751 currentMenu->event(gui_event);
752 break;
753 }
754 case SDL_VIDEOEXPOSE:
755 currentMenu->resize( currentMenu->getWidth(), currentMenu->getHeight() );
756 break;
757 case SDL_ACTIVEEVENT:
758 if( event.active.gain == 1 ){
759 currentMenu->resize( currentMenu->getWidth(), currentMenu->getHeight() );
760 }
761 break;
762 case SDL_QUIT:
763 running = false;
764 quitState = QUIT;
765 break;
766 default:
767 break;
768 }
769 }
770
771 SDL_Delay(10); // give the CPU time to relax... (we are in main menu)
772
773 if(currentMenu->needsRedraw()) {
774 currentMenu->draw(*painter);
775 flipScreenBuffer();
776 }
777
778 frame++;
779 if(SDL_GetTicks() - ticks > 1000) {
780 #ifdef DEBUG_FPS
781 printf("FPS: %d.\n", frame);
782 #endif
783 frame = 0;
784 ticks = SDL_GetTicks();
785 }
786 }
787
788 return quitState;
789 }
790