From 4b2417855373761a126b30749c3ae5191a5c8d5d Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Wed, 29 Apr 2020 16:50:31 +0300 Subject: [PATCH] Rumble mode selection --- Cocoa/AppDelegate.m | 1 + Cocoa/Document.m | 11 +++++++++ Cocoa/GBPreferencesWindow.h | 1 + Cocoa/GBPreferencesWindow.m | 20 ++++++++++++++++ Cocoa/Preferences.xib | 48 +++++++++++++++++++++++++++++-------- Core/gb.h | 1 + Core/rumble.c | 13 +++++++++- Core/rumble.h | 9 +++++++ 8 files changed, 93 insertions(+), 11 deletions(-) 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 */