HandheldCompanion
HandheldCompanion copied to clipboard
Gyro based on mouse control
Code proposal from Frank, as is currently implemented in the Gyro application.
Especially interesting features:
- Additional gain rate multiplier when a certain button is pressed. When using below code with an FPS that has a scope option, a lot of games reduce the sensitivity, this can then be overcome with this extra multiplier
- Very smooth motion!
//鼠标操作. mouse
[System.Runtime.InteropServices.DllImport("user32")]
private static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
//移动鼠标
const int MOUSEEVENTF_MOVE = 0x0001;
//模拟鼠标左键按下
const int MOUSEEVENTF_LEFTDOWN = 0x0002;
//模拟鼠标左键抬起
const int MOUSEEVENTF_LEFTUP = 0x0004;
//模拟鼠标右键按下
const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
//模拟鼠标右键抬起
const int MOUSEEVENTF_RIGHTUP = 0x0010;
//模拟鼠标中键按下
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
//模拟鼠标中键抬起
const int MOUSEEVENTF_MIDDLEUP = 0x0040;
//标示是否采用绝对坐标
const int MOUSEEVENTF_ABSOLUTE = 0x8000;
//模拟鼠标滚轮滚动操作,必须配合dwData参数
const int MOUSEEVENTF_WHEEL = 0x0800;
public static void MoveMouse(int a, int b)
{
mouse_event(MOUSEEVENTF_MOVE, a, b, 0, 0);
}
double[] mouseBuffer = new double[3]; //used for slowly move which gyro data less than 1
public void mouseMove(double[] gyro) //gyro is raw data from gyrometer
{
if (setting.simulateType == Settings.SIMULATETYPE.Mouse && setting.gyroEnabled)
{
if (getHotkeyTriggerState()) //check enabled button pressed or hotkey pressed
{
if (Math.Abs(gyro[0]) >= setting.mouseThreshold || Math.Abs(gyro[1]) >= setting.mouseThreshold || Math.Abs(gyro[2]) >= setting.mouseThreshold) //check threshold, setting.mouseThreshold's default value is 1
{
double gainRate = 1.0;
if (selectedIndex >= 0 && PhysicalController[selectedIndex].isConnected() && PhysicalController[selectedIndex].HasGainButtonPressed(setting.gainButton)) //check if gain button pressed which supplies a multiplier by mouseRate
{
gainRate = setting.gainRate;
}
if (Math.Abs(gyro[0]) >= setting.mouseThreshold)
{
gyro[0] = gyro[0] * setting.mouseRate * gainRate / 20;
if( Math.Abs(gyro[0]) < 1 )
{
mouseBuffer[0] += gyro[0];
if(Math.Abs(mouseBuffer[0]) >= setting.mouseThreshold)
{
if( gyro[0] > 0 )
{
gyro[0] += 1;
}
else
{
gyro[0] -= 1;
}
mouseBuffer[0] = 0;
}
} else
{
mouseBuffer[0] = 0;
}
}
else
{
gyro[0] = 0;
}
if (Math.Abs(gyro[1]) >= setting.mouseThreshold)
{
gyro[1] = gyro[1] * setting.mouseRate * gainRate / 20;
if (Math.Abs(gyro[1]) < 1)
{
mouseBuffer[1] += gyro[1];
if ( Math.Abs(mouseBuffer[1]) >= setting.mouseThreshold)
{
if (gyro[1] > 0)
{
gyro[1] += 1;
}
else
{
gyro[1] -= 1;
}
mouseBuffer[1] = 0;
}
}
else
{
mouseBuffer[1] = 0;
}
}
else
{
gyro[1] = 0;
}
if (Math.Abs(gyro[2]) >= setting.mouseThreshold)
{
gyro[2] = gyro[2] * setting.mouseRate * gainRate / 20;
if (Math.Abs(gyro[2]) < 1)
{
mouseBuffer[2] += gyro[2];
if ( Math.Abs(mouseBuffer[2]) >= setting.mouseThreshold )
{
if (gyro[2] > 0)
{
gyro[2] += 1;
}
else
{
gyro[2] -= 1;
}
mouseBuffer[2] = 0;
}
}
else
{
mouseBuffer[2] = 0;
}
}
else
{
gyro[2] = 0;
}
if (setting.axisSelectType == Settings.AXISTYPE.XY) //different axis
{
MoveMouse((int)(setting.XReverse * setting.XRate * gyro[1]), (int)(-setting.YReverse * setting.YRate * gyro[0]));
}
else if (setting.axisSelectType == Settings.AXISTYPE.XZ)
{
MoveMouse((int)(setting.XReverse * setting.XRate * gyro[2]), (int)(-setting.YReverse * setting.YRate * gyro[0]));
}
}
}
}
}
```
This is really cool
Yeah, I'd love this as well. I like to use gamepad + mouse for FPS games (on my steamdeck). And I love to mix the gyro into the mouse so I can use the trackpads for rough movement, and the gyro for exact aiming.
It is with great pleasure I can say that after more then a year this feature is included in upcoming release 0.18. Mind you, it will probably require additional tweaks and settings etc, but it works.