diff --git a/macosx/Snes9x/AppDelegate.h b/macosx/Snes9x/AppDelegate.h index 6b6ef36f..b3b872bd 100644 --- a/macosx/Snes9x/AppDelegate.h +++ b/macosx/Snes9x/AppDelegate.h @@ -20,10 +20,17 @@ #import #import +#import "S9xPreferences/S9xPreferencesWindowController.h" + +extern NSWindowFrameAutosaveName const kMainWindowIdentifier; @interface AppDelegate : NSObject @property (nonatomic, readonly, assign) BOOL isRunningEmulation; +@property (nonatomic, strong) S9xEngine *s9xEngine; +@property (nonatomic, strong) NSMutableDictionary *keys; +@property (nonatomic, strong) NSWindow *gameWindow; +@property (nonatomic, strong) S9xPreferencesWindowController *preferencesWindowController; - (void)setButtonCode:(S9xButtonCode)buttonCode forKeyCode:(int16)keyCode player:(int8)player; - (void)clearButton:(S9xButtonCode)button forPlayer:(int8)player; diff --git a/macosx/Snes9x/AppDelegate.m b/macosx/Snes9x/AppDelegate.m index 7cf43904..53be4ace 100644 --- a/macosx/Snes9x/AppDelegate.m +++ b/macosx/Snes9x/AppDelegate.m @@ -19,20 +19,9 @@ ***********************************************************************************/ #import - #import "AppDelegate.h" -#import "S9xPrefsConstants.h" -#import "S9xPrefsViewController.h" - -@interface AppDelegate () -@property (nonatomic, strong) S9xEngine *s9xEngine; -@property (nonatomic, strong) NSMutableDictionary *keys; -@property (nonatomic, strong) NSWindow *window; -@property (nonatomic, strong, nullable) NSWindowController *prefsWindowController; -@end - -static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; +NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; @implementation AppDelegate @@ -42,25 +31,25 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; [self setupDefaults]; [self importRecentItems]; - NSWindow *window = [[NSWindow alloc] initWithContentRect:s9xView.frame styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO]; + NSWindow *gameWindow = [[NSWindow alloc] initWithContentRect:s9xView.frame styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO]; - window.contentView.wantsLayer = YES; - window.contentView.layer.backgroundColor = NSColor.blackColor.CGColor; + gameWindow.contentView.wantsLayer = YES; + gameWindow.contentView.layer.backgroundColor = NSColor.blackColor.CGColor; - window.title = @"Snes9x"; - window.restorationClass = [self class]; - window.frameAutosaveName = kMainWindowIdentifier; - window.releasedWhenClosed = NO; - window.backgroundColor = NSColor.clearColor; + gameWindow.title = @"Snes9x"; + gameWindow.restorationClass = [self class]; + gameWindow.frameAutosaveName = kMainWindowIdentifier; + gameWindow.releasedWhenClosed = NO; + gameWindow.backgroundColor = NSColor.clearColor; - if ( ![window setFrameUsingName:kMainWindowIdentifier] ) + if ( ![gameWindow setFrameUsingName:kMainWindowIdentifier] ) { - [window center]; + [gameWindow center]; } - self.window = window; + self.gameWindow = gameWindow; - [NSNotificationCenter.defaultCenter addObserverForName:NSWindowWillCloseNotification object:window queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification *notification) + [NSNotificationCenter.defaultCenter addObserverForName:NSWindowWillCloseNotification object:gameWindow queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification *notification) { [self.s9xEngine quit]; }]; @@ -453,16 +442,16 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; { [self.s9xEngine recreateS9xView]; - NSWindow *window = self.window; - [window.contentView addSubview:s9xView]; - [s9xView.topAnchor constraintEqualToAnchor:window.contentView.topAnchor].active = YES; - [s9xView.bottomAnchor constraintEqualToAnchor:window.contentView.bottomAnchor].active = YES; - [s9xView.centerXAnchor constraintEqualToAnchor:window.contentView.centerXAnchor].active = YES; - [s9xView.leftAnchor constraintGreaterThanOrEqualToAnchor:window.contentView.leftAnchor].active = YES; - [s9xView.rightAnchor constraintLessThanOrEqualToAnchor:window.contentView.rightAnchor].active = YES; + NSWindow *gameWindow = self.gameWindow; + [gameWindow.contentView addSubview:s9xView]; + [s9xView.topAnchor constraintEqualToAnchor:gameWindow.contentView.topAnchor].active = YES; + [s9xView.bottomAnchor constraintEqualToAnchor:gameWindow.contentView.bottomAnchor].active = YES; + [s9xView.centerXAnchor constraintEqualToAnchor:gameWindow.contentView.centerXAnchor].active = YES; + [s9xView.leftAnchor constraintGreaterThanOrEqualToAnchor:gameWindow.contentView.leftAnchor].active = YES; + [s9xView.rightAnchor constraintLessThanOrEqualToAnchor:gameWindow.contentView.rightAnchor].active = YES; - [window makeKeyAndOrderFront:self]; + [gameWindow makeKeyAndOrderFront:self]; [NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:url]; return YES; } @@ -492,19 +481,16 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; [NSApp terminate:sender]; } -- (IBAction)openPrefs:(id)sender +- (IBAction)openPreferencesWindow:(id)sender { - if ( self.prefsWindowController == nil ) + if ( self.preferencesWindowController == nil ) { - NSWindow *prefsWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable backing:NSBackingStoreBuffered defer:NO]; - prefsWindow.title = NSLocalizedString(@"Preferences", @""); - self.prefsWindowController = [[NSWindowController alloc] initWithWindow:prefsWindow]; - - prefsWindow.contentViewController = [[S9xPrefsViewController alloc] initWithNibName:@"S9xPrefsViewController" bundle:nil]; - [prefsWindow center]; - } - - [self.prefsWindowController.window makeKeyAndOrderFront:self]; + self.preferencesWindowController = [[S9xPreferencesWindowController alloc] initWithWindowNibName:@"S9xPreferencesWindowController"]; + } + + [self.preferencesWindowController showWindow:nil]; + [self.preferencesWindowController.window makeKeyAndOrderFront:nil]; + [self.preferencesWindowController.window makeKeyWindow]; } - (void)setVideoMode:(int)videoMode @@ -545,9 +531,9 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; - (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad { - if (NSApp.keyWindow != nil && NSApp.keyWindow == self.prefsWindowController.window) + if (NSApp.keyWindow != nil && NSApp.keyWindow == self.preferencesWindowController.window) { - return [((S9xPrefsViewController *) self.prefsWindowController.contentViewController) handleInput:input fromJoypad:joypad]; + return [((S9xPreferencesWindowController *) self.preferencesWindowController.contentViewController) handleInput:input fromJoypad:joypad]; } return NO; diff --git a/macosx/Snes9x/Base.lproj/MainMenu.xib b/macosx/Snes9x/Base.lproj/MainMenu.xib index e5258657..9b36323f 100644 --- a/macosx/Snes9x/Base.lproj/MainMenu.xib +++ b/macosx/Snes9x/Base.lproj/MainMenu.xib @@ -1,8 +1,7 @@ - + - - + @@ -29,7 +28,7 @@ - + diff --git a/macosx/Snes9x/S9xButtonConfigTextField.h b/macosx/Snes9x/S9xPreferences/S9xButtonConfigTextField.h similarity index 100% rename from macosx/Snes9x/S9xButtonConfigTextField.h rename to macosx/Snes9x/S9xPreferences/S9xButtonConfigTextField.h diff --git a/macosx/Snes9x/S9xButtonConfigTextField.m b/macosx/Snes9x/S9xPreferences/S9xButtonConfigTextField.m similarity index 99% rename from macosx/Snes9x/S9xButtonConfigTextField.m rename to macosx/Snes9x/S9xPreferences/S9xButtonConfigTextField.m index 00eea7ec..9dbd76e2 100644 --- a/macosx/Snes9x/S9xButtonConfigTextField.m +++ b/macosx/Snes9x/S9xPreferences/S9xButtonConfigTextField.m @@ -20,7 +20,6 @@ #include #include - #import "S9xButtonConfigTextField.h" @implementation S9xButtonConfigTextField diff --git a/macosx/Snes9x/S9xPrefsConstants.h b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.h similarity index 59% rename from macosx/Snes9x/S9xPrefsConstants.h rename to macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.h index adb1bd6e..feb31366 100644 --- a/macosx/Snes9x/S9xPrefsConstants.h +++ b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.h @@ -17,8 +17,10 @@ (c) Copyright 2005 Ryan Vogt (c) Copyright 2019 Michael Donald Buckley ***********************************************************************************/ +#import +#import "S9xButtonConfigTextField.h" -#import +NS_ASSUME_NONNULL_BEGIN extern NSString * const kKeyboardPrefs; extern NSString * const kJoypadInputPrefs; @@ -26,3 +28,17 @@ extern NSString * const kJoypadPlayerPrefs; extern NSString * const kShowFPSPref; extern NSString * const kVideoModePref; extern NSString * const kMacFrameSkipPref; + +@interface S9xPreferencesWindowController : NSWindowController +@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; +@end + +NS_ASSUME_NONNULL_END diff --git a/macosx/Snes9x/S9xPrefsViewController.m b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m similarity index 66% rename from macosx/Snes9x/S9xPrefsViewController.m rename to macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m index f351dcb9..ed27397c 100644 --- a/macosx/Snes9x/S9xPrefsViewController.m +++ b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m @@ -19,23 +19,24 @@ ***********************************************************************************/ #import - #import "AppDelegate.h" -#import "S9xPrefsConstants.h" -#import "S9xPrefsViewController.h" +#import "S9xPreferencesWindowController.h" #import "S9xButtonConfigTextField.h" -@interface S9xPrefsViewController () -@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; -@end +NSString * const kKeyboardPrefs = @"KeyboardConfig"; +NSString * const kJoypadInputPrefs = @"JoypadInputs"; +NSString * const kJoypadPlayerPrefs = @"JoypadPlayers"; +NSString * const kShowFPSPref = @"ShowFPS"; +NSString * const kVideoModePref = @"VideoMode"; +NSString * const kMacFrameSkipPref = @"FrameSkip"; -@implementation S9xPrefsViewController +@implementation S9xPreferencesWindowController +@synthesize tabView, videoModePopup, showFPSCheckbox, devicePopUp, playerPopUp, macFrameSkipTextField, macFrameSkipStepper, macFrameSkipAutomaticButton, configTextFields; + +- (void)windowDidLoad +{ + [self refresh]; +} - (void)awakeFromNib { @@ -50,56 +51,21 @@ [self.devicePopUp.menu addItem:item]; } + // 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; + + 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]; - - for (NSView *subview in self.view.subviews) - { - if ( [subview isKindOfClass:[S9xButtonConfigTextField class]] ) - { - S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)subview; - [field addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL]; - [field addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL]; - } - } -} - -- (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; - } - } - } - } -} - -- (void)viewDidAppear -{ - [super viewDidAppear]; - [self.view.window makeFirstResponder:self.view]; - [self refresh]; } - (void)refresh @@ -136,33 +102,28 @@ controlsDict[@(i)] = keyboardDict[@(i + (playerNum * kNumButtons)).stringValue]; } - for (NSView *subview in self.view.subviews) + for (S9xButtonConfigTextField *configTextField in self.configTextFields) { - if ([subview isKindOfClass:[S9xButtonConfigTextField class]]) - { - S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)subview; + [configTextField removeObserver:self forKeyPath:@"keyCode"]; + [configTextField removeObserver:self forKeyPath:@"joypadInput"]; - [field removeObserver:self forKeyPath:@"keyCode"]; - [field removeObserver:self forKeyPath:@"joypadInput"]; + NSNumber *keyCode = controlsDict[@(configTextField.tag)]; - NSNumber *keyCode = controlsDict[@(field.tag)]; + configTextField.joypadInput = nil; - field.joypadInput = nil; + if ( keyCode != nil ) + { + configTextField.keyCode = keyCode.intValue; + } + else + { + configTextField.keyCode = -1; + } - if ( keyCode != nil ) - { - field.keyCode = keyCode.intValue; - } - else - { - field.keyCode = -1; - } + [configTextField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL]; + [configTextField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL]; - [field addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL]; - [field addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL]; - - field.disableKeyboardInput = NO; - } + configTextField.disableKeyboardInput = NO; } } else @@ -172,46 +133,109 @@ NSString *joypadKey = [appDelegate prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index]; NSDictionary *joypadDIct = [[NSUserDefaults.standardUserDefaults objectForKey:kJoypadInputPrefs] objectForKey:joypadKey]; - for (NSView *subview in self.view.subviews) + for (S9xButtonConfigTextField *configTextField in self.configTextFields) { - if ([subview isKindOfClass:[S9xButtonConfigTextField class]]) + [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) { - S9xButtonConfigTextField *textField = (S9xButtonConfigTextField *)subview; - - [textField removeObserver:self forKeyPath:@"keyCode"]; - [textField removeObserver:self forKeyPath:@"joypadInput"]; - - uint32 cookie = 0; - int32 value = 0; - S9xButtonCode buttonCode = (S9xButtonCode)textField.tag; - NSString *inputString = joypadDIct[@(buttonCode).stringValue]; - - textField.keyCode = -1; - - if ([appDelegate getValuesFromString:inputString cookie:&cookie value:&value]) + if ([joypad isEqual:item.representedObject]) { - S9xJoypadInput *input = [S9xJoypadInput new]; - input.cookie = cookie; - input.value = value; - input.buttonCode = buttonCode; - textField.joypadInput = input; - textField.stringValue = [appDelegate labelForVendorID:joypad.vendorID productID:joypad.productID cookie:cookie value:value]; + [self.devicePopUp selectItem:item]; + break; } - else - { - textField.joypadInput = nil; - textField.stringValue = @""; - } - - [textField addObserver:self forKeyPath:@"keyCode" options:NSKeyValueObservingOptionNew context:NULL]; - [textField addObserver:self forKeyPath:@"joypadInput" options:NSKeyValueObservingOptionNew context:NULL]; - - textField.disableKeyboardInput = YES; } } } } +- (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)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"keyCode"]) @@ -259,67 +283,40 @@ } } -- (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]; -} - -- (IBAction)showFPS:(NSButton *)sender +- (void)setShowFPS:(BOOL)value { AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; - [appDelegate setShowFPS:sender.state == NSOnState]; + [appDelegate setShowFPS:value]; } -- (IBAction)setVideoMode:(NSPopUpButton *)sender +- (void)setVideoMode:(int)value { AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; - [appDelegate setVideoMode:(int)sender.selectedTag]; + [appDelegate setVideoMode:value]; } -- (IBAction)setMacFrameSkip:(int)value +- (void)setMacFrameSkip:(int)value { AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; [appDelegate setMacFrameSkip:value]; } -- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad +- (IBAction)onToolbarItemPress:(NSToolbarItem *)sender { - 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; + [self.tabView selectTabViewItemAtIndex:sender.tag]; } -- (IBAction) bumpMacFrameSkip:(NSStepper *)sender +- (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; @@ -342,7 +339,7 @@ [self setMacFrameSkip:sender.intValue]; } -- (IBAction) onCheckMacFrameSkipAutomaticButton:(NSButton *)sender +- (IBAction)onCheckMacFrameSkipAutomaticButton:(NSButton *)sender { if (sender.intValue == 1) { // when automatic is checked, disable macFrameSkipTextField and @@ -358,4 +355,22 @@ [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]; +} @end diff --git a/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.xib b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.xib new file mode 100644 index 00000000..eef93933 --- /dev/null +++ b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.xib @@ -0,0 +1,1593 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macosx/Snes9x/S9xPrefsConstants.m b/macosx/Snes9x/S9xPrefsConstants.m deleted file mode 100644 index 56adac4c..00000000 --- a/macosx/Snes9x/S9xPrefsConstants.m +++ /dev/null @@ -1,28 +0,0 @@ -/*****************************************************************************\ - 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 Michael Donald Buckley - ***********************************************************************************/ - -#import "S9xPrefsConstants.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"; diff --git a/macosx/Snes9x/S9xPrefsViewController.h b/macosx/Snes9x/S9xPrefsViewController.h deleted file mode 100644 index bc3b908c..00000000 --- a/macosx/Snes9x/S9xPrefsViewController.h +++ /dev/null @@ -1,28 +0,0 @@ -/*****************************************************************************\ - 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 Michael Donald Buckley - ***********************************************************************************/ -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface S9xPrefsViewController : NSViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/macosx/Snes9x/S9xPrefsViewController.xib b/macosx/Snes9x/S9xPrefsViewController.xib deleted file mode 100644 index 970908f5..00000000 --- a/macosx/Snes9x/S9xPrefsViewController.xib +++ /dev/null @@ -1,873 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/macosx/snes9x.xcodeproj/project.pbxproj b/macosx/snes9x.xcodeproj/project.pbxproj index 397656db..e3368cf4 100755 --- a/macosx/snes9x.xcodeproj/project.pbxproj +++ b/macosx/snes9x.xcodeproj/project.pbxproj @@ -209,7 +209,6 @@ 30D15DE822CE6BC9005BC352 /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = CFA518D60EBCB4CA008379F6 /* ioapi.h */; }; 30D15DE922CE6BC9005BC352 /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = CFA518DA0EBCB4D2008379F6 /* unzip.h */; }; 30D15DEA22CE6FE1005BC352 /* mac-os.mm in Sources */ = {isa = PBXBuildFile; fileRef = EAE0E96604D582B700A80003 /* mac-os.mm */; }; - 30D2506E2373AACC0076A160 /* S9xPrefsConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D2506D2373AACC0076A160 /* S9xPrefsConstants.m */; }; 30D709B0236F583600AAB7C3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = EA3BEA980A28384E00A8FAE5 /* Localizable.strings */; }; 30D709B1236F585100AAB7C3 /* Snes9x Help in Resources */ = {isa = PBXBuildFile; fileRef = EA3BEAA80A28386500A8FAE5 /* Snes9x Help */; }; 30D709B2236F731B00AAB7C3 /* CART.icns in Resources */ = {isa = PBXBuildFile; fileRef = EA3D2F3C0A26083B00BDACCC /* CART.icns */; }; @@ -219,8 +218,8 @@ 30D709B6236F731B00AAB7C3 /* folder_Freezes.icns in Resources */ = {isa = PBXBuildFile; fileRef = EA3D2F3B0A26083B00BDACCC /* folder_Freezes.icns */; }; 30D709B7236F731B00AAB7C3 /* musicbox_ledon.icns in Resources */ = {isa = PBXBuildFile; fileRef = EA3D2F380A26083B00BDACCC /* musicbox_ledon.icns */; }; 30D709B8236F731B00AAB7C3 /* musicbox_ledoff.icns in Resources */ = {isa = PBXBuildFile; fileRef = EA3D2F390A26083B00BDACCC /* musicbox_ledoff.icns */; }; - 30D709C1236F7E3200AAB7C3 /* S9xPrefsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D709BF236F7E3200AAB7C3 /* S9xPrefsViewController.m */; }; - 30D709C2236F7E3200AAB7C3 /* S9xPrefsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 30D709C0236F7E3200AAB7C3 /* S9xPrefsViewController.xib */; }; + 30D709C1236F7E3200AAB7C3 /* S9xPreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D709BF236F7E3200AAB7C3 /* S9xPreferencesWindowController.m */; }; + 30D709C2236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 30D709C0236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib */; }; 30D709C5236F90DF00AAB7C3 /* S9xButtonConfigTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 30D709C4236F90DF00AAB7C3 /* S9xButtonConfigTextField.m */; }; /* End PBXBuildFile section */ @@ -298,11 +297,9 @@ 30D15CEF22CE6B5A005BC352 /* snes9x_framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = snes9x_framework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30D15CF122CE6B5A005BC352 /* snes9x_framework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = snes9x_framework.h; sourceTree = ""; }; 30D15CF222CE6B5A005BC352 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 30D2506D2373AACC0076A160 /* S9xPrefsConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPrefsConstants.m; sourceTree = ""; }; - 30D2506F2373AB880076A160 /* S9xPrefsConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPrefsConstants.h; sourceTree = ""; }; - 30D709BE236F7E3200AAB7C3 /* S9xPrefsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPrefsViewController.h; sourceTree = ""; }; - 30D709BF236F7E3200AAB7C3 /* S9xPrefsViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPrefsViewController.m; sourceTree = ""; }; - 30D709C0236F7E3200AAB7C3 /* S9xPrefsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xPrefsViewController.xib; sourceTree = ""; }; + 30D709BE236F7E3200AAB7C3 /* S9xPreferencesWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xPreferencesWindowController.h; sourceTree = ""; }; + 30D709BF236F7E3200AAB7C3 /* S9xPreferencesWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xPreferencesWindowController.m; sourceTree = ""; }; + 30D709C0236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = S9xPreferencesWindowController.xib; sourceTree = ""; }; 30D709C3236F90DF00AAB7C3 /* S9xButtonConfigTextField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = S9xButtonConfigTextField.h; sourceTree = ""; }; 30D709C4236F90DF00AAB7C3 /* S9xButtonConfigTextField.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = S9xButtonConfigTextField.m; sourceTree = ""; }; 85FEF90620DDB15B00C038E9 /* bml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bml.cpp; sourceTree = ""; usesTabs = 1; }; @@ -638,6 +635,7 @@ 30714716230E379500917F82 /* Snes9x */ = { isa = PBXGroup; children = ( + 600546BE250F8F1700EC0977 /* S9xPreferences */, 30C49EF6250C0F2B007D04F8 /* Snes9xDebug.entitlements */, 30714717230E379500917F82 /* AppDelegate.h */, 30714718230E379500917F82 /* AppDelegate.m */, @@ -646,13 +644,6 @@ 3071471F230E379600917F82 /* Info.plist */, 30714720230E379600917F82 /* main.m */, 30714722230E379600917F82 /* Snes9x.entitlements */, - 30D709BE236F7E3200AAB7C3 /* S9xPrefsViewController.h */, - 30D709BF236F7E3200AAB7C3 /* S9xPrefsViewController.m */, - 30D709C0236F7E3200AAB7C3 /* S9xPrefsViewController.xib */, - 30D709C3236F90DF00AAB7C3 /* S9xButtonConfigTextField.h */, - 30D709C4236F90DF00AAB7C3 /* S9xButtonConfigTextField.m */, - 30D2506D2373AACC0076A160 /* S9xPrefsConstants.m */, - 30D2506F2373AB880076A160 /* S9xPrefsConstants.h */, 3082C4282379199F0081CA7C /* S9xApplication.h */, 3082C4292379199F0081CA7C /* S9xApplication.m */, ); @@ -681,6 +672,18 @@ path = "snes9x framework"; sourceTree = ""; }; + 600546BE250F8F1700EC0977 /* S9xPreferences */ = { + isa = PBXGroup; + children = ( + 30D709C3236F90DF00AAB7C3 /* S9xButtonConfigTextField.h */, + 30D709C4236F90DF00AAB7C3 /* S9xButtonConfigTextField.m */, + 30D709BE236F7E3200AAB7C3 /* S9xPreferencesWindowController.h */, + 30D709BF236F7E3200AAB7C3 /* S9xPreferencesWindowController.m */, + 30D709C0236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib */, + ); + path = S9xPreferences; + sourceTree = ""; + }; BF0B39791FA5792F002B04D3 /* apu */ = { isa = PBXGroup; children = ( @@ -1179,7 +1182,7 @@ 30D709B2236F731B00AAB7C3 /* CART.icns in Resources */, 30D709B7236F731B00AAB7C3 /* musicbox_ledon.icns in Resources */, 30D709B6236F731B00AAB7C3 /* folder_Freezes.icns in Resources */, - 30D709C2236F7E3200AAB7C3 /* S9xPrefsViewController.xib in Resources */, + 30D709C2236F7E3200AAB7C3 /* S9xPreferencesWindowController.xib in Resources */, 3071471E230E379600917F82 /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1206,8 +1209,7 @@ 30714721230E379600917F82 /* main.m in Sources */, 30714719230E379500917F82 /* AppDelegate.m in Sources */, 3082C42A2379199F0081CA7C /* S9xApplication.m in Sources */, - 30D709C1236F7E3200AAB7C3 /* S9xPrefsViewController.m in Sources */, - 30D2506E2373AACC0076A160 /* S9xPrefsConstants.m in Sources */, + 30D709C1236F7E3200AAB7C3 /* S9xPreferencesWindowController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };