Message ID | 1367788390-29835-25-git-send-email-dh.herrmann@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Jiri Kosina |
Headers | show |
On Sun, May 5, 2013 at 5:13 PM, David Herrmann <dh.herrmann@gmail.com> wrote: > The Wii U Pro Controller is a new Nintendo remote device that looks very > similar to the XBox controller. It has nearly the same features and uses > the same protocol as the Wii Remote. As with the classic controller, could this please be mapped to the standard gamepad where possible? Todd. -- Todd Showalter, President, Electron Jump Games, Inc. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Todd On Mon, May 6, 2013 at 2:43 AM, Todd Showalter <todd@electronjump.com> wrote: > On Sun, May 5, 2013 at 5:13 PM, David Herrmann <dh.herrmann@gmail.com> wrote: > >> The Wii U Pro Controller is a new Nintendo remote device that looks very >> similar to the XBox controller. It has nearly the same features and uses >> the same protocol as the Wii Remote. > > As with the classic controller, could this please be mapped to the > standard gamepad where possible? > - left stick to ABS_LX, ABS_LY > - right stick to ABS_RX, ABS_RY These make sense to me, indeed. > - dpad to ABS_DX, ABS_DY These are digital buttons on this gamepad. What's wrong with KEY_{left, right, up, down}? Or I would prefer BTN_{left, right, up, down} instead. > - left trigger to ABS_LTRIG > - right trigger to ABS_RTRIG These are also digital buttons, so what's wrong with BTN_TL/TR? > - x to BTN_NORTH > - a to BTN_EAST > - b to BTN_SOUTH > - y to BTN_WEST These make sense to me. At least keyboards also return the American keycodes instead of trying to guess the label. However, if you want "help texts" in your applications, like "press A to continue", you need a user-space helper library, anyway. Otherwise, you cannot be sure this key is labeled "A" on the current device. That's also the reason why I don't think these mappings really help. > - zl to BTN_LSHOULDER > - zr to BTN_RSHOULDER Again, why not reuse BTN_ZL/ZR? > - plus to BTN_START > - minus to BTN_SELECT > - home to BTN_SYSTEM The other Nintendo drivers return BTN_MODE for "home". Could you explain what's wrong with that? Thanks! David -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, May 6, 2013 at 1:49 AM, David Herrmann <dh.herrmann@gmail.com> wrote: >>> The Wii U Pro Controller is a new Nintendo remote device that looks very >>> similar to the XBox controller. It has nearly the same features and uses >>> the same protocol as the Wii Remote. >> >> As with the classic controller, could this please be mapped to the >> standard gamepad where possible? > >> - left stick to ABS_LX, ABS_LY >> - right stick to ABS_RX, ABS_RY > > These make sense to me, indeed. > >> - dpad to ABS_DX, ABS_DY > > These are digital buttons on this gamepad. What's wrong with > KEY_{left, right, up, down}? Or I would prefer BTN_{left, right, up, > down} instead. Some of the gamepads in evdev currently map their dpads to ABS_HAT0X, ABS_HAT0Y. For the most part I'd be good with switching them to buttons; it's mostly just a matter of choosing a standard and sticking to it. The only argument for making them ABS_ values (other than "some of them already do that") is the Sony controllers; the PS2 and PS3 dpads are actually pressure sensitive, and have an effective resolution double that of the analog sticks even before you take the deadzone into account. The PS* analog sticks are very noisy and need large deadzones, while the dpad pressure sensitivity is quite stable around the center for obvious reasons. >> - left trigger to ABS_LTRIG >> - right trigger to ABS_RTRIG > > These are also digital buttons, so what's wrong with BTN_TL/TR? They're digital on the classic pro, but they're analog on the classic, IIRC. I believe they also have separate "button" values when they bottom out, much like the gamecube controller, but that's beyond the scope of the standard gamepad I'm proposing. >> - x to BTN_NORTH >> - a to BTN_EAST >> - b to BTN_SOUTH >> - y to BTN_WEST > > These make sense to me. At least keyboards also return the American > keycodes instead of trying to guess the label. However, if you want > "help texts" in your applications, like "press A to continue", you > need a user-space helper library, anyway. Otherwise, you cannot be > sure this key is labeled "A" on the current device. > That's also the reason why I don't think these mappings really help. I'd far rather have position-defined buttons and then some sort of mapping I could look up to tell me what the label was on the player's controller. I might want to put help text up, but I definitely want to read the button. Besides, with the standard gamepad I'm proposing you could throw up a diagram of the controller with (for example) an arrow pointing to a blank NORTH button just saying "Menu" or "Battloid Mode" or "Use". Making a game is often about deciding where to spend your limited resources. Money, time, artwork and programming effort you spend customizing the help screens for different controllers is effort not being spent on making the part of the game that people play better. >> - zl to BTN_LSHOULDER >> - zr to BTN_RSHOULDER > > Again, why not reuse BTN_ZL/ZR? Because there are equivalent controls on lots of other gamepads. L1/R1 on sony gamepads, LB/RB on xbox 360, and so forth. Again, it's the position and function that matters, not the arbitrary label on the button. The label on the button is only arguably useful for help text, but there is *so much* variance in labeling between functionally identical hardware that it makes no sense to waste the development effort on custom per-controller help text. >> - plus to BTN_START >> - minus to BTN_SELECT >> - home to BTN_SYSTEM > > The other Nintendo drivers return BTN_MODE for "home". Could you > explain what's wrong with that? It's not essential; we could make the others do BTN_MODE. The idea is that we've got what's essentially a system request button on many gamepads; a button whose job is to bypass the game and bring up the underlying OS. On recent Nintendo controllers (Wii, WiiU) it's the "Home" button. On PS3 it's the playstation logo button. On XBox 360 controllers it's the big glowy X button. All of those are attempting to solve the same problem on their respective consoles; how does one simply get through a full-screen game to talk to the OS when the gamepad is the primary input method and all of its functions have game mappings? The answer in all three cases was to put a system button on the controller that games aren't allowed to map. We're not bound by that, obviously, but in the case of living room gaming PCs where we may well have Linux boxes that are being treated like game consoles much of the time, having a standardized system request button on gamepads that have appropriate hardware is a useful abstraction. I'm suggesting calling it BTN_SYSTEM rather than BTN_MODE because to me BTN_MODE implies different things, but it's admittedly semantics at that point. Todd. -- Todd Showalter, President, Electron Jump Games, Inc. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Todd On Mon, May 6, 2013 at 4:14 PM, Todd Showalter <todd@electronjump.com> wrote: > On Mon, May 6, 2013 at 1:49 AM, David Herrmann <dh.herrmann@gmail.com> wrote: > >>>> The Wii U Pro Controller is a new Nintendo remote device that looks very >>>> similar to the XBox controller. It has nearly the same features and uses >>>> the same protocol as the Wii Remote. >>> >>> As with the classic controller, could this please be mapped to the >>> standard gamepad where possible? >> >>> - left stick to ABS_LX, ABS_LY >>> - right stick to ABS_RX, ABS_RY >> >> These make sense to me, indeed. >> >>> - dpad to ABS_DX, ABS_DY >> >> These are digital buttons on this gamepad. What's wrong with >> KEY_{left, right, up, down}? Or I would prefer BTN_{left, right, up, >> down} instead. > > Some of the gamepads in evdev currently map their dpads to > ABS_HAT0X, ABS_HAT0Y. For the most part I'd be good with switching > them to buttons; it's mostly just a matter of choosing a standard and > sticking to it. The only argument for making them ABS_ values (other > than "some of them already do that") is the Sony controllers; the PS2 > and PS3 dpads are actually pressure sensitive, and have an effective > resolution double that of the analog sticks even before you take the > deadzone into account. The PS* analog sticks are very noisy and need > large deadzones, while the dpad pressure sensitivity is quite stable > around the center for obvious reasons. See below, same reasons apply here. >>> - left trigger to ABS_LTRIG >>> - right trigger to ABS_RTRIG >> >> These are also digital buttons, so what's wrong with BTN_TL/TR? > > They're digital on the classic pro, but they're analog on the > classic, IIRC. I believe they also have separate "button" values when > they bottom out, much like the gamecube controller, but that's beyond > the scope of the standard gamepad I'm proposing. What's the problem with using both, ABS _and_ BTN? I don't think we should do any interpretation in the kernel. Devices that have analog triggers report ABS_XTRIG, devices with digital triggers report BTN_TX. Userspace simply needs to listen for both. And if a device exports both (like the Wii classic controller), they simply export both and userspace chooses whatever it prefers. As long as both ABS_XTRIG and BTN_TX are defined to correspond to the same triggers, I think it's better to use both. Or am I missing something? >>> - x to BTN_NORTH >>> - a to BTN_EAST >>> - b to BTN_SOUTH >>> - y to BTN_WEST >> >> These make sense to me. At least keyboards also return the American >> keycodes instead of trying to guess the label. However, if you want >> "help texts" in your applications, like "press A to continue", you >> need a user-space helper library, anyway. Otherwise, you cannot be >> sure this key is labeled "A" on the current device. >> That's also the reason why I don't think these mappings really help. > > I'd far rather have position-defined buttons and then some sort of > mapping I could look up to tell me what the label was on the player's > controller. I might want to put help text up, but I definitely want > to read the button. Besides, with the standard gamepad I'm proposing > you could throw up a diagram of the controller with (for example) an > arrow pointing to a blank NORTH button just saying "Menu" or "Battloid > Mode" or "Use". > > Making a game is often about deciding where to spend your limited > resources. Money, time, artwork and programming effort you spend > customizing the help screens for different controllers is effort not > being spent on making the part of the game that people play better. As I said before, I don't really care. I will send v2 with a patch that introduces these buttons. Lets see what Dmitry thinks. But we need a user-space library, anyway, to get button-names (as I explained earlier). >>> - zl to BTN_LSHOULDER >>> - zr to BTN_RSHOULDER >> >> Again, why not reuse BTN_ZL/ZR? > > Because there are equivalent controls on lots of other gamepads. > L1/R1 on sony gamepads, LB/RB on xbox 360, and so forth. Again, it's > the position and function that matters, not the arbitrary label on the > button. The label on the button is only arguably useful for help > text, but there is *so much* variance in labeling between functionally > identical hardware that it makes no sense to waste the development > effort on custom per-controller help text. No, I meant what's wrong with re-using BTN_ZX for this purpose? Why introduce new constants? Just say, all new drivers must not use BTN_ZX if it's not a shoulder button. This avoids introducing BTN_XSHOULDER. And btw., there is no BTN_ZL/ZR, I meant BTN_TL2/TR2.. sorry for the confusion, my bad. >>> - plus to BTN_START >>> - minus to BTN_SELECT >>> - home to BTN_SYSTEM >> >> The other Nintendo drivers return BTN_MODE for "home". Could you >> explain what's wrong with that? > > It's not essential; we could make the others do BTN_MODE. The > idea is that we've got what's essentially a system request button on > many gamepads; a button whose job is to bypass the game and bring up > the underlying OS. On recent Nintendo controllers (Wii, WiiU) it's > the "Home" button. On PS3 it's the playstation logo button. On XBox > 360 controllers it's the big glowy X button. > > All of those are attempting to solve the same problem on their > respective consoles; how does one simply get through a full-screen > game to talk to the OS when the gamepad is the primary input method > and all of its functions have game mappings? The answer in all three > cases was to put a system button on the controller that games aren't > allowed to map. > > We're not bound by that, obviously, but in the case of living room > gaming PCs where we may well have Linux boxes that are being treated > like game consoles much of the time, having a standardized system > request button on gamepads that have appropriate hardware is a useful > abstraction. I'm suggesting calling it BTN_SYSTEM rather than > BTN_MODE because to me BTN_MODE implies different things, but it's > admittedly semantics at that point. So how about the following? +static const __u16 wiimod_pro_map[] = { + BTN_EAST, /* WIIMOD_PRO_KEY_A */ + BTN_SOUTH, /* WIIMOD_PRO_KEY_B */ + BTN_NORTH, /* WIIMOD_PRO_KEY_X */ + BTN_WEST, /* WIIMOD_PRO_KEY_Y */ + BTN_START, /* WIIMOD_PRO_KEY_PLUS */ + BTN_SELECT, /* WIIMOD_PRO_KEY_MINUS */ + BTN_MODE, /* WIIMOD_PRO_KEY_HOME */ + BTN_DLEFT, /* WIIMOD_PRO_KEY_LEFT */ + BTN_DRIGHT, /* WIIMOD_PRO_KEY_RIGHT */ + BTN_DUP, /* WIIMOD_PRO_KEY_UP */ + BTN_DDOWN, /* WIIMOD_PRO_KEY_DOWN */ + BTN_TL, /* WIIMOD_PRO_KEY_TL */ + BTN_TR, /* WIIMOD_PRO_KEY_TR */ + BTN_TL2, /* WIIMOD_PRO_KEY_ZL */ + BTN_TR2, /* WIIMOD_PRO_KEY_ZR */ + BTN_THUMBL, /* WIIMOD_PRO_KEY_THUMBL */ + BTN_THUMBR, /* WIIMOD_PRO_KEY_THUMBR */ +}; That would introduce BTN_DLEFT/DRIGHT/DUP/DDOWN for D-Pad buttons and BTN_EAST/SOUTH/NORTH/WEST for action buttons. If everyone is ok with this, I will resend the patches for Pro-Controller after the other parts of this series got applied/acked/nacked/whatever. I will also add some documentation to src/Documentation/input/ and try to see what we can do about the other gamepads. Thanks David -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, May 8, 2013 at 11:33 AM, David Herrmann <dh.herrmann@gmail.com> wrote: >> They're digital on the classic pro, but they're analog on the >> classic, IIRC. I believe they also have separate "button" values when >> they bottom out, much like the gamecube controller, but that's beyond >> the scope of the standard gamepad I'm proposing. > > What's the problem with using both, ABS _and_ BTN? I don't think we > should do any interpretation in the kernel. Devices that have analog > triggers report ABS_XTRIG, devices with digital triggers report > BTN_TX. Userspace simply needs to listen for both. And if a device > exports both (like the Wii classic controller), they simply export > both and userspace chooses whatever it prefers. My opinion is that the kernel is the right place to provide hardware abstraction, and that a standard gamepad is useful the same way a standard mouse, a standard ethernet device or a standard filesystem interface are useful abstractions. That is, I don't want to have to care who made it if I want to make normal use of it. My opinion isn't universally shared, however, so I'm working on a library to sit between the kernel and things that want a standard gamepad. > As long as both ABS_XTRIG and BTN_TX are defined to correspond to the > same triggers, I think it's better to use both. Or am I missing > something? The problem is the specific thing I'm trying to solve with the idea of the standard gamepad. Right now, if I open() something in /dev/input that seems like it ought to be a gamepad, I get a giant unsorted bag of events that are only comprehensible via a priori knowledge. I keep coming back to the ps3 controller because it's the worst offender that I've found; the right stick maps to ABS_Z, ABS_RZ, while the XBox controller right stick maps to ABS_RX, ABS_RY. This is not documented anywhere I've found, and I've no idea what quirks other controllers have in their mappings or whether they are documented or not. What I'm trying to do is make it so that there are five categories of control, in order of usefulness to games: 1) known controls that all sane gamepads will have (left stick, dpad, NSEW buttons...) 2) known controls that most sane gamepads will have (right stick...) 3) known controls that many gamepads have (system/mode button, select button...) 4) common things (accelerometers...) 5) device-specific controls Right now, almost everything is in bucket 5, and from a game development point of view that sucks. The further up the buckets we can move a control, the better. So, the problem that I have with "devices that have analog triggers report XTRIG, devices with digital triggers report TX" is that absent a common mapping I now potentially have to care about the difference when I'm developing a game. It moves these to bucket 3, which means as a developer I likely just don't use them unless my game really needs them. > As I said before, I don't really care. I will send v2 with a patch > that introduces these buttons. Lets see what Dmitry thinks. > > But we need a user-space library, anyway, to get button-names (as I > explained earlier). I'm working on that. :) > No, I meant what's wrong with re-using BTN_ZX for this purpose? Why > introduce new constants? Just say, all new drivers must not use BTN_ZX > if it's not a shoulder button. This avoids introducing BTN_XSHOULDER. I suppose we could just use that. It probably makes more sense to use BTN_TL and BTN_TR, though; the xbox 360 controller maps LB and RB to BTN_TL and BTN_TR, and they're equivalent placement and function. > And btw., there is no BTN_ZL/ZR, I meant BTN_TL2/TR2.. sorry for the > confusion, my bad. Fair enough. > So how about the following? > > +static const __u16 wiimod_pro_map[] = { > + BTN_EAST, /* WIIMOD_PRO_KEY_A */ > + BTN_SOUTH, /* WIIMOD_PRO_KEY_B */ > + BTN_NORTH, /* WIIMOD_PRO_KEY_X */ > + BTN_WEST, /* WIIMOD_PRO_KEY_Y */ > + BTN_START, /* WIIMOD_PRO_KEY_PLUS */ > + BTN_SELECT, /* WIIMOD_PRO_KEY_MINUS */ > + BTN_MODE, /* WIIMOD_PRO_KEY_HOME */ > + BTN_DLEFT, /* WIIMOD_PRO_KEY_LEFT */ > + BTN_DRIGHT, /* WIIMOD_PRO_KEY_RIGHT */ > + BTN_DUP, /* WIIMOD_PRO_KEY_UP */ > + BTN_DDOWN, /* WIIMOD_PRO_KEY_DOWN */ > + BTN_TL, /* WIIMOD_PRO_KEY_TL */ > + BTN_TR, /* WIIMOD_PRO_KEY_TR */ > + BTN_TL2, /* WIIMOD_PRO_KEY_ZL */ > + BTN_TR2, /* WIIMOD_PRO_KEY_ZR */ > + BTN_THUMBL, /* WIIMOD_PRO_KEY_THUMBL */ > + BTN_THUMBR, /* WIIMOD_PRO_KEY_THUMBR */ > +}; > > That would introduce BTN_DLEFT/DRIGHT/DUP/DDOWN for D-Pad buttons and > BTN_EAST/SOUTH/NORTH/WEST for action buttons. That looks fine to me. Todd. -- Todd Showalter, President, Electron Jump Games, Inc. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, May 08, 2013 at 12:40:51PM -0400, Todd Showalter wrote: > On Wed, May 8, 2013 at 11:33 AM, David Herrmann <dh.herrmann@gmail.com> wrote: > > >> They're digital on the classic pro, but they're analog on the > >> classic, IIRC. I believe they also have separate "button" values when > >> they bottom out, much like the gamecube controller, but that's beyond > >> the scope of the standard gamepad I'm proposing. > > > > What's the problem with using both, ABS _and_ BTN? I don't think we > > should do any interpretation in the kernel. Devices that have analog > > triggers report ABS_XTRIG, devices with digital triggers report > > BTN_TX. Userspace simply needs to listen for both. And if a device > > exports both (like the Wii classic controller), they simply export > > both and userspace chooses whatever it prefers. > > My opinion is that the kernel is the right place to provide > hardware abstraction, and that a standard gamepad is useful the same > way a standard mouse, a standard ethernet device or a standard > filesystem interface are useful abstractions. That is, I don't want > to have to care who made it if I want to make normal use of it. My > opinion isn't universally shared, however, so I'm working on a library > to sit between the kernel and things that want a standard gamepad. > > > As long as both ABS_XTRIG and BTN_TX are defined to correspond to the > > same triggers, I think it's better to use both. Or am I missing > > something? > > The problem is the specific thing I'm trying to solve with the > idea of the standard gamepad. Right now, if I open() something in > /dev/input that seems like it ought to be a gamepad, I get a giant > unsorted bag of events that are only comprehensible via a priori > knowledge. I keep coming back to the ps3 controller because it's the > worst offender that I've found; the right stick maps to ABS_Z, ABS_RZ, > while the XBox controller right stick maps to ABS_RX, ABS_RY. This is > not documented anywhere I've found, and I've no idea what quirks other > controllers have in their mappings or whether they are documented or > not. So PS3 gamepad is such a mess because we simply do not have a driver that maps the buttons properly. IIRC it gets bound to a generic HID driver that enumerates absolute axis in a very naive fashion. I think there were some effort in making PS3 work in userspace (in BT mode), but I do not know if it was ever completed. So for PS3 what we need is a HID driver providing proper mapping, nothing more, nothing less. > > What I'm trying to do is make it so that there are five categories > of control, in order of usefulness to games: > > 1) known controls that all sane gamepads will have (left stick, dpad, > NSEW buttons...) > 2) known controls that most sane gamepads will have (right stick...) > 3) known controls that many gamepads have (system/mode button, select button...) > 4) common things (accelerometers...) > 5) device-specific controls > > Right now, almost everything is in bucket 5, and from a game > development point of view that sucks. The further up the buckets we > can move a control, the better. > > So, the problem that I have with "devices that have analog > triggers report XTRIG, devices with digital triggers report TX" is > that absent a common mapping I now potentially have to care about the > difference when I'm developing a game. It moves these to bucket 3, > which means as a developer I likely just don't use them unless my game > really needs them. Or you have your library that provides ABS->BTN translation. You can even have your API structured such that consumer provides list of events it is interested in and the library tries to synthesize missing events if it can. > > > As I said before, I don't really care. I will send v2 with a patch > > that introduces these buttons. Lets see what Dmitry thinks. So we already have: #define BTN_A 0x130 #define BTN_B 0x131 #define BTN_C 0x132 #define BTN_X 0x133 #define BTN_Y 0x134 #define BTN_Z 0x135 #define BTN_TL 0x136 #define BTN_TR 0x137 #define BTN_TL2 0x138 #define BTN_TR2 0x139 #define BTN_SELECT 0x13a #define BTN_START 0x13b #define BTN_MODE 0x13c #define BTN_THUMBL 0x13d #define BTN_THUMBR 0x13e So if we really want to have BTN_NORTH, etc, we want to alias existing ones.
On Wed, May 8, 2013 at 1:05 PM, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote: > Or you have your library that provides ABS->BTN translation. > > You can even have your API structured such that consumer provides list > of events it is interested in and the library tries to synthesize > missing events if it can. That's in the plans. > So we already have: > > #define BTN_A 0x130 > #define BTN_B 0x131 > #define BTN_C 0x132 > #define BTN_X 0x133 > #define BTN_Y 0x134 > #define BTN_Z 0x135 > #define BTN_TL 0x136 > #define BTN_TR 0x137 > #define BTN_TL2 0x138 > #define BTN_TR2 0x139 > #define BTN_SELECT 0x13a > #define BTN_START 0x13b > #define BTN_MODE 0x13c > #define BTN_THUMBL 0x13d > #define BTN_THUMBR 0x13e > > So if we really want to have BTN_NORTH, etc, we want to alias existing > ones. The problem is that the alias differs with hardware. BTN_A would be: - BTN_SOUTH on xbox gamepads - BTN_EAST on nintendo gamepads and ouya Nintendo is: A -> WEST B -> SOUTH X -> NORTH Y -> EAST While Microsoft is: A -> SOUTH B -> EAST X -> WEST Y -> NORTH They're mirror images of each other. So just aliasing is going to break something. Todd. -- Todd Showalter, President, Electron Jump Games, Inc. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Todd On Wed, May 8, 2013 at 7:20 PM, Todd Showalter <todd@electronjump.com> wrote: > On Wed, May 8, 2013 at 1:05 PM, Dmitry Torokhov > <dmitry.torokhov@gmail.com> wrote: > >> Or you have your library that provides ABS->BTN translation. >> >> You can even have your API structured such that consumer provides list >> of events it is interested in and the library tries to synthesize >> missing events if it can. > > That's in the plans. > >> So we already have: >> >> #define BTN_A 0x130 >> #define BTN_B 0x131 >> #define BTN_C 0x132 >> #define BTN_X 0x133 >> #define BTN_Y 0x134 >> #define BTN_Z 0x135 >> #define BTN_TL 0x136 >> #define BTN_TR 0x137 >> #define BTN_TL2 0x138 >> #define BTN_TR2 0x139 >> #define BTN_SELECT 0x13a >> #define BTN_START 0x13b >> #define BTN_MODE 0x13c >> #define BTN_THUMBL 0x13d >> #define BTN_THUMBR 0x13e >> >> So if we really want to have BTN_NORTH, etc, we want to alias existing >> ones. > > The problem is that the alias differs with hardware. BTN_A would be: > > - BTN_SOUTH on xbox gamepads > - BTN_EAST on nintendo gamepads and ouya > > Nintendo is: > > A -> WEST > B -> SOUTH > X -> NORTH > Y -> EAST > > While Microsoft is: > > A -> SOUTH > B -> EAST > X -> WEST > Y -> NORTH > > They're mirror images of each other. So just aliasing is going to > break something. No. Just ignore BTN_A/B/X/Y, use BTN_EAST/WEST/NORTH/SOUTH instead. Only for legacy gamepads with wrong mappings you might reuse these. So we basically overwrite the old names. So you no longer care for BTN_A/B/X/Y and they will no longer represent the labels of the buttons, but instead the location. Regards David -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, May 08, 2013 at 01:20:58PM -0400, Todd Showalter wrote: > On Wed, May 8, 2013 at 1:05 PM, Dmitry Torokhov > <dmitry.torokhov@gmail.com> wrote: > > > Or you have your library that provides ABS->BTN translation. > > > > You can even have your API structured such that consumer provides list > > of events it is interested in and the library tries to synthesize > > missing events if it can. > > That's in the plans. > > > So we already have: > > > > #define BTN_A 0x130 > > #define BTN_B 0x131 > > #define BTN_C 0x132 > > #define BTN_X 0x133 > > #define BTN_Y 0x134 > > #define BTN_Z 0x135 > > #define BTN_TL 0x136 > > #define BTN_TR 0x137 > > #define BTN_TL2 0x138 > > #define BTN_TR2 0x139 > > #define BTN_SELECT 0x13a > > #define BTN_START 0x13b > > #define BTN_MODE 0x13c > > #define BTN_THUMBL 0x13d > > #define BTN_THUMBR 0x13e > > > > So if we really want to have BTN_NORTH, etc, we want to alias existing > > ones. > > The problem is that the alias differs with hardware. BTN_A would be: > > - BTN_SOUTH on xbox gamepads > - BTN_EAST on nintendo gamepads and ouya > > Nintendo is: > > A -> WEST > B -> SOUTH > X -> NORTH > Y -> EAST > > While Microsoft is: > > A -> SOUTH > B -> EAST > X -> WEST > Y -> NORTH > > They're mirror images of each other. So just aliasing is going to > break something. We should take existing in-kernel mapping (that would be XBOX and other less advanced gamepads in drivers/input/joystick), alias NORTH/SOUTH/EAST/WEST accordingly, have new users use NSEW button definitions. Thanks.
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 3e69656..279a07d 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -452,6 +452,8 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem) return WIIMOTE_EXT_CLASSIC_CONTROLLER; if (rmem[4] == 0x04 && rmem[5] == 0x02) return WIIMOTE_EXT_BALANCE_BOARD; + if (rmem[4] == 0x01 && rmem[5] == 0x20) + return WIIMOTE_EXT_PRO_CONTROLLER; return WIIMOTE_EXT_UNKNOWN; } @@ -601,6 +603,15 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = { WIIMOD_NO_MP, WIIMOD_NULL, }, + [WIIMOTE_DEV_PRO_CONTROLLER] = (const __u8[]) { + WIIMOD_BATTERY, + WIIMOD_LED1, + WIIMOD_LED2, + WIIMOD_LED3, + WIIMOD_LED4, + WIIMOD_NO_MP, + WIIMOD_NULL, + }, }; static void wiimote_modules_load(struct wiimote_data *wdata, @@ -785,6 +796,7 @@ static const char *wiimote_devtype_names[WIIMOTE_DEV_NUM] = { [WIIMOTE_DEV_GEN10] = "Nintendo Wii Remote (Gen 1)", [WIIMOTE_DEV_GEN20] = "Nintendo Wii Remote Plus (Gen 2)", [WIIMOTE_DEV_BALANCE_BOARD] = "Nintendo Wii Balance Board", + [WIIMOTE_DEV_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller", }; /* Try to guess the device type based on all collected information. We @@ -805,6 +817,9 @@ static void wiimote_init_set_type(struct wiimote_data *wdata, if (exttype == WIIMOTE_EXT_BALANCE_BOARD) { devtype = WIIMOTE_DEV_BALANCE_BOARD; goto done; + } else if (exttype == WIIMOTE_EXT_PRO_CONTROLLER) { + devtype = WIIMOTE_DEV_PRO_CONTROLLER; + goto done; } if (!strcmp(name, "Nintendo RVL-CNT-01")) { @@ -816,6 +831,9 @@ static void wiimote_init_set_type(struct wiimote_data *wdata, } else if (!strcmp(name, "Nintendo RVL-WBC-01")) { devtype = WIIMOTE_DEV_BALANCE_BOARD; goto done; + } else if (!strcmp(name, "Nintendo RVL-CNT-01-UC")) { + devtype = WIIMOTE_DEV_PRO_CONTROLLER; + goto done; } if (vendor == USB_VENDOR_ID_NINTENDO) { @@ -1058,6 +1076,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = { [WIIMOTE_EXT_NUNCHUK] = "Nintendo Wii Nunchuk", [WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller", [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board", + [WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller", }; /* @@ -1634,6 +1653,8 @@ static ssize_t wiimote_ext_show(struct device *dev, return sprintf(buf, "classic\n"); case WIIMOTE_EXT_BALANCE_BOARD: return sprintf(buf, "balanceboard\n"); + case WIIMOTE_EXT_PRO_CONTROLLER: + return sprintf(buf, "procontroller\n"); case WIIMOTE_EXT_UNKNOWN: /* fallthrough */ default: @@ -1680,6 +1701,8 @@ static ssize_t wiimote_dev_show(struct device *dev, return sprintf(buf, "gen20\n"); case WIIMOTE_DEV_BALANCE_BOARD: return sprintf(buf, "balanceboard\n"); + case WIIMOTE_DEV_PRO_CONTROLLER: + return sprintf(buf, "procontroller\n"); case WIIMOTE_DEV_PENDING: return sprintf(buf, "pending\n"); case WIIMOTE_DEV_UNKNOWN: diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index e2afe06..ab25a64 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c @@ -1540,6 +1540,300 @@ static const struct wiimod_ops wiimod_bboard = { }; /* + * Pro Controller + * Released with the Wii U was the Nintendo Wii U Pro Controller. It does not + * work together with the classic Wii, but only with the new Wii U. However, it + * uses the same protocol and provides a builtin "classic controller pro" + * extension, few standard buttons, a rumble motor, 4 LEDs and a battery. + * We provide all these via a standard extension device as the device doesn't + * feature an extension port. + */ + +enum wiimod_pro_keys { + WIIMOD_PRO_KEY_A, + WIIMOD_PRO_KEY_B, + WIIMOD_PRO_KEY_X, + WIIMOD_PRO_KEY_Y, + WIIMOD_PRO_KEY_PLUS, + WIIMOD_PRO_KEY_MINUS, + WIIMOD_PRO_KEY_HOME, + WIIMOD_PRO_KEY_LEFT, + WIIMOD_PRO_KEY_RIGHT, + WIIMOD_PRO_KEY_UP, + WIIMOD_PRO_KEY_DOWN, + WIIMOD_PRO_KEY_TL, + WIIMOD_PRO_KEY_TR, + WIIMOD_PRO_KEY_ZL, + WIIMOD_PRO_KEY_ZR, + WIIMOD_PRO_KEY_THUMBL, + WIIMOD_PRO_KEY_THUMBR, + WIIMOD_PRO_KEY_NUM, +}; + +static const __u16 wiimod_pro_map[] = { + BTN_A, /* WIIMOD_PRO_KEY_A */ + BTN_B, /* WIIMOD_PRO_KEY_B */ + BTN_X, /* WIIMOD_PRO_KEY_X */ + BTN_Y, /* WIIMOD_PRO_KEY_Y */ + BTN_START, /* WIIMOD_PRO_KEY_PLUS */ + BTN_SELECT, /* WIIMOD_PRO_KEY_MINUS */ + BTN_MODE, /* WIIMOD_PRO_KEY_HOME */ + KEY_LEFT, /* WIIMOD_PRO_KEY_LEFT */ + KEY_RIGHT, /* WIIMOD_PRO_KEY_RIGHT */ + KEY_UP, /* WIIMOD_PRO_KEY_UP */ + KEY_DOWN, /* WIIMOD_PRO_KEY_DOWN */ + BTN_TL, /* WIIMOD_PRO_KEY_TL */ + BTN_TR, /* WIIMOD_PRO_KEY_TR */ + BTN_TL2, /* WIIMOD_PRO_KEY_ZL */ + BTN_TR2, /* WIIMOD_PRO_KEY_ZR */ + BTN_THUMBL, /* WIIMOD_PRO_KEY_THUMBL */ + BTN_THUMBR, /* WIIMOD_PRO_KEY_THUMBR */ +}; + +static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext) +{ + __s16 rx, ry, lx, ly; + + /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | + * -----+-----+-----+-----+-----+-----+-----+-----+-----+ + * 1 | LX <7:0> | + * -----+-----------------------+-----------------------+ + * 2 | 0 0 0 0 | LX <11:8> | + * -----+-----------------------+-----------------------+ + * 3 | RX <7:0> | + * -----+-----------------------+-----------------------+ + * 4 | 0 0 0 0 | RX <11:8> | + * -----+-----------------------+-----------------------+ + * 5 | LY <7:0> | + * -----+-----------------------+-----------------------+ + * 6 | 0 0 0 0 | LY <11:8> | + * -----+-----------------------+-----------------------+ + * 7 | RY <7:0> | + * -----+-----------------------+-----------------------+ + * 8 | 0 0 0 0 | RY <11:8> | + * -----+-----+-----+-----+-----+-----+-----+-----+-----+ + * 9 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | + * -----+-----+-----+-----+-----+-----+-----+-----+-----+ + * 10 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | + * -----+-----+-----+-----+-----+-----+-----+-----+-----+ + * 11 | 1 | BATTERY | USB |CHARG|LTHUM|RTHUM| + * -----+-----+-----------------+-----------+-----+-----+ + * All buttons are low-active (0 if pressed) + * RX and RY are right analog stick + * LX and LY are left analog stick + * BLT is left trigger, BRT is right trigger. + * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons + * BZL is left Z button and BZR is right Z button + * B-, BH, B+ are +, HOME and - buttons + * BB, BY, BA, BX are A, B, X, Y buttons + * + * Bits marked as 0/1 are unknown and never changed during tests. + * + * Not entirely verified: + * CHARG: 1 if uncharging, 0 if charging + * USB: 1 if not connected, 0 if connected via USB + * BATTERY: battery capacity from 000 (empty) to 100 (full) + */ + + lx = (ext[0] & 0xff) | ((ext[1] & 0x0f) << 8); + rx = (ext[2] & 0xff) | ((ext[3] & 0x0f) << 8); + ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8); + ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8); + + input_report_abs(wdata->extension.input, ABS_HAT0X, lx - 0x800); + input_report_abs(wdata->extension.input, ABS_HAT0Y, ly - 0x800); + input_report_abs(wdata->extension.input, ABS_HAT1X, rx - 0x800); + input_report_abs(wdata->extension.input, ABS_HAT1Y, ry - 0x800); + + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT], + !(ext[8] & 0x80)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_DOWN], + !(ext[8] & 0x40)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_TL], + !(ext[8] & 0x20)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_MINUS], + !(ext[8] & 0x10)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_HOME], + !(ext[8] & 0x08)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_PLUS], + !(ext[8] & 0x04)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_TR], + !(ext[8] & 0x02)); + + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_ZL], + !(ext[9] & 0x80)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_B], + !(ext[9] & 0x40)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_Y], + !(ext[9] & 0x20)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_A], + !(ext[9] & 0x10)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_X], + !(ext[9] & 0x08)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_ZR], + !(ext[9] & 0x04)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_LEFT], + !(ext[9] & 0x02)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_UP], + !(ext[9] & 0x01)); + + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_THUMBL], + !(ext[10] & 0x02)); + input_report_key(wdata->extension.input, + wiimod_pro_map[WIIMOD_PRO_KEY_THUMBR], + !(ext[10] & 0x01)); + + input_sync(wdata->extension.input); +} + +static int wiimod_pro_open(struct input_dev *dev) +{ + struct wiimote_data *wdata = input_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&wdata->state.lock, flags); + wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; + wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); + spin_unlock_irqrestore(&wdata->state.lock, flags); + + return 0; +} + +static void wiimod_pro_close(struct input_dev *dev) +{ + struct wiimote_data *wdata = input_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&wdata->state.lock, flags); + wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; + wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); + spin_unlock_irqrestore(&wdata->state.lock, flags); +} + +static int wiimod_pro_play(struct input_dev *dev, void *data, + struct ff_effect *eff) +{ + struct wiimote_data *wdata = input_get_drvdata(dev); + __u8 value; + unsigned long flags; + + /* + * The wiimote supports only a single rumble motor so if any magnitude + * is set to non-zero then we start the rumble motor. If both are set to + * zero, we stop the rumble motor. + */ + + if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) + value = 1; + else + value = 0; + + spin_lock_irqsave(&wdata->state.lock, flags); + wiiproto_req_rumble(wdata, value); + spin_unlock_irqrestore(&wdata->state.lock, flags); + + return 0; +} + +static int wiimod_pro_probe(const struct wiimod_ops *ops, + struct wiimote_data *wdata) +{ + int ret, i; + + wdata->extension.input = input_allocate_device(); + if (!wdata->extension.input) + return -ENOMEM; + + set_bit(FF_RUMBLE, wdata->extension.input->ffbit); + input_set_drvdata(wdata->extension.input, wdata); + + if (input_ff_create_memless(wdata->extension.input, NULL, + wiimod_pro_play)) { + ret = -ENOMEM; + goto err_free; + } + + wdata->extension.input->open = wiimod_pro_open; + wdata->extension.input->close = wiimod_pro_close; + wdata->extension.input->dev.parent = &wdata->hdev->dev; + wdata->extension.input->id.bustype = wdata->hdev->bus; + wdata->extension.input->id.vendor = wdata->hdev->vendor; + wdata->extension.input->id.product = wdata->hdev->product; + wdata->extension.input->id.version = wdata->hdev->version; + wdata->extension.input->name = WIIMOTE_NAME " Pro Controller"; + + set_bit(EV_KEY, wdata->extension.input->evbit); + for (i = 0; i < WIIMOD_PRO_KEY_NUM; ++i) + set_bit(wiimod_pro_map[i], + wdata->extension.input->keybit); + + set_bit(EV_ABS, wdata->extension.input->evbit); + set_bit(ABS_HAT0X, wdata->extension.input->absbit); + set_bit(ABS_HAT0Y, wdata->extension.input->absbit); + set_bit(ABS_HAT1X, wdata->extension.input->absbit); + set_bit(ABS_HAT1Y, wdata->extension.input->absbit); + input_set_abs_params(wdata->extension.input, + ABS_HAT0X, -0x800, 0x800, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_HAT0Y, -0x800, 0x800, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_HAT1X, -0x800, 0x800, 2, 4); + input_set_abs_params(wdata->extension.input, + ABS_HAT1Y, -0x800, 0x800, 2, 4); + + ret = input_register_device(wdata->extension.input); + if (ret) + goto err_free; + + return 0; + +err_free: + input_free_device(wdata->extension.input); + wdata->extension.input = NULL; + return ret; +} + +static void wiimod_pro_remove(const struct wiimod_ops *ops, + struct wiimote_data *wdata) +{ + unsigned long flags; + + if (!wdata->extension.input) + return; + + spin_lock_irqsave(&wdata->state.lock, flags); + wiiproto_req_rumble(wdata, 0); + spin_unlock_irqrestore(&wdata->state.lock, flags); + + input_unregister_device(wdata->extension.input); + wdata->extension.input = NULL; +} + +static const struct wiimod_ops wiimod_pro = { + .flags = WIIMOD_FLAG_EXT16, + .arg = 0, + .probe = wiimod_pro_probe, + .remove = wiimod_pro_remove, + .in_ext = wiimod_pro_in_ext, +}; + +/* * Builtin Motion Plus * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which * disables polling for Motion-Plus. This should be set only for devices which @@ -1788,4 +2082,5 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { [WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk, [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic, [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard, + [WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro, }; diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 5cf8bcb..f1474f3 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h @@ -77,6 +77,7 @@ enum wiimote_devtype { WIIMOTE_DEV_GEN10, WIIMOTE_DEV_GEN20, WIIMOTE_DEV_BALANCE_BOARD, + WIIMOTE_DEV_PRO_CONTROLLER, WIIMOTE_DEV_NUM, }; @@ -86,6 +87,7 @@ enum wiimote_exttype { WIIMOTE_EXT_NUNCHUK, WIIMOTE_EXT_CLASSIC_CONTROLLER, WIIMOTE_EXT_BALANCE_BOARD, + WIIMOTE_EXT_PRO_CONTROLLER, WIIMOTE_EXT_NUM, };
The Wii U Pro Controller is a new Nintendo remote device that looks very similar to the XBox controller. It has nearly the same features and uses the same protocol as the Wii Remote. We add a new wiimote extension device so the Pro Controller is properly detected and supported. The device reports MP support, which is odd and I couldn't get it working, yet. Hence, we disable MP registers for now. Further investigation is needed to see what extra capabilities are provided. There are some other unknown bits in the extension reports that I couldn't figure out what they do. You can use hidraw to access these if you're interested. We might want to hook up the "charging" and "USB" bits to the battery device so user-space can query whether it is currently charged via USB. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> --- drivers/hid/hid-wiimote-core.c | 23 +++ drivers/hid/hid-wiimote-modules.c | 295 ++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-wiimote.h | 2 + 3 files changed, 320 insertions(+)