Gamepad clamp-beyond-radius implemented

This commit is contained in:
Aaron Culliney 2014-12-05 22:31:12 -08:00
parent e61ff8e660
commit a24436e88f
8 changed files with 72 additions and 33 deletions

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="6245" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1060" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6245"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6254"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -244,7 +244,7 @@ CA
<rect key="frame" x="20" y="153" width="212" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="91" height="18"/>
<size key="cellSize" width="89" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="800-L1-WxW">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -272,7 +272,7 @@ CA
<rect key="frame" x="271" y="153" width="212" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="91" height="18"/>
<size key="cellSize" width="89" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
<buttonCell key="prototype" type="radio" title="Radio" imagePosition="left" alignment="left" inset="2" id="uEc-fa-XXZ">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -318,14 +318,14 @@ CA
<action selector="startupDiskBChoiceChanged:" target="FHO-g2-V3A" id="tQS-5l-DDf"/>
</connections>
</button>
<box autoresizesSubviews="NO" verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="7ZU-H6-jQn">
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="7ZU-H6-jQn">
<rect key="frame" x="12" y="59" width="498" height="5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<box autoresizesSubviews="NO" horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="864-Ov-2tE">
<box horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="864-Ov-2tE">
<rect key="frame" x="259" y="70" width="5" height="217"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
@ -441,7 +441,7 @@ DQ
<action selector="peggedChoiceChanged:" target="mUW-Rh-bL1" id="K2H-Vc-15h"/>
</connections>
</button>
<box autoresizesSubviews="NO" verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="9U0-v9-wTm">
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="9U0-v9-wTm">
<rect key="frame" x="17" y="183" width="508" height="5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
@ -485,7 +485,7 @@ DQ
</buttonCell>
<cells>
<column>
<buttonCell type="radio" title="No soundcard" imagePosition="left" alignment="left" enabled="NO" state="on" tag="1" inset="2" id="QsT-B1-n2t">
<buttonCell type="radio" title="No soundcard" imagePosition="left" alignment="left" enabled="NO" tag="1" inset="2" id="QsT-B1-n2t">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
@ -511,15 +511,6 @@ DQ
<rect key="frame" x="10" y="33" width="534" height="298"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="dak-eg-hHn">
<rect key="frame" x="15" y="278" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Color :" id="eHo-1T-edz">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" id="1sF-py-jCs">
<rect key="frame" x="115" y="271" width="158" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
@ -558,6 +549,15 @@ DQ
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="dak-eg-hHn">
<rect key="frame" x="15" y="277" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Color :" id="eHo-1T-edz">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
</tabViewItem>
@ -566,7 +566,7 @@ DQ
<rect key="frame" x="10" y="33" width="534" height="298"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<box autoresizesSubviews="NO" horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="Fkg-X3-0XG">
<box horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="Fkg-X3-0XG">
<rect key="frame" x="265" y="9" width="5" height="286"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
@ -654,15 +654,15 @@ DQ
<action selector="autoRecenterChoiceChanged:" target="mUW-Rh-bL1" id="Ehf-jm-Exs"/>
</connections>
</button>
<button id="wu9-dx-Rxy" userLabel="Clip to Radius">
<button id="wu9-dx-Rxy" userLabel="Clamp beyond Radius">
<rect key="frame" x="15" y="245" width="217" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="Clip to Radius" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="AMY-tC-0Yf">
<buttonCell key="cell" type="check" title="Clamp Beyond Radius" bezelStyle="regularSquare" imagePosition="left" alignment="left" state="on" inset="2" id="AMY-tC-0Yf" userLabel="Clip beyond Radius">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clipToRadiusChoiceChanged:" target="mUW-Rh-bL1" id="CWO-Ct-YTC"/>
<action selector="clipToRadiusChoiceChanged:" target="mUW-Rh-bL1" id="I8b-k9-H4g"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="e2h-SS-aex">
@ -692,14 +692,15 @@ DQ
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" id="LUN-A2-S1l">
<rect key="frame" x="15" y="9" width="246" height="34"/>
<rect key="frame" x="15" y="9" width="246" height="85"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="TEm-S7-9qg">
<font key="font" metaFont="system"/>
<string key="title">We recommend the Clip to Radius setting for gamepad devices (not traditional joysticks) which cannot generate values in the extreme corners.</string>
<string key="title">"Clamp Beyond Radius" setting is recommended for gamepad devices (not traditional joysticks) which cannot generate values in the extreme corners.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<string key="userLabel">Clamp Beyond Radius setting is recommended for gamepad devices (not traditional joysticks) which cannot generate values in the extreme corners.</string>
</textField>
</subviews>
</view>

View File

@ -24,19 +24,22 @@
CGRect bounds = [self bounds];
NSAssert(bounds.size.height == 256.f, @"view should be 256pts high");
NSAssert(bounds.size.width == 256.f, @"view should be 256pts wide");
NSAssert(bounds.size.height == JOY_RANGE, @"view should be 256pts high");
NSAssert(bounds.size.width == JOY_RANGE, @"view should be 256pts wide");
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(context);
CGContextSetLineWidth(context, 1);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
CGContextAddEllipseInRect(context, bounds);
CGContextStrokePath(context);
if (joy_clip_to_radius && (joy_mode == JOY_PCJOY))
{
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
CGContextAddEllipseInRect(context, bounds);
CGContextStrokePath(context);
}
CGFloat x_val = joy_x;
CGFloat y_val = 256-joy_y;
CGFloat y_val = JOY_RANGE-joy_y;
CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
CGRect cursor = CGRectMake(x_val-(pulseSize/2.f), y_val-(pulseSize/2.f), pulseSize, pulseSize);

View File

@ -123,7 +123,27 @@ void gldriver_joystick_reset(void) {
#pragma mark -
#pragma mark NSObject(DDHidJoystickDelegate)
#define DDHID_JOYSTICK_NORMALIZER (256.f/(DDHID_JOYSTICK_VALUE_MAX*2))
#define DDHID_JOYSTICK_NORMALIZER ((float)JOY_RANGE/(DDHID_JOYSTICK_VALUE_MAX*2))
#define QUARTER_JOY (HALF_JOY_RANGE>>1)
static inline void clampBeyondRadius(void) {
CGFloat half_x = joy_x - HALF_JOY_RANGE;
CGFloat half_y = joy_y - HALF_JOY_RANGE;
CGFloat r = sqrtf(half_x*half_x + half_y*half_y);
bool shouldClip = (r > HALF_JOY_RANGE);
if (joy_clip_to_radius && shouldClip) {
if (joy_x < HALF_JOY_RANGE) {
joy_x = (joy_x < QUARTER_JOY) ? 0.f : joy_x;
} else {
joy_x = (joy_x < HALF_JOY_RANGE+QUARTER_JOY) ? joy_x : JOY_RANGE-1;
}
if (joy_y < HALF_JOY_RANGE) {
joy_y = (joy_y < QUARTER_JOY) ? 0.f : joy_y;
} else {
joy_y = (joy_y < HALF_JOY_RANGE+QUARTER_JOY) ? joy_y : JOY_RANGE-1;
}
}
}
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick xChanged:(int)value
{
@ -137,6 +157,8 @@ void gldriver_joystick_reset(void) {
if (joy_x > 0xFF) {
joy_x = 0xFF;
}
clampBeyondRadius();
}
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick yChanged:(int)value
@ -151,6 +173,8 @@ void gldriver_joystick_reset(void) {
if (joy_y > 0xFF) {
joy_y = 0xFF;
}
clampBeyondRadius();
}
- (void)ddhidJoystick:(DDHidJoystick *)joystick stick:(unsigned int)stick otherAxis:(unsigned)otherAxis valueChanged:(int)value

View File

@ -21,6 +21,7 @@
#define kApple2ColorConfig @"kApple2ColorConfig"
#define kApple2JoystickConfig @"kApple2JoystickConfig"
#define kApple2JoystickAutoRecenter @"kApple2JoystickAutoRecenter"
#define kApple2JoystickClipToRadius @"kApple2JoystickClipToRadius"
#define kApple2JoystickStep @"kApple2JoystickStep"
@interface EmulatorPrefsController ()
@ -121,11 +122,16 @@
joy_mode = (joystick_mode_t)mode;
[self.joystickChoice selectItemAtIndex:mode];
#ifdef KEYPAD_JOYSTICK
joy_auto_recenter = [defaults integerForKey:kApple2JoystickAutoRecenter];
[self.joystickRecenter setState:joy_auto_recenter ? NSOnState : NSOffState];
joy_step = [defaults integerForKey:kApple2JoystickStep];
[self.joystickStepLabel setIntegerValue:joy_step];
[self.joystickStepper setIntegerValue:joy_step];
#endif
joy_clip_to_radius = [defaults boolForKey:kApple2JoystickClipToRadius];
[self.joystickClipToRadius setState:joy_clip_to_radius ? NSOnState : NSOffState];
[self _setupJoystickUI];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(drawJoystickCalibration:) name:(NSString *)kDrawTimerNotification object:nil];
@ -149,6 +155,7 @@
[defaults setInteger:joy_mode forKey:kApple2JoystickConfig];
[defaults setInteger:joy_step forKey:kApple2JoystickStep];
[defaults setBool:joy_auto_recenter forKey:kApple2JoystickAutoRecenter];
[defaults setBool:joy_clip_to_radius forKey:kApple2JoystickClipToRadius];
}
- (IBAction)sliderDidMove:(id)sender
@ -249,7 +256,8 @@
- (IBAction)clipToRadiusChoiceChanged:(id)sender
{
// TBD : handle joysticks with radius (most gamepads)
joy_clip_to_radius = ([self.joystickClipToRadius state] == NSOnState);
[self _savePrefs];
}
- (IBAction)stepValueChanged:(id)sender

View File

@ -25,5 +25,5 @@ and other contributors\
\f0\b \cf0 Special thanks to
\f1\b0 \
Tom CharlesWorth\
and the AppleWin project}
Tom Charlesworth\
and the AppleWin project}

View File

@ -68,6 +68,7 @@ static inline GLenum safeGLGetError(void) {
}
#else
#define GLenum int
#define safeGLGetError() 0
#define glGetError() 0
#endif

View File

@ -27,6 +27,7 @@ uint16_t joy_y = HALF_JOY_RANGE;
uint8_t joy_button0 = 0;
uint8_t joy_button1 = 0;
uint8_t joy_button2 = 0; // unused?
bool joy_clip_to_radius = false;
#ifdef KEYPAD_JOYSTICK
short joy_step = 1;

View File

@ -27,6 +27,7 @@ extern uint16_t joy_y;
extern uint8_t joy_button0;
extern uint8_t joy_button1;
extern uint8_t joy_button2;
extern bool joy_clip_to_radius;
#ifdef KEYPAD_JOYSTICK
extern uint8_t joy_auto_recenter;