mirror of https://github.com/snes9xgit/snes9x.git
Mac: Restore Mouse, SuperScope and Justifier support
This commit is contained in:
parent
364aa1ba5d
commit
f7c6625d67
|
@ -31,6 +31,7 @@ extern NSWindowFrameAutosaveName const kMainWindowIdentifier;
|
|||
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -115,6 +115,62 @@
|
|||
<action selector="hardwareReset:" target="-1" id="dRy-5Q-N2I"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="YAv-y2-CdP"/>
|
||||
<menuItem title="Controls" id="2xu-Kh-K2Q">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" id="Scs-jj-0pz">
|
||||
<items>
|
||||
<menuItem title="Gamepads" tag="1" id="ntk-uz-aiW">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="GxE-k5-uWL"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Mouse (Port 1)" tag="2" id="5es-Zi-iof">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="jtg-E2-98q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Mouse (Port 2)" tag="3" id="vrV-Bh-KyE">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="LGe-fJ-vTb"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Super Scope (Port 2)" tag="4" id="ZF8-Xw-08U">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="1qY-rM-anV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Multitap (Port 2)" tag="5" id="cdn-s1-eHL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="qrs-Ih-u7R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Multitap (Both Ports)" tag="6" id="fQJ-1V-NpK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="5d9-tW-Rfm"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justifier (Port 2)" tag="7" id="hUi-aI-ihE">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="QBV-bU-viB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Double Justifier (Port 2)" tag="8" id="wTw-mT-ha1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="updateDeviceSetting:" target="-1" id="XZV-DZ-rX3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
|
@ -171,5 +227,8 @@
|
|||
</items>
|
||||
<point key="canvasLocation" x="132" y="154"/>
|
||||
</menu>
|
||||
<menuItem title="Mouse (Port 2)" id="P6N-Mq-1PD">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -236,68 +236,70 @@ NSString * const kMacFrameSkipPref = @"FrameSkip";
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting {}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
|
||||
{
|
||||
if ([keyPath isEqualToString:@"keyCode"])
|
||||
{
|
||||
S9xButtonConfigTextField *field = (S9xButtonConfigTextField *)object;
|
||||
S9xButtonCode buttonCode = (S9xButtonCode)field.tag;
|
||||
uint16_t keyCode = field.keyCode;
|
||||
int8_t player = self.playerPopUp.selectedItem.tag;
|
||||
if ([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,7 +315,7 @@ NSString * const kMacFrameSkipPref = @"FrameSkip";
|
|||
|
||||
- (IBAction)onSelectVideoMode:(NSPopUpButton *)sender
|
||||
{
|
||||
[self setVideoMode:(int)sender.selectedTag];
|
||||
[self setVideoMode:(int)sender.selectedTag];
|
||||
}
|
||||
|
||||
- (IBAction)bumpMacFrameSkip:(NSStepper *)sender
|
||||
|
@ -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
|
||||
|
|
|
@ -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";
|
|
@ -1,8 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict/>
|
||||
</plist>
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <NSObject>
|
||||
- (BOOL)handleInput:(S9xJoypadInput *)input fromJoypad:(S9xJoypad *)joypad;
|
||||
- (void)deviceSettingChanged:(S9xDeviceSetting)deviceSetting;
|
||||
@end
|
||||
|
||||
extern id<S9xInputDelegate> inputDelegate;
|
||||
|
@ -195,6 +208,8 @@ extern id<S9xInputDelegate> inputDelegate;
|
|||
- (void)setMacFrameSkip:(int)_macFrameSkip;
|
||||
- (void)setShowFPS:(BOOL)showFPS;
|
||||
|
||||
- (void)setDeviceSetting:(S9xDeviceSetting)_deviceSetting;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
336
macosx/mac-os.mm
336
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<S9xInputDelegate>)delegate
|
||||
{
|
||||
|
|
|
@ -263,7 +263,7 @@
|
|||
306561FF236A8BA700A1B3B2 /* gamecontrollerdb.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = gamecontrollerdb.txt; sourceTree = "<group>"; };
|
||||
30714715230E379500917F82 /* Snes9x.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Snes9x.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
30714717230E379500917F82 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
30714718230E379500917F82 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
30714718230E379500917F82 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; usesTabs = 0; };
|
||||
3071471A230E379600917F82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
3071471D230E379600917F82 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
3071471F230E379600917F82 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue