Mac: refactor preferences code, fix a couple connections, and add new icons

This commit is contained in:
Michael Buckley 2021-04-25 17:44:40 -07:00
parent 8a5d29c4a9
commit 4b66a6a955
44 changed files with 2509 additions and 1923 deletions

View File

@ -1,6 +1,6 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
@ -15,7 +15,7 @@
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>

View File

@ -20,6 +20,7 @@
#import <Carbon/Carbon.h>
#import "AppDelegate.h"
#import "S9xPreferencesConstants.h"
NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
@ -212,7 +213,7 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
{
[self.s9xEngine clearButton:button forPlayer:player];
NSMutableDictionary *keyDict = [[NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs] mutableCopy];
[keyDict removeObjectForKey:@(button).stringValue];
[keyDict removeObjectForKey:@(button + (kNumButtons * player)).stringValue];
[NSUserDefaults.standardUserDefaults setObject:[keyDict copy] forKey:kKeyboardPrefs];
[NSUserDefaults.standardUserDefaults synchronize];
}
@ -549,7 +550,7 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
{
if (NSApp.keyWindow != nil && NSApp.keyWindow == self.preferencesWindowController.window)
{
return [((S9xPreferencesWindowController *) self.preferencesWindowController.contentViewController) handleInput:input fromJoypad:joypad];
return [((S9xPreferencesWindowController *) self.preferencesWindowController) handleInput:input fromJoypad:joypad];
}
return NO;

View File

@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"filename" : "display.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "display@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"filename" : "emulation.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "emulation@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"filename" : "files.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "files@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"filename" : "gamepad.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "gamepad@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

View File

@ -0,0 +1,18 @@
{
"images" : [
{
"filename" : "sound.png",
"idiom" : "mac",
"scale" : "1x"
},
{
"filename" : "sound@2x.png",
"idiom" : "mac",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface S9xControlsPreferencesViewController : S9xPreferencesViewController
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,294 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <snes9x_framework/snes9x_framework.h>
#import "AppDelegate.h"
#import "S9xButtonConfigTextField.h"
#import "S9xPreferencesConstants.h"
#import "S9xControlsPreferencesViewController.h"
@interface S9xControlsPreferencesViewController () <S9xInputDelegate>
@property (nonatomic, weak) IBOutlet NSPopUpButton *devicePopUp;
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerPopUp;
@property (nonatomic, strong) NSArray *configTextFields;
@end
@implementation S9xControlsPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xControlsPreferencesViewController" bundle:nil])
{
self.title = NSLocalizedString(@"Controls", nil);
self.image = [NSImage imageNamed:@"gamepad"];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSUInteger joypadIndex = 0;
for (S9xJoypad *joypad in [appDelegate listJoypads])
{
NSMenuItem *item = [NSMenuItem new];
item.title = joypad.name;
item.tag = joypadIndex++;
item.representedObject = joypad;
[self.devicePopUp.menu addItem:item];
}
// collect all S9xButtonConfigTextFields within subviews
NSMutableArray *configTextFields = [[NSMutableArray alloc] init];
for ( NSView *view in self.view.subviews )
{
if ([view isKindOfClass:[S9xButtonConfigTextField class]])
{
[configTextFields addObject:view];
}
}
self.configTextFields = configTextFields;
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
}
// select Keyboard as default
[self selectDeviceForPlayer:0];
}
- (void)refresh
{
if (self.devicePopUp.selectedItem.tag < 0)
{
NSMutableDictionary<NSNumber *, NSNumber *> *controlsDict = [NSMutableDictionary new];
NSDictionary *keyboardDict = [NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs];
NSInteger playerNum = self.playerPopUp.selectedItem.tag;
for (NSUInteger i = 0; i < kNumButtons; ++i)
{
controlsDict[@(i)] = keyboardDict[@(i + (playerNum * kNumButtons)).stringValue];
}
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
NSNumber *keyCode = controlsDict[@(configTextField.tag)];
configTextField.joypadInput = nil;
if ( keyCode != nil )
{
configTextField.keyCode = keyCode.intValue;
}
else
{
configTextField.keyCode = -1;
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = NO;
}
}
else
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
NSString *joypadKey = [appDelegate prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
NSDictionary *joypadDIct = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] objectForKey:joypadKey];
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
uint32 cookie = 0;
int32 value = 0;
S9xButtonCode buttonCode = (S9xButtonCode)configTextField.tag;
NSString *inputString = joypadDIct[@(buttonCode).stringValue];
configTextField.keyCode = -1;
if ([appDelegate getValuesFromString:inputString cookie:&cookie value:&value])
{
S9xJoypadInput *input = [S9xJoypadInput new];
input.cookie = cookie;
input.value = value;
input.buttonCode = buttonCode;
configTextField.joypadInput = input;
configTextField.stringValue = [appDelegate labelForVendorID:joypad.vendorID productID:joypad.productID cookie:cookie value:value];
}
else
{
configTextField.joypadInput = nil;
configTextField.stringValue = @"";
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = YES;
}
}
}
- (void)selectDeviceForPlayer:(int8_t)player
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSString* joypadKey = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadPlayerPrefs] objectForKey:@(player).stringValue];
[self.devicePopUp selectItemAtIndex:0];
if (joypadKey != nil)
{
uint32 vendorID = 0;
uint32 productID = 0;
uint32 index = 0;
if ( [appDelegate getValuesFromString:joypadKey vendorID:&vendorID productID:&productID index:&index])
{
S9xJoypad *joypad = [S9xJoypad new];
joypad.vendorID = vendorID;
joypad.productID = productID;
joypad.index = index;
for (NSMenuItem *item in self.devicePopUp.menu.itemArray)
{
if ([joypad isEqual:item.representedObject])
{
[self.devicePopUp selectItem:item];
break;
}
}
}
}
}
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad
{
id firstResponder = self.view.window.firstResponder;
if ([firstResponder respondsToSelector:@selector(isFieldEditor)] && [firstResponder isFieldEditor])
{
firstResponder = [firstResponder delegate];
}
if ([firstResponder respondsToSelector:@selector(setJoypadInput:)])
{
S9xJoypad *currentJoypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isEqual:currentJoypad])
{
[firstResponder setJoypadInput:input];
return YES;
}
}
return NO;
}
- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting {}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"keyCode"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
uint16_t keyCode = field.keyCode;
int8_t player = self.playerPopUp.selectedItem.tag;
if (keyCode != (CGKeyCode)-1)
{
[((AppDelegate *) NSApp.delegate) setButtonCode:buttonCode forKeyCode:keyCode player:player];
}
else
{
[((AppDelegate *) NSApp.delegate) clearButton:buttonCode forPlayer:player];
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
else if ( [keyPath isEqualToString:@"joypadInput"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isKindOfClass:[S9xJoypad class]])
{
S9xJoypadInput *input = field.joypadInput;
if (input != nil)
{
[((AppDelegate *)NSApp.delegate) setButton:buttonCode forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index cookie:input.cookie value:input.value];
}
else
{
[((AppDelegate *)NSApp.delegate) clearJoypadForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index buttonCode:buttonCode];
}
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
}
- (IBAction)playerDropdownChanged:(NSPopUpButton *)sender
{
[self selectDeviceForPlayer:sender.selectedTag];
[self refresh];
}
- (IBAction)deviceDropdownChanged:(NSPopUpButton *)sender
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
if (sender.selectedTag >= 0)
{
S9xJoypad *joypad = sender.selectedItem.representedObject;
[appDelegate setPlayer:self.playerPopUp.selectedTag forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
}
else
{
[appDelegate setPlayer:self.playerPopUp.selectedTag forVendorID:0 productID:0 index:0];
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
@end

View File

@ -0,0 +1,775 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xControlsPreferencesViewController">
<connections>
<outlet property="devicePopUp" destination="mJx-JF-xDg" id="xYP-Mi-jhu"/>
<outlet property="playerPopUp" destination="hfx-Lg-t9P" id="pJR-nP-Ajt"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="547"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hfx-Lg-t9P">
<rect key="frame" x="18" y="503" width="472" height="25"/>
<popUpButtonCell key="cell" type="push" title="Player 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Mes-ZE-LOG" id="3Oa-7I-2cH">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="nds-U1-9Cm">
<items>
<menuItem title="Player 1" state="on" id="Mes-ZE-LOG"/>
<menuItem title="Player 2" tag="1" id="AWG-xK-l3f"/>
<menuItem title="Player 3" tag="2" id="jSq-tK-TKM"/>
<menuItem title="Player 4" tag="3" id="hmJ-yy-u6L"/>
<menuItem title="Player 5" tag="4" id="4J1-GS-DgW"/>
<menuItem title="Player 6" tag="5" id="UH1-NG-PB6"/>
<menuItem title="Player 7" tag="6" id="DjI-Q2-ZNu"/>
<menuItem title="Player 8" tag="7" id="6Z7-mO-SMy"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="playerDropdownChanged:" target="-2" id="P4K-gg-QUK"/>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qMp-14-9zW">
<rect key="frame" x="18" y="443" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Up" id="hua-jM-68w">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2BM-Lt-WwR">
<rect key="frame" x="18" y="413" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Down" id="z7r-rj-abc">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="biW-Zy-9NZ">
<rect key="frame" x="18" y="383" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Left" id="zD3-HS-vYg">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rsc-8R-cwh">
<rect key="frame" x="18" y="353" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Right" id="m1L-Ha-tjV">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yHT-3q-ctP">
<rect key="frame" x="18" y="323" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="A" id="AOM-k9-LVv">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WcI-SC-fZV">
<rect key="frame" x="18" y="293" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="B" id="afx-UX-ra7">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="atg-Fg-IgS">
<rect key="frame" x="18" y="263" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="X" id="R4J-4s-qIx">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NeB-Rh-CKs">
<rect key="frame" x="18" y="233" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Y" id="Nho-ku-fUk">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rz0-Kg-nHG">
<rect key="frame" x="18" y="203" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="L" id="jvi-9B-mJS">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AiU-u8-z9t">
<rect key="frame" x="18" y="173" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="R" id="ckb-YM-tFe">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3Cb-Ht-JzJ">
<rect key="frame" x="18" y="143" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Start" id="oqQ-e5-KNH">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ISU-xt-cZa">
<rect key="frame" x="18" y="113" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Select" id="RW3-fW-YAS">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="c4Z-r1-O38">
<rect key="frame" x="18" y="83" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Function" id="xbY-Z6-sBG">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rsg-HQ-Cig">
<rect key="frame" x="18" y="53" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Alt" id="nKE-jO-OCz">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="dL6-2Y-CIz">
<rect key="frame" x="18" y="23" width="88" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Turbo Control" id="i08-K8-ZqE">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="drA-2C-LPt">
<rect key="frame" x="230" y="443" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Pause/Resume" id="tle-rH-QLe">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5DP-Qu-lS2">
<rect key="frame" x="230" y="413" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Freeze" id="HsC-E3-aUn">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jQs-eL-Df4">
<rect key="frame" x="230" y="383" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Defrost" id="LO9-bN-27u">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TuE-fA-Shh">
<rect key="frame" x="230" y="353" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Screenshot" id="XrV-eO-k3u">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jHT-Uw-MKM">
<rect key="frame" x="230" y="323" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Fast Forward" id="IrR-8T-GsO">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R5Q-JF-7P7">
<rect key="frame" x="230" y="293" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Increase FF Speed" id="DL5-qE-hMa">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="O9g-UA-3gp">
<rect key="frame" x="230" y="263" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Decrease FF Speed" id="JoH-8A-HTb">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vrB-v6-gvS">
<rect key="frame" x="230" y="233" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Turbo" id="5Ok-p3-jsW">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RXV-hd-YH8">
<rect key="frame" x="230" y="203" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Cursor" id="bLP-cT-3YD">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fG8-lF-YYW">
<rect key="frame" x="230" y="173" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Super Scope Off Screen" id="e9h-qE-jme">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eyk-QN-lkH">
<rect key="frame" x="230" y="143" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Pause Super Scope" id="5op-LV-kgt">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0xy-5S-ffb">
<rect key="frame" x="230" y="113" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Left Mouse" id="hBs-n4-TD6">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jOm-aT-92f">
<rect key="frame" x="230" y="83" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Right Mouse" id="PMa-Fr-3vd">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ymc-Xn-VtU">
<rect key="frame" x="230" y="53" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Save SPC" id="Yvu-uO-lMI">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mJx-JF-xDg">
<rect key="frame" x="18" y="474" width="472" height="25"/>
<popUpButtonCell key="cell" type="push" title="Keyboard" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="-1" imageScaling="proportionallyDown" inset="2" selectedItem="Cs2-1w-ccm" id="ui9-4e-0EL">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="vSY-DD-mp3">
<items>
<menuItem title="Keyboard" state="on" tag="-1" id="Cs2-1w-ccm"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="deviceDropdownChanged:" target="-2" id="oH3-xl-IZF"/>
</connections>
</popUpButton>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="1" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5wn-WM-n7f" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="410" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="6tU-6G-dKy"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="k5A-MS-Z6b">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="2" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Pdg-iO-Rlv" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="380" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Vzs-rb-iSz"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="2uN-kX-Tga">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i6K-Iu-xdk" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="440" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="B3A-lY-BCn"/>
<constraint firstAttribute="width" constant="100" id="TGv-i2-qc7"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="kfN-fb-kJk">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="3" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="W7s-0d-JNo" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="350" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="KgL-oM-FNL"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="nDY-Wf-kMT">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="7" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="56u-eS-Y7s" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="320" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="old-cu-PoH"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="wpF-K9-uGS">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="6" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xib-ad-dgH" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="260" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="nCJ-u5-vpC"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="P74-cT-Hhv">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="4" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lSq-25-AV2" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="230" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Zwq-yn-TeE"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="hXa-pS-qJq">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="5" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6dg-5z-gNX" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="290" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Qe9-et-5QN"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="jfT-jr-LeY"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="IJx-NV-DIi">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="8" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Ro-Ix-JD5" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="200" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Jls-qj-Gt0"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="3A1-Qy-pvY">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="9" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fkh-aT-XE9" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="170" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="vbp-eP-ql6"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="9ih-Vg-mrB">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="11" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hLf-i4-NRV" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="110" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="3XK-UH-gXU"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="nlX-ww-ZuR">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="21" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SSJ-4e-Tc8" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="80" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="jbE-Yf-hDQ"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="gvL-GU-9rC">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="10" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ycZ-re-pMx" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="140" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="XTE-Jx-pv7"/>
<constraint firstAttribute="width" constant="100" id="qte-MS-3PL"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="Pdd-Ps-WDJ">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="22" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rX2-Wj-CDJ" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="50" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="mYj-MI-dHJ"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="2ey-x8-4NN">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="26" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r5O-6f-xdH" customClass="S9xButtonConfigTextField">
<rect key="frame" x="112" y="20" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="0QT-Md-0M0"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="C2T-pv-auB">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="13" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0FY-cv-M9B" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="410" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="xmT-dz-x8T"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="W5m-b8-Ljs">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="14" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fve-dp-udd" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="380" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="l23-fI-CtT"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="tn1-Kx-fp1">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="25" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ns3-zZ-EQY" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="440" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Hvr-RF-2d2"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="ILE-7H-7um"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="1UX-yF-wRM">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="15" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GDm-WA-rkG" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="350" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="B4h-mm-FkB"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="0YR-us-6Qy">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="12" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HIj-cE-Twd" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="320" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="IEA-AN-TmA"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="4hD-Qo-n6n">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="23" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VRq-kT-wkC" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="260" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="79e-XA-N79"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="zEb-u6-7A0">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="17" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yHB-42-ebc" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="230" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="saj-Wb-IdB"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="GMG-pM-ni9">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="24" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TIz-bI-n89" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="290" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="OHA-S7-m2g"/>
<constraint firstAttribute="width" constant="100" id="vKB-Bb-kJu"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="IRI-9H-J9c">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="19" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E3S-mU-OmJ" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="200" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="ayN-Z9-uyh"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="rM5-vB-rnj">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="20" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lw1-zP-Vdy" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="170" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="tyK-xj-HxC"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="eWo-k0-67t">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="27" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="S5E-xU-QAK" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="110" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="JGe-qf-ind"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="TpE-Vu-cmT">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="28" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WCt-Ri-ndL" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="80" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="khS-Ng-mZK"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="n7S-b5-pPm">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="18" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eZA-Af-a2e" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="140" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="LjM-MK-DCE"/>
<constraint firstAttribute="width" constant="100" id="OO3-Rg-dMj"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="9dt-yN-DB1">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<searchField wantsLayer="YES" verticalHuggingPriority="750" tag="16" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iZL-4Q-g2k" customClass="S9xButtonConfigTextField">
<rect key="frame" x="387" y="50" width="100" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="VOg-Zt-Sna"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" id="RUv-v1-sy4">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
</subviews>
<constraints>
<constraint firstItem="lSq-25-AV2" firstAttribute="leading" secondItem="NeB-Rh-CKs" secondAttribute="trailing" constant="8" id="06f-oZ-gc9"/>
<constraint firstItem="eyk-QN-lkH" firstAttribute="width" secondItem="0xy-5S-ffb" secondAttribute="width" id="0BG-4g-olJ"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="top" secondItem="i6K-Iu-xdk" secondAttribute="bottom" constant="8" id="0pz-eS-OKy"/>
<constraint firstItem="biW-Zy-9NZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="168-h5-GLY"/>
<constraint firstItem="biW-Zy-9NZ" firstAttribute="width" secondItem="rsc-8R-cwh" secondAttribute="width" id="1Ec-Bs-A10"/>
<constraint firstItem="jHT-Uw-MKM" firstAttribute="leading" secondItem="R5Q-JF-7P7" secondAttribute="leading" id="1TJ-hk-cUg"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="firstBaseline" secondItem="fG8-lF-YYW" secondAttribute="firstBaseline" id="1as-cC-yzO"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="top" secondItem="eZA-Af-a2e" secondAttribute="bottom" constant="8" id="1ee-ws-w0M"/>
<constraint firstItem="3Cb-Ht-JzJ" firstAttribute="width" secondItem="ISU-xt-cZa" secondAttribute="width" id="1ue-OI-XNP"/>
<constraint firstItem="qMp-14-9zW" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="2ef-fb-3h5"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="leading" secondItem="R5Q-JF-7P7" secondAttribute="trailing" constant="8" id="2hW-Ue-Vsp"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="firstBaseline" secondItem="TuE-fA-Shh" secondAttribute="firstBaseline" id="42O-Cs-57E"/>
<constraint firstItem="WcI-SC-fZV" firstAttribute="width" secondItem="atg-Fg-IgS" secondAttribute="width" id="4g4-85-hQA"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="leading" secondItem="3Cb-Ht-JzJ" secondAttribute="trailing" constant="8" id="4gJ-MX-zP2"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="top" secondItem="Lw1-zP-Vdy" secondAttribute="bottom" constant="8" id="5TI-QI-4q6"/>
<constraint firstItem="c4Z-r1-O38" firstAttribute="width" secondItem="Rsg-HQ-Cig" secondAttribute="width" id="5dc-cT-5xJ"/>
<constraint firstItem="yHT-3q-ctP" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="69R-sL-5SF"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="leading" secondItem="fG8-lF-YYW" secondAttribute="trailing" constant="8" id="76v-dF-nMk"/>
<constraint firstItem="fG8-lF-YYW" firstAttribute="leading" secondItem="eyk-QN-lkH" secondAttribute="leading" id="7v6-7P-4kI"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="firstBaseline" secondItem="2BM-Lt-WwR" secondAttribute="firstBaseline" id="8Aa-9s-wDv"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="firstBaseline" secondItem="jHT-Uw-MKM" secondAttribute="firstBaseline" id="8K4-J6-7Ln"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="top" secondItem="5wn-WM-n7f" secondAttribute="bottom" constant="8" id="94J-2J-YaO"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="firstBaseline" secondItem="Ymc-Xn-VtU" secondAttribute="firstBaseline" id="9It-Ku-20r"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="firstBaseline" secondItem="yHT-3q-ctP" secondAttribute="firstBaseline" id="9O2-n7-6FK"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="leading" secondItem="5DP-Qu-lS2" secondAttribute="trailing" constant="8" id="9Os-Qg-zY5"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="leading" secondItem="i6K-Iu-xdk" secondAttribute="trailing" constant="20" id="Aeq-Py-t3S"/>
<constraint firstItem="Rsg-HQ-Cig" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Aj6-EC-8k6"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="leading" secondItem="jOm-aT-92f" secondAttribute="trailing" constant="8" id="BiA-bF-aa5"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="firstBaseline" secondItem="0xy-5S-ffb" secondAttribute="firstBaseline" id="C8b-74-452"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="firstBaseline" secondItem="eyk-QN-lkH" secondAttribute="firstBaseline" id="CNE-YW-lQs"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="leading" secondItem="dL6-2Y-CIz" secondAttribute="trailing" constant="8" id="Cb7-fX-o5V"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="firstBaseline" secondItem="O9g-UA-3gp" secondAttribute="firstBaseline" id="DNz-VN-dnq"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="firstBaseline" secondItem="c4Z-r1-O38" secondAttribute="firstBaseline" id="Dfe-L2-A5d"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="top" secondItem="W7s-0d-JNo" secondAttribute="bottom" constant="8" id="DgW-BJ-cTD"/>
<constraint firstItem="eyk-QN-lkH" firstAttribute="leading" secondItem="0xy-5S-ffb" secondAttribute="leading" id="DoA-iC-K2h"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="top" secondItem="hLf-i4-NRV" secondAttribute="bottom" constant="8" id="DpQ-z0-7bk"/>
<constraint firstItem="AiU-u8-z9t" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="DuJ-xv-SYs"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="EEK-cj-r1K"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="leading" secondItem="jQs-eL-Df4" secondAttribute="trailing" constant="8" id="ERu-oo-Fo3"/>
<constraint firstItem="NeB-Rh-CKs" firstAttribute="width" secondItem="Rz0-Kg-nHG" secondAttribute="width" id="Elw-OX-aVc"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="firstBaseline" secondItem="vrB-v6-gvS" secondAttribute="firstBaseline" id="F14-1E-cTk"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="top" secondItem="TIz-bI-n89" secondAttribute="bottom" constant="8" id="FAT-MC-j2R"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="top" secondItem="lSq-25-AV2" secondAttribute="bottom" constant="8" id="FTG-52-WZK"/>
<constraint firstAttribute="trailing" secondItem="mJx-JF-xDg" secondAttribute="trailing" constant="20" id="FjE-V8-WQf"/>
<constraint firstItem="0xy-5S-ffb" firstAttribute="leading" secondItem="jOm-aT-92f" secondAttribute="leading" id="FnI-WM-zIE"/>
<constraint firstItem="56u-eS-Y7s" firstAttribute="leading" secondItem="yHT-3q-ctP" secondAttribute="trailing" constant="8" id="FuE-hi-SKb"/>
<constraint firstItem="jOm-aT-92f" firstAttribute="width" secondItem="Ymc-Xn-VtU" secondAttribute="width" id="GAQ-Ss-XPz"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="top" secondItem="HIj-cE-Twd" secondAttribute="bottom" constant="8" id="GIp-2p-zxM"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="top" secondItem="rX2-Wj-CDJ" secondAttribute="bottom" constant="8" id="GUg-cU-Mdi"/>
<constraint firstItem="NeB-Rh-CKs" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Gvp-Gk-jnY"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="HDg-WG-2Oj"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="firstBaseline" secondItem="drA-2C-LPt" secondAttribute="firstBaseline" id="I5P-lB-vVE"/>
<constraint firstAttribute="trailing" secondItem="hfx-Lg-t9P" secondAttribute="trailing" constant="20" id="IUn-oP-elS"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="firstBaseline" secondItem="biW-Zy-9NZ" secondAttribute="firstBaseline" id="Iw8-MZ-gXl"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="firstBaseline" secondItem="atg-Fg-IgS" secondAttribute="firstBaseline" id="JUk-Fe-nnv"/>
<constraint firstItem="mJx-JF-xDg" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="KLG-ZJ-Qep"/>
<constraint firstItem="r5O-6f-xdH" firstAttribute="firstBaseline" secondItem="dL6-2Y-CIz" secondAttribute="firstBaseline" id="KwJ-iX-Lem"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="top" secondItem="mJx-JF-xDg" secondAttribute="bottom" constant="15" id="L3y-MX-53u"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="leading" secondItem="Rsg-HQ-Cig" secondAttribute="trailing" constant="8" id="L8E-dg-fZy"/>
<constraint firstItem="O9g-UA-3gp" firstAttribute="width" secondItem="vrB-v6-gvS" secondAttribute="width" id="Lfb-33-q2U"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="firstBaseline" secondItem="WcI-SC-fZV" secondAttribute="firstBaseline" id="MHx-P2-7u9"/>
<constraint firstItem="O9g-UA-3gp" firstAttribute="leading" secondItem="vrB-v6-gvS" secondAttribute="leading" id="MQQ-jz-tfP"/>
<constraint firstItem="jOm-aT-92f" firstAttribute="leading" secondItem="Ymc-Xn-VtU" secondAttribute="leading" id="Ne8-17-j3I"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="top" secondItem="fkh-aT-XE9" secondAttribute="bottom" constant="8" id="NfM-lU-BGG"/>
<constraint firstItem="SSJ-4e-Tc8" firstAttribute="leading" secondItem="c4Z-r1-O38" secondAttribute="trailing" constant="8" id="NxT-Rc-8Yb"/>
<constraint firstItem="TIz-bI-n89" firstAttribute="firstBaseline" secondItem="R5Q-JF-7P7" secondAttribute="firstBaseline" id="Oql-bB-XA7"/>
<constraint firstItem="Rz0-Kg-nHG" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="P8J-kI-F1j"/>
<constraint firstItem="jHT-Uw-MKM" firstAttribute="width" secondItem="R5Q-JF-7P7" secondAttribute="width" id="PQg-0q-7tB"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="leading" secondItem="TuE-fA-Shh" secondAttribute="trailing" constant="8" id="PlS-Sb-BJl"/>
<constraint firstItem="RXV-hd-YH8" firstAttribute="width" secondItem="fG8-lF-YYW" secondAttribute="width" id="Qkw-4J-1Xs"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="firstBaseline" secondItem="RXV-hd-YH8" secondAttribute="firstBaseline" id="Qzk-e3-HIm"/>
<constraint firstAttribute="trailing" secondItem="hfx-Lg-t9P" secondAttribute="trailing" constant="20" id="SUL-1F-PVw"/>
<constraint firstItem="lSq-25-AV2" firstAttribute="top" secondItem="xib-ad-dgH" secondAttribute="bottom" constant="8" id="Scm-FO-oTB"/>
<constraint firstItem="ISU-xt-cZa" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Spb-nj-cDC"/>
<constraint firstItem="RXV-hd-YH8" firstAttribute="leading" secondItem="fG8-lF-YYW" secondAttribute="leading" id="TNu-0d-7hY"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="top" secondItem="SSJ-4e-Tc8" secondAttribute="bottom" constant="8" id="TVc-Gm-Z9C"/>
<constraint firstItem="Rz0-Kg-nHG" firstAttribute="width" secondItem="AiU-u8-z9t" secondAttribute="width" id="TuG-69-3ZZ"/>
<constraint firstItem="S5E-xU-QAK" firstAttribute="leading" secondItem="0xy-5S-ffb" secondAttribute="trailing" constant="8" id="V45-bc-c8o"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="firstBaseline" secondItem="5DP-Qu-lS2" secondAttribute="firstBaseline" id="VjF-HO-8el"/>
<constraint firstItem="atg-Fg-IgS" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="W43-Jm-i2I"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="leading" secondItem="vrB-v6-gvS" secondAttribute="trailing" constant="8" id="WC4-cY-SXd"/>
<constraint firstItem="qMp-14-9zW" firstAttribute="width" secondItem="2BM-Lt-WwR" secondAttribute="width" id="Wmc-Lc-tZx"/>
<constraint firstItem="rX2-Wj-CDJ" firstAttribute="firstBaseline" secondItem="Rsg-HQ-Cig" secondAttribute="firstBaseline" id="X7F-Js-Nra"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="firstBaseline" secondItem="AiU-u8-z9t" secondAttribute="firstBaseline" id="XMx-Tw-IXd"/>
<constraint firstItem="Pdg-iO-Rlv" firstAttribute="leading" secondItem="biW-Zy-9NZ" secondAttribute="trailing" constant="8" id="Y6V-wt-Xb5"/>
<constraint firstItem="Rsg-HQ-Cig" firstAttribute="width" secondItem="dL6-2Y-CIz" secondAttribute="width" id="Y72-0k-X9j"/>
<constraint firstItem="VRq-kT-wkC" firstAttribute="leading" secondItem="O9g-UA-3gp" secondAttribute="trailing" constant="8" id="YQZ-ll-Hgx"/>
<constraint firstItem="rsc-8R-cwh" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="Yar-cB-3Qx"/>
<constraint firstAttribute="bottom" secondItem="r5O-6f-xdH" secondAttribute="bottom" constant="20" id="ZFe-ts-Cxn"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="leading" secondItem="Rz0-Kg-nHG" secondAttribute="trailing" constant="8" id="ZT8-H1-D7g"/>
<constraint firstItem="vrB-v6-gvS" firstAttribute="leading" secondItem="RXV-hd-YH8" secondAttribute="leading" id="ZkV-M1-Yc3"/>
<constraint firstItem="2BM-Lt-WwR" firstAttribute="width" secondItem="biW-Zy-9NZ" secondAttribute="width" id="a8L-cO-AXv"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="firstBaseline" secondItem="jQs-eL-Df4" secondAttribute="firstBaseline" id="aa9-Eu-wYV"/>
<constraint firstItem="lSq-25-AV2" firstAttribute="firstBaseline" secondItem="NeB-Rh-CKs" secondAttribute="firstBaseline" id="bGA-rb-hEr"/>
<constraint firstItem="5DP-Qu-lS2" firstAttribute="leading" secondItem="jQs-eL-Df4" secondAttribute="leading" id="cST-Al-uuC"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="leading" secondItem="ISU-xt-cZa" secondAttribute="trailing" constant="8" id="dBX-fh-DCK"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="width" secondItem="5DP-Qu-lS2" secondAttribute="width" id="dXn-LW-UPX"/>
<constraint firstItem="0xy-5S-ffb" firstAttribute="width" secondItem="jOm-aT-92f" secondAttribute="width" id="dYD-sh-m5R"/>
<constraint firstItem="TuE-fA-Shh" firstAttribute="width" secondItem="jHT-Uw-MKM" secondAttribute="width" id="dy3-xX-glM"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="firstBaseline" secondItem="jOm-aT-92f" secondAttribute="firstBaseline" id="eRT-n8-fY0"/>
<constraint firstItem="mJx-JF-xDg" firstAttribute="top" secondItem="hfx-Lg-t9P" secondAttribute="bottom" constant="8" id="erO-qQ-EkZ"/>
<constraint firstItem="3Cb-Ht-JzJ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="f8t-7g-9tF"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="leading" secondItem="rsc-8R-cwh" secondAttribute="trailing" constant="8" id="ffY-aY-doh"/>
<constraint firstItem="rsc-8R-cwh" firstAttribute="width" secondItem="yHT-3q-ctP" secondAttribute="width" id="frA-S7-zPQ"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="top" secondItem="yHB-42-ebc" secondAttribute="bottom" constant="8" id="fwb-mN-WZp"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="top" secondItem="Pdg-iO-Rlv" secondAttribute="bottom" constant="8" id="gsZ-9n-duu"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="top" secondItem="5Ro-Ix-JD5" secondAttribute="bottom" constant="8" id="h0C-jn-NJC"/>
<constraint firstItem="c4Z-r1-O38" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="hJV-iW-3K0"/>
<constraint firstItem="ycZ-re-pMx" firstAttribute="firstBaseline" secondItem="3Cb-Ht-JzJ" secondAttribute="firstBaseline" id="i7O-Pd-BBi"/>
<constraint firstItem="drA-2C-LPt" firstAttribute="leading" secondItem="5DP-Qu-lS2" secondAttribute="leading" id="iFX-tU-zbX"/>
<constraint firstItem="TuE-fA-Shh" firstAttribute="leading" secondItem="jHT-Uw-MKM" secondAttribute="leading" id="iuz-gv-oL8"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="firstBaseline" secondItem="qMp-14-9zW" secondAttribute="firstBaseline" id="jOJ-6W-gyj"/>
<constraint firstItem="R5Q-JF-7P7" firstAttribute="leading" secondItem="O9g-UA-3gp" secondAttribute="leading" id="jvo-2N-1c6"/>
<constraint firstItem="ISU-xt-cZa" firstAttribute="width" secondItem="c4Z-r1-O38" secondAttribute="width" id="k5K-QA-Kdy"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="firstBaseline" secondItem="ISU-xt-cZa" secondAttribute="firstBaseline" id="k6v-Nf-0Ns"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="centerY" secondItem="i6K-Iu-xdk" secondAttribute="centerY" id="k7c-VC-F2q"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="leading" secondItem="atg-Fg-IgS" secondAttribute="trailing" constant="8" id="kJe-AZ-BHz"/>
<constraint firstItem="eZA-Af-a2e" firstAttribute="leading" secondItem="eyk-QN-lkH" secondAttribute="trailing" constant="8" id="kY5-nM-9bS"/>
<constraint firstItem="Ns3-zZ-EQY" firstAttribute="leading" secondItem="drA-2C-LPt" secondAttribute="trailing" constant="8" id="lk5-8o-ywx"/>
<constraint firstItem="xib-ad-dgH" firstAttribute="top" secondItem="6dg-5z-gNX" secondAttribute="bottom" constant="8" id="lkr-rc-E9z"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="top" secondItem="WCt-Ri-ndL" secondAttribute="bottom" constant="8" id="mqw-LZ-0G5"/>
<constraint firstItem="Fve-dp-udd" firstAttribute="top" secondItem="0FY-cv-M9B" secondAttribute="bottom" constant="8" id="nH6-Hj-btT"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="leading" secondItem="jHT-Uw-MKM" secondAttribute="trailing" constant="8" id="nKL-DQ-J82"/>
<constraint firstItem="jQs-eL-Df4" firstAttribute="leading" secondItem="TuE-fA-Shh" secondAttribute="leading" id="nb5-yD-0IC"/>
<constraint firstItem="fkh-aT-XE9" firstAttribute="leading" secondItem="AiU-u8-z9t" secondAttribute="trailing" constant="8" id="ndh-2g-JB9"/>
<constraint firstItem="jQs-eL-Df4" firstAttribute="width" secondItem="TuE-fA-Shh" secondAttribute="width" id="oPW-AK-dKc"/>
<constraint firstItem="yHB-42-ebc" firstAttribute="top" secondItem="VRq-kT-wkC" secondAttribute="bottom" constant="8" id="oeJ-JF-RKD"/>
<constraint firstItem="R5Q-JF-7P7" firstAttribute="width" secondItem="O9g-UA-3gp" secondAttribute="width" id="oxq-qE-PNY"/>
<constraint firstItem="5Ro-Ix-JD5" firstAttribute="firstBaseline" secondItem="Rz0-Kg-nHG" secondAttribute="firstBaseline" id="p1Y-oC-uPf"/>
<constraint firstItem="i6K-Iu-xdk" firstAttribute="leading" secondItem="qMp-14-9zW" secondAttribute="trailing" constant="8" id="pTv-cw-KOT"/>
<constraint firstItem="yHT-3q-ctP" firstAttribute="width" secondItem="WcI-SC-fZV" secondAttribute="width" id="py1-Eh-zaX"/>
<constraint firstItem="hLf-i4-NRV" firstAttribute="top" secondItem="ycZ-re-pMx" secondAttribute="bottom" constant="8" id="qXw-Lj-0TQ"/>
<constraint firstItem="dL6-2Y-CIz" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="qux-d1-Xew"/>
<constraint firstItem="WcI-SC-fZV" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="r1e-VI-uCi"/>
<constraint firstItem="GDm-WA-rkG" firstAttribute="top" secondItem="Fve-dp-udd" secondAttribute="bottom" constant="8" id="r8m-Lq-tOo"/>
<constraint firstItem="WCt-Ri-ndL" firstAttribute="top" secondItem="S5E-xU-QAK" secondAttribute="bottom" constant="8" id="sGu-iz-XWu"/>
<constraint firstItem="E3S-mU-OmJ" firstAttribute="leading" secondItem="RXV-hd-YH8" secondAttribute="trailing" constant="8" id="sJJ-wb-4ei"/>
<constraint firstItem="5wn-WM-n7f" firstAttribute="leading" secondItem="2BM-Lt-WwR" secondAttribute="trailing" constant="8" id="sri-x8-63C"/>
<constraint firstAttribute="trailing" secondItem="Ns3-zZ-EQY" secondAttribute="trailing" constant="20" id="tTK-hB-OcK"/>
<constraint firstItem="5DP-Qu-lS2" firstAttribute="width" secondItem="jQs-eL-Df4" secondAttribute="width" id="v4q-jw-tEN"/>
<constraint firstItem="vrB-v6-gvS" firstAttribute="width" secondItem="RXV-hd-YH8" secondAttribute="width" id="vOz-7q-3y1"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="top" secondItem="56u-eS-Y7s" secondAttribute="bottom" constant="8" id="w60-xz-Iy3"/>
<constraint firstItem="iZL-4Q-g2k" firstAttribute="leading" secondItem="Ymc-Xn-VtU" secondAttribute="trailing" constant="8" id="wCh-Wh-Hlj"/>
<constraint firstItem="atg-Fg-IgS" firstAttribute="width" secondItem="NeB-Rh-CKs" secondAttribute="width" id="wHM-2M-Nn5"/>
<constraint firstItem="2BM-Lt-WwR" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="xDh-um-N7F"/>
<constraint firstItem="W7s-0d-JNo" firstAttribute="firstBaseline" secondItem="rsc-8R-cwh" secondAttribute="firstBaseline" id="xJA-hJ-9ju"/>
<constraint firstItem="HIj-cE-Twd" firstAttribute="top" secondItem="GDm-WA-rkG" secondAttribute="bottom" constant="8" id="y1B-3t-tX1"/>
<constraint firstItem="6dg-5z-gNX" firstAttribute="leading" secondItem="WcI-SC-fZV" secondAttribute="trailing" constant="8" id="yFh-hz-kHH"/>
<constraint firstItem="hfx-Lg-t9P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" id="yfN-yW-OCy"/>
<constraint firstItem="Lw1-zP-Vdy" firstAttribute="top" secondItem="E3S-mU-OmJ" secondAttribute="bottom" constant="8" id="z2d-6U-MiE"/>
<constraint firstItem="0FY-cv-M9B" firstAttribute="top" secondItem="Ns3-zZ-EQY" secondAttribute="bottom" constant="8" id="z51-WK-EFf"/>
<constraint firstItem="fG8-lF-YYW" firstAttribute="width" secondItem="eyk-QN-lkH" secondAttribute="width" id="zN5-Ta-ZyL"/>
<constraint firstItem="AiU-u8-z9t" firstAttribute="width" secondItem="3Cb-Ht-JzJ" secondAttribute="width" id="zY2-nG-XLO"/>
</constraints>
<point key="canvasLocation" x="100.5" y="317.5"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface S9xDisplayPreferencesViewController : S9xPreferencesViewController
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,140 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xDisplayPreferencesViewController.h"
#import "AppDelegate.h"
#import "S9xPreferencesConstants.h"
@interface S9xDisplayPreferencesViewController ()
@property (nonatomic, weak) IBOutlet NSPopUpButton *videoModePopup;
@property (nonatomic, weak) IBOutlet NSButton *showFPSCheckbox;
@property (nonatomic, weak) IBOutlet NSTextField *macFrameSkipTextField;
@property (nonatomic, weak) IBOutlet NSStepper *macFrameSkipStepper;
@property (nonatomic, weak) IBOutlet NSButton *macFrameSkipAutomaticButton;
@end
@implementation S9xDisplayPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xDisplayPreferencesViewController" bundle:nil])
{
self.title = NSLocalizedString(@"Display", nil);
self.image = [NSImage imageNamed:@"display"];
}
return self;
}
- (void)refresh
{
NSUInteger index = MIN([NSUserDefaults.standardUserDefaults integerForKey:kVideoModePref], 1);
[self.videoModePopup selectItemAtIndex:index];
NSInteger macFrameSkipDefault = [NSUserDefaults.standardUserDefaults integerForKey:kMacFrameSkipPref];
// if macFrameSkip is equal to -1, set automatic checkbox
// to be checked, disable the ability to change frame skip values
// from stepper/text field, else leave automatic checkbox
// unchecked and set textfield to value
if (macFrameSkipDefault == -1) {
[self.macFrameSkipTextField setEnabled: false];
[self.macFrameSkipStepper setEnabled: false];
[self.macFrameSkipTextField setIntValue: 0]; // show something at least
[self.macFrameSkipAutomaticButton setIntValue: 1];
} else {
[self.macFrameSkipTextField setIntValue: (int)macFrameSkipDefault];
[self.macFrameSkipAutomaticButton setIntValue: 0];
}
self.showFPSCheckbox.state = [NSUserDefaults.standardUserDefaults boolForKey:kShowFPSPref];
}
- (void)setShowFPS:(BOOL)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setShowFPS:value];
}
- (void)setVideoMode:(int)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setVideoMode:value];
}
- (void)setMacFrameSkip:(int)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setMacFrameSkip:value];
}
- (IBAction)onCheckShowFPS:(NSButton *)sender
{
[self setShowFPS:sender.state == NSOnState];
}
- (IBAction)onSelectVideoMode:(NSPopUpButton *)sender
{
[self setVideoMode:(int)sender.selectedTag];
}
- (IBAction)bumpMacFrameSkip:(NSStepper *)sender
{
int bumpValue = sender.intValue; // 1 or -1
int nextValue = self.macFrameSkipTextField.intValue + bumpValue;
// constrain value
if (nextValue < 0) {
nextValue = 0;
}
if (nextValue > 200) {
nextValue = 200;
}
[self.macFrameSkipTextField setIntValue: nextValue];
[sender setIntValue:0]; // reset stepper value
[self setMacFrameSkip:self.macFrameSkipTextField.intValue]; // execute setter
}
- (IBAction)onChangeMacFrameSkipTextField:(NSTextField *)sender
{
[self setMacFrameSkip:sender.intValue];
}
- (IBAction)onCheckMacFrameSkipAutomaticButton:(NSButton *)sender
{
if (sender.intValue == 1) {
// when automatic is checked, disable macFrameSkipTextField and
// macFrameSkipStepper, then set macFrameSkip to -1 (automatic)
[self.macFrameSkipTextField setEnabled:false];
[self.macFrameSkipStepper setEnabled:false];
[self setMacFrameSkip:-1];
} else {
// when automatic is unchecked, enable macFrameSkipTextField and
// macFrameSkipStepper, then set macFrameSkip to value of text field
[self.macFrameSkipTextField setEnabled:true];
[self.macFrameSkipStepper setEnabled:true];
[self setMacFrameSkip:self.macFrameSkipTextField.intValue];
}
}
@end

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xDisplayPreferencesViewController">
<connections>
<outlet property="macFrameSkipAutomaticButton" destination="HpL-ki-SDO" id="hPl-P0-mvs"/>
<outlet property="macFrameSkipStepper" destination="zyT-O2-0sb" id="6Q0-2k-0T1"/>
<outlet property="macFrameSkipTextField" destination="Lbx-fj-Qrr" id="osF-6h-BzL"/>
<outlet property="showFPSCheckbox" destination="L7y-jf-JVg" id="6ow-hE-XXg"/>
<outlet property="videoModePopup" destination="OI9-bg-DuI" id="PvP-Hx-Vau"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="151"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="yd0-xg-vGs">
<rect key="frame" x="0.0" y="0.0" width="507" height="151"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="LFW-8s-VKQ">
<rect key="frame" x="119" y="0.0" width="270" height="151"/>
<subviews>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OI9-bg-DuI">
<rect key="frame" x="124" y="107" width="105" height="25"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="paO-Xk-hsA"/>
</constraints>
<popUpButtonCell key="cell" type="push" title="Blocky" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Vv2-tk-Ebi" id="jye-T4-0az">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="9AQ-P1-ChO">
<items>
<menuItem title="Blocky" state="on" id="Vv2-tk-Ebi"/>
<menuItem title="Smooth" tag="2" id="CLK-AE-tm8"/>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="onSelectVideoMode:" target="-2" id="lBQ-uk-W6V"/>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gpP-AC-4vc">
<rect key="frame" x="18" y="113" width="102" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Video Mode:" id="7JS-yL-J9G">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VBP-Fm-L9b">
<rect key="frame" x="18" y="65" width="102" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Frame Skipping:" id="mhD-jP-ljM">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uUW-Tw-a6Y">
<rect key="frame" x="124" y="91" width="82" height="11"/>
<textFieldCell key="cell" controlSize="mini" lineBreakMode="clipping" allowsUndo="NO" title="* Requires restart" id="1SE-Ov-fWE">
<font key="font" metaFont="label" size="9"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HpL-ki-SDO">
<rect key="frame" x="124" y="38" width="84" height="18"/>
<buttonCell key="cell" type="check" title="Automatic" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="4k0-7d-r2h">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onCheckMacFrameSkipAutomaticButton:" target="-2" id="dTf-XU-vh1"/>
</connections>
</button>
<textField verticalHuggingPriority="750" tag="30" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lbx-fj-Qrr">
<rect key="frame" x="126" y="62" width="100" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Iok-xg-PvY"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" allowsUndo="NO" state="on" borderStyle="bezel" userInterfaceLayoutDirection="rightToLeft" drawsBackground="YES" id="xyG-Of-4gh">
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" formatWidth="-1" groupingSize="0" minimumIntegerDigits="1" maximumIntegerDigits="42" id="BOo-d9-0U5">
<real key="minimum" value="0.0"/>
<real key="maximum" value="200"/>
</numberFormatter>
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="onChangeMacFrameSkipTextField:" target="-2" id="fsa-B9-lvw"/>
</connections>
</textField>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" tag="31" translatesAutoresizingMaskIntoConstraints="NO" id="zyT-O2-0sb">
<rect key="frame" x="223" y="59" width="19" height="28"/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="-1" maxValue="1" id="hfq-Kd-vMY"/>
<connections>
<action selector="bumpMacFrameSkip:" target="-2" id="nO0-pv-prO"/>
</connections>
</stepper>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="L7y-jf-JVg">
<rect key="frame" x="124" y="18" width="128" height="18"/>
<buttonCell key="cell" type="check" title="Show Frame Rate" bezelStyle="regularSquare" imagePosition="left" inset="2" id="Dh3-fX-pCP">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onCheckShowFPS:" target="-2" id="Ka2-ya-VKb"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="zyT-O2-0sb" firstAttribute="leading" secondItem="Lbx-fj-Qrr" secondAttribute="trailing" id="60H-eA-pm1"/>
<constraint firstItem="L7y-jf-JVg" firstAttribute="top" secondItem="HpL-ki-SDO" secondAttribute="bottom" constant="6" symbolic="YES" id="BO0-eG-e89"/>
<constraint firstItem="uUW-Tw-a6Y" firstAttribute="leading" secondItem="OI9-bg-DuI" secondAttribute="leading" id="CsD-Fy-FnF"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="OI9-bg-DuI" secondAttribute="trailing" constant="20" symbolic="YES" id="EnY-Ex-Vjr"/>
<constraint firstItem="OI9-bg-DuI" firstAttribute="top" secondItem="LFW-8s-VKQ" secondAttribute="top" constant="20" symbolic="YES" id="Gkp-If-WQ7"/>
<constraint firstItem="L7y-jf-JVg" firstAttribute="leading" secondItem="HpL-ki-SDO" secondAttribute="leading" id="Ii0-ir-7aA"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="L7y-jf-JVg" secondAttribute="trailing" constant="20" symbolic="YES" id="OVK-cK-U18"/>
<constraint firstItem="OI9-bg-DuI" firstAttribute="leading" secondItem="gpP-AC-4vc" secondAttribute="trailing" constant="8" symbolic="YES" id="P20-Ai-aR3"/>
<constraint firstItem="uUW-Tw-a6Y" firstAttribute="top" secondItem="OI9-bg-DuI" secondAttribute="bottom" constant="8" symbolic="YES" id="POE-lq-hTo"/>
<constraint firstItem="HpL-ki-SDO" firstAttribute="top" secondItem="Lbx-fj-Qrr" secondAttribute="bottom" constant="8" symbolic="YES" id="R2c-ft-4WS"/>
<constraint firstItem="HpL-ki-SDO" firstAttribute="leading" secondItem="Lbx-fj-Qrr" secondAttribute="leading" id="R9W-Ea-L6W"/>
<constraint firstItem="VBP-Fm-L9b" firstAttribute="trailing" secondItem="gpP-AC-4vc" secondAttribute="trailing" id="bWX-k2-FBV"/>
<constraint firstItem="VBP-Fm-L9b" firstAttribute="firstBaseline" secondItem="Lbx-fj-Qrr" secondAttribute="firstBaseline" id="eUP-IE-hXl"/>
<constraint firstItem="gpP-AC-4vc" firstAttribute="firstBaseline" secondItem="OI9-bg-DuI" secondAttribute="firstBaseline" id="gKc-rZ-1we"/>
<constraint firstItem="zyT-O2-0sb" firstAttribute="centerY" secondItem="Lbx-fj-Qrr" secondAttribute="centerY" id="js3-IF-IDi"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="HpL-ki-SDO" secondAttribute="trailing" constant="20" symbolic="YES" id="paD-hJ-4Gp"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" priority="250" constant="270" id="q4s-pc-mPg"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="zyT-O2-0sb" secondAttribute="trailing" constant="20" symbolic="YES" id="sr9-z2-jmc"/>
<constraint firstItem="Lbx-fj-Qrr" firstAttribute="top" secondItem="uUW-Tw-a6Y" secondAttribute="bottom" constant="8" symbolic="YES" id="t7b-0t-9sJ"/>
<constraint firstAttribute="bottom" secondItem="L7y-jf-JVg" secondAttribute="bottom" constant="20" symbolic="YES" id="uCs-pH-Z5k"/>
<constraint firstItem="VBP-Fm-L9b" firstAttribute="leading" secondItem="LFW-8s-VKQ" secondAttribute="leading" constant="20" symbolic="YES" id="uby-sK-7dY"/>
<constraint firstItem="Lbx-fj-Qrr" firstAttribute="leading" secondItem="VBP-Fm-L9b" secondAttribute="trailing" constant="8" symbolic="YES" id="xz5-q9-ZJa"/>
<constraint firstItem="gpP-AC-4vc" firstAttribute="leading" secondItem="LFW-8s-VKQ" secondAttribute="leading" constant="20" symbolic="YES" id="zbK-oD-FtO"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="507" id="LgG-58-Nxg"/>
<constraint firstItem="LFW-8s-VKQ" firstAttribute="centerX" secondItem="yd0-xg-vGs" secondAttribute="centerX" id="Yad-yP-t9Y"/>
<constraint firstItem="LFW-8s-VKQ" firstAttribute="top" secondItem="yd0-xg-vGs" secondAttribute="top" id="sGv-5E-LPr"/>
<constraint firstAttribute="bottom" secondItem="LFW-8s-VKQ" secondAttribute="bottom" id="tAE-dU-c7N"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="yd0-xg-vGs" secondAttribute="bottom" id="4u0-Fk-lFh"/>
<constraint firstAttribute="trailing" secondItem="yd0-xg-vGs" secondAttribute="trailing" id="SVF-Xc-xmN"/>
<constraint firstItem="yd0-xg-vGs" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="kPL-pE-UAT"/>
<constraint firstItem="yd0-xg-vGs" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="wvZ-g2-cfI"/>
</constraints>
<point key="canvasLocation" x="136.5" y="120.5"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface S9xEmulationPreferencesViewController : S9xPreferencesViewController
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,40 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xEmulationPreferencesViewController.h"
@interface S9xEmulationPreferencesViewController ()
@end
@implementation S9xEmulationPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xEmulationPreferencesViewController" bundle:nil])
{
self.title = NSLocalizedString(@"Emulation", nil);
self.image = [NSImage imageNamed:@"emulation"];
}
return self;
}
@end

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xEmulationPreferencesViewController">
<connections>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6GI-mh-tXk">
<rect key="frame" x="18" y="20" width="471" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="467" id="Pdt-vx-oWM"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Emulation preferences under development." id="o3r-9I-jVn">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="6GI-mh-tXk" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="GXM-Ra-e49"/>
<constraint firstAttribute="bottom" secondItem="6GI-mh-tXk" secondAttribute="bottom" constant="20" symbolic="YES" id="OUI-Ov-Y6R"/>
<constraint firstItem="6GI-mh-tXk" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="YVL-DQ-Gfa"/>
<constraint firstAttribute="trailing" secondItem="6GI-mh-tXk" secondAttribute="trailing" constant="20" symbolic="YES" id="a0U-zi-q3c"/>
</constraints>
<point key="canvasLocation" x="-126.5" y="0.0"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface S9xFilesPreferencesViewController : S9xPreferencesViewController
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,40 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xFilesPreferencesViewController.h"
@interface S9xFilesPreferencesViewController ()
@end
@implementation S9xFilesPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xFilesPreferencesViewController" bundle:nil])
{
self.title = NSLocalizedString(@"Files", nil);
self.image = [NSImage imageNamed:@"files"];
}
return self;
}
@end

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xFilesPreferencesViewController">
<connections>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aL7-Lc-j6C">
<rect key="frame" x="18" y="20" width="471" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="467" id="sPb-EJ-tB4"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Files preferences under development." id="pdV-RD-BIW">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="aL7-Lc-j6C" secondAttribute="bottom" constant="20" symbolic="YES" id="DHP-FQ-PUz"/>
<constraint firstItem="aL7-Lc-j6C" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="LOW-ER-gqe"/>
<constraint firstAttribute="trailing" secondItem="aL7-Lc-j6C" secondAttribute="trailing" constant="20" symbolic="YES" id="OFv-GT-WdM"/>
<constraint firstItem="aL7-Lc-j6C" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="uLy-CL-rzP"/>
</constraints>
<point key="canvasLocation" x="-126.5" y="0.0"/>
</customView>
</objects>
</document>

View File

@ -0,0 +1,281 @@
//
// S9xGamepadPreferencesViewController.m
// Snes9x
//
// Created by Buckley on 4/14/21.
//
#import <snes9x_framework/snes9x_framework.h>
#import "AppDelegate.h"
#import "S9xButtonConfigTextField.h"
#import "S9xPreferencesConstants.h"
#import "S9xControlsPreferencesViewController.h"
@interface S9xControlsPreferencesViewController () <S9xInputDelegate>
@property (nonatomic, weak) IBOutlet NSPopUpButton *devicePopUp;
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerPopUp;
@property (nonatomic, strong) NSArray *configTextFields;
@end
@implementation S9xControlsPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xGamepadPreferencesViewController" bundle:nil])
{
self.title = @"Controls";
}
return self;
}
@dynamic image;
- (NSImage *)image
{
return [NSImage imageNamed:@"gamepad"];
}
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSUInteger joypadIndex = 0;
for (S9xJoypad *joypad in [appDelegate listJoypads])
{
NSMenuItem *item = [NSMenuItem new];
item.title = joypad.name;
item.tag = joypadIndex++;
item.representedObject = joypad;
[self.devicePopUp.menu addItem:item];
}
// collect all S9xButtonConfigTextFields within subviews
NSMutableArray *configTextFields = [[NSMutableArray alloc] init];
for ( NSView *view in self.view.subviews )
{
if ([view isKindOfClass:[S9xButtonConfigTextField class]])
{
[configTextFields addObject:view];
}
}
self.configTextFields = configTextFields;
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
}
// select Keyboard as default
[self selectDeviceForPlayer:0];
}
- (void)refresh
{
if (self.devicePopUp.selectedItem.tag < 0)
{
NSMutableDictionary<NSNumber *, NSNumber *> *controlsDict = [NSMutableDictionary new];
NSDictionary *keyboardDict = [NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs];
NSInteger playerNum = self.playerPopUp.selectedItem.tag;
for (NSUInteger i = 0; i < kNumButtons; ++i)
{
controlsDict[@(i)] = keyboardDict[@(i + (playerNum * kNumButtons)).stringValue];
}
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
NSNumber *keyCode = controlsDict[@(configTextField.tag)];
configTextField.joypadInput = nil;
if ( keyCode != nil )
{
configTextField.keyCode = keyCode.intValue;
}
else
{
configTextField.keyCode = -1;
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = NO;
}
}
else
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
NSString *joypadKey = [appDelegate prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
NSDictionary *joypadDIct = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] objectForKey:joypadKey];
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
uint32 cookie = 0;
int32 value = 0;
S9xButtonCode buttonCode = (S9xButtonCode)configTextField.tag;
NSString *inputString = joypadDIct[@(buttonCode).stringValue];
configTextField.keyCode = -1;
if ([appDelegate getValuesFromString:inputString cookie:&cookie value:&value])
{
S9xJoypadInput *input = [S9xJoypadInput new];
input.cookie = cookie;
input.value = value;
input.buttonCode = buttonCode;
configTextField.joypadInput = input;
configTextField.stringValue = [appDelegate labelForVendorID:joypad.vendorID productID:joypad.productID cookie:cookie value:value];
}
else
{
configTextField.joypadInput = nil;
configTextField.stringValue = @"";
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = YES;
}
}
}
- (void)selectDeviceForPlayer:(int8_t)player
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSString* joypadKey = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadPlayerPrefs] objectForKey:@(player).stringValue];
[self.devicePopUp selectItemAtIndex:0];
if (joypadKey != nil)
{
uint32 vendorID = 0;
uint32 productID = 0;
uint32 index = 0;
if ( [appDelegate getValuesFromString:joypadKey vendorID:&vendorID productID:&productID index:&index])
{
S9xJoypad *joypad = [S9xJoypad new];
joypad.vendorID = vendorID;
joypad.productID = productID;
joypad.index = index;
for (NSMenuItem *item in self.devicePopUp.menu.itemArray)
{
if ([joypad isEqual:item.representedObject])
{
[self.devicePopUp selectItem:item];
break;
}
}
}
}
}
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad
{
id firstResponder = self.view.window.firstResponder;
if ([firstResponder respondsToSelector:@selector(isFieldEditor)] && [firstResponder isFieldEditor])
{
firstResponder = [firstResponder delegate];
}
if ([firstResponder respondsToSelector:@selector(setJoypadInput:)])
{
S9xJoypad *currentJoypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isEqual:currentJoypad])
{
[firstResponder setJoypadInput:input];
return YES;
}
}
return NO;
}
- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting {}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"keyCode"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
uint16_t keyCode = field.keyCode;
int8_t player = self.playerPopUp.selectedItem.tag;
if (keyCode != (CGKeyCode)-1)
{
[((AppDelegate *) NSApp.delegate) setButtonCode:buttonCode forKeyCode:keyCode player:player];
}
else
{
[((AppDelegate *) NSApp.delegate) clearButton:buttonCode forPlayer:player];
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
else if ( [keyPath isEqualToString:@"joypadInput"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isKindOfClass:[S9xJoypad class]])
{
S9xJoypadInput *input = field.joypadInput;
if (input != nil)
{
[((AppDelegate *)NSApp.delegate) setButton:buttonCode forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index cookie:input.cookie value:input.value];
}
else
{
[((AppDelegate *)NSApp.delegate) clearJoypadForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index buttonCode:buttonCode];
}
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
}
- (IBAction)playerDropdownChanged:(NSPopUpButton *)sender
{
[self selectDeviceForPlayer:sender.selectedTag];
[self refresh];
}
- (IBAction)deviceDropdownChanged:(NSPopUpButton *)sender
{
if (sender.selectedTag >= 0)
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = sender.selectedItem.representedObject;
[appDelegate setPlayer:self.playerPopUp.selectedTag forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
[NSUserDefaults.standardUserDefaults synchronize];
}
[self refresh];
}
@end

View File

@ -0,0 +1,32 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString * const kKeyboardPrefs;
extern NSString * const kJoypadInputPrefs;
extern NSString * const kJoypadPlayerPrefs;
extern NSString * const kShowFPSPref;
extern NSString * const kVideoModePref;
extern NSString * const kMacFrameSkipPref;
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,28 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesConstants.h"
NSString * const kKeyboardPrefs = @"KeyboardConfig";
NSString * const kJoypadInputPrefs = @"JoypadInputs";
NSString * const kJoypadPlayerPrefs = @"JoypadPlayers";
NSString * const kShowFPSPref = @"ShowFPS";
NSString * const kVideoModePref = @"VideoMode";
NSString * const kMacFrameSkipPref = @"FrameSkip";

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface S9xPreferencesTabViewController : NSTabViewController
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,79 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesTabViewController.h"
@interface S9xPreferencesTabViewController ()
@end
@implementation S9xPreferencesTabViewController
{
BOOL _didHide;
}
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
[super tabView:tabView willSelectTabViewItem:tabViewItem];
NSTabViewItem *currentTabViewItem = tabView.selectedTabViewItem;
if ( currentTabViewItem == nil || currentTabViewItem == tabViewItem )
{
return;
}
currentTabViewItem.view.hidden = YES;
tabViewItem.view.hidden = YES;
_didHide = YES;
NSWindow *window = self.view.window;
NSSize tabViewSize = tabViewItem.view.fittingSize;
NSSize newWindowSize = [window frameRectForContentRect:(CGRect){CGPointZero, tabViewSize}].size;
NSRect windowFrame = window.frame;
windowFrame.origin.y += windowFrame.size.height;
windowFrame.origin.y -= newWindowSize.height;
windowFrame.size = newWindowSize;
if ( self.isViewLoaded )
{
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context)
{
[self.view.window.animator setFrame:windowFrame display:YES];
} completionHandler:^
{
tabViewItem.view.hidden = NO;
}];
}
}
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
{
[super tabView:tabView didSelectTabViewItem:tabViewItem];
if ( _didHide )
{
tabViewItem.view.hidden = YES;
_didHide = NO;
}
}
@end

View File

@ -0,0 +1,33 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface S9xPreferencesViewController : NSViewController
- (void)refresh;
@property (nonatomic, strong) NSImage *image;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,40 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
@interface S9xPreferencesViewController ()
@end
@implementation S9xPreferencesViewController
- (void)viewWillAppear
{
[super viewWillAppear];
[self refresh];
}
- (void)refresh
{
// Implemented by subclasses.
}
@end

View File

@ -1,6 +1,6 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
@ -15,30 +15,16 @@
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <Cocoa/Cocoa.h>
#import "S9xButtonConfigTextField.h"
NS_ASSUME_NONNULL_BEGIN
extern NSString * const kKeyboardPrefs;
extern NSString * const kJoypadInputPrefs;
extern NSString * const kJoypadPlayerPrefs;
extern NSString * const kShowFPSPref;
extern NSString * const kVideoModePref;
extern NSString * const kMacFrameSkipPref;
@interface S9xPreferencesWindowController : NSWindowController<S9xInputDelegate>
@property (nonatomic, weak) IBOutlet NSTabView *tabView;
@property (nonatomic, weak) IBOutlet NSPopUpButton *videoModePopup;
@property (nonatomic, weak) IBOutlet NSButton *showFPSCheckbox;
@property (nonatomic, weak) IBOutlet NSPopUpButton *devicePopUp;
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerPopUp;
@property (nonatomic, weak) IBOutlet NSTextField *macFrameSkipTextField;
@property (nonatomic, weak) IBOutlet NSStepper *macFrameSkipStepper;
@property (nonatomic, weak) IBOutlet NSButton *macFrameSkipAutomaticButton;
@property (nonatomic, strong) NSArray *configTextFields;
@interface S9xPreferencesWindowController : NSWindowController
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,6 +1,6 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
@ -15,23 +15,39 @@
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 Michael Donald Buckley
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import <snes9x_framework/snes9x_framework.h>
#import "AppDelegate.h"
#import "S9xPreferencesWindowController.h"
#import "S9xButtonConfigTextField.h"
#import "S9xPreferencesConstants.h"
#import "S9xPreferencesWindowController.h"
NSString * const kKeyboardPrefs = @"KeyboardConfig";
NSString * const kJoypadInputPrefs = @"JoypadInputs";
NSString * const kJoypadPlayerPrefs = @"JoypadPlayers";
NSString * const kShowFPSPref = @"ShowFPS";
NSString * const kVideoModePref = @"VideoMode";
NSString * const kMacFrameSkipPref = @"FrameSkip";
#import "S9xPreferencesTabViewController.h"
#import "S9xControlsPreferencesViewController.h"
#import "S9xDisplayPreferencesViewController.h"
#import "S9xSoundPreferencesViewController.h"
#import "S9xEmulationPreferencesViewController.h"
#import "S9xFilesPreferencesViewController.h"
@interface S9xPreferencesWindowController ()
@property (nonatomic, readonly, strong) NSArray<S9xPreferencesViewController *> *tabs;
@property (nonatomic, readonly, strong) NSTabViewController *tabViewController;
@end
@implementation S9xPreferencesWindowController
@synthesize tabView, videoModePopup, showFPSCheckbox, devicePopUp, playerPopUp, macFrameSkipTextField, macFrameSkipStepper, macFrameSkipAutomaticButton, configTextFields;
- (NSArray<S9xPreferencesViewController *> *)tabs
{
return self.contentViewController.childViewControllers;
}
@dynamic tabViewController;
- (S9xPreferencesTabViewController *)tabViewController
{
return (S9xPreferencesTabViewController *)self.contentViewController;
}
- (void)windowDidLoad
{
@ -40,340 +56,45 @@ NSString * const kMacFrameSkipPref = @"FrameSkip";
- (void)awakeFromNib
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSUInteger joypadIndex = 0;
for (S9xJoypad *joypad in [appDelegate listJoypads])
{
NSMenuItem *item = [NSMenuItem new];
item.title = joypad.name;
item.tag = joypadIndex++;
item.representedObject = joypad;
[self.devicePopUp.menu addItem:item];
}
S9xPreferencesTabViewController *tabViewController = [S9xPreferencesTabViewController new];
tabViewController.tabStyle = NSTabViewControllerTabStyleToolbar;
self.contentViewController = tabViewController;
// collect all S9xButtonConfigTextFields within subviews
NSMutableArray *configTextFields = [[NSMutableArray alloc] init];
for (NSTabViewItem *tabViewItem in self.tabView.tabViewItems) {
[configTextFields addObjectsFromArray:[self getS9xButtonConfigTextFields:tabViewItem.view]];
}
self.configTextFields = configTextFields;
[self addPane:[S9xControlsPreferencesViewController new] to:tabViewController];
[self addPane:[S9xDisplayPreferencesViewController new] to:tabViewController];
[self addPane:[S9xSoundPreferencesViewController new] to:tabViewController];
[self addPane:[S9xEmulationPreferencesViewController new] to:tabViewController];
[self addPane:[S9xFilesPreferencesViewController new] to:tabViewController];
}
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
}
// select Keyboard as default
[self selectDeviceForPlayer:0];
- (void)addPane:(S9xPreferencesViewController *)pane to:(NSTabViewController *)tabController
{
[tabController addChildViewController:pane];
tabController.tabView.tabViewItems.lastObject.image = pane.image;
}
- (void)refresh
{
NSUInteger index = MIN([NSUserDefaults.standardUserDefaults integerForKey:kVideoModePref], 1);
[self.videoModePopup selectItemAtIndex:index];
NSInteger macFrameSkipDefault = [NSUserDefaults.standardUserDefaults integerForKey:kMacFrameSkipPref];
// if macFrameSkip is equal to -1, set automatic checkbox
// to be checked, disable the ability to change frame skip values
// from stepper/text field, else leave automatic checkbox
// unchecked and set textfield to value
if (macFrameSkipDefault == -1) {
[self.macFrameSkipTextField setEnabled: false];
[self.macFrameSkipStepper setEnabled: false];
[self.macFrameSkipTextField setIntValue: 0]; // show something at least
[self.macFrameSkipAutomaticButton setIntValue: 1];
} else {
[self.macFrameSkipTextField setIntValue: (int)macFrameSkipDefault];
[self.macFrameSkipAutomaticButton setIntValue: 0];
for ( S9xPreferencesViewController *tab in self.tabs )
{
[tab refresh];
}
self.showFPSCheckbox.state = [NSUserDefaults.standardUserDefaults boolForKey:kShowFPSPref];
if (self.devicePopUp.selectedItem.tag < 0)
{
NSMutableDictionary<NSNumber *, NSNumber *> *controlsDict = [NSMutableDictionary new];
NSDictionary *keyboardDict = [NSUserDefaults.standardUserDefaults objectForKey:kKeyboardPrefs];
NSInteger playerNum = self.playerPopUp.selectedItem.tag;
for (NSUInteger i = 0; i < kNumButtons; ++i)
{
controlsDict[@(i)] = keyboardDict[@(i + (playerNum * kNumButtons)).stringValue];
}
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
NSNumber *keyCode = controlsDict[@(configTextField.tag)];
configTextField.joypadInput = nil;
if ( keyCode != nil )
{
configTextField.keyCode = keyCode.intValue;
}
else
{
configTextField.keyCode = -1;
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = NO;
}
}
else
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
NSString *joypadKey = [appDelegate prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
NSDictionary *joypadDIct = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] objectForKey:joypadKey];
for (S9xButtonConfigTextField *configTextField in self.configTextFields)
{
[configTextField removeObserver:self forKeyPath:@"keyCode"];
[configTextField removeObserver:self forKeyPath:@"joypadInput"];
uint32 cookie = 0;
int32 value = 0;
S9xButtonCode buttonCode = (S9xButtonCode)configTextField.tag;
NSString *inputString = joypadDIct[@(buttonCode).stringValue];
configTextField.keyCode = -1;
if ([appDelegate getValuesFromString:inputString cookie:&cookie value:&value])
{
S9xJoypadInput *input = [S9xJoypadInput new];
input.cookie = cookie;
input.value = value;
input.buttonCode = buttonCode;
configTextField.joypadInput = input;
configTextField.stringValue = [appDelegate labelForVendorID:joypad.vendorID productID:joypad.productID cookie:cookie value:value];
}
else
{
configTextField.joypadInput = nil;
configTextField.stringValue = @"";
}
[configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL];
[configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL];
configTextField.disableKeyboardInput = YES;
}
}
}
- (NSArray *)getS9xButtonConfigTextFields:(NSView*)view {
NSMutableArray *S9xButtonConfigTextFields = [[NSMutableArray alloc] init];
if ([view isKindOfClass:[S9xButtonConfigTextField class]]) {
[S9xButtonConfigTextFields addObject:view];
} else if (view.subviews) {
for (NSView *subview in view.subviews) {
[S9xButtonConfigTextFields addObjectsFromArray:[self getS9xButtonConfigTextFields:subview]];
}
}
return [NSArray arrayWithArray:S9xButtonConfigTextFields];
}
- (void)selectDeviceForPlayer:(int8_t)player
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
NSString* joypadKey = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadPlayerPrefs] objectForKey:@(player).stringValue];
[self.devicePopUp selectItemAtIndex:0];
if (joypadKey != nil)
{
uint32 vendorID = 0;
uint32 productID = 0;
uint32 index = 0;
if ( [appDelegate getValuesFromString:joypadKey vendorID:&vendorID productID:&productID index:&index])
{
S9xJoypad *joypad = [S9xJoypad new];
joypad.vendorID = vendorID;
joypad.productID = productID;
joypad.index = index;
for (NSMenuItem *item in self.devicePopUp.menu.itemArray)
{
if ([joypad isEqual:item.representedObject])
{
[self.devicePopUp selectItem:item];
break;
}
}
}
}
}
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad
{
id firstResponder = self.window.firstResponder;
if ([firstResponder respondsToSelector:@selector(isFieldEditor)] && [firstResponder isFieldEditor])
{
firstResponder = [firstResponder delegate];
}
if ([firstResponder respondsToSelector:@selector(setJoypadInput:)])
{
S9xJoypad *currentJoypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isEqual:currentJoypad])
{
[firstResponder setJoypadInput:input];
return YES;
}
}
return NO;
}
- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting {}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"keyCode"])
NSTabViewController *tabViewController = self.tabViewController;
NSUInteger index = self.tabViewController.selectedTabViewItemIndex;
if ( index >= 0 && index < tabViewController.childViewControllers.count )
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
uint16_t keyCode = field.keyCode;
int8_t player = self.playerPopUp.selectedItem.tag;
if (keyCode != (CGKeyCode)-1)
S9xPreferencesViewController *viewController = tabViewController.childViewControllers[index];
if ( [viewController isKindOfClass:[S9xControlsPreferencesViewController class]] )
{
[((AppDelegate *) NSApp.delegate) setButtonCode:buttonCode forKeyCode:keyCode player:player];
return [((S9xControlsPreferencesViewController *)viewController) handleInput:input fromJoypad:joypad];
}
else
{
[((AppDelegate *) NSApp.delegate) clearButton:buttonCode forPlayer:player];
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
else if ( [keyPath isEqualToString:@"joypadInput"])
{
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
S9xJoypad *joypad = self.devicePopUp.selectedItem.representedObject;
if ([joypad isKindOfClass:[S9xJoypad class]])
{
S9xJoypadInput *input = field.joypadInput;
if (input != nil)
{
[((AppDelegate *)NSApp.delegate) setButton:buttonCode forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index cookie:input.cookie value:input.value];
}
else
{
[((AppDelegate *)NSApp.delegate) clearJoypadForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index buttonCode:buttonCode];
}
}
[NSUserDefaults.standardUserDefaults synchronize];
[self refresh];
}
}
- (void)setShowFPS:(BOOL)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setShowFPS:value];
}
- (void)setVideoMode:(int)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setVideoMode:value];
}
- (void)setMacFrameSkip:(int)value
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[appDelegate setMacFrameSkip:value];
}
- (IBAction)onToolbarItemPress:(NSToolbarItem *)sender
{
[self.tabView selectTabViewItemAtIndex:sender.tag];
}
- (IBAction)onCheckShowFPS:(NSButton *)sender
{
[self setShowFPS:sender.state == NSOnState];
}
- (IBAction)onSelectVideoMode:(NSPopUpButton *)sender
{
[self setVideoMode:(int)sender.selectedTag];
}
- (IBAction)bumpMacFrameSkip:(NSStepper *)sender
{
int bumpValue = sender.intValue; // 1 or -1
int nextValue = self.macFrameSkipTextField.intValue + bumpValue;
// constrain value
if (nextValue < 0) {
nextValue = 0;
}
if (nextValue > 200) {
nextValue = 200;
}
[self.macFrameSkipTextField setIntValue: nextValue];
[sender setIntValue:0]; // reset stepper value
[self setMacFrameSkip:self.macFrameSkipTextField.intValue]; // execute setter
}
- (IBAction)onChangeMacFrameSkipTextField:(NSTextField *)sender
{
[self setMacFrameSkip:sender.intValue];
}
- (IBAction)onCheckMacFrameSkipAutomaticButton:(NSButton *)sender
{
if (sender.intValue == 1) {
// when automatic is checked, disable macFrameSkipTextField and
// macFrameSkipStepper, then set macFrameSkip to -1 (automatic)
[self.macFrameSkipTextField setEnabled:false];
[self.macFrameSkipStepper setEnabled:false];
[self setMacFrameSkip:-1];
} else {
// when automatic is unchecked, enable macFrameSkipTextField and
// macFrameSkipStepper, then set macFrameSkip to value of text field
[self.macFrameSkipTextField setEnabled:true];
[self.macFrameSkipStepper setEnabled:true];
[self setMacFrameSkip:self.macFrameSkipTextField.intValue];
}
}
- (IBAction)onChangePlayerDropdown:(NSPopUpButton *)sender
{
[self selectDeviceForPlayer:sender.selectedTag];
[self refresh];
}
- (IBAction)onChangeDeviceDropdown:(NSPopUpButton *)sender
{
if (sender.selectedTag >= 0)
{
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
S9xJoypad *joypad = sender.selectedItem.representedObject;
[appDelegate setPlayer:self.playerPopUp.selectedTag forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
[NSUserDefaults.standardUserDefaults synchronize];
}
[self refresh];
return NO;
}
@end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xPreferencesViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface S9xSoundPreferencesViewController : S9xPreferencesViewController
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,40 @@
/*****************************************************************************\
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
This file is licensed under the Snes9x License.
For further information, consult the LICENSE file in the root directory.
\*****************************************************************************/
/***********************************************************************************
SNES9X for Mac OS (c) Copyright John Stiles
Snes9x for Mac OS X
(c) Copyright 2001 - 2011 zones
(c) Copyright 2002 - 2005 107
(c) Copyright 2002 PB1400c
(c) Copyright 2004 Alexander and Sander
(c) Copyright 2004 - 2005 Steven Seeger
(c) Copyright 2005 Ryan Vogt
(c) Copyright 2019 - 2021 Michael Donald Buckley
***********************************************************************************/
#import "S9xSoundPreferencesViewController.h"
@interface S9xSoundPreferencesViewController ()
@end
@implementation S9xSoundPreferencesViewController
- (instancetype)init
{
if (self = [super initWithNibName:@"S9xSoundPreferencesViewController" bundle:nil])
{
self.title = NSLocalizedString(@"Sound", nil);
self.image = [NSImage imageNamed:@"sound"];
}
return self;
}
@end

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="S9xSoundPreferencesViewController">
<connections>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="507" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="W94-br-7N2">
<rect key="frame" x="18" y="20" width="471" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="467" id="JJF-pE-kQF"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Sound preferences under development." id="uFa-AL-smD">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="W94-br-7N2" secondAttribute="trailing" constant="20" symbolic="YES" id="3bV-Wl-7UL"/>
<constraint firstItem="W94-br-7N2" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="EQA-Nv-uLN"/>
<constraint firstAttribute="bottom" secondItem="W94-br-7N2" secondAttribute="bottom" constant="20" symbolic="YES" id="Lpt-Rw-aXq"/>
<constraint firstItem="W94-br-7N2" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="U8K-Qr-NuM"/>
</constraints>
<point key="canvasLocation" x="136.5" y="0.0"/>
</customView>
</objects>
</document>

View File

@ -17,8 +17,20 @@
302EECA522DAD1B9006D1502 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 302EECA422DAD1B9006D1502 /* CoreAudio.framework */; };
3042F7E3232E9BDD00C03F5E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3042F7E2232E9BDD00C03F5E /* Carbon.framework */; };
3045A1EF22D03C4B0092B97D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3045A1EE22D03C4B0092B97D /* Cocoa.framework */; };
304B364A262E328400F8DC8E /* S9xControlsPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 304B3649262E328400F8DC8E /* S9xControlsPreferencesViewController.xib */; };
304B366C262E82B800F8DC8E /* S9xPreferencesConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 304B366B262E82B800F8DC8E /* S9xPreferencesConstants.m */; };
3059DA94250690DB003EF183 /* compat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3059DA93250690DB003EF183 /* compat.cpp */; };
30656200236A8BA700A1B3B2 /* gamecontrollerdb.txt in Resources */ = {isa = PBXBuildFile; fileRef = 306561FF236A8BA700A1B3B2 /* gamecontrollerdb.txt */; };
306937CA2635EE5800007ABB /* S9xDisplayPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937C82635EE5800007ABB /* S9xDisplayPreferencesViewController.m */; };
306937CB2635EE5800007ABB /* S9xDisplayPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 306937C92635EE5800007ABB /* S9xDisplayPreferencesViewController.xib */; };
306937D02636253900007ABB /* S9xPreferencesTabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937CF2636253900007ABB /* S9xPreferencesTabViewController.m */; };
306937D526362A1100007ABB /* S9xPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937D426362A1100007ABB /* S9xPreferencesViewController.m */; };
306937DC26362B2400007ABB /* S9xSoundPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937DA26362B2400007ABB /* S9xSoundPreferencesViewController.m */; };
306937DD26362B2400007ABB /* S9xSoundPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 306937DB26362B2400007ABB /* S9xSoundPreferencesViewController.xib */; };
306937E22636352100007ABB /* S9xEmulationPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937E02636352100007ABB /* S9xEmulationPreferencesViewController.m */; };
306937E32636352100007ABB /* S9xEmulationPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 306937E12636352100007ABB /* S9xEmulationPreferencesViewController.xib */; };
306937E82636365100007ABB /* S9xFilesPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 306937E62636365100007ABB /* S9xFilesPreferencesViewController.m */; };
306937E92636365100007ABB /* S9xFilesPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 306937E72636365100007ABB /* S9xFilesPreferencesViewController.xib */; };
30714719230E379500917F82 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 30714718230E379500917F82 /* AppDelegate.m */; };
3071471B230E379600917F82 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3071471A230E379600917F82 /* Assets.xcassets */; };
3071471E230E379600917F82 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3071471C230E379600917F82 /* MainMenu.xib */; };
@ -58,6 +70,7 @@
3082C4262378BCE80081CA7C /* FakeResources.c in Sources */ = {isa = PBXBuildFile; fileRef = 3082C4212378BCE80081CA7C /* FakeResources.c */; };
3082C4272378BCE80081CA7C /* FakeResources.h in Headers */ = {isa = PBXBuildFile; fileRef = 3082C4222378BCE80081CA7C /* FakeResources.h */; };
3082C42A2379199F0081CA7C /* S9xApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 3082C4292379199F0081CA7C /* S9xApplication.m */; };
309C54802627F3060055DD95 /* S9xControlsPreferencesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 309C547F2627F3060055DD95 /* S9xControlsPreferencesViewController.m */; };
30A6F62423B2771A00630584 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A6F62323B2771A00630584 /* MetalKit.framework */; };
30A6F62623B29EF500630584 /* shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 30A6F62523B29EF500630584 /* shaders.metal */; };
30A6F62823B29F8200630584 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30A6F62723B29F8200630584 /* Metal.framework */; };
@ -259,8 +272,27 @@
3042F7E2232E9BDD00C03F5E /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
3045A1EC22D03C430092B97D /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
3045A1EE22D03C4B0092B97D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
304B3649262E328400F8DC8E /* S9xControlsPreferencesViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = S9xControlsPreferencesViewController.xib; sourceTree = "<group>"; };
304B366A262E82B800F8DC8E /* S9xPreferencesConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPreferencesConstants.h; sourceTree = "<group>"; };
304B366B262E82B800F8DC8E /* S9xPreferencesConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPreferencesConstants.m; sourceTree = "<group>"; };
3059DA93250690DB003EF183 /* compat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = compat.cpp; sourceTree = "<group>"; };
306561FF236A8BA700A1B3B2 /* gamecontrollerdb.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = gamecontrollerdb.txt; sourceTree = "<group>"; };
306937C72635EE5800007ABB /* S9xDisplayPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xDisplayPreferencesViewController.h; sourceTree = "<group>"; };
306937C82635EE5800007ABB /* S9xDisplayPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xDisplayPreferencesViewController.m; sourceTree = "<group>"; };
306937C92635EE5800007ABB /* S9xDisplayPreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xDisplayPreferencesViewController.xib; sourceTree = "<group>"; };
306937CE2636253900007ABB /* S9xPreferencesTabViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPreferencesTabViewController.h; sourceTree = "<group>"; };
306937CF2636253900007ABB /* S9xPreferencesTabViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPreferencesTabViewController.m; sourceTree = "<group>"; };
306937D326362A1100007ABB /* S9xPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPreferencesViewController.h; sourceTree = "<group>"; };
306937D426362A1100007ABB /* S9xPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPreferencesViewController.m; sourceTree = "<group>"; };
306937D926362B2400007ABB /* S9xSoundPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xSoundPreferencesViewController.h; sourceTree = "<group>"; };
306937DA26362B2400007ABB /* S9xSoundPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xSoundPreferencesViewController.m; sourceTree = "<group>"; };
306937DB26362B2400007ABB /* S9xSoundPreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xSoundPreferencesViewController.xib; sourceTree = "<group>"; };
306937DF2636352100007ABB /* S9xEmulationPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xEmulationPreferencesViewController.h; sourceTree = "<group>"; };
306937E02636352100007ABB /* S9xEmulationPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xEmulationPreferencesViewController.m; sourceTree = "<group>"; };
306937E12636352100007ABB /* S9xEmulationPreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xEmulationPreferencesViewController.xib; sourceTree = "<group>"; };
306937E52636365100007ABB /* S9xFilesPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xFilesPreferencesViewController.h; sourceTree = "<group>"; };
306937E62636365100007ABB /* S9xFilesPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xFilesPreferencesViewController.m; sourceTree = "<group>"; };
306937E72636365100007ABB /* S9xFilesPreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xFilesPreferencesViewController.xib; sourceTree = "<group>"; };
30714715230E379500917F82 /* Snes9x.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Snes9x.app; sourceTree = BUILT_PRODUCTS_DIR; };
30714717230E379500917F82 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
30714718230E379500917F82 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; usesTabs = 0; };
@ -285,6 +317,8 @@
3082C4222378BCE80081CA7C /* FakeResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FakeResources.h; sourceTree = "<group>"; };
3082C4282379199F0081CA7C /* S9xApplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xApplication.h; sourceTree = "<group>"; };
3082C4292379199F0081CA7C /* S9xApplication.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xApplication.m; sourceTree = "<group>"; };
309C547E2627F3060055DD95 /* S9xControlsPreferencesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xControlsPreferencesViewController.h; sourceTree = "<group>"; };
309C547F2627F3060055DD95 /* S9xControlsPreferencesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xControlsPreferencesViewController.m; sourceTree = "<group>"; };
30A6F62323B2771A00630584 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; };
30A6F62523B29EF500630584 /* shaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = shaders.metal; sourceTree = "<group>"; };
30A6F62723B29F8200630584 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
@ -677,9 +711,30 @@
children = (
30D709C3236F90DF00AAB7C3 /* S9xButtonConfigTextField.h */,
30D709C4236F90DF00AAB7C3 /* S9xButtonConfigTextField.m */,
309C547E2627F3060055DD95 /* S9xControlsPreferencesViewController.h */,
309C547F2627F3060055DD95 /* S9xControlsPreferencesViewController.m */,
304B3649262E328400F8DC8E /* S9xControlsPreferencesViewController.xib */,
306937C72635EE5800007ABB /* S9xDisplayPreferencesViewController.h */,
306937C82635EE5800007ABB /* S9xDisplayPreferencesViewController.m */,
306937C92635EE5800007ABB /* S9xDisplayPreferencesViewController.xib */,
306937DF2636352100007ABB /* S9xEmulationPreferencesViewController.h */,
306937E02636352100007ABB /* S9xEmulationPreferencesViewController.m */,
306937E12636352100007ABB /* S9xEmulationPreferencesViewController.xib */,
306937E52636365100007ABB /* S9xFilesPreferencesViewController.h */,
306937E62636365100007ABB /* S9xFilesPreferencesViewController.m */,
306937E72636365100007ABB /* S9xFilesPreferencesViewController.xib */,
304B366A262E82B800F8DC8E /* S9xPreferencesConstants.h */,
304B366B262E82B800F8DC8E /* S9xPreferencesConstants.m */,
306937CE2636253900007ABB /* S9xPreferencesTabViewController.h */,
306937CF2636253900007ABB /* S9xPreferencesTabViewController.m */,
306937D326362A1100007ABB /* S9xPreferencesViewController.h */,
306937D426362A1100007ABB /* S9xPreferencesViewController.m */,
30D709BE236F7E3200AAB7C3 /* S9xPreferencesWindowController.h */,
30D709BF236F7E3200AAB7C3 /* S9xPreferencesWindowController.m */,
30D709C0236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib */,
306937D926362B2400007ABB /* S9xSoundPreferencesViewController.h */,
306937DA26362B2400007ABB /* S9xSoundPreferencesViewController.m */,
306937DB26362B2400007ABB /* S9xSoundPreferencesViewController.xib */,
);
path = S9xPreferences;
sourceTree = "<group>";
@ -1175,7 +1230,10 @@
3071471B230E379600917F82 /* Assets.xcassets in Resources */,
30D709B4236F731B00AAB7C3 /* SAVE.icns in Resources */,
30D709B8236F731B00AAB7C3 /* musicbox_ledoff.icns in Resources */,
306937CB2635EE5800007ABB /* S9xDisplayPreferencesViewController.xib in Resources */,
306937E92636365100007ABB /* S9xFilesPreferencesViewController.xib in Resources */,
30D709B0236F583600AAB7C3 /* Localizable.strings in Resources */,
304B364A262E328400F8DC8E /* S9xControlsPreferencesViewController.xib in Resources */,
30D709B1236F585100AAB7C3 /* Snes9x Help in Resources */,
30D709B3236F731B00AAB7C3 /* SRAM.icns in Resources */,
30D709B5236F731B00AAB7C3 /* folder_SRAMs.icns in Resources */,
@ -1183,7 +1241,9 @@
30D709B7236F731B00AAB7C3 /* musicbox_ledon.icns in Resources */,
30D709B6236F731B00AAB7C3 /* folder_Freezes.icns in Resources */,
30D709C2236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib in Resources */,
306937E32636352100007ABB /* S9xEmulationPreferencesViewController.xib in Resources */,
3071471E230E379600917F82 /* MainMenu.xib in Resources */,
306937DD26362B2400007ABB /* S9xSoundPreferencesViewController.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1205,11 +1265,19 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
306937D526362A1100007ABB /* S9xPreferencesViewController.m in Sources */,
306937E22636352100007ABB /* S9xEmulationPreferencesViewController.m in Sources */,
309C54802627F3060055DD95 /* S9xControlsPreferencesViewController.m in Sources */,
30D709C5236F90DF00AAB7C3 /* S9xButtonConfigTextField.m in Sources */,
306937E82636365100007ABB /* S9xFilesPreferencesViewController.m in Sources */,
306937D02636253900007ABB /* S9xPreferencesTabViewController.m in Sources */,
30714721230E379600917F82 /* main.m in Sources */,
306937CA2635EE5800007ABB /* S9xDisplayPreferencesViewController.m in Sources */,
30714719230E379500917F82 /* AppDelegate.m in Sources */,
306937DC26362B2400007ABB /* S9xSoundPreferencesViewController.m in Sources */,
3082C42A2379199F0081CA7C /* S9xApplication.m in Sources */,
30D709C1236F7E3200AAB7C3 /* S9xPreferencesWindowController.m in Sources */,
304B366C262E82B800F8DC8E /* S9xPreferencesConstants.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};