【发布时间】:2012-01-28 09:54:18
【问题描述】:
我需要使用 C 或 Java(哪个更容易)来捕获操纵杆输入。
有类似问题的答案,但都使用 C++ 或 C#。
程序只需要获取摇杆倾斜的方向和量。
我使用的是 Windows7,所以我可能需要使用 winmm.dll,如here 所述。
如果有人能用 C 或 Java 解释如何做到这一点,我将不胜感激。
【问题讨论】:
-
您是否意识到您链接到的已接受答案中指向的函数是 C 函数?
我需要使用 C 或 Java(哪个更容易)来捕获操纵杆输入。
有类似问题的答案,但都使用 C++ 或 C#。
程序只需要获取摇杆倾斜的方向和量。
我使用的是 Windows7,所以我可能需要使用 winmm.dll,如here 所述。
如果有人能用 C 或 Java 解释如何做到这一点,我将不胜感激。
【问题讨论】:
两种语言都有预制库。更重要的问题是您必须使用的语言或您主要喜欢哪种语言。添加 C 代码只是为了将此类功能添加到 Java 程序中并不一定有意义。以类似的方式,您不会想从 C 调用 Java,只是为了获得操纵杆输入。
“java 游戏杆”在 Google 上的首次点击是 this one。还没试过。
至于 C++ 代码(很可能也是 C#),您应该能够在 C 中使用相同的代码,假设它是纯 Windows API 代码(因为它也在 C 中)。所以你不应该有任何问题来适应这些。
编辑:
关于您链接的答案:您应该能够在 C 中 1:1 使用此解决方案(在 Java 中,您必须编写基本上相同的代码)。但是不要自己声明所有内容,只需 #include <windows.h> 就可以了(在 C 中)。
【讨论】:
我推荐Simple Directmedia Layer library 用于纯 C 解决方案。该库使用起来很愉快,他们的documentation and code examples 很棒:
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# solution 确实是纯 Windows API 代码!
在 C 中只是 #include <windows.h> 而不是 [DllImport("winmm.dll")]
you 链接到 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 支持structs 与 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文件中
open 在失败时返回 -1。 如果成功打开,则设置标志值(在为操纵杆声明变量时定义)。
使用
读取操纵杆输入 (read(STATE[gamepad].fd, &je, sizeof(je)) > 0)
结构定义: je 是一个结构对象 //它在joystick.h中
je 现已更新。 je.type 是 joystick.h 头文件中提到的三件事之一 如果按下按钮,则 je.number 是一个 int,表示制造商指定的按钮编号。如果摇杆被移动,则 je.number 表示制造商的轴规格。 幅度存在于 je.value 中,相应地分配给摇杆的相应变量。
【讨论】: