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 @@
-
-
+