Update the Cocoa debugger interface with buttons, add an interrupt command
After Width: | Height: | Size: 197 B |
After Width: | Height: | Size: 314 B |
|
@ -4,6 +4,8 @@
|
|||
#import "GBSplitView.h"
|
||||
#import "GBVisualizerView.h"
|
||||
#import "GBOSDView.h"
|
||||
#import "GBOptionalVisualEffectView.h"
|
||||
#import "GBDebuggerButton.h"
|
||||
|
||||
@class GBCheatWindowController;
|
||||
@class GBPaletteView;
|
||||
|
@ -58,6 +60,13 @@
|
|||
@property uint8_t oamHeight;
|
||||
@property (strong) IBOutlet NSView *audioRecordingAccessoryView;
|
||||
@property (strong) IBOutlet NSPopUpButton *audioFormatButton;
|
||||
@property (strong) IBOutlet GBOptionalVisualEffectView *debuggerSidebarEffectView;
|
||||
|
||||
@property (strong) IBOutlet GBDebuggerButton *debuggerContinueButton;
|
||||
@property (strong) IBOutlet GBDebuggerButton *debuggerNextButton;
|
||||
@property (strong) IBOutlet GBDebuggerButton *debuggerStepButton;
|
||||
@property (strong) IBOutlet GBDebuggerButton *debuggerFinishButton;
|
||||
|
||||
|
||||
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale;
|
||||
-(uint8_t) readMemory:(uint16_t) addr;
|
||||
|
|
112
Cocoa/Document.m
|
@ -74,7 +74,7 @@ enum model {
|
|||
|
||||
bool fullScreen;
|
||||
bool in_sync_input;
|
||||
bool _debuggerCommandWhilePaused;
|
||||
NSString *_debuggerCommandWhilePaused;
|
||||
HFController *hex_controller;
|
||||
|
||||
NSString *lastConsoleInput;
|
||||
|
@ -549,6 +549,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
|
||||
- (void) start
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateDebuggerButtons];
|
||||
[slave updateDebuggerButtons];
|
||||
});
|
||||
self.gbsPlayPauseButton.state = true;
|
||||
self.view.mouseHidingEnabled = (self.mainWindow.styleMask & NSWindowStyleMaskFullScreen) != 0;
|
||||
if (master) {
|
||||
|
@ -562,6 +566,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
|
||||
- (void) stop
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateDebuggerButtons];
|
||||
[slave updateDebuggerButtons];
|
||||
});
|
||||
self.gbsPlayPauseButton.state = false;
|
||||
if (master) {
|
||||
if (!master->running) return;
|
||||
|
@ -1151,16 +1159,21 @@ static bool is_path_writeable(const char *path)
|
|||
[[NSUserDefaults standardUserDefaults] setBool:!_audioClient.isPlaying forKey:@"Mute"];
|
||||
}
|
||||
|
||||
- (bool) isPaused
|
||||
{
|
||||
if (self.partner) {
|
||||
return !self.partner->running || GB_debugger_is_stopped(&gb) || GB_debugger_is_stopped(&self.partner->gb);
|
||||
}
|
||||
return (!running) || GB_debugger_is_stopped(&gb);
|
||||
}
|
||||
|
||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem
|
||||
{
|
||||
if ([anItem action] == @selector(mute:)) {
|
||||
[(NSMenuItem *)anItem setState:!_audioClient.isPlaying];
|
||||
}
|
||||
else if ([anItem action] == @selector(togglePause:)) {
|
||||
if (master) {
|
||||
[(NSMenuItem *)anItem setState:(!master->running) || (GB_debugger_is_stopped(&gb)) || (GB_debugger_is_stopped(&gb))];
|
||||
}
|
||||
[(NSMenuItem *)anItem setState:(!running) || (GB_debugger_is_stopped(&gb))];
|
||||
[(NSMenuItem *)anItem setState:self.isPaused];
|
||||
return !GB_debugger_is_stopped(&gb);
|
||||
}
|
||||
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE) {
|
||||
|
@ -1322,15 +1335,27 @@ static bool is_path_writeable(const char *path)
|
|||
[self.consoleWindow orderBack:nil];
|
||||
}
|
||||
|
||||
- (IBAction)consoleInput:(NSTextField *)sender
|
||||
- (void)queueDebuggerCommand:(NSString *)command
|
||||
{
|
||||
if (!master && !running && !GB_debugger_is_stopped(&gb)) {
|
||||
_debuggerCommandWhilePaused = true;
|
||||
_debuggerCommandWhilePaused = command;
|
||||
GB_debugger_break(&gb);
|
||||
[self start];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!in_sync_input) {
|
||||
[self log:">"];
|
||||
}
|
||||
[self log:[command UTF8String]];
|
||||
[self log:"\n"];
|
||||
[has_debugger_input lock];
|
||||
[debugger_input_queue addObject:command];
|
||||
[has_debugger_input unlockWithCondition:1];
|
||||
}
|
||||
|
||||
- (IBAction)consoleInput:(NSTextField *)sender
|
||||
{
|
||||
NSString *line = [sender stringValue];
|
||||
if ([line isEqualToString:@""] && lastConsoleInput) {
|
||||
line = lastConsoleInput;
|
||||
|
@ -1341,15 +1366,8 @@ static bool is_path_writeable(const char *path)
|
|||
else {
|
||||
line = @"";
|
||||
}
|
||||
|
||||
if (!in_sync_input) {
|
||||
[self log:">"];
|
||||
}
|
||||
[self log:[line UTF8String]];
|
||||
[self log:"\n"];
|
||||
[has_debugger_input lock];
|
||||
[debugger_input_queue addObject:line];
|
||||
[has_debugger_input unlockWithCondition:1];
|
||||
|
||||
[self queueDebuggerCommand: line];
|
||||
|
||||
[sender setStringValue:@""];
|
||||
}
|
||||
|
@ -1397,7 +1415,7 @@ static bool is_path_writeable(const char *path)
|
|||
[console_output_lock unlock];
|
||||
}
|
||||
|
||||
- (char *) getDebuggerInput
|
||||
- (char *)getDebuggerInput
|
||||
{
|
||||
bool isPlaying = _audioClient.isPlaying;
|
||||
if (isPlaying) {
|
||||
|
@ -1408,11 +1426,16 @@ static bool is_path_writeable(const char *path)
|
|||
[audioLock unlock];
|
||||
in_sync_input = true;
|
||||
[self updateSideView];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self updateDebuggerButtons];
|
||||
});
|
||||
[self.partner updateDebuggerButtons];
|
||||
[self log:">"];
|
||||
if (_debuggerCommandWhilePaused) {
|
||||
_debuggerCommandWhilePaused = false;
|
||||
NSString *command = _debuggerCommandWhilePaused;
|
||||
_debuggerCommandWhilePaused = nil;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self consoleInput:self.consoleInput];
|
||||
[self queueDebuggerCommand:command];
|
||||
});
|
||||
}
|
||||
[has_debugger_input lockWhenCondition:1];
|
||||
|
@ -1426,6 +1449,8 @@ static bool is_path_writeable(const char *path)
|
|||
shouldClearSideView = false;
|
||||
[self.debuggerSideView setString:@""];
|
||||
}
|
||||
[self updateDebuggerButtons];
|
||||
[self.partner updateDebuggerButtons];
|
||||
});
|
||||
if (isPlaying) {
|
||||
[_audioClient start];
|
||||
|
@ -2231,7 +2256,7 @@ static bool is_path_writeable(const char *path)
|
|||
/* NSSplitView renders its separator without the proper vibrancy, so we made it transparent and move an
|
||||
NSBox-based separator that renders properly so it acts like the split view's separator. */
|
||||
NSRect rect = self.debuggerVerticalLine.frame;
|
||||
rect.origin.x = [[[splitview arrangedSubviews] firstObject] frame].size.width - 1;
|
||||
rect.origin.x = [[[splitview arrangedSubviews] firstObject] frame].size.width - 2;
|
||||
self.debuggerVerticalLine.frame = rect;
|
||||
}
|
||||
|
||||
|
@ -2573,4 +2598,49 @@ static bool is_path_writeable(const char *path)
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)updateDebuggerButtons
|
||||
{
|
||||
bool updateContinue = false;
|
||||
if (@available(macOS 10.10, *)) {
|
||||
if ([self.consoleInput.placeholderAttributedString.string isEqualToString:self.debuggerContinueButton.alternateTitle]) {
|
||||
[self.debuggerContinueButton mouseExited:nil];
|
||||
updateContinue = true;
|
||||
}
|
||||
}
|
||||
if (self.isPaused) {
|
||||
self.debuggerContinueButton.toolTip = self.debuggerContinueButton.title = @"Continue";
|
||||
self.debuggerContinueButton.alternateTitle = @"continue";
|
||||
self.debuggerContinueButton.imagePosition = NSImageOnly;
|
||||
if (@available(macOS 10.14, *)) {
|
||||
self.debuggerContinueButton.contentTintColor = nil;
|
||||
}
|
||||
self.debuggerContinueButton.image = [NSImage imageNamed:@"ContinueTemplate"];
|
||||
|
||||
self.debuggerNextButton.enabled = true;
|
||||
self.debuggerStepButton.enabled = true;
|
||||
self.debuggerFinishButton.enabled = true;
|
||||
}
|
||||
else {
|
||||
self.debuggerContinueButton.toolTip = self.debuggerContinueButton.title = @"Interrupt";
|
||||
self.debuggerContinueButton.alternateTitle = @"interrupt";
|
||||
self.debuggerContinueButton.imagePosition = NSImageOnly;
|
||||
if (@available(macOS 10.14, *)) {
|
||||
self.debuggerContinueButton.contentTintColor = [NSColor controlAccentColor];
|
||||
}
|
||||
self.debuggerContinueButton.image = [NSImage imageNamed:@"InterruptTemplate"];
|
||||
|
||||
self.debuggerNextButton.enabled = false;
|
||||
self.debuggerStepButton.enabled = false;
|
||||
self.debuggerFinishButton.enabled = false;
|
||||
}
|
||||
if (updateContinue) {
|
||||
[self.debuggerContinueButton mouseEntered:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)debuggerButtonPressed:(NSButton *)sender
|
||||
{
|
||||
[self queueDebuggerCommand:sender.alternateTitle];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
|
||||
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -14,9 +15,14 @@
|
|||
<outlet property="consoleInput" destination="l22-S8-uji" id="Heu-am-YgB"/>
|
||||
<outlet property="consoleOutput" destination="doS-dM-hnl" id="Gn5-ju-Wb0"/>
|
||||
<outlet property="consoleWindow" destination="21F-Ah-yHX" id="eQ4-ug-LsT"/>
|
||||
<outlet property="debuggerContinueButton" destination="G4h-KO-Z3g" id="Dad-5e-XYM"/>
|
||||
<outlet property="debuggerFinishButton" destination="vtb-n5-Qlz" id="9vv-fJ-gxp"/>
|
||||
<outlet property="debuggerNextButton" destination="cOi-Rs-9gS" id="Xjx-uM-D0u"/>
|
||||
<outlet property="debuggerSideView" destination="JgV-7E-iwp" id="RaA-fw-3i1"/>
|
||||
<outlet property="debuggerSideViewInput" destination="w0g-eK-jM4" id="GBf-WK-ryI"/>
|
||||
<outlet property="debuggerSidebarEffectView" destination="4Z2-33-dYY" id="Ja6-bC-rQg"/>
|
||||
<outlet property="debuggerSplitView" destination="pUc-ZN-vl5" id="0sG-0D-cID"/>
|
||||
<outlet property="debuggerStepButton" destination="DsN-Ce-QoH" id="Ts4-uK-pvI"/>
|
||||
<outlet property="debuggerVerticalLine" destination="7bR-gM-1At" id="rfy-7Z-388"/>
|
||||
<outlet property="feedImageView" destination="Ar0-nN-eop" id="wHa-St-o4G"/>
|
||||
<outlet property="gridButton" destination="fL6-2S-Rgd" id="jtV-jh-GHC"/>
|
||||
|
@ -87,50 +93,31 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="921" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="l22-S8-uji">
|
||||
<rect key="frame" x="0.0" y="0.0" width="921" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" id="p3j-nS-44f" customClass="GBTerminalTextFieldCell">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" red="0.16470588235294117" green="0.16470588235294117" blue="0.16470588235294117" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<allowedInputSourceLocales>
|
||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||
</allowedInputSourceLocales>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="consoleInput:" target="-2" id="ylQ-vw-ARS"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="960-dL-7ZY">
|
||||
<rect key="frame" x="0.0" y="23" width="921" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box horizontalHuggingPriority="750" boxType="separator" id="7bR-gM-1At">
|
||||
<rect key="frame" x="590" y="25" width="5" height="376"/>
|
||||
<rect key="frame" x="590" y="0.0" width="5" height="401"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
</box>
|
||||
<splitView dividerStyle="thin" vertical="YES" id="pUc-ZN-vl5" customClass="GBSplitView">
|
||||
<rect key="frame" x="0.0" y="25" width="921" height="376"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="921" height="401"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<customView fixedFrame="YES" id="2rj-7i-kxc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="376"/>
|
||||
<customView fixedFrame="YES" id="2rj-7i-kxc" customClass="GBOptionalVisualEffectView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="401"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oTo-zx-o6N">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="376"/>
|
||||
<rect key="frame" x="0.0" y="52" width="591" height="349"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="EQe-Ad-L7S">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="376"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="349"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView ambiguous="YES" editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" id="doS-dM-hnl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="376"/>
|
||||
<textView ambiguous="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" id="doS-dM-hnl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="591" height="349"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.14901960784313725" green="0.14901960784313725" blue="0.14901960784313725" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<size key="minSize" width="591" height="376"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.25" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<size key="minSize" width="591" height="349"/>
|
||||
<size key="maxSize" width="1160" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<allowedInputSourceLocales>
|
||||
|
@ -138,29 +125,112 @@
|
|||
</allowedInputSourceLocales>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.16470588235294117" green="0.16470588235294117" blue="0.16470588235294117" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="3fZ-tl-Zi7">
|
||||
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="cwi-6E-rbh">
|
||||
<rect key="frame" x="575" y="0.0" width="16" height="376"/>
|
||||
<rect key="frame" x="575" y="0.0" width="16" height="349"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" mirrorLayoutDirectionWhenInternationalizing="never" id="l22-S8-uji">
|
||||
<rect key="frame" x="0.0" y="0.0" width="593" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" drawsBackground="YES" id="p3j-nS-44f" customClass="GBTerminalTextFieldCell">
|
||||
<font key="font" metaFont="fixedUser" size="11"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.25" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||
<allowedInputSourceLocales>
|
||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||
</allowedInputSourceLocales>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="consoleInput:" target="-2" id="ylQ-vw-ARS"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="xJr-K6-B4B">
|
||||
<rect key="frame" x="0.0" y="49" width="591" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="9DF-fj-a2v">
|
||||
<rect key="frame" x="0.0" y="24" width="591" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G4h-KO-Z3g" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="0.0" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" title="Interrupt" alternateTitle="interrupt" bezelStyle="rounded" image="InterruptTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="wfO-32-eG5">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="controlAccentColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="SjG-90-8dJ"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="NZ8-eJ-Uyd"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cOi-Rs-9gS" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="26" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" title="Step Over" alternateTitle="next" bezelStyle="rounded" image="NextTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="buW-ke-lgF">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="g7E-UM-SHV"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="1uM-AA-yHi"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DsN-Ce-QoH" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="52" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" title="Step Into" alternateTitle="step" bezelStyle="rounded" image="StepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="ATJ-Vx-zbo">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="QMw-82-HKJ"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="qaF-TF-cwg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vtb-n5-Qlz" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="76" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" title="Step Out" alternateTitle="finish" bezelStyle="rounded" image="FinishTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="8mF-ii-5Hx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="krr-9m-Jfz"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="uYK-tU-BnO"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oCa-UH-1mi" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="565" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" title="Help" alternateTitle="help" bezelStyle="rounded" image="HelpTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="tvn-kY-8FO">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="PwN-rf-AcB"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="blK-B3-MWI"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</customView>
|
||||
<customView fixedFrame="YES" id="4Z2-33-dYY">
|
||||
<rect key="frame" x="592" y="0.0" width="329" height="376"/>
|
||||
<customView fixedFrame="YES" id="4Z2-33-dYY" customClass="GBOptionalVisualEffectView">
|
||||
<rect key="frame" x="592" y="0.0" width="329" height="401"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" scrollerKnobStyle="dark" translatesAutoresizingMaskIntoConstraints="NO" id="V9U-Ua-F4z">
|
||||
<rect key="frame" x="0.0" y="329" width="329" height="47"/>
|
||||
<rect key="frame" x="0.0" y="354" width="329" height="47"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="YHx-TM-zIC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="47"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView ambiguous="YES" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" allowsUndo="YES" allowsNonContiguousLayout="YES" textCompletion="NO" spellingCorrection="YES" id="w0g-eK-jM4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="47"/>
|
||||
|
@ -186,22 +256,22 @@
|
|||
</scroller>
|
||||
</scrollView>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5qI-qZ-nkh">
|
||||
<rect key="frame" x="0.0" y="327" width="327" height="5"/>
|
||||
<rect key="frame" x="0.0" y="352" width="329" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vts-CC-ZjQ">
|
||||
<rect key="frame" x="0.0" y="2" width="329" height="328"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="Cs9-3x-ATg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="328"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView ambiguous="YES" editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" spellingCorrection="YES" id="JgV-7E-iwp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="328"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" red="0.14901960780000001" green="0.14901960780000001" blue="0.14901960780000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<size key="minSize" width="329" height="328"/>
|
||||
<size key="minSize" width="329" height="354"/>
|
||||
<size key="maxSize" width="1160" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<allowedInputSourceLocales>
|
||||
|
@ -216,7 +286,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="4jm-Gm-D2R">
|
||||
<rect key="frame" x="313" y="0.0" width="16" height="328"/>
|
||||
<rect key="frame" x="313" y="0.0" width="16" height="354"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
|
@ -778,7 +848,7 @@
|
|||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="mzf-yu-RID">
|
||||
<rect key="frame" x="1" y="0.0" width="398" height="274"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" headerView="pvX-uJ-qK5" id="tA3-8T-bxb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="398" height="257"/>
|
||||
|
@ -877,7 +947,12 @@
|
|||
</customObject>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="FinishTemplate" width="14" height="14"/>
|
||||
<image name="HelpTemplate" width="14" height="14"/>
|
||||
<image name="InterruptTemplate" width="14" height="14"/>
|
||||
<image name="NSFolder" width="32" height="32"/>
|
||||
<image name="NSStopProgressFreestandingTemplate" width="14" height="14"/>
|
||||
<image name="NextTemplate" width="14" height="14"/>
|
||||
<image name="StepTemplate" width="14" height="14"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
After Width: | Height: | Size: 166 B |
After Width: | Height: | Size: 298 B |
|
@ -0,0 +1,7 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class GBDocument;
|
||||
@interface GBDebuggerButton : NSButton
|
||||
@property (weak) IBOutlet NSTextField *textField;
|
||||
@end
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#import "GBDebuggerButton.h"
|
||||
|
||||
@implementation GBDebuggerButton
|
||||
{
|
||||
NSTrackingArea *_trackingArea;
|
||||
}
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder
|
||||
{
|
||||
self = [super initWithCoder:coder];
|
||||
self.toolTip = self.title;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)event
|
||||
{
|
||||
if (@available(macOS 10.10, *)) {
|
||||
NSDictionary *attributes = @{
|
||||
NSForegroundColorAttributeName: [NSColor colorWithWhite:1.0 alpha:0.5],
|
||||
NSFontAttributeName: self.textField.font
|
||||
};
|
||||
self.textField.placeholderAttributedString =
|
||||
[[NSAttributedString alloc] initWithString:self.alternateTitle attributes:attributes];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)event
|
||||
{
|
||||
if (@available(macOS 10.10, *)) {
|
||||
if ([self.textField.placeholderAttributedString.string isEqualToString:self.alternateTitle]) {
|
||||
self.textField.placeholderAttributedString = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)updateTrackingAreas
|
||||
{
|
||||
[super updateTrackingAreas];
|
||||
if (_trackingArea) {
|
||||
[self removeTrackingArea:_trackingArea];
|
||||
}
|
||||
|
||||
_trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:_trackingArea];
|
||||
}
|
||||
@end
|
|
@ -1,7 +1,11 @@
|
|||
#import <Carbon/Carbon.h>
|
||||
#import "GBTerminalTextFieldCell.h"
|
||||
#import "NSTextFieldCell+Inset.h"
|
||||
|
||||
@interface GBTerminalTextView : NSTextView
|
||||
{
|
||||
@public __weak NSTextField *_field;
|
||||
}
|
||||
@property GB_gameboy_t *gb;
|
||||
@end
|
||||
|
||||
|
@ -10,7 +14,7 @@
|
|||
GBTerminalTextView *field_editor;
|
||||
}
|
||||
|
||||
- (NSTextView *)fieldEditorForView:(NSView *)controlView
|
||||
- (NSTextView *)fieldEditorForView:(NSTextField *)controlView
|
||||
{
|
||||
if (field_editor) {
|
||||
field_editor.gb = self.gb;
|
||||
|
@ -19,6 +23,10 @@
|
|||
field_editor = [[GBTerminalTextView alloc] init];
|
||||
[field_editor setFieldEditor:true];
|
||||
field_editor.gb = self.gb;
|
||||
field_editor->_field = (NSTextField *)controlView;
|
||||
((NSTextFieldCell *)controlView.cell).textInset =
|
||||
field_editor.textContainerInset =
|
||||
NSMakeSize(0, 2);
|
||||
return field_editor;
|
||||
}
|
||||
|
||||
|
@ -185,14 +193,21 @@
|
|||
return [super resignFirstResponder];
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)dirtyRect
|
||||
- (NSColor *)backgroundColor
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[super drawRect:dirtyRect];
|
||||
if (reverse_search_mode && [super string].length == 0) {
|
||||
NSMutableDictionary *attributes = [self.typingAttributes mutableCopy];
|
||||
NSColor *color = [attributes[NSForegroundColorAttributeName] colorWithAlphaComponent:0.5];
|
||||
[attributes setObject:color forKey:NSForegroundColorAttributeName];
|
||||
[[[NSAttributedString alloc] initWithString:@"Reverse search..." attributes:attributes] drawAtPoint:NSMakePoint(2, 0)];
|
||||
[[[NSAttributedString alloc] initWithString:@"Reverse search..." attributes:attributes] drawAtPoint:NSMakePoint(2, 2)];
|
||||
}
|
||||
else {
|
||||
[super drawRect:dirtyRect];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
After Width: | Height: | Size: 183 B |
After Width: | Height: | Size: 323 B |
After Width: | Height: | Size: 93 B |
After Width: | Height: | Size: 118 B |
|
@ -0,0 +1,6 @@
|
|||
#import <AppKit/AppKit.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface NSTextFieldCell (Inset)
|
||||
@property NSSize textInset;
|
||||
@end
|
|
@ -0,0 +1,39 @@
|
|||
#import "NSTextFieldCell+Inset.h"
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@interface NSTextFieldCell ()
|
||||
- (CGRect)_textLayerDrawingRectForCellFrame:(CGRect)rect;
|
||||
@property NSSize textInset;
|
||||
@end
|
||||
|
||||
@implementation NSTextFieldCell (Inset)
|
||||
|
||||
- (void)setTextInset:(NSSize)textInset
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(textInset), @(textInset), OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
- (NSSize)textInset
|
||||
{
|
||||
return [objc_getAssociatedObject(self, _cmd) sizeValue];
|
||||
}
|
||||
|
||||
- (CGRect)_textLayerDrawingRectForCellFrameHook:(CGRect)rect
|
||||
{
|
||||
CGRect ret = [self _textLayerDrawingRectForCellFrameHook:rect];
|
||||
NSSize inset = self.textInset;
|
||||
ret.origin.x += inset.width;
|
||||
ret.origin.y += inset.height;
|
||||
ret.size.width -= inset.width;
|
||||
ret.size.height -= inset.height;
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
method_exchangeImplementations(class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrame:)),
|
||||
class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrameHook:)));
|
||||
}
|
||||
|
||||
@end
|
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 309 B |
After Width: | Height: | Size: 130 B |
After Width: | Height: | Size: 255 B |
|
@ -710,7 +710,7 @@ static const char *lstrip(const char *str)
|
|||
|
||||
#define STOPPED_ONLY \
|
||||
if (!gb->debug_stopped) { \
|
||||
GB_log(gb, "Program is running. \n"); \
|
||||
GB_log(gb, "Program is running, use 'interrupt' to stop execution.\n"); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
|
@ -749,6 +749,24 @@ static bool cont(GB_gameboy_t *gb, char *arguments, char *modifiers, const debug
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool interrupt(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugger_command_t *command)
|
||||
{
|
||||
NO_MODIFIERS
|
||||
|
||||
if (strlen(lstrip(arguments))) {
|
||||
print_usage(gb, command);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gb->debug_stopped) {
|
||||
GB_log(gb, "Program already stopped.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
gb->debug_stopped = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool next(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugger_command_t *command)
|
||||
{
|
||||
NO_MODIFIERS
|
||||
|
@ -1966,6 +1984,7 @@ static bool help(GB_gameboy_t *gb, char *arguments, char *modifiers, const debug
|
|||
/* Commands without implementations are aliases of the previous non-alias commands */
|
||||
static const debugger_command_t commands[] = {
|
||||
{"continue", 1, cont, "Continue running until next stop"},
|
||||
{"interrupt", 1, interrupt, "Interrupt the program execution"},
|
||||
{"next", 1, next, "Run the next instruction, skipping over function calls"},
|
||||
{"step", 1, step, "Run the next instruction, stepping into function calls"},
|
||||
{"finish", 1, finish, "Run until the current function returns"},
|
||||
|
|