Added CPU under/over-clocking support in Core, add under-clocking hotkey in the Cocoa port, allow modifier keys to be configured as input keys in Cocoa.
This commit is contained in:
parent
0cbbaac490
commit
afcc66fb3c
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
@"GBTurbo": @(kVK_Space),
|
@"GBTurbo": @(kVK_Space),
|
||||||
@"GBRewind": @(kVK_Tab),
|
@"GBRewind": @(kVK_Tab),
|
||||||
|
@"GBSlow-Motion": @(kVK_Shift),
|
||||||
|
|
||||||
@"GBFilter": @"NearestNeighbor",
|
@"GBFilter": @"NearestNeighbor",
|
||||||
@"GBColorCorrection": @(GB_COLOR_CORRECTION_EMULATE_HARDWARE),
|
@"GBColorCorrection": @(GB_COLOR_CORRECTION_EMULATE_HARDWARE),
|
||||||
|
@ -12,6 +12,7 @@ typedef enum : NSUInteger {
|
|||||||
GBStart,
|
GBStart,
|
||||||
GBTurbo,
|
GBTurbo,
|
||||||
GBRewind,
|
GBRewind,
|
||||||
|
GBUnderclock,
|
||||||
GBButtonCount
|
GBButtonCount
|
||||||
} GBButton;
|
} GBButton;
|
||||||
|
|
||||||
|
@ -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"};
|
NSString const *GBButtonNames[] = {@"Right", @"Left", @"Up", @"Down", @"A", @"B", @"Select", @"Start", @"Turbo", @"Rewind", @"Slow-Motion"};
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
NSPopUpButton *_colorCorrectionPopupButton;
|
NSPopUpButton *_colorCorrectionPopupButton;
|
||||||
NSPopUpButton *_rewindPopupButton;
|
NSPopUpButton *_rewindPopupButton;
|
||||||
NSButton *_aspectRatioCheckbox;
|
NSButton *_aspectRatioCheckbox;
|
||||||
|
NSEventModifierFlags previousModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)filterList
|
+ (NSArray *)filterList
|
||||||
@ -145,6 +146,18 @@
|
|||||||
[self makeFirstResponder:self.controlsTableView];
|
[self makeFirstResponder:self.controlsTableView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) flagsChanged:(NSEvent *)event
|
||||||
|
{
|
||||||
|
if (event.modifierFlags > previousModifiers) {
|
||||||
|
[self keyDown:event];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self keyUp:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
previousModifiers = event.modifierFlags;
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)graphicFilterChanged:(NSPopUpButton *)sender
|
- (IBAction)graphicFilterChanged:(NSPopUpButton *)sender
|
||||||
{
|
{
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:[[self class] filterList][[sender indexOfSelectedItem]]
|
[[NSUserDefaults standardUserDefaults] setObject:[[self class] filterList][[sender indexOfSelectedItem]]
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
NSTrackingArea *tracking_area;
|
NSTrackingArea *tracking_area;
|
||||||
BOOL _mouseHidingEnabled;
|
BOOL _mouseHidingEnabled;
|
||||||
bool enableAnalog;
|
bool enableAnalog;
|
||||||
|
bool underclockKeyDown;
|
||||||
|
double clockMultiplier;
|
||||||
|
NSEventModifierFlags previousModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) awakeFromNib
|
- (void) awakeFromNib
|
||||||
@ -51,6 +54,7 @@
|
|||||||
owner:self
|
owner:self
|
||||||
userInfo:nil];
|
userInfo:nil];
|
||||||
[self addTrackingArea:tracking_area];
|
[self addTrackingArea:tracking_area];
|
||||||
|
clockMultiplier = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) filterChanged
|
- (void) filterChanged
|
||||||
@ -153,6 +157,14 @@
|
|||||||
|
|
||||||
- (void) flip
|
- (void) flip
|
||||||
{
|
{
|
||||||
|
if (underclockKeyDown && clockMultiplier > 0.5) {
|
||||||
|
clockMultiplier -= 0.1;
|
||||||
|
GB_set_clock_multiplier(_gb, clockMultiplier);
|
||||||
|
}
|
||||||
|
if (!underclockKeyDown && clockMultiplier < 1.0) {
|
||||||
|
clockMultiplier += 0.1;
|
||||||
|
GB_set_clock_multiplier(_gb, clockMultiplier);
|
||||||
|
}
|
||||||
current_buffer = (current_buffer + 1) % self.numberOfBuffers;
|
current_buffer = (current_buffer + 1) % self.numberOfBuffers;
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
}
|
}
|
||||||
@ -181,6 +193,10 @@
|
|||||||
GB_set_turbo_mode(_gb, false, false);
|
GB_set_turbo_mode(_gb, false, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBUnderclock:
|
||||||
|
underclockKeyDown = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GB_set_key_state(_gb, (GB_key_t)i, true);
|
GB_set_key_state(_gb, (GB_key_t)i, true);
|
||||||
break;
|
break;
|
||||||
@ -211,6 +227,10 @@
|
|||||||
self.isRewinding = false;
|
self.isRewinding = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBUnderclock:
|
||||||
|
underclockKeyDown = false;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GB_set_key_state(_gb, (GB_key_t)i, false);
|
GB_set_key_state(_gb, (GB_key_t)i, false);
|
||||||
break;
|
break;
|
||||||
@ -243,6 +263,10 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBUnderclock:
|
||||||
|
underclockKeyDown = state;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (i < GB_KEY_A) {
|
if (i < GB_KEY_A) {
|
||||||
enableAnalog = false;
|
enableAnalog = false;
|
||||||
@ -324,4 +348,16 @@
|
|||||||
return _mouseHidingEnabled;
|
return _mouseHidingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) flagsChanged:(NSEvent *)event
|
||||||
|
{
|
||||||
|
if (event.modifierFlags > previousModifiers) {
|
||||||
|
[self keyDown:event];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self keyUp:event];
|
||||||
|
}
|
||||||
|
|
||||||
|
previousModifiers = event.modifierFlags;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -13,21 +13,32 @@
|
|||||||
{
|
{
|
||||||
/* These cases are not handled by stringForVirtualKey */
|
/* These cases are not handled by stringForVirtualKey */
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case 115: return @"↖";
|
|
||||||
case 119: return @"↘";
|
case kVK_Home: return @"↖";
|
||||||
case 116: return @"⇞";
|
case kVK_End: return @"↘";
|
||||||
case 121: return @"⇟";
|
case kVK_PageUp: return @"⇞";
|
||||||
case 51: return @"⌫";
|
case kVK_PageDown: return @"⇟";
|
||||||
case 117: return @"⌦";
|
case kVK_Delete: return @"⌫";
|
||||||
case 76: return @"⌤";
|
case kVK_ForwardDelete: return @"⌦";
|
||||||
|
case kVK_ANSI_KeypadEnter: return @"⌤";
|
||||||
|
case kVK_CapsLock: return @"⇪";
|
||||||
|
case kVK_Shift: return @"Left ⇧";
|
||||||
|
case kVK_Control: return @"Left ⌃";
|
||||||
|
case kVK_Option: return @"Left ⌥";
|
||||||
|
case kVK_Command: return @"Left ⌘";
|
||||||
|
case kVK_RightShift: return @"Right ⇧";
|
||||||
|
case kVK_RightControl: return @"Right ⌃";
|
||||||
|
case kVK_RightOption: return @"Right ⌥";
|
||||||
|
case kVK_RightCommand: return @"Right ⌘";
|
||||||
|
case kVK_Function: return @"fn";
|
||||||
|
|
||||||
/* Label Keypad buttons accordingly */
|
/* Label Keypad buttons accordingly */
|
||||||
default:
|
default:
|
||||||
if ((keyCode < 82 || keyCode > 92)) {
|
if ((keyCode < kVK_ANSI_Keypad0 || keyCode > kVK_ANSI_Keypad9)) {
|
||||||
return [NSPrefPaneUtils stringForVirtualKey:keyCode modifiers:0];
|
return [NSPrefPaneUtils stringForVirtualKey:keyCode modifiers:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
case 65: case 67: case 69: case 75: case 78: case 81:
|
case kVK_ANSI_KeypadDecimal: case kVK_ANSI_KeypadMultiply: case kVK_ANSI_KeypadPlus: case kVK_ANSI_KeypadDivide: case kVK_ANSI_KeypadMinus: case kVK_ANSI_KeypadEquals:
|
||||||
return [@"Keypad " stringByAppendingString:[NSPrefPaneUtils stringForVirtualKey:keyCode modifiers:0]];
|
return [@"Keypad " stringByAppendingString:[NSPrefPaneUtils stringForVirtualKey:keyCode modifiers:0]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="196" y="240" width="292" height="516"/>
|
<rect key="contentRect" x="196" y="240" width="292" height="535"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
<view key="contentView" id="EiT-Mj-1SZ">
|
<view key="contentView" id="EiT-Mj-1SZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="292" height="516"/>
|
<rect key="frame" x="0.0" y="0.0" width="292" height="535"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T91-rh-rRp">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T91-rh-rRp">
|
||||||
<rect key="frame" x="18" y="487" width="256" height="17"/>
|
<rect key="frame" x="18" y="506" width="256" 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="Graphics Filter:" id="pXg-WY-8Q5">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Graphics Filter:" id="pXg-WY-8Q5">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC">
|
||||||
<rect key="frame" x="30" y="455" width="245" height="26"/>
|
<rect key="frame" x="30" y="474" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="I1w-05-lGl">
|
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="I1w-05-lGl">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wc3-2K-6CD">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wc3-2K-6CD">
|
||||||
<rect key="frame" x="18" y="433" width="256" height="17"/>
|
<rect key="frame" x="18" y="452" width="256" 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="Color Correction:" id="5Si-hz-EK3">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Color Correction:" id="5Si-hz-EK3">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -76,7 +76,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VEz-N4-uP6">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VEz-N4-uP6">
|
||||||
<rect key="frame" x="30" y="401" width="245" height="26"/>
|
<rect key="frame" x="30" y="420" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="D2J-wV-1vu" id="fNJ-Fi-yOm">
|
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="D2J-wV-1vu" id="fNJ-Fi-yOm">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
@ -97,7 +97,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T69-6N-dhT">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T69-6N-dhT">
|
||||||
<rect key="frame" x="30" y="321" width="245" height="26"/>
|
<rect key="frame" x="30" y="340" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Disabled (Keep DC Offset)" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Fgo-0S-zUG" id="om2-Bn-43B">
|
<popUpButtonCell key="cell" type="push" title="Disabled (Keep DC Offset)" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Fgo-0S-zUG" id="om2-Bn-43B">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
@ -117,7 +117,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7fg-Ww-JjR">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7fg-Ww-JjR">
|
||||||
<rect key="frame" x="30" y="267" width="245" height="26"/>
|
<rect key="frame" x="30" y="286" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="lxQ-4n-kEv" id="lvb-QF-0Ht">
|
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="lxQ-4n-kEv" id="lvb-QF-0Ht">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
@ -141,7 +141,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfj-tg-7OP">
|
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfj-tg-7OP">
|
||||||
<rect key="frame" x="18" y="376" width="256" height="18"/>
|
<rect key="frame" x="18" y="395" width="256" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="check" title="Keep Aspect Ratio" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="lsj-rC-Eo6">
|
<buttonCell key="cell" type="check" title="Keep Aspect Ratio" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="lsj-rC-Eo6">
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
@ -152,7 +152,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Utu-t4-cLx">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Utu-t4-cLx">
|
||||||
<rect key="frame" x="18" y="245" width="256" height="17"/>
|
<rect key="frame" x="18" y="264" width="256" 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="Button configuration:" id="YqW-Ds-VIC">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Button configuration:" id="YqW-Ds-VIC">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -161,7 +161,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WU3-oV-KHO">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WU3-oV-KHO">
|
||||||
<rect key="frame" x="18" y="353" width="256" height="17"/>
|
<rect key="frame" x="18" y="372" width="256" 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="High-pass Filter:" id="YLF-RL-b2D">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="High-pass Filter:" id="YLF-RL-b2D">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -170,7 +170,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="w9w-yX-KxB">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="w9w-yX-KxB">
|
||||||
<rect key="frame" x="18" y="299" width="256" height="17"/>
|
<rect key="frame" x="18" y="318" width="256" 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="Rewinding Duration:" id="JaO-5h-ugl">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Rewinding Duration:" id="JaO-5h-ugl">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -201,14 +201,14 @@
|
|||||||
</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="26" y="45" width="252" height="192"/>
|
<rect key="frame" x="26" y="45" width="252" height="211"/>
|
||||||
<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" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid">
|
||||||
<rect key="frame" x="1" y="1" width="250" height="190"/>
|
<rect key="frame" x="1" y="1" width="250" height="209"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView focusRingType="none" appearanceType="vibrantLight" 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" appearanceType="vibrantLight" 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="250" height="190"/>
|
<rect key="frame" x="0.0" y="0.0" width="250" height="209"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<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"/>
|
||||||
|
@ -359,7 +359,7 @@ void GB_apu_run(GB_gameboy_t *gb)
|
|||||||
|
|
||||||
if (gb->apu_output.sample_rate) {
|
if (gb->apu_output.sample_rate) {
|
||||||
gb->apu_output.cycles_since_render += cycles;
|
gb->apu_output.cycles_since_render += cycles;
|
||||||
double cycles_per_sample = CPU_FREQUENCY / (double)gb->apu_output.sample_rate; // TODO: this should be cached!
|
double cycles_per_sample = GB_get_clock_rate(gb) / (double)gb->apu_output.sample_rate;
|
||||||
|
|
||||||
if (gb->apu_output.sample_cycles > cycles_per_sample) {
|
if (gb->apu_output.sample_cycles > cycles_per_sample) {
|
||||||
gb->apu_output.sample_cycles -= cycles_per_sample;
|
gb->apu_output.sample_cycles -= cycles_per_sample;
|
||||||
@ -837,7 +837,7 @@ void GB_set_sample_rate(GB_gameboy_t *gb, unsigned int sample_rate)
|
|||||||
gb->apu_output.sample_rate = sample_rate;
|
gb->apu_output.sample_rate = sample_rate;
|
||||||
gb->apu_output.buffer_position = 0;
|
gb->apu_output.buffer_position = 0;
|
||||||
if (sample_rate) {
|
if (sample_rate) {
|
||||||
gb->apu_output.highpass_rate = pow(0.999958, CPU_FREQUENCY / (double)sample_rate);
|
gb->apu_output.highpass_rate = pow(0.999958, GB_get_clock_rate(gb) / (double)sample_rate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
Core/gb.c
14
Core/gb.c
@ -100,6 +100,7 @@ void GB_init(GB_gameboy_t *gb)
|
|||||||
gb->async_input_callback = default_async_input_callback;
|
gb->async_input_callback = default_async_input_callback;
|
||||||
#endif
|
#endif
|
||||||
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
||||||
|
gb->clock_multiplier = 1.0;
|
||||||
|
|
||||||
GB_reset(gb);
|
GB_reset(gb);
|
||||||
}
|
}
|
||||||
@ -116,6 +117,7 @@ void GB_init_cgb(GB_gameboy_t *gb)
|
|||||||
gb->async_input_callback = default_async_input_callback;
|
gb->async_input_callback = default_async_input_callback;
|
||||||
#endif
|
#endif
|
||||||
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type
|
||||||
|
gb->clock_multiplier = 1.0;
|
||||||
|
|
||||||
GB_reset(gb);
|
GB_reset(gb);
|
||||||
}
|
}
|
||||||
@ -307,7 +309,7 @@ uint64_t GB_run_frame(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
gb->turbo = old_turbo;
|
gb->turbo = old_turbo;
|
||||||
gb->turbo_dont_skip = old_dont_skip;
|
gb->turbo_dont_skip = old_dont_skip;
|
||||||
return gb->cycles_since_last_sync * FRAME_LENGTH * LCDC_PERIOD;
|
return gb->cycles_since_last_sync * 1000000000LL / GB_get_clock_rate(gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB_set_pixels_output(GB_gameboy_t *gb, uint32_t *output)
|
void GB_set_pixels_output(GB_gameboy_t *gb, uint32_t *output)
|
||||||
@ -580,3 +582,13 @@ void *GB_get_direct_access(GB_gameboy_t *gb, GB_direct_access_t access, size_t *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier)
|
||||||
|
{
|
||||||
|
gb->clock_multiplier = multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GB_get_clock_rate(GB_gameboy_t *gb)
|
||||||
|
{
|
||||||
|
return CPU_FREQUENCY * gb->clock_multiplier;
|
||||||
|
}
|
||||||
|
@ -162,7 +162,6 @@ typedef enum {
|
|||||||
#define CPU_FREQUENCY 0x400000
|
#define CPU_FREQUENCY 0x400000
|
||||||
#define DIV_CYCLES (0x100)
|
#define DIV_CYCLES (0x100)
|
||||||
#define INTERNAL_DIV_CYCLES (0x40000)
|
#define INTERNAL_DIV_CYCLES (0x40000)
|
||||||
#define FRAME_LENGTH (1000000000LL * LCDC_PERIOD / CPU_FREQUENCY) // in nanoseconds
|
|
||||||
|
|
||||||
#if !defined(MIN)
|
#if !defined(MIN)
|
||||||
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
|
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
|
||||||
@ -495,6 +494,7 @@ struct GB_gameboy_internal_s {
|
|||||||
uint8_t boot_rom[0x900];
|
uint8_t boot_rom[0x900];
|
||||||
bool vblank_just_occured; // For slow operations involving syscalls; these should only run once per vblank
|
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()
|
uint8_t cycles_since_run; // How many cycles have passed since the last call to GB_run()
|
||||||
|
double clock_multiplier;
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -583,4 +583,9 @@ void GB_serial_set_data(GB_gameboy_t *gb, uint8_t data);
|
|||||||
|
|
||||||
void GB_disconnect_serial(GB_gameboy_t *gb);
|
void GB_disconnect_serial(GB_gameboy_t *gb);
|
||||||
|
|
||||||
|
#ifdef GB_INTERNAL
|
||||||
|
uint32_t GB_get_clock_rate(GB_gameboy_t *gb);
|
||||||
|
#endif
|
||||||
|
void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier);
|
||||||
|
|
||||||
#endif /* GB_h */
|
#endif /* GB_h */
|
||||||
|
@ -40,7 +40,7 @@ bool GB_timing_sync_turbo(GB_gameboy_t *gb)
|
|||||||
{
|
{
|
||||||
if (!gb->turbo_dont_skip) {
|
if (!gb->turbo_dont_skip) {
|
||||||
int64_t nanoseconds = get_nanoseconds();
|
int64_t nanoseconds = get_nanoseconds();
|
||||||
if (nanoseconds <= gb->last_sync + FRAME_LENGTH) {
|
if (nanoseconds <= gb->last_sync + (1000000000LL * LCDC_PERIOD / GB_get_clock_rate(gb))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
gb->last_sync = nanoseconds;
|
gb->last_sync = nanoseconds;
|
||||||
@ -57,7 +57,7 @@ void GB_timing_sync(GB_gameboy_t *gb)
|
|||||||
/* Prevent syncing if not enough time has passed.*/
|
/* Prevent syncing if not enough time has passed.*/
|
||||||
if (gb->cycles_since_last_sync < LCDC_PERIOD / 4) return;
|
if (gb->cycles_since_last_sync < LCDC_PERIOD / 4) return;
|
||||||
|
|
||||||
uint64_t target_nanoseconds = gb->cycles_since_last_sync * FRAME_LENGTH / LCDC_PERIOD;
|
uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / GB_get_clock_rate(gb);
|
||||||
int64_t nanoseconds = get_nanoseconds();
|
int64_t nanoseconds = get_nanoseconds();
|
||||||
if (labs((signed long)(nanoseconds - gb->last_sync)) < target_nanoseconds ) {
|
if (labs((signed long)(nanoseconds - gb->last_sync)) < target_nanoseconds ) {
|
||||||
nsleep(target_nanoseconds + gb->last_sync - nanoseconds);
|
nsleep(target_nanoseconds + gb->last_sync - nanoseconds);
|
||||||
|
Loading…
Reference in New Issue
Block a user