FreeJoy-Team / FreeJoy

STM32F103 USB HID game device controller with flexible configuration
GNU General Public License v3.0
760 stars 142 forks source link

feature req: reduced range axes for older host OSes #183

Open kfix opened 2 years ago

kfix commented 2 years ago

Retro enthusiasts could use a "retro compatible" boolean option on all axes to increase compatibility for older computer software. this option would either:

tl;dr

FreeJoy compiles in a static range for all axes (-32768 to 32768) in both its firmware and the configurator. This is presented to the hosting device in the HID descriptor when its plugged in.

This works great in my modern Windows 10 machines with the two old CH gameport sticks I've BluePilled. I've also used it with a G4 Mac OS9 computer and it "just works" (with addon USB Overdrive 1.4).

But it seems Windows 98 Second Edition (with unofficial "USB 2.0 Upgrade" patch) clamps any negative values to 0, so it can only register 1 quadrant of a joystick (or 1/2 of a throttle).

I've attempted to work around this in the Configurator by applying to the X & Y axes:

this makes the stick calibrate-able in Win98, provided the joystick has physical trim adjusters on its axes. I had to lightly trim mine off-center to block the cursor from "wrapping around" to logical:0 after it exceeded logical:32768

the OS calibration is needed to make it scale the Freejoy's 50%-reduced values back up to 100% so it can register a full range again.

So that scaling leads to the next issue: the 65k value range is just too much for some old software.

when running a game in Win9x's "DOS Shell", the Gameport emulation Windows appears to be even more taxing when the logical values are as big as FreeJoy's range and the OS its applying its own scaling (due to use of its calibration panel) PLUS the calibrated timer-polling that the DOS games all do.

This emulation works fine with an unmodified CH USB Combatstick which presents a 0 - 256 logical axis. If you don't calibrate it in Windows, there's less math to be done on the inputs, and since its only an 8-bit controller, the numbers are small.

I tried using the prescaler at 10% to bring the numbers down, which helped the software, but I think Windows is still doing too much work here and its noticeable... (frame drops in Wing Commander)

I'll probably dedicate one of my Freejoy sticks to a custom build (if i can bootstrap the dev environment) to try these hacks or maybe use EazyJoy or some other Arduino thing, but It'd be really cool if just a few more clicks in FreeJoy could do it!

kfix commented 2 years ago

I tested a MS Sidewinder Precision Pro wit a native USB dongle and it is working just fine in Win 98's DOS shell with no calibrations required. I had installed the Sidewinder specific software previously but it seems to be working just as a standard HID joystick.

MacOS HID Explorer shows it is reporting a -512 : 512 range. So maybe "Retro Compatible mode" only requires smaller ranges, not that they be purely positive numbers.

Probably because my testing is on a 800mhz Transmeta Crusoe, which is not the most performant 686-compatible CPU in existence!

virtual812 commented 1 year ago

Bit late, but wondering if changing the resolution to 8 or 10 bit would work for you? This should produce a smaller range of -512 : 512 , right out of the Freejoy hardware, same as what the MacOS HID saw.

kfix commented 10 months ago

I can't remember what version of FreeJoy I was testing with, but its HID was reporting -32k:32k for all axes in 8bit mode, which is why my initial issue description had this 2nd bullet point:

  • scale down the logical-min & logical-max when a reduced bit-resolution is used, instead of the current "stepping" behavior seen in lower bits on the large fixed scale

these values still look hardcoded to me: https://github.com/FreeJoy-Team/FreeJoy/blob/3cdf103c7b8329d0ce264ccd1390ead5d804d9ad/application/Src/usb_desc.c#L206-L207

and it looks like when the configurator's settings (tmp_app_config) are merged into JoystickHID_ReportDescriptor[] at power on, they're still these same values: https://github.com/FreeJoy-Team/FreeJoy/blob/3cdf103c7b8329d0ce264ccd1390ead5d804d9ad/application/Src/usb_hw.c#L372-L377

this function seems to be upscaling analog inputs on 8/10-bit axes into 16-bit to fit these limits:

https://github.com/FreeJoy-Team/FreeJoy/blob/3cdf103c7b8329d0ce264ccd1390ead5d804d9ad/application/Src/analog.c#L175-L194

https://github.com/FreeJoy-Team/FreeJoy/blob/3cdf103c7b8329d0ce264ccd1390ead5d804d9ad/application/Inc/common_defines.h#L23-L24