00001
00002
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
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
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
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
00063
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
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
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
00118 ostringstream outputString;
00119 outputString << (int) count;
00120 buffer = "Screenshot" + outputString.str() + ".tga";
00121
00122
00123 fileStream.open(buffer.c_str(), ios::in);
00124 if (!fileStream) {
00125
00126 done = true;
00127 } else {
00128
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
00148 SwitchFrom();
00149
00150
00151 m_next->SwitchTo(this);
00152 m_next->PrepareTopContainer();
00153
00154
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
00165 m_next = next;
00166
00167
00168
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
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
00187 EnterTextMode(width, height);
00188
00189 DisplayBackground(texture->GetTexture(), shade);
00190
00191
00192 if (needsText) {
00193 tempTop = new gcn::Container();
00194
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
00223 int width = Config::s_config->GetWinWidth();
00224 int height = Config::s_config->GetWinHeight();
00225
00226
00227 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00228
00229
00230 glColor3f(shade, shade, shade);
00231
00232 glEnable(GL_TEXTURE_2D);
00233
00234 glBindTexture(GL_TEXTURE_2D, myLoadingTexture);
00235
00236
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 }