mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-01 23:52:49 +02:00
Add Rapid A/B to Cocoa and SDL, closes #589
This commit is contained in:
@@ -43,7 +43,7 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
[NSApplication sharedApplication].applicationIconImage = [NSImage imageNamed:@"AppIcon"];
|
[NSApplication sharedApplication].applicationIconImage = [NSImage imageNamed:@"AppIcon"];
|
||||||
|
|
||||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
for (unsigned i = 0; i < GBButtonCount; i++) {
|
for (unsigned i = 0; i < GBKeyboardButtonCount; i++) {
|
||||||
if ([[defaults objectForKey:button_to_preference_name(i, 0)] isKindOfClass:[NSString class]]) {
|
if ([[defaults objectForKey:button_to_preference_name(i, 0)] isKindOfClass:[NSString class]]) {
|
||||||
[defaults removeObjectForKey:button_to_preference_name(i, 0)];
|
[defaults removeObjectForKey:button_to_preference_name(i, 0)];
|
||||||
}
|
}
|
||||||
|
@@ -7,20 +7,24 @@ typedef enum {
|
|||||||
GBB,
|
GBB,
|
||||||
GBSelect,
|
GBSelect,
|
||||||
GBStart,
|
GBStart,
|
||||||
|
GBRapidA,
|
||||||
|
GBRapidB,
|
||||||
GBTurbo,
|
GBTurbo,
|
||||||
GBRewind,
|
GBRewind,
|
||||||
GBUnderclock,
|
GBUnderclock,
|
||||||
GBHotkey1,
|
GBHotkey1,
|
||||||
GBHotkey2,
|
GBHotkey2,
|
||||||
GBJoypadButtonCount,
|
GBTotalButtonCount,
|
||||||
GBButtonCount = GBUnderclock + 1,
|
GBKeyboardButtonCount = GBUnderclock + 1,
|
||||||
GBGameBoyButtonCount = GBStart + 1,
|
GBPerPlayerButtonCount = GBRapidB + 1,
|
||||||
} GBButton;
|
} GBButton;
|
||||||
|
|
||||||
#define GBJoyKitHotkey1 JOYButtonUsageGeneric0 + 0x100
|
#define GBJoyKitHotkey1 JOYButtonUsageGeneric0 + 0x100
|
||||||
#define GBJoyKitHotkey2 JOYButtonUsageGeneric0 + 0x101
|
#define GBJoyKitHotkey2 JOYButtonUsageGeneric0 + 0x101
|
||||||
|
#define GBJoyKitRapidA JOYButtonUsageGeneric0 + 0x102
|
||||||
|
#define GBJoyKitRapidB JOYButtonUsageGeneric0 + 0x103
|
||||||
|
|
||||||
extern NSString const *GBButtonNames[GBJoypadButtonCount];
|
extern NSString const *GBButtonNames[GBTotalButtonCount];
|
||||||
|
|
||||||
static inline NSString *n2s(uint64_t number)
|
static inline NSString *n2s(uint64_t number)
|
||||||
{
|
{
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "GBButtons.h"
|
#import "GBButtons.h"
|
||||||
|
|
||||||
NSString const *GBButtonNames[] = {@"Right", @"Left", @"Up", @"Down", @"A", @"B", @"Select", @"Start", @"Turbo", @"Rewind", @"Slow-Motion", @"Hotkey 1", @"Hotkey 2"};
|
NSString const *GBButtonNames[] = {@"Right", @"Left", @"Up", @"Down", @"A", @"B", @"Select", @"Start", @"Rapid A", @"Rapid B", @"Turbo", @"Rewind", @"Slow-Motion", @"Hotkey 1", @"Hotkey 2"};
|
||||||
|
@@ -40,16 +40,16 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||||||
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||||
{
|
{
|
||||||
if (self.playerListButton.selectedTag == 0) {
|
if (self.playerListButton.selectedTag == 0) {
|
||||||
return GBButtonCount;
|
return GBKeyboardButtonCount;
|
||||||
}
|
}
|
||||||
return GBGameBoyButtonCount;
|
return GBPerPlayerButtonCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) usesForKey:(unsigned) key
|
- (unsigned) usesForKey:(unsigned) key
|
||||||
{
|
{
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
for (unsigned player = 4; player--;) {
|
for (unsigned player = 4; player--;) {
|
||||||
for (unsigned button = player == 0? GBButtonCount:GBGameBoyButtonCount; button--;) {
|
for (unsigned button = player == 0? GBKeyboardButtonCount:GBPerPlayerButtonCount; button--;) {
|
||||||
NSNumber *other = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(button, player)];
|
NSNumber *other = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(button, player)];
|
||||||
if (other && [other unsignedIntValue] == key) {
|
if (other && [other unsignedIntValue] == key) {
|
||||||
ret++;
|
ret++;
|
||||||
@@ -205,7 +205,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||||||
if (joystick_configuration_state == GBUnderclock) {
|
if (joystick_configuration_state == GBUnderclock) {
|
||||||
[self.configureJoypadButton setTitle:@"Press Button for Slo-Mo"]; // Full name is too long :<
|
[self.configureJoypadButton setTitle:@"Press Button for Slo-Mo"]; // Full name is too long :<
|
||||||
}
|
}
|
||||||
else if (joystick_configuration_state < GBJoypadButtonCount) {
|
else if (joystick_configuration_state < GBTotalButtonCount) {
|
||||||
[self.configureJoypadButton setTitle:[NSString stringWithFormat:@"Press Button for %@", GBButtonNames[joystick_configuration_state]]];
|
[self.configureJoypadButton setTitle:[NSString stringWithFormat:@"Press Button for %@", GBButtonNames[joystick_configuration_state]]];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -227,7 +227,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||||||
|
|
||||||
if (!button.isPressed) return;
|
if (!button.isPressed) return;
|
||||||
if (joystick_configuration_state == -1) return;
|
if (joystick_configuration_state == -1) return;
|
||||||
if (joystick_configuration_state == GBJoypadButtonCount) return;
|
if (joystick_configuration_state == GBTotalButtonCount) return;
|
||||||
if (!joystick_being_configured) {
|
if (!joystick_being_configured) {
|
||||||
joystick_being_configured = controller.uniqueID;
|
joystick_being_configured = controller.uniqueID;
|
||||||
}
|
}
|
||||||
@@ -266,6 +266,8 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||||||
[GBB] = JOYButtonUsageB,
|
[GBB] = JOYButtonUsageB,
|
||||||
[GBSelect] = JOYButtonUsageSelect,
|
[GBSelect] = JOYButtonUsageSelect,
|
||||||
[GBStart] = JOYButtonUsageStart,
|
[GBStart] = JOYButtonUsageStart,
|
||||||
|
[GBRapidA] = GBJoyKitRapidA,
|
||||||
|
[GBRapidB] = GBJoyKitRapidB,
|
||||||
[GBTurbo] = JOYButtonUsageL1,
|
[GBTurbo] = JOYButtonUsageL1,
|
||||||
[GBRewind] = JOYButtonUsageL2,
|
[GBRewind] = JOYButtonUsageL2,
|
||||||
[GBUnderclock] = JOYButtonUsageR1,
|
[GBUnderclock] = JOYButtonUsageR1,
|
||||||
|
@@ -119,6 +119,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
bool _mouseControlEnabled;
|
bool _mouseControlEnabled;
|
||||||
NSMutableDictionary<NSNumber *, JOYController *> *_controllerMapping;
|
NSMutableDictionary<NSNumber *, JOYController *> *_controllerMapping;
|
||||||
unsigned _lastPlayerCount;
|
unsigned _lastPlayerCount;
|
||||||
|
|
||||||
|
bool _rapidA[4], _rapidB[4];
|
||||||
|
uint8_t _rapidACount[4], _rapidBCount[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)alloc
|
+ (instancetype)alloc
|
||||||
@@ -343,6 +346,17 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
(analogClockMultiplierValid && analogClockMultiplier < 1)) {
|
(analogClockMultiplierValid && analogClockMultiplier < 1)) {
|
||||||
[self.osdView displayText:@"Slow motion…"];
|
[self.osdView displayText:@"Slow motion…"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned i = GB_get_player_count(_gb); i--;) {
|
||||||
|
if (_rapidA[i]) {
|
||||||
|
_rapidACount[i]++;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, i, !(_rapidACount[i] & 2));
|
||||||
|
}
|
||||||
|
if (_rapidB[i]) {
|
||||||
|
_rapidBCount[i]++;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, i, !(_rapidBCount[i] & 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
[super flip];
|
[super flip];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +384,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
player_count = 2;
|
player_count = 2;
|
||||||
}
|
}
|
||||||
for (unsigned player = 0; player < player_count; player++) {
|
for (unsigned player = 0; player < player_count; player++) {
|
||||||
for (GBButton button = 0; button < GBButtonCount; button++) {
|
for (GBButton button = 0; button < GBKeyboardButtonCount; button++) {
|
||||||
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
||||||
if (!key) continue;
|
if (!key) continue;
|
||||||
|
|
||||||
@@ -401,6 +415,18 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
analogClockMultiplierValid = false;
|
analogClockMultiplierValid = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBRapidA:
|
||||||
|
_rapidA[player] = true;
|
||||||
|
_rapidACount[player] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, player, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBRapidB:
|
||||||
|
_rapidB[player] = true;
|
||||||
|
_rapidBCount[player] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, player, true);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (self.document.partner) {
|
if (self.document.partner) {
|
||||||
if (player == 0) {
|
if (player == 0) {
|
||||||
@@ -444,7 +470,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
player_count = 2;
|
player_count = 2;
|
||||||
}
|
}
|
||||||
for (unsigned player = 0; player < player_count; player++) {
|
for (unsigned player = 0; player < player_count; player++) {
|
||||||
for (GBButton button = 0; button < GBButtonCount; button++) {
|
for (GBButton button = 0; button < GBKeyboardButtonCount; button++) {
|
||||||
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
||||||
if (!key) continue;
|
if (!key) continue;
|
||||||
|
|
||||||
@@ -470,6 +496,16 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
underclockKeyDown = false;
|
underclockKeyDown = false;
|
||||||
analogClockMultiplierValid = false;
|
analogClockMultiplierValid = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBRapidA:
|
||||||
|
_rapidA[player] = false;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, player, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBRapidB:
|
||||||
|
_rapidB[player] = false;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, player, false);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (self.document.partner) {
|
if (self.document.partner) {
|
||||||
@@ -651,7 +687,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (usage) {
|
switch ((unsigned)usage) {
|
||||||
|
|
||||||
case JOYButtonUsageNone: break;
|
case JOYButtonUsageNone: break;
|
||||||
case JOYButtonUsageA: GB_set_key_state_for_player(effectiveGB, GB_KEY_A, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageA: GB_set_key_state_for_player(effectiveGB, GB_KEY_A, effectivePlayer, button.isPressed); break;
|
||||||
@@ -696,7 +732,16 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||||||
case JOYButtonUsageDPadUp: GB_set_key_state_for_player(effectiveGB, GB_KEY_UP, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageDPadUp: GB_set_key_state_for_player(effectiveGB, GB_KEY_UP, effectivePlayer, button.isPressed); break;
|
||||||
case JOYButtonUsageDPadDown: GB_set_key_state_for_player(effectiveGB, GB_KEY_DOWN, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageDPadDown: GB_set_key_state_for_player(effectiveGB, GB_KEY_DOWN, effectivePlayer, button.isPressed); break;
|
||||||
|
|
||||||
default:
|
case GBJoyKitRapidA:
|
||||||
|
_rapidA[effectivePlayer] = button.isPressed;
|
||||||
|
_rapidACount[effectivePlayer] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, effectivePlayer, button.isPressed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBJoyKitRapidB:
|
||||||
|
_rapidB[effectivePlayer] = button.isPressed;
|
||||||
|
_rapidBCount[effectivePlayer] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, effectivePlayer, button.isPressed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="oUc-bq-d5t">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" id="oUc-bq-d5t">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="66" height="17"/>
|
<rect key="frame" x="0.0" y="0.0" width="66" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" title="Test" id="xyx-iy-kse">
|
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" title="Test" id="xyx-iy-kse">
|
||||||
|
@@ -986,15 +986,15 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<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">
|
<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="124" width="262" height="211"/>
|
<rect key="frame" x="32" y="87" width="262" height="249"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<clipView key="contentView" focusRingType="none" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid">
|
<clipView key="contentView" focusRingType="none" drawsBackground="NO" id="AMs-PO-nid">
|
||||||
<rect key="frame" x="1" y="1" width="260" height="209"/>
|
<rect key="frame" x="1" y="1" width="260" height="247"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" id="UDd-IJ-fxX">
|
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" id="UDd-IJ-fxX">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="260" height="209"/>
|
<rect key="frame" x="0.0" y="0.0" width="260" height="247"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<size key="intercellSpacing" width="3" height="2"/>
|
<size key="intercellSpacing" width="3" height="2"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||||
@@ -1044,7 +1044,7 @@
|
|||||||
</scroller>
|
</scroller>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fcF-wc-KwM">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fcF-wc-KwM">
|
||||||
<rect key="frame" x="30" y="99" width="231" height="17"/>
|
<rect key="frame" x="30" y="62" width="231" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Controller for multiplayer games:" id="AJA-9b-VKI">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Controller for multiplayer games:" id="AJA-9b-VKI">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -1053,7 +1053,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Az-0R-oNw">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Az-0R-oNw">
|
||||||
<rect key="frame" x="42" y="66" width="255" height="26"/>
|
<rect key="frame" x="42" y="29" width="255" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="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">
|
<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"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
@@ -11,6 +11,27 @@ enum scaling_mode {
|
|||||||
GB_SDL_SCALING_MAX,
|
GB_SDL_SCALING_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GB_CONF_KEYS_RIGHT = GB_KEY_RIGHT,
|
||||||
|
GB_CONF_KEYS_LEFT = GB_KEY_LEFT,
|
||||||
|
GB_CONF_KEYS_UP = GB_KEY_UP,
|
||||||
|
GB_CONF_KEYS_DOWN = GB_KEY_DOWN,
|
||||||
|
GB_CONF_KEYS_A = GB_KEY_A,
|
||||||
|
GB_CONF_KEYS_B = GB_KEY_B,
|
||||||
|
GB_CONF_KEYS_SELECT = GB_KEY_SELECT,
|
||||||
|
GB_CONF_KEYS_START = GB_KEY_START,
|
||||||
|
GB_CONF_KEYS_TURBO,
|
||||||
|
GB_CONF_KEYS_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GB_CONF_KEYS2_REWIND,
|
||||||
|
GB_CONF_KEYS2_UNDERCLOCK,
|
||||||
|
GB_CONF_KEYS2_RAPID_A,
|
||||||
|
GB_CONF_KEYS2_RAPID_B,
|
||||||
|
GB_CONF_KEYS2_COUNT = 32,
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
JOYPAD_BUTTON_RIGHT,
|
JOYPAD_BUTTON_RIGHT,
|
||||||
JOYPAD_BUTTON_LEFT,
|
JOYPAD_BUTTON_LEFT,
|
||||||
@@ -26,6 +47,8 @@ typedef enum {
|
|||||||
JOYPAD_BUTTON_SLOW_MOTION,
|
JOYPAD_BUTTON_SLOW_MOTION,
|
||||||
JOYPAD_BUTTON_HOTKEY_1,
|
JOYPAD_BUTTON_HOTKEY_1,
|
||||||
JOYPAD_BUTTON_HOTKEY_2,
|
JOYPAD_BUTTON_HOTKEY_2,
|
||||||
|
JOYPAD_BUTTON_RAPID_A,
|
||||||
|
JOYPAD_BUTTON_RAPID_B,
|
||||||
JOYPAD_BUTTONS_MAX
|
JOYPAD_BUTTONS_MAX
|
||||||
} joypad_button_t;
|
} joypad_button_t;
|
||||||
|
|
||||||
@@ -65,7 +88,7 @@ typedef enum {
|
|||||||
} hotkey_action_t;
|
} hotkey_action_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SDL_Scancode keys[9];
|
SDL_Scancode keys[GB_CONF_KEYS_COUNT];
|
||||||
GB_color_correction_mode_t color_correction_mode;
|
GB_color_correction_mode_t color_correction_mode;
|
||||||
enum scaling_mode scaling_mode;
|
enum scaling_mode scaling_mode;
|
||||||
uint8_t blending_mode;
|
uint8_t blending_mode;
|
||||||
@@ -89,7 +112,7 @@ typedef struct {
|
|||||||
|
|
||||||
/* v0.11 */
|
/* v0.11 */
|
||||||
uint32_t rewind_length;
|
uint32_t rewind_length;
|
||||||
SDL_Scancode keys_2[32]; /* Rewind and underclock, + padding for the future */
|
SDL_Scancode keys_2[GB_CONF_KEYS2_COUNT]; /* Rewind and underclock, + padding for the future */
|
||||||
uint8_t joypad_configuration[32]; /* 14 Keys + padding for the future*/;
|
uint8_t joypad_configuration[32]; /* 14 Keys + padding for the future*/;
|
||||||
uint8_t joypad_axises[JOYPAD_AXISES_MAX];
|
uint8_t joypad_axises[JOYPAD_AXISES_MAX];
|
||||||
|
|
||||||
|
13
SDL/gui.c
13
SDL/gui.c
@@ -1764,16 +1764,17 @@ static const struct menu_item keyboard_menu[] = {
|
|||||||
{"Turbo:", modify_key, key_name,},
|
{"Turbo:", modify_key, key_name,},
|
||||||
{"Rewind:", modify_key, key_name,},
|
{"Rewind:", modify_key, key_name,},
|
||||||
{"Slow-Motion:", modify_key, key_name,},
|
{"Slow-Motion:", modify_key, key_name,},
|
||||||
|
{"Rapid A:", modify_key, key_name,},
|
||||||
|
{"Rapid B:", modify_key, key_name,},
|
||||||
{"Back", enter_controls_menu},
|
{"Back", enter_controls_menu},
|
||||||
{NULL,}
|
{NULL,}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *key_name(unsigned index)
|
static const char *key_name(unsigned index)
|
||||||
{
|
{
|
||||||
if (index > 8) {
|
SDL_Scancode code = index >= GB_CONF_KEYS_COUNT? configuration.keys_2[index - GB_CONF_KEYS_COUNT] : configuration.keys[index];
|
||||||
return SDL_GetScancodeName(configuration.keys_2[index - 9]);
|
if (!code) return "Not Set";
|
||||||
}
|
return SDL_GetScancodeName(code);
|
||||||
return SDL_GetScancodeName(configuration.keys[index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enter_keyboard_menu(unsigned index)
|
static void enter_keyboard_menu(unsigned index)
|
||||||
@@ -2532,7 +2533,7 @@ void run_gui(bool is_running)
|
|||||||
}
|
}
|
||||||
else if (gui_state == WAITING_FOR_KEY) {
|
else if (gui_state == WAITING_FOR_KEY) {
|
||||||
if (current_selection > 8) {
|
if (current_selection > 8) {
|
||||||
configuration.keys_2[current_selection - 9] = event.key.keysym.scancode;
|
configuration.keys_2[current_selection - GB_CONF_KEYS_COUNT] = event.key.keysym.scancode;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
configuration.keys[current_selection] = event.key.keysym.scancode;
|
configuration.keys[current_selection] = event.key.keysym.scancode;
|
||||||
@@ -2773,6 +2774,8 @@ void run_gui(bool is_running)
|
|||||||
"Slow-Motion",
|
"Slow-Motion",
|
||||||
"Hotkey 1",
|
"Hotkey 1",
|
||||||
"Hotkey 2",
|
"Hotkey 2",
|
||||||
|
"Rapid A",
|
||||||
|
"Rapid B",
|
||||||
"",
|
"",
|
||||||
}) [joypad_configuration_progress],
|
}) [joypad_configuration_progress],
|
||||||
gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
|
gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
|
||||||
|
39
SDL/main.c
39
SDL/main.c
@@ -26,6 +26,8 @@ static bool paused = false;
|
|||||||
static uint32_t pixel_buffer_1[256 * 224], pixel_buffer_2[256 * 224];
|
static uint32_t pixel_buffer_1[256 * 224], pixel_buffer_2[256 * 224];
|
||||||
static uint32_t *active_pixel_buffer = pixel_buffer_1, *previous_pixel_buffer = pixel_buffer_2;
|
static uint32_t *active_pixel_buffer = pixel_buffer_1, *previous_pixel_buffer = pixel_buffer_2;
|
||||||
static bool underclock_down = false, rewind_down = false, do_rewind = false, rewind_paused = false, turbo_down = false;
|
static bool underclock_down = false, rewind_down = false, do_rewind = false, rewind_paused = false, turbo_down = false;
|
||||||
|
static bool rapid_a = false, rapid_b = false;
|
||||||
|
static uint8_t rapid_a_count = 0, rapid_b_count = 0;
|
||||||
static double clock_mutliplier = 1.0;
|
static double clock_mutliplier = 1.0;
|
||||||
|
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
@@ -322,8 +324,18 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (button == JOYPAD_BUTTON_RAPID_A) {
|
||||||
|
rapid_a = event.type == SDL_JOYBUTTONDOWN;
|
||||||
|
rapid_a_count = 0;
|
||||||
|
GB_set_key_state(gb, GB_KEY_A, event.type == SDL_JOYBUTTONDOWN);
|
||||||
|
}
|
||||||
|
else if (button == JOYPAD_BUTTON_RAPID_B) {
|
||||||
|
rapid_b = event.type == SDL_JOYBUTTONDOWN;
|
||||||
|
rapid_b_count = 0;
|
||||||
|
GB_set_key_state(gb, GB_KEY_B, event.type == SDL_JOYBUTTONDOWN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_JOYAXISMOTION: {
|
case SDL_JOYAXISMOTION: {
|
||||||
static bool axis_active[2] = {false, false};
|
static bool axis_active[2] = {false, false};
|
||||||
@@ -475,21 +487,31 @@ static void handle_events(GB_gameboy_t *gb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_KEYUP: // Fallthrough
|
case SDL_KEYUP: // Fallthrough
|
||||||
if (event.key.keysym.scancode == configuration.keys[8]) {
|
if (event.key.keysym.scancode == configuration.keys[GB_CONF_KEYS_TURBO]) {
|
||||||
turbo_down = event.type == SDL_KEYDOWN;
|
turbo_down = event.type == SDL_KEYDOWN;
|
||||||
GB_audio_clear_queue();
|
GB_audio_clear_queue();
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.scancode == configuration.keys_2[0]) {
|
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_REWIND]) {
|
||||||
rewind_down = event.type == SDL_KEYDOWN;
|
rewind_down = event.type == SDL_KEYDOWN;
|
||||||
if (event.type == SDL_KEYUP) {
|
if (event.type == SDL_KEYUP) {
|
||||||
rewind_paused = false;
|
rewind_paused = false;
|
||||||
}
|
}
|
||||||
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
|
||||||
}
|
}
|
||||||
else if (event.key.keysym.scancode == configuration.keys_2[1]) {
|
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_UNDERCLOCK]) {
|
||||||
underclock_down = event.type == SDL_KEYDOWN;
|
underclock_down = event.type == SDL_KEYDOWN;
|
||||||
}
|
}
|
||||||
|
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_RAPID_A]) {
|
||||||
|
rapid_a = event.type == SDL_KEYDOWN;
|
||||||
|
rapid_a_count = 0;
|
||||||
|
GB_set_key_state(gb, GB_KEY_A, event.type == SDL_KEYDOWN);
|
||||||
|
}
|
||||||
|
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_RAPID_B]) {
|
||||||
|
rapid_b = event.type == SDL_KEYDOWN;
|
||||||
|
rapid_b_count = 0;
|
||||||
|
GB_set_key_state(gb, GB_KEY_B, event.type == SDL_KEYDOWN);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
for (unsigned i = 0; i < GB_KEY_MAX; i++) {
|
for (unsigned i = 0; i < GB_KEY_MAX; i++) {
|
||||||
if (event.key.keysym.scancode == configuration.keys[i]) {
|
if (event.key.keysym.scancode == configuration.keys[i]) {
|
||||||
@@ -520,6 +542,15 @@ static void vblank(GB_gameboy_t *gb, GB_vblank_type_t type)
|
|||||||
GB_set_clock_multiplier(gb, clock_mutliplier);
|
GB_set_clock_multiplier(gb, clock_mutliplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rapid_a) {
|
||||||
|
rapid_a_count++;
|
||||||
|
GB_set_key_state(gb, GB_KEY_A, !(rapid_a_count & 2));
|
||||||
|
}
|
||||||
|
if (rapid_b) {
|
||||||
|
rapid_b_count++;
|
||||||
|
GB_set_key_state(gb, GB_KEY_B, !(rapid_b_count & 2));
|
||||||
|
}
|
||||||
|
|
||||||
if (turbo_down) {
|
if (turbo_down) {
|
||||||
show_osd_text("Fast forward...");
|
show_osd_text("Fast forward...");
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,9 @@ typedef enum {
|
|||||||
GBUnderclock,
|
GBUnderclock,
|
||||||
// GBHotkey1, // Todo
|
// GBHotkey1, // Todo
|
||||||
// GBHotkey2, // Todo
|
// GBHotkey2, // Todo
|
||||||
GBJoypadButtonCount,
|
GBTotalButtonCount,
|
||||||
GBButtonCount = GBUnderclock + 1,
|
GBKeyboardButtonCount = GBUnderclock + 1,
|
||||||
GBGameBoyButtonCount = GBStart + 1,
|
GBPerPlayerButtonCount = GBStart + 1,
|
||||||
GBUnusedButton = 0xFF,
|
GBUnusedButton = 0xFF,
|
||||||
} GBButton;
|
} GBButton;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user