gamepad-test-element.cpp

Go to the documentation of this file.
00001 /*
00002  * gamepad-test-element.cpp
00003  *
00004  * Copyright (C) 2010  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  * Implementation of gamepad dialog Test element
00032  */
00033 
00034 // includes --------------------------------------------------------------------
00035 #include "gamepad-vgfx-element.h"       // always include our own header first
00036 
00037 #include "datahash/datahash_util.h"
00038 #include "gamepad-vgfx/gamepad-vgfx.h"
00039 
00040 
00041 namespace gamepad {
00042 
00043 
00044 static const char * s_testElementName           = "gamepadVgfxTest";
00045 
00046 
00047 ////////////////////////////////////////////////////////////////////////////////
00048 //
00049 //      static helper methods
00050 //
00051 ////////////////////////////////////////////////////////////////////////////////
00052 
00053 static float
00054 getFloat
00055 (
00056 IN const pot_value_t& pv
00057 )
00058 throw()
00059 {
00060         float delta = pv.maxSeen - pv.minSeen;
00061         if (delta <= 0) {
00062                 return 0;
00063         }
00064 
00065         return (pv.value - pv.minSeen) / delta;
00066 }
00067 
00068 
00069 
00070 ////////////////////////////////////////////////////////////////////////////////
00071 //
00072 //      TestElement -- class that implements the dialog::Element interface
00073 //
00074 ////////////////////////////////////////////////////////////////////////////////
00075 
00076 class TestElement : public dialog::Element {
00077 public:
00078         // constructor, destructor ---------------------------------------------
00079         ~TestElement(void) throw() { }
00080 
00081         // dialog::Element class interface methods -----------------------------
00082         int getWidth(void) { return m_width; }
00083         int getHeight(void) { return m_height; }
00084         void draw(IN const dialog::point_t& offset); 
00085         void cursor(IN const dialog::point_t& pos) { }
00086         const char * button(IN int button, IN int state,
00087                                 IN const dialog::point_t& pos)
00088                                 { return NULL; }
00089         void addData(IN crypto::DESKey * key, IO Datahash * data) { }
00090 
00091         // static factory methods ----------------------------------------------
00092         static smart_ptr<dialog::Element> create(IN dialog::Manager * mgr,
00093                                 IN smart_ptr<Gamepad>& gp,
00094                                 IN smart_ptr<vgfx::Drawer>& drawer);
00095 
00096 private:
00097         // private constructors ------------------------------------------------
00098         TestElement(void) throw(); 
00099 
00100         // private typedefs ----------------------------------------------------
00101 
00102         // private helper methods ----------------------------------------------
00103         void initialize(IN dialog::Manager * mgr,
00104                                 IN smart_ptr<Gamepad>& gp,
00105                                 IN smart_ptr<vgfx::Drawer>& drawer);
00106 
00107         // private member data -------------------------------------------------
00108         int                             m_width;
00109         int                             m_height;
00110         smart_ptr<Gamepad>              m_gamepad;
00111         smart_ptr<TypeVgfxRenderer>     m_renderer;
00112         Type *                          m_type;
00113 };
00114 
00115 
00116 
00117 TestElement::TestElement
00118 (
00119 void
00120 )
00121 throw()
00122 {
00123         m_type = NULL;
00124 
00125         m_width = 400;
00126         m_height = 300;
00127 }
00128 
00129 
00130 
00131 smart_ptr<dialog::Element>
00132 TestElement::create
00133 (
00134 IN dialog::Manager * mgr,
00135 IN smart_ptr<Gamepad>& gamepad,
00136 IN smart_ptr<vgfx::Drawer>& drawer
00137 )
00138 {
00139         ASSERT(mgr, "null");
00140         ASSERT(gamepad, "null");
00141         ASSERT(drawer, "null");
00142 
00143         smart_ptr<TestElement> local = new TestElement;
00144         ASSERT(local, "out of memory");
00145 
00146         local->initialize(mgr, gamepad, drawer);
00147 
00148         return local;
00149 }
00150 
00151 
00152 
00153 ////////////////////////////////////////////////////////////////////////////////
00154 //
00155 //      TestElement -- dialog::Element class interface methods
00156 //
00157 ////////////////////////////////////////////////////////////////////////////////
00158 
00159 void
00160 TestElement::draw
00161 (
00162 IN const dialog::point_t& offset
00163 )
00164 {
00165         ASSERT(m_gamepad, "null");
00166         ASSERT(m_type, "null");
00167 
00168         // anything to tweak?
00169         int nButtons = m_type->getInputCount(eInput_Button);
00170         for (int i = 0; i < nButtons; ++i) {
00171                 float val = (eButtonDown & m_gamepad->getButton(i)) ? 1.0 : 0.5;
00172                 const char * logical =
00173                     m_type->getLogicalName(eInput_Button, i);
00174                 m_renderer->setIntensity(logical, val);
00175         }
00176 
00177         int nJoysticks = m_type->getInputCount(eInput_Joystick);
00178         for (int i = 0; i < nJoysticks; ++i) {
00179                 joystick_t joy;
00180                 m_gamepad->getJoystick(i, joy);
00181                 float x = getFloat(joy.x);
00182                 float y = getFloat(joy.y);
00183                 float intensity = 0.5;
00184                 if (x < 0.3 || x > 0.7 || y < 0.3 || y > 0.7) {
00185                         intensity = 1.0;
00186                 }
00187                 const char * logical =
00188                     m_type->getLogicalName(eInput_Joystick, i);
00189                 m_renderer->setIntensity(logical, intensity);
00190                 m_renderer->setPosition(logical, x, y);
00191         }
00192 
00193         int nPots = m_type->getInputCount(eInput_Pot);
00194         for (int i = 0; i < nPots; ++i) {
00195                 pot_value_t pv;
00196                 m_gamepad->getPot(i, pv);
00197                 const char * logical =
00198                     m_type->getLogicalName(eInput_Pot, i);
00199                 float intensity = 0.25 + 0.75 * getFloat(pv);
00200                 m_renderer->setIntensity(logical, intensity);
00201         }
00202 
00203         int nDpads = m_type->getInputCount(eInput_Dpad);
00204         for (int i = 0; i < nDpads; ++i) {
00205                 eDpad dp = m_gamepad->getDpad(i);
00206                 float x = 0.5;
00207                 float y = 0.5;
00208                 if (eDpad_Left & dp)
00209                         x = 0;
00210                 else if (eDpad_Right & dp)
00211                         x = 1;
00212                 if (eDpad_Up & dp)
00213                         y = 0;
00214                 else if (eDpad_Down & dp)
00215                         y = 1;
00216 
00217                 float intensity = 0.5;
00218                 if (x < 0.4 || x > 0.6 || y < 0.4 || y > 0.6) {
00219                         intensity = 1.0;
00220                 }
00221                 const char * logical = 
00222                     m_type->getLogicalName(eInput_Dpad, i);
00223 
00224                 m_renderer->setIntensity(logical, intensity);
00225                 m_renderer->setPosition(logical, x, y);
00226         }
00227 
00228         // now draw
00229         m_renderer->draw(offset.x, offset.y, m_width, m_height);
00230 }
00231 
00232 
00233 
00234 ////////////////////////////////////////////////////////////////////////////////
00235 //
00236 //      TestElement -- private helper methods
00237 //
00238 ////////////////////////////////////////////////////////////////////////////////
00239 
00240 void
00241 TestElement::initialize
00242 (
00243 IN dialog::Manager * mgr,
00244 IN smart_ptr<Gamepad>& gp,
00245 IN smart_ptr<vgfx::Drawer>& drawer
00246 )
00247 {
00248         ASSERT(mgr, "null");
00249         ASSERT(gp, "null");
00250         ASSERT(drawer, "null");
00251 
00252         m_gamepad = gp;
00253         ASSERT(!m_type, "already have a type?");
00254         m_type = gp->getType();
00255         ASSERT(m_type, "null type");
00256 
00257         m_renderer = TypeVgfxRenderer::create(m_type, drawer);
00258         ASSERT(m_renderer, "null");
00259 }
00260 
00261 
00262 
00263 ////////////////////////////////////////////////////////////////////////////////
00264 //
00265 //      TestFactory - class that implements the dialog::Factory interface
00266 //                      for gamepad Testing elements
00267 //
00268 ////////////////////////////////////////////////////////////////////////////////
00269 
00270 class TestFactory : public dialog::Factory {
00271 public:
00272         // constructor, destructor ---------------------------------------------
00273         ~TestFactory(void) throw() { }
00274 
00275         // dialog::Factory class interface methods -----------------------------
00276         smart_ptr<dialog::Element> createElement(IN const char * type,
00277                                 IN dialog::Manager * mgr,
00278                                 IN const Datahash * data);
00279 
00280         // static factory methods ----------------------------------------------
00281         static smart_ptr<dialog::Factory> create(IN smart_ptr<Manager>& mgr,
00282                                 IN smart_ptr<vgfx::Drawer>& drawer) {
00283                         ASSERT(mgr, "null");
00284                         ASSERT(drawer, "null");
00285                         smart_ptr<TestFactory> local = new TestFactory;
00286                         ASSERT(local, "out of memory");
00287                         local->m_mgr = mgr;
00288                         local->m_drawer = drawer;
00289                         return local;
00290                 }
00291 private:
00292         // private constructors ------------------------------------------------
00293         TestFactory(void) throw() { }
00294 
00295         // private typedefs ----------------------------------------------------
00296         // private member data -------------------------------------------------
00297         smart_ptr<Manager>      m_mgr;
00298         smart_ptr<vgfx::Drawer> m_drawer;
00299 };
00300 
00301 
00302 
00303 ////////////////////////////////////////////////////////////////////////////////
00304 //
00305 //      TestFactory -- dialog::Factory class interface methods
00306 //
00307 ////////////////////////////////////////////////////////////////////////////////
00308 
00309 smart_ptr<dialog::Element>
00310 TestFactory::createElement
00311 (
00312 IN const char * type,
00313 IN dialog::Manager * mgr,
00314 IN const Datahash * data
00315 )
00316 {
00317         ASSERT(type, "null");
00318         ASSERT(mgr, "null");
00319         ASSERT(data, "null");
00320 
00321         const char * index = getOptionalString(data, "gamepadId", "-1");
00322         int idx = atoi(index);
00323         int nGamepads = m_mgr->getGamepadCount();
00324         ASSERT_THROW(idx >= 0 && idx < nGamepads,
00325             "Bad gamepad index: '" << index << "'");
00326 
00327         smart_ptr<Gamepad> gamepad = m_mgr->getGamepad(idx);
00328         ASSERT_THROW(gamepad, "gamepad does not exist: " << idx);
00329 
00330         ASSERT_THROW(!strcmp(type, s_testElementName),
00331            "Bad test element type: " << type);
00332 
00333         return TestElement::create(mgr, gamepad, m_drawer);
00334 }
00335 
00336 
00337 
00338 
00339 ////////////////////////////////////////////////////////////////////////////////
00340 //
00341 //      public API
00342 //
00343 ////////////////////////////////////////////////////////////////////////////////
00344 
00345 void
00346 registerVgfxTestFactory
00347 (
00348 IN smart_ptr<Manager>& gamepadMgr,
00349 IN dialog::Manager * dialogMgr,
00350 IN smart_ptr<vgfx::Drawer>& drawer
00351 )
00352 {
00353         ASSERT(gamepadMgr, "null");
00354         ASSERT(dialogMgr, "null");
00355         ASSERT(drawer, "null");
00356 
00357         smart_ptr<dialog::Factory> factory =
00358             TestFactory::create(gamepadMgr, drawer);
00359         ASSERT(factory, "null");
00360 
00361         dialogMgr->registerFactory(s_testElementName, factory);
00362 }
00363 
00364 
00365 
00366 const char *
00367 getVgfxTestElementName
00368 (
00369 void
00370 )
00371 throw()
00372 {
00373         return s_testElementName;
00374 }
00375 
00376 
00377 
00378 };      // gamepad namespace
00379