MAMEWorld >> Programming
View all threads Index   Threaded Mode Threaded  

Pages: 1

byuu
MAME Fan
Reged: 03/17/06
Posts: 41
Send PM


Capturing analog button input on Windows *DELETED*
#185850 - 03/24/09 01:32 AM


Post deleted by byuu



byuu
MAME Fan
Reged: 03/17/06
Posts: 41
Send PM


EDIT: I think I understand what's going on now. new [Re: byuu]
#185878 - 03/24/09 01:51 PM


Another copy-paste because I'm lazy, sorry.

-----

Yesterday I requested assistance for a joypad axis mapping issue, but I believe I understand the problem and have the proper solution now.

Background: new joypads have pressure-sensitive buttons; rather than simply being on or off, the joypad reports how far down a button is pressed. Given how new this is, various input APIs and indeed the USB HID itself do not directly support these new buttons. Instead, they are mapped as axes, which are basically bi-directional sticks. Unlike buttons that start off fully depressed, sticks start off centered.

A problem arises in trying to tell them apart: at application startup, polling the joypad state returns zero, or centered, for all axes. Even buttons that are fully depressed. It isn't until a button is pressed or an axis is moved that the actual state of the pressure-sensitive buttons are read correctly.

I believe the reason for this is due to the design of the USB HID. Rather than having an interface to poll the current state of joypads, it instead sends messages with the state of the entire device whenever the state is changed (eg a button is pressed.) On Windows, this would correspond to the raw input WM_INPUT window message. DirectInput appears to buffer this information on an app-by-app basis. On Linux, this data seems to be cached by the input driver globally; so each joypad needs only one message sent per system reset.

So what happens when you first start an application? It can't possibly know the state until a message is sent, so it feeds back what you would expect: unpressed buttons and centered (zero-positioned) axes.

Further, we can't simply check the axis states after the first button press, because the user may decide to move an axis or press an analog button first. Since we can't tell which object state changed, we may end up detecting an analog button as a stick or vice versa.

My solution was to display a popup the first time the user attempts to map a joypad axis. It asks the user not to press any buttons, and to leave all axes alone; and then to press okay. After hitting okay, I then query the states of each axis. To prevent needing to calibrate the joypad every time the application is run, and to avoid issues with swapping out joypads, I save the type of input by appending it onto the assignment name for a given ID, eg "joypad01.axis03::trigger" states that axis03 is a pressure-sensitive button (or trigger), whereas "joypad01.axis03::lo" indicates an axis that is triggered by moving a given axis left or up (depending on direction.) Therefore, on future startups, the type of axis will already be known without having to prompt the user to calibrate the joypad again.

-----

Of course my theory could be wrong. If anyone's certain that it is, I'd certainly like to know. But my solution works regardless, so all is well

And hopefully the above info will be helpful to any emu authors here writing joypad polling code.



Dullaron
Diablo III - Dunard #1884
Reged: 07/22/05
Posts: 6125
Loc: Fort Worth, Tx
Send PM


Did someone talk to you? new [Re: byuu]
#185984 - 03/25/09 07:11 PM


Just wondering.



W11 Home 64-bit + Nobara OS / AMD Radeon RX 5700 XT / AMD Ryzen 7 3700X 8-Core 3.59 GHz / RAM 64 GB



StilettoAdministrator
They're always after me Lucky ROMS!
Reged: 03/07/04
Posts: 6472
Send PM


Re: Did someone talk to you? new [Re: Dullaron]
#186012 - 03/26/09 03:15 AM


> Just wondering.

I sent an email to Derrick (MAMEDEV's DirectInput fanboy) but by the time he replied to me, byuu had solved it himself.

- Stiletto



R. Belmont
Cuckoo for IGAvania
Reged: 09/21/03
Posts: 9716
Loc: ECV-197 The Orville
Send PM


Re: EDIT: I think I understand what's going on now. new [Re: byuu]
#186374 - 03/30/09 03:47 PM


That's probably correct, yeah. Related: I've heard you can't properly read the X360 pad in Windows via DirectInput - they force you to use XInput instead. Which reminds me, I need to get XAudio2 working before DSound is deprecated further



byuu
MAME Fan
Reged: 03/17/06
Posts: 41
Send PM


Re: EDIT: I think I understand what's going on now. new [Re: R. Belmont]
#186667 - 04/02/09 04:27 AM


Funny, I just added support for XInput the other day.

An Xbox 360 controller will work, but with one exception: the left and right triggers (pressure-sensitive analog buttons) are mapped as one single axis. You can map low and high as their own buttons, but if the user tries pressing both at the same time, they cancel each other out.

It's an artificial limitation, as other controllers map each analog button as its own axis just fine.

Luckily the code's really easy, just one function call to XInputGetState() -- no need for initialization / resource freeing, and the return code tells you if the device is connected.

The downside is DirectInput makes it really tough to identify the controllers. I use RawInput's device name to do it, but there's a few other methods.

Further, it requires xinput1_3.dll; which doesn't ship with XP 2k5 or Vista SP0.

And I was just thinking about writing an XAudio 2 driver, heh. It at least shares the WAVEFORMATEX struct, but otherwise it looks quite different from literally everything else in DirectX.

Should share code or something for that



uRebelScum
Regular
Reged: 09/21/03
Posts: 538
Loc: California
Send PM


Re: EDIT: I think I understand what's going on now. new [Re: byuu]
#186724 - 04/02/09 08:43 PM


> > ... you can't properly read the X360
> > pad in Windows via DirectInput - they force you to use XInput instead....
>
> ...An Xbox 360 controller will work, but with one exception: the left and right triggers
> (pressure-sensitive analog buttons) are mapped as one single axis. You can map low
> and high as their own buttons, but if the user tries pressing both at the same time,
> they cancel each other out.
>
> It's an artificial limitation, as other controllers map each analog button as its own
> axis just fine....

Yup, it's a limitation due to microsoft's driver, not of XInput vs directInput. If the user uses redclOud's XBCD driver instead, directInput can see the triggers as separate axes. QED

Why MS is limiting the driver and saying it's a limit of directInput is up for argument. (Over simplification, promotion of XInput/XBox developement, warning of depreciation of directInput, laziness, etc.)



Robin
www.urebelscum.speedhost.com/ or
www.angelfire.com/retro/u_rebelscum or
rain.prohosting.com/urebel



byuu
MAME Fan
Reged: 03/17/06
Posts: 41
Send PM


Re: EDIT: I think I understand what's going on now. new [Re: uRebelScum]
#186739 - 04/02/09 11:59 PM


I understand the motivation for creating this driver, but if it:
a) doesn't change the device name to not look like an Xbox 360 controller, or
b) doesn't support the XInput API

... then it is an absolutely terrible idea. Any application that properly supports XInput per MSDN's method (including my own) will end up not supporting these controllers at all.

With Windows 7, and likely earlier versions, you literally just plug the Xbox 360 controller in. It detects it, connects to Windows Update, downloads the device drivers and installs them.

Asking an end-user to install a third-party driver because you don't wish to support XInput is bad. Yes, it's BS that Microsoft makes us support a new API for a single controller; but two wrongs do not make a right.


Pages: 1

MAMEWorld >> Programming
View all threads Index   Threaded Mode Threaded  

Extra information Permissions
Moderator:  Pi 
0 registered and 20 anonymous users are browsing this forum.
You cannot start new topics
You cannot reply to topics
HTML is enabled
UBBCode is enabled
Thread views: 5303