VOGONS


First post, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

Hi!

I started investigating why some joysticks seem to have a deadzone in DosBox and others don't. While digging around, I found something that looked wrong to me.

Since I haven't had time to create my own development environment, yet, I thought I'd post what I found and see if anyone cared to give me a sanity check... what am I missing?

I'll apologize in advance if this has been covered somewhere.

In SDL source code 1.2.14, in the src\joystick\win32\SDL_mmjoystick.c file, there's a section of code that initializes the joystick information:

	for ( i = 0; i < MAX_AXES; ++i ) {
if ( (i<2) || (SYS_Joystick[index].wCaps & caps_flags[i-2]) ) {
joystick->hwdata->transaxis[i].offset =
AXIS_MIN - axis_min[i];
joystick->hwdata->transaxis[i].scale =
(float)(AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]);
} else {
joystick->hwdata->transaxis[i].offset = 0;
joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
}
}

Note that the offset is calculated before the scale. When processing joystick inputs, the offset is added to the windows-reported position, and the scale is then applied.

value = (int)(((float)pos[i] + transaxis[i].offset) * transaxis[i].scale);

I think this generates really bad values. Consider a joystick that presents itself at +/- 10,000. SDL converts it all to +/- 32,767. So the above code generates an offset of -22,767 and a scale of 3.28.

Plugging in a real coordinate of 0 should generate an output coordinate of 0. But using the second equation, it's -22,767 * 3.28 or, basically, too large to deal with.

This might explain why games such as Privateer, start with some joysticks stuck in the upper left and why the calibration routine fails.

I believe the scale needs to be applied to the minaxis value before calculating the offset and then the real data value needs to be scaled before applying the offset.

Using those rules, the offset would be 0 and the scale as above. This makes 0 equal to 0.

So, the updated code would be:

	for ( i = 0; i < MAX_AXES; ++i ) {
if ( (i<2) || (SYS_Joystick[index].wCaps & caps_flags[i-2]) ) {
joystick->hwdata->transaxis[i].scale =
(float)(AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]);
joystick->hwdata->transaxis[i].offset =
AXIS_MIN - (axis_min[i] * oystick->hwdata->transaxis[i].scale);
} else {
joystick->hwdata->transaxis[i].offset = 0;
joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
}
}

and

value = (int)(((float)pos[i] * transaxis[i].scale) + transaxis[i].offset);

Comments?

Reply 1 of 8, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

You should report this to the sdl folks at http://forums.sdl.org
I'm not saying that it is misplaced here but it's a problem that should be fixed on the sdl side or if it isn't a problem they should be able to tell you why 😉

Windows 3.1x guide for DOSBox
60 seconds guide to DOSBox
DOSBox SVN snapshot for macOS (10.4-11.x ppc/intel 32/64bit) notarized for gatekeeper

Reply 2 of 8, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

You're absolutely right, and I will. However, you need to go through some hoops to post over there, and I'm on the last one.

I'll post this there as soon as I get authorized. 😀

I just thought some of the guys here might know of this problem, point out my error, or want to try a quick test.

I'm very concerned that I'm missing something because this seems like a largish error.

Reply 3 of 8, by leileilol

User metadata
Rank l33t++
Rank
l33t++

Good luck. SDL is rotting and needs a bunch of vital updates in input for a long time.

apsosig.png
long live PCem

Reply 4 of 8, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Your code definitely makes more sense, thanks for checkint this out! Keep us updated what the SDL people tell.
You may especially want to check if sdl 1.3 has the same code for the joystick.

Reply 5 of 8, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

The same file has the same problems in the 1.3 source tree from early August.

However, it looks like 1.3 is also providing support for the DirectX interface that took over for the legacy windows joystick API. That interface does all the heavy lifting. You provide it the range you want, and the OS does the work.

So, for Win apps where the DX interface is used, the joystick should not have the problems I'm theorizing. I didn't look, though, to see if you have to make changes or if the DX interface is automatically used when available.

EDIT: It looks like it's all how you compile the library. Also, the DX driver claims to not have tested sliders and hats.

I also haven't looked to see if the same problems are in other OS versions.

Reply 6 of 8, by Dominus

User metadata
Rank DOSBox Moderator
Rank
DOSBox Moderator

Sdl forum can be a pain but when you show up there with a real bug and solution they are helpful and do listen 😉
Seems more and more as if they need to do a bugfix release of the 1.2 branch...

Reply 7 of 8, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

Yes... well, as soon as someone gives me posting access, I'll put it up there.

Reply 8 of 8, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

Still nothing on the SDL website.

I made the changes and it had no effect, which I suppose is good. I use Windows 7, and all joysticks that I have go from 0 to 65535, which is the same total range as SDL, so the code that's there will work with it.

However, I think I finally worked out the details on the deadzone for the joysticks. I'll open a new thread on it.