mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
187 lines
No EOL
4.9 KiB
C++
187 lines
No EOL
4.9 KiB
C++
#include "Common.h"
|
|
#include "WindowsKeyManager.h"
|
|
#include "Shared/KeyDefinitions.h"
|
|
|
|
WindowsKeyManager::WindowsKeyManager(Emulator* emu, HWND hWnd)
|
|
{
|
|
_emu = emu;
|
|
_hWnd = hWnd;
|
|
|
|
ResetKeyState();
|
|
|
|
_keyDefinitions = KeyDefinition::GetSharedKeyDefinitions();
|
|
|
|
//Init XInput buttons
|
|
vector<string> buttonNames = { "Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2", "RT Up", "RT Down", "RT Left", "RT Right", "LT Up", "LT Down", "LT Left", "LT Right" };
|
|
for(int i = 0; i < 4; i++) {
|
|
for(int j = 0; j < (int)buttonNames.size(); j++) {
|
|
_keyDefinitions.push_back({ "Pad" + std::to_string(i + 1) + " " + buttonNames[j], (uint32_t)(WindowsKeyManager::BaseXInputIndex + i * 0x100 + j + 1) });
|
|
}
|
|
}
|
|
|
|
//Init DirectInput buttons
|
|
vector<string> diButtonNames = { "Y+", "Y-", "X-", "X+", "Y2+", "Y2-", "X2-", "X2+", "Z+", "Z-", "Z2+", "Z2-", "DPad Up", "DPad Down", "DPad Right", "DPad Left" };
|
|
for(int i = 0; i < 16; i++) {
|
|
for(int j = 0; j < (int)diButtonNames.size(); j++) {
|
|
_keyDefinitions.push_back({ "Joy" + std::to_string(i + 1) + " " + diButtonNames[j], (uint32_t)(WindowsKeyManager::BaseDirectInputIndex + i * 0x100 + j) });
|
|
}
|
|
|
|
for(int j = 0; j < 128; j++) {
|
|
_keyDefinitions.push_back({ "Joy" + std::to_string(i + 1) + " But" + std::to_string(j + 1), (uint32_t)(WindowsKeyManager::BaseDirectInputIndex + i * 0x100 + j + diButtonNames.size())});
|
|
}
|
|
}
|
|
|
|
for(KeyDefinition& keyDef : _keyDefinitions) {
|
|
_keyNames[keyDef.keyCode] = keyDef.name;
|
|
_keyCodes[keyDef.name] = keyDef.keyCode;
|
|
}
|
|
|
|
StartUpdateDeviceThread();
|
|
}
|
|
|
|
WindowsKeyManager::~WindowsKeyManager()
|
|
{
|
|
_stopUpdateDeviceThread = true;
|
|
_stopSignal.Signal();
|
|
_updateDeviceThread.join();
|
|
}
|
|
|
|
void WindowsKeyManager::StartUpdateDeviceThread()
|
|
{
|
|
_updateDeviceThread = std::thread([=]() {
|
|
_xInput.reset(new XInputManager(_emu));
|
|
_directInput.reset(new DirectInputManager(_emu, _hWnd));
|
|
|
|
while(!_stopUpdateDeviceThread) {
|
|
//Check for newly plugged in XInput controllers every 5 secs
|
|
//Do not check for DirectInput controllers because this takes more time and sometimes causes issues/freezes
|
|
if(_xInput->NeedToUpdate()) {
|
|
_xInput->UpdateDeviceList();
|
|
}
|
|
_stopSignal.Wait(5000);
|
|
}
|
|
});
|
|
}
|
|
|
|
void WindowsKeyManager::RefreshState()
|
|
{
|
|
if(!_xInput || !_directInput) {
|
|
return;
|
|
}
|
|
|
|
_xInput->RefreshState();
|
|
_directInput->RefreshState();
|
|
}
|
|
|
|
bool WindowsKeyManager::IsKeyPressed(uint16_t key)
|
|
{
|
|
if(_disableAllKeys || key == 0) {
|
|
return false;
|
|
}
|
|
|
|
if(key >= WindowsKeyManager::BaseXInputIndex) {
|
|
if(!_xInput || !_directInput) {
|
|
return false;
|
|
}
|
|
|
|
if(key >= WindowsKeyManager::BaseDirectInputIndex) {
|
|
//Directinput key
|
|
uint8_t gamepadPort = (key - WindowsKeyManager::BaseDirectInputIndex) / 0x100;
|
|
uint8_t gamepadButton = (key - WindowsKeyManager::BaseDirectInputIndex) % 0x100;
|
|
return _directInput->IsPressed(gamepadPort, gamepadButton);
|
|
} else {
|
|
//XInput key
|
|
uint8_t gamepadPort = (key - WindowsKeyManager::BaseXInputIndex) / 0x100;
|
|
uint8_t gamepadButton = (key - WindowsKeyManager::BaseXInputIndex) % 0x100;
|
|
return _xInput->IsPressed(gamepadPort, gamepadButton);
|
|
}
|
|
} else if(key < 0x205) {
|
|
return _keyState[key] != 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button)
|
|
{
|
|
return _keyState[WindowsKeyManager::BaseMouseButtonIndex + (int)button];
|
|
}
|
|
|
|
vector<uint16_t> WindowsKeyManager::GetPressedKeys()
|
|
{
|
|
vector<uint16_t> result;
|
|
if(!_xInput || !_directInput) {
|
|
return result;
|
|
}
|
|
|
|
_xInput->RefreshState();
|
|
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
|
|
for(int j = 1; j <= 26; j++) {
|
|
if(_xInput->IsPressed(i, j)) {
|
|
result.push_back(WindowsKeyManager::BaseXInputIndex + i * 0x100 + j);
|
|
}
|
|
}
|
|
}
|
|
|
|
_directInput->RefreshState();
|
|
for(int i = _directInput->GetJoystickCount() - 1; i >= 0; i--) {
|
|
for(int j = 0; j < 16+128; j++) {
|
|
if(_directInput->IsPressed(i, j)) {
|
|
result.push_back(WindowsKeyManager::BaseDirectInputIndex + i * 0x100 + j);
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < 0x205; i++) {
|
|
if(_keyState[i]) {
|
|
result.push_back(i);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
string WindowsKeyManager::GetKeyName(uint16_t keyCode)
|
|
{
|
|
auto keyDef = _keyNames.find(keyCode);
|
|
if(keyDef != _keyNames.end()) {
|
|
return keyDef->second;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
uint16_t WindowsKeyManager::GetKeyCode(string keyName)
|
|
{
|
|
auto keyDef = _keyCodes.find(keyName);
|
|
if(keyDef != _keyCodes.end()) {
|
|
return keyDef->second;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void WindowsKeyManager::UpdateDevices()
|
|
{
|
|
if(!_xInput || !_directInput) {
|
|
return;
|
|
}
|
|
|
|
_xInput->UpdateDeviceList();
|
|
_directInput->UpdateDeviceList();
|
|
}
|
|
|
|
bool WindowsKeyManager::SetKeyState(uint16_t scanCode, bool state)
|
|
{
|
|
if(scanCode < 0x205 && _keyState[scanCode] != state) {
|
|
_keyState[scanCode] = state;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void WindowsKeyManager::SetDisabled(bool disabled)
|
|
{
|
|
_disableAllKeys = disabled;
|
|
}
|
|
|
|
void WindowsKeyManager::ResetKeyState()
|
|
{
|
|
memset(_keyState, 0, sizeof(_keyState));
|
|
} |