| 1 | //============================================================================ | 
|---|
| 2 | // | 
|---|
| 3 | //   SSSS    tt          lll  lll | 
|---|
| 4 | //  SS  SS   tt           ll   ll | 
|---|
| 5 | //  SS     tttttt  eeee   ll   ll   aaaa | 
|---|
| 6 | //   SSSS    tt   ee  ee  ll   ll      aa | 
|---|
| 7 | //      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator" | 
|---|
| 8 | //  SS  SS   tt   ee      ll   ll  aa  aa | 
|---|
| 9 | //   SSSS     ttt  eeeee llll llll  aaaaa | 
|---|
| 10 | // | 
|---|
| 11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony | 
|---|
| 12 | // and the Stella Team | 
|---|
| 13 | // | 
|---|
| 14 | // See the file "License.txt" for information on usage and redistribution of | 
|---|
| 15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. | 
|---|
| 16 | //============================================================================ | 
|---|
| 17 |  | 
|---|
| 18 | #include "Logger.hxx" | 
|---|
| 19 | #include "OSystem.hxx" | 
|---|
| 20 | #include "Console.hxx" | 
|---|
| 21 | #include "Joystick.hxx" | 
|---|
| 22 | #include "Settings.hxx" | 
|---|
| 23 | #include "EventHandler.hxx" | 
|---|
| 24 | #include "PJoystickHandler.hxx" | 
|---|
| 25 |  | 
|---|
| 26 | #ifdef GUI_SUPPORT | 
|---|
| 27 | #include "DialogContainer.hxx" | 
|---|
| 28 | #endif | 
|---|
| 29 |  | 
|---|
| 30 | static constexpr char CTRL_DELIM = '^'; | 
|---|
| 31 |  | 
|---|
| 32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 33 | PhysicalJoystickHandler::PhysicalJoystickHandler( | 
|---|
| 34 | OSystem& system, EventHandler& handler) | 
|---|
| 35 | : myOSystem(system), | 
|---|
| 36 | myHandler(handler) | 
|---|
| 37 | { | 
|---|
| 38 | Int32 version = myOSystem.settings().getInt( "event_ver"); | 
|---|
| 39 | // Load previously saved joystick mapping (if any) from settings | 
|---|
| 40 | istringstream buf(myOSystem.settings().getString( "joymap")); | 
|---|
| 41 | string joymap, joyname; | 
|---|
| 42 |  | 
|---|
| 43 | // First compare if event list version has changed, and disregard the entire mapping if true | 
|---|
| 44 | getline(buf, joymap, CTRL_DELIM); // event list size, ignore | 
|---|
| 45 | if(version == Event::VERSION) | 
|---|
| 46 | { | 
|---|
| 47 | // Otherwise, put each joystick mapping entry into the database | 
|---|
| 48 | while(getline(buf, joymap, CTRL_DELIM)) | 
|---|
| 49 | { | 
|---|
| 50 | istringstream namebuf(joymap); | 
|---|
| 51 | getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM); | 
|---|
| 52 | if(joyname.length() != 0) | 
|---|
| 53 | myDatabase.emplace(joyname, StickInfo(joymap)); | 
|---|
| 54 | } | 
|---|
| 55 | } | 
|---|
| 56 | } | 
|---|
| 57 |  | 
|---|
| 58 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 59 | int PhysicalJoystickHandler::add(PhysicalJoystickPtr stick) | 
|---|
| 60 | { | 
|---|
| 61 | // Skip if we couldn't open it for any reason | 
|---|
| 62 | if(stick->ID < 0) | 
|---|
| 63 | return -1; | 
|---|
| 64 |  | 
|---|
| 65 | // Figure out what type of joystick this is | 
|---|
| 66 | bool specialAdaptor = false; | 
|---|
| 67 |  | 
|---|
| 68 | if(BSPF::containsIgnoreCase(stick->name, "2600-daptor")) | 
|---|
| 69 | { | 
|---|
| 70 | specialAdaptor = true; | 
|---|
| 71 | if(stick->numAxes == 4) | 
|---|
| 72 | { | 
|---|
| 73 | // TODO - detect controller type based on z-axis | 
|---|
| 74 | stick->name = "2600-daptor D9"; | 
|---|
| 75 | } | 
|---|
| 76 | else if(stick->numAxes == 3) | 
|---|
| 77 | { | 
|---|
| 78 | stick->name = "2600-daptor II"; | 
|---|
| 79 | } | 
|---|
| 80 | else | 
|---|
| 81 | stick->name = "2600-daptor"; | 
|---|
| 82 | } | 
|---|
| 83 | else if(BSPF::containsIgnoreCase(stick->name, "Stelladaptor")) | 
|---|
| 84 | { | 
|---|
| 85 | stick->name = "Stelladaptor"; | 
|---|
| 86 | specialAdaptor = true; | 
|---|
| 87 | } | 
|---|
| 88 | else | 
|---|
| 89 | { | 
|---|
| 90 | // We need unique names for mappable devices | 
|---|
| 91 | // For non-unique names that already have a database entry, | 
|---|
| 92 | // we append ' #x', where 'x' increases consecutively | 
|---|
| 93 | int count = 0; | 
|---|
| 94 | for(const auto& i: myDatabase) | 
|---|
| 95 | if(BSPF::startsWithIgnoreCase(i.first, stick->name) && i.second.joy) | 
|---|
| 96 | ++count; | 
|---|
| 97 |  | 
|---|
| 98 | if(count > 0) | 
|---|
| 99 | { | 
|---|
| 100 | ostringstream name; | 
|---|
| 101 | name << stick->name << " #"<< count+1; | 
|---|
| 102 | stick->name = name.str(); | 
|---|
| 103 | } | 
|---|
| 104 | stick->type = PhysicalJoystick::JT_REGULAR; | 
|---|
| 105 | } | 
|---|
| 106 | // The stick *must* be inserted here, since it may be used below | 
|---|
| 107 | mySticks[stick->ID] = stick; | 
|---|
| 108 |  | 
|---|
| 109 | // Map the stelladaptors we've found according to the specified ports | 
|---|
| 110 | if(specialAdaptor) | 
|---|
| 111 | mapStelladaptors(myOSystem.settings().getString( "saport")); | 
|---|
| 112 |  | 
|---|
| 113 | // Add stick to database | 
|---|
| 114 | auto it = myDatabase.find(stick->name); | 
|---|
| 115 | if(it != myDatabase.end()) // already present | 
|---|
| 116 | { | 
|---|
| 117 | it->second.joy = stick; | 
|---|
| 118 | stick->setMap(it->second.mapping); | 
|---|
| 119 | enableEmulationMappings(); | 
|---|
| 120 | } | 
|---|
| 121 | else // adding for the first time | 
|---|
| 122 | { | 
|---|
| 123 | StickInfo info( "", stick); | 
|---|
| 124 | myDatabase.emplace(stick->name, info); | 
|---|
| 125 | setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kEmulationMode, true); | 
|---|
| 126 | setStickDefaultMapping(stick->ID, Event::NoType, EventMode::kMenuMode, true); | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | return stick->ID; | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 133 | bool PhysicalJoystickHandler::remove(int id) | 
|---|
| 134 | { | 
|---|
| 135 | // When a joystick is removed, we delete the actual joystick object but | 
|---|
| 136 | // remember its mapping, since it will eventually be saved to settings | 
|---|
| 137 |  | 
|---|
| 138 | // Sticks that are removed must have initially been added | 
|---|
| 139 | // So we use the 'active' joystick list to access them | 
|---|
| 140 | try | 
|---|
| 141 | { | 
|---|
| 142 | PhysicalJoystickPtr stick = mySticks.at(id); | 
|---|
| 143 |  | 
|---|
| 144 | auto it = myDatabase.find(stick->name); | 
|---|
| 145 | if(it != myDatabase.end() && it->second.joy == stick) | 
|---|
| 146 | { | 
|---|
| 147 | ostringstream buf; | 
|---|
| 148 | buf << "Removed joystick "<< mySticks[id]->ID << ":"<< endl | 
|---|
| 149 | << "  "<< mySticks[id]->about() << endl; | 
|---|
| 150 | Logger::info(buf.str()); | 
|---|
| 151 |  | 
|---|
| 152 | // Remove joystick, but remember mapping | 
|---|
| 153 | it->second.mapping = stick->getMap(); | 
|---|
| 154 | it->second.joy = nullptr; | 
|---|
| 155 | mySticks.erase(id); | 
|---|
| 156 |  | 
|---|
| 157 | return true; | 
|---|
| 158 | } | 
|---|
| 159 | } | 
|---|
| 160 | catch(const std::out_of_range&) | 
|---|
| 161 | { | 
|---|
| 162 | // fall through to indicate remove failed | 
|---|
| 163 | } | 
|---|
| 164 |  | 
|---|
| 165 | return false; | 
|---|
| 166 | } | 
|---|
| 167 |  | 
|---|
| 168 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 169 | bool PhysicalJoystickHandler::remove(const string& name) | 
|---|
| 170 | { | 
|---|
| 171 | auto it = myDatabase.find(name); | 
|---|
| 172 | if(it != myDatabase.end() && it->second.joy == nullptr) | 
|---|
| 173 | { | 
|---|
| 174 | myDatabase.erase(it); | 
|---|
| 175 | return true; | 
|---|
| 176 | } | 
|---|
| 177 | return false; | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 181 | void PhysicalJoystickHandler::mapStelladaptors(const string& saport) | 
|---|
| 182 | { | 
|---|
| 183 | // saport will have two values: | 
|---|
| 184 | //   'lr' means treat first valid adaptor as left port, second as right port | 
|---|
| 185 | //   'rl' means treat first valid adaptor as right port, second as left port | 
|---|
| 186 | // We know there will be only two such devices (at most), since the logic | 
|---|
| 187 | // in setupJoysticks take care of that | 
|---|
| 188 | int saCount = 0; | 
|---|
| 189 | int saOrder[NUM_PORTS] = { 1, 2 }; | 
|---|
| 190 | if(BSPF::equalsIgnoreCase(saport, "rl")) | 
|---|
| 191 | { | 
|---|
| 192 | saOrder[0] = 2; saOrder[1] = 1; | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | for(auto& stick: mySticks) | 
|---|
| 196 | { | 
|---|
| 197 | // remove previously added emulated ports | 
|---|
| 198 | size_t pos = stick.second->name.find( " (emulates "); | 
|---|
| 199 |  | 
|---|
| 200 | if(pos != std::string::npos) | 
|---|
| 201 | stick.second->name.erase(pos); | 
|---|
| 202 |  | 
|---|
| 203 | if(BSPF::startsWithIgnoreCase(stick.second->name, "Stelladaptor")) | 
|---|
| 204 | { | 
|---|
| 205 | if(saOrder[saCount] == 1) | 
|---|
| 206 | { | 
|---|
| 207 | stick.second->name += " (emulates left joystick port)"; | 
|---|
| 208 | stick.second->type = PhysicalJoystick::JT_STELLADAPTOR_LEFT; | 
|---|
| 209 | } | 
|---|
| 210 | else if(saOrder[saCount] == 2) | 
|---|
| 211 | { | 
|---|
| 212 | stick.second->name += " (emulates right joystick port)"; | 
|---|
| 213 | stick.second->type = PhysicalJoystick::JT_STELLADAPTOR_RIGHT; | 
|---|
| 214 | } | 
|---|
| 215 | saCount++; | 
|---|
| 216 | } | 
|---|
| 217 | else if(BSPF::startsWithIgnoreCase(stick.second->name, "2600-daptor")) | 
|---|
| 218 | { | 
|---|
| 219 | if(saOrder[saCount] == 1) | 
|---|
| 220 | { | 
|---|
| 221 | stick.second->name += " (emulates left joystick port)"; | 
|---|
| 222 | stick.second->type = PhysicalJoystick::JT_2600DAPTOR_LEFT; | 
|---|
| 223 | } | 
|---|
| 224 | else if(saOrder[saCount] == 2) | 
|---|
| 225 | { | 
|---|
| 226 | stick.second->name += " (emulates right joystick port)"; | 
|---|
| 227 | stick.second->type = PhysicalJoystick::JT_2600DAPTOR_RIGHT; | 
|---|
| 228 | } | 
|---|
| 229 | saCount++; | 
|---|
| 230 | } | 
|---|
| 231 | } | 
|---|
| 232 | myOSystem.settings().setValue( "saport", saport); | 
|---|
| 233 | } | 
|---|
| 234 |  | 
|---|
| 235 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 236 | // Depending on parameters, this method does the following: | 
|---|
| 237 | // 1. update all events with default (event == Event::NoType, updateDefault == true) | 
|---|
| 238 | // 2. reset all events to default    (event == Event::NoType, updateDefault == false) | 
|---|
| 239 | // 3. reset one event to default     (event != Event::NoType) | 
|---|
| 240 | void PhysicalJoystickHandler::setDefaultAction(const PhysicalJoystickPtr& j, | 
|---|
| 241 | EventMapping map, Event::Type event, | 
|---|
| 242 | EventMode mode, bool updateDefaults) | 
|---|
| 243 | { | 
|---|
| 244 | // If event is 'NoType', erase and reset all mappings | 
|---|
| 245 | // Otherwise, only reset the given event | 
|---|
| 246 | bool eraseAll = !updateDefaults && (event == Event::NoType); | 
|---|
| 247 |  | 
|---|
| 248 | if(updateDefaults) | 
|---|
| 249 | { | 
|---|
| 250 | // if there is no existing mapping for the event or | 
|---|
| 251 | //  the default mapping for the event is unused, set default key for event | 
|---|
| 252 | if(j->joyMap.getEventMapping(map.event, mode).size() == 0 || | 
|---|
| 253 | !j->joyMap.check(mode, map.button, map.axis, map.adir, map.hat, map.hdir)) | 
|---|
| 254 | { | 
|---|
| 255 | j->joyMap.add(map.event, mode, map.button, map.axis, map.adir, map.hat, map.hdir); | 
|---|
| 256 | } | 
|---|
| 257 | } | 
|---|
| 258 | else if(eraseAll || map.event == event) | 
|---|
| 259 | { | 
|---|
| 260 | // TODO: allow for multiple defaults | 
|---|
| 261 | //j->joyMap.eraseEvent(map.event, mode); | 
|---|
| 262 | j->joyMap.add(map.event, mode, map.button, map.axis, map.adir, map.hat, map.hdir); | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 268 | void PhysicalJoystickHandler::setStickDefaultMapping(int stick, Event::Type event, | 
|---|
| 269 | EventMode mode, bool updateDefaults) | 
|---|
| 270 | { | 
|---|
| 271 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 272 |  | 
|---|
| 273 | if(j) | 
|---|
| 274 | { | 
|---|
| 275 | switch (mode) | 
|---|
| 276 | { | 
|---|
| 277 | case EventMode::kEmulationMode: | 
|---|
| 278 | if((stick % 2) == 0) // even sticks | 
|---|
| 279 | { | 
|---|
| 280 | // put all controller events into their own mode's mappings | 
|---|
| 281 | for (const auto& item : DefaultLeftJoystickMapping) | 
|---|
| 282 | setDefaultAction(j, item, event, EventMode::kJoystickMode, updateDefaults); | 
|---|
| 283 | for (const auto& item : DefaultLeftPaddlesMapping) | 
|---|
| 284 | setDefaultAction(j, item, event, EventMode::kPaddlesMode, updateDefaults); | 
|---|
| 285 | for (const auto& item : DefaultLeftKeypadMapping) | 
|---|
| 286 | setDefaultAction(j, item, event, EventMode::kKeypadMode, updateDefaults); | 
|---|
| 287 | } | 
|---|
| 288 | else // odd sticks | 
|---|
| 289 | { | 
|---|
| 290 | // put all controller events into their own mode's mappings | 
|---|
| 291 | for (const auto& item : DefaultRightJoystickMapping) | 
|---|
| 292 | setDefaultAction(j, item, event, EventMode::kJoystickMode, updateDefaults); | 
|---|
| 293 | for (const auto& item : DefaultRightPaddlesMapping) | 
|---|
| 294 | setDefaultAction(j, item, event, EventMode::kPaddlesMode, updateDefaults); | 
|---|
| 295 | for (const auto& item : DefaultRightKeypadMapping) | 
|---|
| 296 | setDefaultAction(j, item, event, EventMode::kKeypadMode, updateDefaults); | 
|---|
| 297 | } | 
|---|
| 298 | for(const auto& item : DefaultCommonMapping) | 
|---|
| 299 | setDefaultAction(j, item, event, EventMode::kCommonMode, updateDefaults); | 
|---|
| 300 | // update running emulation mapping too | 
|---|
| 301 | enableEmulationMappings(); | 
|---|
| 302 | break; | 
|---|
| 303 |  | 
|---|
| 304 | case EventMode::kMenuMode: | 
|---|
| 305 | for (const auto& item : DefaultMenuMapping) | 
|---|
| 306 | setDefaultAction(j, item, event, EventMode::kMenuMode, updateDefaults); | 
|---|
| 307 | break; | 
|---|
| 308 |  | 
|---|
| 309 | default: | 
|---|
| 310 | break; | 
|---|
| 311 | } | 
|---|
| 312 | } | 
|---|
| 313 | } | 
|---|
| 314 |  | 
|---|
| 315 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 316 | void PhysicalJoystickHandler::setDefaultMapping(Event::Type event, EventMode mode) | 
|---|
| 317 | { | 
|---|
| 318 | eraseMapping(event, mode); | 
|---|
| 319 | for (auto& i : mySticks) | 
|---|
| 320 | setStickDefaultMapping(i.first, event, mode); | 
|---|
| 321 | } | 
|---|
| 322 |  | 
|---|
| 323 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 324 | void PhysicalJoystickHandler::defineControllerMappings(const Controller::Type type, Controller::Jack port) | 
|---|
| 325 | { | 
|---|
| 326 | // determine controller events to use | 
|---|
| 327 | switch(type) | 
|---|
| 328 | { | 
|---|
| 329 | case Controller::Type::Keyboard: | 
|---|
| 330 | case Controller::Type::KidVid: | 
|---|
| 331 | if(port == Controller::Jack::Left) | 
|---|
| 332 | myLeftMode = EventMode::kKeypadMode; | 
|---|
| 333 | else | 
|---|
| 334 | myRightMode = EventMode::kKeypadMode; | 
|---|
| 335 | break; | 
|---|
| 336 |  | 
|---|
| 337 | case Controller::Type::Paddles: | 
|---|
| 338 | case Controller::Type::PaddlesIAxDr: | 
|---|
| 339 | case Controller::Type::PaddlesIAxis: | 
|---|
| 340 | if(port == Controller::Jack::Left) | 
|---|
| 341 | myLeftMode = EventMode::kPaddlesMode; | 
|---|
| 342 | else | 
|---|
| 343 | myRightMode = EventMode::kPaddlesMode; | 
|---|
| 344 | break; | 
|---|
| 345 |  | 
|---|
| 346 | case Controller::Type::CompuMate: | 
|---|
| 347 | myLeftMode = myRightMode = EventMode::kCompuMateMode; | 
|---|
| 348 | break; | 
|---|
| 349 |  | 
|---|
| 350 | default: | 
|---|
| 351 | // let's use joystick then | 
|---|
| 352 | if(port == Controller::Jack::Left) | 
|---|
| 353 | myLeftMode = EventMode::kJoystickMode; | 
|---|
| 354 | else | 
|---|
| 355 | myRightMode = EventMode::kJoystickMode; | 
|---|
| 356 | } | 
|---|
| 357 | } | 
|---|
| 358 |  | 
|---|
| 359 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 360 | void PhysicalJoystickHandler::enableEmulationMappings() | 
|---|
| 361 | { | 
|---|
| 362 | for (auto& stick : mySticks) | 
|---|
| 363 | { | 
|---|
| 364 | const PhysicalJoystickPtr j = stick.second; | 
|---|
| 365 |  | 
|---|
| 366 | // start from scratch and enable common mappings | 
|---|
| 367 | j->joyMap.eraseMode(EventMode::kEmulationMode); | 
|---|
| 368 | } | 
|---|
| 369 |  | 
|---|
| 370 | enableCommonMappings(); | 
|---|
| 371 |  | 
|---|
| 372 | // enable right mode first, so that in case of mapping clashes the left controller has preference | 
|---|
| 373 | switch (myRightMode) | 
|---|
| 374 | { | 
|---|
| 375 | case EventMode::kPaddlesMode: | 
|---|
| 376 | enableMappings(RightPaddlesEvents, EventMode::kPaddlesMode); | 
|---|
| 377 | break; | 
|---|
| 378 |  | 
|---|
| 379 | case EventMode::kKeypadMode: | 
|---|
| 380 | enableMappings(RightKeypadEvents, EventMode::kKeypadMode); | 
|---|
| 381 | break; | 
|---|
| 382 |  | 
|---|
| 383 | default: | 
|---|
| 384 | enableMappings(RightJoystickEvents, EventMode::kJoystickMode); | 
|---|
| 385 | break; | 
|---|
| 386 | } | 
|---|
| 387 |  | 
|---|
| 388 | switch (myLeftMode) | 
|---|
| 389 | { | 
|---|
| 390 | case EventMode::kPaddlesMode: | 
|---|
| 391 | enableMappings(LeftPaddlesEvents, EventMode::kPaddlesMode); | 
|---|
| 392 | break; | 
|---|
| 393 |  | 
|---|
| 394 | case EventMode::kKeypadMode: | 
|---|
| 395 | enableMappings(LeftKeypadEvents, EventMode::kKeypadMode); | 
|---|
| 396 | break; | 
|---|
| 397 |  | 
|---|
| 398 | default: | 
|---|
| 399 | enableMappings(LeftJoystickEvents, EventMode::kJoystickMode); | 
|---|
| 400 | break; | 
|---|
| 401 | } | 
|---|
| 402 | } | 
|---|
| 403 |  | 
|---|
| 404 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 405 | void PhysicalJoystickHandler::enableCommonMappings() | 
|---|
| 406 | { | 
|---|
| 407 | for (int i = Event::NoType + 1; i < Event::LastType; i++) | 
|---|
| 408 | { | 
|---|
| 409 | Event::Type event = static_cast<Event::Type>(i); | 
|---|
| 410 |  | 
|---|
| 411 | if(isCommonEvent(event)) | 
|---|
| 412 | enableMapping(event, EventMode::kCommonMode); | 
|---|
| 413 | } | 
|---|
| 414 | } | 
|---|
| 415 |  | 
|---|
| 416 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 417 | void PhysicalJoystickHandler::enableMappings(const Event::EventSet events, EventMode mode) | 
|---|
| 418 | { | 
|---|
| 419 | for (const auto& event : events) | 
|---|
| 420 | enableMapping(event, mode); | 
|---|
| 421 | } | 
|---|
| 422 |  | 
|---|
| 423 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 424 | void PhysicalJoystickHandler::enableMapping(const Event::Type event, EventMode mode) | 
|---|
| 425 | { | 
|---|
| 426 | // copy from controller mode into emulation mode | 
|---|
| 427 | for (auto& stick : mySticks) | 
|---|
| 428 | { | 
|---|
| 429 | const PhysicalJoystickPtr j = stick.second; | 
|---|
| 430 |  | 
|---|
| 431 | JoyMap::JoyMappingArray joyMappings = j->joyMap.getEventMapping(event, mode); | 
|---|
| 432 |  | 
|---|
| 433 | for (const auto& mapping : joyMappings) | 
|---|
| 434 | j->joyMap.add(event, EventMode::kEmulationMode, mapping.button, mapping.axis, mapping.adir); | 
|---|
| 435 | } | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 439 | EventMode PhysicalJoystickHandler::getEventMode(const Event::Type event, const EventMode mode) const | 
|---|
| 440 | { | 
|---|
| 441 | if(mode == EventMode::kEmulationMode) | 
|---|
| 442 | { | 
|---|
| 443 | if(isJoystickEvent(event)) | 
|---|
| 444 | return EventMode::kJoystickMode; | 
|---|
| 445 |  | 
|---|
| 446 | if(isPaddleEvent(event)) | 
|---|
| 447 | return EventMode::kPaddlesMode; | 
|---|
| 448 |  | 
|---|
| 449 | if(isKeypadEvent(event)) | 
|---|
| 450 | return EventMode::kKeypadMode; | 
|---|
| 451 |  | 
|---|
| 452 | if(isCommonEvent(event)) | 
|---|
| 453 | return EventMode::kCommonMode; | 
|---|
| 454 | } | 
|---|
| 455 |  | 
|---|
| 456 | return mode; | 
|---|
| 457 | } | 
|---|
| 458 |  | 
|---|
| 459 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 460 | bool PhysicalJoystickHandler::isJoystickEvent(const Event::Type event) const | 
|---|
| 461 | { | 
|---|
| 462 | return LeftJoystickEvents.find(event) != LeftJoystickEvents.end() | 
|---|
| 463 | || RightJoystickEvents.find(event) != RightJoystickEvents.end(); | 
|---|
| 464 | } | 
|---|
| 465 |  | 
|---|
| 466 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 467 | bool PhysicalJoystickHandler::isPaddleEvent(const Event::Type event) const | 
|---|
| 468 | { | 
|---|
| 469 | return LeftPaddlesEvents.find(event) != LeftPaddlesEvents.end() | 
|---|
| 470 | || RightPaddlesEvents.find(event) != RightPaddlesEvents.end(); | 
|---|
| 471 | } | 
|---|
| 472 |  | 
|---|
| 473 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 474 | bool PhysicalJoystickHandler::isKeypadEvent(const Event::Type event) const | 
|---|
| 475 | { | 
|---|
| 476 | return LeftKeypadEvents.find(event) != LeftKeypadEvents.end() | 
|---|
| 477 | || RightKeypadEvents.find(event) != RightKeypadEvents.end(); | 
|---|
| 478 | } | 
|---|
| 479 |  | 
|---|
| 480 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 481 | bool PhysicalJoystickHandler::isCommonEvent(const Event::Type event) const | 
|---|
| 482 | { | 
|---|
| 483 | return !(isJoystickEvent(event) || isPaddleEvent(event) || isKeypadEvent(event)); | 
|---|
| 484 | } | 
|---|
| 485 |  | 
|---|
| 486 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 487 | void PhysicalJoystickHandler::eraseMapping(Event::Type event, EventMode mode) | 
|---|
| 488 | { | 
|---|
| 489 | // If event is 'NoType', erase and reset all mappings | 
|---|
| 490 | // Otherwise, only reset the given event | 
|---|
| 491 | if(event == Event::NoType) | 
|---|
| 492 | { | 
|---|
| 493 | for (auto& stick : mySticks) | 
|---|
| 494 | { | 
|---|
| 495 | stick.second->eraseMap(mode);          // erase all events | 
|---|
| 496 | if(mode == EventMode::kEmulationMode) | 
|---|
| 497 | { | 
|---|
| 498 | stick.second->eraseMap(EventMode::kCommonMode); | 
|---|
| 499 | stick.second->eraseMap(EventMode::kJoystickMode); | 
|---|
| 500 | stick.second->eraseMap(EventMode::kPaddlesMode); | 
|---|
| 501 | stick.second->eraseMap(EventMode::kKeypadMode); | 
|---|
| 502 | } | 
|---|
| 503 | } | 
|---|
| 504 | } | 
|---|
| 505 | else | 
|---|
| 506 | { | 
|---|
| 507 | for (auto& stick : mySticks) | 
|---|
| 508 | { | 
|---|
| 509 | stick.second->eraseEvent(event, mode); // only reset the specific event | 
|---|
| 510 | stick.second->eraseEvent(event, getEventMode(event, mode)); | 
|---|
| 511 | } | 
|---|
| 512 | } | 
|---|
| 513 | } | 
|---|
| 514 |  | 
|---|
| 515 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 516 | void PhysicalJoystickHandler::saveMapping() | 
|---|
| 517 | { | 
|---|
| 518 | // Save the joystick mapping hash table, making sure to update it with | 
|---|
| 519 | // any changes that have been made during the program run | 
|---|
| 520 | ostringstream joybuf; | 
|---|
| 521 |  | 
|---|
| 522 | for(const auto& i: myDatabase) | 
|---|
| 523 | { | 
|---|
| 524 | const string& map = i.second.joy ? i.second.joy->getMap() : i.second.mapping; | 
|---|
| 525 | if(map != "") | 
|---|
| 526 | joybuf << CTRL_DELIM << map; | 
|---|
| 527 | } | 
|---|
| 528 | myOSystem.settings().setValue( "joymap", joybuf.str()); | 
|---|
| 529 | } | 
|---|
| 530 |  | 
|---|
| 531 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 532 | string PhysicalJoystickHandler::getMappingDesc(Event::Type event, EventMode mode) const | 
|---|
| 533 | { | 
|---|
| 534 | ostringstream buf; | 
|---|
| 535 | EventMode evMode = getEventMode(event, mode); | 
|---|
| 536 |  | 
|---|
| 537 | for(const auto& s: mySticks) | 
|---|
| 538 | { | 
|---|
| 539 | uInt32 stick = s.first; | 
|---|
| 540 | const PhysicalJoystickPtr j = s.second; | 
|---|
| 541 |  | 
|---|
| 542 | if(j) | 
|---|
| 543 | { | 
|---|
| 544 | //Joystick mapping / labeling | 
|---|
| 545 | if(j->joyMap.getEventMapping(event, evMode).size()) | 
|---|
| 546 | { | 
|---|
| 547 | if(buf.str() != "") | 
|---|
| 548 | buf << ", "; | 
|---|
| 549 | buf << j->joyMap.getEventMappingDesc(stick, event, evMode); | 
|---|
| 550 | } | 
|---|
| 551 | } | 
|---|
| 552 | } | 
|---|
| 553 | return buf.str(); | 
|---|
| 554 | } | 
|---|
| 555 |  | 
|---|
| 556 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 557 | bool PhysicalJoystickHandler::addJoyMapping(Event::Type event, EventMode mode, int stick, | 
|---|
| 558 | int button, JoyAxis axis, JoyDir adir) | 
|---|
| 559 | { | 
|---|
| 560 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 561 |  | 
|---|
| 562 | if(j && event < Event::LastType && | 
|---|
| 563 | button >= JOY_CTRL_NONE && button < j->numButtons && | 
|---|
| 564 | axis >= JoyAxis::NONE && int(axis) < j->numAxes) | 
|---|
| 565 | { | 
|---|
| 566 | EventMode evMode = getEventMode(event, mode); | 
|---|
| 567 |  | 
|---|
| 568 | // This confusing code is because each axis has two associated values, | 
|---|
| 569 | // but analog events only affect one of the axis. | 
|---|
| 570 | if(Event::isAnalog(event)) | 
|---|
| 571 | { | 
|---|
| 572 | j->joyMap.add(event, evMode, button, axis, JoyDir::ANALOG); | 
|---|
| 573 | // update running emulation mapping too | 
|---|
| 574 | j->joyMap.add(event, EventMode::kEmulationMode, button, axis, JoyDir::ANALOG); | 
|---|
| 575 | } | 
|---|
| 576 | else | 
|---|
| 577 | { | 
|---|
| 578 | j->joyMap.add(event, evMode, button, axis, adir); | 
|---|
| 579 | // update running emulation mapping too | 
|---|
| 580 | j->joyMap.add(event, EventMode::kEmulationMode, button, axis, adir); | 
|---|
| 581 | } | 
|---|
| 582 | return true; | 
|---|
| 583 | } | 
|---|
| 584 | return false; | 
|---|
| 585 | } | 
|---|
| 586 |  | 
|---|
| 587 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 588 | bool PhysicalJoystickHandler::addJoyHatMapping(Event::Type event, EventMode mode, int stick, | 
|---|
| 589 | int button, int hat, JoyHatDir hdir) | 
|---|
| 590 | { | 
|---|
| 591 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 592 |  | 
|---|
| 593 | if(j && event < Event::LastType && | 
|---|
| 594 | button >= JOY_CTRL_NONE && button < j->numButtons && | 
|---|
| 595 | hat >= 0 && hat < j->numHats && hdir != JoyHatDir::CENTER) | 
|---|
| 596 | { | 
|---|
| 597 | j->joyMap.add(event, getEventMode(event, mode), button, hat, hdir); | 
|---|
| 598 | // update running emulation mapping too | 
|---|
| 599 | j->joyMap.add(event, EventMode::kEmulationMode, button, hat, hdir); | 
|---|
| 600 | return true; | 
|---|
| 601 | } | 
|---|
| 602 | return false; | 
|---|
| 603 | } | 
|---|
| 604 |  | 
|---|
| 605 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 606 | void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) | 
|---|
| 607 | { | 
|---|
| 608 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 609 |  | 
|---|
| 610 | if(j) | 
|---|
| 611 | { | 
|---|
| 612 | int button = j->buttonLast[stick]; | 
|---|
| 613 |  | 
|---|
| 614 | if(myHandler.state() == EventHandlerState::EMULATION) | 
|---|
| 615 | { | 
|---|
| 616 | // Check for analog events, which are handled differently | 
|---|
| 617 | // A value change lower than ~90% indicates analog input | 
|---|
| 618 | if(abs(j->axisLastValue[axis] - value) < 30000) | 
|---|
| 619 | { | 
|---|
| 620 | Event::Type eventAxisAnalog = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::ANALOG); | 
|---|
| 621 |  | 
|---|
| 622 | myHandler.handleEvent(eventAxisAnalog, value); | 
|---|
| 623 | } | 
|---|
| 624 | else | 
|---|
| 625 | { | 
|---|
| 626 | // Otherwise, we assume the event is digital | 
|---|
| 627 | // Every axis event has two associated values, negative and positive | 
|---|
| 628 | Event::Type eventAxisNeg = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::NEG); | 
|---|
| 629 | Event::Type eventAxisPos = j->joyMap.get(EventMode::kEmulationMode, button, JoyAxis(axis), JoyDir::POS); | 
|---|
| 630 |  | 
|---|
| 631 | if(value > Joystick::deadzone()) | 
|---|
| 632 | myHandler.handleEvent(eventAxisPos); | 
|---|
| 633 | else if(value < -Joystick::deadzone()) | 
|---|
| 634 | myHandler.handleEvent(eventAxisNeg); | 
|---|
| 635 | else | 
|---|
| 636 | { | 
|---|
| 637 | // Treat any deadzone value as zero | 
|---|
| 638 | value = 0; | 
|---|
| 639 |  | 
|---|
| 640 | // Now filter out consecutive, similar values | 
|---|
| 641 | // (only pass on the event if the state has changed) | 
|---|
| 642 | if(j->axisLastValue[axis] != value) | 
|---|
| 643 | { | 
|---|
| 644 | // Turn off both events, since we don't know exactly which one | 
|---|
| 645 | // was previously activated. | 
|---|
| 646 | myHandler.handleEvent(eventAxisNeg, false); | 
|---|
| 647 | myHandler.handleEvent(eventAxisPos, false); | 
|---|
| 648 | } | 
|---|
| 649 | } | 
|---|
| 650 | } | 
|---|
| 651 | j->axisLastValue[axis] = value; | 
|---|
| 652 | } | 
|---|
| 653 | else if(myHandler.hasOverlay()) | 
|---|
| 654 | { | 
|---|
| 655 | // First, clamp the values to simulate digital input | 
|---|
| 656 | // (the only thing that the underlying code understands) | 
|---|
| 657 | if(value > Joystick::deadzone()) | 
|---|
| 658 | value = 32000; | 
|---|
| 659 | else if(value < -Joystick::deadzone()) | 
|---|
| 660 | value = -32000; | 
|---|
| 661 | else | 
|---|
| 662 | value = 0; | 
|---|
| 663 |  | 
|---|
| 664 | // Now filter out consecutive, similar values | 
|---|
| 665 | // (only pass on the event if the state has changed) | 
|---|
| 666 | if(value != j->axisLastValue[axis]) | 
|---|
| 667 | { | 
|---|
| 668 | #ifdef GUI_SUPPORT | 
|---|
| 669 | myHandler.overlay().handleJoyAxisEvent(stick, JoyAxis(axis), convertAxisValue(value), button); | 
|---|
| 670 | #endif | 
|---|
| 671 | j->axisLastValue[axis] = value; | 
|---|
| 672 | } | 
|---|
| 673 | } | 
|---|
| 674 | } | 
|---|
| 675 | } | 
|---|
| 676 |  | 
|---|
| 677 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 678 | void PhysicalJoystickHandler::handleBtnEvent(int stick, int button, bool pressed) | 
|---|
| 679 | { | 
|---|
| 680 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 681 |  | 
|---|
| 682 | if(j) | 
|---|
| 683 | { | 
|---|
| 684 | j->buttonLast[stick] = pressed ? button : JOY_CTRL_NONE; | 
|---|
| 685 |  | 
|---|
| 686 | // Handle buttons which switch eventhandler state | 
|---|
| 687 | if(pressed && myHandler.changeStateByEvent(j->joyMap.get(EventMode::kEmulationMode, button))) | 
|---|
| 688 | return; | 
|---|
| 689 |  | 
|---|
| 690 | // Determine which mode we're in, then send the event to the appropriate place | 
|---|
| 691 | if(myHandler.state() == EventHandlerState::EMULATION) | 
|---|
| 692 | myHandler.handleEvent(j->joyMap.get(EventMode::kEmulationMode, button), pressed); | 
|---|
| 693 | #ifdef GUI_SUPPORT | 
|---|
| 694 | else if(myHandler.hasOverlay()) | 
|---|
| 695 | myHandler.overlay().handleJoyBtnEvent(stick, button, pressed); | 
|---|
| 696 | #endif | 
|---|
| 697 | } | 
|---|
| 698 | } | 
|---|
| 699 |  | 
|---|
| 700 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 701 | void PhysicalJoystickHandler::handleHatEvent(int stick, int hat, int value) | 
|---|
| 702 | { | 
|---|
| 703 | // Preprocess all hat events, converting to Stella JoyHatDir type | 
|---|
| 704 | // Generate multiple equivalent hat events representing combined direction | 
|---|
| 705 | // when we get a diagonal hat event | 
|---|
| 706 |  | 
|---|
| 707 | const PhysicalJoystickPtr j = joy(stick); | 
|---|
| 708 |  | 
|---|
| 709 | if(j) | 
|---|
| 710 | { | 
|---|
| 711 | const int button = j->buttonLast[stick]; | 
|---|
| 712 |  | 
|---|
| 713 | if(myHandler.state() == EventHandlerState::EMULATION) | 
|---|
| 714 | { | 
|---|
| 715 | myHandler.handleEvent(j->joyMap.get(EventMode::kEmulationMode, button, hat, JoyHatDir::UP), | 
|---|
| 716 | value & EVENT_HATUP_M); | 
|---|
| 717 | myHandler.handleEvent(j->joyMap.get(EventMode::kEmulationMode, button, hat, JoyHatDir::RIGHT), | 
|---|
| 718 | value & EVENT_HATRIGHT_M); | 
|---|
| 719 | myHandler.handleEvent(j->joyMap.get(EventMode::kEmulationMode, button, hat, JoyHatDir::DOWN), | 
|---|
| 720 | value & EVENT_HATDOWN_M); | 
|---|
| 721 | myHandler.handleEvent(j->joyMap.get(EventMode::kEmulationMode, button, hat, JoyHatDir::LEFT), | 
|---|
| 722 | value & EVENT_HATLEFT_M); | 
|---|
| 723 | } | 
|---|
| 724 | #ifdef GUI_SUPPORT | 
|---|
| 725 | else if(myHandler.hasOverlay()) | 
|---|
| 726 | { | 
|---|
| 727 | if(value == EVENT_HATCENTER_M) | 
|---|
| 728 | myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHatDir::CENTER, button); | 
|---|
| 729 | else | 
|---|
| 730 | { | 
|---|
| 731 | if(value & EVENT_HATUP_M) | 
|---|
| 732 | myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHatDir::UP, button); | 
|---|
| 733 | if(value & EVENT_HATRIGHT_M) | 
|---|
| 734 | myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHatDir::RIGHT, button); | 
|---|
| 735 | if(value & EVENT_HATDOWN_M) | 
|---|
| 736 | myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHatDir::DOWN, button); | 
|---|
| 737 | if(value & EVENT_HATLEFT_M) | 
|---|
| 738 | myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHatDir::LEFT, button); | 
|---|
| 739 | } | 
|---|
| 740 | } | 
|---|
| 741 | #endif | 
|---|
| 742 | } | 
|---|
| 743 | } | 
|---|
| 744 |  | 
|---|
| 745 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 746 | VariantList PhysicalJoystickHandler::database() const | 
|---|
| 747 | { | 
|---|
| 748 | VariantList db; | 
|---|
| 749 | for(const auto& i: myDatabase) | 
|---|
| 750 | VarList::push_back(db, i.first, i.second.joy ? i.second.joy->ID : -1); | 
|---|
| 751 |  | 
|---|
| 752 | return db; | 
|---|
| 753 | } | 
|---|
| 754 |  | 
|---|
| 755 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 756 | ostream& operator<<(ostream& os, const PhysicalJoystickHandler& jh) | 
|---|
| 757 | { | 
|---|
| 758 | os << "---------------------------------------------------------"<< endl | 
|---|
| 759 | << "joy database:"<< endl; | 
|---|
| 760 | for(const auto& i: jh.myDatabase) | 
|---|
| 761 | os << i.first << endl << i.second << endl << endl; | 
|---|
| 762 |  | 
|---|
| 763 | os << "---------------------"<< endl | 
|---|
| 764 | << "joy active:"<< endl; | 
|---|
| 765 | for(const auto& i: jh.mySticks) | 
|---|
| 766 | os << i.first << ": "<< *i.second << endl; | 
|---|
| 767 | os << "---------------------------------------------------------" | 
|---|
| 768 | << endl << endl << endl; | 
|---|
| 769 |  | 
|---|
| 770 | return os; | 
|---|
| 771 | } | 
|---|
| 772 |  | 
|---|
| 773 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 774 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftJoystickMapping = { | 
|---|
| 775 | // Left joystick (assume buttons zero..two) | 
|---|
| 776 | {Event::JoystickZeroFire,   0}, | 
|---|
| 777 | {Event::JoystickZeroFire5,  1}, | 
|---|
| 778 | {Event::JoystickZeroFire9,  2}, | 
|---|
| 779 | // Left joystick left/right directions | 
|---|
| 780 | {Event::JoystickZeroLeft,   JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG}, | 
|---|
| 781 | {Event::JoystickZeroRight,  JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS}, | 
|---|
| 782 | // Left joystick up/down directions | 
|---|
| 783 | {Event::JoystickZeroUp,     JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG}, | 
|---|
| 784 | {Event::JoystickZeroDown,   JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS}, | 
|---|
| 785 | // Left joystick left/right directions (assume hat 0) | 
|---|
| 786 | {Event::JoystickZeroLeft,   JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::LEFT}, | 
|---|
| 787 | {Event::JoystickZeroRight,  JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::RIGHT}, | 
|---|
| 788 | // Left joystick up/down directions (assume hat 0) | 
|---|
| 789 | {Event::JoystickZeroUp,     JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::UP}, | 
|---|
| 790 | {Event::JoystickZeroDown,   JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::DOWN}, | 
|---|
| 791 | }; | 
|---|
| 792 |  | 
|---|
| 793 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 794 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRightJoystickMapping = { | 
|---|
| 795 | // Right joystick (assume buttons zero..two) | 
|---|
| 796 | {Event::JoystickOneFire,    0}, | 
|---|
| 797 | {Event::JoystickOneFire5,   1}, | 
|---|
| 798 | {Event::JoystickOneFire9,   2}, | 
|---|
| 799 | // Right joystick left/right directions | 
|---|
| 800 | {Event::JoystickOneLeft,    JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG}, | 
|---|
| 801 | {Event::JoystickOneRight,   JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS}, | 
|---|
| 802 | // Right joystick up/down directions | 
|---|
| 803 | {Event::JoystickOneUp,      JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG}, | 
|---|
| 804 | {Event::JoystickOneDown,    JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS}, | 
|---|
| 805 | // Right joystick left/right directions (assume hat 0) | 
|---|
| 806 | {Event::JoystickOneLeft,    JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::LEFT}, | 
|---|
| 807 | {Event::JoystickOneRight,   JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::RIGHT}, | 
|---|
| 808 | // Right joystick up/down directions (assume hat 0) | 
|---|
| 809 | {Event::JoystickOneUp,      JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::UP}, | 
|---|
| 810 | {Event::JoystickOneDown,    JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::DOWN}, | 
|---|
| 811 | }; | 
|---|
| 812 |  | 
|---|
| 813 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 814 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftPaddlesMapping = { | 
|---|
| 815 | {Event::PaddleZeroAnalog,   JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG}, | 
|---|
| 816 | // Current code does NOT allow digital and anlog events on the same axis at the same time | 
|---|
| 817 | //{Event::PaddleZeroDecrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS}, | 
|---|
| 818 | //{Event::PaddleZeroIncrease, JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG}, | 
|---|
| 819 | {Event::PaddleZeroFire,     0}, | 
|---|
| 820 | {Event::PaddleOneAnalog,    JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG}, | 
|---|
| 821 | // Current code does NOT allow digital and anlog events on the same axis at the same | 
|---|
| 822 | //{Event::PaddleOneDecrease,  JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS}, | 
|---|
| 823 | //{Event::PaddleOneIncrease,  JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG}, | 
|---|
| 824 | {Event::PaddleOneFire,      1}, | 
|---|
| 825 | }; | 
|---|
| 826 |  | 
|---|
| 827 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 828 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRightPaddlesMapping = { | 
|---|
| 829 | {Event::PaddleTwoAnalog,    JOY_CTRL_NONE, JoyAxis::X, JoyDir::ANALOG}, | 
|---|
| 830 | // Current code does NOT allow digital and anlog events on the same axis at the same | 
|---|
| 831 | //{Event::PaddleTwoDecrease,  JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS}, | 
|---|
| 832 | //{Event::PaddleTwoIncrease,  JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG}, | 
|---|
| 833 | {Event::PaddleTwoFire,      0}, | 
|---|
| 834 | {Event::PaddleThreeAnalog,  JOY_CTRL_NONE, JoyAxis::Y, JoyDir::ANALOG}, | 
|---|
| 835 | // Current code does NOT allow digital and anlog events on the same axis at the same | 
|---|
| 836 | //{Event::PaddleThreeDecrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS}, | 
|---|
| 837 | //{Event::PaddleThreeIncrease,JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG}, | 
|---|
| 838 | {Event::PaddleThreeFire,    1}, | 
|---|
| 839 | }; | 
|---|
| 840 |  | 
|---|
| 841 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 842 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultLeftKeypadMapping = { | 
|---|
| 843 | {Event::KeyboardZero1,      0}, | 
|---|
| 844 | {Event::KeyboardZero2,      1}, | 
|---|
| 845 | {Event::KeyboardZero3,      2}, | 
|---|
| 846 | {Event::KeyboardZero4,      3}, | 
|---|
| 847 | {Event::KeyboardZero5,      4}, | 
|---|
| 848 | {Event::KeyboardZero6,      5}, | 
|---|
| 849 | {Event::KeyboardZero7,      6}, | 
|---|
| 850 | {Event::KeyboardZero8,      7}, | 
|---|
| 851 | {Event::KeyboardZero9,      8}, | 
|---|
| 852 | {Event::KeyboardZeroStar,   9}, | 
|---|
| 853 | {Event::KeyboardZero0,      10}, | 
|---|
| 854 | {Event::KeyboardZeroPound,  11}, | 
|---|
| 855 | }; | 
|---|
| 856 |  | 
|---|
| 857 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 858 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultRightKeypadMapping = { | 
|---|
| 859 | {Event::KeyboardOne1,       0}, | 
|---|
| 860 | {Event::KeyboardOne2,       1}, | 
|---|
| 861 | {Event::KeyboardOne3,       2}, | 
|---|
| 862 | {Event::KeyboardOne4,       3}, | 
|---|
| 863 | {Event::KeyboardOne5,       4}, | 
|---|
| 864 | {Event::KeyboardOne6,       5}, | 
|---|
| 865 | {Event::KeyboardOne7,       6}, | 
|---|
| 866 | {Event::KeyboardOne8,       7}, | 
|---|
| 867 | {Event::KeyboardOne9,       8}, | 
|---|
| 868 | {Event::KeyboardOneStar,    9}, | 
|---|
| 869 | {Event::KeyboardOne0,       10}, | 
|---|
| 870 | {Event::KeyboardOnePound,   11}, | 
|---|
| 871 | }; | 
|---|
| 872 |  | 
|---|
| 873 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 874 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultCommonMapping = { | 
|---|
| 875 | // valid for all joysticks | 
|---|
| 876 | //#if defined(RETRON77) | 
|---|
| 877 | {Event::CmdMenuMode,        2}, | 
|---|
| 878 | {Event::OptionsMenuMode,    3}, | 
|---|
| 879 | {Event::ExitMode,           4}, | 
|---|
| 880 | {Event::RewindPause,        5}, | 
|---|
| 881 | {Event::ConsoleSelect,      7}, | 
|---|
| 882 | {Event::ConsoleReset,       8}, | 
|---|
| 883 | //#endif | 
|---|
| 884 | }; | 
|---|
| 885 |  | 
|---|
| 886 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 
|---|
| 887 | PhysicalJoystickHandler::EventMappingArray PhysicalJoystickHandler::DefaultMenuMapping = { | 
|---|
| 888 | // valid for all joysticks | 
|---|
| 889 | {Event::UISelect,           0}, | 
|---|
| 890 | {Event::UIOK,               1}, | 
|---|
| 891 | {Event::UITabNext,          2}, | 
|---|
| 892 | {Event::UITabPrev,          3}, | 
|---|
| 893 | {Event::UICancel,           5}, | 
|---|
| 894 |  | 
|---|
| 895 | {Event::UINavPrev,          JOY_CTRL_NONE, JoyAxis::X, JoyDir::NEG}, | 
|---|
| 896 | {Event::UITabPrev,          0,             JoyAxis::X, JoyDir::NEG}, | 
|---|
| 897 | {Event::UINavNext,          JOY_CTRL_NONE, JoyAxis::X, JoyDir::POS}, | 
|---|
| 898 | {Event::UITabNext,          0,             JoyAxis::X, JoyDir::POS}, | 
|---|
| 899 | {Event::UIUp,               JOY_CTRL_NONE, JoyAxis::Y, JoyDir::NEG}, | 
|---|
| 900 | {Event::UIDown,             JOY_CTRL_NONE, JoyAxis::Y, JoyDir::POS}, | 
|---|
| 901 |  | 
|---|
| 902 | {Event::UINavPrev,          JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::LEFT}, | 
|---|
| 903 | {Event::UINavNext,          JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::RIGHT}, | 
|---|
| 904 | {Event::UIUp,               JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::UP}, | 
|---|
| 905 | {Event::UIDown,             JOY_CTRL_NONE, JoyAxis::NONE, JoyDir::NONE, 0, JoyHatDir::DOWN}, | 
|---|
| 906 | }; | 
|---|
| 907 |  | 
|---|