JoyShockLibrary icon indicating copy to clipboard operation
JoyShockLibrary copied to clipboard

[Feature suggestion] Sample with motion

Open r57zone opened this issue 1 year ago • 2 comments

Hello, it would be great to have a simple, reference sample showcasing how to correctly work with the library. It would be nice if the sample also included mouse moving and rotation (on 3.0 can't get stable yaw, pitch, roll axes - one axis smoothly transitions to another, probably I'm doing something wrong, on 2.2.0 I got it right).

Such a sample could greatly help beginner developers easily understand and incorporate these features into their projects.

Additionally, the sample could serve as a kind of test for the library, checking its basic functions.

Thank you for your library and work.

r57zone avatar Oct 02 '23 08:10 r57zone

Hi @r57zone! I'd love to add a reference sample. I can't really work on it at the moment without getting permission from my employer, but for now, hopefully this code snippet is helpful.

This code is from this sample that I created while developing v3.0 (using Dear ImGui), but didn't have time to polish it enough to include: image

JibbSmart avatar Oct 05 '23 07:10 JibbSmart

This sample is just what need, thanks 👍

r57zone avatar Oct 05 '23 07:10 r57zone

I simplified the example a bit, maybe it will be useful to someone.

#include "JoyShockLibrary.h"
#include <windows.h>

// Settings
int _gyroSpace = 2;
float _sensitivity = 0.5f;
float _tightening = 2.f;
int _defaultCalibrationMode = 1;

// Callback for applying settings to new connections
void ConnectCallback(int deviceId)
{
	JslSetGyroSpace(deviceId, _gyroSpace);
	if (_defaultCalibrationMode > 0)
	{
		JslSetAutomaticCalibration(deviceId, true);
	}
}

void MoveMouse(float x, float y)
{
	static float accumulatedX = 0.f;
	static float accumulatedY = 0.f;

	accumulatedX += x;
	accumulatedY += y;

	int applicableX = (int)accumulatedX;
	int applicableY = (int)accumulatedY;

	accumulatedX -= applicableX;
	accumulatedY -= applicableY;

	INPUT input = { 0 };
	input.type = INPUT_MOUSE;
	input.mi.mouseData = 0;
	input.mi.time = 0;
	input.mi.dx = applicableX;
	input.mi.dy = applicableY;
	input.mi.dwFlags = MOUSEEVENTF_MOVE;
	SendInput(1, &input, sizeof(input));
}

void CalculateYawPitchRoll(float quatW, float quatX, float quatY, float quatZ, float& yaw, float& pitch, float& roll)
{
	yaw = atan2f(2.0f * (quatW * quatZ + quatX * quatY), 1.0f - 2.0f * (quatY * quatY + quatZ * quatZ));
	pitch = asinf(2.0f * (quatW * quatY - quatZ * quatX));
	roll = atan2f(2.0f * (quatW * quatX + quatY * quatZ), 1.0f - 2.0f * (quatX * quatX + quatY * quatY));
}

void HandleDeviceConnections()
{
	int deviceHandles[16];
	int numConnectedDevices = JslGetConnectedDeviceHandles(deviceHandles, 16);

	if (numConnectedDevices > 0)
	{
		for (int deviceIndex = 0; deviceIndex < numConnectedDevices; ++deviceIndex)
		{
			const int deviceHandle = deviceHandles[deviceIndex];
			float velocityX, velocityY, velocityZ;
			JslGetAndFlushAccumulatedGyro(deviceHandle, velocityX, velocityY, velocityZ);

			float frameTime = 1.f / 60.f;

			const float inputSize = sqrtf(velocityX * velocityX + velocityY * velocityY + velocityZ * velocityZ);
			float tightenedSensitivity = _sensitivity * 50.f;
			if (inputSize < _tightening && _tightening > 0)
			{
				tightenedSensitivity *= inputSize / _tightening;
			}
			MoveMouse(-velocityY * tightenedSensitivity * frameTime, -velocityX * tightenedSensitivity * frameTime);

		
			MOTION_STATE motionState = JslGetMotionState(deviceHandle);
			float yaw, pitch, roll;
			CalculateYawPitchRoll(motionState.quatW, motionState.quatX, motionState.quatY, motionState.quatZ, yaw, pitch, roll);

			//std::cout << "Device " << deviceIndex << " connected." << std::endl;
			//std::cout << "Gravity = (" << motionState.gravX << ", " << motionState.gravY << ", " << motionState.gravZ << ")" << std::endl;
			//std::cout << "Acceleration = (" << motionState.accelX << ", " << motionState.accelY << ", " << motionState.accelZ << ")" << std::endl;
			
			//std::cout << "Yaw = " << yaw << ", Pitch = " << pitch << ", Roll = " << roll << std::endl; // 
		
			std::cout << "Devices connected: " << deviceIndex << std::endl;
		}
	}
	else
	{
		std::cout << "Not devices." << std::endl;
	}
}

int main()
{
	SetConsoleTitle("JoyShock Library Sample");
	JslSetConnectCallback(ConnectCallback);
	JslConnectDevices();

	while (true)
	{
		HandleDeviceConnections();

		if (GetAsyncKeyState(VK_ESCAPE) & 0x8000)
			break;

		Sleep(1);
	}

	return 0;
}```

r57zone avatar Sep 04 '24 10:09 r57zone