Crayon2000 / MiisendU-Wii-U

A UsendMii client for the Wii U
32 stars 3 forks source link

Support gyroscope with DS4 emulation #14

Open Crayon2000 opened 2 years ago

Crayon2000 commented 2 years ago

In UsendMii, add support for gyroscope with DualShock 4 emulation (ViGEm).

What we know from the VPADStatus structure: Item Description
gyro The value of the DRC angular velocity in each direction. 360 dps is expressed as a value ranging from 0 to 1.
angle The value of the DRC rotational angle obtained by calculating the value of the angular velocity in each direction. 360 degrees is expressed as a value ranging from 0 to 1.0.

In ViGEm the DS4_REPORT_EX structure:

typedef struct _DS4_REPORT_EX
{
    union
    {
        struct
        {
//...
            SHORT wGyroX;
            SHORT wGyroY;
            SHORT wGyroZ;
//...
        } Report;

        UCHAR ReportBuffer[63];
    };
} DS4_REPORT_EX, *PDS4_REPORT_EX;

From the README in https://github.com/jangxx/node-ViGEmClient:

Sets the gyroscope orientation. Each value is in degrees and must be between -2000 and 2000.

This is all the information I have right now about the gyroscope on the WiiU GamePad and the DualShock 4!

Crayon2000 commented 2 years ago

What I have done so far is take the angle from the Wii U GamePad and use it in this method to fill a ViGEm report:

void TDualShockController::SetGyro(const float AX, const float AY, const float AZ)
{
    FReport.Report.wGyroX = floor((AX * 360.0f) + 0.5f);
    FReport.Report.wGyroY = floor((AY * 360.0f) + 0.5f);
    FReport.Report.wGyroZ = floor((AZ * 360.0f) + 0.5f);
}

The only software I have to test the emulated DS4 is Fortnite. I have never tried a real DS4 in the game because I don't have one. It's doing something, but I have no clue if it's working as expected!

Here is the version to test: UsendMii-Gyro-Test.zip

ViGEmBus v1.17.333 is required.

Crayon2000 commented 2 years ago

Interesting links:

BalisticNick commented 2 years ago

ok, have tested this out on cemu and it is definitely registering input but it almost seems that the values that it is getting are subdued in a way like a full 180 only registers as a very tiny movement. please ask if you need any help, I do own a ps5 controller if that means anything.

Victorsitou commented 1 year ago

Any news on this?

Daerdaal commented 1 year ago

I tried it on Yuzu with TOTK with DS4 and the test build of UsendMii with vigembus 1.17.333 There is something, but only with very large angles of the Wii U (90 degres) and you have just a litle response when your are aiming the bow, and the Y axis of the gyro seems flipped. Every others buttons and sticks works fine, and the respnsiveness is very good. IT's strange to see the gyro inside the game so powerless when you have the "UsendMii" Cube (in the interface of UsendMii) reacting so well at the same time in the wondows nect to the yuzu one.

netux commented 10 months ago

I can confirm what everyone else is saying about that test build: the gyro is very damped compared to the cube shown in the USendMii, and I also noticed some random drift.

What I have done so far is take the angle from the Wii U GamePad and use it in this method to fill a ViGEm report:

void TDualShockController::SetGyro(const float AX, const float AY, const float AZ)
{
    FReport.Report.wGyroX = floor((AX * 360.0f) + 0.5f);
    FReport.Report.wGyroY = floor((AY * 360.0f) + 0.5f);
    FReport.Report.wGyroZ = floor((AZ * 360.0f) + 0.5f);
}

Here you are converting the Wii U GamePad gyro values (I assume going from 0.0 to 1.0?) to degrees (0.0 to 360.0) But you also mentioned ViGEm expects values from -2000 to +2000. So maybe the code should be like so?

void TDualShockController::SetGyro(const float AX, const float AY, const float AZ)
{
    FReport.Report.wGyroX = floor((AX * 4000.0f) - 2000.0f);
    FReport.Report.wGyroY = floor((AY * 4000.0f) - 2000.0f);
    FReport.Report.wGyroZ = floor((AZ * 4000.0f) - 2000.0f);
}
Daerdaal commented 10 months ago

As thre are not much update here, and as the UsendMii code is not open, i wonder if it would be possible to make changes "in the over side". I mean change a little the ViGEm code and make a "special wiiU to DS4 version" that modifie wGyroX, wGyroY, and wGyroZDS4_inside the ViGEm REPORT_EX structure ?