Ignore Down+Left, Down+Right, Up+Left, Up+Right?
Moderator: ZSNES Mods
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
Ignore Down+Left, Down+Right, Up+Left, Up+Right?
If one uses a gamepad with a 8 way d-pad, playing in ZSNES becomes a pain. The reason is that e.g. pressing Downleft on the d-pad results in Left and Down being sent at the same time (or nearly at the same time) and ZSNES treats this as if only Left was pressed (at least with my P1500 gamepad). This makes it really difficult to press Down because if you don't press it 100% perfectly a Left or a Right will be the result. That's worse than a non-perfect Down not being noticed at all because it results in an unwanted move.
The same problem occurs with the other diagonals on the d-pad.
Is it possible to implement a feature which filters out Down+Left, Down+Right, Up+Left and Up+Right signals to solve the problems?
PS: I am aware of the following thread: http://board.zsnes.com/phpBB2/viewtopic ... light=dpad
The same problem occurs with the other diagonals on the d-pad.
Is it possible to implement a feature which filters out Down+Left, Down+Right, Up+Left and Up+Right signals to solve the problems?
PS: I am aware of the following thread: http://board.zsnes.com/phpBB2/viewtopic ... light=dpad
-
- ZSNES Developer
- Posts: 6747
- Joined: Tue Dec 28, 2004 6:47 am
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
-
- ZSNES Developer
- Posts: 6747
- Joined: Tue Dec 28, 2004 6:47 am
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
There is no such thing as an 8-way D-pad. Never has been, never will.
The only trouble you have is because of the shitty design of the D-pad shape itself, failing to register a straight direction press properly. It's not a fault of Zsnes, it's also not an issue with your pad being too "modern" or something. It's just a crappy pad.
The only trouble you have is because of the shitty design of the D-pad shape itself, failing to register a straight direction press properly. It's not a fault of Zsnes, it's also not an issue with your pad being too "modern" or something. It's just a crappy pad.
[size=75][b]Procrastination.[/b]
Hard Work Often Pays Off After Time, but Laziness Always Pays Off Now.[/size]
Hard Work Often Pays Off After Time, but Laziness Always Pays Off Now.[/size]
Hmm.
If the joypad is in analog mode, the code will poll X/Y axis values, between -0x7fff (left for X, top for Y), 0 (center) and 0x8000 (right for X, bottom for Y). A joypad resistance variable basically controls how perfect the presses have to be. Some cheaper joypads will only send -0x7fff or 0x8000 on perfect angle presses, or not at all. Hence being within ~10% of those values is usually a good, loose threshold. More for fighters, less for RPGs.
Digital mode is the same, but gives exact positions from the above (eg either -0x7fff, 0, or 0x8000 -- nothing else in between), and may trigger the same nasty issues with perfect angles and such. However, the thing to note here is that a joypad resistance variable has no effect on digital mode.
There is also the analog mode POV hat. This one gives precise angles in a 360*100 "degree" circle. But even though you're in analog mode, the POV hat is digital. So agian, you could run into a lousy driver.
Anyway, be sure to try both digital and analog modes if you can.
Your best bet is to try out the Windows control panel joypad calibrator. If you are able to make the movements you want, then ZSNES' driver could use some work. If you are not, then throw your gamepad away :(
If the joypad is in analog mode, the code will poll X/Y axis values, between -0x7fff (left for X, top for Y), 0 (center) and 0x8000 (right for X, bottom for Y). A joypad resistance variable basically controls how perfect the presses have to be. Some cheaper joypads will only send -0x7fff or 0x8000 on perfect angle presses, or not at all. Hence being within ~10% of those values is usually a good, loose threshold. More for fighters, less for RPGs.
Digital mode is the same, but gives exact positions from the above (eg either -0x7fff, 0, or 0x8000 -- nothing else in between), and may trigger the same nasty issues with perfect angles and such. However, the thing to note here is that a joypad resistance variable has no effect on digital mode.
There is also the analog mode POV hat. This one gives precise angles in a 360*100 "degree" circle. But even though you're in analog mode, the POV hat is digital. So agian, you could run into a lousy driver.
Anyway, be sure to try both digital and analog modes if you can.
Your best bet is to try out the Windows control panel joypad calibrator. If you are able to make the movements you want, then ZSNES' driver could use some work. If you are not, then throw your gamepad away :(
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
The gamepad works fine in the game controller configuration in the the windows control panel. When I use the analog stick on the game pad I can move the cross around perfectly. If I press a direction on the d-pad it is shown in the field "Cooliehat" (I think it's also called "POV"). For example if I press Downleft a red arrow indicates Downleft on the Cooliehat. It works with all 8 directions of the Cooliehat.byuu wrote:Your best bet is to try out the Windows control panel joypad calibrator. If you are able to make the movements you want, then ZSNES' driver could use some work. If you are not, then throw your gamepad away
However, if I press Downleft in ZSNES this is recognized as Left.
By the way, when setting the controls in ZSNES it doesn't make any difference if I press a certain direction on the d-pad or if I move the analog stick to that direction.
Here is the code that checks the position of the POV hat:If I press a direction on the d-pad it is shown in the field "Cooliehat" (I think it's also called "POV"). For example if I press Downleft a red arrow indicates Downleft on the Cooliehat. It works with all 8 directions of the Cooliehat.
However, if I press Downleft in ZSNES this is recognized as Left.
Code: Select all
https://zsnes.bountysource.com/svn/!source/5159/trunk/src/win/winlink.cpp#2838
Up would be "up-left", "pure up" and "up-right"; Left would be "down-left", "pure left" and "up-left"; etc.
The only idea I have is to maybe divide the POV hat value by 4500 first, just in case the actual values are not exactly multiples of 4500 for some reason. Eg this would trigger a right keypress for 4500 - 13499, rather than for only 4500, 9000 and 13500.
Code: Select all
switch (js[i].rgdwPOV[p])
Code: Select all
switch (js[i].rgdwPOV[p] / 4500 * 4500)
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
No, I wouldn't mind trying one of your programs. Just tell me where to download it and what I have to do.byuu wrote:I don't suppose you'd be interested in trying out one of my software programs to see if the joypad support there works for you? I poll the POV hat the same way, so if it's broken there, I can try fixing it. If that works, we can apply the fix to ZSNES. I understand if you're busy or don't want to.
Ok, I spoke with Red_Wraith to track down the problem.
The POV hat is working as designed, it's just not very sensitive with only nine possible positions available. And the game in question had some of its own control handling problems.
However, there was in fact an issue with the analog joystick on ZSNES' side.
Take a look at line 2722:
There's more code below this to test lZ, rX, rY and rZ. l for left, r for right, obviously. All of it applies ... though I don't know of any controllers with a Z-axis on their analog stick.
Basically, when your analog stick is centered, lX = 0, lY = 0. Left is a negative lX value, up to -32767 when the stick is all the way to the left. Right is positive, up to 32768. Up goes to 32768 and down to -32767.
ZSNES is basically triggering a keypress whenever the axis is even one point off center in any direction. This basically makes the controls way too loose to be enjoyable. And if you have a particularly bad analog connection (one that shakes on its own in joy.cpl), it may even send false keypresses when you don't touch the controller.
There is now zinput.cfg, which contains:
However, it appears this variable is not used at all by the current DirectInput code (maybe it's SDL-specific?)
My recommendation would be to modify the above code as such:
Also, the default value for this is a little tricky ... it appears some controllers have a smaller cap for sensitivity than -32767 to 32768. Red_Wraith's was -16384 to 16383.
I would recommend converting joy_sensitivity to a sensitivity percentage (eg 0 - 100 percent). Then to adjust, do something like this:
To get the correct range, modify line 1113 in this file get the range rather than set it, as setting it apparently isn't doing you any favors when you compare the current position against zero.
A good default resistance that works well both with loose control games such as fighters, and tight control games such as RPGs, is 75%. Meaning, you have to push the axis 75% of the way to the edge to trigger a keypress in the emulator.
The POV hat is working as designed, it's just not very sensitive with only nine possible positions available. And the game in question had some of its own control handling problems.
However, there was in fact an issue with the analog joystick on ZSNES' side.
Code: Select all
https://zsnes.bountysource.com/svn/!source/5159/trunk/src/win/winlink.cpp
Code: Select all
2722 if (!X1Disable[i])
2723 {
2724 if (js[i].lX > 0)
2725 {
2726 keys[0x100 + I * 32 + 0] = 1;
2727 }
2728 }
2729
2730 if (!X2Disable[i])
2731 {
2732 if (js[i].lX < 0)
2733 {
2734 keys[0x100 + I * 32 + 1] = 1;
2735 }
2736 }
2737
2738 if (!Y1Disable[i])
2739 {
2740 if (js[i].lY > 0)
2741 {
2742 keys[0x100 + I * 32 + 2] = 1;
2743 }
2744 }
2745
2746 if (!Y2Disable[i])
2747 {
2748 if (js[i].lY < 0)
2749 {
2750 keys[0x100 + I * 32 + 3] = 1;
2751 }
2752 }
Basically, when your analog stick is centered, lX = 0, lY = 0. Left is a negative lX value, up to -32767 when the stick is all the way to the left. Right is positive, up to 32768. Up goes to 32768 and down to -32767.
ZSNES is basically triggering a keypress whenever the axis is even one point off center in any direction. This basically makes the controls way too loose to be enjoyable. And if you have a particularly bad analog connection (one that shakes on its own in joy.cpl), it may even send false keypresses when you don't touch the controller.
There is now zinput.cfg, which contains:
Code: Select all
; Joystick Sensitivity [0..32767]
; Change this value if you have input issues. Higher value = less sensitive.
; If your joystick is not being read at all, try 128 or other low values.
joy_sensitivity=N
My recommendation would be to modify the above code as such:
Code: Select all
if (js[i].lX > joy_sensitivity)
Code: Select all
if (js[i].lX < -joy_sensitivity)
Code: Select all
if (js[i].lY > joy_sensitivity)
Code: Select all
if (js[i].lY < -joy_sensitivity)
I would recommend converting joy_sensitivity to a sensitivity percentage (eg 0 - 100 percent). Then to adjust, do something like this:
Code: Select all
int range = min(5, max(joy_sensitivity, 95)) / 100 * (axis_range / 2);
A good default resistance that works well both with loose control games such as fighters, and tight control games such as RPGs, is 75%. Meaning, you have to push the axis 75% of the way to the edge to trigger a keypress in the emulator.
Yeah the D-Pad design has always been flawed. You can mess with the .CFG as has been suggested but I'm going to recommend a different controller. I use a PS2 to USB adapter that solves this problem. The Playstation 2 controller has segmented buttons for it's D-Pad so this never really becomes an issue.
Hope this helps.
Hope this helps.
-
- Rookie
- Posts: 16
- Joined: Mon Nov 05, 2007 11:58 pm
Here is what I changed in src\win\winlink.cpp of revision 4538 to fix my analog stick. The forum user joebells asked me about this and here is my quick fix (about line 2919).
Of course byuu's suggestion would be much better, but what I needed was just a quick 'n dirty fix.
Maybe it would also work if "-16384" was used instead of "-16383" (not tested).
We couldn't fix the problem with my D-Pad because it was a hardware problem (sucky D-Pad) but the fix for the analog stick made the analog stick more useable.
Quote about the D-Pad thing (original topic):
Of course byuu's suggestion would be much better, but what I needed was just a quick 'n dirty fix.
Code: Select all
if (!X1Disable[i])
{
if (js[i].lX>16383) keys[0x100 + i * 32 + 0] = 1;
}
if (!X2Disable[i])
{
if (js[i].lX<-16383) keys[0x100 + i * 32 + 1] = 1;
}
if (!Y1Disable[i])
{
if (js[i].lY>16383) keys[0x100 + i * 32 + 2] = 1;
}
if (!Y2Disable[i])
{
if (js[i].lY<-16383) keys[0x100 + i * 32 + 3] = 1;
We couldn't fix the problem with my D-Pad because it was a hardware problem (sucky D-Pad) but the fix for the analog stick made the analog stick more useable.
Quote about the D-Pad thing (original topic):
Red_Wraith wrote:I managed it: The diagonal directions get blocked now.
Unfortunately the gaming experience hasn't become much better using the D-pad. Now at least no unintended directions are triggered anymore but the fact that it is hard to press left, right, up or down without pressing one of the diagonals by accident instead doesn't make the control much more pleasesureful. Thus, I can forget my 8 way D-pad.
Thanks Red_Wraith I had tried putting joy_sensitivity in there but that led to the joy not working at all. I had to go with 8192 for my controller. I tried your middle value but that didn't quite work(it sort of did but not great) then I tried 24575 and that didn't work worth anything. So I went with 8192 and in my limited testing it seems much better. It doesn't register a down press until about half way between left or right and down.
I wish someone would either come up with a replacement dpad setup for the 360 controller, or someone make a bluetooth, ps3 dual shock driver that works under vistax64. I imagine someone will write the second one at some point as the ps3 gets more popular. I can't believe ms screwed up the dpad so badly. There hardware usually isn't too bad.
So thank you Red_Wraith for that, byuu for the initial help, and nach for making zget so easy to use. And of course thanks to all the other zsnes devs for making such a great emulator. Can't wait for 2.0
I wish someone would either come up with a replacement dpad setup for the 360 controller, or someone make a bluetooth, ps3 dual shock driver that works under vistax64. I imagine someone will write the second one at some point as the ps3 gets more popular. I can't believe ms screwed up the dpad so badly. There hardware usually isn't too bad.
So thank you Red_Wraith for that, byuu for the initial help, and nach for making zget so easy to use. And of course thanks to all the other zsnes devs for making such a great emulator. Can't wait for 2.0
-
- ZSNES Developer
- Posts: 6747
- Joined: Tue Dec 28, 2004 6:47 am
The variable is used differently between the SDL and Windows ports. I wasn't aware of this, so it shouldn't be a problem to change.byuu wrote:Ok, I spoke with Red_Wraith to track down the problem.
The POV hat is working as designed, it's just not very sensitive with only nine possible positions available. And the game in question had some of its own control handling problems.
However, there was in fact an issue with the analog joystick on ZSNES' side.
Take a look at line 2722:Code: Select all
https://zsnes.bountysource.com/svn/!source/5159/trunk/src/win/winlink.cpp
There's more code below this to test lZ, rX, rY and rZ. l for left, r for right, obviously. All of it applies ... though I don't know of any controllers with a Z-axis on their analog stick.Code: Select all
2722 if (!X1Disable[i]) 2723 { 2724 if (js[i].lX > 0) 2725 { 2726 keys[0x100 + I * 32 + 0] = 1; 2727 } 2728 } 2729 2730 if (!X2Disable[i]) 2731 { 2732 if (js[i].lX < 0) 2733 { 2734 keys[0x100 + I * 32 + 1] = 1; 2735 } 2736 } 2737 2738 if (!Y1Disable[i]) 2739 { 2740 if (js[i].lY > 0) 2741 { 2742 keys[0x100 + I * 32 + 2] = 1; 2743 } 2744 } 2745 2746 if (!Y2Disable[i]) 2747 { 2748 if (js[i].lY < 0) 2749 { 2750 keys[0x100 + I * 32 + 3] = 1; 2751 } 2752 }
Basically, when your analog stick is centered, lX = 0, lY = 0. Left is a negative lX value, up to -32767 when the stick is all the way to the left. Right is positive, up to 32768. Up goes to 32768 and down to -32767.
ZSNES is basically triggering a keypress whenever the axis is even one point off center in any direction. This basically makes the controls way too loose to be enjoyable. And if you have a particularly bad analog connection (one that shakes on its own in joy.cpl), it may even send false keypresses when you don't touch the controller.
There is now zinput.cfg, which contains:
However, it appears this variable is not used at all by the current DirectInput code (maybe it's SDL-specific?)Code: Select all
; Joystick Sensitivity [0..32767] ; Change this value if you have input issues. Higher value = less sensitive. ; If your joystick is not being read at all, try 128 or other low values. joy_sensitivity=N
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
Yes, the Xbox 360 controller is odd. 99% of gamepads have an axis range of -32768 to +32767 in both directions. The Xbox controller has a range of -16384 to +16383. So you actually picked the perfect value for pointing to the middle of your controller.joebells wrote:I had to go with 8192 for my controller.
50% tolerance is a pretty good compromise between working well in both fighting and role playing games.
Neat, thanks. Let me know if it gives you any trouble. I need to add the axis range detection code myself, as I don't think my code supports the Xbox 360 controller, either.I wasn't aware of this, so it shouldn't be a problem to change.
Well I used perfect when really neither truly supports the 360 controller as it uses Xinput and when using it through direct input you can't use both L and R triggers at the same time. They get treated as one axis with one being negative and one being positive and when you press them both at the same time they cancel each other out. But thats a whole different can of worms. I get by using the L and R bumpers, doesn't feel as nice but it works.
That's odd ...joebells wrote:actually byuu your emulator supported my 360 controller perfectly, joystick and all.
Code: Select all
int resistance = 75; //config::input.axis_resistance;
resistance = max(1, min(99, resistance));
resistance = int32_t(double(resistance) * 32768.0 / 100.0);
int resistance_lo = 0x7fff - resistance;
int resistance_hi = 0x8000 + resistance;
Darn, another API. Eh, I'll look into it when more controllers require it.Well I used perfect when really neither truly supports the 360 controller as it uses Xinput and when using it through direct input you can't use both L and R triggers at the same time.
I have heard it is extremely easy to program. yeah I think the 360 controller is the only one to use it. Still wouldn't be an issue period if microsoft had just put a decent dpad on the 360 controller instead of making us use the analog, and if they had written a proper controller driver so the buttons could be setup and mapped and such instead of trying to push everyone to use Xinput. The 360 controller control panel is a joke.
The controller does feel the best out of all of them though I think.
And yeah when I was using bsnes for a couple of days I had no issues with the analog joystick as my input method. It correctly registerd a right or left press until about 45 degrees up or down instead of until 1 degree up or down like zsnes was.
The controller does feel the best out of all of them though I think.
And yeah when I was using bsnes for a couple of days I had no issues with the analog joystick as my input method. It correctly registerd a right or left press until about 45 degrees up or down instead of until 1 degree up or down like zsnes was.
-
- Buzzkill Gil
- Posts: 4294
- Joined: Wed Jan 12, 2005 7:14 pm
That's because MS is stupid.joebells wrote:Well I used perfect when really neither truly supports the 360 controller as it uses Xinput and when using it through direct input you can't use both L and R triggers at the same time. They get treated as one axis with one being negative and one being positive and when you press them both at the same time they cancel each other out. But thats a whole different can of worms. I get by using the L and R bumpers, doesn't feel as nice but it works.
If I recall, their DirectInput mapping treats L and R as the left and right halves of ONE axis instead of two separate axes.
XBCD will let you reconfigure that.
thats what my post said about the one axisGil_Hamilton wrote:
If I recall, their DirectInput mapping treats L and R as the left and right halves of ONE axis instead of two separate axes.
XBCD will let you reconfigure that.
as far as xbcd no luck for us wireless folk it only works on the wired version. There is a japanese driver someone wrote for the wireless but it only allows one controller per wireless gaming receiver instead of the four normally allowed. The driver is not signed either and under vista sp1 you cannot permanately disable driver signing so f8 every boot or install some funky boot software to do it for you. Other than that though the driver is really nice with lots of options.