DFInput: Implement SDL2 GameController support.

This change allows the user to use SDL2’s GameController API instead of the Joystick API.
The Game Controller API maps the buttons similar to an Xbox 360 controller, so some tricky mapping needed to be done.
Note that it currently only supports OS X.

git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@89828 e17a0e51-4ae3-4d35-97c3-1a29b211df97
This commit is contained in:
SND\MaddTheSane_cp 2014-04-08 02:33:19 +00:00
parent 0d4ea9238b
commit c875a3566e
24 changed files with 448 additions and 153 deletions

View File

@ -471,7 +471,6 @@
551A751717868BEB0052D185 /* version.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = version.plist; sourceTree = "<group>"; };
551A751E17868BEB0052D185 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = "<group>"; };
551A752017868BEB0052D185 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
551A752217868BEB0052D185 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = "<group>"; };
551A752517868BEB0052D185 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
551A752717868BEB0052D185 /* cfg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cfg.c; sourceTree = "<group>"; };
551A752817868BEB0052D185 /* cfg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cfg.h; sourceTree = "<group>"; };
@ -741,6 +740,7 @@
559366C612B694DF004ACC1E /* ix86_fpu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ix86_fpu.c; sourceTree = "<group>"; };
559366C712B694DF004ACC1E /* ix86_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ix86_mmx.c; sourceTree = "<group>"; };
559366C812B694DF004ACC1E /* ix86_sse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ix86_sse.c; sourceTree = "<group>"; };
5593804E18F38C060022C282 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
5598AAF017D2D5450024F71D /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
5598AAF217D2D5470024F71D /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
5598AAF517D2D54A0024F71D /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -2579,7 +2579,7 @@
551A752117868BEB0052D185 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
551A752217868BEB0052D185 /* English */,
5593804E18F38C060022C282 /* en */,
5598AAFB17D2E9E90024F71D /* fr */,
55707E901812357B007CC5D0 /* hu */,
558328D3184F246B00DFACE4 /* zh-Hans */,

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13C64" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5053"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NetPcsxrHIDInputPluginPadController">
@ -15,31 +15,29 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<window title="Input Configuration" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" wantsToBeColor="NO" visibleAtLaunch="NO" animationBehavior="default" id="5" userLabel="Configuration">
<window title="Input Configuration" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" visibleAtLaunch="NO" animationBehavior="default" id="5" userLabel="Configuration">
<windowStyleMask key="styleMask" titled="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="87" y="281" width="469" height="439"/>
<rect key="contentRect" x="87" y="281" width="469" height="474"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/>
<value key="minSize" type="size" width="310" height="160"/>
<view key="contentView" id="6">
<rect key="frame" x="0.0" y="0.0" width="469" height="439"/>
<rect key="frame" x="0.0" y="0.0" width="469" height="474"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<tabView translatesAutoresizingMaskIntoConstraints="NO" id="11">
<rect key="frame" x="13" y="51" width="443" height="382"/>
<rect key="frame" x="13" y="51" width="443" height="417"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Controller 1" identifier="pad1" id="9">
<view key="view" id="7">
<rect key="frame" x="10" y="33" width="423" height="336"/>
<rect key="frame" x="10" y="33" width="423" height="371"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="167">
<rect key="frame" x="0.0" y="0.0" width="423" height="336"/>
<rect key="frame" x="0.0" y="0.0" width="423" height="371"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<constraints>
<constraint firstAttribute="height" constant="336" id="MAN-ya-b9q"/>
<constraint firstAttribute="height" constant="371" id="MAN-ya-b9q"/>
<constraint firstAttribute="width" constant="423" id="bGa-w5-ZON"/>
</constraints>
</customView>
@ -55,15 +53,15 @@
</tabViewItem>
<tabViewItem label="Controller 2" identifier="pad2" id="8">
<view key="view" id="10">
<rect key="frame" x="10" y="33" width="423" height="336"/>
<rect key="frame" x="10" y="33" width="423" height="371"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="153">
<rect key="frame" x="0.0" y="0.0" width="423" height="336"/>
<rect key="frame" x="0.0" y="0.0" width="423" height="371"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<constraints>
<constraint firstAttribute="width" constant="423" id="H35-Lr-OgY"/>
<constraint firstAttribute="height" constant="336" id="HBB-Jg-lOB"/>
<constraint firstAttribute="height" constant="371" id="HBB-Jg-lOB"/>
</constraints>
</customView>
</subviews>
@ -82,7 +80,7 @@
</connections>
</tabView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="256">
<rect key="frame" x="396" y="13" width="59" height="32"/>
<rect key="frame" x="373" y="13" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="257">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -96,7 +94,7 @@ DQ
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="261">
<rect key="frame" x="314" y="13" width="82" height="32"/>
<rect key="frame" x="291" y="13" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="262">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -119,15 +117,16 @@ Gw
<constraint firstAttribute="trailing" secondItem="256" secondAttribute="trailing" constant="20" symbolic="YES" id="267"/>
<constraint firstItem="261" firstAttribute="baseline" secondItem="256" secondAttribute="baseline" id="C2F-N8-ou7"/>
<constraint firstItem="261" firstAttribute="top" secondItem="11" secondAttribute="bottom" constant="20" symbolic="YES" id="Iaf-EF-wEU"/>
<constraint firstItem="256" firstAttribute="width" secondItem="261" secondAttribute="width" id="vHo-ek-FKR"/>
</constraints>
</view>
</window>
<customView id="16" userLabel="Controller View" customClass="NetPcsxrHIDInputPluginPadView">
<rect key="frame" x="0.0" y="0.0" width="423" height="336"/>
<rect key="frame" x="0.0" y="0.0" width="423" height="371"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="194">
<rect key="frame" x="18" y="300" width="43" height="14"/>
<rect key="frame" x="18" y="335" width="43" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Device:" id="208">
<font key="font" metaFont="smallSystem"/>
@ -136,7 +135,7 @@ Gw
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" tag="1" translatesAutoresizingMaskIntoConstraints="NO" id="189">
<rect key="frame" x="64" y="295" width="195" height="22"/>
<rect key="frame" x="64" y="330" width="195" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="189" id="4yb-mx-WCf"/>
@ -155,7 +154,7 @@ Gw
</connections>
</popUpButton>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="185">
<rect key="frame" x="62" y="10" width="299" height="14"/>
<rect key="frame" x="62" y="42" width="299" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="center" title="To reset an entry: Select it and press the delete '←' key" id="206">
<font key="font" metaFont="smallSystem"/>
@ -164,7 +163,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="132">
<rect key="frame" x="262" y="300" width="36" height="14"/>
<rect key="frame" x="262" y="335" width="36" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" alignment="right" title="Type:" id="205">
<font key="font" metaFont="smallSystem"/>
@ -173,7 +172,7 @@ Gw
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" tag="2" translatesAutoresizingMaskIntoConstraints="NO" id="126">
<rect key="frame" x="301" y="295" width="105" height="22"/>
<rect key="frame" x="301" y="330" width="105" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="99" id="236"/>
@ -197,14 +196,14 @@ Gw
</connections>
</popUpButton>
<scrollView horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="121">
<rect key="frame" x="20" y="32" width="383" height="258"/>
<rect key="frame" x="20" y="64" width="383" height="261"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<clipView key="contentView" id="xit-lf-WfZ">
<rect key="frame" x="1" y="17" width="381" height="240"/>
<rect key="frame" x="1" y="17" width="366" height="243"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" tag="1" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="14" headerView="212" id="123">
<rect key="frame" x="0.0" y="0.0" width="381" height="240"/>
<rect key="frame" x="0.0" y="0.0" width="366" height="243"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@ -223,7 +222,7 @@ Gw
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</textFieldCell>
</tableColumn>
<tableColumn identifier="button" width="254.96499633789062" minWidth="46.965000152587891" maxWidth="1000" id="124">
<tableColumn identifier="button" width="239.96499633789062" minWidth="46.965000152587891" maxWidth="1000" id="124">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Button">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -249,26 +248,39 @@ Gw
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="210">
<rect key="frame" x="366" y="17" width="16" height="240"/>
<rect key="frame" x="367" y="17" width="15" height="243"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="212">
<rect key="frame" x="0.0" y="0.0" width="381" height="17"/>
<rect key="frame" x="0.0" y="0.0" width="366" height="17"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
<button toolTip="Uses the SDL2 Game Controller API to automatically map buttons" translatesAutoresizingMaskIntoConstraints="NO" id="e1h-QZ-6Ge">
<rect key="frame" x="18" y="18" width="176" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Use Game Controller API" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="XyD-IN-gbq">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="toggleSDL2:" target="16" id="Tey-Wc-OLI"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="126" firstAttribute="leading" secondItem="132" secondAttribute="trailing" constant="8" symbolic="YES" id="238"/>
<constraint firstItem="132" firstAttribute="leading" secondItem="189" secondAttribute="trailing" constant="8" symbolic="YES" id="248"/>
<constraint firstItem="189" firstAttribute="leading" secondItem="194" secondAttribute="trailing" constant="8" symbolic="YES" id="277"/>
<constraint firstAttribute="bottom" secondItem="185" secondAttribute="bottom" constant="10" id="290"/>
<constraint firstItem="185" firstAttribute="top" secondItem="121" secondAttribute="bottom" constant="8" symbolic="YES" id="291"/>
<constraint firstItem="121" firstAttribute="top" secondItem="126" secondAttribute="bottom" constant="8" symbolic="YES" id="1x0-zI-e7A"/>
<constraint firstItem="132" firstAttribute="baseline" secondItem="194" secondAttribute="baseline" id="BCf-9Q-wD8"/>
<constraint firstItem="121" firstAttribute="trailing" secondItem="126" secondAttribute="trailing" id="Cpf-JP-y1U"/>
<constraint firstItem="e1h-QZ-6Ge" firstAttribute="top" secondItem="185" secondAttribute="bottom" constant="8" symbolic="YES" id="FPM-zy-889"/>
<constraint firstAttribute="bottom" secondItem="e1h-QZ-6Ge" secondAttribute="bottom" constant="20" symbolic="YES" id="GJ2-vT-ITb"/>
<constraint firstItem="132" firstAttribute="baseline" secondItem="126" secondAttribute="baseline" id="Gpf-Vs-HAL"/>
<constraint firstAttribute="centerX" secondItem="185" secondAttribute="centerX" id="H9E-Ql-g68"/>
<constraint firstItem="e1h-QZ-6Ge" firstAttribute="leading" secondItem="16" secondAttribute="leading" constant="20" symbolic="YES" id="JUT-z6-29z"/>
<constraint firstAttribute="centerX" secondItem="121" secondAttribute="centerX" id="Mor-Zp-Kl1"/>
<constraint firstItem="189" firstAttribute="top" secondItem="16" secondAttribute="top" constant="20" symbolic="YES" id="kWH-eJ-7CV"/>
<constraint firstItem="194" firstAttribute="leading" secondItem="16" secondAttribute="leading" constant="20" symbolic="YES" id="nGT-PI-3rO"/>
@ -279,7 +291,8 @@ Gw
<outlet property="deviceMenu" destination="189" id="200"/>
<outlet property="tableView" destination="123" id="133"/>
<outlet property="typeMenu" destination="126" id="134"/>
<outlet property="useSDL2Check" destination="e1h-QZ-6Ge" id="R4k-Le-dph"/>
</connections>
</customView>
</objects>
</document>
</document>

View File

@ -41,7 +41,15 @@
"R-Stick Down" = "R-Stick Down";
"R-Stick Up" = "R-Stick Up";
//Unused right now
// Game Controller names
"Left Bumper" = "Left Bumper";
"Right Bumper" = "Right Bumper";
"Left Trigger" = "Left Trigger";
"Right Trigger" = "Right Trigger";
"Guide" = "Guide";
"Back" = "Back";
// Unused right now
"Centered" = "Centered";
"Up" = "Up";
"Right" = "Right";
@ -51,5 +59,3 @@
"Left" = "Left";
"Leftup" = "Left-up";
"Leftdown" = "Left-down";

View File

@ -46,3 +46,9 @@
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "262"; */
"262.title" = "Cancel";
/* Class = "NSButtonCell"; title = "Use Game Controller API"; ObjectID = "XyD-IN-gbq"; */
"XyD-IN-gbq.title" = "Use Game Controller API";
/* Class = "NSButton"; ibShadowedToolTip = "Uses the SDL2 Game Controller API to automatically map buttons"; ObjectID = "e1h-QZ-6Ge"; */
"e1h-QZ-6Ge.ibShadowedToolTip" = "Uses the SDL2 Game Controller API to automatically map buttons";

View File

@ -15,7 +15,6 @@
"(Keyboard only)" = "(Keyboard only)";
"(Not Set)" = "(Non défini)";
"D-Pad Up" = "Pavé directionnel Haut";
"D-Pad Down" = "Pavé directionnel Bas";
"D-Pad Left" = "Pavé directionnel Gauche";
@ -32,7 +31,7 @@
"Start" = "Start";
"L3" = "L3";
"R3" = "R3";
//"Analog" = "Analog"; //Not translated
//"Analog" = "Analog"; // Not translated
"L-Stick Right" = "L-Stick Droite";
"L-Stick Left" = "L-Stick Gauche";
"L-Stick Down" = "L-Stick Bas";
@ -42,7 +41,15 @@
"R-Stick Down" = "R-Stick Bas";
"R-Stick Up" = "R-Stick Haut";
//Unused right now
// Game Controller names
//"Left Bumper" = "Left Bumper";
//"Right Bumper" = "Right Bumper";
//"Left Trigger" = "Left Trigger";
//"Right Trigger" = "Right Trigger";
//"Guide" = "Guide";
//"Back" = "Back";
// Unused right now
"Centered" = "Centré";
"Up" = "Haut";
"Right" = "Droite";

View File

@ -46,3 +46,9 @@
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "262"; */
"262.title" = "Cancel";
/* Class = "NSButtonCell"; title = "Use Game Controller API"; ObjectID = "XyD-IN-gbq"; */
//"XyD-IN-gbq.title" = "Use Game Controller API";
/* Class = "NSButton"; ibShadowedToolTip = "Uses the SDL2 Game Controller API to automatically map buttons"; ObjectID = "e1h-QZ-6Ge"; */
//"e1h-QZ-6Ge.ibShadowedToolTip" = "Uses the SDL2 Game Controller API to automatically map buttons";

View File

@ -41,7 +41,15 @@
"R-Stick Down" = "Jobb kar le";
"R-Stick Up" = "Jobb kar fel";
//Unused right now
// Game Controller names
//"Left Bumper" = "Left Bumper";
//"Right Bumper" = "Right Bumper";
//"Left Trigger" = "Left Trigger";
//"Right Trigger" = "Right Trigger";
//"Guide" = "Guide";
//"Back" = "Back";
// Unused right now
"Centered" = "Középen";
"Up" = "Fel";
"Right" = "Jobbra";

View File

@ -46,3 +46,9 @@
/* Class = "NSButtonCell"; title = "Cancel"; ObjectID = "262"; */
"262.title" = "Cancel";
/* Class = "NSButtonCell"; title = "Use Game Controller API"; ObjectID = "XyD-IN-gbq"; */
//"XyD-IN-gbq.title" = "Use Game Controller API";
/* Class = "NSButton"; ibShadowedToolTip = "Uses the SDL2 Game Controller API to automatically map buttons"; ObjectID = "e1h-QZ-6Ge"; */
//"e1h-QZ-6Ge.ibShadowedToolTip" = "Uses the SDL2 Game Controller API to automatically map buttons";

View File

@ -25,14 +25,13 @@
#include "cfg.h"
@interface ControllerList : NSObject <NSTableViewDataSource>
@property (getter = isUsingSDL2) BOOL usingSDL2;
- (id)initWithConfig;
+ (void)setCurrentController:(int)which;
+ (int)currentController;
+ (int)buttonOfRow:(NSInteger)row;
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
- (void)deleteRow:(NSInteger)which;
@end

View File

@ -25,43 +25,83 @@
static int currentController;
static NSArray *labelText;
static NSArray *GameControllerText;
@implementation ControllerList
- (BOOL)isUsingSDL2
{
return g.cfg.PadDef[currentController].UseSDL2;
}
- (void)setUsingSDL2:(BOOL)_usingSDL2
{
g.cfg.PadDef[currentController].UseSDL2 = _usingSDL2;
}
- (id)initWithConfig
{
if (self = [super init]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *plugBundle = [NSBundle bundleForClass:[ControllerList class]];
labelText = @[[plugBundle localizedStringForKey:@"D-Pad Up" value:@"" table:nil],
[plugBundle localizedStringForKey:@"D-Pad Down" value:@"" table:nil],
[plugBundle localizedStringForKey:@"D-Pad Left" value:@"" table:nil],
[plugBundle localizedStringForKey:@"D-Pad Right" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Cross" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Circle" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Square" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Triangle" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L1" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R1" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L2" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R2" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Select" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Start" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L3" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R3" value:@"" table:nil],
[plugBundle localizedStringForKey:@"Analog" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L-Stick Right" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L-Stick Left" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L-Stick Down" value:@"" table:nil],
[plugBundle localizedStringForKey:@"L-Stick Up" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R-Stick Right" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R-Stick Left" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R-Stick Down" value:@"" table:nil],
[plugBundle localizedStringForKey:@"R-Stick Up" value:@"" table:nil]];
NSBundle *plugBundle = [NSBundle bundleForClass:[self class]];
labelText = @[NSLocalizedStringFromTableInBundle(@"D-Pad Up", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Cross", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Circle", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Square", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Triangle", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L1", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R1", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L2", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R2", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Select", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Start", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L3", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R3", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Analog", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Up", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Up", nil, plugBundle, @"")];
GameControllerText = @[NSLocalizedStringFromTableInBundle(@"D-Pad Up", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"D-Pad Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Cross", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Circle", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Square", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Triangle", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Left Bumper", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Right Bumper", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Left Trigger", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Right Trigger", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Back", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Start", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L3", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R3", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"Guide", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"L-Stick Up", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Right", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Left", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Down", nil, plugBundle, @""),
NSLocalizedStringFromTableInBundle(@"R-Stick Up", nil, plugBundle, @"")];
});
}
return self;
@ -117,6 +157,18 @@ static const int DPad[DKEY_TOTAL] = {
} else {
char buf[256] = {0};
if ([self isUsingSDL2]) {
NSString *keyBoardString, *gamePadStr = GameControllerText[rowIndex];
if (rowIndex < DKEY_TOTAL) {
GetKeyboardKeyDescription(buf, currentController, DPad[rowIndex]);
} else {
NSInteger tmpRowIndex = rowIndex - DKEY_TOTAL;
GetKeyboardAnalogDescription(buf, currentController, (int)(tmpRowIndex / 4), tmpRowIndex % 4);
}
keyBoardString = @(buf);
return [keyBoardString isEqualToString:@""] ? gamePadStr : [gamePadStr stringByAppendingFormat:@" / %@", keyBoardString];
} else {
// actual keys
if (rowIndex < DKEY_TOTAL) {
GetKeyDescription(buf, currentController, DPad[rowIndex]);
@ -126,6 +178,7 @@ static const int DPad[DKEY_TOTAL] = {
}
return @(buf);
}
}
}

View File

@ -26,8 +26,10 @@
@implementation MappingCell
- (id)initTextCell:(NSString *)aString {
self = [super initTextCell:aString];
[self setEditable:NO];
if (self = [super initTextCell:aString]) {
[self setEditable:NO];
}
return self;
}

View File

@ -35,6 +35,6 @@
- (IBAction)ok:(id)sender;
@end
extern NSDictionary *DefaultPadArray(int padnum);
extern void LoadPadArray(int padnum, NSDictionary *nsPrefs);
extern NSDictionary *SavePadArray(int padnum);
__private_extern__ NSDictionary *DefaultPadArray(int padnum);
__private_extern__ void LoadPadArray(int padnum, NSDictionary *nsPrefs);
__private_extern__ NSDictionary *SavePadArray(int padnum);

View File

@ -145,8 +145,8 @@ void LoadPADConfig()
[usrDefaults registerDefaults:
@{PrefsKey: @{kDFPad1: DefaultPadArray(0),
kDFPad2: DefaultPadArray(1),
kDFThreading: @YES}}];
kDFPad2: DefaultPadArray(1),
kDFThreading: @YES}}];
//Load the old preferences if present and we don't have new ones.
NSFileManager *fm = [NSFileManager defaultManager];

View File

@ -32,9 +32,11 @@
ControllerList *controller;
}
@property (weak) IBOutlet NSButton *useSDL2Check;
- (IBAction)setType:(id)sender;
- (IBAction)setDevice:(id)sender;
- (IBAction)toggleSDL2:(id)sender;
- (void)setController:(int)which;
@end

View File

@ -26,7 +26,7 @@
- (id)initWithFrame:(NSRect)frameRect
{
if ((self = [super initWithFrame:frameRect]) != nil) {
if (self = [super initWithFrame:frameRect]) {
controller = [[ControllerList alloc] initWithConfig];
[self setController:0];
}
@ -35,13 +35,14 @@
- (void)drawRect:(NSRect)rect
{
}
- (IBAction)setType:(id)sender
{
g.cfg.PadDef[[ControllerList currentController]].Type =
([sender indexOfSelectedItem] > 0 ? PSE_PAD_TYPE_ANALOGPAD : PSE_PAD_TYPE_STANDARD);
[tableView reloadData];
}
@ -50,36 +51,49 @@
g.cfg.PadDef[[ControllerList currentController]].DevNum = (int)[sender indexOfSelectedItem] - 1;
}
- (IBAction)toggleSDL2:(id)sender
{
controller.usingSDL2 = !controller.usingSDL2;
[tableView reloadData];
}
- (void)setController:(int)which
{
int i;
[ControllerList setCurrentController:which];
[tableView setDataSource:controller];
[deviceMenu removeAllItems];
[deviceMenu addItemWithTitle:[[NSBundle bundleForClass:[self class]] localizedStringForKey:@"(Keyboard only)" value:@"" table:nil]];
for (i = 0; i < SDL_NumJoysticks(); i++) {
NSMenuItem *joystickItem = nil;
NSMenuItem *joystickItem;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Joystick *tmpJoy = SDL_JoystickOpen(i);
joystickItem = [[NSMenuItem alloc] initWithTitle:@(SDL_JoystickName(tmpJoy)) action:NULL keyEquivalent:@""];
SDL_JoystickClose(tmpJoy);
NSString *tmpString;
if (SDL_IsGameController(i)) {
tmpString = @(SDL_GameControllerNameForIndex(i));
} else {
tmpString = @(SDL_JoystickNameForIndex(i));
}
joystickItem = [[NSMenuItem alloc] initWithTitle:tmpString action:NULL keyEquivalent:@""];
#else
joystickItem = [[NSMenuItem alloc] initWithTitle:@(SDL_JoystickName(i)) action:NULL keyEquivalent:@""];
#endif
[joystickItem setTag:i + 1];
[[deviceMenu menu] addItem:joystickItem];
}
if (g.cfg.PadDef[which].DevNum >= SDL_NumJoysticks()) {
g.cfg.PadDef[which].DevNum = -1;
}
[deviceMenu selectItemAtIndex:g.cfg.PadDef[which].DevNum + 1];
[typeMenu selectItemAtIndex:(g.cfg.PadDef[which].Type == PSE_PAD_TYPE_ANALOGPAD ? 1 : 0)];
[self.useSDL2Check setState:g.cfg.PadDef[which].UseSDL2 ? NSOnState : NSOffState];
[tableView reloadData];
}
@ -92,7 +106,7 @@
- (void)keyDown:(NSEvent *)theEvent
{
unsigned short key = [theEvent keyCode];
if ([[theEvent window] firstResponder] == tableView) {
if (key == 51 || key == 117) {
// delete keys - remove the mappings for the selected item
@ -105,7 +119,7 @@
return;
}
}
[super keyDown:theEvent];
}

View File

@ -25,7 +25,8 @@ long DoConfiguration();
void DoAbout();
long PADconfigure(void) {
if (SDL_WasInit(SDL_INIT_JOYSTICK)) return PSE_ERR_FATAL; // cannot change settings on the fly
if (SDL_WasInit(SDL_INIT_JOYSTICK))
return PSE_ERR_FATAL; // cannot change settings on the fly
DoConfiguration();
//LoadPADConfig();
@ -152,7 +153,7 @@ static const char *XKeysymToString(uint16_t key) {
i++;
}
sprintf(buf, "0x%.2X", key);
snprintf(buf, sizeof(buf), "0x%.2X", key);
return buf;
}
@ -194,6 +195,24 @@ void GetKeyDescription(char *buf, int joynum, int key)
}
}
void GetKeyboardKeyDescription(char *buf, int joynum, int key)
{
if (g.cfg.PadDef[joynum].KeyDef[key].Key != 0) {
sprintf(buf, _("Keyboard: %s"), XKeysymToString(g.cfg.PadDef[joynum].KeyDef[key].Key));
} else {
buf[0] = '\0';
}
}
void GetKeyboardAnalogDescription(char *buf, int joynum, int analognum, int dir)
{
if (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key != 0) {
sprintf(buf, _("Keyboard: %s"), XKeysymToString(g.cfg.PadDef[joynum].AnalogDef[analognum][dir].Key));
} else {
buf[0] = '\0';
}
}
void GetAnalogDescription(char *buf, int joynum, int analognum, int dir)
{
switch (g.cfg.PadDef[joynum].AnalogDef[analognum][dir].JoyEvType) {

View File

@ -23,6 +23,8 @@
void GetKeyDescription(char *buf, int joynum, int key);
void GetAnalogDescription(char *buf, int joynum, int analognum, int dir);
void GetKeyboardKeyDescription(char *buf, int joynum, int key);
void GetKeyboardAnalogDescription(char *buf, int joynum, int analognum, int dir);
void InitAxisPos(int padnum);
int ReadDKeyEvent(int padnum, int key);
int ReadAnalogEvent(int padnum, int analognum, int analogdir);

View File

@ -43,6 +43,7 @@
#define dRightAnalogYM @"RightAnalogYM"
#define VibrateOn @"Visual Vibration"
#define UseSDL2Mapping @"SDL2 Mapping"
NSDictionary *DefaultPadArray(int padnum)
{
@ -63,7 +64,8 @@ NSDictionary *DefaultPadArray(int padnum)
dTriangle: [NSMutableDictionary dictionaryWithObjectsAndKeys:@0, joyVal, @(BUTTON), joyType, nil],
dCircle: [NSMutableDictionary dictionaryWithObjectsAndKeys:@1, joyVal, @(BUTTON), joyType, nil],
dCross: [NSMutableDictionary dictionaryWithObjectsAndKeys:@2, joyVal, @(BUTTON), joyType, nil],
dSquare: [NSMutableDictionary dictionaryWithObjectsAndKeys:@3, joyVal, @(BUTTON), joyType, nil]}];
dSquare: [NSMutableDictionary dictionaryWithObjectsAndKeys:@3, joyVal, @(BUTTON), joyType, nil],
UseSDL2Mapping: @YES}];
if (padnum == 0) {
mutArray[dSelect][dfKey] = @9;
mutArray[dStart][dfKey] = @10;
@ -154,6 +156,7 @@ void LoadPadArray(int padnum, NSDictionary *nsPrefs)
curDef->DevNum = [nsPrefs[deviceNumber] charValue];
curDef->Type = [nsPrefs[padType] unsignedShortValue];
curDef->VisualVibration = [nsPrefs[VibrateOn] boolValue]; //Not implemented on OS X right now.
curDef->UseSDL2 = [nsPrefs[UseSDL2Mapping] boolValue];
//Analog buttons
SetKeyFromDictionary(nsPrefs[dL3], &curDef->KeyDef[DKEY_L3]);
@ -192,7 +195,7 @@ void LoadPadArray(int padnum, NSDictionary *nsPrefs)
NSDictionary *SavePadArray(int padnum)
{
NSMutableDictionary *mutArray = [NSMutableDictionary dictionary];
NSMutableDictionary *mutArray = [[NSMutableDictionary alloc] init];
PADDEF *curDef = &g.cfg.PadDef[padnum];
mutArray[deviceNumber] = @(curDef->DevNum);
mutArray[padType] = @(curDef->Type);
@ -200,7 +203,6 @@ NSDictionary *SavePadArray(int padnum)
switch (curDef->Type) {
case PSE_PAD_TYPE_ANALOGPAD:
{
mutArray[dL3] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_L3]);
mutArray[dR3] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_R3]);
mutArray[dAnalog] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_ANALOG]);
@ -214,11 +216,9 @@ NSDictionary *SavePadArray(int padnum)
mutArray[dRightAnalogXM] = DictionaryFromButtonDef(curDef->AnalogDef[ANALOG_RIGHT][ANALOG_XM]);
mutArray[dRightAnalogYP] = DictionaryFromButtonDef(curDef->AnalogDef[ANALOG_RIGHT][ANALOG_YP]);
mutArray[dRightAnalogYM] = DictionaryFromButtonDef(curDef->AnalogDef[ANALOG_RIGHT][ANALOG_YM]);
}
//Fall through
case PSE_PAD_TYPE_STANDARD:
{
mutArray[dL1] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_L1]);
mutArray[dL2] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_L2]);
mutArray[dR1] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_R1]);
@ -234,7 +234,7 @@ NSDictionary *SavePadArray(int padnum)
mutArray[dCircle] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_CIRCLE]);
mutArray[dCross] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_CROSS]);
mutArray[dSquare] = DictionaryFromButtonDef(curDef->KeyDef[DKEY_SQUARE]);
}
mutArray[UseSDL2Mapping] = @((BOOL)curDef->UseSDL2);
break;
default:

View File

@ -41,7 +41,15 @@
"R-Stick Down" = "R-摇杆 ↓ / 下";
"R-Stick Up" = "R-摇杆 ↑ / 上";
//Unused right now
// Game Controller names
//"Left Bumper" = "Left Bumper";
//"Right Bumper" = "Right Bumper";
//"Left Trigger" = "Left Trigger";
//"Right Trigger" = "Right Trigger";
//"Guide" = "Guide";
//"Back" = "Back";
// Unused right now
"Centered" = "中间键";
"Up" = "↑ / 上";
"Right" = "→ / 右";

View File

@ -46,3 +46,9 @@
/* Class = "NSButtonCell"; title = "取消"; ObjectID = "262"; */
"262.title" = "取消";
/* Class = "NSButtonCell"; title = "Use Game Controller API"; ObjectID = "XyD-IN-gbq"; */
//"XyD-IN-gbq.title" = "Use Game Controller API";
/* Class = "NSButton"; ibShadowedToolTip = "Uses the SDL2 Game Controller API to automatically map buttons"; ObjectID = "e1h-QZ-6Ge"; */
//"e1h-QZ-6Ge.ibShadowedToolTip" = "Uses the SDL2 Game Controller API to automatically map buttons";

View File

@ -18,6 +18,15 @@
#include "pad.h"
#if SDL_VERSION_ATLEAST(2,0,0)
static SDL_GameControllerAxis PsxAxisMap[] = {
SDL_CONTROLLER_AXIS_LEFTX,
SDL_CONTROLLER_AXIS_LEFTY,
SDL_CONTROLLER_AXIS_RIGHTX,
SDL_CONTROLLER_AXIS_RIGHTY
};
#endif
void InitAnalog() {
g.PadState[0].AnalogStatus[ANALOG_LEFT][0] = 127;
g.PadState[0].AnalogStatus[ANALOG_LEFT][1] = 127;
@ -42,6 +51,23 @@ void CheckAnalog() {
}
for (j = 0; j < ANALOG_TOTAL; j++) {
#if SDL_VERSION_ATLEAST(2,0,0)
if (g.PadState[i].GCDev != NULL) {
for(k = 0; k < 2; k++) {
unsigned int absVal;
val = SDL_GameControllerGetAxis(g.PadState[i].GCDev, PsxAxisMap[j << 1 | k]);
absVal = abs(val);
if (absVal > 0) {
absVal += 32640;
absVal /= 256;
g.PadState[i].AnalogStatus[j][k] = val > 0 ? absVal : -absVal;
} else {
g.PadState[i].AnalogStatus[j][k] = 0;
}
}
continue;
}
#endif
for (k = 0; k < 4; k++) {
if (g.PadState[i].AnalogKeyStatus[j][k]) {
switch (k) {

View File

@ -25,6 +25,27 @@
#if SDL_VERSION_ATLEAST(2,0,0)
int has_haptic;
SDL_GameControllerButton controllerMap[] = {
SDL_CONTROLLER_BUTTON_BACK,
SDL_CONTROLLER_BUTTON_LEFTSTICK,
SDL_CONTROLLER_BUTTON_RIGHTSTICK,
SDL_CONTROLLER_BUTTON_START,
SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_INVALID, //SDL2 doesn't map the bumpers to buttons, but axies
SDL_CONTROLLER_BUTTON_INVALID, //The bumpers are analogous to L2 and R2
SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
SDL_CONTROLLER_BUTTON_Y,
SDL_CONTROLLER_BUTTON_B,
SDL_CONTROLLER_BUTTON_A,
SDL_CONTROLLER_BUTTON_X,
SDL_CONTROLLER_BUTTON_GUIDE
};
#endif
static void (*gpuVisualVibration)(uint32_t, uint32_t) = NULL;
@ -100,6 +121,8 @@ long PADopen(unsigned long *Disp) {
}
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
has_haptic = 0;
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) == 0)
has_haptic = 1;
@ -135,14 +158,16 @@ long PADclose(void) {
DestroySDLJoy();
DestroyKeyboard();
#if SDL_VERSION_ATLEAST(2,0,0)
if (SDL_WasInit(SDL_INIT_EVERYTHING & ~(SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK))) {
if (SDL_WasInit(SDL_INIT_EVERYTHING & ~(SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER))) {
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
} else
#endif
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
} else {
#else
if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_JOYSTICK)) {
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
} else {
#endif
SDL_Quit();
}
}

View File

@ -38,6 +38,7 @@ extern "C" {
#include <SDL_joystick.h>
#if SDL_VERSION_ATLEAST(2,0,0)
#include <SDL_haptic.h>
#include <SDL_gamecontroller.h>
#endif
#ifdef _MACOSX
@ -147,12 +148,19 @@ typedef struct tagKeyDef {
enum { ANALOG_XP = 0, ANALOG_XM, ANALOG_YP, ANALOG_YM };
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_GameControllerButton controllerMap[DKEY_TOTAL];
#endif
typedef struct tagPadDef {
int8_t DevNum;
uint16_t Type;
uint8_t VisualVibration;
KEYDEF KeyDef[DKEY_TOTAL];
KEYDEF AnalogDef[ANALOG_TOTAL][4];
#if SDL_VERSION_ATLEAST(2,0,0)
int8_t UseSDL2;
#endif
} PADDEF;
typedef struct tagEmuDef {
@ -188,7 +196,8 @@ typedef struct tagPadState {
uint8_t Vib0, Vib1;
volatile uint8_t VibF[2];
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_Haptic *haptic;
SDL_Haptic *haptic;
SDL_GameController *GCDev;
#else
#ifdef __linux__
int VibrateDev;

View File

@ -18,44 +18,44 @@
#include "pad.h"
#if SDL_VERSION_ATLEAST(2,0,0)
static SDL_HapticEffect haptic_rumbleEffect;
#endif
void JoyInitHaptic()
{
#if SDL_VERSION_ATLEAST(2,0,0)
uint8_t i;
uint8_t i;
//unsigned int haptic_query = 0;
for (i = 0; i < 2; i++)
{
if (g.PadState[i].JoyDev && SDL_JoystickIsHaptic(g.PadState[i].JoyDev))
{
if (g.PadState[i].haptic != NULL)
{
SDL_HapticClose(g.PadState[i].haptic);
g.PadState[i].haptic = NULL;
}
for (i = 0; i < 2; i++)
{
SDL_Joystick *curJoy = g.PadState[i].JoyDev;
if (!curJoy && g.PadState[i].GCDev) {
curJoy = SDL_GameControllerGetJoystick(g.PadState[i].GCDev);
}
if (SDL_JoystickIsHaptic(curJoy))
{
if (g.PadState[i].haptic != NULL)
{
SDL_HapticClose(g.PadState[i].haptic);
g.PadState[i].haptic = NULL;
}
g.PadState[i].haptic = SDL_HapticOpenFromJoystick(g.PadState[i].JoyDev);
if (g.PadState[i].haptic == NULL)
continue;
g.PadState[i].haptic = SDL_HapticOpenFromJoystick(curJoy);
if (g.PadState[i].haptic == NULL)
continue;
if (SDL_HapticRumbleSupported(g.PadState[i].haptic) == SDL_FALSE)
{
printf("\nRumble not supported\n");
g.PadState[i].haptic = NULL;
continue;
}
if (SDL_HapticRumbleSupported(g.PadState[i].haptic) == SDL_FALSE)
{
printf("\nRumble not supported\n");
g.PadState[i].haptic = NULL;
continue;
}
if (SDL_HapticRumbleInit(g.PadState[i].haptic) != 0)
{
printf("\nFailed to initialize rumble: %s\n", SDL_GetError());
g.PadState[i].haptic = NULL;
continue;
}
}
}
if (SDL_HapticRumbleInit(g.PadState[i].haptic) != 0)
{
printf("\nFailed to initialize rumble: %s\n", SDL_GetError());
g.PadState[i].haptic = NULL;
continue;
}
}
}
#endif
}
@ -84,14 +84,22 @@ int JoyHapticRumble(int pad, uint32_t low, uint32_t high)
void InitSDLJoy() {
uint8_t i;
uint8_t emukeydev;
g.PadState[0].JoyKeyStatus = 0xFFFF;
g.PadState[1].JoyKeyStatus = 0xFFFF;
for (i = 0; i < 2; i++) {
if (g.cfg.PadDef[i].DevNum >= 0) {
#if SDL_VERSION_ATLEAST(2,0,0)
if (g.cfg.PadDef[i].UseSDL2) {
g.PadState[i].GCDev = SDL_GameControllerOpen(g.cfg.PadDef[i].DevNum);
}
if (!g.PadState[i].GCDev) {
g.PadState[i].JoyDev = SDL_JoystickOpen(g.cfg.PadDef[i].DevNum);
}
#else
g.PadState[i].JoyDev = SDL_JoystickOpen(g.cfg.PadDef[i].DevNum);
#endif
// Saves an extra call to SDL joystick open
if (g.cfg.E.DevNum == g.cfg.PadDef[i].DevNum) {
g.cfg.E.EmuKeyDev = g.PadState[i].JoyDev;
@ -106,10 +114,10 @@ void InitSDLJoy() {
}
#if SDL_VERSION_ATLEAST(2,0,0)
if (has_haptic)
{
JoyInitHaptic();
}
if (has_haptic)
{
JoyInitHaptic();
}
#endif
if (g.cfg.E.EmuKeyDev == 0 && g.cfg.E.DevNum >= 0) {
@ -117,6 +125,9 @@ void InitSDLJoy() {
}
SDL_JoystickEventState(SDL_IGNORE);
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_GameControllerEventState(SDL_IGNORE);
#endif
InitAnalog();
}
@ -126,21 +137,31 @@ void DestroySDLJoy() {
if (SDL_WasInit(SDL_INIT_JOYSTICK)) {
for (i = 0; i < 2; i++) {
if (g.PadState[i].JoyDev != NULL) {
#if SDL_VERSION_ATLEAST(2,0,0)
if (g.PadState[i].haptic != NULL)
{
SDL_HapticClose(g.PadState[i].haptic);
g.PadState[i].haptic = NULL;
}
#endif
if (g.PadState[i].JoyDev != NULL || g.PadState[i].GCDev != NULL) {
if (g.PadState[i].haptic != NULL) {
SDL_HapticClose(g.PadState[i].haptic);
g.PadState[i].haptic = NULL;
}
if (g.PadState[i].GCDev != NULL) {
SDL_GameControllerClose(g.PadState[i].GCDev);
} else {
SDL_JoystickClose(g.PadState[i].JoyDev);
}
}
#else
if (g.PadState[i].JoyDev != NULL) {
SDL_JoystickClose(g.PadState[i].JoyDev);
}
#endif
}
}
for (i = 0; i < 2; i++) {
g.PadState[i].JoyDev = NULL;
#if SDL_VERSION_ATLEAST(2,0,0)
g.PadState[i].GCDev = NULL;
#endif
}
g.cfg.E.EmuKeyDev = NULL;
}
@ -167,14 +188,14 @@ static void bup(int pad, int bit)
void CheckJoy() {
uint8_t i, j, n;
#if SDL_VERSION_ATLEAST(2,0,0)
SDL_GameControllerUpdate();
#endif
SDL_JoystickUpdate();
for (i = 0; i < 2; i++) {
if (g.PadState[i].JoyDev == NULL) {
continue;
}
if (g.PadState[i].JoyDev != NULL) {
g.PadState[i].JoyKeyStatus = ~0;
for (j = 0; j < DKEY_TOTAL; j++) {
switch (g.cfg.PadDef[i].KeyDef[j].JoyEvType) {
@ -219,6 +240,63 @@ void CheckJoy() {
}
}
}
#if SDL_VERSION_ATLEAST(2,0,0)
if (g.PadState[i].GCDev != NULL) {
g.PadState[i].JoyKeyStatus = ~0;
for (j = 0; j < DKEY_TOTAL; j++) {
Sint16 axis2;
switch (j) {
case DKEY_SELECT:
case DKEY_L3:
case DKEY_R3:
case DKEY_START:
case DKEY_UP:
case DKEY_RIGHT:
case DKEY_DOWN:
case DKEY_LEFT:
case DKEY_L1:
case DKEY_R1:
case DKEY_TRIANGLE:
case DKEY_CIRCLE:
case DKEY_CROSS:
case DKEY_SQUARE:
case DKEY_ANALOG:
if (SDL_GameControllerGetButton(g.PadState[i].GCDev, controllerMap[j])) {
bdown(i, j);
} else {
bup(i, j);
}
break;
case DKEY_L2:
axis2 = SDL_GameControllerGetAxis(g.PadState[i].GCDev, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
if (axis2 > 0) {
bdown(i, j);
} else {
bup(i, j);
}
break;
case DKEY_R2:
axis2 = SDL_GameControllerGetAxis(g.PadState[i].GCDev, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
if (axis2 > 0) {
bdown(i, j);
} else {
bup(i, j);
}
break;
default:
break;
}
}
}
#endif
}
// Check for emulator button states
for (i=(g.cfg.E.EmuKeyDev == NULL ? EMU_TOTAL : 0) ; i < EMU_TOTAL ; i++) {