VirtualBoxのUbuntuのC/C++で、USB接続のゲームパッド/ジョイスティックを扱いたい。
USBデバイスとして認識されていることを確認する。
以下の例では、ゲームパッド「JC-U3912T」が認識されていることが分かる。
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 007: ID 056e:200e Elecom Co., Ltd JC-U3912T
Bus 002 Device 002: ID 80ee:0021 VirtualBox USB Tablet
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
jstest-gtkをインストール。
$ sudo apt-get install jstest-gtk
jstest-gtkを実行する。
$ jstest-gtk
この例では、/dev/input/js2 が所望のゲームパッド「JC-U3912T」であることが分かる。
ゲームパッドを選択して「Properties」を開くと、ゲームパッドの動作確認ができる。
#include <vector>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/joystick.h>
using namespace std;
#define JOY_DEV "/dev/input/js2"
int main()
{
int joy_fd = -1;
int num_of_axis = 0;
int num_of_buttons = 0;
char name_of_joystick[80];
vector<int> joy_axis;
vector<char> joy_button;
if((joy_fd=open(JOY_DEV, O_RDONLY)) < 0) {
printf("Failed to open %s\n", JOY_DEV);
return -1;
}
ioctl(joy_fd, JSIOCGAXES, &num_of_axis);
ioctl(joy_fd, JSIOCGBUTTONS, &num_of_buttons);
ioctl(joy_fd, JSIOCGNAME(80), &name_of_joystick);
printf("Joystick: %s\n", name_of_joystick);
printf("Axis: %d\n", num_of_axis);
printf("Buttons: %d\n", num_of_buttons);
printf("\nHit Enter key\n");
while ( getchar() != '\n') { ; }
joy_button.resize(num_of_buttons,0);
joy_axis.resize(num_of_axis,0);
fcntl(joy_fd, F_SETFL, O_NONBLOCK);
while(true)
{
js_event js;
read(joy_fd, &js, sizeof(js_event));
switch (js.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
if((int)js.number >= num_of_axis){
printf("Axis number error: %d\n", (int)js.number);
continue;
}
joy_axis[(int)js.number] = js.value;
break;
case JS_EVENT_BUTTON:
if((int)js.number >= num_of_buttons){
printf("Button number error: %d\n", (int)js.number);
continue;
}
joy_button[(int)js.number] = js.value;
break;
}
printf("Axis:");
for(int i = 0; i < num_of_axis; i++){ printf(" %6d", joy_axis[i]); }
printf("\n");
printf("Button:");
for(int i = 0; i < num_of_buttons; i++){ printf(" %d", joy_button[i]); }
printf("\n");
usleep(1000);
}
close(joy_fd);
return 0;
}