ClientMain.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <server/ServerMain.h>
00022 #include <client/ClientMain.h>
00023 #include <client/ClientDialog.h>
00024 #include <client/ScorchedClient.h>
00025 #include <client/ClientAdmin.h>
00026 #include <client/ClientSave.h>
00027 #include <client/ClientParams.h>
00028 #include <client/ClientChannelManager.h>
00029 #include <client/ClientGameStoppedHandler.h>
00030 #include <client/ClientMessageHandler.h>
00031 #include <client/ClientConnectionRejectHandler.h>
00032 #include <client/ClientGiftMoneyHandler.h>
00033 #include <client/ClientLinesHandler.h>
00034 #include <client/ClientStartGameHandler.h>
00035 #include <client/ClientProcessingLoop.h>
00036 #include <client/ClientScoreHandler.h>
00037 #include <client/ClientAddPlayerHandler.h>
00038 #include <client/ClientNewGameHandler.h>
00039 #include <client/ClientConnectionAcceptHandler.h>
00040 #include <client/ClientConnectionAuthHandler.h>
00041 #include <client/ClientOperationHandler.h>
00042 #include <client/ClientRmPlayerHandler.h>
00043 #include <client/ClientGameStateHandler.h>
00044 #include <client/ClientInitializeHandler.h>
00045 #include <client/ClientAdminResultHandler.h>
00046 #include <client/ClientPlayerStateHandler.h>
00047 #include <client/ClientStartTimerHandler.h>
00048 #include <client/ClientSyncCheckHandler.h>
00049 #include <client/ClientFileHandler.h>
00050 #include <client/ClientDefenseHandler.h>
00051 #include <client/ClientPlayerStatusHandler.h>
00052 #include <client/ClientState.h>
00053 #include <client/ClientWindowSetup.h>
00054 #include <lang/LangResource.h>
00055 #include <graph/Mouse.h>
00056 #include <graph/Gamma.h>
00057 #include <graph/OptionsDisplay.h>
00058 #include <graph/OptionsDisplayConsole.h>
00059 #include <graph/MainCamera.h>
00060 #include <graph/Main2DCamera.h>
00061 #include <graph/Display.h>
00062 #include <dialogs/HelpButtonDialog.h>
00063 #include <dialogs/AnimatedBackdropDialog.h>
00064 #include <dialogs/BackdropDialog.h>
00065 #include <server/ScorchedServer.h>
00066 #include <console/ConsoleFileReader.h>
00067 #include <console/Console.h>
00068 #include <GLW/GLWWindowManager.h>
00069 #include <GLW/GLWWindowSkinManager.h>
00070 #include <engine/MainLoop.h>
00071 #include <engine/ActionController.h>
00072 #include <dialogs/ProgressDialog.h>
00073 #include <net/NetServerTCP.h>
00074 #include <net/NetServerTCP2.h>
00075 #include <net/NetServerTCP3.h>
00076 #include <net/NetLoopBack.h>
00077 #include <common/ARGParser.h>
00078 #include <common/Keyboard.h>
00079 #include <common/OptionsScorched.h>
00080 #include <common/Keyboard.h>
00081 #include <common/ProgressCounter.h>
00082 #include <common/Clock.h>
00083 #include <common/Defines.h>
00084 #include <sound/Sound.h>
00085 #include <SDL/SDL.h>
00086 
00087 static int mouseEventCount = 0;
00088 static bool paused = false;
00089 extern char scorched3dAppName[128];
00090 
00091 static bool initHardware(ProgressCounter *progressCounter)
00092 {
00093         progressCounter->setNewPercentage(0.0f);
00094         progressCounter->setNewOp(LANG_RESOURCE("INITIALIZING_KEYBOARD", "Initializing Keyboard"));
00095         if (!Keyboard::instance()->init())
00096         {
00097                 S3D::dialogMessage("Scorched3D Keyboard", 
00098                         "SDL failed to aquire keyboard.\n"
00099 #ifdef WIN32
00100                         "Is DirectX 5.0 installed?"
00101 #endif
00102                 );
00103                 return false;
00104         }
00105         progressCounter->setNewOp(LANG_RESOURCE("LOADING_KEYBOARD", "Loading Keyboard Bindings"));
00106         if (!Keyboard::instance()->loadKeyFile())
00107         {
00108                 S3D::dialogMessage("Scorched3D Keyboard", 
00109                         "Failed to process keyboard file keys.xml");
00110                 return false;
00111         }
00112 
00113         if (!OptionsDisplay::instance()->getNoSound())
00114         {
00115                 progressCounter->setNewOp(LANG_RESOURCE("INITIALIZING_SOUND", "Initializing Sound"));
00116                 if (!Sound::instance()->init(
00117                         OptionsDisplay::instance()->getSoundChannels()))
00118                 {
00119                         S3D::dialogMessage("Scorched3D Sound", 
00120                                 "Failed to aquire sound.\n"
00121                                 "Is anything else currently using the sound card?");
00122                 }
00123                 Sound::instance()->getDefaultListener()->setGain(
00124                         float(OptionsDisplay::instance()->getSoundVolume()) / 128.0f);
00125         }
00126         return true;
00127 }
00128 
00129 static bool initComs(ProgressCounter *progressCounter)
00130 {
00131         progressCounter->setNewPercentage(0.0f);
00132         progressCounter->setNewOp(LANG_RESOURCE("INITIALIZING_COMS", "Initializing Coms"));
00133         ScorchedClient::instance();
00134 
00135         // Tidy up any existing net handlers
00136         if (ScorchedClient::instance()->getContext().getNetInterfaceValid())
00137         {
00138                 ScorchedClient::instance()->getContext().getNetInterface().stop();
00139                 delete &ScorchedClient::instance()->getContext().getNetInterface();
00140                 ScorchedClient::instance()->getContext().setNetInterface(0);
00141         }
00142         if (ScorchedServer::instance()->getContext().getNetInterfaceValid())
00143         {
00144                 ScorchedServer::instance()->getContext().getNetInterface().stop();
00145                 delete &ScorchedServer::instance()->getContext().getNetInterface();
00146                 ScorchedServer::instance()->getContext().setNetInterface(0);
00147         }
00148 
00149         // Create the new net handlers
00150         if (ClientParams::instance()->getConnectedToServer())
00151         {
00152                 ScorchedClient::instance()->getContext().setNetInterface(
00153                         //new NetServerTCP(new NetServerTCPScorchedProtocol());
00154                         //new NetServerUDP();
00155                         //new NetServerTCP2();
00156                         new NetServerTCP3());
00157         }
00158         else
00159         {
00160                 NetLoopBack *serverLoopBack = new NetLoopBack(true);
00161                 ScorchedServer::instance()->getContext().setNetInterface(serverLoopBack);
00162                 NetLoopBack *clientLoopBack = new NetLoopBack(false);
00163                 ScorchedClient::instance()->getContext().setNetInterface(clientLoopBack);
00164                 serverLoopBack->setLoopBack(clientLoopBack);
00165                 clientLoopBack->setLoopBack(serverLoopBack);
00166         }
00167         ScorchedClient::instance()->getNetInterface().setMessageHandler(
00168                 &ScorchedClient::instance()->getComsMessageHandler());
00169         ClientAdmin::instance();
00170 
00171         return true;
00172 }
00173 
00174 static bool initComsHandlers()
00175 {
00176         // Setup the coms handlers
00177         ScorchedClient::instance()->getComsMessageHandler().setConnectionHandler(
00178                 ClientMessageHandler::instance());
00179         ClientChannelManager::instance();
00180         ClientConnectionRejectHandler::instance();
00181         ClientGiftMoneyHandler::instance();
00182         ClientLinesHandler::instance();
00183         ClientConnectionAcceptHandler::instance();
00184         ClientConnectionAuthHandler::instance();
00185         ClientAddPlayerHandler::instance();
00186         ClientNewGameHandler::instance();
00187         ClientInitializeHandler::instance();
00188         ClientRmPlayerHandler::instance();
00189         ClientStartTimerHandler::instance();
00190         ClientSyncCheckHandler::instance();
00191         ClientFileHandler::instance();
00192         ClientOperationHandler::instance();
00193         ClientGameStoppedHandler::instance();
00194         ClientStartGameHandler::instance();
00195         ClientGameStateHandler::instance();
00196         ClientPlayerStateHandler::instance();
00197         ClientDefenseHandler::instance();
00198         ClientPlayerStatusHandler::instance();
00199         ClientScoreHandler::instance();
00200         ClientAdminResultHandler::instance();
00201 
00202         return true;
00203 }
00204 
00205 static bool initWindows(ProgressCounter *progressCounter)
00206 {
00207         progressCounter->setNewPercentage(0.0f);
00208         progressCounter->setNewOp(LANG_RESOURCE("INITIALIZING_WINDOWS", "Initializing Windows"));
00209         if (!GLWWindowSkinManager::defaultinstance()->loadWindows())
00210         {
00211                 S3D::dialogMessage("Scorched3D", "Failed to load default windows skins");
00212                 return false;
00213         }
00214         ClientWindowSetup::setupStartWindows(GLWWindowSkinManager::defaultinstance());
00215         HelpButtonDialog::instance();
00216 
00217         Console::instance()->init();
00218         std::string errorString;
00219         if (!ConsoleFileReader::loadFileIntoConsole(S3D::getDataFile("data/autoexec.xml"), errorString))
00220         {
00221                 S3D::dialogMessage("Failed to parse data/autoexec.xml", errorString);
00222                 return false;
00223         }
00224 
00225         return true;
00226 }
00227 
00228 static bool initClient()
00229 {
00230         ProgressCounter progressCounter;
00231         progressCounter.setUser(ProgressDialogSync::instance());
00232         progressCounter.setNewPercentage(0.0f);
00233 
00234         // Load in all the coms
00235         if (!initComs(&progressCounter)) return false;
00236         
00237         // Start the server (if required)
00238         if (!ClientParams::instance()->getConnectedToServer())
00239         {
00240                 if (!startServer(true, &progressCounter)) return false;
00241         }
00242 
00243         ScorchedClient::instance()->getGameState().stimulate(ClientState::StimConnect);
00244 
00245         return true;
00246 }
00247 
00248 static bool startClientInternal()
00249 {
00250         // Check if we are connecting to a server
00251         if (ClientParams::instance()->getConnect()[0])
00252         {
00253                 return initClient();    
00254         }
00255         else if (ClientParams::instance()->getStartCustom() ||
00256                 ClientParams::instance()->getClientFile()[0])
00257         {
00258                 std::string clientFile = ClientParams::instance()->getClientFile();
00259                 if (ClientParams::instance()->getStartCustom())
00260                 {
00261                         clientFile = S3D::getSettingsFile("singlecustom.xml");
00262                 }
00263 
00264                 // If not load the client settings file
00265                 if (!S3D::fileExists(clientFile.c_str()))
00266                 {
00267                         S3D::dialogExit(scorched3dAppName, S3D::formatStringBuffer(
00268                                 "Client file \"%s\" does not exist.",
00269                                 clientFile.c_str()));
00270                 }
00271                 ScorchedServer::instance()->getOptionsGame().getMainOptions().readOptionsFromFile(
00272                         (char *) clientFile.c_str());
00273 
00274                 return initClient();
00275         }
00276         else if (ClientParams::instance()->getSaveFile()[0])
00277         {
00278                 // Or the client saved game
00279                 if (!S3D::fileExists(ClientParams::instance()->getSaveFile()))
00280                 {
00281                         S3D::dialogExit(scorched3dAppName, S3D::formatStringBuffer(
00282                                 "Client save file \"%s\" does not exist.",
00283                                 ClientParams::instance()->getSaveFile()));
00284                 }
00285                 if (!ClientSave::loadClient(ClientParams::instance()->getSaveFile()) ||
00286                         !ClientSave::restoreClient(true, false))
00287                 {
00288                         S3D::dialogExit(scorched3dAppName, S3D::formatStringBuffer(
00289                                 "Cannot load client save file \"%s\".",
00290                                 ClientParams::instance()->getSaveFile()));
00291                 }
00292 
00293                 return initClient();
00294         }
00295         else
00296         {
00297                 // Do nothing
00298         }
00299 
00300         return true;
00301 }
00302 
00303 bool ClientMain::startClient()
00304 {
00305         AnimatedBackdropDialog::instance()->drawBackground();
00306         BackdropDialog::instance()->capture();
00307 
00308         return startClientInternal();
00309 }
00310 
00311 bool ClientMain::clientEventLoop(float frameTime)
00312 {
00313         static SDL_Event event;
00314         bool idle = true;
00315         if (SDL_PollEvent(&event))
00316         {
00317                 idle = false;
00318                 switch (event.type)
00319                 {
00320                 /* keyboard events */
00321                 case SDL_KEYUP:
00322                         break;
00323                 case SDL_KEYDOWN:
00324                         /* keyevents are handled in mainloop */
00325                         Keyboard::instance()->processKeyboardEvent(event);
00326                         break;
00327 
00328                         /* mouse events */
00329                 case SDL_MOUSEBUTTONDOWN:
00330                 case SDL_MOUSEBUTTONUP:
00331                 case SDL_MOUSEMOTION:
00332                         Mouse::instance()->processMouseEvent(event);
00333                         break;
00334                 case SDL_ACTIVEEVENT:
00335                         if (event.active.gain == 0)
00336                         {
00337                                 Gamma::instance()->reset();
00338                         }
00339                         else
00340                         {
00341                                 Gamma::instance()->set();
00342                         }
00343 
00344                         paused = ( OptionsDisplay::instance()->getFocusPause() && (event.active.gain == 0));
00345                         break;
00346                 case SDL_VIDEORESIZE:
00347                         /*Display::instance()->changeSettings(
00348                                 event.resize.w,event.resize.h, 
00349                                 OptionsDisplay::instance()->getFullScreen());*/
00350                         MainCamera::instance()->getCamera().setWindowSize(
00351                                 event.resize.w, event.resize.h);
00352                         Main2DCamera::instance()->getViewPort().setWindowSize(
00353                                 event.resize.w, event.resize.h);
00354                                 
00355                         break;
00356                 case SDL_QUIT:
00357                         ScorchedClient::instance()->getMainLoop().exitLoop();
00358                         break;
00359                 }
00360         }
00361 
00362         return idle;
00363 }
00364 
00365 bool ClientMain::clientMain()
00366 {
00367         // Create the actual window
00368         if (!createScorchedWindow()) return false;
00369 
00370         // Start the initial windows
00371         ClientState::setupGameState();
00372         ProgressCounter progressCounter;
00373         ProgressDialog::instance()->changeTip();
00374         progressCounter.setUser(ProgressDialogSync::instance());
00375         progressCounter.setNewPercentage(0.0f);
00376         if (!initHardware(&progressCounter)) return false;
00377         if (!initWindows(&progressCounter)) return false;
00378         if (!initComsHandlers()) return false;
00379 
00380         OptionsDisplayConsole::instance()->addDisplayToConsole();
00381 
00382         // Try and start the client
00383         if (!startClientInternal()) return false;
00384 
00385         // Enter the SDL main loop to process SDL events
00386         Clock loopClock;
00387         for (;;)
00388         {
00389                 float frameTime = loopClock.getTimeDifference();
00390                 bool idle = clientEventLoop(frameTime);
00391 
00392                 if (!ScorchedClient::instance()->getMainLoop().mainLoop()) break;
00393                 if ((!paused) && (idle) )
00394                 {
00395                         ScorchedClient::instance()->getMainLoop().draw();
00396                 }
00397                 else
00398                 {
00399                         ClientProcessingLoop::instance()->dontLimitFrameTime();
00400                 }
00401                 if (paused) SDL_Delay(100);  // Otherwise when not drawing graphics its an infinite loop        
00402         }
00403 
00404         if (ScorchedClient::instance()->getContext().getNetInterfaceValid())
00405         {
00406                 ScorchedClient::instance()->getNetInterface().disconnectAllClients();
00407         }
00408         GLWWindowManager::instance()->savePositions();
00409     SDL_Delay(1000);
00410         Gamma::instance()->reset();
00411         Sound::instance()->destroy();
00412         Lang::instance()->saveUndefined();
00413 
00414         return true;
00415 }
00416 

Generated on Mon Feb 16 15:14:36 2009 for Scorched3D by  doxygen 1.5.3