src/MainMenu.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * Menu Class Code
00003  */
00004 
00005 #include <cstdlib>
00006 #include <guichan.hpp>
00007 #include <guichan/sdl.hpp>
00008 #include <guichan/opengl.hpp>
00009 #include "SDL.h"
00010 #include "GLee.h"
00011 #include "Menu/CCGui.h"
00012 #include "Menu/CCButton.h"
00013 #include "Menu/CCTable.h"
00014 #include "Menu/CCTextField.h"
00015 #include "Menu/CCLabel.h"
00016 #include "Config.h"
00017 #include "Texture.h"
00018 #include "Log.h"
00019 #include "font.h"
00020 #include "IGameState.h"
00021 #include "StateSailing.h"
00022 #include "StateNewGame.h"
00023 #include "Callback.h"
00024 #include "SoundStream.h"
00025 #include "tinyxml.h"
00026 #include "MainMenu.h"
00027 
00028 using namespace std;
00029 
00030 const string k_defaultName = "John Smith";
00031 const string k_defaultShip = "Jolly Smith";
00032 
00033 const string MainMenu::s_mainFontName = "papyrus.png";
00034 const string MainMenu::s_highlightFontName = "highlightPapyrus.png";
00035 const string MainMenu::s_disabledFontName = "disabledPapyrus.png";
00036 const string MainMenu::s_smallFontName = "smallFont.png";
00037 
00038 MainMenu::MainMenu(bool *done): IGameState(NULL) {
00039   CCLabel *tempLabel;
00040 
00041   Log::s_log->Message("MainMenu");
00042   DisplaySplashScreen("title.png", "", s_mainFontName, 1);
00043 
00044   // Set the static GameState mainMenu pointer to this
00045   IGameState::SetMainMenu(this);
00046 
00047   // Bool value to set to quit
00048   m_done = done;
00049 
00050   // Set the pointer to the main sailing state to null
00051   m_mainGame = NULL;
00052 
00053   m_background = new Texture("background.png");
00054 
00055   m_contCallback.SetCallback(this, &MainMenu::ContinueGame);
00056   m_newCallback.SetCallback(this, &MainMenu::NewGame);
00057   m_saveCallback.SetCallback(this, &MainMenu::SaveGame);
00058   m_loadCallback.SetCallback(this, &MainMenu::LoadGame);
00059   m_exitCallback.SetCallback(this, &MainMenu::Exit);
00060   m_acceptCallback.SetCallback(this, &MainMenu::Accept);
00061   m_cancelCallback.SetCallback(this, &MainMenu::Cancel);
00062 
00063   Log::s_log->Message("\tMenu: Callbacks Set.");
00064 
00065   // Set up the main menu
00066   m_mainMenu = new gcn::Container();
00067   m_mainMenu->setDimension(gcn::Rectangle(0, 0,
00068                       Config::s_config->GetWinWidth(),
00069                       Config::s_config->GetWinHeight()));
00070   m_mainMenu->setOpaque(false);
00071 
00072   m_mainMenuTable = new CCTable(1, 5);
00073 
00074   m_contButton = new CCButton("Continue", "contButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_contCallback);
00075   m_contButton->setEnabled(false);
00076   m_contButton->setVisible(true);
00077   m_exitButton = new CCButton("Exit", "exitButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_exitCallback);
00078   m_exitButton->setVisible(true);
00079   m_newButton = new CCButton("New", "newButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_newCallback);
00080   m_newButton->setVisible(true);
00081   m_loadButton = new CCButton("Load", "loadButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_loadCallback);
00082   m_loadButton->setVisible(true);
00083   m_saveButton = new CCButton("Save", "saveButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_saveCallback);
00084   m_saveButton->setEnabled(false);
00085   m_saveButton->setVisible(true);
00086 
00087   m_mainMenuTable->add(0, 0, m_contButton);
00088   m_mainMenuTable->add(0, 1, m_newButton);
00089   m_mainMenuTable->add(0, 4, m_exitButton);
00090   m_mainMenuTable->add(0, 3, m_loadButton);
00091   m_mainMenuTable->add(0, 2, m_saveButton);
00092 
00093   m_mainMenuTable->setVisible(true);
00094   m_mainMenuTable->setOpaque(false);
00095   m_mainMenu->add(m_mainMenuTable, 10, 100);
00096 
00097   // Set up the new game menu
00098   m_newGameMenu = new gcn::Container();
00099   m_newGameMenu->setDimension(gcn::Rectangle(0, 0,
00100                            Config::s_config->GetWinWidth(),
00101                            Config::s_config->GetWinHeight()));
00102   m_newGameMenu->setOpaque(false);
00103 
00104   m_newGameTable = new CCTable(2, 3);
00105   m_newGameTable->setRowBuffer(10);
00106   m_newGameTable->setColumnBuffer(10);
00107 
00108   m_acceptButton = new CCButton("Accept", "acceptButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_acceptCallback);
00109   m_acceptButton->setVisible(true);
00110   m_cancelButton = new CCButton("Cancel", "cancelButton", s_mainFontName, s_highlightFontName, s_disabledFontName, &m_cancelCallback);
00111   m_cancelButton->setVisible(true);
00112 
00113   tempLabel = new CCLabel("Your Name:", s_smallFontName);
00114   m_newGameTable->add(0, 0, tempLabel);
00115   m_nameText = new CCTextField(k_defaultName, s_smallFontName, 150);
00116   m_newGameTable->add(1, 0, m_nameText);
00117 
00118   tempLabel = new CCLabel("Ship Name:", s_smallFontName);
00119   m_newGameTable->add(0, 1, tempLabel);
00120   m_shipText = new CCTextField(k_defaultShip, s_smallFontName, 150);
00121   m_newGameTable->add(1, 1, m_shipText);
00122   m_newGameTable->add(0, 2, m_acceptButton);
00123   m_newGameTable->add(1, 2, m_cancelButton);
00124 
00125   m_newGameTable->setVisible(true);
00126   m_newGameTable->setOpaque(false);
00127 
00128   m_newGameMenu->add(m_newGameTable, 10, 100);
00129 
00130   Log::s_log->Message("\tGraphics and font initialized.");
00131 
00132   m_top->add(m_mainMenu, 0, 0);
00133   m_top->add(m_newGameMenu, 0, 0);
00134   m_newGameMenu->setVisible(false);
00135 
00136   m_mainMenu->requestMoveToTop();
00137 
00138   Log::s_log->Message("\tGuichan finished.");
00139 
00140   // Initialize the sound buffer and source
00141   try {
00142     m_music.open("./data/Music/title.ogg");
00143     m_music.display();
00144 
00145     if (!m_music.playback()) {
00146       Log::s_log->Message("Music Playback didn't work.");
00147     }
00148   } catch (string error) {
00149     Log::s_log->Message(error.c_str());
00150   }
00151 
00152   Log::s_log->Message("\tMusic loaded");
00153 
00154   Log::s_log->Message("MainMenu initialized");
00155 }
00156 
00157 MainMenu::~MainMenu() {
00158   if (m_previous == m_mainGame) m_previous = NULL;
00159 
00160   delete m_mainGame;
00161 
00162   // Delete Guichan stuff
00163   delete m_mainMenu;
00164   delete m_mainMenuTable;
00165   delete m_newGameMenu;
00166   delete m_newGameTable;
00167 
00168   // Delete buffer and source
00169   try {
00170     m_music.release();
00171   } catch (...) {
00172     Log::s_log->Message("Error releasing MainMenu music");
00173   }
00174 
00175   delete m_background;
00176 
00177   // Set the static GameState mainMenu pointer back to NULL
00178   IGameState::SetMainMenu(NULL);
00179 
00180   Log::s_log->Message("MainMenu deleted");
00181 }
00182 
00183 void MainMenu::Update(const unsigned int ticks) {
00184   if (!m_music.update())
00185     Log::s_log->Message("Audio Playback didn't work");
00186 
00187   CheckInput();
00188 }
00189 
00190 void MainMenu::Display() {
00191   glLoadIdentity();
00192   DisplayBackground(m_background->GetTexture(), 1);
00193 }
00194 
00195 void MainMenu::CheckInput()
00196 {
00197   SDL_Event event;
00198   /*
00199    * Poll SDL events
00200    */
00201   while(SDL_PollEvent(&event))
00202   {
00203     if (event.type == SDL_KEYDOWN)
00204     {
00205       /*
00206       if (event.key.keysym.sym == SDLK_ESCAPE)
00207       {
00208         done = false;
00209       }
00210       if (event.key.keysym.sym == SDLK_f)
00211       {
00212         if (event.key.keysym.mod & KMOD_CTRL)
00213         {
00214           // Works with X11 only
00215           //SDL_WM_ToggleFullScreen(screen);
00216         }
00217       }
00218       */
00219       if (event.key.keysym.sym == SDLK_z) {
00220         TakeScreenshot();
00221       }
00222     }
00223     else if(event.type == SDL_QUIT)
00224     {
00225       *m_done = true;
00226     }
00227 
00228     /*
00229      * Now that we are done polling and using SDL events we pass
00230      * the leftovers to the SDLInput object to later be handled by
00231      * the Gui. (This example doesn't require us to do this 'cause a
00232      * label doesn't use input. But will do it anyway to show how to
00233      * set up an SDL application with Guichan.)
00234      */
00235     CCGui::s_CCGui->m_input->pushInput(event);
00236   }
00237 }
00238 
00239 void MainMenu::DoExit() {
00240   *m_done = true;
00241 }
00242 
00243 void MainMenu::SwitchTo(IGameState *oldState) {
00244   if (m_mainGame != NULL) {
00245     m_contButton->setEnabled(true);
00246     m_saveButton->setEnabled(true);
00247   } else {
00248     m_contButton->setEnabled(false);
00249     m_saveButton->setEnabled(false);
00250   }
00251   EnterTextMode(Config::s_config->GetWinWidth(), Config::s_config->GetWinHeight());
00252   m_music.reload();
00253 }
00254 
00255 void MainMenu::SwitchFrom() {
00256 }
00257 
00258 void MainMenu::ContinueGame(int i) {
00259   if (m_previous != NULL) {
00260     m_contButton->mouseOut();
00261     PrepareStateSwitch(m_previous, NULL);
00262   }
00263 }
00264 
00265 void MainMenu::NewGame(int i) {
00266   ResetNewGameMenu();
00267   m_newButton->mouseOut();
00268   m_newGameMenu->setVisible(true);
00269   m_mainMenu->setVisible(false);
00270   m_newGameMenu->requestMoveToTop();
00271 }
00272 
00273 void MainMenu::SaveGame(int i) {
00274   TiXmlDocument doc;
00275   TiXmlElement rootNode("CCSaveGame");
00276 
00277   // Shouldn't try to save if the game hasn't even started
00278   if (m_mainGame != NULL) {
00279     m_mainGame->Save(&rootNode);
00280     doc.InsertEndChild(rootNode);
00281     // This will need to change once we can do multiple save games
00282     doc.SaveFile("CCSave.xml");
00283     PrepareStateSwitch(m_mainGame, NULL);
00284   }
00285 }
00286 
00287 void MainMenu::LoadGame(int i) {
00288   // This will need to change once we allow multiple save games
00289   TiXmlDocument doc("CCSave.xml");
00290 
00291   doc.LoadFile();
00292   if (doc.Error()) {
00293     // Should throw an exception
00294     Log::s_log->Message("Warning: Could not load game, %s (line %d)", doc.ErrorDesc(), doc.ErrorRow());
00295     return;
00296   }
00297 
00298   if (m_mainGame == NULL) {
00299     // Game hasn't been started yet, need to create it
00300     // The player/ship names don't matter since we are loading those values
00301     m_mainGame = new StateSailing("Default", "Default");
00302   }
00303   // Now we can load the game
00304   m_mainGame->Load(doc.FirstChildElement("CCSaveGame"));
00305 
00306   m_mainGame->Dump();
00307 
00308   // Switch to game state
00309   PrepareStateSwitch(m_mainGame, NULL);
00310 }
00311 
00312 void MainMenu::Exit(int ID) {
00313   DoExit();
00314 }
00315 
00316 void MainMenu::Accept(int i) {
00317   if (m_mainGame == NULL) {
00318     // New game
00319     m_mainGame = new StateSailing(m_nameText->getText(), m_shipText->getText());
00320   } else {
00321     // Just reset existing game
00322     m_mainGame->NewGame(m_nameText->getText(), m_shipText->getText());
00323   }
00324 
00325   m_acceptButton->mouseOut();
00326   m_mainMenu->setVisible(true);
00327   m_newGameMenu->setVisible(false);
00328   m_mainMenu->requestMoveToTop();
00329 
00330   PrepareStateSwitch(m_mainGame, NULL);
00331 }
00332 
00333 void MainMenu::Cancel(int i) {
00334   m_cancelButton->mouseOut();
00335   m_mainMenu->setVisible(true);
00336   m_newGameMenu->setVisible(false);
00337   m_mainMenu->requestMoveToTop();
00338 }
00339 
00340 void MainMenu::SetMainGame(StateSailing *sailingState) {
00341   m_mainGame = sailingState;
00342 }
00343 
00344 void MainMenu::ResetNewGameMenu() {
00345   m_nameText->setText(k_defaultName);
00346   m_shipText->setText(k_defaultShip);
00347 }

Generated on Mon Jan 8 22:34:12 2007 for CrownandCutlass by  doxygen 1.4.7