src/IGameState.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * IGameState Code
00003  */
00004 
00005 #include <iostream>
00006 #include <fstream>
00007 #include <string>
00008 #include <sstream>
00009 #include "SDL.h"
00010 #include "Log.h"
00011 #include "Config.h"
00012 #include "image.h"
00013 #include "Texture.h"
00014 #undef DELETE
00015 #include "MainMenu.h"
00016 #include "Menu/CCGui.h"
00017 #include "Menu/CCLabel.h"
00018 #include "font.h"
00019 #include "IGameState.h"
00020 
00021 using namespace std;
00022 
00023 IGameState *IGameState::s_mainMenu = NULL;
00024 IGameState **IGameState::s_currentPtr = NULL;
00025 
00026 unsigned char IGameState::s_nextScreen = 0;
00027 
00028 IGameState::IGameState(IGameState *prev) {
00029   m_previous = prev;
00030   m_next = NULL;
00031 
00032   m_top.reset(new gcn::Container());
00033   // Set the dimension of the top container to match the screen.
00034   m_top->setDimension(gcn::Rectangle(0, 0,
00035                       Config::s_config->GetWinWidth(),
00036                       Config::s_config->GetWinHeight()));
00037 }
00038 
00039 IGameState::~IGameState() {
00040   CCGui::s_CCGui->SetTopContainer(NULL);
00041 }
00042 
00043 // Static function to set mainMenu pointer
00044 void IGameState::SetMainMenu(IGameState *menu) {
00045   if ((menu != NULL) && (s_mainMenu != NULL)) {
00046     Log::s_log->Message("Warning: setMainMenu called with non-null mainMenu pointer");
00047   }
00048   s_mainMenu = menu;
00049 }
00050 
00051 // Static function to set currentPtr pointer
00052 void IGameState::SetCurrentPtr(IGameState **current) {
00053   if (s_currentPtr != NULL) {
00054     Log::s_log->Message("Warning: setCurrentPtr called with non-null currentPtr pointer");
00055   }
00056   s_currentPtr = current;
00057 }
00058 
00059 void IGameState::Loop(const unsigned int ticks) {
00060   Update(ticks);
00061 
00062   // Don't need to clear color buffer, since every pixel is redrawn
00063   // Just do it anyway, while it's in development
00064   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00065 
00066   Display();
00067 
00068   try {
00069     glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);
00070     glPushMatrix();
00071     glLoadIdentity();
00072     EnterTextMode(Config::s_config->GetWinWidth(), Config::s_config->GetWinHeight());
00073     CCGui::s_CCGui->UpdateGui();
00074     //ExitTextMode();
00075     glPopMatrix();
00076     glPopAttrib();
00077   } catch (gcn::Exception e) {
00078     Log::s_log->Message("Guichan exception: %s\n\t%s: line %i", e.getMessage().c_str(), e.getFilename().c_str(), e.getLine());
00079   }
00080 
00081   SDL_GL_SwapBuffers();
00082 
00083   if (m_next != NULL) {
00084     SwitchStates();
00085   }
00086 }
00087 
00088 void IGameState::DoExit() {
00089   // The MainMenu object needs to overload this
00090   if (s_mainMenu != NULL) {
00091     s_mainMenu->DoExit();
00092   }
00093 }
00094 
00095 void IGameState::TakeScreenshot() {
00096   string buffer;
00097   ifstream fileStream;
00098 
00099   bool loop = false;
00100   bool done = false;
00101   unsigned char count = s_nextScreen;
00102 
00103   int width = Config::s_config->GetWinWidth();
00104   int height = Config::s_config->GetWinHeight();
00105 
00106   while (!done) {
00107     if (count == 0) {
00108       if (loop == true) {
00109         Log::s_log->Message("Error: All 256 screenshot names are taken, could not take screenshot");
00110         return;
00111       }
00112       else {
00113         loop = true;
00114       }
00115     }
00116 
00117     // Create the file name
00118     ostringstream outputString;
00119     outputString << (int) count;
00120     buffer = "Screenshot" + outputString.str() + ".tga";
00121 
00122     // Check to see if the file already exists
00123     fileStream.open(buffer.c_str(), ios::in);
00124     if (!fileStream) {
00125       // The file doesn't exist, so this is the name to use
00126       done = true;
00127     } else {
00128       // A file by that name already exists, close the file & look for new name
00129       fileStream.close();
00130     }
00131 
00132     count++;
00133   }
00134 
00135   s_nextScreen = count;
00136 
00137   SaveScreenshot(buffer.c_str(), width, height);
00138   Log::s_log->Message((string) "Screenshot saved as " + buffer);
00139 }
00140 
00141 void IGameState::SwitchStates() {
00142   if (m_next == NULL) {
00143     Log::s_log->Message("Warning: SwitchState called with null m_next");
00144     return;
00145   }
00146 
00147   // Prepare to leave this state
00148   SwitchFrom();
00149 
00150   // Prepare to enter the next state
00151   m_next->SwitchTo(this);
00152   m_next->PrepareTopContainer();
00153 
00154   // Hand control over to the next state
00155   *s_currentPtr = m_next;
00156   m_next = NULL;
00157 }
00158 
00159 void IGameState::PrepareStateSwitch(IGameState *next, IGameState *prev) {
00160   if (m_next != NULL){
00161     Log::s_log->Message("Warning: SetNextState called on a non-null m_next");
00162   }
00163 
00164   // Set the next pointer, so at the end of the game loop, the state is changed
00165   m_next = next;
00166 
00167   // Set the next state's previous pointer, if it's not NULL
00168   // If it is null, just leave the previous pointer alone
00169   if (prev != NULL) {
00170     m_next->m_previous = prev;
00171   }
00172 }
00173 
00174 void IGameState::DisplaySplashScreen(const string imageName, const string text, const string fontName, float shade) {
00175   bool needsText = text.length() > 0;
00176   gcn::Widget* oldTop;
00177   gcn::Container* tempTop;
00178   auto_ptr<CCLabel> myLabel;
00179 
00180   // Temp storage for window width & height
00181   int width = Config::s_config->GetWinWidth();
00182   int height = Config::s_config->GetWinHeight();
00183 
00184   auto_ptr<Texture> texture(new Texture(imageName));
00185 
00186   // Get ready for text mode
00187   EnterTextMode(width, height);
00188 
00189   DisplayBackground(texture->GetTexture(), shade);
00190 
00191   // Only do all of the guichan work if there is text to display
00192   if (needsText) {
00193     tempTop = new gcn::Container();
00194     // Set the dimension of the top container to match the screen.
00195     tempTop->setDimension(gcn::Rectangle(0, 0,
00196                           Config::s_config->GetWinWidth(),
00197                           Config::s_config->GetWinHeight()));
00198 
00199     tempTop->setOpaque(false);
00200     tempTop->setVisible(true);
00201 
00202     myLabel.reset(new CCLabel(text, fontName));
00203     tempTop->add(myLabel.get(), (Config::s_config->GetWinWidth() / 2) - (myLabel->getWidth() / 2),
00204                  (Config::s_config->GetWinHeight() / 2) - (myLabel->getHeight() / 2));
00205 
00206     oldTop = CCGui::s_CCGui->GetTopContainer();
00207     CCGui::s_CCGui->SetTopContainer(tempTop);
00208     CCGui::s_CCGui->UpdateGui();
00209   }
00210 
00211   SDL_GL_SwapBuffers();
00212 
00213   if (needsText) {
00214     CCGui::s_CCGui->SetTopContainer(oldTop);
00215     delete tempTop;
00216   }
00217 }
00218 
00219 
00220 
00221 void IGameState::DisplayBackground(GLuint myLoadingTexture, float shade) {
00222   // Temp storage for window width & height
00223   int width = Config::s_config->GetWinWidth();
00224   int height = Config::s_config->GetWinHeight();
00225 
00226   // Clear the depth buffer
00227   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00228 
00229   // Set the color
00230   glColor3f(shade, shade, shade);
00231 
00232   glEnable(GL_TEXTURE_2D);
00233 
00234   glBindTexture(GL_TEXTURE_2D, myLoadingTexture);
00235 
00236   // Draw the actual background quad
00237   glBegin(GL_QUADS);
00238   glTexCoord2f(0, 0);
00239   glVertex3f(0, 0, 0);
00240   glTexCoord2f(0, 1);
00241   glVertex3f(0, height, 0);
00242   glTexCoord2f(1, 1);
00243   glVertex3f(width, height, 0);
00244   glTexCoord2f(1, 0);
00245   glVertex3f(width, 0, 0);
00246   glEnd();
00247 }
00248 
00249 void IGameState::PrepareTopContainer() {
00250   if (m_top.get() != NULL) {
00251     m_top->setOpaque(false);
00252     m_top->setVisible(true);
00253   }
00254   CCGui::s_CCGui->SetTopContainer(m_top.get());
00255 }

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