我需要使用 C 或 Java(哪个更容易)来捕获操纵杆输入。
有类似问题的答案,但它们都使用 C++ 或 C#。
程序只需要获取操纵杆倾斜的方向和量。我使用的是 Windows7,所以我可能需要使用 winmm.dll,如此处所述。
如果有人可以用 C 或 Java 解释如何做到这一点,我将不胜感激。
两种语言都有预制的库。更重要的问题是您必须使用的语言或您主要喜欢哪种语言。添加 C 代码只是为了将此类功能添加到 Java 程序中并不一定有意义。以类似的方式,您不想从 C 中调用 Java,只是为了获得操纵杆输入。
谷歌上第一次点击“java 操纵杆”是这个。还没试过。
至于 C++ 代码(很可能也是 C#),您应该能够在 C 中使用相同的代码,假设它是纯 Windows API 代码(因为它也在 C 中)。所以你不应该有任何问题来适应这些。
编辑:关于您链接的答案:您应该能够在 C 中 1:1 使用此解决方案(在 Java 中,您必须编写基本上相同的代码)。但是,不要自己声明所有内容,而是#include <windows.h>
应该准备好(在 C 中)。
对于纯 C 解决方案,我推荐Simple Directmedia Layer 库。该库使用起来很愉快,它们的文档和代码示例很棒:
SDL_Joystick *joy;
// Initialize the joystick subsystem
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if(SDL_NumJoysticks()>0){
// Open joystick
joy=SDL_JoystickOpen(0);
...
C# 解决方案确实是纯 Windows API 代码!在 C#include <windows.h>
中,而不是[DllImport("winmm.dll")]
您链接到winmm.lib
. 下面的例子应该清楚地说明:
void printJoystickData()
{
// The captured data will be written to the following struct:
//typedef struct joyinfo_tag {
// UINT wXpos;
// UINT wYpos;
// UINT wZpos;
// UINT wButtons;
//} JOYINFO,*PJOYINFO,*LPJOYINFO;
JOYINFO joystickInfo;
// The ID of the joystick you are using. If there is only one joystick use JOYSTICKID1.
UINT joystickId = JOYSTICKID1;
MMRESULT errorCode = joyGetPos(joystickId, &joystickInfo);
switch(errorCode)
{
case JOYERR_NOERROR: // No error. joystickInfo now contains contains the captured data.
{
printf("The X position (left/right tilt) is %u\n", joystickInfo.wXpos);
printf("The Y position (up/down tilt) is %u\n", joystickInfo.wYpos);
printf("The Z position (usually the throttle) is %u\n", joystickInfo.wZpos);
// These values range from 0 to 65536. 32768 is the centre position.
// Test button 1. You can do the same for JOY_BUTTON2, JOY_BUTTON3 etc.
// wButtons is a UNINT that is the OR of all pressed button flags.
if(joystickInfo.wButtons & JOY_BUTTON1)
printf("Button 1 was pressed.");
break;
}
case JOYERR_PARMS: fprintf(stderr, "Invalid parameters to joyGetPos."); break;
case JOYERR_NOCANDO: fprintf(stderr, " Failed to capture joystick input."); break;
case JOYERR_UNPLUGGED: fprintf(stderr, "The joystick identified by joystickId isn't plugged in."); break;
case MMSYSERR_NODRIVER: fprintf(stderr, "No (active) joystick driver available."); break;
}
}
Simple Directmedia Layer 库(由 blahdiblah 建议)看起来也很有希望,但对于我需要做的事情,我认为上面的代码更简单。
对于 Java,使用Mario 建议的Central Nexus Device API 。下载包括文档。
您链接到的示例实际上并没有使用任何面向对象的东西,这意味着您可以很容易地将它移植到 C。
C 支持struct
s 与 C# 相同(在堆栈上分配),所以这基本上是复制粘贴。
可能会绊倒你的一件事是[DllImport]
属性。此属性的目的是从托管 C# 代码中 p/invoke(平台调用)非托管 DLL。在这里,您将用于extern
访问 Windows API。
请参阅此 URL 以获取 Gamepad.c 和 Gamepad.h 文件。 https://github.com/elanthis/gamepad
使用打开操纵杆
STATE.fd = open(STATE.device, O_RDWR|O_NONBLOCK);
结构定义:
STATE 是一个结构对象。//在Gamepad.h文件中
打开失败时返回 -1。如果成功打开,则设置标志值(在为操纵杆声明变量时定义)。
使用读取操纵杆输入
(read(STATE[gamepad].fd, &je, sizeof(je)) > 0)
结构体定义:je是结构体对象 //在joystick.h中
je is updated now. je.type is one among the three things mentioned in the joystick.h header file If a button is pressed , then je.number is an int that denotes the button number as specified by the manufacturer. If a stick is moved , then je.number denotes the axis specification by the manufacturer. The magnitude is present in the je.value which is assigned to the stick's corresponding variable accordingly.