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
|
||||
Linux/Config.cpp
|
||||
Linux/ConfigHelper.cpp
|
||||
Linux/KeyboardMouse.cpp
|
||||
Linux/KeyboardQueue.cpp
|
||||
Linux/LilyPad.cpp)
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#include "HidDevice.h"
|
||||
#include "DualShock3.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include "Linux/KeyboardMouse.h"
|
||||
#endif
|
||||
|
||||
void EnumDevices(int hideDXXinput) {
|
||||
// Needed for enumeration of some device types.
|
||||
dm->ReleaseInput();
|
||||
|
@ -40,6 +44,8 @@ void EnumDevices(int hideDXXinput) {
|
|||
EnumDualShock3s();
|
||||
EnumXInputDevices();
|
||||
EnumDirectInputDevices(hideDXXinput);
|
||||
#else
|
||||
EnumLnx();
|
||||
#endif
|
||||
|
||||
dm->CopyBindings(oldDm->numDevices, oldDm->devices);
|
||||
|
|
|
@ -130,6 +130,8 @@ enum DeviceAPI {
|
|||
// to ignore individual buttons. Wrapper itself takes care
|
||||
// of ignoring bound keys. Otherwise, works normally.
|
||||
IGNORE_KEYBOARD = 7,
|
||||
// XXX
|
||||
LNX_KEYBOARD = 16,
|
||||
};
|
||||
|
||||
enum DeviceType {
|
||||
|
|
|
@ -24,3 +24,9 @@ int GetQueuedKeyEvent(keyEvent *event);
|
|||
|
||||
// Cleans up as well as clears queue.
|
||||
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");
|
||||
if (config.closeHacks&1) config.closeHacks &= ~2;
|
||||
|
||||
config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", WM);
|
||||
if (!config.keyboardApi) config.keyboardApi = WM;
|
||||
config.keyboardApi = (DeviceAPI)cfg.ReadInt(L"General Settings", L"Keyboard Mode", LNX_KEYBOARD);
|
||||
if (!config.keyboardApi) config.keyboardApi = LNX_KEYBOARD;
|
||||
config.mouseApi = (DeviceAPI) cfg.ReadInt(L"General Settings", L"Mouse Mode");
|
||||
|
||||
config.volume = cfg.ReadInt(L"General Settings", L"Volume", 100);
|
||||
|
@ -292,6 +292,7 @@ int LoadSettings(int force, wchar_t *file) {
|
|||
config.multipleBinding = multipleBinding;
|
||||
|
||||
//TODO RefreshEnabledDevicesAndDisplay(1);
|
||||
RefreshEnabledDevices(1); // XXX For the moment only a subfonction
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -314,6 +315,7 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
|||
for (int i=0; i<dm->numDevices; i++) {
|
||||
Device *dev = dm->devices[i];
|
||||
|
||||
// XXX windows magic?
|
||||
if (!dev->attached && dev->displayName[0] != '[') {
|
||||
wchar_t *newName = (wchar_t*) malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12));
|
||||
wsprintfW(newName, L"[Detached] %s", dev->displayName);
|
||||
|
@ -328,6 +330,8 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
|||
((dev->api == DI && config.gameApis.directInput) ||
|
||||
(dev->api == DS3 && config.gameApis.dualShock3) ||
|
||||
(dev->api == XINPUT && config.gameApis.xInput)))) {
|
||||
dm->EnableDevice(i);
|
||||
#if 0 // windows magic?
|
||||
if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName &&
|
||||
!wcsicmp(dev->displayName, L"DX PLAYSTATION(R)3 Controller")) {
|
||||
dm->DisableDevice(i);
|
||||
|
@ -335,6 +339,7 @@ void RefreshEnabledDevices(int updateDeviceList) {
|
|||
else {
|
||||
dm->EnableDevice(i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
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() {
|
||||
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.numBytes = 0;
|
||||
ClearKeyQueue();
|
||||
R_ClearKeyQueue();
|
||||
// Just in case, when resuming emulation.
|
||||
ReleaseModifierKeys();
|
||||
|
||||
|
@ -811,6 +812,7 @@ void CALLBACK PADclose() {
|
|||
DEBUG_TEXT_OUT("LilyPad closed\n\n");
|
||||
updateQueued = 0;
|
||||
ClearKeyQueue();
|
||||
R_ClearKeyQueue();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue