Skip to content
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

Support gyroscope with DS4 emulation #14

Open
Crayon2000 opened this issue Jun 4, 2022 · 7 comments
Open

Support gyroscope with DS4 emulation #14

Crayon2000 opened this issue Jun 4, 2022 · 7 comments
Assignees

Comments

@Crayon2000
Copy link
Owner

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 Crayon2000 self-assigned this Jun 4, 2022
@Crayon2000
Copy link
Owner Author

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.

@BalisticNick
Copy link

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
Copy link

Any news on this?

@Daerdaal
Copy link

Daerdaal commented Sep 3, 2023

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
Copy link

netux commented Dec 27, 2023

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
Copy link

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 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants