macOS fixes (#3357)

* macOS compile

* Fix memprotect error on macOS

* Fix semaphore wait + thread cancel on macOS

* Fix timedlock timeout calculation

* spu2-x macOS

* onepad macOS support

* Add MacOS game controller db

* Disable onepad_legacy on macOS

* Fix spu2-x configuration crashes

* Make recompiler work on 32-bit macOS

* Use dylib extension for plugins on macOS

* Make app bundle on macOS

* Use git info for Info.plist version
This commit is contained in:
tellowkrinkle 2020-05-24 01:19:47 -05:00 committed by GitHub
parent 8eb1bc1986
commit f9771c38a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 561 additions and 62 deletions

View File

@ -31,6 +31,7 @@ include(SearchForStuff)
include(SelectPcsx2Plugins) include(SelectPcsx2Plugins)
# Must be done after SearchForStuff # Must be done after SearchForStuff
get_git_version_info()
write_svnrev_h() write_svnrev_h()
if(NOT NO_TRANSLATION) if(NOT NO_TRANSLATION)

View File

@ -77,6 +77,11 @@ if(PACKAGE_MODE)
add_definitions(-DPLUGIN_DIR_COMPILATION=${PLUGIN_DIR} -DGAMEINDEX_DIR_COMPILATION=${GAMEINDEX_DIR} -DDOC_DIR_COMPILATION=${DOC_DIR}) add_definitions(-DPLUGIN_DIR_COMPILATION=${PLUGIN_DIR} -DGAMEINDEX_DIR_COMPILATION=${GAMEINDEX_DIR} -DDOC_DIR_COMPILATION=${DOC_DIR})
endif() endif()
if(APPLE)
option(OSX_USE_DEFAULT_SEARCH_PATH "Don't prioritize system library paths" OFF)
option(SKIP_POSTPROCESS_BUNDLE "Skip postprocessing bundle for redistributability" OFF)
endif()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Compiler extra # Compiler extra
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@ -468,3 +473,33 @@ if(CMAKE_BUILD_TYPE MATCHES "Release" OR PACKAGE_MODE)
message(WARNING "GTK3 is highly experimental besides it requires a wxWidget built with __WXGTK3__ support !!!") message(WARNING "GTK3 is highly experimental besides it requires a wxWidget built with __WXGTK3__ support !!!")
endif() endif()
endif() endif()
#-------------------------------------------------------------------------------
# MacOS-specific things
#-------------------------------------------------------------------------------
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
# CMake defaults the suffix for modules to .so on macOS but wx tells us that the
# extension is .dylib (so that's what we search for)
if(APPLE)
set(CMAKE_SHARED_MODULE_SUFFIX ".dylib")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
if(NOT OSX_USE_DEFAULT_SEARCH_PATH)
# Hack up the path to prioritize the path to built-in OS libraries to
# increase the chance of not depending on a bunch of copies of them
# installed by MacPorts, Fink, Homebrew, etc, and ending up copying
# them into the bundle. Since we depend on libraries which are not
# part of OS X (wx, etc.), however, don't remove the default path
# entirely. This is still kinda evil, since it defeats the user's
# path settings...
# See http://www.cmake.org/cmake/help/v3.0/command/find_program.html
list(APPEND CMAKE_PREFIX_PATH "/usr")
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip,-dead_strip_dylibs")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-dead_strip,-dead_strip_dylibs")
endif()

View File

@ -0,0 +1,10 @@
# This file should be run with cmake -DPCSX2_BUNDLE_PATH=path -P Pcsx2PostprocessBundle.cmake
get_filename_component(PCSX2_BUNDLE_PATH "${PCSX2_BUNDLE_PATH}" ABSOLUTE)
# Fixup plugins too
file(GLOB_RECURSE plugins "${PCSX2_BUNDLE_PATH}/Contents/MacOS/*.dylib")
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS ON)
fixup_bundle("${PCSX2_BUNDLE_PATH}" "${plugins}" "")

View File

@ -35,7 +35,7 @@ function(detectOperatingSystem)
endif() endif()
endfunction() endfunction()
function(write_svnrev_h) function(get_git_version_info)
set(PCSX2_WC_TIME 0) set(PCSX2_WC_TIME 0)
set(PCSX2_GIT_REV "") set(PCSX2_GIT_REV "")
if (GIT_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.git) if (GIT_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.git)
@ -50,9 +50,24 @@ function(write_svnrev_h)
OUTPUT_VARIABLE PCSX2_GIT_REV OUTPUT_VARIABLE PCSX2_GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
endif() endif()
if(PCSX2_GIT_REV)
set(PCSX2_VERSION_LONG "${PCSX2_GIT_REV}")
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?(-[a-z][a-z0-9]+)?" PCSX2_VERSION_SHORT "${PCSX2_VERSION_LONG}")
else()
set(PCSX2_VERSION_LONG "Unknown (git unavailable)")
set(PCSX2_VERSION_SHORT "Unknown")
endif()
if ("${PCSX2_WC_TIME}" STREQUAL "") if ("${PCSX2_WC_TIME}" STREQUAL "")
set(PCSX2_WC_TIME 0) set(PCSX2_WC_TIME 0)
endif() endif()
set(PCSX2_WC_TIME "${PCSX2_WC_TIME}" PARENT_SCOPE)
set(PCSX2_GIT_REV "${PCSX2_GIT_REV}" PARENT_SCOPE)
set(PCSX2_VERSION_LONG "${PCSX2_VERSION_LONG}" PARENT_SCOPE)
set(PCSX2_VERSION_SHORT "${PCSX2_VERSION_SHORT}" PARENT_SCOPE)
endfunction()
function(write_svnrev_h)
file(WRITE ${CMAKE_BINARY_DIR}/common/include/svnrev.h "#define SVN_REV ${PCSX2_WC_TIME}ll \n#define SVN_MODS 0\n#define GIT_REV \"${PCSX2_GIT_REV}\"") file(WRITE ${CMAKE_BINARY_DIR}/common/include/svnrev.h "#define SVN_REV ${PCSX2_WC_TIME}ll \n#define SVN_MODS 0\n#define GIT_REV \"${PCSX2_GIT_REV}\"")
endfunction() endfunction()
@ -114,6 +129,14 @@ macro(add_pcsx2_plugin lib srcs libs flags)
else(PACKAGE_MODE) else(PACKAGE_MODE)
install(TARGETS ${lib} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins) install(TARGETS ${lib} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
endif(PACKAGE_MODE) endif(PACKAGE_MODE)
if (APPLE)
# Copy to app bundle
add_custom_command(TARGET ${lib} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:PCSX2>/plugins"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:${lib}>" "$<TARGET_FILE_DIR:PCSX2>/plugins/"
)
add_dependencies(pcsx2-postprocess-bundle ${lib})
endif()
endmacro(add_pcsx2_plugin) endmacro(add_pcsx2_plugin)
macro(add_pcsx2_lib lib srcs libs flags) macro(add_pcsx2_lib lib srcs libs flags)

View File

@ -245,9 +245,10 @@ else()
endif() endif()
# old version of the plugin that still supports SDL1 # old version of the plugin that still supports SDL1
if(wxWidgets_FOUND AND GTKn_FOUND AND SDLn_FOUND AND X11_FOUND) # Was never ported to macOS
if(wxWidgets_FOUND AND GTKn_FOUND AND SDLn_FOUND AND X11_FOUND AND NOT APPLE)
set(onepad_legacy TRUE) set(onepad_legacy TRUE)
elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/onepad_legacy") elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/onepad_legacy" OR APPLE)
set(onepad_legacy FALSE) set(onepad_legacy FALSE)
else() else()
set(onepad_legacy FALSE) set(onepad_legacy FALSE)

View File

@ -233,7 +233,7 @@ public:
extern IConsoleWriter Console; extern IConsoleWriter Console;
#if defined(__unix__) #if defined(__unix__) || defined(__APPLE__)
extern void Console_SetStdout(FILE *fp); extern void Console_SetStdout(FILE *fp);
#endif #endif
extern void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp = NULL); extern void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp = NULL);

View File

@ -47,14 +47,18 @@
// //
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#define MACH_CHECK(mach_retval) \ static void MACH_CHECK(kern_return_t mach_retval)
do { \ {
kern_return_t _kr = (mach_retval); \ switch (mach_retval) {
if (_kr != KERN_SUCCESS) { \ case KERN_SUCCESS: break;
fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \ case KERN_ABORTED: // Awoken due reason unrelated to semaphore (e.g. pthread_cancel)
assert(_kr == KERN_SUCCESS); \ pthread_testcancel(); // Unlike sem_wait, mach semaphore ops aren't cancellation points
} \ // fallthrough
} while (0) default:
fprintf(stderr, "mach error: %s", mach_error_string(mach_retval));
assert(mach_retval == KERN_SUCCESS);
}
}
Threading::Semaphore::Semaphore() Threading::Semaphore::Semaphore()
{ {

View File

@ -86,7 +86,12 @@ void _platform_InstallSignalHandler()
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SysPageFaultSignalFilter; sa.sa_sigaction = SysPageFaultSignalFilter;
#ifdef __APPLE__
// MacOS uses SIGBUS for memory permission violations
sigaction(SIGBUS, &sa, NULL);
#else
sigaction(SIGSEGV, &sa, NULL); sigaction(SIGSEGV, &sa, NULL);
#endif
} }
static __ri void PageSizeAssertionTest(size_t size) static __ri void PageSizeAssertionTest(size_t size)

View File

@ -61,22 +61,21 @@ static int xpthread_mutex_timedlock(
int err = 0; int err = 0;
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) { while ((err = pthread_mutex_trylock(mutex)) == EBUSY) {
// check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX
struct timeval now;
gettimeofday(&now, NULL);
if (now.tv_sec > abs_timeout->tv_sec
|| (now.tv_sec == abs_timeout->tv_sec
&& (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec)) {
return ETIMEDOUT;
}
// acquiring lock failed, sleep some // acquiring lock failed, sleep some
struct timespec ts; struct timespec ts;
ts.tv_sec = 0; ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS; ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
int status; while (nanosleep(&ts, &ts) == -1);
while ((status = nanosleep(&ts, &ts)) == -1)
;
// check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX
struct timeval now;
int res = gettimeofday(&now, NULL);
if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec ||
(u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec) {
return ETIMEDOUT;
}
} }
return err; return err;

View File

@ -410,7 +410,7 @@ set(pcsx2LinuxSources
set(pcsx2OSXSources set(pcsx2OSXSources
gui/CpuUsageProviderLnx.cpp gui/CpuUsageProviderLnx.cpp
# Linux/LnxConsolePipe.cpp Linux/LnxConsolePipe.cpp
# Linux/LnxKeyCodes.cpp # Linux/LnxKeyCodes.cpp
Darwin/DarwinFlatFileReader.cpp Darwin/DarwinFlatFileReader.cpp
) )
@ -745,6 +745,36 @@ if(NOT USE_CLANG)
endif() endif()
endif() endif()
if (APPLE)
# MacOS defaults to having a maximum protection of the __DATA segment of rw (non-executable)
# We have a bunch of page-sized arrays in bss that we use for jit
# Obviously not being able to make those arrays executable would be a problem
target_link_options(${Output} PRIVATE -Wl,-segprot,__DATA,rwx,rw)
set_target_properties(${Output} PROPERTIES
MACOSX_BUNDLE true
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/Info.plist.in"
OUTPUT_NAME PCSX2
)
target_sources(${Output} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns")
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/gui/Resources/PCSX2.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# If they say to skip postprocess bundle, leave the target in but make it so they have
# to manually run it
if (SKIP_POSTPROCESS_BUNDLE)
set(postprocessBundleType "")
else()
set(postprocessBundleType ALL)
endif()
# Use custom_target and not custom_command so plugins can add themselves as dependencies
add_custom_target(pcsx2-postprocess-bundle ${postprocessBundleType}
COMMAND ${CMAKE_COMMAND} "-DPCSX2_BUNDLE_PATH=$<TARGET_FILE_DIR:${Output}>/../.."
-P ${CMAKE_SOURCE_DIR}/cmake/Pcsx2PostprocessBundle.cmake
)
add_dependencies(pcsx2-postprocess-bundle ${Output})
endif()
if(dev9ghzdrk) if(dev9ghzdrk)
if(PACKAGE_MODE) if(PACKAGE_MODE)
install(CODE "execute_process(COMMAND /bin/bash -c \"echo 'Enabling networking capability on Linux...';set -x; [ -f ${BIN_DIR}/${Output} ] && sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' ${BIN_DIR}/${Output}; set +x\")") install(CODE "execute_process(COMMAND /bin/bash -c \"echo 'Enabling networking capability on Linux...';set -x; [ -f ${BIN_DIR}/${Output} ] && sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' ${BIN_DIR}/${Output}; set +x\")")

View File

@ -347,7 +347,6 @@ extern void __Log( const char* fmt, ... );
# define SetDoubleBuffered(x) # define SetDoubleBuffered(x)
// TODO OSX OsxKeyCodes.cpp pending // TODO OSX OsxKeyCodes.cpp pending
# define NewPipeRedir(x) NULL
#endif #endif
#define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write #define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>iso</string>
<string>cso</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>PCSX2.icns</string>
<key>CFBundleTypeName</key>
<string>PS2 Game</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>PCSX2</string>
<key>CFBundleIconFile</key>
<string>PCSX2.icns</string>
<key>CFBundleIdentifier</key>
<string>net.pcsx2.pcsx2</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${PCSX2_VERSION_SHORT}</string>
<key>CFBundleVersion</key>
<string>${PCSX2_VERSION_LONG}</string>
<key>NSHumanReadableCopyright</key>
<string>Licensed under GPL version 3</string>
<key>LSMinimumSystemVersion</key>
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

Binary file not shown.

View File

@ -28,8 +28,10 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "wx_dialog/dialog.h" #include "wx_dialog/dialog.h"
#ifndef __APPLE__
Display *GSdsp; Display *GSdsp;
Window GSwin; Window GSwin;
#endif
void SysMessage(const char *fmt, ...) void SysMessage(const char *fmt, ...)
{ {
@ -67,8 +69,10 @@ PADtest()
s32 _PADopen(void *pDsp) s32 _PADopen(void *pDsp)
{ {
#ifndef __APPLE__
GSdsp = *(Display **)pDsp; GSdsp = *(Display **)pDsp;
GSwin = (Window) * (((u32 *)pDsp) + 1); GSwin = (Window) * (((u32 *)pDsp) + 1);
#endif
return 0; return 0;
} }
@ -100,6 +104,7 @@ void PollForJoystickInput(int cpad)
EXPORT_C_(void) EXPORT_C_(void)
PADupdate(int pad) PADupdate(int pad)
{ {
#ifndef __APPLE__
// Gamepad inputs don't count as an activity. Therefore screensaver will // Gamepad inputs don't count as an activity. Therefore screensaver will
// be fired after a couple of minute. // be fired after a couple of minute.
// Emulate an user activity // Emulate an user activity
@ -109,6 +114,7 @@ PADupdate(int pad)
// 1 call every 4096 Vsync is enough // 1 call every 4096 Vsync is enough
XResetScreenSaver(GSdsp); XResetScreenSaver(GSdsp);
} }
#endif
// Actually PADupdate is always call with pad == 0. So you need to update both // Actually PADupdate is always call with pad == 0. So you need to update both
// pads -- Gregory // pads -- Gregory
@ -118,7 +124,7 @@ PADupdate(int pad)
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) { for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) {
g_key_status.keyboard_state_acces(cpad); g_key_status.keyboard_state_acces(cpad);
} }
PollForX11KeyboardInput(); UpdateKeyboardInput();
// Get joystick state + Commit // Get joystick state + Commit
for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) { for (int cpad = 0; cpad < GAMEPAD_NUMBER; cpad++) {

View File

@ -27,6 +27,8 @@
#if defined(__unix__) #if defined(__unix__)
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#elif defined(__APPLE__)
#include <Carbon/Carbon.h>
#endif #endif
#include "keyboard.h" #include "keyboard.h"
@ -41,7 +43,75 @@ char *KeysymToChar(int keysym)
} }
#endif #endif
#if defined(__unix__) /// g_key_status.press but with proper handling for analog buttons
static void PressButton(u32 pad, u32 button) {
// Analog controls.
if (IsAnalogKey(button)) {
switch (button) {
case PAD_R_LEFT:
case PAD_R_UP:
case PAD_L_LEFT:
case PAD_L_UP:
g_key_status.press(pad, button, -MAX_ANALOG_VALUE);
break;
case PAD_R_RIGHT:
case PAD_R_DOWN:
case PAD_L_RIGHT:
case PAD_L_DOWN:
g_key_status.press(pad, button, MAX_ANALOG_VALUE);
break;
}
} else {
g_key_status.press(pad, button);
}
}
#if defined(__APPLE__)
// Mac keyboard input code is based on Dolphin's Source/Core/InputCommon/ControllerInterface/Quartz/QuartzKeyboardAndMouse.mm
// Copyright 2016 Dolphin Emulator Project
// Licensed under GPLv2+
// All keycodes are 16 bits or less, so we use top 16 bits to differentiate source
// Keyboard keys use discriminator 0
// Mouse buttons use discriminator 1
void UpdateKeyboardInput() {
for (int pad = 0; pad < GAMEPAD_NUMBER; pad++) {
const auto& map = g_conf.keysym_map[pad];
// If we loop over all keys press/release based on current state,
// joystick axes (which have two bound keys) will always go to the later-polled key
// Instead, release all keys first and then set the ones that are pressed
for (const auto& key : map) g_key_status.release(pad, key.second);
for (const auto& key : map) {
bool state;
if (key.first >> 16 == 0) {
state = CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key.first);
} else {
state = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, (CGMouseButton)(key.first & 0xFFFF));
}
if (state) PressButton(pad, key.second);
}
}
}
bool PollForNewKeyboardKeys(u32 &pkey) {
// All keycodes in <HIToolbox/Events.h> are 0x7e or lower. If you notice
// keys that aren't being recognized, bump this number up!
for (int key = 0; key < 0x80; key++) {
if (CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key)) {
pkey = key == kVK_Escape ? 0 : key;
return true;
}
}
for (auto btn : {kCGMouseButtonLeft, kCGMouseButtonCenter, kCGMouseButtonRight}) {
if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, btn)) {
pkey = btn | (1 << 16);
return true;
}
}
return false;
}
#elif defined(__unix__)
static bool s_grab_input = false; static bool s_grab_input = false;
static bool s_Shift = false; static bool s_Shift = false;
static unsigned int s_previous_mouse_x = 0; static unsigned int s_previous_mouse_x = 0;
@ -82,24 +152,7 @@ static void AnalyzeKeyEvent(keyEvent &evt)
} }
} }
// Analog controls. PressButton(pad, index);
if (IsAnalogKey(index)) {
switch (index) {
case PAD_R_LEFT:
case PAD_R_UP:
case PAD_L_LEFT:
case PAD_L_UP:
g_key_status.press(pad, index, -MAX_ANALOG_VALUE);
break;
case PAD_R_RIGHT:
case PAD_R_DOWN:
case PAD_L_RIGHT:
case PAD_L_DOWN:
g_key_status.press(pad, index, MAX_ANALOG_VALUE);
break;
}
} else if (index != -1)
g_key_status.press(pad, index);
//PAD_LOG("Key pressed:%d\n", index); //PAD_LOG("Key pressed:%d\n", index);
@ -191,7 +244,7 @@ static void AnalyzeKeyEvent(keyEvent &evt)
} }
} }
void PollForX11KeyboardInput() void UpdateKeyboardInput()
{ {
keyEvent evt = {0}; keyEvent evt = {0};
XEvent E = {0}; XEvent E = {0};
@ -222,7 +275,7 @@ void PollForX11KeyboardInput()
} }
} }
bool PollX11KeyboardMouseEvent(u32 &pkey) bool PollForNewKeyboardKeys(u32 &pkey)
{ {
GdkEvent *ev = gdk_event_get(); GdkEvent *ev = gdk_event_get();

View File

@ -24,12 +24,14 @@
#include "onepad.h" #include "onepad.h"
#if defined(__unix__) #if defined(__unix__) || defined(__APPLE__)
extern void UpdateKeyboardInput();
extern bool PollForNewKeyboardKeys(u32 &pkey);
#ifndef __APPLE__
extern Display *GSdsp; extern Display *GSdsp;
extern void PollForX11KeyboardInput();
extern bool PollX11KeyboardMouseEvent(u32 &pkey);
extern Window GSwin; extern Window GSwin;
#endif
#else #else

View File

@ -183,7 +183,7 @@ PADopen(void *pDsp)
g_ev_fifo.reset(); g_ev_fifo.reset();
#if defined(__unix__) #if defined(__unix__) || defined(__APPLE__)
GamePad::EnumerateGamePads(s_vgamePad); GamePad::EnumerateGamePads(s_vgamePad);
#endif #endif
return _PADopen(pDsp); return _PADopen(pDsp);

View File

@ -101,7 +101,7 @@ enum gamePadValues {
PAD_R_LEFT // Right joystick (Left) ← PAD_R_LEFT // Right joystick (Left) ←
}; };
#if defined(__unix__) #if defined(__unix__) || defined(__APPLE__)
#include "GamePad.h" #include "GamePad.h"
#endif #endif
#include "bitwise.h" #include "bitwise.h"

View File

@ -1,4 +1,127 @@
# Linux - from # https://github.com/gabomdq/ # Mac OS, Linux - from # https://github.com/gabomdq/
# Mac OS X
030000008f0e00000300000009010000,2In1 USB Joystick,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000000d0f0000ee00000000010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,
03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,
03000000242f00002d00000007010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000006d04000018c2000000010000,Logitech RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,
030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,
0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d620000011a7000000020000,Nintendo Switch Core (Plus) Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,
03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
# Linux # Linux
05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,

View File

@ -19,6 +19,149 @@
#include "dialog.h" #include "dialog.h"
#ifdef __APPLE__
#include <Carbon/Carbon.h>
static std::string KeyName(int pad, int key, int keysym)
{
// Mouse
if (keysym >> 16) {
switch (keysym & 0xFFFF) {
case kCGMouseButtonLeft:
return "Mouse Left";
case kCGMouseButtonRight:
return "Mouse Right";
case kCGMouseButtonCenter:
return "Mouse Middle";
default: // Use only number for extra button
return "Mouse " + std::to_string(keysym & 0xFFFF);
}
}
switch (keysym) {
case kVK_ANSI_A: return "A";
case kVK_ANSI_B: return "B";
case kVK_ANSI_C: return "C";
case kVK_ANSI_D: return "D";
case kVK_ANSI_E: return "E";
case kVK_ANSI_F: return "F";
case kVK_ANSI_G: return "G";
case kVK_ANSI_H: return "H";
case kVK_ANSI_I: return "I";
case kVK_ANSI_J: return "J";
case kVK_ANSI_K: return "K";
case kVK_ANSI_L: return "L";
case kVK_ANSI_M: return "M";
case kVK_ANSI_N: return "N";
case kVK_ANSI_O: return "O";
case kVK_ANSI_P: return "P";
case kVK_ANSI_Q: return "Q";
case kVK_ANSI_R: return "R";
case kVK_ANSI_S: return "S";
case kVK_ANSI_T: return "T";
case kVK_ANSI_U: return "U";
case kVK_ANSI_V: return "V";
case kVK_ANSI_W: return "W";
case kVK_ANSI_X: return "X";
case kVK_ANSI_Y: return "Y";
case kVK_ANSI_Z: return "Z";
case kVK_ANSI_0: return "0";
case kVK_ANSI_1: return "1";
case kVK_ANSI_2: return "2";
case kVK_ANSI_3: return "3";
case kVK_ANSI_4: return "4";
case kVK_ANSI_5: return "5";
case kVK_ANSI_6: return "6";
case kVK_ANSI_7: return "7";
case kVK_ANSI_8: return "8";
case kVK_ANSI_9: return "9";
case kVK_ANSI_Grave: return "`";
case kVK_ANSI_Minus: return "-";
case kVK_ANSI_Equal: return "=";
case kVK_ANSI_LeftBracket: return "[";
case kVK_ANSI_RightBracket: return "]";
case kVK_ANSI_Backslash: return "\\";
case kVK_ANSI_Semicolon: return ";";
case kVK_ANSI_Quote: return "'";
case kVK_ANSI_Comma: return ",";
case kVK_ANSI_Period: return ".";
case kVK_ANSI_Slash: return "/";
case kVK_Escape: return "";
case kVK_Tab: return "";
case kVK_Delete: return "";
case kVK_ForwardDelete: return "";
case kVK_Return: return "";
case kVK_Space: return "";
case kVK_ANSI_KeypadDecimal: return "Keypad .";
case kVK_ANSI_KeypadMultiply: return "Keypad *";
case kVK_ANSI_KeypadPlus: return "Keypad +";
case kVK_ANSI_KeypadClear: return "";
case kVK_ANSI_KeypadDivide: return "Keypad /";
case kVK_ANSI_KeypadEnter: return "";
case kVK_ANSI_KeypadMinus: return "Keypad -";
case kVK_ANSI_KeypadEquals: return "Keypad =";
case kVK_ANSI_Keypad0: return "Keypad 0";
case kVK_ANSI_Keypad1: return "Keypad 1";
case kVK_ANSI_Keypad2: return "Keypad 2";
case kVK_ANSI_Keypad3: return "Keypad 3";
case kVK_ANSI_Keypad4: return "Keypad 4";
case kVK_ANSI_Keypad5: return "Keypad 5";
case kVK_ANSI_Keypad6: return "Keypad 6";
case kVK_ANSI_Keypad7: return "Keypad 7";
case kVK_ANSI_Keypad8: return "Keypad 8";
case kVK_ANSI_Keypad9: return "Keypad 9";
case kVK_Command: return "Left ⌘";
case kVK_Shift: return "Left ⇧";
case kVK_CapsLock: return "";
case kVK_Option: return "Left ⌥";
case kVK_Control: return "Left ⌃";
case kVK_RightCommand: return "Right ⌘";
case kVK_RightShift: return "Right ⇧";
case kVK_RightOption: return "Right ⌥";
case kVK_RightControl: return "Right ⌃";
case kVK_Function: return "fn";
case kVK_VolumeUp: return "Volume Up";
case kVK_VolumeDown: return "Volume Down";
case kVK_Mute: return "Mute";
case kVK_F1: return "F1";
case kVK_F2: return "F2";
case kVK_F3: return "F3";
case kVK_F4: return "F4";
case kVK_F5: return "F5";
case kVK_F6: return "F6";
case kVK_F7: return "F7";
case kVK_F8: return "F8";
case kVK_F9: return "F9";
case kVK_F10: return "F10";
case kVK_F11: return "F11";
case kVK_F12: return "F12";
case kVK_F13: return "F13";
case kVK_F14: return "F14";
case kVK_F15: return "F15";
case kVK_F16: return "F16";
case kVK_F17: return "F17";
case kVK_F18: return "F18";
case kVK_F19: return "F19";
case kVK_F20: return "F20";
case kVK_Help: return "Help";
case kVK_Home: return "";
case kVK_PageUp: return "";
case kVK_End: return "";
case kVK_PageDown: return "";
case kVK_LeftArrow: return "";
case kVK_RightArrow: return "";
case kVK_DownArrow: return "";
case kVK_UpArrow: return "";
case kVK_ISO_Section: return "Section";
case kVK_JIS_Yen: return "¥";
case kVK_JIS_Underscore: return "_";
case kVK_JIS_KeypadComma: return "Keypad ,";
case kVK_JIS_Eisu: return "英数";
case kVK_JIS_Kana: return "かな";
default: return "Key " + std::to_string(keysym);
}
}
#else
static std::string KeyName(int pad, int key, int keysym) static std::string KeyName(int pad, int key, int keysym)
{ {
// Mouse // Mouse
@ -39,6 +182,7 @@ static std::string KeyName(int pad, int key, int keysym)
return std::string(XKeysymToString(keysym)); return std::string(XKeysymToString(keysym));
} }
#endif
// Construtor of Dialog // Construtor of Dialog
Dialog::Dialog() Dialog::Dialog()
@ -431,7 +575,7 @@ void Dialog::config_key(int pad, int key)
u32 key_pressed = 0; u32 key_pressed = 0;
while (!captured) { while (!captured) {
if (PollX11KeyboardMouseEvent(key_pressed)) { if (PollForNewKeyboardKeys(key_pressed)) {
// special case for keyboard/mouse to handle multiple keys // special case for keyboard/mouse to handle multiple keys
// Note: key_pressed == 0 when ESC is hit to abort the capture // Note: key_pressed == 0 when ESC is hit to abort the capture
if (key_pressed > 0) { if (key_pressed > 0) {

View File

@ -20,7 +20,7 @@ set(CommonFlags
# plugin name # plugin name
set(Output spu2x-2.0.0) set(Output spu2x-2.0.0)
if (UNIX AND NOT APPLE) if (UNIX)
if (SDL2_API) if (SDL2_API)
set(spu2xFinalFlags "-DSPU2X_SDL2" ${CommonFlags}) set(spu2xFinalFlags "-DSPU2X_SDL2" ${CommonFlags})
else() else()

View File

@ -23,6 +23,9 @@
#include <SDL.h> #include <SDL.h>
#include <SDL_audio.h> #include <SDL_audio.h>
#endif #endif
#ifdef __APPLE__
#include <dispatch/dispatch.h>
#endif
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
static const int LATENCY_MAX = 3000; static const int LATENCY_MAX = 3000;
@ -147,7 +150,7 @@ void ReadSettings()
#endif #endif
#endif #endif
#ifdef __unix__ #if defined(__unix__) || defined(__APPLE__)
CfgReadStr(L"SDL", L"HostApi", temp, L"pulseaudio"); CfgReadStr(L"SDL", L"HostApi", temp, L"pulseaudio");
SdlOutputAPI = 0; SdlOutputAPI = 0;
#if SDL_MAJOR_VERSION >= 2 #if SDL_MAJOR_VERSION >= 2
@ -165,7 +168,7 @@ void ReadSettings()
#ifdef SPU2X_PORTAUDIO #ifdef SPU2X_PORTAUDIO
PortaudioOut->ReadSettings(); PortaudioOut->ReadSettings();
#endif #endif
#ifdef __unix__ #if defined(__unix__) || defined(__APPLE__)
SDLOut->ReadSettings(); SDLOut->ReadSettings();
#endif #endif
SoundtouchCfg::ReadSettings(); SoundtouchCfg::ReadSettings();
@ -218,7 +221,7 @@ void WriteSettings()
#ifdef SPU2X_PORTAUDIO #ifdef SPU2X_PORTAUDIO
PortaudioOut->WriteSettings(); PortaudioOut->WriteSettings();
#endif #endif
#ifdef __unix__ #if defined(__unix__) || defined(__APPLE__)
SDLOut->WriteSettings(); SDLOut->WriteSettings();
#endif #endif
SoundtouchCfg::WriteSettings(); SoundtouchCfg::WriteSettings();
@ -235,7 +238,7 @@ void debug_dialog()
DebugConfig::DisplayDialog(); DebugConfig::DisplayDialog();
} }
#if defined(__unix__) #if defined(__unix__) || defined(__APPLE__)
// Format the slider with ms. // Format the slider with ms.
static gchar *cb_scale_format_ms(GtkScale *scale, gdouble value) static gchar *cb_scale_format_ms(GtkScale *scale, gdouble value)
@ -334,6 +337,8 @@ void DisplayDialog()
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "0 - ALSA (recommended)"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "0 - ALSA (recommended)");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "1 - OSS (legacy)"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "1 - OSS (legacy)");
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "2 - JACK"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "2 - JACK");
#elif defined(__APPLE__)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "CoreAudio");
#else #else
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "OSS"); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(api_box), "OSS");
#endif #endif
@ -466,7 +471,11 @@ void DisplayDialog()
#else #else
switch (OutputAPI) { switch (OutputAPI) {
case 0: case 0:
#ifdef __APPLE__
PortaudioOut->SetApiSettings(L"CoreAudio");
#else
PortaudioOut->SetApiSettings(L"OSS"); PortaudioOut->SetApiSettings(L"OSS");
#endif
break; break;
default: default:
PortaudioOut->SetApiSettings(L"Unknown"); PortaudioOut->SetApiSettings(L"Unknown");
@ -499,10 +508,23 @@ void DisplayDialog()
void configure() void configure()
{ {
#ifdef __APPLE__
// Rest of macOS UI doesn't use GTK so we need to init it now
gtk_init(nullptr, nullptr);
// GTK expects us to be using its event loop, rather than Cocoa's
// If we call its stuff right now, it'll attempt to drain a static autorelease pool that was already drained by Cocoa (see https://github.com/GNOME/gtk/blob/8c1072fad1cb6a2e292fce2441b4a571f173ce0f/gdk/quartz/gdkeventloop-quartz.c#L640-L646)
// We can convince it that touching that pool would be unsafe by running all GTK calls within a CFRunLoop
// (Blocks submitted to the main queue by dispatch_async are run by its CFRunLoop)
dispatch_async(dispatch_get_main_queue(), ^{
#endif
initIni(); initIni();
ReadSettings(); ReadSettings();
DisplayDialog(); DisplayDialog();
WriteSettings(); WriteSettings();
delete spuConfig; delete spuConfig;
spuConfig = NULL; spuConfig = NULL;
#ifdef __APPLE__
// End of `dispatch_async(...` above
});
#endif
} }

View File

@ -154,7 +154,7 @@ void WriteSettings()
CfgWriteStr(Section, L"Reg_Dump_Filename", RegDumpFileName); CfgWriteStr(Section, L"Reg_Dump_Filename", RegDumpFileName);
} }
#ifdef __unix__ #if defined(__unix__) || defined(__APPLE__)
void DisplayDialog() void DisplayDialog()
{ {
GtkWidget *dialog; GtkWidget *dialog;

View File

@ -71,7 +71,7 @@ void WriteSettings()
CfgWriteInt(L"SOUNDTOUCH", L"OverlapMS", OverlapMS); CfgWriteInt(L"SOUNDTOUCH", L"OverlapMS", OverlapMS);
} }
#ifdef __unix__ #if defined(__unix__) || defined(__APPLE__)
static GtkWidget *seq_label, *seek_label, *over_label; static GtkWidget *seq_label, *seek_label, *over_label;
static GtkWidget *seq_slide, *seek_slide, *over_slide; static GtkWidget *seq_slide, *seek_slide, *over_slide;