demoConfig/main.cpp

Go to the documentation of this file.
00001 /*
00002  * main.cpp
00003  *
00004  * Copyright (C) 2010,2011  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Simple program to demonstrate the gamepad configuration conversations.
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include <iostream>
00012 
00013 #include "conversation/conversation.h"
00014 #include "datahash/datahash_text.h"
00015 #include "dialog/dialog.h"
00016 #include "dialog-draw/dialog-draw.h"
00017 #include "gamepad-config-dialog/gamepad-config-dialog.h"
00018 #include "gamepad-vgfx-element/gamepad-vgfx-element.h"
00019 #include "glut-demo/glut-demo.h"
00020 #include "glut-font/glut-font.h"
00021 #include "opengl-effects/opengl-effects.h"
00022 #include "perf/perf.h"
00023 #include "restream/restream.h"
00024 #include "util/file.h"
00025 #include "vgfx-opengl-draw/vgfx-opengl-draw.h"
00026 #include "wave-glut/texture.h"
00027 
00028 
00029 // resources (namespace / name)
00030 static const char * s_resourceFont      = "demoConfig/gravitat.ttf";
00031 static const char * s_resourceMap       = "demoConfig/nasa-mars-map.png";
00032 
00033 static const float s_fontPointSize      = 24.0;
00034 
00035 static const char * s_dialogId          = "gamepadConfig";
00036 
00037 static const float s_degreesPerSecond   = 30.0;
00038 
00039 
00040 ////////////////////////////////////////////////////////////////////////////////
00041 //
00042 //      static helper methods
00043 //
00044 ////////////////////////////////////////////////////////////////////////////////
00045 
00046 class Host : public glut::DemoHost, public converse::ConversationRouter,
00047                 public dialog::Host {
00048 public:
00049         // constructor, destructor ---------------------------------------------
00050         ~Host(void) throw() { }
00051 
00052         // public class methods ------------------------------------------------
00053 
00054         // glut::DemoHost class interface methods ------------------------------
00055 
00056         bool displayAxes(void) { return false; }
00057         bool displayQueuedPolys(void) { return false; }
00058 
00059         void onInit(void) {
00060                         ASSERT(m_dataDir, "null");
00061                         m_counter = 0;
00062 
00063                         // get access to our built-in resources
00064                         smart_ptr<nstream::Manager> mgr =
00065                             nstream::getResourceStreamManager();
00066                         ASSERT_THROW(mgr, "failed to create resource stream");
00067 
00068                         // load the font
00069                         m_fontMgr = glut::FontManager::create();
00070                         ASSERT_THROW(m_fontMgr, "null");
00071 
00072                         smart_ptr<nstream::Stream> stream =
00073                             nstream::openNamedStream(mgr, s_resourceFont);
00074 
00075                         // create OpenGL dialog drawer
00076                         dialog::ogl_dialog_draw_t odd;
00077                         odd.font = m_fontMgr->getFont(stream);
00078                         ASSERT_THROW(odd.font,
00079                             "Failed to load font from resources");
00080                         odd.font->setFaceSize(s_fontPointSize);
00081                         smart_ptr<dialog::Drawer> drawer =
00082                             dialog::createOpenGLDrawer(odd);
00083                         ASSERT_THROW(drawer, "failed to create OpenGL drawer");
00084 
00085                         // create OpenGL vgfx drawer
00086                         smart_ptr<vgfx::Drawer> vgfxDrawer =
00087                             vgfx::createOpenGLDrawer();
00088                         ASSERT_THROW(vgfxDrawer,
00089                             "failed to create OpenGL vgfx drawer");
00090 
00091                         // create the gamepad manager
00092                         m_gamepadMgr = gamepad::Manager::create(m_dataDir);
00093                         ASSERT_THROW(m_gamepadMgr, "failed to create");
00094 
00095                         // create our local dialog manager
00096                         smart_ptr<crypto::DESKey> nullKey;
00097                         m_dialogMgr = dialog::Manager::create(nullKey, drawer);
00098                         ASSERT_THROW(m_dialogMgr, "failed to create");
00099 
00100                         // register the TestElement factory
00101                         gamepad::registerVgfxTestFactory(m_gamepadMgr,
00102                             m_dialogMgr, vgfxDrawer);
00103 
00104                         // register the SimpleElement factory
00105                         gamepad::registerVgfxSimpleFactory(m_gamepadMgr,
00106                             m_dialogMgr, vgfxDrawer);
00107 
00108                         // create the conversation manager
00109                         m_converseMgr =
00110                             converse::ConversationManager::create(this);
00111                         ASSERT_THROW(m_converseMgr, "failed to create");
00112 
00113                         // kick off the dialog
00114                         m_x = 100;
00115                         m_y = 100;
00116                         this->startDialog();
00117 
00118                         // load the map
00119                         media::image_t img;
00120                         ASSERT_THROW(media::loadImage(mgr, s_resourceMap, img),
00121                             "Failed to load file: " << s_resourceMap);
00122 
00123                         // create texture-mapped sphere
00124                         glut::tex_sphere_t ts;
00125                         ts.radius = 3.0;
00126                         ts.textureId = glut::createTextureFromImage(img);
00127 
00128                         m_sphere = glut::createMappedSphere(ts);
00129                         ASSERT(m_sphere, "null");
00130 
00131                         m_angle = 0.0;
00132                 }
00133 
00134         void onIdle(IN float dt) {
00135                         m_angle += s_degreesPerSecond * dt;
00136                 }
00137 
00138         void display3D(IN const glut::render_context_t& rc,
00139                                 IN glut::RenderQueue * rq) {
00140                         ASSERT(rq, "null");
00141 
00142                         glTranslatef(0, 0, 5);
00143                         glRotatef(-33, 1, 0, 0);
00144 
00145                         // draw planet...
00146                         glMatrixMode(GL_MODELVIEW);
00147                         glPushMatrix();
00148 
00149                         glRotatef(m_angle, 0, 1, 0);
00150 
00151                         m_sphere->render(rc, rq);
00152 
00153                         glPopMatrix();
00154 
00155                         // draw spheres
00156                         glColor3f(0.5, 0.5, 0.5);
00157                         for (int i = 0; i < 3; ++i) {
00158                                 glPushMatrix();
00159 
00160                                 float sign = pow(-1.0f, i);
00161                                 glRotatef(m_angle * (3 - i) * sign, 0, 1, 0);
00162                                 glTranslatef(0, 0, (i * 1.5) + 4.5);
00163                                 glRotatef(m_angle * 2.5 * sign, 0, 1, 0);
00164                                 glutSolidSphere(0.25, 6, 6);
00165 
00166                                 glPopMatrix();
00167                         }
00168                 }
00169 
00170         void display2D(int width, int height) {
00171                         ++m_counter;
00172                         if (0 == (m_counter % 128)) {
00173                                 if (m_gamepadMgr->rediscover()) {
00174                                         gamepad::autoconfigureGamepads(m_gamepadMgr);
00175                                 }
00176                         }
00177                         m_gamepadMgr->update(); // re-poll all button state
00178                         m_converseMgr->updateAll();
00179                         m_dialogMgr->display(width, height);
00180                 }
00181 
00182         void onButton(IN int button, IN int state, IN int x, IN int y) {
00183                         // intercept all mouse clicks
00184                         if (!m_dialogMgr->doesDialogExist(s_dialogId)) {
00185                                 // no dialog?  if this is a click down, start
00186                                 if (state) {
00187                                         m_x = x;
00188                                         m_y = y;
00189                                         this->startDialog();
00190                                 }
00191                                 return;
00192                         }
00193                         m_dialogMgr->button(button, state, x, y);
00194                 }
00195 
00196         void onCursor(IN int x, IN int y) {
00197                         m_dialogMgr->cursor(x, y);
00198                 }
00199 
00200         // converse::ConversationRouter class interface methods ----------------
00201         void routeConversationTS(IN const char * guid,
00202                                 IN int dialogId,
00203                                 IN int playerId,
00204                                 IN converse::conn_id_t connId,
00205                                 IN const char * dialogData) {
00206                         //DPRINTF("Asked to render dialog '%s'", guid);
00207 
00208                         // convert dialog text to hash
00209                         smart_ptr<Datahash> hash =
00210                             readHashFromString(dialogData);
00211                         ASSERT_THROW(hash, "failed to read hash from string");
00212 
00213                         // remember dialog ID etc
00214                         m_guid = guid;
00215                         m_dialogId = dialogId;
00216                         m_connId = connId;
00217                         m_playerId = playerId;
00218 
00219                         // for now, dumb routing: display everything here!
00220                         ASSERT(m_dialogMgr, "null");
00221                         if (dialogId) {
00222                                 m_dialogMgr->createDialog(guid, m_x, m_y, hash, this);
00223                         } else {
00224                                 m_dialogMgr->destroyDialog(guid);
00225                         }
00226                 }
00227 
00228         // dialog::Host class interface methods --------------------------------
00229         void notifySubmit(IN const char * guid, IN const Datahash * reply) {
00230                         DPRINTF("Received submit for dialog: %s", guid);
00231                         ASSERT(reply, "null");
00232 
00233                         // forward to conversation host
00234                         m_converseMgr->handleDialogReplyTS(guid, m_dialogId,
00235                             m_connId, m_playerId, reply);
00236                 }
00237 
00238         // static factory method -----------------------------------------------
00239         static smart_ptr<Host> create(IN const char * dataDir,
00240                                         IN const char * imageDir) {
00241                         ASSERT(dataDir, "null");
00242                         ASSERT(imageDir, "null");
00243 
00244                         smart_ptr<nstream::Manager> fsMgr =
00245                             nstream::getFilesystemManager(dataDir);
00246                         ASSERT_THROW(fsMgr,
00247                             "Failed to create filesystem manager for data dir: "
00248                             << dataDir);
00249 
00250                         smart_ptr<Host> local = new Host;
00251                         ASSERT(local, "out of memory");
00252                         local->m_dataDir = fsMgr->getRoot();
00253                         local->m_imageDir = imageDir;
00254 
00255                         return local;
00256                 }
00257 
00258 private:
00259         // private methods -----------------------------------------------------
00260         Host(void) throw() { }
00261 
00262         void startDialog(void) {
00263                         ASSERT(m_gamepadMgr, "null");
00264                         ASSERT(m_converseMgr, "null");
00265 
00266                         // create the gamepad config conversation host
00267                         smart_ptr<converse::ConversationHost> host =
00268                             gamepad::createConfigurationHost(m_gamepadMgr);
00269                         ASSERT(host, "failed to create");
00270 
00271                         // request conversation
00272                         m_converseMgr->updateConversationTS(s_dialogId,
00273                             1, 1, host);
00274                 }
00275 
00276         // private member data -------------------------------------------------
00277         smart_ptr<converse::ConversationManager>        m_converseMgr;
00278         smart_ptr<gamepad::Manager>                     m_gamepadMgr;
00279         smart_ptr<dialog::Manager>                      m_dialogMgr;
00280         smart_ptr<nstream::Folder>                      m_dataDir;
00281         smart_ptr<glut::Renderable>                     m_sphere;
00282         smart_ptr<glut::FontManager>                    m_fontMgr;
00283         const char *                                    m_guid;
00284         std::string                                     m_imageDir;
00285         int                                             m_dialogId;
00286         converse::conn_id_t                             m_connId;
00287         int                                             m_playerId;
00288         int                                             m_counter;
00289         int                                             m_x;
00290         int                                             m_y;
00291         float                                           m_angle;
00292 };
00293 
00294 
00295 ////////////////////////////////////////////////////////////////////////////////
00296 //
00297 //      entry point
00298 //
00299 ////////////////////////////////////////////////////////////////////////////////
00300 
00301 int
00302 main
00303 (
00304 IN int argc,
00305 IN const char * argv[]
00306 )
00307 {
00308         int retval = 0;
00309         ASSERT(2 == argc, "Usage: demoConfig <data-directory>");
00310         const char * dataDir = argv[1];
00311         DPRINTF("Using data directory: '%s'", dataDir);
00312 
00313         try {
00314 
00315                 // get this directory
00316                 const char * exePath = argv[0];
00317                 DPRINTF("Executable: %s", exePath);
00318                 std::string parentDir;
00319                 GetParentDirectory(exePath, parentDir);
00320 
00321                 const char * title = "Gamepad Configuration Demo";
00322 
00323                 smart_ptr<glut::DemoHost> host =
00324                     Host::create(dataDir, parentDir.c_str());
00325                 ASSERT(host, "failed to create demo host");
00326 
00327                 glut::startDemo(argc, argv, title, host);
00328 
00329         } catch (std::exception& e) {
00330                 DPRINTF("Exception!  %s", e.what());
00331                 retval = 1;
00332         }
00333 
00334         perf::dumpTimingSummary(std::cerr);
00335 
00336         return retval;
00337 }
00338