2016-04-13 19:43:16 +00:00
|
|
|
#import "GBPreferencesWindow.h"
|
|
|
|
#import "NSString+StringForKey.h"
|
|
|
|
#import "GBButtons.h"
|
2020-08-22 00:27:57 +00:00
|
|
|
#import "BigSurToolbar.h"
|
2017-01-24 19:00:56 +00:00
|
|
|
#import <Carbon/Carbon.h>
|
2016-04-13 19:43:16 +00:00
|
|
|
|
|
|
|
@implementation GBPreferencesWindow
|
|
|
|
{
|
|
|
|
bool is_button_being_modified;
|
|
|
|
NSInteger button_being_modified;
|
2017-12-30 14:23:17 +00:00
|
|
|
signed joystick_configuration_state;
|
|
|
|
NSString *joystick_being_configured;
|
2019-10-19 16:26:04 +00:00
|
|
|
bool joypad_wait;
|
2016-04-28 20:07:05 +00:00
|
|
|
|
|
|
|
NSPopUpButton *_graphicsFilterPopupButton;
|
2017-08-15 18:59:53 +00:00
|
|
|
NSPopUpButton *_highpassFilterPopupButton;
|
2017-10-12 14:22:22 +00:00
|
|
|
NSPopUpButton *_colorCorrectionPopupButton;
|
2020-03-26 18:54:18 +00:00
|
|
|
NSPopUpButton *_frameBlendingModePopupButton;
|
2020-01-29 12:19:11 +00:00
|
|
|
NSPopUpButton *_colorPalettePopupButton;
|
2020-02-08 11:28:46 +00:00
|
|
|
NSPopUpButton *_displayBorderPopupButton;
|
2018-02-10 12:42:14 +00:00
|
|
|
NSPopUpButton *_rewindPopupButton;
|
2016-07-05 18:23:55 +00:00
|
|
|
NSButton *_aspectRatioCheckbox;
|
2019-10-19 16:26:04 +00:00
|
|
|
NSButton *_analogControlsCheckbox;
|
2018-02-10 21:30:30 +00:00
|
|
|
NSEventModifierFlags previousModifiers;
|
2018-12-01 15:16:50 +00:00
|
|
|
|
|
|
|
NSPopUpButton *_dmgPopupButton, *_sgbPopupButton, *_cgbPopupButton;
|
2018-12-15 16:55:41 +00:00
|
|
|
NSPopUpButton *_preferredJoypadButton;
|
2020-04-29 13:50:31 +00:00
|
|
|
NSPopUpButton *_rumbleModePopupButton;
|
2016-04-28 20:07:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSArray *)filterList
|
|
|
|
{
|
|
|
|
/* The filter list as ordered in the popup button */
|
|
|
|
static NSArray * filters = nil;
|
|
|
|
if (!filters) {
|
|
|
|
filters = @[
|
|
|
|
@"NearestNeighbor",
|
|
|
|
@"Bilinear",
|
|
|
|
@"SmoothBilinear",
|
2020-01-29 13:51:53 +00:00
|
|
|
@"MonoLCD",
|
2018-02-17 18:43:48 +00:00
|
|
|
@"LCD",
|
2018-11-19 16:52:11 +00:00
|
|
|
@"CRT",
|
2016-04-28 20:07:05 +00:00
|
|
|
@"Scale2x",
|
|
|
|
@"Scale4x",
|
|
|
|
@"AAScale2x",
|
|
|
|
@"AAScale4x",
|
2016-06-14 11:11:37 +00:00
|
|
|
@"HQ2x",
|
2016-06-08 21:06:55 +00:00
|
|
|
@"OmniScale",
|
2016-06-16 22:06:52 +00:00
|
|
|
@"OmniScaleLegacy",
|
|
|
|
@"AAOmniScaleLegacy",
|
2016-04-28 20:07:05 +00:00
|
|
|
];
|
|
|
|
}
|
|
|
|
return filters;
|
|
|
|
}
|
|
|
|
|
2020-08-22 00:27:57 +00:00
|
|
|
- (NSWindowToolbarStyle)toolbarStyle
|
|
|
|
{
|
|
|
|
return NSWindowToolbarStylePreference;
|
|
|
|
}
|
|
|
|
|
2017-12-30 14:23:17 +00:00
|
|
|
- (void)close
|
|
|
|
{
|
|
|
|
joystick_configuration_state = -1;
|
|
|
|
[self.configureJoypadButton setEnabled:YES];
|
|
|
|
[self.skipButton setEnabled:NO];
|
2019-10-19 16:26:04 +00:00
|
|
|
[self.configureJoypadButton setTitle:@"Configure Controller"];
|
2017-12-30 14:23:17 +00:00
|
|
|
[super close];
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:07:05 +00:00
|
|
|
- (NSPopUpButton *)graphicsFilterPopupButton
|
|
|
|
{
|
|
|
|
return _graphicsFilterPopupButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setGraphicsFilterPopupButton:(NSPopUpButton *)graphicsFilterPopupButton
|
|
|
|
{
|
|
|
|
_graphicsFilterPopupButton = graphicsFilterPopupButton;
|
|
|
|
NSString *filter = [[NSUserDefaults standardUserDefaults] objectForKey:@"GBFilter"];
|
|
|
|
[_graphicsFilterPopupButton selectItemAtIndex:[[[self class] filterList] indexOfObject:filter]];
|
2016-04-13 19:43:16 +00:00
|
|
|
}
|
|
|
|
|
2017-08-15 18:59:53 +00:00
|
|
|
- (NSPopUpButton *)highpassFilterPopupButton
|
|
|
|
{
|
|
|
|
return _highpassFilterPopupButton;
|
|
|
|
}
|
|
|
|
|
2017-10-12 14:22:22 +00:00
|
|
|
- (void)setColorCorrectionPopupButton:(NSPopUpButton *)colorCorrectionPopupButton
|
|
|
|
{
|
|
|
|
_colorCorrectionPopupButton = colorCorrectionPopupButton;
|
|
|
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"];
|
|
|
|
[_colorCorrectionPopupButton selectItemAtIndex:mode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)colorCorrectionPopupButton
|
|
|
|
{
|
|
|
|
return _colorCorrectionPopupButton;
|
|
|
|
}
|
|
|
|
|
2020-03-26 18:54:18 +00:00
|
|
|
- (void)setFrameBlendingModePopupButton:(NSPopUpButton *)frameBlendingModePopupButton
|
|
|
|
{
|
|
|
|
_frameBlendingModePopupButton = frameBlendingModePopupButton;
|
|
|
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBFrameBlendingMode"];
|
|
|
|
[_frameBlendingModePopupButton selectItemAtIndex:mode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)frameBlendingModePopupButton
|
|
|
|
{
|
|
|
|
return _frameBlendingModePopupButton;
|
|
|
|
}
|
|
|
|
|
2020-01-29 12:19:11 +00:00
|
|
|
- (void)setColorPalettePopupButton:(NSPopUpButton *)colorPalettePopupButton
|
|
|
|
{
|
|
|
|
_colorPalettePopupButton = colorPalettePopupButton;
|
|
|
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorPalette"];
|
|
|
|
[_colorPalettePopupButton selectItemAtIndex:mode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)colorPalettePopupButton
|
|
|
|
{
|
|
|
|
return _colorPalettePopupButton;
|
|
|
|
}
|
|
|
|
|
2020-02-08 11:28:46 +00:00
|
|
|
- (void)setDisplayBorderPopupButton:(NSPopUpButton *)displayBorderPopupButton
|
|
|
|
{
|
|
|
|
_displayBorderPopupButton = displayBorderPopupButton;
|
|
|
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBBorderMode"];
|
|
|
|
[_displayBorderPopupButton selectItemWithTag:mode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)displayBorderPopupButton
|
|
|
|
{
|
|
|
|
return _displayBorderPopupButton;
|
|
|
|
}
|
|
|
|
|
2020-04-29 13:50:31 +00:00
|
|
|
- (void)setRumbleModePopupButton:(NSPopUpButton *)rumbleModePopupButton
|
|
|
|
{
|
|
|
|
_rumbleModePopupButton = rumbleModePopupButton;
|
|
|
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBRumbleMode"];
|
|
|
|
[_rumbleModePopupButton selectItemWithTag:mode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)rumbleModePopupButton
|
|
|
|
{
|
|
|
|
return _rumbleModePopupButton;
|
|
|
|
}
|
|
|
|
|
2018-02-10 12:42:14 +00:00
|
|
|
- (void)setRewindPopupButton:(NSPopUpButton *)rewindPopupButton
|
|
|
|
{
|
|
|
|
_rewindPopupButton = rewindPopupButton;
|
|
|
|
NSInteger length = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBRewindLength"];
|
|
|
|
[_rewindPopupButton selectItemWithTag:length];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)rewindPopupButton
|
|
|
|
{
|
|
|
|
return _rewindPopupButton;
|
|
|
|
}
|
|
|
|
|
2017-08-15 18:59:53 +00:00
|
|
|
- (void)setHighpassFilterPopupButton:(NSPopUpButton *)highpassFilterPopupButton
|
|
|
|
{
|
|
|
|
_highpassFilterPopupButton = highpassFilterPopupButton;
|
|
|
|
[_highpassFilterPopupButton selectItemAtIndex:[[[NSUserDefaults standardUserDefaults] objectForKey:@"GBHighpassFilter"] unsignedIntegerValue]];
|
|
|
|
}
|
|
|
|
|
2016-04-13 19:43:16 +00:00
|
|
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
|
|
|
{
|
2018-12-04 22:00:16 +00:00
|
|
|
if (self.playerListButton.selectedTag == 0) {
|
|
|
|
return GBButtonCount;
|
|
|
|
}
|
|
|
|
return GBGameBoyButtonCount;
|
2016-04-13 19:43:16 +00:00
|
|
|
}
|
|
|
|
|
2020-06-09 22:10:11 +00:00
|
|
|
- (unsigned) usesForKey:(unsigned) key
|
|
|
|
{
|
|
|
|
unsigned ret = 0;
|
|
|
|
for (unsigned player = 4; player--;) {
|
|
|
|
for (unsigned button = player == 0? GBButtonCount:GBGameBoyButtonCount; button--;) {
|
|
|
|
NSNumber *other = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(button, player)];
|
|
|
|
if (other && [other unsignedIntValue] == key) {
|
|
|
|
ret++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-04-13 19:43:16 +00:00
|
|
|
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
|
|
|
{
|
|
|
|
if ([tableColumn.identifier isEqualToString:@"keyName"]) {
|
|
|
|
return GBButtonNames[row];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_button_being_modified && button_being_modified == row) {
|
|
|
|
return @"Select a new key...";
|
|
|
|
}
|
2018-12-04 22:00:16 +00:00
|
|
|
|
|
|
|
NSNumber *key = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(row, self.playerListButton.selectedTag)];
|
|
|
|
if (key) {
|
2020-06-09 22:10:11 +00:00
|
|
|
if ([self usesForKey:[key unsignedIntValue]] > 1) {
|
|
|
|
return [[NSAttributedString alloc] initWithString:[NSString displayStringForKeyCode: [key unsignedIntegerValue]]
|
|
|
|
attributes:@{NSForegroundColorAttributeName: [NSColor colorWithRed:0.9375 green:0.25 blue:0.25 alpha:1.0],
|
|
|
|
NSFontAttributeName: [NSFont boldSystemFontOfSize:[NSFont systemFontSize]]
|
|
|
|
}];
|
|
|
|
}
|
2018-12-04 22:00:16 +00:00
|
|
|
return [NSString displayStringForKeyCode: [key unsignedIntegerValue]];
|
|
|
|
}
|
2016-04-13 19:43:16 +00:00
|
|
|
|
2018-12-04 22:00:16 +00:00
|
|
|
return @"";
|
2016-04-13 19:43:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
|
|
|
{
|
2018-12-04 22:00:16 +00:00
|
|
|
|
2016-04-13 19:43:16 +00:00
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
is_button_being_modified = true;
|
|
|
|
button_being_modified = row;
|
|
|
|
tableView.enabled = NO;
|
2018-12-04 22:00:16 +00:00
|
|
|
self.playerListButton.enabled = NO;
|
2016-04-13 19:43:16 +00:00
|
|
|
[tableView reloadData];
|
|
|
|
[self makeFirstResponder:self];
|
|
|
|
});
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
-(void)keyDown:(NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
if (!is_button_being_modified) {
|
2018-06-17 20:24:02 +00:00
|
|
|
if (self.firstResponder != self.controlsTableView && [theEvent type] != NSEventTypeFlagsChanged) {
|
2016-04-13 19:43:16 +00:00
|
|
|
[super keyDown:theEvent];
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
is_button_being_modified = false;
|
|
|
|
|
2017-01-24 19:00:56 +00:00
|
|
|
[[NSUserDefaults standardUserDefaults] setInteger:theEvent.keyCode
|
2018-12-04 22:00:16 +00:00
|
|
|
forKey:button_to_preference_name(button_being_modified, self.playerListButton.selectedTag)];
|
2016-04-13 19:43:16 +00:00
|
|
|
self.controlsTableView.enabled = YES;
|
2018-12-04 22:00:16 +00:00
|
|
|
self.playerListButton.enabled = YES;
|
2016-04-13 19:43:16 +00:00
|
|
|
[self.controlsTableView reloadData];
|
|
|
|
[self makeFirstResponder:self.controlsTableView];
|
|
|
|
}
|
2017-08-15 18:59:53 +00:00
|
|
|
|
2018-02-10 21:30:30 +00:00
|
|
|
- (void) flagsChanged:(NSEvent *)event
|
|
|
|
{
|
|
|
|
if (event.modifierFlags > previousModifiers) {
|
|
|
|
[self keyDown:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
previousModifiers = event.modifierFlags;
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:07:05 +00:00
|
|
|
- (IBAction)graphicFilterChanged:(NSPopUpButton *)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:[[self class] filterList][[sender indexOfSelectedItem]]
|
|
|
|
forKey:@"GBFilter"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBFilterChanged" object:nil];
|
|
|
|
}
|
2016-04-13 19:43:16 +00:00
|
|
|
|
2017-08-15 18:59:53 +00:00
|
|
|
- (IBAction)highpassFilterChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender indexOfSelectedItem])
|
|
|
|
forKey:@"GBHighpassFilter"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBHighpassFilterChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
- (IBAction)changeAnalogControls:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] == NSOnState
|
|
|
|
forKey:@"GBAnalogControls"];
|
|
|
|
}
|
|
|
|
|
2016-07-05 18:23:55 +00:00
|
|
|
- (IBAction)changeAspectRatio:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] != NSOnState
|
|
|
|
forKey:@"GBAspectRatioUnkept"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBAspectChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2017-10-12 14:22:22 +00:00
|
|
|
- (IBAction)colorCorrectionChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender indexOfSelectedItem])
|
|
|
|
forKey:@"GBColorCorrection"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBColorCorrectionChanged" object:nil];
|
2020-03-26 18:54:18 +00:00
|
|
|
}
|
2017-10-12 14:22:22 +00:00
|
|
|
|
2020-03-26 18:54:18 +00:00
|
|
|
- (IBAction)franeBlendingModeChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender indexOfSelectedItem])
|
|
|
|
forKey:@"GBFrameBlendingMode"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBFrameBlendingModeChanged" object:nil];
|
|
|
|
|
2017-10-12 14:22:22 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 12:19:11 +00:00
|
|
|
- (IBAction)colorPaletteChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender indexOfSelectedItem])
|
|
|
|
forKey:@"GBColorPalette"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBColorPaletteChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2020-02-08 11:28:46 +00:00
|
|
|
- (IBAction)displayBorderChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedItem].tag)
|
|
|
|
forKey:@"GBBorderMode"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBBorderModeChanged" object:nil];
|
2017-10-12 14:22:22 +00:00
|
|
|
}
|
|
|
|
|
2020-04-29 13:50:31 +00:00
|
|
|
- (IBAction)rumbleModeChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedItem].tag)
|
|
|
|
forKey:@"GBRumbleMode"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBRumbleModeChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2018-02-10 12:42:14 +00:00
|
|
|
- (IBAction)rewindLengthChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedTag])
|
|
|
|
forKey:@"GBRewindLength"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBRewindLengthChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2017-12-30 14:23:17 +00:00
|
|
|
- (IBAction) configureJoypad:(id)sender
|
|
|
|
{
|
|
|
|
[self.configureJoypadButton setEnabled:NO];
|
|
|
|
[self.skipButton setEnabled:YES];
|
|
|
|
joystick_being_configured = nil;
|
|
|
|
[self advanceConfigurationStateMachine];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction) skipButton:(id)sender
|
|
|
|
{
|
|
|
|
[self advanceConfigurationStateMachine];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) advanceConfigurationStateMachine
|
|
|
|
{
|
|
|
|
joystick_configuration_state++;
|
2019-10-19 16:26:04 +00:00
|
|
|
if (joystick_configuration_state == GBUnderclock) {
|
|
|
|
[self.configureJoypadButton setTitle:@"Press Button for Slo-Mo"]; // Full name is too long :<
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
2019-10-19 16:26:04 +00:00
|
|
|
else if (joystick_configuration_state < GBButtonCount) {
|
|
|
|
[self.configureJoypadButton setTitle:[NSString stringWithFormat:@"Press Button for %@", GBButtonNames[joystick_configuration_state]]];
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
joystick_configuration_state = -1;
|
|
|
|
[self.configureJoypadButton setEnabled:YES];
|
|
|
|
[self.skipButton setEnabled:NO];
|
|
|
|
[self.configureJoypadButton setTitle:@"Configure Joypad"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
- (void)controller:(JOYController *)controller buttonChangedState:(JOYButton *)button
|
2017-12-30 14:23:17 +00:00
|
|
|
{
|
2019-10-19 16:26:04 +00:00
|
|
|
/* Debounce */
|
|
|
|
if (joypad_wait) return;
|
|
|
|
joypad_wait = true;
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
|
joypad_wait = false;
|
|
|
|
});
|
2020-04-29 13:52:32 +00:00
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (!button.isPressed) return;
|
2017-12-30 14:23:17 +00:00
|
|
|
if (joystick_configuration_state == -1) return;
|
|
|
|
if (joystick_configuration_state == GBButtonCount) return;
|
|
|
|
if (!joystick_being_configured) {
|
2019-10-19 16:26:04 +00:00
|
|
|
joystick_being_configured = controller.uniqueID;
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
2019-10-19 16:26:04 +00:00
|
|
|
else if (![joystick_being_configured isEqualToString:controller.uniqueID]) {
|
2017-12-30 14:23:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
NSMutableDictionary *instance_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitInstanceMapping"] mutableCopy];
|
2017-12-30 14:23:17 +00:00
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
NSMutableDictionary *name_mappings = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitNameMapping"] mutableCopy];
|
2017-12-30 14:23:17 +00:00
|
|
|
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (!instance_mappings) {
|
|
|
|
instance_mappings = [[NSMutableDictionary alloc] init];
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (!name_mappings) {
|
|
|
|
name_mappings = [[NSMutableDictionary alloc] init];
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
NSMutableDictionary *mapping = nil;
|
|
|
|
if (joystick_configuration_state != 0) {
|
|
|
|
mapping = [instance_mappings[controller.uniqueID] mutableCopy];
|
2017-12-30 14:23:17 +00:00
|
|
|
}
|
2019-10-19 16:26:04 +00:00
|
|
|
else {
|
2017-12-30 14:23:17 +00:00
|
|
|
mapping = [[NSMutableDictionary alloc] init];
|
|
|
|
}
|
|
|
|
|
2019-06-14 15:06:15 +00:00
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
static const unsigned gb_to_joykit[] = {
|
|
|
|
[GBRight]=JOYButtonUsageDPadRight,
|
|
|
|
[GBLeft]=JOYButtonUsageDPadLeft,
|
|
|
|
[GBUp]=JOYButtonUsageDPadUp,
|
|
|
|
[GBDown]=JOYButtonUsageDPadDown,
|
|
|
|
[GBA]=JOYButtonUsageA,
|
|
|
|
[GBB]=JOYButtonUsageB,
|
|
|
|
[GBSelect]=JOYButtonUsageSelect,
|
|
|
|
[GBStart]=JOYButtonUsageStart,
|
|
|
|
[GBTurbo]=JOYButtonUsageL1,
|
|
|
|
[GBRewind]=JOYButtonUsageL2,
|
|
|
|
[GBUnderclock]=JOYButtonUsageR1,
|
|
|
|
};
|
2019-06-14 15:06:15 +00:00
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (joystick_configuration_state == GBUnderclock) {
|
|
|
|
for (JOYAxis *axis in controller.axes) {
|
|
|
|
if (axis.value > 0.5) {
|
|
|
|
mapping[@"AnalogUnderclock"] = @(axis.uniqueID);
|
|
|
|
}
|
|
|
|
}
|
2019-06-14 15:06:15 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (joystick_configuration_state == GBTurbo) {
|
|
|
|
for (JOYAxis *axis in controller.axes) {
|
|
|
|
if (axis.value > 0.5) {
|
|
|
|
mapping[@"AnalogTurbo"] = @(axis.uniqueID);
|
|
|
|
}
|
|
|
|
}
|
2019-06-14 15:06:15 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
mapping[n2s(button.uniqueID)] = @(gb_to_joykit[joystick_configuration_state]);
|
2019-06-14 15:06:15 +00:00
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
instance_mappings[controller.uniqueID] = mapping;
|
|
|
|
name_mappings[controller.deviceName] = mapping;
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:instance_mappings forKey:@"JoyKitInstanceMapping"];
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:name_mappings forKey:@"JoyKitNameMapping"];
|
2019-06-14 15:06:15 +00:00
|
|
|
[self advanceConfigurationStateMachine];
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
- (NSButton *)analogControlsCheckbox
|
|
|
|
{
|
|
|
|
return _analogControlsCheckbox;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setAnalogControlsCheckbox:(NSButton *)analogControlsCheckbox
|
|
|
|
{
|
|
|
|
_analogControlsCheckbox = analogControlsCheckbox;
|
|
|
|
[_analogControlsCheckbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBAnalogControls"]];
|
|
|
|
}
|
|
|
|
|
2016-07-05 18:23:55 +00:00
|
|
|
- (NSButton *)aspectRatioCheckbox
|
|
|
|
{
|
|
|
|
return _aspectRatioCheckbox;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setAspectRatioCheckbox:(NSButton *)aspectRatioCheckbox
|
|
|
|
{
|
|
|
|
_aspectRatioCheckbox = aspectRatioCheckbox;
|
|
|
|
[_aspectRatioCheckbox setState: ![[NSUserDefaults standardUserDefaults] boolForKey:@"GBAspectRatioUnkept"]];
|
|
|
|
}
|
|
|
|
|
2017-01-24 19:00:56 +00:00
|
|
|
- (void)awakeFromNib
|
|
|
|
{
|
|
|
|
[super awakeFromNib];
|
2018-06-20 21:48:02 +00:00
|
|
|
[self updateBootROMFolderButton];
|
2017-01-24 19:00:56 +00:00
|
|
|
[[NSDistributedNotificationCenter defaultCenter] addObserver:self.controlsTableView selector:@selector(reloadData) name:(NSString*)kTISNotifySelectedKeyboardInputSourceChanged object:nil];
|
2019-10-19 16:26:04 +00:00
|
|
|
[JOYController registerListener:self];
|
|
|
|
joystick_configuration_state = -1;
|
2017-01-24 19:00:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
2019-10-19 16:26:04 +00:00
|
|
|
[JOYController unregisterListener:self];
|
2017-01-24 19:00:56 +00:00
|
|
|
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self.controlsTableView];
|
|
|
|
}
|
|
|
|
|
2018-06-20 21:48:02 +00:00
|
|
|
- (IBAction)selectOtherBootROMFolder:(id)sender
|
|
|
|
{
|
|
|
|
NSOpenPanel *panel = [[NSOpenPanel alloc] init];
|
|
|
|
[panel setCanChooseDirectories:YES];
|
|
|
|
[panel setCanChooseFiles:NO];
|
|
|
|
[panel setPrompt:@"Select"];
|
|
|
|
[panel setDirectoryURL:[[NSUserDefaults standardUserDefaults] URLForKey:@"GBBootROMsFolder"]];
|
|
|
|
[panel beginSheetModalForWindow:self completionHandler:^(NSModalResponse result) {
|
|
|
|
if (result == NSModalResponseOK) {
|
|
|
|
NSURL *url = [[panel URLs] firstObject];
|
|
|
|
[[NSUserDefaults standardUserDefaults] setURL:url forKey:@"GBBootROMsFolder"];
|
|
|
|
}
|
|
|
|
[self updateBootROMFolderButton];
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) updateBootROMFolderButton
|
|
|
|
{
|
|
|
|
NSURL *url = [[NSUserDefaults standardUserDefaults] URLForKey:@"GBBootROMsFolder"];
|
|
|
|
BOOL is_dir = false;
|
|
|
|
[[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&is_dir];
|
|
|
|
if (!is_dir) url = nil;
|
|
|
|
|
|
|
|
if (url) {
|
|
|
|
[self.bootROMsFolderItem setTitle:[url lastPathComponent]];
|
|
|
|
NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[url path]];
|
|
|
|
[icon setSize:NSMakeSize(16, 16)];
|
|
|
|
[self.bootROMsFolderItem setHidden:NO];
|
|
|
|
[self.bootROMsFolderItem setImage:icon];
|
|
|
|
[self.bootROMsButton selectItemAtIndex:1];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
[self.bootROMsFolderItem setHidden:YES];
|
|
|
|
[self.bootROMsButton selectItemAtIndex:0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)useBuiltinBootROMs:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setURL:nil forKey:@"GBBootROMsFolder"];
|
|
|
|
[self updateBootROMFolderButton];
|
|
|
|
}
|
|
|
|
|
2018-12-01 15:16:50 +00:00
|
|
|
- (void)setDmgPopupButton:(NSPopUpButton *)dmgPopupButton
|
|
|
|
{
|
|
|
|
_dmgPopupButton = dmgPopupButton;
|
|
|
|
[_dmgPopupButton selectItemWithTag:[[NSUserDefaults standardUserDefaults] integerForKey:@"GBDMGModel"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)dmgPopupButton
|
|
|
|
{
|
|
|
|
return _dmgPopupButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setSgbPopupButton:(NSPopUpButton *)sgbPopupButton
|
|
|
|
{
|
|
|
|
_sgbPopupButton = sgbPopupButton;
|
|
|
|
[_sgbPopupButton selectItemWithTag:[[NSUserDefaults standardUserDefaults] integerForKey:@"GBSGBModel"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)sgbPopupButton
|
|
|
|
{
|
|
|
|
return _sgbPopupButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setCgbPopupButton:(NSPopUpButton *)cgbPopupButton
|
|
|
|
{
|
|
|
|
_cgbPopupButton = cgbPopupButton;
|
|
|
|
[_cgbPopupButton selectItemWithTag:[[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)cgbPopupButton
|
|
|
|
{
|
|
|
|
return _cgbPopupButton;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)dmgModelChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedTag])
|
|
|
|
forKey:@"GBDMGModel"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBDMGModelChanged" object:nil];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)sgbModelChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedTag])
|
|
|
|
forKey:@"GBSGBModel"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBSGBModelChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)cgbModelChanged:(id)sender
|
|
|
|
{
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedTag])
|
|
|
|
forKey:@"GBCGBModel"];
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBCGBModelChanged" object:nil];
|
|
|
|
}
|
|
|
|
|
2018-12-04 22:00:16 +00:00
|
|
|
- (IBAction)reloadButtonsData:(id)sender
|
|
|
|
{
|
|
|
|
[self.controlsTableView reloadData];
|
|
|
|
}
|
|
|
|
|
2018-12-15 16:55:41 +00:00
|
|
|
- (void)setPreferredJoypadButton:(NSPopUpButton *)preferredJoypadButton
|
|
|
|
{
|
|
|
|
_preferredJoypadButton = preferredJoypadButton;
|
|
|
|
[self refreshJoypadMenu:nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPopUpButton *)preferredJoypadButton
|
|
|
|
{
|
|
|
|
return _preferredJoypadButton;
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
- (void)controllerConnected:(JOYController *)controller
|
|
|
|
{
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
|
[self refreshJoypadMenu:nil];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)controllerDisconnected:(JOYController *)controller
|
|
|
|
{
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
|
[self refreshJoypadMenu:nil];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-12-15 16:55:41 +00:00
|
|
|
- (IBAction)refreshJoypadMenu:(id)sender
|
|
|
|
{
|
2019-10-19 16:26:04 +00:00
|
|
|
bool preferred_is_connected = false;
|
|
|
|
NSString *player_string = n2s(self.playerListButton.selectedTag);
|
|
|
|
NSString *selected_controller = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitDefaultControllers"][player_string];
|
|
|
|
|
|
|
|
[self.preferredJoypadButton removeAllItems];
|
|
|
|
[self.preferredJoypadButton addItemWithTitle:@"None"];
|
|
|
|
for (JOYController *controller in [JOYController allControllers]) {
|
|
|
|
[self.preferredJoypadButton addItemWithTitle:[NSString stringWithFormat:@"%@ (%@)", controller.deviceName, controller.uniqueID]];
|
|
|
|
|
|
|
|
self.preferredJoypadButton.lastItem.identifier = controller.uniqueID;
|
|
|
|
|
|
|
|
if ([controller.uniqueID isEqualToString:selected_controller]) {
|
|
|
|
preferred_is_connected = true;
|
|
|
|
[self.preferredJoypadButton selectItem:self.preferredJoypadButton.lastItem];
|
2018-12-15 16:55:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
if (!preferred_is_connected && selected_controller) {
|
|
|
|
[self.preferredJoypadButton addItemWithTitle:[NSString stringWithFormat:@"Unavailable Controller (%@)", selected_controller]];
|
|
|
|
self.preferredJoypadButton.lastItem.identifier = selected_controller;
|
|
|
|
[self.preferredJoypadButton selectItem:self.preferredJoypadButton.lastItem];
|
2018-12-15 16:55:41 +00:00
|
|
|
}
|
2019-10-19 16:26:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (!selected_controller) {
|
2018-12-15 16:55:41 +00:00
|
|
|
[self.preferredJoypadButton selectItemWithTitle:@"None"];
|
|
|
|
}
|
|
|
|
[self.controlsTableView reloadData];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)changeDefaultJoypad:(id)sender
|
|
|
|
{
|
2019-10-19 16:26:04 +00:00
|
|
|
NSMutableDictionary *default_joypads = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitDefaultControllers"] mutableCopy];
|
2018-12-15 16:55:41 +00:00
|
|
|
if (!default_joypads) {
|
|
|
|
default_joypads = [[NSMutableDictionary alloc] init];
|
|
|
|
}
|
|
|
|
|
2019-10-19 16:26:04 +00:00
|
|
|
NSString *player_string = n2s(self.playerListButton.selectedTag);
|
2018-12-15 16:55:41 +00:00
|
|
|
if ([[sender titleOfSelectedItem] isEqualToString:@"None"]) {
|
|
|
|
[default_joypads removeObjectForKey:player_string];
|
|
|
|
}
|
|
|
|
else {
|
2019-10-19 16:26:04 +00:00
|
|
|
default_joypads[player_string] = [[sender selectedItem] identifier];
|
2018-12-15 16:55:41 +00:00
|
|
|
}
|
2019-10-19 16:26:04 +00:00
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:default_joypads forKey:@"JoyKitDefaultControllers"];
|
2018-12-15 16:55:41 +00:00
|
|
|
}
|
2016-04-13 19:43:16 +00:00
|
|
|
@end
|