Hi all, been busy the past few days...
Great news, about the A-PAC! What did you have to do to make it work? (Or what wasn't working)?
see below for the code diffs
Can you calibrate it, and if so how?
well, I can run the jscal command and that seems to work... I have followed the directions here:
file:///usr/src/linux/Documentation/input/joystick.txt
... however the jstest program keeps seg-faulting. Not sure why. So I have no way of knowing if the jscal is doing anything for me. When I start starwars for instance, the cursor is always a little left of center. What's strange is that I have gone into the service menu on the game and when it gets to the pot tester, it shows everything right in the center when the control is in the center - weird.
I need to calibrate my AKI (analog HID joystick interface) -- I have it connected to a steering wheel and pedals. The pedals are wired for a dual axis configuration. When I play a game like Outrun, the wheel works great but there is not enough of a 'range of motion' for AdvMAME to see the pedals.
So far nothing w/ 'emerge joystick' (no ebuilds), jscalibrator (display issue), and jstest, jscal, commands (get bashed).
Also, to the best of my knowledge: Joystick calibration is NOT supported in AdvMAME outside of the DOS platforms.
I'm not sure about this one... I read the advmame mailing list archives and I would tend to agree with you about the DOS-only cal menu. I will continue to investigate this, but for now - if you need a solution you might try manually setting the ranges in the input driver using a hack version of the method I describe below. This will only work if you don't swap what you have connected to your AKI board. For instance you could hack axis 0 for instance because your pedal is connected to that. If you swap stuff, you might be out of luck for now...
The Nitty Gritty:I will post the files I changed, with the filenames in
green and my changes in
red. All these files are in: /usr/src/linux/drivers/usb/input
hid.h:
/*
* HID device quirks.
*/
#define HID_QUIRK_INVERT 0x001
#define HID_QUIRK_NOTOUCH 0x002
#define HID_QUIRK_IGNORE 0x004
#define HID_QUIRK_NOGET 0x008
#define HID_QUIRK_HIDDEV 0x010
#define HID_QUIRK_BADPAD 0x020
#define HID_QUIRK_MULTI_INPUT 0x040
#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
#define HID_QUIRK_ANALOG_RANGE_HACK 0x800
hid-input.c:
if (usage->type == EV_ABS) {
int a = field->logical_minimum;
int b = field->logical_maximum;
if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
a = field->logical_minimum = 0;
b = field->logical_maximum = 255;
#ifdef DEBUG
printk("(set logical min/max to %d / %d)", field->logical_minimum, field->logical_maximum);
#endif
}
if ((device->quirks & HID_QUIRK_ANALOG_RANGE_HACK) && (usage->code == ABS_X || usage->code == ABS_Y)) {
a = field->logical_minimum = -32768;
b = field->logical_maximum = 32767;
#ifdef DEBUG
printk("(HID_QUIRK_ANALOG_RANGE_HACK: set logical min/max to %d/%d)", field->logical_minimum, field->logical_maximum);
#endif
}
if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
else input_set_abs_params(input, usage->code, a, b, 0, 0);
}
hid-core.c:
#define USB_VENDOR_ID_LD 0x0f11
#define USB_DEVICE_ID_CASSY 0x1000
#define USB_DEVICE_ID_POCKETCASSY 0x1010
#define USB_DEVICE_ID_MOBILECASSY 0x1020
#define USB_DEVICE_ID_JWM 0x1080
#define USB_DEVICE_ID_DMMP 0x1081
#define USB_DEVICE_ID_UMIP 0x1090
#define USB_DEVICE_ID_VIDEOCOM 0x1200
#define USB_DEVICE_ID_COM3LAB 0x2000
#define USB_DEVICE_ID_TELEPORT 0x2010
#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
#define USB_DEVICE_ID_POWERCONTROL 0x2030
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
#define USB_VENDOR_ID_GGG 0xfafa
#define USB_DEVICE_ID_GGG_GPWIZ49 0x0007
#define USB_VENDOR_ID_ULTIMARC 0xd209
#define USB_DEVICE_ID_APAC 0x0306 // actually the G-PAC, but should be the same as the A-PAC
/*
* Alphabetically sorted blacklist by quirk type.
*/
static struct hid_blacklist {
... skip a few lines ...
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_GGG, USB_DEVICE_ID_GGG_GPWIZ49, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_GGG, USB_DEVICE_ID_GGG_GPWIZ49 + 1, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_GGG, USB_DEVICE_ID_GGG_GPWIZ49 + 2, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_GGG, USB_DEVICE_ID_GGG_GPWIZ49 + 3, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_ULTIMARC, USB_DEVICE_ID_APAC, HID_QUIRK_ANALOG_RANGE_HACK},
{ 0, 0 }
};
... make sense? That was the most elegant way to do it, IMO.
Anyway, MHJ, you might follow a similar strategy by editing the hid.h file and make a new quirk, like HID_QUIRK_MHJ_PEDAL_LIMIT_HACK, giving it a new set bit (0x1000) then add #defines for your AKI's vendor and device IDs, then modifying the hid_blacklist to assign said hack to said vendor/device IDs. Then modify the hid-input.c file, adding a new case for your hack, applying only to PEDAL_AXIS:
if ((device->quirks & HID_QUIRK_ANALOG_RANGE_HACK) && (usage->code == ABS_PEDAL_AXIS)) {
a = field->logical_minimum = APPROPRIATE_LOW_VALUE;
b = field->logical_maximum = APPROPRIATE_HIGH_VALUE;
#ifdef DEBUG
printk("(HID_QUIRK_ANALOG_RANGE_HACK: set logical min/max to %d/%d)", field->logical_minimum, field->logical_maximum);
#endif
}
I can't remember how the AKI works, but I bet it appears to the OS as one X/Y joystick and one X/Y/Z joystick. If that's the case, put the pedals on axis Z and replace PEDAL_AXIS above w/ Z, so this doesn't booger up the range for the other stick on the AKI. Use the evtest program to find your appropriate range values. Do not use advj for the range values because they are already scaled. You need the device-level ones.
I hope this gets you started at least. My favorite beer is Hoegaarden.
Rock
p.s. If I don't go completely insane, I plan to develop a proper kernel patch for this.