Qt 4.8 和製MESS その4

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
}