Joystick refactor pt. Deux: Support Joysticks.
Add support for non-GameController SDL Joysticks. Add proxy class wxSDLJoyDev to support using either SDL_GameController* or SDL_Joystick* values in joystate.dev. Add pretty much identical SDL code to support SDL_Joystick* when the device cannot be opened as an SDL_GameController*, without changing the API. SDL_Joystick* devices operate almost identically to SDL_Controller* devices with their own default mappings, for both events and polling. Filter axis motion events in the bindings editor widget for subsequent events within 300ms. This gets rid of the double binding for +1/-1 when the stick is moved to a direction. Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
parent
ad3327d437
commit
09e8da43db
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-04-27 20:23+0000\n"
|
||||
"POT-Creation-Date: 2020-05-04 01:24+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -831,11 +831,11 @@ msgid ""
|
|||
"along with this program. If not, see http://www.gnu.org/licenses ."
|
||||
msgstr ""
|
||||
|
||||
#: cmdevents.cpp:3069
|
||||
#: cmdevents.cpp:3076
|
||||
msgid "LAN link is already active. Disable link mode to disconnect."
|
||||
msgstr ""
|
||||
|
||||
#: cmdevents.cpp:3075
|
||||
#: cmdevents.cpp:3082
|
||||
msgid "Network is not supported in local mode."
|
||||
msgstr ""
|
||||
|
||||
|
@ -1016,78 +1016,78 @@ msgstr ""
|
|||
msgid "Not a valid GBA cartridge"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:1146
|
||||
#: panel.cpp:1150
|
||||
msgid "No memory for rewinding"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:1156
|
||||
#: panel.cpp:1160
|
||||
msgid "Error writing rewind state"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2253
|
||||
#: panel.cpp:2257
|
||||
msgid "Failed to set glXSwapIntervalEXT"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2262
|
||||
#: panel.cpp:2266
|
||||
msgid "Failed to set glXSwapIntervalSGI"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2271
|
||||
#: panel.cpp:2275
|
||||
msgid "Failed to set glXSwapIntervalMESA"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2278
|
||||
#: panel.cpp:2282
|
||||
msgid "No support for wglGetExtensionsString"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2280
|
||||
#: panel.cpp:2284
|
||||
msgid "No support for WGL_EXT_swap_control"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2289
|
||||
#: panel.cpp:2293
|
||||
msgid "Failed to set wglSwapIntervalEXT"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2295
|
||||
#: panel.cpp:2299
|
||||
msgid "No VSYNC available on this platform"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2391
|
||||
#: panel.cpp:2395
|
||||
msgid "memory allocation error"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2394
|
||||
#: panel.cpp:2398
|
||||
msgid "error initializing codec"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2397
|
||||
#: panel.cpp:2401
|
||||
msgid "error writing to output file"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2400
|
||||
#: panel.cpp:2404
|
||||
msgid "can't guess output format from file name"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2405
|
||||
#: panel.cpp:2409
|
||||
msgid "programming error; aborting!"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2417 panel.cpp:2446
|
||||
#: panel.cpp:2421 panel.cpp:2450
|
||||
#, c-format
|
||||
msgid "Unable to begin recording to %s (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2474
|
||||
#: panel.cpp:2478
|
||||
#, c-format
|
||||
msgid "Error in audio/video recording (%s); aborting"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2480
|
||||
#: panel.cpp:2484
|
||||
#, c-format
|
||||
msgid "Error in audio recording (%s); aborting"
|
||||
msgstr ""
|
||||
|
||||
#: panel.cpp:2490
|
||||
#: panel.cpp:2494
|
||||
#, c-format
|
||||
msgid "Error in video recording (%s); aborting"
|
||||
msgstr ""
|
||||
|
@ -1148,16 +1148,26 @@ msgstr ""
|
|||
msgid "CONTROL"
|
||||
msgstr ""
|
||||
|
||||
#: widgets/sdljoy.cpp:115
|
||||
#: widgets/sdljoy.cpp:129
|
||||
#, c-format
|
||||
msgid "Connected game controller %d"
|
||||
msgstr ""
|
||||
|
||||
#: widgets/sdljoy.cpp:129
|
||||
#: widgets/sdljoy.cpp:143
|
||||
#, c-format
|
||||
msgid "Disconnected game controller %d"
|
||||
msgstr ""
|
||||
|
||||
#: widgets/sdljoy.cpp:229
|
||||
#, c-format
|
||||
msgid "Connected joystick %d"
|
||||
msgstr ""
|
||||
|
||||
#: widgets/sdljoy.cpp:246
|
||||
#, c-format
|
||||
msgid "Disconnected joystick %d"
|
||||
msgstr ""
|
||||
|
||||
#: xaudio2.cpp:35
|
||||
msgid "XAudio2: Enumerating devices failed!"
|
||||
msgstr ""
|
||||
|
|
|
@ -68,7 +68,18 @@ int wxJoyKeyTextCtrl::DigitalButton(wxSDLJoyEvent& event)
|
|||
|
||||
void wxJoyKeyTextCtrl::OnJoy(wxSDLJoyEvent& event)
|
||||
{
|
||||
short val = event.GetControlValue();
|
||||
static wxLongLong last_event = 0;
|
||||
|
||||
int val = event.GetControlValue();
|
||||
int type = event.GetControlType();
|
||||
|
||||
// Filter consecutive axis motions within 300ms, as this adds two bindings
|
||||
// +1/-1 instead of the one intended.
|
||||
if (type == WXSDLJOY_AXIS && wxGetUTCTimeMillis() - last_event < 300)
|
||||
return;
|
||||
|
||||
last_event = wxGetUTCTimeMillis();
|
||||
|
||||
int mod = DigitalButton(event);
|
||||
int key = event.GetControlIndex(), joy = event.GetJoy() + 1;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <cstddef>
|
||||
#include "wxvbam.h"
|
||||
#include "wx/sdljoy.h"
|
||||
#include "SDL.h"
|
||||
|
@ -8,6 +9,9 @@
|
|||
|
||||
using namespace Range;
|
||||
|
||||
// For testing a GameController as a Joystick:
|
||||
//#define SDL_IsGameController(x) false
|
||||
|
||||
DEFINE_EVENT_TYPE(wxEVT_SDLJOY)
|
||||
|
||||
wxSDLJoy::wxSDLJoy()
|
||||
|
@ -16,8 +20,10 @@ wxSDLJoy::wxSDLJoy()
|
|||
{
|
||||
// Start up joystick if not already started
|
||||
// FIXME: check for errors
|
||||
SDL_Init(SDL_INIT_JOYSTICK);
|
||||
SDL_Init(SDL_INIT_GAMECONTROLLER);
|
||||
SDL_GameControllerEventState(SDL_ENABLE);
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
}
|
||||
|
||||
wxSDLJoy::~wxSDLJoy()
|
||||
|
@ -49,6 +55,9 @@ void wxSDLJoy::Poll()
|
|||
{
|
||||
auto joy = e.cbutton.which;
|
||||
|
||||
if (!SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (contains(joystate, joy)) {
|
||||
auto but = e.cbutton.button;
|
||||
auto val = e.cbutton.state;
|
||||
|
@ -78,6 +87,9 @@ void wxSDLJoy::Poll()
|
|||
{
|
||||
auto joy = e.caxis.which;
|
||||
|
||||
if (!SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (contains(joystate, joy)) {
|
||||
auto axis = e.caxis.axis;
|
||||
auto val = axisval(e.caxis.value);
|
||||
|
@ -108,6 +120,9 @@ void wxSDLJoy::Poll()
|
|||
{
|
||||
auto joy = e.cdevice.which;
|
||||
|
||||
if (!SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (add_all || contains(joystate, joy)) {
|
||||
DisconnectController(joy);
|
||||
ConnectController(joy);
|
||||
|
@ -133,11 +148,112 @@ void wxSDLJoy::Poll()
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
// Joystck events for non-GameControllers.
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
{
|
||||
auto joy = e.jbutton.which;
|
||||
|
||||
if (SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (contains(joystate, joy)) {
|
||||
auto but = e.jbutton.button;
|
||||
auto val = e.jbutton.state;
|
||||
auto prev_val = joystate[joy].button[but];
|
||||
|
||||
if (handler && val != prev_val) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = but;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = prev_val;
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
joystate[joy].button[but] = val;
|
||||
|
||||
wxLogDebug("GOT SDL_JOYBUTTON: joy:%d but:%d val:%d prev_val:%d", joy, but, val, prev_val);
|
||||
}
|
||||
|
||||
got_event = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_JOYAXISMOTION:
|
||||
{
|
||||
auto joy = e.jaxis.which;
|
||||
|
||||
if (SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (contains(joystate, joy)) {
|
||||
auto axis = e.jaxis.axis;
|
||||
auto val = axisval(e.jaxis.value);
|
||||
auto prev_val = joystate[joy].axis[axis];
|
||||
|
||||
if (handler && val != prev_val) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = axis;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = prev_val;
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
|
||||
joystate[joy].axis[axis] = val;
|
||||
|
||||
wxLogDebug("GOT SDL_JOYAXISMOTION: joy:%d axis:%d val:%d prev_val:%d", joy, axis, val, prev_val);
|
||||
}
|
||||
}
|
||||
|
||||
got_event = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_JOYDEVICEADDED:
|
||||
{
|
||||
auto joy = e.cdevice.which;
|
||||
|
||||
if (SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (add_all || contains(joystate, joy)) {
|
||||
DisconnectController(joy);
|
||||
ConnectController(joy);
|
||||
|
||||
systemScreenMessage(wxString::Format(_("Connected joystick %d"), joy + 1));
|
||||
}
|
||||
|
||||
got_event = true;
|
||||
|
||||
break;
|
||||
}
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
{
|
||||
auto joy = e.cdevice.which;
|
||||
|
||||
if (SDL_IsGameController(joy))
|
||||
break;
|
||||
|
||||
if (contains(joystate, joy)) {
|
||||
DisconnectController(joy);
|
||||
|
||||
systemScreenMessage(wxString::Format(_("Disconnected joystick %d"), joy + 1));
|
||||
}
|
||||
|
||||
got_event = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// I am only doing this shit because hotplug support is fucking broken in SDL right now.
|
||||
|
||||
bool do_poll = false;
|
||||
wxLongLong tm = wxGetUTCTimeMillis();
|
||||
|
||||
|
@ -152,45 +268,90 @@ void wxSDLJoy::Poll()
|
|||
for (auto&& joy : joystate) {
|
||||
if (!joy.second.dev) continue;
|
||||
|
||||
for (uint8_t but = 0; but < SDL_CONTROLLER_BUTTON_MAX; but++) {
|
||||
auto last_state = joy.second.button[but];
|
||||
auto state = SDL_GameControllerGetButton(joy.second.dev, static_cast<SDL_GameControllerButton>(but));
|
||||
if (SDL_IsGameController(joy.first)) {
|
||||
for (uint8_t but = 0; but < SDL_CONTROLLER_BUTTON_MAX; but++) {
|
||||
auto last_state = joy.second.button[but];
|
||||
auto state = SDL_GameControllerGetButton(joy.second.dev, static_cast<SDL_GameControllerButton>(but));
|
||||
|
||||
if (last_state != state) {
|
||||
if (handler) {
|
||||
if (last_state != state) {
|
||||
if (handler) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy.first;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = but;
|
||||
ev.ctrl_val = state;
|
||||
ev.prev_val = last_state;
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
joy.second.button[but] = state;
|
||||
|
||||
wxLogDebug("POLLED SDL_CONTROLLERBUTTON: joy:%d but:%d val:%d prev_val:%d", joy.first, but, state, last_state);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t axis = 0; axis < SDL_CONTROLLER_AXIS_MAX; axis++) {
|
||||
auto val = axisval(SDL_GameControllerGetAxis(joy.second.dev, static_cast<SDL_GameControllerAxis>(axis)));
|
||||
auto prev_val = joy.second.axis[axis];
|
||||
|
||||
if (handler && val != prev_val) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy.first;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = but;
|
||||
ev.ctrl_val = state;
|
||||
ev.prev_val = last_state;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = axis;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = prev_val;
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
|
||||
joy.second.axis[axis] = val;
|
||||
|
||||
wxLogDebug("POLLED SDL_CONTROLLERAXISMOTION: joy:%d axis:%d val:%d prev_val:%d", joy.first, axis, val, prev_val);
|
||||
}
|
||||
|
||||
joy.second.button[but] = state;
|
||||
|
||||
wxLogDebug("POLLED SDL_CONTROLLERBUTTON: joy:%d but:%d val:%d prev_val:%d", joy.first, but, state, last_state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (uint8_t but = 0; but < SDL_JoystickNumButtons(joy.second.dev); but++) {
|
||||
auto last_state = joy.second.button[but];
|
||||
auto state = SDL_JoystickGetButton(joy.second.dev, but);
|
||||
|
||||
for (uint8_t axis = 0; axis < SDL_CONTROLLER_AXIS_MAX; axis++) {
|
||||
auto val = axisval(SDL_GameControllerGetAxis(joy.second.dev, static_cast<SDL_GameControllerAxis>(axis)));
|
||||
auto prev_val = joy.second.axis[axis];
|
||||
if (last_state != state) {
|
||||
if (handler) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy.first;
|
||||
ev.ctrl_type = WXSDLJOY_BUTTON;
|
||||
ev.ctrl_idx = but;
|
||||
ev.ctrl_val = state;
|
||||
ev.prev_val = last_state;
|
||||
|
||||
if (handler && val != prev_val) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy.first;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = axis;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = prev_val;
|
||||
handler->ProcessEvent(ev);
|
||||
}
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
joy.second.button[but] = state;
|
||||
|
||||
joy.second.axis[axis] = val;
|
||||
wxLogDebug("POLLED SDL_JOYBUTTON: joy:%d but:%d val:%d prev_val:%d", joy.first, but, state, last_state);
|
||||
}
|
||||
}
|
||||
|
||||
wxLogDebug("POLLED SDL_CONTROLLERAXISMOTION: joy:%d axis:%d val:%d prev_val:%d", joy.first, axis, val, prev_val);
|
||||
for (uint8_t axis = 0; axis < SDL_JoystickNumAxes(joy.second.dev); axis++) {
|
||||
auto val = axisval(SDL_JoystickGetAxis(joy.second.dev, axis));
|
||||
auto prev_val = joy.second.axis[axis];
|
||||
|
||||
if (handler && val != prev_val) {
|
||||
wxSDLJoyEvent ev(wxEVT_SDLJOY);
|
||||
ev.joy = joy.first;
|
||||
ev.ctrl_type = WXSDLJOY_AXIS;
|
||||
ev.ctrl_idx = axis;
|
||||
ev.ctrl_val = val;
|
||||
ev.prev_val = prev_val;
|
||||
|
||||
handler->ProcessEvent(ev);
|
||||
|
||||
joy.second.axis[axis] = val;
|
||||
|
||||
wxLogDebug("POLLED SDL_JOYAXISMOTION: joy:%d axis:%d val:%d prev_val:%d", joy.first, axis, val, prev_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,15 +360,31 @@ void wxSDLJoy::Poll()
|
|||
|
||||
void wxSDLJoy::ConnectController(uint8_t joy)
|
||||
{
|
||||
if (!(joystate[joy].dev = SDL_GameControllerOpen(joy)))
|
||||
wxLogDebug("SDL_GameControllerOpen(%d) failed: %s", joy, SDL_GetError());
|
||||
if (SDL_IsGameController(joy)) {
|
||||
if (!(joystate[joy].dev = SDL_GameControllerOpen(joy))) {
|
||||
wxLogDebug("SDL_GameControllerOpen(%d) failed: %s", joy, SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(joystate[joy].dev = SDL_JoystickOpen(joy))) {
|
||||
wxLogDebug("SDL_JoystickOpen(%d) failed: %s", joy, SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxSDLJoy::DisconnectController(uint8_t joy)
|
||||
{
|
||||
if (auto& dev = joystate[joy].dev) {
|
||||
if (SDL_GameControllerGetAttached(dev))
|
||||
SDL_GameControllerClose(dev);
|
||||
if (SDL_IsGameController(joy)) {
|
||||
if (SDL_GameControllerGetAttached(dev))
|
||||
SDL_GameControllerClose(dev);
|
||||
}
|
||||
else {
|
||||
if (SDL_JoystickGetAttached(dev))
|
||||
SDL_JoystickClose(dev);
|
||||
}
|
||||
|
||||
dev = nullptr;
|
||||
}
|
||||
|
@ -256,9 +433,9 @@ void wxSDLJoy::SetRumble(bool do_rumble)
|
|||
rumbling = do_rumble;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
// do rumble only on device 0
|
||||
// Do rumble only on device 0, and only if it's a GameController.
|
||||
auto dev = joystate[0].dev;
|
||||
if (dev) {
|
||||
if (dev && SDL_IsGameController(0)) {
|
||||
if (rumbling) {
|
||||
SDL_GameControllerRumble(dev, 0xFFFF, 0xFFFF, 300);
|
||||
if (!IsRunning())
|
||||
|
@ -269,8 +446,6 @@ void wxSDLJoy::SetRumble(bool do_rumble)
|
|||
Stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
Stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -278,3 +453,37 @@ void wxSDLJoy::Notify()
|
|||
{
|
||||
SetRumble(rumbling);
|
||||
}
|
||||
|
||||
wxSDLJoyDev::operator SDL_GameController*&()
|
||||
{
|
||||
return dev_gc;
|
||||
}
|
||||
|
||||
SDL_GameController*& wxSDLJoyDev::operator=(SDL_GameController* ptr)
|
||||
{
|
||||
dev_gc = ptr;
|
||||
return dev_gc;
|
||||
}
|
||||
|
||||
|
||||
wxSDLJoyDev::operator SDL_Joystick*&()
|
||||
{
|
||||
return dev_js;
|
||||
}
|
||||
|
||||
SDL_Joystick*& wxSDLJoyDev::operator=(SDL_Joystick* ptr)
|
||||
{
|
||||
dev_js = ptr;
|
||||
return dev_js;
|
||||
}
|
||||
|
||||
wxSDLJoyDev::operator bool()
|
||||
{
|
||||
return dev_gc != nullptr;
|
||||
}
|
||||
|
||||
std::nullptr_t& wxSDLJoyDev::operator=(std::nullptr_t&& null_ptr)
|
||||
{
|
||||
dev_gc = null_ptr;
|
||||
return null_ptr;
|
||||
}
|
||||
|
|
|
@ -9,19 +9,39 @@
|
|||
//
|
||||
// The target window will receive EVT_SDLJOY events of type wxSDLJoyEvent.
|
||||
|
||||
#include <cstddef>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <wx/time.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/timer.h>
|
||||
#include <SDL_joystick.h>
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include "../common/contains.h"
|
||||
|
||||
struct wxSDLJoyDev {
|
||||
private:
|
||||
union {
|
||||
SDL_GameController* dev_gc = nullptr;
|
||||
SDL_Joystick* dev_js;
|
||||
};
|
||||
public:
|
||||
operator SDL_GameController*&();
|
||||
SDL_GameController*& operator=(SDL_GameController* ptr);
|
||||
|
||||
operator SDL_Joystick*&();
|
||||
SDL_Joystick*& operator=(SDL_Joystick* ptr);
|
||||
|
||||
operator bool();
|
||||
|
||||
std::nullptr_t& operator=(std::nullptr_t&& null_ptr);
|
||||
};
|
||||
|
||||
struct wxSDLJoyState {
|
||||
SDL_GameController* dev = nullptr;
|
||||
std::array<int16_t, SDL_CONTROLLER_AXIS_MAX> axis{};
|
||||
std::array<uint8_t, SDL_CONTROLLER_BUTTON_MAX> button{};
|
||||
wxSDLJoyDev dev;
|
||||
std::unordered_map<uint8_t, int16_t> axis{};
|
||||
std::unordered_map<uint8_t, uint8_t> button{};
|
||||
};
|
||||
|
||||
class wxSDLJoy : public wxTimer {
|
||||
|
|
Loading…
Reference in New Issue