-
-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix DualShock3 rumble intensity by removing overflow and adjusting motor set… #163
base: main
Are you sure you want to change the base?
Fix DualShock3 rumble intensity by removing overflow and adjusting motor set… #163
Conversation
The Wii U Pro Controller only supports turning the rumble motor on and off. Wii U games try to work around this by repeatedly turning the motor on and off with a specific frequency. The duration is set to 1, since most games will output several rumble packets per second anyways. I remember experimenting with setting this value to 0xFF, which sometimes caused the rumble motor to be on continuously even after it was supposed to stop. |
I'm attaching a newer 30_bloopair.rpx so you can try it with your dualshock 3. Rumble now works where it didn't before. I think a duration of 1 on the Dualshock3 is only like 20ms. As you said, the WiiU expects rumble to be either on or off. Hence, 0xff duration which just turns the rumble on without a timeout on the Dualshock3. Yes, it should rumble continuously, until the WiiU tells it to stop rumbling. Just as the WiiU intends. I played a couple of games yesterday, and didn't have the problem of the rumble motor being on continuously. If this later becomes a problem, it's an easy fix. Think of the DualShock3 duration as a watchdog timeout for rumble. I think the WiiU's ds_data->rumble isn't always 0 or 1. If it is any value > 3, the multiplying by 64 overflow will get weird. I assumed that WiiU rumble is 0 to 255, some sort of linear increase in physical rumble power, corresponding to the DualShock3's. Just passing the WiiU 8-bit value to the Dualshock3 seems to work correctly. p.s. The rpx I sent also fixes the triggers, but that's another issue I've yet to commit. |
Rumble currently works for me, but it is very faint as mentioned in #73.
Bloopair/ios/ios_pad/source/main.h Line 49 in 2dff9bb
Maybe the multiplier could be turned in to a configurable option though. |
Update: I was able to get the rumble motor stuck multiple times, by hovering over apps in the Wii U menu. |
Thanks for explaining the binary rumble value in the main header, I didn't know that. Given the binary on/off for WiiU rumble: I changed it just to max out the rumble on both ds3 motors and turn them off based on that wiiu flag. And changed the ds3 rumble duration to a second (which should eliminate it staying on/rumbling unintentionally). Normally it should get turned off before then by the WiiU, the one-second duration is just a watchdog/off timer. A future configurable option might be the ds3 rumble intensity (now at max). I saw there is a volume in the WiiU's native controller configuration (where you can disable rumble), and maybe we could use that volume value as the rumble strength? I do suspect that there is some WiiU rumble intensity setting in those 7 unused bits of the packet, but I haven't experimented. I don't have a WiiU Pro Controller. The WiiU Gamepad rumble is super weak. I didn't sleep much last night, and have a Christmas luncheon thing to attend, but I will get around soon to making another commit with what seems to be working now. |
Bloopair comes with a configuration system which is used by Koopair. So this could be a configurable option in Koopair. |
I got a ps3 controller today, and was disappointed that the
DualShock 3 rumble didn't work.
In the Bloopair code for emulating a Wii U Pro Controller using a PS3 (DualShock 3) controller, the function responsible for sending rumble (vibration) data to the DS3 has a line:
rep.left_motor_force = ds_data->rumble * 64;
and similarly:
rep.right_motor_force = ds_data->rumble;
where ds_data->rumble is presumably an 8-bit value (0–255). Here’s the problem:
Because the big motor value is multiplied by 64 and stored in an 8-bit field, it constantly overflows, often ending up as zero or a small fraction of the intended force. Meanwhile, the small motor is being driven incorrectly as a full 0–255 range instead of a simple on/off. The result is that the controller hardly rumbles, or rumbles inconsistently.
Left Motor Overflow
The left motor field (left_motor_force) is also just an 8-bit value (0–255).
If ds_data->rumble is larger than 3 or 4, multiplying by 64 immediately overflows in 8 bits.
For example, if ds_data->rumble is 4, 4×64=256 which is 0x100, but in an 8-bit field that becomes 0x00.
If ds_data->rumble is 5, 5×64=320, which modulo 256 becomes 64—an unexpected, relatively weak vibration level.
As a result, the large motor (which is the more powerful motor in the DualShock 3) never gets its intended full range of rumble.
Most values are converted to either 0 or small values, causing the “weak” rumble effect.
Small Motor Misuse
The right motor in a DualShock 3 (the “small” motor) effectively supports on/off states rather than a full 0–255 range. Yet the code assigns it the direct ds_data->rumble value. If ds_data->rumble is large, you’re effectively trying to pass a high value to a motor that only wants 0 or 1.
This doesn’t necessarily break things, but it’s not how Sony’s official HID docs typically implement DS3 rumble. The small motor should be 0 or 1, plus a duration—while the big motor uses a 0–255 force value.
Duration
Both motors also have a duration field. In the snippet it’s set to 1, which is extremely short. Typically you’d set that to something like 0xFF for indefinite rumble. Otherwise, the DS3 might shut off the motor after the short duration expires.
Fixes #73