00001 #include "Menu.h"
00002 #include "List.h"
00003 #include "Parser.h"
00004 #include "Sprite.h"
00005 #include "Game.h"
00006 #include "Control.h"
00007
00008 using namespace std;
00009
00010 int Menu::_textHeight = 50;
00011 int Menu::_leftMargin = 150;
00012 int Menu::_topMargin = 100;
00013 Menu::Menu()
00014 :_selected(0),_background(0)
00015 {
00016 }
00017 Menu::Menu(std::string filename)
00018 :_selected(0),_background(0)
00019 {
00020 List* menuInfo = Parser::parse(filename);
00021 load(menuInfo);
00022 delete menuInfo;
00023 }
00024
00025 Menu::Menu(List* menuInfo)
00026 :_selected(0),_background(0)
00027 {
00028 load(menuInfo);
00029 }
00030
00031 void Menu::load(List* menuInfo)
00032 {
00033
00034 menuInfo = menuInfo->rest();
00035 while(!menuInfo->empty())
00036 {
00037 List * current = menuInfo->firstList();
00038 menuInfo = menuInfo->rest();
00039
00040 if(current->firstString() == "submenu")
00041 {
00042 current = current->rest();
00043 _options.push_back(new Menu(current->firstString()));
00044 }
00045 else if(current->firstString() == "menu")
00046 {
00047 _options.push_back(new Menu(current));
00048 }
00049 else if(current->firstString() == "selectKey")
00050 {
00051 _options.push_back(new SelectKeyMenu(current));
00052 }
00053 else if(current->firstString() == "newGame")
00054 {
00055 _options.push_back(new NewGameMenu(current));
00056 }
00057 else if(current->firstString() == "background")
00058 {
00059 current = current->rest();
00060 _background = Sprite::loadSprite(current->firstString());
00061 }
00062 else if(current->firstString() == "title")
00063 {
00064 current = current->rest();
00065 _title = current->firstString();
00066 }
00067 else if(current->firstString() == "subtitle")
00068 {
00069 current = current->rest();
00070 _subtitles.push_back(" " + current->firstString());
00071 }
00072 }
00073
00074 if(_background)
00075 _background->setRect(Screen::instance()->getScreenRect());
00076
00077 _selectedMax = _options.size() - 1;
00078 }
00079
00080 void Menu::drawTitle(int x, int y, bool selected)
00081 {
00082 if(selected)
00083 glfuncs::instance()->glPrint( x, y, "> " + _title, false);
00084 else
00085 glfuncs::instance()->glPrint( x, y, " " + _title, false);
00086 }
00087
00088 bool Menu::control(SDL_Event event)
00089 {
00090
00091 if(event.type == SDL_KEYDOWN) {
00092 if(event.key.keysym.sym == Control::menuDownKey){
00093 if(_selected < _selectedMax)
00094 _selected ++;
00095 }
00096 else if(event.key.keysym.sym == Control::menuUpKey){
00097 if(_selected > 0)
00098 _selected --;
00099 }
00100 else if(event.key.keysym.sym == Control::selectKey){
00101 return select();
00102 }
00103 }
00104 return false;
00105 }
00106
00107 void Menu::draw()
00108 {
00109 if(_background)
00110 _background->draw(0,0,Sprite::SCREEN);
00111
00112 drawTitle(_leftMargin,_topMargin,false);
00113
00114
00115 int offset = _topMargin + _textHeight - _textHeight/4;
00116
00117 for(int i=0; i<_subtitles.size(); i++){
00118 glfuncs::instance()->glPrint( _leftMargin, offset, _subtitles[i], true);
00119 offset+= _textHeight/4;
00120 }
00121
00122 offset += _textHeight;
00123 for(size_t i = 0; i< _options.size(); i++)
00124 _options[i]->drawTitle(_leftMargin,offset + _textHeight*i, _selected==i);
00125
00126
00127
00128 Screen::drawScramble();
00129
00130
00131
00132 }
00133
00134 bool Menu::select()
00135 {
00136 _options[_selected]->mainLoop();
00137 return false;
00138 }
00139
00140 void Menu::mainLoop()
00141 {
00142 SDL_Event event;
00143 Screen* screen = Screen::instance();
00144 bool leave = false;
00145 int ticks = SDL_GetTicks();
00146
00147
00148
00149 while( !leave)
00150 {
00151
00152 glfuncs::instance()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00153
00154
00155 while((SDL_GetTicks() - ticks) < 1000/Screen::FRAMERATE)
00156 {
00157
00158 Sleep(0);
00159 }
00160
00161
00162 ticks = SDL_GetTicks();
00163
00164 draw();
00165
00166
00167 glfuncs::instance()->glFinish();
00168 SDL_GL_SwapBuffers();
00169
00170
00171 while(SDL_PollEvent(&event))
00172 {
00173 leave = control(event);
00174 if(event.type == SDL_KEYDOWN) {
00175 if( event.key.keysym.sym == Control::quitKey)
00176 leave = true;
00177 }
00178
00179 else if( event.type == SDL_QUIT )
00180 {
00181 leave = true;
00182 }
00183 }
00184
00185 }
00186 }
00187
00188 Menu::~Menu()
00189 {
00190 for(size_t i =0 ; i< _options.size(); i++)
00191 delete (_options[i]);
00192 }
00193
00194
00195
00196 SelectKeyMenu::SelectKeyMenu(List * menuInfo)
00197 :Menu(menuInfo)
00198 {
00199 _title = "Select Keys";
00200 _selectedMax = 8;
00201
00202 _options.clear();
00203 _subtitles.clear();
00204 _subtitles.push_back(" Press Esc to return to previous menu.");
00205 _subtitles.push_back("");
00206 _subtitles.push_back(" Select a control, then press space followed by the new key to set a key for that action");
00207
00208
00209 _text[0] = "Up: ";
00210 _text[1] = "Down/Crouch: ";
00211 _text[2] = "Left: ";
00212 _text[3] = "Right: ";
00213 _text[4] = "Jump: ";
00214 _text[5] = "Primary Fire: ";
00215 _text[6] = "Primary Fire: ";
00216 _text[7] = "Alt Fire: ";
00217 _text[8] = "Alt Fire: ";
00218
00219 _keys[0] += (string)SDL_GetKeyName(Control::upKey);
00220 _keys[1] += (string)SDL_GetKeyName(Control::downKey);
00221 _keys[2] += (string)SDL_GetKeyName(Control::leftKey);
00222 _keys[3] += (string)SDL_GetKeyName(Control::rightKey);
00223 _keys[4] += (string)SDL_GetKeyName(Control::jumpKey);
00224 _keys[5] += (string)SDL_GetKeyName(Control::shoot1Key);
00225 _keys[6] += (string)SDL_GetKeyName(Control::shoot2Key);
00226 _keys[7] += (string)SDL_GetKeyName(Control::altShoot1Key);
00227 _keys[8] += (string)SDL_GetKeyName(Control::altShoot2Key);
00228
00229
00230 }
00231 void SelectKeyMenu::draw()
00232 {
00233
00234
00235 Menu::draw();
00236
00237 int offset = _textHeight*4;
00238
00239 for(int i=0; i<9; i++)
00240 {
00241 if(_selected == i)
00242 glfuncs::instance()->glPrint( _leftMargin, offset, "> " + _text[i] + _keys[i], false);
00243 else
00244 glfuncs::instance()->glPrint( _leftMargin, offset, " " + _text[i] + _keys[i], false);
00245 offset += _textHeight;
00246 }
00247
00248
00249 }
00250
00251 bool SelectKeyMenu::select()
00252 {
00253
00254 _keys[_selected] = "Press a key";
00255
00256
00257 glfuncs::instance()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00258 draw();
00259 glfuncs::instance()->glFinish();
00260 SDL_GL_SwapBuffers();
00261
00262 SDL_Event event;
00263 SDLKey keysym;
00264 while(true)
00265 {
00266 SDL_PollEvent(&event);
00267 if(event.type == SDL_KEYDOWN) {
00268 keysym = event.key.keysym.sym;
00269 break;
00270 }
00271 }
00272
00273 _keys[_selected] = SDL_GetKeyName(keysym);
00274
00275 switch(_selected)
00276 {
00277 case 0:
00278 Control::upKey = keysym;
00279 break;
00280 case 1:
00281 Control::downKey = keysym;
00282 break;
00283 case 2:
00284 Control::leftKey = keysym;
00285 break;
00286 case 3:
00287 Control::rightKey = keysym;
00288 break;
00289 case 4:
00290 Control::jumpKey = keysym;
00291 break;
00292 case 5:
00293 Control::shoot1Key = keysym;
00294 break;
00295 case 6:
00296 Control::shoot2Key = keysym;
00297 break;
00298 case 7:
00299 Control::altShoot1Key = keysym;
00300 break;
00301 case 8:
00302 Control::altShoot2Key = keysym;
00303 break;
00304
00305 }
00306 return false;
00307 }
00308
00309
00310
00311 NewGameMenu::NewGameMenu(List * menuInfo)
00312 :Menu(menuInfo)
00313 {
00314
00315 _title = "New Game";
00316 _options.clear();
00317 _selected = 0;
00318 _totalLevels = 0;
00319 _selectedMax = 0;
00320
00321 _won = false;
00322
00323
00324 List* levelList = Parser::parse("levels/levellist.txt");
00325 while( !levelList->empty() )
00326 {
00327 _levelFile.push_back( levelList->firstList()->firstString() );
00328 bool inMenu = levelList->firstList()->rest()->firstInt();
00329 if(inMenu)
00330 _selectedMax ++;
00331
00332 _levelInMenu.push_back(inMenu);
00333 _levelUnLocked.push_back( levelList->firstList()->rest()->rest()->firstInt() );
00334 _levelName.push_back( levelList->firstList()->rest()->rest()->rest()->firstString() );
00335
00336 levelList = levelList->rest();
00337 }
00338 _selectedMax --;
00339 _totalLevels = _levelInMenu.size();
00340 }
00341
00342 void NewGameMenu::draw()
00343 {
00344 Menu::draw();
00345
00346 int offset = _textHeight*4;
00347 int select =0;
00348 for(int i=0; i <= _totalLevels; i++)
00349 {
00350 if(_levelInMenu[i]){
00351 if(_levelUnLocked[i]){
00352 if(_selected == select)
00353 glfuncs::instance()->glPrint( _leftMargin, offset, "> " + _levelName[i], false);
00354 else
00355 glfuncs::instance()->glPrint( _leftMargin, offset, " " + _levelName[i], false);
00356 }else
00357 {
00358 if(_selected == select)
00359 glfuncs::instance()->glPrint( _leftMargin, offset, "> " + (string)"[Locked]", false);
00360 else
00361 glfuncs::instance()->glPrint( _leftMargin, offset, " " + (string)"[Locked]", false);
00362 }
00363 offset += _textHeight;
00364 select ++;
00365 }
00366 }
00367
00368 }
00369
00370 bool NewGameMenu::select()
00371 {
00372
00373
00374 int i=0;
00375 int selected = _selected;
00376 for(i=0; selected > 0 ; i++)
00377 {
00378 if(_levelInMenu[i])
00379 selected --;
00380 }
00381 for(;!_levelInMenu[i];i++){}
00382
00383 if(!_levelUnLocked[i])
00384 return false;
00385
00386 Screen::drawLoading();
00387
00388 _game = new Game(i);
00389
00390 for(;;)
00391 {
00392 if( !_game->mainLoop() )
00393 break;
00394 else if( _game->wonLevel())
00395 {
00396
00397
00398
00399 _levelUnLocked[++i] = true;
00400
00401 if(_levelInMenu[i])
00402 _selected++;
00403
00404 Screen::drawLoading();
00405
00406 if(!_game->nextLevel())
00407 {
00408 _won = true;
00409 break;
00410 }
00411 }
00412 else
00413 _game->resetLevel();
00414 }
00415
00416
00417 ofstream file("levels/levellist.txt");
00418 file << Parser::open << endl;
00419 for(int j=0; j< _totalLevels; j++){
00420
00421 file << Parser::open;
00422 file << _levelFile[j] << " "
00423 << _levelInMenu[j] << " "
00424 << _levelUnLocked[j] << " "
00425 << "\"" <<_levelName[j] << "\"";
00426 file << Parser::close << endl;
00427 }
00428 file << Parser::close;
00429 file.close();
00430
00431
00432
00433 delete _game;
00434 _game = NULL;
00435
00436 return true;
00437 }
00438
00439 TitleScreenMenu::TitleScreenMenu(List * menuInfo)
00440 :Menu(menuInfo)
00441 {}
00442 bool TitleScreenMenu::select()
00443 {
00444 _options[0]->mainLoop();
00445 return true;
00446 }
00447 void TitleScreenMenu::draw()
00448 {
00449 if(_background)
00450 _background->draw(0,0,Sprite::SCREEN);
00451
00452 Screen::drawScramble();
00453 }