鼠标平滑(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/mouse-smoothing-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 6 分钟阅读 - 2757 个词 阅读量 0鼠标平滑(译文)
原文地址:https://www.codeproject.com/Articles/5247322/Mouse-Smoothing
原文作者:wqaxs36
译文由本站 robot-v1.0 翻译
前言
Mouse smoothing feature to your mouse
鼠标的平滑功能
- 下载演示-30.1 KB(Download demo - 30.1 KB) (您需要Visual Studio和2个鼠标.)((You need Visual Studio and 2 mouses.))
编辑(Edit)
最终,我找到了一种使该工具与支持禁用"原始鼠标输入"的任何视频游戏(如<使命召唤>游戏)一起使用的方法.(Finally, I found a way to make this tool work with any video games that support the disable of Raw Mouse Input, like Call of Duty games.) 我只需要平滑直接从HID数据包绘制的鼠标偏移量,而不是平滑使用鼠标偏移量创建的屏幕坐标.(I just needed to smooth the mouse offset directly draw from the HID packets and not smooth the screen coordinate made with the mouse offset.)
介绍(Introduction)
(该程序只是我编写的代码,已实现为另一个程序:((This program is just a code I wrote, implemented into another program:) https://github.com/djpnewton/busdog(https://github.com/djpnewton/busdog) ).().) 该程序将鼠标平滑功能添加到鼠标上,如果您不知道什么是鼠标平滑,则基本上是鼠标物理移动和鼠标坐标(游戏中的摄像头)之间的延迟.(This program adds the function of mouse smoothing to your mouse, if you don’t know what is mouse smoothing, it’s basically a delay between your mouse physical moves and the mouse coordinates (camera in game).) 它用于防止鼠标抖动和相机真实感.(It’s used to prevent jitter mouse movement and camera realism.) 还有希望与之一起玩游戏的玩家(我). :)(And gamers (me) who wish to play games with it. :)) 要使用它:(To use it:)
-
首先,您需要安装USB嗅探器驱动程序才能读取鼠标的HID数据包.(First thing first, you need to install the USB sniffer driver to be able to read HID packet of the mouse.)
-
去(Go to) https://github.com/djpnewton/busdog#downloads(https://github.com/djpnewton/busdog#downloads) 并选择Windows位版本.(and select the Windows bit version.)
-
运行该程序并在要求时安装驱动程序.(Run the program and install the driver when it’s asked.) (免责声明:您可以通过安装所有USB设备来关闭它,并且不能使其正常工作,因此使用该设备时需您自担风险.)((Disclaimer: You can have all your USB devices down by installing it and cannot have them working back, so use it at your own risk.))
-
的第48行评论(Comment line 48 of)图形用户界面(GUI.cs)((()
Process.Start("devcon.exe", ...
)()) -
编译,运行程序并检查您的鼠标设备(第一个检查案例)知道您的鼠标的VID/PID,下面是一个教程:(Compile, run the program and check your mouse device, (first check case) knows with the VID/PID of your mouse, below is a tutorial:) https://honeywellaidc.force.com/supportppr/s/article/How-to-find-out-the-VID-and-PID-for-a-USB-device-on-Windows-7(https://honeywellaidc.force.com/supportppr/s/article/How-to-find-out-the-VID-and-PID-for-a-USB-device-on-Windows-7)
-
关闭程序并取消注释上一行(Close the program and uncomment the previous line commented)
-
去(Go to)装置经理(Device Manager),找到鼠标,转到(, find your mouse, go to)物产(Properties)>(>)活动>信息(Events > Information)
-
并复制以以下内容开头的鼠标名称:(And copy your Mouse name that begins with:)
-
然后将下面的行部分(#48)替换为您选择的名称:(Then replace the line section (#48) below by the name you picked:)
-
下载(Download) https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/devcon(https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/devcon) 并放在(and put it to the)**bin/发布(bin/Release)**夹(folder)
-
编译并运行(Compile and run)
-
将第二只鼠标连接到PC(否则Windows将不会显示鼠标光标),但不要使用此2(Connect a second mouse to your PC (else Windows will not display mouse cursor), but don’t use this 2)nd(nd)鼠标,请使用主鼠标连接到所选的VID/PID.(mouse, use your main mouse connected to the VID/PID you chosen.)
-
享受顺利:)(Enjoy the smooth :))
-
要在游戏中使用它,您需要禁用游戏的"原始鼠标输入"(To use it ingame, you need to disable Raw Mouse Input of the game)
-
要关闭程序,您可以(To close the program, you can)Alt-F4(Alt-F4)或者只是关闭程序((or just close the program ()Alt + Tab(Alt+Tab)对于).(for).)
背景(Background)
这个程序的想法来自我在玩<星际公民>,<鼠标平滑>时所发现的发现.(This program idea came from the discovery I made when I played Star Citizen, Mouse Smoothing.)
从那以后,我喜欢游戏中相机平滑的想法.(And since that, I love this idea of camera smoothing in game.) 最近,<使命召唤:现代战争>引入了它,虽然不如SC可调,但向前迈出了一大步.(Lately, Call of Duty: Modern Warfare has introduced it, not as adjustable as SC, but it’s a good step forward.)
使用代码(Using the Code)
该程序需要使光标移动与鼠标的物理移动不同步.(This program needs to desync cursor movement from the mouse physical moves.) 为此,我使用了来自WDK的devcon可执行文件,这是非常有用的工具,用于管理连接到PC的硬件.(And for that, I used devcon executable from WDK, very useful tool to manage the hardware connected to the PC.)
- https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/devcon(https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/devcon) 它还需要使用内核挂钩:(It also needs the use of a kernel hooker:) https://github.com/djpnewton/busdog(https://github.com/djpnewton/busdog) 从鼠标读取HID数据包并使用程序模拟鼠标驱动程序(本).(to read HID packets from the mouse and simulate a mouse driver with a program (this).) 鼠标平滑基于以下插值公式:(The mouse smoothing is based on the interpolation equation below:)
EndPoint = StartPoint + ((EndPoint - StarPoint) * InterpSpeed))
Point InterpTo(Point CurrentLocation, float InterpSpeed)
{
// 0.90 < InterpSpeed < 1
Delta.X = TargetLocation.X - CurrentLocation.X;
Delta.Y = TargetLocation.Y - CurrentLocation.Y;
DeltaMove.X = (int)(Delta.X * InterpSpeed);
DeltaMove.Y = (int)(Delta.Y * InterpSpeed);
TargetLocation.X = (CurrentLocation.X + DeltaMove.X);
TargetLocation.Y = (CurrentLocation.Y + DeltaMove.Y);
return TargetLocation;
}
这是实现鼠标驱动程序模拟的代码:(And here’s the code where mouse driver simulation is implemented:)
void RecievedFilterTraces(object sender, FilterTraceArrivedEventArgs e)
{
try
{
Native.CurrentLocation.X = 0;
Native.CurrentLocation.Y = 0;
foreach (FilterTrace filterTrace in e.Traces)
{
if (filterTrace.Buffer[0] != 0x80)
{
// X Coordinates
if (filterTrace.Buffer[3] == 0x00) // UP
{
Native.CurrentLocation.X += filterTrace.Buffer[2];
}
else if (filterTrace.Buffer[3] == 0xFF) // DOWN
{
Native.CurrentLocation.X -= 0x100 - filterTrace.Buffer[2];
}
// Y Coordinates
if (filterTrace.Buffer[5] == 0x00) // UP
{
Native.CurrentLocation.Y += filterTrace.Buffer[4];
}
else if (filterTrace.Buffer[5] == 0xFF) // DOWN
{
Native.CurrentLocation.Y -= 0x100 - filterTrace.Buffer[4];
}
// MOUSE_L
if (GetBit(filterTrace.Buffer[0], 0) == 1)
{
if (MouseButton[0] == 0)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
}
MouseButton[0] = 1;
}
else if (MouseButton[0] == 1)
{
mouse_event(MOUSEEVENTF_LEFTUP, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
MouseButton[0] = 0;
}
// MOUSE_R
if (GetBit(filterTrace.Buffer[0], 1) == 1)
{
if (MouseButton[0] == 0)
{
mouse_event(MOUSEEVENTF_RIGHTDOWN, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
}
MouseButton[1] = 1;
}
else if (MouseButton[1] == 1)
{
mouse_event(MOUSEEVENTF_RIGHTUP, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
MouseButton[1] = 0;
}
// MOUSE_M
if (GetBit(filterTrace.Buffer[0], 2) == 1)
{
if (MouseButton[0] == 0)
{
mouse_event(MOUSEEVENTF_MIDDLEDOWN, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
}
MouseButton[2] = 1;
}
else if (MouseButton[2] == 1)
{
mouse_event(MOUSEEVENTF_MIDDLEUP, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0, 0);
MouseButton[2] = 0;
}
// MOUSE_B
if (GetBit(filterTrace.Buffer[0], 3) == 1)
{
if (MouseButton[0] == 0)
{
mouse_event(MOUSEEVENTF_XDOWN, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0x0001, 0);
}
MouseButton[3] = 1;
}
else if (MouseButton[3] == 1)
{
mouse_event(MOUSEEVENTF_XUP, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0x0001, 0);
MouseButton[3] = 0;
}
// MOUSE_F
if (GetBit(filterTrace.Buffer[0], 4) == 1)
{
if (MouseButton[0] == 0)
{
mouse_event(MOUSEEVENTF_XDOWN, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0x0002, 0);
}
MouseButton[4] = 1;
}
else if (MouseButton[4] == 1)
{
mouse_event(MOUSEEVENTF_XUP, Native.CurrentLocation.X,
Native.CurrentLocation.Y, 0x0002, 0);
MouseButton[4] = 0;
}
// Wheel
if (filterTrace.Buffer[6] == 0x01) // UP
{
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, 120, 0);
}
else if (filterTrace.Buffer[6] == 0xFF) // DOWN
{
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -120, 0);
}
}
}
}
catch
{
}
}
filterTrace.Buffer
包含鼠标的HID数据包和(contains the HID packets of the mouse and the) if()
链用于解析数据包并根据我收到的内容执行操作.(chain is used to parse the packets and do actions according to what I receive.)
其余的代码只是(The rest of the code is just the code of) BusDog
我没有写,所以我不能很好地向你解释它是如何工作的.(that I didn’t write, so I cannot explain well to you how it works.)
但是这是该程序的主要代码:(But here’s the main code of that program:)
void TraceBufRead()
{
DeviceIOCTL devIO = new DeviceIOCTL(busdogPath, true);
while (true)
{
uint bytesReturned;
// send the get trace buffer command to the driver
devIO.DeviceIoControl(IOCTL_BUSDOG_GET_BUFFER,
IntPtr.Zero,
0,
outBuffer,
outBufferSize,
out bytesReturned);
if (CurrentLocation == TargetLocation)
{
while (true)
{
// keep checking if the I/O request has been fulfilled
// (abort after 500ms so our thread can be killed)
if (devIO.WaitForOverlappedIo(500, out bytesReturned))
{
break;
}
}
}
// we have a result so now we convert the buffer into a trace list and call the event
FilterTraceArrived(this, new FilterTraceArrivedEventArgs
(GetTraceList(outBuffer, outBufferSize, bytesReturned)));
Start = InterpTo(CurrentLocation, 0.971546f);
int X = Cursor.Position.X;
int Y = Cursor.Position.Y;
Start.X += X;
Start.Y += Y;
Cursor.Position = Start;
// stall trace stream to allow main thread to have a turn now and then
Thread.Sleep(10);
}
}
FilterTraceArrived
线是循环通过HID数据包收集鼠标坐标的位置.(line is where the loop gather mouse coordinate through HID packet.)
if (CurrentLocation == TargetLocation)
line是循环等待鼠标物理动作的地方.(line is where the loop waits for mouse physics action.)
兴趣点(Points of Interest)
数学方程式很有趣,但前提是我们找到了一个应用程序. :)(Mathematic equations are fun, but only if we found an application. :))
结论(Conclusion)
鼠标平滑在玩视频游戏时增加了新的视角,是一种新的玩法.(Mouse smoothing adds a new perspective when playing video games, a new way to play.)
历史(History)
- 30(30)日(th)2019年9月:初始版本(September, 2019: Initial version)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# .NET Windows Dev 新闻 翻译