00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "gamepad-map.h"
00036
00037 #include "datahash/datahash_util.h"
00038 #include "util/parsing.h"
00039
00040
00041 namespace gamepad {
00042
00043
00044 Map::~Map(void) throw() { }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 class Mapping : public Map {
00060 public:
00061
00062 ~Mapping(void) throw() { }
00063
00064
00065 void initialize(IN const Datahash * hash);
00066
00067
00068 const char * getId(void) const throw() { return m_id.c_str(); }
00069 const char * getTypeId(void) const throw() { return m_typeId.c_str(); }
00070 const char * getName(void) const throw() { return m_name.c_str(); }
00071 const VecString& getDeviceNames(void) const throw() { return m_devices; }
00072 const button_map_t * getButtonMapping(IN const char * logicalName) const throw();
00073 const joystick_map_t * getJoystickMapping(IN const char * logicalName) const throw();
00074 const pot_map_t * getPotMapping(IN const char * logicalName) const throw();
00075 const dpad_map_t * getDpadMapping(IN const char * logicalName) const throw();
00076
00077 private:
00078
00079 typedef std::map<std::string, button_map_t> buttons_t;
00080 typedef std::map<std::string, joystick_map_t> joysticks_t;
00081 typedef std::map<std::string, pot_map_t> pots_t;
00082 typedef std::map<std::string, dpad_map_t> dpads_t;
00083
00084
00085 std::string m_id;
00086 std::string m_typeId;
00087 std::string m_name;
00088 VecString m_devices;
00089 buttons_t m_buttons;
00090 joysticks_t m_joysticks;
00091 pots_t m_pots;
00092 dpads_t m_dpads;
00093 };
00094
00095
00096
00097 void
00098 Mapping::initialize
00099 (
00100 IN const Datahash * in_hash
00101 )
00102 {
00103 ASSERT(in_hash, "null");
00104
00105
00106
00107
00108 const Datahash * hash = getSubhash(in_hash, "map");
00109 ASSERT_THROW(hash, "gamepad map hash does not contain 'map' section?");
00110
00111 m_id = getString(hash, "id");
00112
00113 m_typeId = getString(hash, "typeId");
00114
00115 m_name = getString(hash, "name");
00116
00117
00118
00119 m_devices.clear();
00120 Datahash::iterator_t i;
00121 hash->getIterator("deviceName", i);
00122 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00123 if (eHashDataType_String != phv->type)
00124 continue;
00125 m_devices.push_back(phv->text);
00126 }
00127
00128
00129
00130 hash->getIterator("button", i);
00131 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00132 if (eHashDataType_Hash != phv->type)
00133 continue;
00134
00135 const Datahash * btn = phv->hash;
00136 ASSERT(btn, "null hash in vector?");
00137
00138 button_map_t bmap;
00139 const char * logical = getString(btn, "logical");
00140 const char * index = getString(btn, "button");
00141 bmap.index = atoi(index);
00142
00143 ASSERT_THROW(bmap.isValid(),
00144 "Gamepad mapping for '" << logical << "' is not valid");
00145 m_buttons[logical] = bmap;
00146 }
00147
00148
00149
00150 hash->getIterator("joystick", i);
00151 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00152 if (eHashDataType_Hash != phv->type)
00153 continue;
00154 const Datahash * joy = phv->hash;
00155 ASSERT(joy, "null hash in vector?");
00156
00157 joystick_map_t jmap;
00158 const char * logical = getString(joy, "logical");
00159 jmap.xIndex = getInt(joy, "xAxis");
00160 jmap.yIndex = getInt(joy, "yAxis");
00161
00162
00163 ASSERT_THROW(jmap.isValid(),
00164 "Gamepad mapping for '" << logical << "' is not valid");
00165 m_joysticks[logical] = jmap;
00166 }
00167
00168
00169
00170 hash->getIterator("pot", i);
00171 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00172 if (eHashDataType_Hash != phv->type)
00173 continue;
00174 const Datahash * pot = phv->hash;
00175 ASSERT(pot, "null hash in vector?");
00176
00177 pot_map_t pmap;
00178 const char * logical = getString(pot, "logical");
00179 pmap.index = getInt(pot, "index");
00180
00181
00182 ASSERT_THROW(pmap.isValid(),
00183 "Gamepad mapping for '" << logical << "' is not valid");
00184 m_pots[logical] = pmap;
00185 }
00186
00187
00188
00189 hash->getIterator("dpad", i);
00190 while (const hash_value_t * phv = hash->getNextElementUnsafe(i)) {
00191 if (eHashDataType_Hash != phv->type)
00192 continue;
00193 const Datahash * dpad = phv->hash;
00194 ASSERT(dpad, "null hash in vector?");
00195
00196 dpad_map_t dmap;
00197 const char * logical = getString(dpad, "logical");
00198 const char * type = getString(dpad, "type");
00199 if (!strcmp("pot", type)) {
00200 } else if (!strcmp("button", type)) {
00201 dmap.type = dpad_map_t::eType_Button;
00202 } else {
00203 ASSERT_THROW(false, "Invalid dpad type: " << type);
00204 }
00205 dmap.index[dpad_map_t::eUp] = getByte(dpad, "up");
00206 dmap.index[dpad_map_t::eDown] = getByte(dpad, "down");
00207 dmap.index[dpad_map_t::eLeft] = getByte(dpad, "left");
00208 dmap.index[dpad_map_t::eRight] = getByte(dpad, "right");
00209
00210
00211 if (dpad_map_t::eType_Invalid == dmap.type) {
00212 if (dmap.index[dpad_map_t::eUp] == dmap.index[dpad_map_t::eDown]) {
00213 dmap.type = dpad_map_t::eType_2Pot;
00214 } else {
00215 dmap.type = dpad_map_t::eType_4Pot;
00216 }
00217 }
00218
00219
00220 const char * flipX = getOptionalString(dpad, "flipX", "");
00221 const char * flipY = getOptionalString(dpad, "flipY", "");
00222 dmap.flipX = getBooleanFromString(flipX);
00223 dmap.flipY = getBooleanFromString(flipY);
00224
00225
00226 ASSERT_THROW(dmap.isValid(),
00227 "Gamepad mapping for '" << logical << "' is not valid");
00228 m_dpads[logical] = dmap;
00229 }
00230
00231
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 const button_map_t *
00243 Mapping::getButtonMapping
00244 (
00245 IN const char * logicalName
00246 )
00247 const
00248 throw()
00249 {
00250 ASSERT(logicalName, "null");
00251
00252 buttons_t::const_iterator i = m_buttons.find(logicalName);
00253 if (m_buttons.end() == i)
00254 return NULL;
00255
00256 return &i->second;
00257 }
00258
00259
00260
00261 const joystick_map_t *
00262 Mapping::getJoystickMapping
00263 (
00264 IN const char * logicalName
00265 )
00266 const
00267 throw()
00268 {
00269 ASSERT(logicalName, "null");
00270
00271 joysticks_t::const_iterator i = m_joysticks.find(logicalName);
00272 if (m_joysticks.end() == i)
00273 return NULL;
00274 return &i->second;
00275 }
00276
00277
00278
00279 const pot_map_t *
00280 Mapping::getPotMapping
00281 (
00282 IN const char * logicalName
00283 )
00284 const
00285 throw()
00286 {
00287 ASSERT(logicalName, "null");
00288
00289 pots_t::const_iterator i = m_pots.find(logicalName);
00290 if (m_pots.end() == i)
00291 return NULL;
00292 return &i->second;
00293 }
00294
00295
00296
00297 const dpad_map_t *
00298 Mapping::getDpadMapping
00299 (
00300 IN const char * logicalName
00301 )
00302 const
00303 throw()
00304 {
00305 ASSERT(logicalName, "null");
00306
00307 dpads_t::const_iterator i = m_dpads.find(logicalName);
00308 if (m_dpads.end() == i)
00309 return NULL;
00310 return &i->second;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 smart_ptr<Map>
00322 readMap
00323 (
00324 IN const Datahash * hash
00325 )
00326 {
00327 ASSERT(hash, "null");
00328
00329 smart_ptr<Mapping> local = new Mapping;
00330 ASSERT(local, "out of memory");
00331
00332 local->initialize(hash);
00333
00334 return local;
00335 }
00336
00337
00338
00339 };
00340