给NES模拟器增加USB手柄的支持
参与HELPER2416开发板助学计划
上次提到了把NES放到HELPER2416上来跑,可是还不能控制,所以今天加个补丁篇——增加USB手柄的支持
由于我也才疏学浅,所以只是把手柄信息读出来就好,关于Linux输入设备相关的知识我也还需要更多学习才行。
就今天的目标:第一,读USB手柄的输入信息,第二:把信息整合到NES模拟器中。
实现第一个目标——我尝试了一下,手柄接到开发板上,会在/dev/input/下产生相应的event文件,我这里出现了event2,所以我只要读它就好:
- static DWORD my_pad1 = 0;
- void *thread_joy_listen(void *arg)
- {
- int keys_fd;
- char ret[2];
- struct input_event t;
- //keys_fd = open ("/dev/input/event2", O_RDONLY|O_NONBLOCK);
- keys_fd = open ("/dev/input/event2", O_RDONLY);
- if (keys_fd <= 0)
- {
- printf ("open /dev/input/event2 device error!\n");
- return 0;
- }
- while (1)
- {
- if (read (keys_fd, &t, sizeof (t)) == sizeof (t))
- {
- switch(t.type)
- {
- case EV_ABS:
- printf("EV_ABS - code 0x%02X, value 0x%02X\n", t.code, t.value);
- switch(t.code)
- {
- case 0:
- switch(t.value)
- {
- case 0x80:
- my_pad1 &= ~(PAD_JOY_LEFT|PAD_JOY_RIGHT);
- break;
- case 0x00:
- my_pad1 |= PAD_JOY_LEFT;
- break;
- case 0xff:
- my_pad1 |= PAD_JOY_RIGHT;
- break;
- default:
- break;
- }
- break;
- case 1:
- switch(t.value)
- {
- case 0x80:
- my_pad1 &= ~(PAD_JOY_UP|PAD_JOY_DOWN);
- break;
- case 0x00:
- my_pad1 |= PAD_JOY_UP;
- break;
- case 0xff:
- my_pad1 |= PAD_JOY_DOWN;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- break;
- /*
- case EV_MSC:
- printf("EV_MSC - code 0x%02X, value 0x%02X\n", t.code,t.value);
- if(t.code == 0x04)
- {
- switch(t.value)
- {
- case 0x90001:
- my_pad1 ^= PAD_JOY_A;
- break;
- case 0x90002:
- my_pad1 ^= PAD_JOY_B;
- break;
- case 0x90003:
- my_pad1 ^= PAD_JOY_B;
- break;
- case 0x90004:
- my_pad1 ^= PAD_JOY_A;
- break;
- case 0x90009:
- my_pad1 ^= PAD_JOY_SELECT;
- break;
- case 0x9000c:
- my_pad1 ^= PAD_JOY_START;
- break;
- default:
- break;
- }
- }
- break;
- */
- case EV_KEY:
- printf("EV_KEY - code 0x%02X, value 0x%02X\n", t.code,t.value);
- switch(t.code)
- {
- case 0x120:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_B;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_B;
- }
- break;
- case 0x121:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_A;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_A;
- }
- break;
- case 0x122:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_A;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_A;
- }
- break;
- case 0x123:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_B;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_B;
- }
- break;
- case 0x128:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_SELECT;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_SELECT;
- }
- break;
- case 0x12b:
- if(t.value)
- {
- my_pad1 |= PAD_JOY_START;
- }
- else
- {
- my_pad1 &= ~PAD_JOY_START;
- }
- break;
- default:
- break;
- }
- break;
- default:
- printf("UNKNOWN - type 0x%02X, code 0x%02X, value 0x%02X\n", t.type, t.code, t.value);
- break;
- }
- }
- }
- close (keys_fd);
- return 0;
- }
进一步的,需要解释:这个函数明显是做了一个线程,专门用来监视手柄状态。我原本想尝试在NES线程中直接不阻塞的读取手柄,可是失败了,最后才想了这个旁门左道的方法。
然后在程序启动以后,直接启动这个线程开始监听手柄了……
- int err;
- pthread_t ntid;
- err = pthread_create(&ntid, NULL, thread_joy_listen, NULL);
然后只要在NES的手柄状态函数中,进行正确的赋值就可以了。
- /* Get a joypad state */
- void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
- {
- *pdwPad1 = my_pad1;
- }
所以,这样,就可以用手柄玩FC游戏了。补充一点,我的手柄值都是我自己试出来的,所以当你使用这些代码,也需要考虑手柄值的对应是否正确。
附上文件:
论坛ID:sjtitr
提交时间:2014.08.30
在QT下边,可以使用/dev/tty1来读键盘,这个是被QT4直接实别的设备!