From f7c6625d67f8a8cbb2999aaf4d4b31fa5d874015 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Mon, 28 Dec 2020 21:13:01 -0800 Subject: [PATCH] Mac: Restore Mouse, SuperScope and Justifier support --- macosx/Snes9x/AppDelegate.h | 1 + macosx/Snes9x/AppDelegate.m | 22 ++ macosx/Snes9x/Base.lproj/MainMenu.xib | 59 +++ .../S9xPreferencesWindowController.m | 113 +++--- macosx/Snes9x/S9xPrefsConstants.m | 28 ++ macosx/Snes9x/Snes9xDebug.entitlements | 5 +- macosx/mac-controls.h | 1 + macosx/mac-controls.mm | 11 +- macosx/mac-joypad.mm | 2 +- macosx/mac-os.h | 21 +- macosx/mac-os.mm | 336 ++++++++++++------ macosx/snes9x.xcodeproj/project.pbxproj | 4 +- 12 files changed, 421 insertions(+), 182 deletions(-) create mode 100644 macosx/Snes9x/S9xPrefsConstants.m diff --git a/macosx/Snes9x/AppDelegate.h b/macosx/Snes9x/AppDelegate.h index b3b872bd..02784c2a 100644 --- a/macosx/Snes9x/AppDelegate.h +++ b/macosx/Snes9x/AppDelegate.h @@ -31,6 +31,7 @@ extern NSWindowFrameAutosaveName const kMainWindowIdentifier; @property (nonatomic, strong) NSMutableDictionary *keys; @property (nonatomic, strong) NSWindow *gameWindow; @property (nonatomic, strong) S9xPreferencesWindowController *preferencesWindowController; +@property (nonatomic, readonly, assign) S9xDeviceSetting deviceSetting; - (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 53be4ace..869784a9 100644 --- a/macosx/Snes9x/AppDelegate.m +++ b/macosx/Snes9x/AppDelegate.m @@ -179,6 +179,8 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; } } + self.deviceSetting = Gamepads; + [self importKeySettings]; [self importGraphicsSettings]; [defaults synchronize]; @@ -465,6 +467,9 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; if (action == @selector(resume:) || action == @selector(softwareReset:) || action == @selector(hardwareReset:)) { return [self.s9xEngine isRunning] && [self.s9xEngine isPaused]; } + else if (action == @selector(updateDeviceSetting:)) { + menuItem.state = (self.deviceSetting == (S9xDeviceSetting)menuItem.tag) ? NSOnState : NSOffState; + } return !self.isRunningEmulation; } @@ -529,6 +534,17 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; [self.s9xEngine hardwareReset]; } +- (IBAction)updateDeviceSetting:(id)sender +{ + self.deviceSetting = (S9xDeviceSetting)[sender tag]; +} + +- (void)setDeviceSetting:(S9xDeviceSetting)deviceSetting +{ + _deviceSetting = deviceSetting; + [self.s9xEngine setDeviceSetting:deviceSetting]; +} + - (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad { if (NSApp.keyWindow != nil && NSApp.keyWindow == self.preferencesWindowController.window) @@ -539,4 +555,10 @@ NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow"; return NO; } +- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting +{ + _deviceSetting = deviceSetting; +} + + @end diff --git a/macosx/Snes9x/Base.lproj/MainMenu.xib b/macosx/Snes9x/Base.lproj/MainMenu.xib index 9b36323f..25ecce20 100644 --- a/macosx/Snes9x/Base.lproj/MainMenu.xib +++ b/macosx/Snes9x/Base.lproj/MainMenu.xib @@ -115,6 +115,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -171,5 +227,8 @@ + + + diff --git a/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m index ed27397c..cc4724af 100644 --- a/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m +++ b/macosx/Snes9x/S9xPreferences/S9xPreferencesWindowController.m @@ -236,68 +236,70 @@ NSString * const kMacFrameSkipPref = @"FrameSkip"; return NO; } +- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting {} + - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)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 ([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]; - } + if (keyCode != (CGKeyCode)-1) + { + [((AppDelegate *) NSApp.delegate) setButtonCode:buttonCode forKeyCode:keyCode player:player]; + } + else + { + [((AppDelegate *) NSApp.delegate) clearButton:buttonCode forPlayer:player]; + } - [NSUserDefaults.standardUserDefaults synchronize]; + [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; + [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 ([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]; - } - } + 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]; - } + [NSUserDefaults.standardUserDefaults synchronize]; + [self refresh]; + } } - (void)setShowFPS:(BOOL)value { - AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; - [appDelegate setShowFPS:value]; + AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; + [appDelegate setShowFPS:value]; } - (void)setVideoMode:(int)value { - AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; - [appDelegate setVideoMode:value]; + AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; + [appDelegate setVideoMode:value]; } - (void)setMacFrameSkip:(int)value { - AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; + AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate; [appDelegate setMacFrameSkip:value]; } @@ -313,14 +315,14 @@ NSString * const kMacFrameSkipPref = @"FrameSkip"; - (IBAction)onSelectVideoMode:(NSPopUpButton *)sender { - [self setVideoMode:(int)sender.selectedTag]; + [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; @@ -328,7 +330,7 @@ NSString * const kMacFrameSkipPref = @"FrameSkip"; if (nextValue > 200) { nextValue = 200; } - + [self.macFrameSkipTextField setIntValue: nextValue]; [sender setIntValue:0]; // reset stepper value [self setMacFrameSkip:self.macFrameSkipTextField.intValue]; // execute setter @@ -358,19 +360,20 @@ NSString * const kMacFrameSkipPref = @"FrameSkip"; - (IBAction)onChangePlayerDropdown:(NSPopUpButton *)sender { - [self selectDeviceForPlayer:sender.selectedTag]; - [self refresh]; + [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]; + 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/S9xPrefsConstants.m b/macosx/Snes9x/S9xPrefsConstants.m new file mode 100644 index 00000000..770e8123 --- /dev/null +++ b/macosx/Snes9x/S9xPrefsConstants.m @@ -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 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 kDeviceSettingPref = @"DeviceSetting"; diff --git a/macosx/Snes9x/Snes9xDebug.entitlements b/macosx/Snes9x/Snes9xDebug.entitlements index 8cc185af..0c67376e 100644 --- a/macosx/Snes9x/Snes9xDebug.entitlements +++ b/macosx/Snes9x/Snes9xDebug.entitlements @@ -1,8 +1,5 @@ - - com.apple.security.cs.disable-library-validation - - + diff --git a/macosx/mac-controls.h b/macosx/mac-controls.h index aab48d3f..c29751c1 100644 --- a/macosx/mac-controls.h +++ b/macosx/mac-controls.h @@ -177,6 +177,7 @@ enum kMacCMapMouse2Pointer = k_HD | k_PT | k_MO | k_C2, kMacCMapSuperscopePointer = k_HD | k_PT | k_SS | k_C1, kMacCMapJustifier1Pointer = k_HD | k_PT | k_LG | k_C1, + kMacCMapJustifier2Pointer = k_HD | k_PT | k_LG | k_C2, kMacCMapPseudoPtrBase = k_HD | k_PS | k_LG | k_C2 // for Justifier 2P }; diff --git a/macosx/mac-controls.mm b/macosx/mac-controls.mm index fc011260..fd5570d0 100644 --- a/macosx/mac-controls.mm +++ b/macosx/mac-controls.mm @@ -163,8 +163,9 @@ void S9xSetupDefaultKeymap (void) ASSIGN_POINTRt(kMacCMapMouse2Pointer, "Pointer Mouse2"); ASSIGN_POINTRt(kMacCMapSuperscopePointer, "Pointer Superscope"); ASSIGN_POINTRt(kMacCMapJustifier1Pointer, "Pointer Justifier1"); + ASSIGN_POINTRt(kMacCMapJustifier2Pointer, "Pointer Justifier2"); - ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2"); + ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2 (Controller)"); ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 0, "ButtonToPointer 1u Med"); ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 1, "ButtonToPointer 1d Med"); ASSIGN_BUTTONf(kMacCMapPseudoPtrBase + 2, "ButtonToPointer 1l Med"); @@ -232,13 +233,13 @@ bool S9xPollPointer (uint32 id, int16 *x, int16 *y) { if (id & k_PT) { - if ((id & k_MO) && fullscreen) - GetGameScreenPointer(x, y, true); - else - GetGameScreenPointer(x, y, false); + *x = (int16) mouseX; + *y = (int16) mouseY; } else + { *x = *y = 0; + } return (true); } diff --git a/macosx/mac-joypad.mm b/macosx/mac-joypad.mm index 78f4a5e8..111b8e4e 100755 --- a/macosx/mac-joypad.mm +++ b/macosx/mac-joypad.mm @@ -718,7 +718,7 @@ void SetUpHID (void) NSNumber *usagePage = (NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey)); NSNumber *usage = (NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsageKey)); - return usagePage.intValue != kHIDPage_GenericDesktop || (usage.intValue != kHIDUsage_GD_GamePad && usage.intValue != kHIDUsage_GD_Joystick); + return usagePage.intValue != kHIDPage_GenericDesktop || (usage.intValue != kHIDUsage_GD_GamePad && usage.intValue != kHIDUsage_GD_Joystick && usage.intValue != kHIDUsage_GD_Mouse); }]]; [orderedDevices sortUsingComparator:^NSComparisonResult(id a, id b) diff --git a/macosx/mac-os.h b/macosx/mac-os.h index f7106456..8c84ba81 100644 --- a/macosx/mac-os.h +++ b/macosx/mac-os.h @@ -65,6 +65,17 @@ enum VIDEOMODE_NTSC_TV_M }; +typedef enum S9xMacDeviceSettings { + Gamepads = 1, + Mouse = 2, + Mouse2 = 3, + SuperScope = 4, + MultiTap = 5, + DoubleMultiTap = 6, + Justifier1 = 7, + Justifier2 = 8, +} S9xDeviceSetting; + typedef struct { long long nextTime[12]; @@ -84,6 +95,8 @@ extern uint32 controlPad[MAC_MAX_PLAYERS]; extern uint8 romDetect, interleaveDetect, videoDetect, headerDetect; extern WindowRef gWindow; extern uint32 glScreenW, glScreenH; +extern CGFloat rawMouseX, rawMouseY; +extern int16 mouseX, mouseY; extern CGRect glScreenBounds; extern CGImageRef macIconImage[118]; extern int macPadIconIndex, macLegendIconIndex, macMusicBoxIconIndex, macFunctionIconIndex; @@ -92,7 +105,7 @@ extern int32 skipFrames; extern int64 lastFrame; extern unsigned long spcFileCount, pngFileCount; extern bool8 finished, cartOpen, autofire; -extern bool8 fullscreen, autoRes, glstretch, gl32bit, vsync, drawoverscan, lastoverscan; +extern bool8 autoRes, glstretch, gl32bit, vsync, drawoverscan, lastoverscan; extern long drawingMethod; extern int videoMode; extern SInt32 macSoundVolume; @@ -109,7 +122,7 @@ extern uint16 macRecordFlag, macPlayFlag, macQTMovFlag; extern bool8 startopendlog, showtimeinfrz, enabletoggle, savewindowpos, onscreeninfo; extern int musicboxmode; extern bool8 applycheat; -extern int padSetting, deviceSetting, deviceSettingMaster; +extern S9xDeviceSetting deviceSetting, deviceSettingMaster; extern int macControllerOption; extern CGPoint unlimitedCursor; extern char npServerIP[256], npName[256]; @@ -134,7 +147,6 @@ void UpdateMenuCommandStatus (Boolean); void ApplyNSRTHeaderControllers (void); void QuitWithFatalError (NSString *); void ChangeInputDevice (void); -void GetGameScreenPointer (int16 *, int16 *, bool); void PostQueueToSubEventLoop (void); int PromptFreezeDefrost (Boolean); uint64 GetMicroseconds(void); @@ -156,6 +168,7 @@ void CopyPressedKeys(uint8 keys[MAC_MAX_PLAYERS][kNumButtons], uint8 gamepadButt @protocol S9xInputDelegate - (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad; +- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting; @end extern id inputDelegate; @@ -195,6 +208,8 @@ extern id inputDelegate; - (void)setMacFrameSkip:(int)_macFrameSkip; - (void)setShowFPS:(BOOL)showFPS; +- (void)setDeviceSetting:(S9xDeviceSetting)_deviceSetting; + @end #endif diff --git a/macosx/mac-os.mm b/macosx/mac-os.mm index 5c8e3531..a4d8771a 100644 --- a/macosx/mac-os.mm +++ b/macosx/mac-os.mm @@ -83,6 +83,9 @@ uint32 glScreenW, glScreenH; CGRect glScreenBounds; +CGFloat rawMouseX, rawMouseY = 0; +int16 mouseX, mouseY = 0; + CGImageRef macIconImage[118]; int macPadIconIndex, macLegendIconIndex, @@ -105,8 +108,7 @@ unsigned long spcFileCount = 0, bool8 cartOpen = false, autofire = false; -bool8 fullscreen = false, - autoRes = false, +bool8 autoRes = false, glstretch = true, gl32bit = true, vsync = true, @@ -134,9 +136,8 @@ int inactiveMode = 2; int musicboxmode = kMBXSoundEmulation; bool8 applycheat = false; -int padSetting = 1, - deviceSetting = 1, - deviceSettingMaster = 1; +S9xDeviceSetting deviceSetting = Gamepads, + deviceSettingMaster = Gamepads; int macControllerOption = SNES_JOYPAD; AutoFireState autofireRec[MAC_MAX_PLAYERS]; @@ -272,14 +273,6 @@ enum mPresets = 201, mDevice = 202, - iPad = 1, - iMouse = 2, - iMouse2 = 3, - iSuperScope = 4, - iMultiPlayer5 = 5, - iMultiPlayer5_2 = 6, - iJustifier1 = 7, - iJustifier2 = 8, mRecentItem = 203 }; @@ -296,7 +289,8 @@ static volatile bool8 rejectinput = false; static bool8 pauseEmulation = false, escKeyDown = false, - frameAdvance = false; + frameAdvance = false, + useMouse = false; static int frameCount = 0; @@ -304,8 +298,6 @@ static bool8 frzselecting = false; static uint16 changeAuto[2] = { 0x0000, 0x0000 }; -static GameViewInfo scopeViewInfo; - static void Initialize (void); static void Deinitialize (void); static void InitAutofire (void); @@ -1533,54 +1525,64 @@ void ChangeInputDevice (void) { switch (deviceSetting) { - case iPad: + case Gamepads: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0); macControllerOption = SNES_JOYPAD; + useMouse = false; break; - case iMouse: + case Mouse: S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0); S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0); macControllerOption = SNES_MOUSE; + useMouse = true; break; - case iMouse2: + case Mouse2: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0); macControllerOption = SNES_MOUSE_SWAPPED; + useMouse = true; break; - case iSuperScope: + case SuperScope: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0); macControllerOption = SNES_SUPERSCOPE; + useMouse = true; break; - case iMultiPlayer5: + case MultiTap: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_MP5, 1, 2, 3, 4); macControllerOption = SNES_MULTIPLAYER5; + useMouse = false; break; - case iMultiPlayer5_2: + case DoubleMultiTap: S9xSetController(0, CTL_MP5, 0, 1, 2, 3); S9xSetController(1, CTL_MP5, 4, 5, 6, 7); macControllerOption = SNES_MULTIPLAYER5_2; + useMouse = false; break; - case iJustifier1: + case Justifier1: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0); macControllerOption = SNES_JUSTIFIER; + useMouse = true; break; - case iJustifier2: + case Justifier2: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0); macControllerOption = SNES_JUSTIFIER_2; + useMouse = true; break; } + + [inputDelegate deviceSettingChanged:deviceSetting]; } void ApplyNSRTHeaderControllers (void) @@ -1593,68 +1595,68 @@ void ApplyNSRTHeaderControllers (void) switch (Memory.NSRTHeader[29]) { case 0x00: // Everything goes - deviceSetting = iPad; - valid = (1 << iPad); + deviceSetting = Gamepads; + valid = (1 << Gamepads); break; case 0x10: // Mouse in Port 0 - deviceSetting = iMouse; - valid = (1 << iMouse); + deviceSetting = Mouse; + valid = (1 << Mouse); break; case 0x01: // Mouse in Port 1 - deviceSetting = iMouse2; - valid = (1 << iMouse2); + deviceSetting = Mouse2; + valid = (1 << Mouse2); break; case 0x03: // Super Scope in Port 1 - deviceSetting = iSuperScope; - valid = (1 << iSuperScope); + deviceSetting = SuperScope; + valid = (1 << SuperScope); break; case 0x06: // Multitap in Port 1 - deviceSetting = iMultiPlayer5; - valid = (1 << iPad) | (1 << iMultiPlayer5); + deviceSetting = MultiTap; + valid = (1 << Gamepads) | (1 << MultiTap); break; case 0x66: // Multitap in Ports 0 and 1 - deviceSetting = iMultiPlayer5_2; - valid = (1 << iPad) | (1 << iMultiPlayer5) | (1 << iMultiPlayer5_2); + deviceSetting = DoubleMultiTap; + valid = (1 << Gamepads) | (1 << MultiTap) | (1 << DoubleMultiTap); break; case 0x08: // Multitap in Port 1, Mouse in new Port 1 - deviceSetting = iMouse2; - valid = (1 << iPad) | (1 << iMouse2) | (1 << iMultiPlayer5); + deviceSetting = Mouse; + valid = (1 << Gamepads) | (1 << Mouse2) | (1 << MultiTap); break; case 0x04: // Pad or Super Scope in Port 1 - deviceSetting = iSuperScope; - valid = (1 << iPad) | (1 << iSuperScope); + deviceSetting = SuperScope; + valid = (1 << Gamepads) | (1 << SuperScope); break; case 0x05: // Justifier - Must ask user... - deviceSetting = iJustifier1; - valid = (1 << iJustifier1) | (1 << iJustifier2); + deviceSetting = Justifier1; + valid = (1 << Justifier1) | (1 << Justifier2); break; case 0x20: // Pad or Mouse in Port 0 - deviceSetting = iMouse; - valid = (1 << iPad) | (1 << iMouse); + deviceSetting = Mouse; + valid = (1 << Gamepads) | (1 << Mouse); break; case 0x22: // Pad or Mouse in Port 0 & 1 - deviceSetting = iMouse; - valid = (1 << iPad) | (1 << iMouse) | (1 << iMouse2); + deviceSetting = Mouse; + valid = (1 << Gamepads) | (1 << Mouse) | (1 << Mouse2); break; case 0x24: // Pad or Mouse in Port 0, Pad or Super Scope in Port 1 - deviceSetting = iSuperScope; - valid = (1 << iPad) | (1 << iMouse) | (1 << iSuperScope); + deviceSetting = SuperScope; + valid = (1 << Gamepads) | (1 << Mouse) | (1 << SuperScope); break; case 0x27: // Pad or Mouse in Port 0, Pad or Mouse or Super Scope in Port 1 - deviceSetting = iSuperScope; - valid = (1 << iPad) | (1 << iMouse) | (1 << iMouse2) | (1 << iSuperScope); + deviceSetting = SuperScope; + valid = (1 << Gamepads) | (1 << Mouse) | (1 << Mouse2) | (1 << SuperScope); break; case 0x99: // Lasabirdie @@ -2442,7 +2444,9 @@ static void ProcessInput (void) } if (macControllerOption == SNES_JUSTIFIER_2) + { ControlPadFlagsToS9xPseudoPointer(controlPad[1]); + } } static void ChangeAutofireSettings (int player, int btn) @@ -2491,66 +2495,6 @@ static void ChangeTurboRate (int d) S9xSetInfoString(msg); } -void GetGameScreenPointer (int16 *x, int16 *y, bool fullmouse) -{ - int ph; - - ph = !drawoverscan ? ((IPPU.RenderedScreenHeight > 256) ? IPPU.RenderedScreenHeight : (IPPU.RenderedScreenHeight << 1)) : (SNES_HEIGHT_EXTENDED << 1); - - if (fullscreen) - { - if (glstretch) - { - float fpw = (float) glScreenH / (float) ph * 512.0f; - - scopeViewInfo.width = (int) (fpw + ((float) glScreenW - fpw) * (float) macAspectRatio / 10000.0); - scopeViewInfo.height = glScreenH; - scopeViewInfo.globalLeft = (int) glScreenBounds.origin.x + ((glScreenW - scopeViewInfo.width) >> 1); - scopeViewInfo.globalTop = (int) glScreenBounds.origin.y; - } - else - { - scopeViewInfo.width = 512; - scopeViewInfo.height = ph; - scopeViewInfo.globalLeft = (int) glScreenBounds.origin.x + ((glScreenW - 512) >> 1); - scopeViewInfo.globalTop = (int) glScreenBounds.origin.y + ((glScreenH - ph ) >> 1); - } - } - else - { - CGRect frame = s9xView.frame; - frame = [s9xView convertRect:frame toView:nil]; - frame = [s9xView.window convertRectToScreen:frame]; - - scopeViewInfo.width = frame.size.width; - scopeViewInfo.globalLeft = frame.origin.x; - - if (windowExtend) - { - scopeViewInfo.height = ph * frame.size.height / kMacWindowHeight; - scopeViewInfo.globalTop = frame.origin.y + ((kMacWindowHeight - ph) >> 1) * frame.size.height / kMacWindowHeight; - } - else - { - scopeViewInfo.height = frame.size.height; - scopeViewInfo.globalTop = frame.origin.y; - } - } - - if (!fullmouse) - { - CGPoint point = [NSEvent mouseLocation]; - - *x = (int16) (((float) (point.x - scopeViewInfo.globalLeft)) / ((float) scopeViewInfo.width ) * (float) IPPU.RenderedScreenWidth); - *y = (int16) (((float) (point.y - scopeViewInfo.globalTop )) / ((float) scopeViewInfo.height) * (float) (!drawoverscan ? IPPU.RenderedScreenHeight : SNES_HEIGHT_EXTENDED)); - } - else - { - *x = (int16) (unlimitedCursor.x / (float) scopeViewInfo.width * (float) IPPU.RenderedScreenWidth); - *y = (int16) (unlimitedCursor.y / (float) scopeViewInfo.height * (float) (!drawoverscan ? IPPU.RenderedScreenHeight : SNES_HEIGHT_EXTENDED)); - } -} - static void Initialize (void) { bzero(&Settings, sizeof(Settings)); @@ -2644,6 +2588,8 @@ static void Deinitialize (void) S9xGraphicsDeinit(); S9xDeinitAPU(); Memory.Deinit(); + + pthread_mutex_destroy(&keyLock); } uint64 GetMicroseconds(void) @@ -2846,6 +2792,11 @@ void QuitWithFatalError ( NSString *message) return self; } +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + newWindow.acceptsMouseMovedEvents = YES; +} + - (void)keyDown:(NSEvent *)event { if (!NSApp.isActive) @@ -2943,8 +2894,145 @@ void QuitWithFatalError ( NSString *message) - (void)mouseDown:(NSEvent *)event { - pauseEmulation = true; - [s9xView updatePauseOverlay]; + if ( useMouse ) + { + switch (deviceSetting) + { + case Mouse: + case SuperScope: + case Justifier1: + pressedKeys[0][kKeyMouseLeft] = true; + break; + + case Mouse2: + case Justifier2: + pressedKeys[1][kKeyMouseLeft] = true; + break; + + default: + break; + } + } + else + { + pauseEmulation = true; + [s9xView updatePauseOverlay]; + } +} + +- (void)mouseUp:(NSEvent *)event +{ + if ( useMouse ) + { + switch (deviceSetting) + { + case Mouse: + case SuperScope: + case Justifier1: + pressedKeys[0][kKeyMouseLeft] = false; + break; + + case Mouse2: + case Justifier2: + pressedKeys[1][kKeyMouseLeft] = false; + break; + + default: + break; + } + } +} + +- (void)rightMouseDown:(NSEvent *)event +{ + if ( useMouse ) + { + switch (deviceSetting) + { + case Mouse: + case SuperScope: + case Justifier1: + pressedKeys[0][kKeyMouseRight] = true; + break; + + case Mouse2: + case Justifier2: + pressedKeys[1][kKeyMouseRight] = true; + break; + + default: + break; + } + } +} + +- (void)rightMouseUp:(NSEvent *)event +{ + if ( useMouse ) + { + switch (deviceSetting) + { + case Mouse: + case SuperScope: + case Justifier1: + pressedKeys[0][kKeyMouseRight] = false; + break; + + case Mouse2: + case Justifier2: + pressedKeys[1][kKeyMouseRight] = false; + break; + + default: + break; + } + } +} + +- (void)mouseMoved:(NSEvent *)event +{ + if ( useMouse && running && !pauseEmulation ) + { + rawMouseX += event.deltaX; + rawMouseY += event.deltaY; + CGRect bounds = self.bounds; + + if (rawMouseX < 0) + { + rawMouseX = 0; + } + else if (rawMouseX > bounds.size.width) + { + rawMouseX = bounds.size.width; + } + + if (rawMouseY < 0) + { + rawMouseY = 0; + } + else if ( rawMouseY > bounds.size.height) + { + rawMouseY = bounds.size.height; + } + + mouseX = (int16) (rawMouseX / ((float) bounds.size.width ) * (float) IPPU.RenderedScreenWidth); + mouseY = (int16) (rawMouseY / ((float) bounds.size.height) * (float) IPPU.RenderedScreenHeight); + } +} + +- (void)mouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + [self mouseMoved:event]; } - (void)updatePauseOverlay @@ -2954,6 +3042,24 @@ void QuitWithFatalError ( NSString *message) CGFloat scaleFactor = MAX(self.window.backingScaleFactor, 1.0); glScreenW = self.frame.size.width * scaleFactor; glScreenH = self.frame.size.height * scaleFactor; + + BOOL showMouse = !useMouse || !running || pauseEmulation; + CGAssociateMouseAndMouseCursorPosition(showMouse); + + if (showMouse) + { + [NSCursor unhide]; + } + else + { + CGRect frame = self.frame; + CGPoint point = CGPointMake(frame.size.width / 2.0, frame.size.height / 2.0); + point = [self convertPoint:point toView:nil]; + point = [self.window convertPointToScreen:point]; + point.y = self.window.screen.frame.size.height - point.y; + CGWarpMouseCursorPosition(point); + [NSCursor hide]; + } }); } @@ -3246,6 +3352,12 @@ void QuitWithFatalError ( NSString *message) macFrameSkip = 200; } +- (void)setDeviceSetting:(S9xDeviceSetting)_deviceSetting +{ + deviceSetting = _deviceSetting; + ChangeInputDevice(); +} + @dynamic inputDelegate; - (void)setInputDelegate:(id)delegate { diff --git a/macosx/snes9x.xcodeproj/project.pbxproj b/macosx/snes9x.xcodeproj/project.pbxproj index e3368cf4..f2127ce9 100755 --- a/macosx/snes9x.xcodeproj/project.pbxproj +++ b/macosx/snes9x.xcodeproj/project.pbxproj @@ -263,7 +263,7 @@ 306561FF236A8BA700A1B3B2 /* gamecontrollerdb.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = gamecontrollerdb.txt; sourceTree = ""; }; 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 = ""; }; - 30714718230E379500917F82 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 30714718230E379500917F82 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; usesTabs = 0; }; 3071471A230E379600917F82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 3071471D230E379600917F82 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 3071471F230E379600917F82 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1428,7 +1428,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = ""; - ENABLE_HARDENED_RUNTIME = YES; + ENABLE_HARDENED_RUNTIME = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0;