mirror of https://github.com/PCSX2/pcsx2.git
lilypad : plug a basic keyboard device
Add a reverse fifo to transfer event from core to plugin Long story short, on linux there is only one event queue in core
This commit is contained in:
parent
aec43f0bee
commit
3096e94616
|
@ -30,6 +30,7 @@ set(lilypadSources
|
||||||
InputManager.cpp
|
InputManager.cpp
|
||||||
Linux/Config.cpp
|
Linux/Config.cpp
|
||||||
Linux/ConfigHelper.cpp
|
Linux/ConfigHelper.cpp
|
||||||
|
Linux/KeyboardMouse.cpp
|
||||||
Linux/KeyboardQueue.cpp
|
Linux/KeyboardQueue.cpp
|
||||||
Linux/LilyPad.cpp)
|
Linux/LilyPad.cpp)
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#include "HidDevice.h"
|
#include "HidDevice.h"
|
||||||
#include "DualShock3.h"
|
#include "DualShock3.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include "Linux/KeyboardMouse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void EnumDevices(int hideDXXinput) {
|
void EnumDevices(int hideDXXinput) {
|
||||||
// Needed for enumeration of some device types.
|
// Needed for enumeration of some device types.
|
||||||
dm->ReleaseInput();
|
dm->ReleaseInput();
|
||||||
|
@ -40,6 +44,8 @@ void EnumDevices(int hideDXXinput) {
|
||||||
EnumDualShock3s();
|
EnumDualShock3s();
|
||||||
EnumXInputDevices();
|
EnumXInputDevices();
|
||||||
EnumDirectInputDevices(hideDXXinput);
|
EnumDirectInputDevices(hideDXXinput);
|
||||||
|
#else
|
||||||
|
EnumLnx();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
||||||
|
|
|
@ -130,6 +130,8 @@ enum DeviceAPI {
|
||||||
// to ignore individual buttons. Wrapper itself takes care
|
// to ignore individual buttons. Wrapper itself takes care
|
||||||
// of ignoring bound keys. Otherwise, works normally.
|
// of ignoring bound keys. Otherwise, works normally.
|
||||||
IGNORE_KEYBOARD = 7,
|
IGNORE_KEYBOARD = 7,
|
||||||
|
// XXX
|
||||||
|
LNX_KEYBOARD = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DeviceType {
|
enum DeviceType {
|
||||||
|
|
|
@ -24,3 +24,9 @@ int GetQueuedKeyEvent(keyEvent *event);
|
||||||
|
|
||||||
// Cleans up as well as clears queue.
|
// Cleans up as well as clears queue.
|
||||||
void ClearKeyQueue();
|
void ClearKeyQueue();
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
void R_QueueKeyEvent(const keyEvent& event);
|
||||||
|
int R_GetQueuedKeyEvent(keyEvent *event);
|
||||||
|
void R_ClearKeyQueue();
|
||||||
|
#endif
|
||||||
|
|
|
@ -158,8 +158,8 @@ int LoadSettings(int force, wchar_t *file) {
|
||||||
config.closeHacks = (u8)cfg.ReadInt(L"General Settings", L"Close Hacks");
|
config.closeHacks = (u8)cfg.ReadInt(L"General Settings", L"Close Hacks");
|
||||||
if (config.closeHacks&1) config.closeHacks &= ~2;
|
if (config.closeHacks&1) config.closeHacks &= ~2;
|
||||||
|
|
||||||
config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", WM);
|
config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", LNX_KEYBOARD);
|
||||||
if (!config.keyboardApi) config.keyboardApi = WM;
|
if (!config.keyboardApi) config.keyboardApi = LNX_KEYBOARD;
|
||||||
config.mouseApi = (DeviceAPI) cfg.ReadInt(L"General Settings", L"Mouse Mode");
|
config.mouseApi = (DeviceAPI) cfg.ReadInt(L"General Settings", L"Mouse Mode");
|
||||||
|
|
||||||
config.volume = cfg.ReadInt(L"General Settings", L"Volume", 100);
|
config.volume = cfg.ReadInt(L"General Settings", L"Volume", 100);
|
||||||
|
@ -292,6 +292,7 @@ int LoadSettings(int force, wchar_t *file) {
|
||||||
config.multipleBinding = multipleBinding;
|
config.multipleBinding = multipleBinding;
|
||||||
|
|
||||||
//TODO RefreshEnabledDevicesAndDisplay(1);
|
//TODO RefreshEnabledDevicesAndDisplay(1);
|
||||||
|
RefreshEnabledDevices(1); // XXX For the moment only a subfonction
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -314,6 +315,7 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
||||||
for (int i=0; i<dm->numDevices; i++) {
|
for (int i=0; i<dm->numDevices; i++) {
|
||||||
Device *dev = dm->devices[i];
|
Device *dev = dm->devices[i];
|
||||||
|
|
||||||
|
// XXX windows magic?
|
||||||
if (!dev->attached && dev->displayName[0] != '[') {
|
if (!dev->attached && dev->displayName[0] != '[') {
|
||||||
wchar_t *newName = (wchar_t*) malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12));
|
wchar_t *newName = (wchar_t*) malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12));
|
||||||
wsprintfW(newName, L"[Detached] %s", dev->displayName);
|
wsprintfW(newName, L"[Detached] %s", dev->displayName);
|
||||||
|
@ -328,6 +330,8 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
||||||
((dev->api == DI && config.gameApis.directInput) ||
|
((dev->api == DI && config.gameApis.directInput) ||
|
||||||
(dev->api == DS3 && config.gameApis.dualShock3) ||
|
(dev->api == DS3 && config.gameApis.dualShock3) ||
|
||||||
(dev->api == XINPUT && config.gameApis.xInput)))) {
|
(dev->api == XINPUT && config.gameApis.xInput)))) {
|
||||||
|
dm->EnableDevice(i);
|
||||||
|
#if 0 // windows magic?
|
||||||
if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName &&
|
if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName &&
|
||||||
!wcsicmp(dev->displayName, L"DX PLAYSTATION(R)3 Controller")) {
|
!wcsicmp(dev->displayName, L"DX PLAYSTATION(R)3 Controller")) {
|
||||||
dm->DisableDevice(i);
|
dm->DisableDevice(i);
|
||||||
|
@ -335,6 +339,7 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
||||||
else {
|
else {
|
||||||
dm->EnableDevice(i);
|
dm->EnableDevice(i);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dm->DisableDevice(i);
|
dm->DisableDevice(i);
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* LilyPad - Pad plugin for PS2 Emulator
|
||||||
|
* Copyright (C) 2002-2015 PCSX2 Dev Team/ChickenLiver
|
||||||
|
*
|
||||||
|
* PCSX2 is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Found- ation, either version 3 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with PCSX2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Linux/KeyboardMouse.h"
|
||||||
|
|
||||||
|
// actually it is even more but it is enough to distinguish different key
|
||||||
|
#define MAX_KEYCODE (0xFF)
|
||||||
|
|
||||||
|
LinuxKeyboard::LinuxKeyboard() :
|
||||||
|
Device(LNX_KEYBOARD, KEYBOARD, L"displayName", L"instanceID", L"deviceID")
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Create a new device YES\n");
|
||||||
|
for (int i=0; i<MAX_KEYCODE; i++) {
|
||||||
|
AddPhysicalControl(PSHBTN, i, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int LinuxKeyboard::Activate(InitInfo* args) {
|
||||||
|
// Always active
|
||||||
|
active = 1;
|
||||||
|
|
||||||
|
AllocState();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (int vkey=5; vkey<256; vkey++) {
|
||||||
|
int value = (unsigned short)(((short)GetAsyncKeyState(vkey))>>15);
|
||||||
|
value += value&1;
|
||||||
|
if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
physicalControlState[vkey] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Every button released
|
||||||
|
memset(physicalControlState, 0, sizeof(int)*MAX_KEYCODE);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LinuxKeyboard::Update() {
|
||||||
|
keyEvent event;
|
||||||
|
int status = 0;
|
||||||
|
while (R_GetQueuedKeyEvent(&event)) {
|
||||||
|
switch (event.evt) {
|
||||||
|
case KeyPress:
|
||||||
|
fprintf(stderr, "key pressed %x\n", event.key);
|
||||||
|
physicalControlState[MAX_KEYCODE & event.key] = FULLY_DOWN;
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
case KeyRelease:
|
||||||
|
fprintf(stderr, "key released %x\n", event.key);
|
||||||
|
physicalControlState[MAX_KEYCODE & event.key] = 0;
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unsupported event %x\n", event.evt);
|
||||||
|
//assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status; // XXX ????
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnumLnx() {
|
||||||
|
dm->AddDevice(new LinuxKeyboard());
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* LilyPad - Pad plugin for PS2 Emulator
|
||||||
|
* Copyright (C) 2002-2015 PCSX2 Dev Team/ChickenLiver
|
||||||
|
*
|
||||||
|
* PCSX2 is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Found- ation, either version 3 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with PCSX2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Global.h"
|
||||||
|
#include "InputManager.h"
|
||||||
|
#include "KeyboardQueue.h"
|
||||||
|
|
||||||
|
class LinuxKeyboard : public Device {
|
||||||
|
public:
|
||||||
|
LinuxKeyboard();
|
||||||
|
int Activate(InitInfo* args);
|
||||||
|
int Update();
|
||||||
|
};
|
||||||
|
|
||||||
|
void EnumLnx();
|
|
@ -66,3 +66,46 @@ int GetQueuedKeyEvent(keyEvent *event) {
|
||||||
void ClearKeyQueue() {
|
void ClearKeyQueue() {
|
||||||
lastQueuedEvent = nextQueuedEvent;
|
lastQueuedEvent = nextQueuedEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// Above code is for events that go from the plugin to core
|
||||||
|
// Here we need the contrary, event that come from core to the plugin
|
||||||
|
// Yes it is a crazy ping-pong hell ! I mostly copy past with
|
||||||
|
// a R_ (which stand for reverse)
|
||||||
|
|
||||||
|
#define R_EVENT_QUEUE_LEN 256
|
||||||
|
static std::mutex core_event;
|
||||||
|
|
||||||
|
static u8 R_lastQueuedEvent = 0;
|
||||||
|
static u8 R_nextQueuedEvent = 0;
|
||||||
|
static keyEvent R_queuedEvents[R_EVENT_QUEUE_LEN];
|
||||||
|
|
||||||
|
void R_QueueKeyEvent(const keyEvent &evt) {
|
||||||
|
std::lock_guard<std::mutex> lock(cSection);
|
||||||
|
|
||||||
|
R_queuedEvents[R_lastQueuedEvent] = evt;
|
||||||
|
R_lastQueuedEvent = (R_lastQueuedEvent + 1) % R_EVENT_QUEUE_LEN;
|
||||||
|
// In case someone has a severe Parkingson's disease
|
||||||
|
assert(R_nextQueuedEvent != R_lastQueuedEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_GetQueuedKeyEvent(keyEvent *event) {
|
||||||
|
if (R_lastQueuedEvent == R_nextQueuedEvent) return 0;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(core_event);
|
||||||
|
*event = R_queuedEvents[R_nextQueuedEvent];
|
||||||
|
R_nextQueuedEvent = (R_nextQueuedEvent + 1) % R_EVENT_QUEUE_LEN;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_ClearKeyQueue() {
|
||||||
|
R_lastQueuedEvent = R_nextQueuedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_C_(void) PADWriteEvent(keyEvent &evt)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "Received evt:%x key:%x\n", evt.evt, evt.key);
|
||||||
|
R_QueueKeyEvent(evt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -729,6 +729,7 @@ s32 CALLBACK PADinit(u32 flags) {
|
||||||
query.lastByte = 1;
|
query.lastByte = 1;
|
||||||
query.numBytes = 0;
|
query.numBytes = 0;
|
||||||
ClearKeyQueue();
|
ClearKeyQueue();
|
||||||
|
R_ClearKeyQueue();
|
||||||
// Just in case, when resuming emulation.
|
// Just in case, when resuming emulation.
|
||||||
ReleaseModifierKeys();
|
ReleaseModifierKeys();
|
||||||
|
|
||||||
|
@ -811,6 +812,7 @@ void CALLBACK PADclose() {
|
||||||
DEBUG_TEXT_OUT("LilyPad closed\n\n");
|
DEBUG_TEXT_OUT("LilyPad closed\n\n");
|
||||||
updateQueued = 0;
|
updateQueued = 0;
|
||||||
ClearKeyQueue();
|
ClearKeyQueue();
|
||||||
|
R_ClearKeyQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue