VOGONS


First post, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

I've seen a lot of complaints about a large deadzone when playing some games, such as Privateer and Wing Commander. Those complaints tend to be worse when using some of the Saitek (e.g. x52) sticks and better when they're using a Sidewinder Force Feedback. That is, the actual joystick seems to affect it.

After a lot of playing around, I've discovered a number of things. In no particular order:

  • Doubling the OHMS value in the Joystick code eliminates the deadzone and seems to make Wing Commander quite playable on my machine. I suspect it has to do with the relative speed of how fast my system is vs. what I force DosBox to run at. I think, perhaps, providing a sensitivity setting on the joystick will allow people to tweak it. Or, perhaps, there is a simulated I/O delay for reading port 201 which isn't present in real life which makes reading the joystick loop take fewer iterations.
  • The SideWinder FF 2 joystick appears to be slightly non-linear in terms of delta change based on stick movement. I seem to have a higher rate of change near the center and a lower rate near the edges. This would tend to provide a higher change for a smaller movement, providing a smaller deadzone and better responsiveness. The Saitec x52 appears to be much more linear.
  • The method for emulating port 201 seems to be inverted from the official game port specification. That is, normally you write to the port, which sends all the axis bits to 0, then you poll it and time until they come back to a 1. However, the code DB uses inverts that. It sets the bit to 1 and changes it to 0 when the timer expires. Frankly, I don't know how WC work with it that way, but it does. Maybe some ports are one way and some another?
  • When I 'fixed' the above, my axis were suddenly inverted! I don't understand why that would be, and it make me doubt the fix. Again, it seems to work regardless so this is more for information and consideration.

So... in summary, I think adding a sensitivity option to the joystick would help solve this a lot. I'll work on that tomorrow.

Reply 1 of 10, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

Wow.. talk about needing to check sources. I found two very nice pages (though one looked like it was based on the other) that specifically said that the joystick axis bit goes to zero when tagged then back to one when finished.

But, I finally found some online source code for real apps, and it's the opposite. So, please ignore the last two bullets from above.

But, I have one new item... the INT15 routine for handling the BIOS version of reading the joystick only generates values from 1 to 256, while the actual BIOS call should return 0 to 511.

Read Joystick Positions : int 15h
Call with: AH = 84 hex
DX = 0001 hex
Returns: AX = Joystick A, axis X (0-511, 0 if timed-out)
BX = Joystick A, axis Y (0-511, 0 if timed-out)
CX = Joystick B, axis X (0-511, 0 if timed-out)
DX = Joystick B, axis Y (0-511, 0 if timed-out)

All of my sources agree on that. Anyone know why it was set to 1-256?

Reply 3 of 10, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

That would make sense, since the BIOS sits in a loop and then converts that value into a number. So faster machines take fewer loops, but the code stays the same.

So, 256 was used as a compromise?

Reply 10 of 10, by Kazoo

User metadata
Rank Newbie
Rank
Newbie

Thanks! That was an interesting read.

I think I had already worked out most of what was discussed there. I found the final post interesting about the difference between timed=true and timed=false for the calibration. It occurs because the timed=false normalizes the joystick to a max of 128 loops, regardless of the cycles setting. And, apparently, 128 loops is only good enough to register a max coordinate of about 130 at the speed Privateer expects to run.

With timed=true, the number of loops executed per millisecond is determined by the cycles setting, and the joystick waits X ms, so cycles very much affects the joystick reading for games that use a tight loop instead of their own internal counter.

The sensitivity option I'm going to add should take care of both of those problems... at least it'll let you customize DosBox joystick handling for the game/machine combination you have.