SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit d15eaf4134d5e674caefba3da231464d1944552d parent ae930472f003e970e97750c8b5996697e8ab4b95 Author: Lior Halphon <LIJI32@gmail.com> Date: Sun, 14 Nov 2021 21:27:12 +0200 Mouse controls for MBC7 Diffstat:
| M | Cocoa/AppDelegate.m | 3 | +++ |
| M | Cocoa/GBPreferencesWindow.h | 2 | ++ |
| M | Cocoa/GBPreferencesWindow.m | 37 | +++++++++++++++++++++++++++++++++++++ |
| M | Cocoa/GBView.m | 67 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
| M | Cocoa/Preferences.xib | 79 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
5 files changed, 162 insertions(+), 26 deletions(-)
diff --git a/Cocoa/AppDelegate.m b/Cocoa/AppDelegate.m @@ -68,6 +68,9 @@ static uint32_t color_to_int(NSColor *color) @"GBRumbleMode": @(GB_RUMBLE_CARTRIDGE_ONLY), @"GBVolume": @(1.0), + + @"GBMBC7JoystickOverride": @NO, + @"GBMBC7AllowMouse": @YES, }]; [JOYController startOnRunLoop:[NSRunLoop currentRunLoop] withOptions:@{ diff --git a/Cocoa/GBPreferencesWindow.h b/Cocoa/GBPreferencesWindow.h @@ -32,4 +32,6 @@ @property (weak) IBOutlet NSButton *screenshotFilterCheckbox; @property (weak) IBOutlet GBPaletteEditorController *paletteEditorController; @property (strong) IBOutlet NSWindow *paletteEditor; +@property (weak) IBOutlet NSButton *joystickMBC7Checkbox; +@property (weak) IBOutlet NSButton *mouseMBC7Checkbox; @end diff --git a/Cocoa/GBPreferencesWindow.m b/Cocoa/GBPreferencesWindow.m @@ -34,6 +34,8 @@ NSButton *_autoUpdatesCheckbox; NSButton *_OSDCheckbox; NSButton *_screenshotFilterCheckbox; + NSButton *_joystickMBC7Checkbox; + NSButton *_mouseMBC7Checkbox; } + (NSArray *)filterList @@ -324,6 +326,19 @@ [[NSNotificationCenter defaultCenter] postNotificationName:@"GBHighpassFilterChanged" object:nil]; } + +- (IBAction)changeMBC7JoystickOverride:(id)sender +{ + [[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] == NSOnState + forKey:@"GBMBC7JoystickOverride"]; +} + +- (IBAction)changeMBC7AllowMouse:(id)sender +{ + [[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] == NSOnState + forKey:@"GBMBC7AllowMouse"]; +} + - (IBAction)changeAnalogControls:(id)sender { [[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] == NSOnState @@ -572,6 +587,28 @@ [self advanceConfigurationStateMachine]; } +- (NSButton *)joystickMBC7Checkbox +{ + return _joystickMBC7Checkbox; +} + +- (void)setJoystickMBC7Checkbox:(NSButton *)joystickMBC7Checkbox +{ + _joystickMBC7Checkbox = joystickMBC7Checkbox; + [_joystickMBC7Checkbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBMBC7JoystickOverride"]]; +} + +- (NSButton *)mouseMBC7Checkbox +{ + return _mouseMBC7Checkbox; +} + +- (void)setMouseMBC7Checkbox:(NSButton *)mouseMBC7Checkbox +{ + _mouseMBC7Checkbox = mouseMBC7Checkbox; + [_mouseMBC7Checkbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBMBC7AllowMouse"]]; +} + - (NSButton *)analogControlsCheckbox { return _analogControlsCheckbox; diff --git a/Cocoa/GBView.m b/Cocoa/GBView.m @@ -118,6 +118,7 @@ static const uint8_t workboy_vk_to_key[] = { JOYController *lastController; GB_frame_blending_mode_t _frameBlendingMode; bool _turbo; + bool _mouseControlEnabled; } + (instancetype)alloc @@ -147,7 +148,7 @@ static const uint8_t workboy_vk_to_key[] = { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ratioKeepingChanged) name:@"GBAspectChanged" object:nil]; tracking_area = [ [NSTrackingArea alloc] initWithRect:(NSRect){} - options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect + options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseMoved owner:self userInfo:nil]; [self addTrackingArea:tracking_area]; @@ -156,6 +157,7 @@ static const uint8_t workboy_vk_to_key[] = { [self addSubview:self.internalView]; self.internalView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; [JOYController registerListener:self]; + _mouseControlEnabled = true; } - (void)screenSizeChanged @@ -461,7 +463,9 @@ static const uint8_t workboy_vk_to_key[] = { - (bool)shouldControllerUseJoystickForMotion:(JOYController *)controller { + if (!_gb) return false; if (!GB_has_accelerometer(_gb)) return false; + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBMBC7JoystickOverride"]) return true; for (JOYAxes3D *axes in controller.axes3D) { if (axes.usage == JOYAxes3DUsageOrientation || axes.usage == JOYAxes3DUsageAcceleration) { return false; @@ -472,6 +476,7 @@ static const uint8_t workboy_vk_to_key[] = { - (void)controller:(JOYController *)controller movedAxis:(JOYAxis *)axis { + if (!_gb) return; if (![self.window isMainWindow]) return; NSDictionary *mapping = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitInstanceMapping"][controller.uniqueID]; @@ -494,13 +499,20 @@ static const uint8_t workboy_vk_to_key[] = { - (void)controller:(JOYController *)controller movedAxes2D:(JOYAxes2D *)axes { + if (!_gb) return; if ([self shouldControllerUseJoystickForMotion:controller]) { - GB_set_accelerometer_values(_gb, -axes.value.x, -axes.value.y); + if (!self.mouseControlsActive) { + GB_set_accelerometer_values(_gb, -axes.value.x, -axes.value.y); + } } } - (void)controller:(JOYController *)controller movedAxes3D:(JOYAxes3D *)axes { + if (!_gb) return; + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBMBC7JoystickOverride"]) return; + if (self.mouseControlsActive) return; + if (axes.usage == JOYAxes3DUsageOrientation) { for (JOYAxes3D *axes in controller.axes3D) { // Only use orientation if there's no acceleration axes @@ -519,7 +531,9 @@ static const uint8_t workboy_vk_to_key[] = { - (void)controller:(JOYController *)controller buttonChangedState:(JOYButton *)button { + if (!_gb) return; if (![self.window isMainWindow]) return; + _mouseControlEnabled = false; if (button.type == JOYButtonTypeAxes2DEmulated && [self shouldControllerUseJoystickForMotion:controller]) return; unsigned player_count = GB_get_player_count(_gb); @@ -625,11 +639,18 @@ static const uint8_t workboy_vk_to_key[] = { return true; } +- (bool)mouseControlsActive +{ + return _gb && GB_is_inited(_gb) && GB_has_accelerometer(_gb) && + _mouseControlEnabled && [[NSUserDefaults standardUserDefaults] boolForKey:@"GBMBC7AllowMouse"]; +} + - (void)mouseEntered:(NSEvent *)theEvent { if (!mouse_hidden) { mouse_hidden = true; - if (_mouseHidingEnabled) { + if (_mouseHidingEnabled && + !self.mouseControlsActive) { [NSCursor hide]; } } @@ -647,6 +668,46 @@ static const uint8_t workboy_vk_to_key[] = { [super mouseExited:theEvent]; } +- (void)mouseDown:(NSEvent *)event +{ + _mouseControlEnabled = true; + if (self.mouseControlsActive) { + if (event.type == NSEventTypeLeftMouseDown) { + GB_set_key_state(_gb, GB_KEY_A, true); + } + } +} + +- (void)mouseUp:(NSEvent *)event +{ + if (self.mouseControlsActive) { + if (event.type == NSEventTypeLeftMouseUp) { + GB_set_key_state(_gb, GB_KEY_A, false); + } + } +} + +- (void)mouseMoved:(NSEvent *)event +{ + if (self.mouseControlsActive) { + NSPoint point = [self convertPoint:[event locationInWindow] toView:nil]; + + point.x /= self.frame.size.width; + point.x *= 2; + point.x -= 1; + + point.y /= self.frame.size.height; + point.y *= 2; + point.y -= 1; + + if (GB_get_screen_width(_gb) != 160) { // has border + point.x *= 256 / 160.0; + point.y *= 224 / 114.0; + } + GB_set_accelerometer_values(_gb, -point.x, point.y); + } +} + - (void)setMouseHidingEnabled:(bool)mouseHidingEnabled { if (mouseHidingEnabled == _mouseHidingEnabled) return; diff --git a/Cocoa/Preferences.xib b/Cocoa/Preferences.xib @@ -85,6 +85,8 @@ <outlet property="graphicsFilterPopupButton" destination="6pP-kK-EEC" id="LS7-HY-kHC"/> <outlet property="highpassFilterPopupButton" destination="T69-6N-dhT" id="0p6-4m-hb1"/> <outlet property="interferenceSlider" destination="FpE-5i-j5L" id="hfH-e8-7cx"/> + <outlet property="joystickMBC7Checkbox" destination="i7F-1r-NkQ" id="msM-WX-w9H"/> + <outlet property="mouseMBC7Checkbox" destination="wUE-aB-ub1" id="mXX-mZ-sKJ"/> <outlet property="paletteEditor" destination="g32-xe-7al" id="WLk-Hh-h5v"/> <outlet property="paletteEditorController" destination="Zxl-vm-6c9" id="uPS-zn-osL"/> <outlet property="playerListButton" destination="gWx-7h-0xq" id="zo6-82-JId"/> @@ -584,11 +586,11 @@ <point key="canvasLocation" x="-854" y="627"/> </customView> <customView id="8TU-6J-NCg"> - <rect key="frame" x="0.0" y="0.0" width="320" height="467"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="537"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <subviews> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Utu-t4-cLx"> - <rect key="frame" x="18" y="430" width="122" height="17"/> + <rect key="frame" x="18" y="500" width="122" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Control settings for" id="YqW-Ds-VIC"> <font key="font" metaFont="system"/> @@ -596,17 +598,17 @@ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> - <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DZu-ts-deW"> - <rect key="frame" x="18" y="87" width="133" height="17"/> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zYm-Ov-RHL"> + <rect key="frame" x="18" y="157" width="273" height="17"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Enable rumble:" id="QMX-3p-s1Z"> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="When playing motion-control games:" id="sgY-3F-qld"> <font key="font" metaFont="system"/> <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> <scrollView focusRingType="none" fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="PBp-dj-EIa"> - <rect key="frame" x="32" y="208" width="257" height="211"/> + <rect key="frame" x="32" y="278" width="257" height="211"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <clipView key="contentView" focusRingType="none" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid"> <rect key="frame" x="1" y="1" width="255" height="209"/> @@ -664,7 +666,7 @@ </scroller> </scrollView> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fcF-wc-KwM"> - <rect key="frame" x="30" y="183" width="231" height="17"/> + <rect key="frame" x="30" y="253" width="231" height="17"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Controller for multiplayer games:" id="AJA-9b-VKI"> <font key="font" metaFont="system"/> @@ -673,7 +675,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Az-0R-oNw"> - <rect key="frame" x="42" y="150" width="250" height="26"/> + <rect key="frame" x="42" y="220" width="250" height="26"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="None" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingMiddle" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="hy8-cr-RrE" id="uEC-vN-8Jq"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -689,11 +691,11 @@ </connections> </popUpButton> <box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="VEc-Ed-Z6f"> - <rect key="frame" x="12" y="139" width="296" height="5"/> + <rect key="frame" x="12" y="209" width="296" height="5"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> </box> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ReM-uo-H0r"> - <rect key="frame" x="227" y="431" width="8" height="17"/> + <rect key="frame" x="227" y="501" width="8" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title=":" id="VhO-3T-glt"> <font key="font" metaFont="system"/> @@ -702,7 +704,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gWx-7h-0xq"> - <rect key="frame" x="140" y="425" width="87" height="26"/> + <rect key="frame" x="140" y="495" width="87" height="26"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Player 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="TO3-R7-9HN" id="pbt-Lr-bU1"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -720,6 +722,48 @@ <action selector="refreshJoypadMenu:" target="QvC-M9-y7g" id="5hY-tg-9VE"/> </connections> </popUpButton> + <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RuW-Db-dzW"> + <rect key="frame" x="18" y="180" width="292" height="25"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="check" title="Analog turbo and slow-motion controls" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="charWrapping" inset="2" id="Mvp-oc-N3t"> + <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="changeAnalogControls:" target="QvC-M9-y7g" id="1xR-gY-WKo"/> + </connections> + </button> + <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i7F-1r-NkQ"> + <rect key="frame" x="30" y="130" width="272" height="21"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="check" title="Prefer joysticks over motion controls" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="charWrapping" inset="2" id="Szg-5G-j50"> + <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="changeMBC7JoystickOverride:" target="QvC-M9-y7g" id="8Oy-4n-4Yl"/> + </connections> + </button> + <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wUE-aB-ub1"> + <rect key="frame" x="30" y="110" width="268" height="18"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="check" title="Allow mouse controls" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="charWrapping" state="on" inset="2" id="z0R-FZ-LfD"> + <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="changeMBC7AllowMouse:" target="QvC-M9-y7g" id="jqY-Nc-x3Y"/> + </connections> + </button> + <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DZu-ts-deW"> + <rect key="frame" x="18" y="87" width="133" height="17"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Enable rumble:" id="QMX-3p-s1Z"> + <font key="font" metaFont="system"/> + <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ogs-xG-b4b"> <rect key="frame" x="30" y="58" width="262" height="22"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> @@ -738,17 +782,6 @@ <action selector="rumbleModeChanged:" target="QvC-M9-y7g" id="AQe-vQ-mSl"/> </connections> </popUpButton> - <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RuW-Db-dzW"> - <rect key="frame" x="18" y="110" width="292" height="25"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> - <buttonCell key="cell" type="check" title="Analog turbo and slow-motion controls" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="charWrapping" inset="2" id="Mvp-oc-N3t"> - <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> - <font key="font" metaFont="system"/> - </buttonCell> - <connections> - <action selector="changeAnalogControls:" target="QvC-M9-y7g" id="1xR-gY-WKo"/> - </connections> - </button> <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qa7-Z7-yfO"> <rect key="frame" x="26" y="13" width="204" height="32"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/> @@ -772,7 +805,7 @@ </connections> </button> </subviews> - <point key="canvasLocation" x="-854" y="260"/> + <point key="canvasLocation" x="-854" y="223"/> </customView> <customView id="ffn-ie-9C3"> <rect key="frame" x="0.0" y="0.0" width="320" height="95"/>
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.