diff --git a/Cocoa/AppDelegate.m b/Cocoa/AppDelegate.m
index be476cf..3404620 100644
--- a/Cocoa/AppDelegate.m
+++ b/Cocoa/AppDelegate.m
@@ -43,6 +43,7 @@
@"GBDMGModel": @(GB_MODEL_DMG_B),
@"GBCGBModel": @(GB_MODEL_CGB_E),
@"GBSGBModel": @(GB_MODEL_SGB2),
+ @"GBRumbleMode": @(GB_RUMBLE_CARTRIDGE_ONLY),
}];
[JOYController startOnRunLoop:[NSRunLoop currentRunLoop] withOptions:@{
diff --git a/Cocoa/Document.m b/Cocoa/Document.m
index 824c816..90a1dc8 100644
--- a/Cocoa/Document.m
+++ b/Cocoa/Document.m
@@ -228,6 +228,11 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
borderModeChanged = true;
}
+- (void) updateRumbleMode
+{
+ GB_set_rumble_mode(&gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBRumbleMode"]);
+}
+
- (void) initCommon
{
GB_init(&gb, [self internalModel]);
@@ -247,6 +252,7 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
GB_set_rewind_length(&gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBRewindLength"]);
GB_apu_set_sample_callback(&gb, audioCallback);
GB_set_rumble_callback(&gb, rumbleCallback);
+ [self updateRumbleMode];
}
- (void) updateMinSize
@@ -556,6 +562,11 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
name:@"GBBorderModeChanged"
object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(updateRumbleMode)
+ name:@"GBRumbleModeChanged"
+ object:nil];
+
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateRewindLength)
name:@"GBRewindLengthChanged"
diff --git a/Cocoa/GBPreferencesWindow.h b/Cocoa/GBPreferencesWindow.h
index 7f6bf06..ee697a8 100644
--- a/Cocoa/GBPreferencesWindow.h
+++ b/Cocoa/GBPreferencesWindow.h
@@ -16,6 +16,7 @@
@property (strong) IBOutlet NSButton *skipButton;
@property (strong) IBOutlet NSMenuItem *bootROMsFolderItem;
@property (strong) IBOutlet NSPopUpButtonCell *bootROMsButton;
+@property (strong) IBOutlet NSPopUpButton *rumbleModePopupButton;
@property (weak) IBOutlet NSPopUpButton *dmgPopupButton;
@property (weak) IBOutlet NSPopUpButton *sgbPopupButton;
diff --git a/Cocoa/GBPreferencesWindow.m b/Cocoa/GBPreferencesWindow.m
index 4d0848c..71183e1 100644
--- a/Cocoa/GBPreferencesWindow.m
+++ b/Cocoa/GBPreferencesWindow.m
@@ -24,6 +24,7 @@
NSPopUpButton *_dmgPopupButton, *_sgbPopupButton, *_cgbPopupButton;
NSPopUpButton *_preferredJoypadButton;
+ NSPopUpButton *_rumbleModePopupButton;
}
+ (NSArray *)filterList
@@ -125,6 +126,18 @@
return _displayBorderPopupButton;
}
+- (void)setRumbleModePopupButton:(NSPopUpButton *)rumbleModePopupButton
+{
+ _rumbleModePopupButton = rumbleModePopupButton;
+ NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBRumbleMode"];
+ [_rumbleModePopupButton selectItemWithTag:mode];
+}
+
+- (NSPopUpButton *)rumbleModePopupButton
+{
+ return _rumbleModePopupButton;
+}
+
- (void)setRewindPopupButton:(NSPopUpButton *)rewindPopupButton
{
_rewindPopupButton = rewindPopupButton;
@@ -267,6 +280,13 @@
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBBorderModeChanged" object:nil];
}
+- (IBAction)rumbleModeChanged:(id)sender
+{
+ [[NSUserDefaults standardUserDefaults] setObject:@([sender selectedItem].tag)
+ forKey:@"GBRumbleMode"];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"GBRumbleModeChanged" object:nil];
+}
+
- (IBAction)rewindLengthChanged:(id)sender
{
[[NSUserDefaults standardUserDefaults] setObject:@([sender selectedTag])
diff --git a/Cocoa/Preferences.xib b/Cocoa/Preferences.xib
index 1107e7d..149f71e 100644
--- a/Cocoa/Preferences.xib
+++ b/Cocoa/Preferences.xib
@@ -76,6 +76,7 @@
+
@@ -463,11 +464,11 @@
-
+
-
+
@@ -475,8 +476,17 @@
+
+
+
+
+
+
+
+
+
-
+
@@ -534,7 +544,7 @@
-
+
@@ -543,7 +553,7 @@
-
+
@@ -559,11 +569,11 @@
-
+
-
+
@@ -572,7 +582,7 @@
-
+
@@ -590,8 +600,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/Core/gb.h b/Core/gb.h
index 7967b6f..97a8069 100644
--- a/Core/gb.h
+++ b/Core/gb.h
@@ -661,6 +661,7 @@ struct GB_gameboy_internal_s {
bool vblank_just_occured; // For slow operations involving syscalls; these should only run once per vblank
uint8_t cycles_since_run; // How many cycles have passed since the last call to GB_run(), in 8MHz units
double clock_multiplier;
+ GB_rumble_mode_t rumble_mode;
uint32_t rumble_on_cycles;
uint32_t rumble_off_cycles;
diff --git a/Core/rumble.c b/Core/rumble.c
index 5ac3d0d..8cbe20d 100644
--- a/Core/rumble.c
+++ b/Core/rumble.c
@@ -1,16 +1,27 @@
#include "rumble.h"
#include "gb.h"
+void GB_set_rumble_mode(GB_gameboy_t *gb, GB_rumble_mode_t mode)
+{
+ gb->rumble_mode = mode;
+ if (gb->rumble_callback) {
+ gb->rumble_callback(gb, 0);
+ }
+}
+
void GB_handle_rumble(GB_gameboy_t *gb)
{
if (gb->rumble_callback) {
+ if (gb->rumble_mode == GB_RUMBLE_DISABLED) {
+ return;
+ }
if (gb->cartridge_type->has_rumble) {
if (gb->rumble_on_cycles + gb->rumble_off_cycles) {
gb->rumble_callback(gb, gb->rumble_on_cycles / (double)(gb->rumble_on_cycles + gb->rumble_off_cycles));
gb->rumble_on_cycles = gb->rumble_off_cycles = 0;
}
}
- else {
+ else if (gb->rumble_mode == GB_RUMBLE_ALL_GAMES) {
unsigned volume = (gb->io_registers[GB_IO_NR50] & 7) + 1 + ((gb->io_registers[GB_IO_NR50] >> 4) & 7) + 1;
unsigned ch4_volume = volume * (!!(gb->io_registers[GB_IO_NR51] & 8) + !!(gb->io_registers[GB_IO_NR51] & 0x80));
unsigned ch1_volume = volume * (!!(gb->io_registers[GB_IO_NR51] & 1) + !!(gb->io_registers[GB_IO_NR51] & 0x10));
diff --git a/Core/rumble.h b/Core/rumble.h
index a378f2d..eae9f37 100644
--- a/Core/rumble.h
+++ b/Core/rumble.h
@@ -3,6 +3,15 @@
#include "gb_struct_def.h"
+typedef enum {
+ GB_RUMBLE_DISABLED,
+ GB_RUMBLE_CARTRIDGE_ONLY,
+ GB_RUMBLE_ALL_GAMES
+} GB_rumble_mode_t;
+
+#ifdef GB_INTERNAL
void GB_handle_rumble(GB_gameboy_t *gb);
+#endif
+void GB_set_rumble_mode(GB_gameboy_t *gb, GB_rumble_mode_t mode);
#endif /* rumble_h */