VOGONS


First post, by jdgabard

User metadata
Rank Newbie
Rank
Newbie

I've been trying to figure this issue out for quite some time. But I've been unable to find a fix, all of the potential culprits I've found have to do with DOSbox, and not original hardware.

System Specs
ALI Chipset ATX Motherboard
K6-2 400mhz
384MB Memory
Soundblaster PCI 128

Joysticks: Thrustmaster FCS and my own SNES2GP adapter http://retrodepot.net/?page_id=1078

The system runs normally with practically every game I've tried. With the exception of Duke Nukem 1-2. From the game menu I go to Game Setup, and then Joystick setup. It asks my to place the stick in the forward left position and click a button. Then it asks to go the the back right position and click a button. Once done I start a new game, and Duke is always moving to the right unless I actively try to change directions to the left.

I do not experience this in any other game. The joystick and the controller adapter work fine in Win98/95 and pretty much every other game I've tried. Just the original Duke games. I'm starting to wonder if this is potentially an issue with the version of Duke I have, or possibly an issue with the SB PCI sound cards, or maybe the system timing just isn't right for some older DOS games.

Any ideas?

Reply 2 of 4, by K1n9_Duk3

User metadata
Rank Member
Rank
Member
jdgabard wrote on 2021-01-13, 00:48:

Duke is always moving to the right unless I actively try to change directions to the left.

Yup, that's definitely a speed problem.

Joystick input is always CPU-speed-sensitive by design. To read the analog values of the x/y axis, the code basically has to count how many times the CPU can read the joystick port before the axis-bits are no longer set. The faster the CPU is, the more joystick port reads it can perform in the same amount of time. That means the same joystick position will have different analog values depending on the system. I'm not too familiar with the hardware side of things, so I can't say whether using a different joystick or controller card would help. Since the stick uses variable resistors to measure its position, adding extra resistors into the circuits might help, but that's really just a wild guess.

The joystick code in Duke Nukem limits the analog range to values from 0 to 500 and stops polling the joystick port once the x or the y axis reaches this predefined maximum value. This limit was put there to prevent the code from polling endlessly when no joystick is connected. This also means that, in your case, the calibration ends up using the value 500 as the maximum value for each axis when the real analog value would actually be much higher. This improper calibration results in the game thinking that the stick is being pushed to the right while it's actually still in the center position. I once tested a joystick on my 200 MHz Pentium system and the analog value was at about 480 or something like that with the stick in the center position, so joystick controls were already near the breaking point in Duke Nukem on that system.

The only way to fix this would be to patch the game(s) to allow a higher range of analog values. There are more games out there that may have the same issues. The joystick code in Duke Nukem was taken directly from old Softdisk/id Software routines. The same "bug" can be found in:

  • Catacomb 1-2
  • Commander Keen 1-3
  • Cosmo's Cosmic Adventure
  • Dangerous Dave 1-2
  • Duke Nukem & Duke Nukem II
  • Hovertank
  • Major Stryker
  • Rescue Rover
  • Shadow Knights

Patching the games to use a range of 0 to 5000 (for example) would be relatively simple. Here are some patch scripts for use with my patching utility. Just copy the patch script into a plain text file and open that file with my patching utility, then follow the instructions. This will modify the joystick code in version 2.0 of Duke Nukem 1:

%exefile dn1.exe 118010	# Duke Nukem: Episode 1 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%exefile dn2.exe 118290 # Duke Nukem: Episode 2 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%exefile dn3.exe 117830 # Duke Nukem: Episode 3 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%end
Last edited by K1n9_Duk3 on 2021-01-16, 22:04. Edited 1 time in total.

Reply 3 of 4, by jdgabard

User metadata
Rank Newbie
Rank
Newbie
K1n9_Duk3 wrote on 2021-01-15, 22:47:
Yup, that's definitely a speed problem. […]
Show full quote
jdgabard wrote on 2021-01-13, 00:48:

Duke is always moving to the right unless I actively try to change directions to the left.

Yup, that's definitely a speed problem.

Joystick input is always CPU-speed-sensitive by design. To read the analog values of the x/y axis, the code basically has to count how many times the CPU can read the joystick port before the axis-bits are lo longer set. The faster the CPU is, the more joystick port reads it can perform in the same amount of time. That means the same joystick position will have different analog values depending on the system. I'm not too familiar with the hardware side of things, so I can't say whether using a different joystick or controller card would help. Since the stick uses variable resistors to measure its position, adding extra resistors into the circuits might help, but that's really just a wild guess.

The joystick code in Duke Nukem limits the analog range to values from 0 to 500 and stops polling the joystick port once the x or the y axis reaches this predefined maximum value. This limit was put there to prevent the code from polling endlessly when no joystick is connected. This also means that, in your case, the calibration ends up using the value 500 as the maximum value for each axis when the real analog value would actually be much higher. This improper calibration results in the game thinking that the stick is being pushed to the right while it's actually still in the center position. I once tested a joystick on my 200 MHz Pentium system and the analog value was at about 480 or something like that with the stick in the center position, so joystick controls were already near the breaking point in Duke Nukem on that system.

The only way to fix this would be to patch the game(s) to allow a higher range of analog values. There are more games out there that may have the same issues. The joystick code in Duke Nukem was taken directly from old Softdisk/id Software routines. The same "bug" can be found in:

  • Catacomb 1-2
  • Commander Keen 1-3
  • Cosmo's Cosmic Adventure
  • Dangerous Dave 1-2
  • Duke Nukem & Duke Nukem II
  • Hovertank
  • Major Stryker
  • Rescue Rover
  • Shadow Knights

Patching the games to use a range of 0 to 5000 (for example) would be relatively simple. Here are some patch scripts for use with my patching utility. Just copy the patch script into a plain text file and open that file with my patching utility, then follow the instructions. This will modify the joystick code in version 2.0 of Duke Nukem 1:

%exefile dn1.exe 118010	# Duke Nukem: Episode 1 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%exefile dn2.exe 118290 # Duke Nukem: Episode 2 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%exefile dn3.exe 117830 # Duke Nukem: Episode 3 (v2.0)
%patch $15F4 5000w
%patch $1603 5000w
%patch $10B4F 5000w
%patch $10B59 5000w

%end

Thanks for the excellent explanation. I don’t see other controllers or game pads working either. As mentioned above I designed one of the tested controllers. And had to learn the ins and outs of the hardware side of the analog port. Like you mentioned above, it could possibly be changed with resistor and cap values.

This makes me think I need to change my test-rig to be a 386 or 486sx machine. Instead of the K6-2 class that I tend to use.

I’ll check out the link when I boot up my computer a little later.