app/aesop-client/main.cpp

Go to the documentation of this file.
00001 /*
00002  * main.cpp
00003  *
00004  * Copyright (C) 2008,2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  */
00031 
00032 // includes --------------------------------------------------------------------
00033 #include "aesop-map/map.h"
00034 #include "cmdline/cmdline.h"
00035 #include "client-game-logic/client-game-logic.h"
00036 #include "datahash/datahash_text.h"
00037 #include "datahash/datahash_util.h"
00038 #include "glut/glut.h"
00039 #include "glut-app/application.h"
00040 #include "mapzone/mapzone.h"
00041 #include "model-loader/model-loader.h"
00042 #include "netlib/netlib.h"
00043 #include "perf/perf.h"
00044 #include "physics-loader/physics-loader.h"
00045 #include "util/file.h"
00046 
00047 
00048 // statics and typedefs --------------------------------------------------------
00049 static const int s_defaultWidth                 = 800;
00050 static const int s_defaultHeight                = 600;
00051 
00052 
00053 
00074 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 static void
00093 initClient
00094 (
00095 IN int argc,
00096 IN const char * argv[],
00097 OUT std::string& title,
00098 OUT std::string& gameModeString,
00099 OUT smart_ptr<glut::Host>& host
00100 )
00101 {
00102         perf::Timer timer("initClient");
00103 
00104         // reset output
00105         title.clear();
00106         gameModeString.clear();
00107         host = NULL;
00108 
00109         smart_ptr<CommandLine> cmd = CommandLine::create(argc, argv);
00110         ASSERT(cmd, "failed to create new command line object");
00111 
00112         // look up config
00113         const char * pfile = getSingleKeyValue(cmd, "client-config", true,
00114             "local client configuration file");
00115 
00116         // determine config parent directory
00117         std::string config_root;
00118         GetParentDirectory(pfile, config_root);
00119         DPRINTF("Using configuration root path: %s", config_root.c_str());
00120 
00121         // game mode string (optional) -- used to drive fullscreen mode
00122         // TODO: better to put this in config?  Fullscreen is a bit hacky
00123         const char * gms = getSingleKeyValue(cmd, "game-mode-string", false,
00124             "parameters for glutEnterGameMode");
00125         if (gms) {
00126                 DPRINTF("using game-mode-string = '%s'", gms);
00127                 gameModeString = gms;
00128         }
00129 
00130         // load parameters
00131         smart_ptr<Datahash> params = readHashFromTextFile(pfile);
00132         ASSERT(params, "failed to construct datahash from config file");
00133 
00134         // get locale
00135         const char * locale = i18n::getHostLocale();
00136         ASSERT_THROW(locale, "failed to determine host locale?");
00137         DPRINTF("Using locale = '%s'", locale);
00138 
00139         // create story object
00140         const char * storyDir = getString(params, "storyDir");
00141         smart_ptr<story::Story> story =
00142             story::Story::create(locale, storyDir);
00143         ASSERT(story, "null");
00144 
00145         // remember title
00146         title = story->getTitle();
00147 
00148         // register map loaders
00149         smart_ptr<aesop::MapFormatReader> reader =
00150             mapzone::getMapFormatReader();
00151         ASSERT(reader, "null");
00152         aesop::registerMapFormatReader(reader);
00153 
00154         // register 3D model loaders
00155         smart_ptr<aesop::TypeComponentLoader> model_loader =
00156             aesop::createModelLoader(story);
00157         ASSERT(model_loader, "null");
00158         aesop::registerTypeComponentLoader(model_loader);
00159 
00160         // register physics object loaders
00161         smart_ptr<aesop::TypeComponentLoader> physics_loader =
00162             aesop::getPhysicsLoader();
00163         ASSERT(physics_loader, "null");
00164         aesop::registerTypeComponentLoader(physics_loader);
00165 
00166         // create game logic object
00167         smart_ptr<aesop::ClientGameLogic> gameLogic =
00168             aesop::createClientGameLogic();
00169         ASSERT(gameLogic, "failed to create game logic object");
00170 
00171         // start up application after all other base initialization
00172         host = aesop::Application::create(config_root.c_str(), params,
00173             gameLogic, story);
00174         ASSERT(host, "failed to create application object");
00175 }
00176 
00177 
00178 
00179 static void
00180 execClient
00181 (
00182 IN int argc,
00183 IN const char * argv[]
00184 )
00185 {
00186         std::string title, gameModeString;
00187         smart_ptr<glut::Host> host;
00188         initClient(argc, argv, title, gameModeString, host);
00189         ASSERT(host, "null");
00190 
00191         // all done with initialization!
00192         glut::start(argc, argv,
00193                 s_defaultWidth, s_defaultHeight,
00194                 title.c_str(),
00195                 gameModeString.c_str(),
00196                 host);
00197 }
00198 
00199 
00200 
00201 
00202 
00203 
00205 //
00206 //      entry point
00207 //
00209 
00210 int
00211 main
00212 (
00213 IN int argc,
00214 IN const char * argv[]
00215 )
00216 {
00217         // start everything up
00218         int retval = 1;
00219         try {
00220                 execClient(argc, argv);
00221         } catch (std::exception& e) {
00222                 DPRINTF("Exception during startup!");
00223                 DPRINTF("%s", e.what());
00224         } catch (...) {
00225                 DPRINTF("Unknown exception during startup!");
00226                 retval = 2;
00227         }
00228 
00229         // only get here on error
00230         return retval;
00231 }
00232