From d15eaf4134d5e674caefba3da231464d1944552d Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Sun, 14 Nov 2021 21:27:12 +0200 Subject: [PATCH] Mouse controls for MBC7 --- Cocoa/AppDelegate.m | 3 ++ Cocoa/GBPreferencesWindow.h | 2 + Cocoa/GBPreferencesWindow.m | 37 +++++++++++++++++ Cocoa/GBView.m | 67 +++++++++++++++++++++++++++++-- Cocoa/Preferences.xib | 79 ++++++++++++++++++++++++++----------- 5 files changed, 162 insertions(+), 26 deletions(-) diff --git a/Cocoa/AppDelegate.m b/Cocoa/AppDelegate.m index 48514a0..eccd137 100644 --- 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 index 355dc6e..30b045c 100644 --- 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 index e1f9fc0..c77a5b7 100644 --- 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 index b374b37..5ae9c79 100644 --- 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 index c9fb8ce..699f264 100644 --- a/Cocoa/Preferences.xib +++ b/Cocoa/Preferences.xib @@ -85,6 +85,8 @@ + + @@ -584,11 +586,11 @@ - + - + @@ -596,17 +598,17 @@ - - + + - + - + @@ -664,7 +666,7 @@ - + @@ -673,7 +675,7 @@ - + @@ -689,11 +691,11 @@ - + - + @@ -702,7 +704,7 @@ - + @@ -720,6 +722,48 @@ + + + + + + + + + + + + @@ -738,17 +782,6 @@ - - +