Windows環境のみですがwinmm.libを使って、ジョイスティック機能を実装してみました。
qt_input.cpp
/* Skelton for retropc emulator Qt Version : tanam Date : 2013.05.18 - */ #include "emu.h" #include "vm/vm.h" #include "fifo.h" #include "fileio.h" #ifndef Q_OS_ANDROID #include <mmsystem.h> #endif #define KEY_KEEP_FRAMES 3 #define COUNTOF(arr) (sizeof(arr) / sizeof((arr)[0])) // Qtキーコード -> 仮想キーコード 変換テーブル std::map<int, int> VKTable; static const struct { int InKey; // Qtのキーコード int VKey; // 仮想キーコード } VKeyDef[] = { { Qt::Key_unknown, 0xff }, { Qt::Key_1, '1' }, // 1 ! { Qt::Key_Exclam, '1' }, // 1 ! { Qt::Key_2, '2' }, // 2 " { Qt::Key_QuoteDbl, '2' }, // 2 " { Qt::Key_3, '3' }, // 3 # { Qt::Key_NumberSign, '3' }, // 3 # { Qt::Key_4, '4' }, // 4 $ { Qt::Key_Dollar, '4' }, // 4 $ { Qt::Key_5, '5' }, // 5 % { Qt::Key_Percent, '5' }, // 5 % { Qt::Key_6, '6' }, // 6 & { Qt::Key_Ampersand, '6' }, // 6 & { Qt::Key_7, '7' }, // 7 ' { Qt::Key_Apostrophe, '7' }, // 7 ' { Qt::Key_8, '8' }, // 8 ( { Qt::Key_ParenLeft, '8' }, // 8 ( { Qt::Key_9, '9' }, // 9 ) { Qt::Key_ParenRight, '9' }, // 9 ) { Qt::Key_0, '0' }, // 0 { Qt::Key_Minus, 0xBD }, // - = { Qt::Key_Equal, 0xBD }, // - = { Qt::Key_AsciiCircum, 0xDE }, // ^ ~ { Qt::Key_AsciiTilde, 0xDE }, // ^ ~ { Qt::Key_Backspace, 0xDC }, // 円 { Qt::Key_Insert, 0x13 }, // BREAK { Qt::Key_Escape, 0x29 }, // FUNC { Qt::Key_Q, 'Q' }, // q Q { Qt::Key_W, 'W' }, // w W { Qt::Key_E, 'E' }, // e E { Qt::Key_R, 'R' }, // r R { Qt::Key_T, 'T' }, // t T { Qt::Key_Y, 'Y' }, // y Y { Qt::Key_U, 'U' }, // u U { Qt::Key_I, 'I' }, // i I { Qt::Key_O, 'O' }, // o O { Qt::Key_P, 'P' }, // p P { Qt::Key_At, 0xC0 }, // @ ` { Qt::Key_QuoteLeft, 0xC0 }, // @ ` { Qt::Key_BracketLeft, 0xDB }, // [ { { Qt::Key_BraceLeft, 0xDB }, // [ { { Qt::Key_Return, 0x0D }, // CR { Qt::Key_Up, 0x26 }, // ↑ { Qt::Key_Down, 0x28 }, // ↓ { Qt::Key_Left, 0x25 }, // ← { Qt::Key_Right, 0x27 }, // → { Qt::Key_Control, 0x11 }, // L-Ctrl { Qt::Key_A, 'A' }, // a A { Qt::Key_S, 'S' }, // s S { Qt::Key_D, 'D' }, // d D { Qt::Key_F, 'F' }, // f F { Qt::Key_G, 'G' }, // g G { Qt::Key_H, 'H' }, // h H { Qt::Key_J, 'J' }, // j J { Qt::Key_K, 'K' }, // k K { Qt::Key_L, 'L' }, // l L { Qt::Key_Semicolon, 0xBB }, // ; + { Qt::Key_Plus, 0xBB }, // ; + { Qt::Key_Colon, 0xBA }, // : * { Qt::Key_Asterisk, 0xBA }, // : * { Qt::Key_BracketRight,0xDD }, // ] } { Qt::Key_BraceRight, 0xDD }, // ] } { Qt::Key_Shift, 0x10 }, // L-Shift { Qt::Key_Z, 'Z' }, // z Z { Qt::Key_X, 'X' }, // x X { Qt::Key_C, 'C' }, // c C { Qt::Key_V, 'V' }, // v V { Qt::Key_B, 'B' }, // b B { Qt::Key_N, 'N' }, // n N { Qt::Key_M, 'M' }, // m M { Qt::Key_Comma, 0xBC }, // , < { Qt::Key_Less, 0xBC }, // , < { Qt::Key_Period, 0xBE }, // . > { Qt::Key_Greater, 0xBE }, // . > { Qt::Key_Slash, 0xBF }, // / ? { Qt::Key_Question, 0xBF }, // / ? { Qt::Key_End, 0xE2 }, // ロ { Qt::Key_F1, 0x70 }, // GRAPH { Qt::Key_F2, 0x71 }, // カナ { Qt::Key_Space, 0x20 }, // Space { Qt::Key_Home, 0x24 }, // Home { Qt::Key_Delete, 0x2E }, // Delete { Qt::Key_Alt, 0xFE }, // Menu { Qt::Key_Menu, 0xFE } // Menu }; int OSD_ConvertKeyCode( int scode ) { if(VKTable.count(scode) == 0){ qDebug("keycode %x unknown\n", scode); return 0xFF; } return VKTable[scode]; } void EMU::keyPressEvent(QKeyEvent *event) { bool keep_frames = false; int code = OSD_ConvertKeyCode(event->key()); if(code == 0x10) key_status[0xA0] = 0x80; else if(code == 0x11) key_status[0xA2] = 0x80; else if(code == 0x70) code=0x12; else if(code == 0x71) code=0x15; key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80; return; } void EMU::keyReleaseEvent(QKeyEvent *event) { int code = OSD_ConvertKeyCode(event->key()); qDebug("keycode %x\n", code); bool keep_frames = false; if (code == 0x10) key_status[0xA0] &= 0x7f; else if(code == 0x11) key_status[0xA2] &= 0x7f; else if(code == 0x70) code=0x12; else if(code == 0x71) code=0x15; if (key_status[code]) key_status[code] &= 0x7f; if (code == 0xFE) ShowPopup(); return; } void EMU::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::RightButton) ShowPopup(); return; } void EMU::initialize_input() { // initialize status memset(key_status, 0, sizeof(key_status)); memset(joy_status, 0, sizeof(joy_status)); #ifndef Q_OS_ANDROID // initialize joysticks joy_num = joyGetNumDevs(); for(int i = 0; i < joy_num && i < 2; i++) { JOYCAPS joycaps; if(joyGetDevCaps(i, &joycaps, sizeof(joycaps)) == JOYERR_NOERROR) { joy_mask[i] = (1 << joycaps.wNumButtons) - 1; } else { joy_mask[i] = 0x0f; // 4buttons } } #endif // initialize keycode convert table // Qtキーコード -> 仮想キーコード 変換テーブル初期化 for( int i=0; i < COUNTOF(VKeyDef); i++ ) VKTable[VKeyDef[i].InKey] = VKeyDef[i].VKey; } void EMU::release_input() { ; } void EMU::update_input() { #ifndef Q_OS_ANDROID // update joystick status memset(joy_status, 0, sizeof(joy_status)); for(int i = 0; i < joy_num && i < 2; i++) { JOYINFOEX joyinfo; joyinfo.dwSize = sizeof(JOYINFOEX); joyinfo.dwFlags = JOY_RETURNALL; if(joyGetPosEx(i, &joyinfo) == JOYERR_NOERROR) { if(joyinfo.dwYpos < 0x3fff) joy_status[i] |= 0x01; // up if(joyinfo.dwYpos > 0xbfff) joy_status[i] |= 0x02; // down if(joyinfo.dwXpos < 0x3fff) joy_status[i] |= 0x04; // left if(joyinfo.dwXpos > 0xbfff) joy_status[i] |= 0x08; // right joy_status[i] |= ((joyinfo.dwButtons & joy_mask[i]) << 4); } } #endif }