diff --git a/bsnes/gb/.github/actions/sanity_tests.sh b/bsnes/gb/.github/actions/sanity_tests.sh
index 8984b264..13b5e39b 100755
--- a/bsnes/gb/.github/actions/sanity_tests.sh
+++ b/bsnes/gb/.github/actions/sanity_tests.sh
@@ -1,10 +1,10 @@
set -e
./build/bin/tester/sameboy_tester --jobs 5 \
- --length 40 .github/actions/cgb_sound.gb \
+ --length 45 .github/actions/cgb_sound.gb \
--length 10 .github/actions/cgb-acid2.gbc \
--length 10 .github/actions/dmg-acid2.gb \
---dmg --length 40 .github/actions/dmg_sound-2.gb \
+--dmg --length 45 .github/actions/dmg_sound-2.gb \
--dmg --length 20 .github/actions/oam_bug-2.gb
mv .github/actions/dmg{,-mode}-acid2.bmp
@@ -15,18 +15,18 @@ mv .github/actions/dmg{,-mode}-acid2.bmp
set +e
FAILED_TESTS=`
-shasum .github/actions/*.bmp | grep -q -E -v \(\
-44ce0c7d49254df0637849c9155080ac7dc3ef3d\ \ .github/actions/cgb-acid2.bmp\|\
+shasum .github/actions/*.bmp | grep -E -v \(\
+5283564df0cf5bb78a7a90aff026c1a4692fd39e\ \ .github/actions/cgb-acid2.bmp\|\
dbcc438dcea13b5d1b80c5cd06bda2592cc5d9e0\ \ .github/actions/cgb_sound.bmp\|\
0caadf9634e40247ae9c15ff71992e8f77bbf89e\ \ .github/actions/dmg-acid2.bmp\|\
-c50daed36c57a8170ff362042694786676350997\ \ .github/actions/dmg-mode-acid2.bmp\|\
+a732077f98f43d9231453b1764d9f797a836924d\ \ .github/actions/dmg-mode-acid2.bmp\|\
c9e944b7e01078bdeba1819bc2fa9372b111f52d\ \ .github/actions/dmg_sound-2.bmp\|\
f0172cc91867d3343fbd113a2bb98100074be0de\ \ .github/actions/oam_bug-2.bmp\
\)`
if [ -n "$FAILED_TESTS" ] ; then
echo "Failed the following tests:"
- echo $FAILED_TESTS | tr " " "\n" | grep -q -o -E "[^/]+\.bmp" | sed s/.bmp// | sort
+ echo $FAILED_TESTS | tr " " "\n" | grep -o -E "[^/]+\.bmp" | sed s/.bmp// | sort
exit 1
fi
diff --git a/bsnes/gb/.github/workflows/sanity.yml b/bsnes/gb/.github/workflows/sanity.yml
index f460931b..ac373239 100644
--- a/bsnes/gb/.github/workflows/sanity.yml
+++ b/bsnes/gb/.github/workflows/sanity.yml
@@ -6,7 +6,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [macos-latest, ubuntu-latest, ubuntu-16.04]
+ os: [macos-latest, ubuntu-latest, ubuntu-18.04]
cc: [gcc, clang]
include:
- os: macos-latest
@@ -33,4 +33,4 @@ jobs:
uses: actions/upload-artifact@v1
with:
name: sameboy-canary-${{ matrix.os }}-${{ matrix.cc }}
- path: build/bin
\ No newline at end of file
+ path: build/bin
diff --git a/bsnes/gb/BootROMs/cgb_boot.asm b/bsnes/gb/BootROMs/cgb_boot.asm
index 848305c5..0bc2b179 100644
--- a/bsnes/gb/BootROMs/cgb_boot.asm
+++ b/bsnes/gb/BootROMs/cgb_boot.asm
@@ -25,6 +25,7 @@ Start:
; Init waveform
ld c, $10
+ ld hl, $FF30
.waveformLoop
ldi [hl], a
cpl
@@ -44,7 +45,6 @@ Start:
ldh [$25], a
ld a, $77
ldh [$24], a
- ld hl, $FF30
; Init BG palette
ld a, $fc
@@ -190,10 +190,9 @@ ENDC
IF !DEF(FAST)
call DoIntroAnimation
- ld a, 45
+ ld a, 48 ; frames to wait after playing the chime
ldh [WaitLoopCounter], a
-; Wait ~0.75 seconds
- ld b, a
+ ld b, 4 ; frames to wait before playing the chime
call WaitBFrames
; Play first sound
@@ -1187,7 +1186,7 @@ ChangeAnimationPalette:
call WaitFrame
call LoadPalettesFromHRAM
; Delay the wait loop while the user is selecting a palette
- ld a, 45
+ ld a, 48
ldh [WaitLoopCounter], a
pop de
pop bc
diff --git a/bsnes/gb/Cocoa/AppDelegate.m b/bsnes/gb/Cocoa/AppDelegate.m
index 108a5c89..48514a05 100644
--- a/bsnes/gb/Cocoa/AppDelegate.m
+++ b/bsnes/gb/Cocoa/AppDelegate.m
@@ -86,7 +86,7 @@ static uint32_t color_to_int(NSColor *color)
}
if ([[NSProcessInfo processInfo].arguments containsObject:@"--update-launch"]) {
- [NSApp activateIgnoringOtherApps:YES];
+ [NSApp activateIgnoringOtherApps:true];
}
}
@@ -106,7 +106,7 @@ static uint32_t color_to_int(NSColor *color)
NSRect new = [_preferencesWindow frameRectForContentRect:tab.frame];
new.origin.x = old.origin.x;
new.origin.y = old.origin.y + (old.size.height - new.size.height);
- [_preferencesWindow setFrame:new display:YES animate:_preferencesWindow.visible];
+ [_preferencesWindow setFrame:new display:true animate:_preferencesWindow.visible];
[_preferencesWindow.contentView addSubview:tab];
}
@@ -171,7 +171,7 @@ static uint32_t color_to_int(NSColor *color)
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
- [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:notification.identifier display:YES];
+ [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:notification.identifier display:true];
}
- (void)updateFound
@@ -242,7 +242,7 @@ static uint32_t color_to_int(NSColor *color)
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@UPDATE_SERVER "/latest_version"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.updatesSpinner stopAnimation:nil];
- [self.updatesButton setEnabled:YES];
+ [self.updatesButton setEnabled:true];
});
if ([(NSHTTPURLResponse *)response statusCode] == 200) {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
@@ -312,7 +312,7 @@ static uint32_t color_to_int(NSColor *color)
_downloadDirectory = [[[NSFileManager defaultManager] URLForDirectory:NSItemReplacementDirectory
inDomain:NSUserDomainMask
appropriateForURL:[[NSBundle mainBundle] bundleURL]
- create:YES
+ create:true
error:nil] path];
NSTask *unzipTask;
if (!_downloadDirectory) {
diff --git a/bsnes/gb/Cocoa/Document.m b/bsnes/gb/Cocoa/Document.m
index 64e3a215..2a54a139 100644
--- a/bsnes/gb/Cocoa/Document.m
+++ b/bsnes/gb/Cocoa/Document.m
@@ -321,7 +321,7 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on)
{
if (_gbsVisualizer) {
dispatch_async(dispatch_get_main_queue(), ^{
- [_gbsVisualizer setNeedsDisplay:YES];
+ [_gbsVisualizer setNeedsDisplay:true];
});
}
[self.view flip];
@@ -422,7 +422,7 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on)
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"Mute"]) {
[self.audioClient start];
}
- hex_timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(reloadMemoryView) userInfo:nil repeats:YES];
+ hex_timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(reloadMemoryView) userInfo:nil repeats:true];
[[NSRunLoop mainRunLoop] addTimer:hex_timer forMode:NSDefaultRunLoopMode];
/* Clear pending alarms, don't play alarms while playing */
@@ -502,7 +502,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
[audioLock unlock];
[self.audioClient stop];
self.audioClient = nil;
- self.view.mouseHidingEnabled = NO;
+ self.view.mouseHidingEnabled = false;
GB_save_battery(&gb, [[[self.fileURL URLByDeletingPathExtension] URLByAppendingPathExtension:@"sav"].path UTF8String]);
GB_save_cheats(&gb, [[[self.fileURL URLByDeletingPathExtension] URLByAppendingPathExtension:@"cht"].path UTF8String]);
unsigned time_to_alarm = GB_time_to_alarm(&gb);
@@ -593,12 +593,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
current_model = (enum model)[sender tag];
}
- if (!modelsChanging && [sender tag] == MODEL_NONE) {
- GB_reset(&gb);
- }
- else {
- GB_switch_model_and_reset(&gb, [self internalModel]);
- }
+ GB_switch_model_and_reset(&gb, [self internalModel]);
if (old_width != GB_get_screen_width(&gb)) {
[self.view screenSizeChanged];
@@ -689,13 +684,13 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
window_frame.size.width);
window_frame.size.height = MAX([[NSUserDefaults standardUserDefaults] integerForKey:@"LastWindowHeight"],
window_frame.size.height);
- [self.mainWindow setFrame:window_frame display:YES];
+ [self.mainWindow setFrame:window_frame display:true];
self.vramStatusLabel.cell.backgroundStyle = NSBackgroundStyleRaised;
NSUInteger height_diff = self.vramWindow.frame.size.height - self.vramWindow.contentView.frame.size.height;
CGRect vram_window_rect = self.vramWindow.frame;
vram_window_rect.size.height = 384 + height_diff + 48;
- [self.vramWindow setFrame:vram_window_rect display:YES animate:NO];
+ [self.vramWindow setFrame:vram_window_rect display:true animate:false];
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [self.fileURL.path lastPathComponent]];
@@ -851,7 +846,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
+ (BOOL)autosavesInPlace
{
- return YES;
+ return true;
}
- (NSString *)windowNibName
@@ -863,7 +858,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)type
{
- return YES;
+ return true;
}
- (IBAction)changeGBSTrack:(id)sender
@@ -902,7 +897,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
{
GB_set_rendering_disabled(&gb, true);
_view = nil;
- for (NSView *view in _mainWindow.contentView.subviews) {
+ for (NSView *view in [_mainWindow.contentView.subviews copy]) {
[view removeFromSuperview];
}
[[NSBundle mainBundle] loadNibNamed:@"GBS" owner:self topLevelObjects:nil];
@@ -1066,7 +1061,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
- (void) windowWillExitFullScreen:(NSNotification *)notification
{
fullScreen = false;
- self.view.mouseHidingEnabled = NO;
+ self.view.mouseHidingEnabled = false;
}
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame
@@ -1161,14 +1156,14 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
}
if (![console_output_timer isValid]) {
- console_output_timer = [NSTimer timerWithTimeInterval:(NSTimeInterval)0.05 target:self selector:@selector(appendPendingOutput) userInfo:nil repeats:NO];
+ console_output_timer = [NSTimer timerWithTimeInterval:(NSTimeInterval)0.05 target:self selector:@selector(appendPendingOutput) userInfo:nil repeats:false];
[[NSRunLoop mainRunLoop] addTimer:console_output_timer forMode:NSDefaultRunLoopMode];
}
[console_output_lock unlock];
/* Make sure mouse is not hidden while debugging */
- self.view.mouseHidingEnabled = NO;
+ self.view.mouseHidingEnabled = false;
}
- (IBAction)showConsoleWindow:(id)sender
@@ -1395,7 +1390,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
bitmapInfo,
provider,
NULL,
- YES,
+ true,
renderingIntent);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
@@ -1603,7 +1598,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
}
[self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
[hex_controller reloadData];
- [self.memoryView setNeedsDisplay:YES];
+ [self.memoryView setNeedsDisplay:true];
}
- (GB_gameboy_t *) gameboy
@@ -1613,7 +1608,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
+ (BOOL)canConcurrentlyReadDocumentsOfType:(NSString *)typeName
{
- return YES;
+ return true;
}
- (void)cameraRequestUpdate
@@ -1754,14 +1749,14 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
window_rect.size.height = 512 + height_diff + 48;
break;
case 3:
- window_rect.size.height = 20 * 16 + height_diff + 24;
+ window_rect.size.height = 20 * 16 + height_diff + 34;
break;
default:
break;
}
window_rect.origin.y -= window_rect.size.height;
- [self.vramWindow setFrame:window_rect display:YES animate:YES];
+ [self.vramWindow setFrame:window_rect display:true animate:true];
}
- (void)mouseDidLeaveImageView:(GBImageView *)view
@@ -1856,7 +1851,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
case 0:
return [Document imageFromData:[NSData dataWithBytesNoCopy:oamInfo[row].image
length:64 * 4 * 2
- freeWhenDone:NO]
+ freeWhenDone:false]
width:8
height:oamHeight
scale:16.0/oamHeight];
@@ -1899,7 +1894,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
{
- return NO;
+ return false;
}
- (IBAction)showVRAMViewer:(id)sender
@@ -1929,7 +1924,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
frame.size = self.feedImageView.image.size;
[self.printerFeedWindow setContentMaxSize:frame.size];
frame.size.height += self.printerFeedWindow.frame.size.height - self.printerFeedWindow.contentView.frame.size.height;
- [self.printerFeedWindow setFrame:frame display:NO animate: self.printerFeedWindow.isVisible];
+ [self.printerFeedWindow setFrame:frame display:false animate: self.printerFeedWindow.isVisible];
[self.printerFeedWindow orderFront:NULL];
});
@@ -1960,8 +1955,8 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
[imageRep setSize:(NSSize){160, self.feedImageView.image.size.height / 2}];
NSData *data = [imageRep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
- [data writeToURL:savePanel.URL atomically:NO];
- [self.printerFeedWindow setIsVisible:NO];
+ [data writeToURL:savePanel.URL atomically:false];
+ [self.printerFeedWindow setIsVisible:false];
}
if (shouldResume) {
[self start];
@@ -2082,9 +2077,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
- (BOOL)splitView:(GBSplitView *)splitView canCollapseSubview:(NSView *)subview;
{
if ([[splitView arrangedSubviews] lastObject] == subview) {
- return YES;
+ return true;
}
- return NO;
+ return false;
}
- (CGFloat)splitView:(GBSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex
@@ -2100,9 +2095,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
- (BOOL)splitView:(GBSplitView *)splitView shouldAdjustSizeOfSubview:(NSView *)view
{
if ([[splitView arrangedSubviews] lastObject] == view) {
- return NO;
+ return false;
}
- return YES;
+ return true;
}
- (void)splitViewDidResizeSubviews:(NSNotification *)notification
@@ -2206,4 +2201,115 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
{
return &gb;
}
+
+- (NSImage *)takeScreenshot
+{
+ NSImage *ret = nil;
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBFilterScreenshots"]) {
+ ret = [_view renderToImage];
+ }
+ if (!ret) {
+ ret = [Document imageFromData:[NSData dataWithBytesNoCopy:_view.currentBuffer
+ length:GB_get_screen_width(&gb) * GB_get_screen_height(&gb) * 4
+ freeWhenDone:false]
+ width:GB_get_screen_width(&gb)
+ height:GB_get_screen_height(&gb)
+ scale:1.0];
+ }
+ [ret lockFocus];
+ NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0,
+ ret.size.width, ret.size.height)];
+ [ret unlockFocus];
+ ret = [[NSImage alloc] initWithSize:ret.size];
+ [ret addRepresentation:bitmapRep];
+ return ret;
+}
+
+- (NSString *)screenshotFilename
+{
+ NSDate *date = [NSDate date];
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+ dateFormatter.dateStyle = NSDateFormatterLongStyle;
+ dateFormatter.timeStyle = NSDateFormatterMediumStyle;
+ return [[NSString stringWithFormat:@"%@ – %@.png",
+ self.fileURL.lastPathComponent.stringByDeletingPathExtension,
+ [dateFormatter stringFromDate:date]] stringByReplacingOccurrencesOfString:@":" withString:@"."]; // Gotta love Mac OS Classic
+
+}
+
+- (IBAction)saveScreenshot:(id)sender
+{
+ NSString *folder = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBScreenshotFolder"];
+ BOOL isDirectory = false;
+ if (folder) {
+ [[NSFileManager defaultManager] fileExistsAtPath:folder isDirectory:&isDirectory];
+ }
+ if (!folder) {
+ bool shouldResume = running;
+ [self stop];
+ NSOpenPanel *openPanel = [NSOpenPanel openPanel];
+ openPanel.canChooseFiles = false;
+ openPanel.canChooseDirectories = true;
+ openPanel.message = @"Choose a folder for screenshots";
+ [openPanel beginSheetModalForWindow:self.mainWindow completionHandler:^(NSInteger result) {
+ if (result == NSModalResponseOK) {
+ [[NSUserDefaults standardUserDefaults] setObject:openPanel.URL.path
+ forKey:@"GBScreenshotFolder"];
+ [self saveScreenshot:sender];
+ }
+ if (shouldResume) {
+ [self start];
+ }
+
+ }];
+ return;
+ }
+ NSImage *image = [self takeScreenshot];
+ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
+ dateFormatter.dateStyle = NSDateFormatterLongStyle;
+ dateFormatter.timeStyle = NSDateFormatterMediumStyle;
+ NSString *filename = [self screenshotFilename];
+ filename = [folder stringByAppendingPathComponent:filename];
+ unsigned i = 2;
+ while ([[NSFileManager defaultManager] fileExistsAtPath:filename]) {
+ filename = [[filename stringByDeletingPathExtension] stringByAppendingFormat:@" %d.png", i++];
+ }
+
+ NSBitmapImageRep *imageRep = (NSBitmapImageRep *)image.representations.firstObject;
+ NSData *data = [imageRep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
+ [data writeToFile:filename atomically:false];
+ [self.osdView displayText:@"Screenshot saved"];
+}
+
+- (IBAction)saveScreenshotAs:(id)sender
+{
+ bool shouldResume = running;
+ [self stop];
+ NSImage *image = [self takeScreenshot];
+ NSSavePanel *savePanel = [NSSavePanel savePanel];
+ [savePanel setNameFieldStringValue:[self screenshotFilename]];
+ [savePanel beginSheetModalForWindow:self.mainWindow completionHandler:^(NSInteger result) {
+ if (result == NSModalResponseOK) {
+ [savePanel orderOut:self];
+ NSBitmapImageRep *imageRep = (NSBitmapImageRep *)image.representations.firstObject;
+ NSData *data = [imageRep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
+ [data writeToURL:savePanel.URL atomically:false];
+ [[NSUserDefaults standardUserDefaults] setObject:savePanel.URL.path.stringByDeletingLastPathComponent
+ forKey:@"GBScreenshotFolder"];
+ }
+ if (shouldResume) {
+ [self start];
+ }
+ }];
+ [self.osdView displayText:@"Screenshot saved"];
+}
+
+- (IBAction)copyScreenshot:(id)sender
+{
+ NSImage *image = [self takeScreenshot];
+ [[NSPasteboard generalPasteboard] clearContents];
+ [[NSPasteboard generalPasteboard] writeObjects:@[image]];
+ [self.osdView displayText:@"Screenshot copied"];
+}
+
@end
diff --git a/bsnes/gb/Cocoa/Document.xib b/bsnes/gb/Cocoa/Document.xib
index ec2b4508..c76c148a 100644
--- a/bsnes/gb/Cocoa/Document.xib
+++ b/bsnes/gb/Cocoa/Document.xib
@@ -1004,7 +1004,7 @@
-
+
@@ -1029,7 +1029,7 @@
-
+
diff --git a/bsnes/gb/Cocoa/GBAudioClient.m b/bsnes/gb/Cocoa/GBAudioClient.m
index 7f2115d7..81a51fd5 100644
--- a/bsnes/gb/Cocoa/GBAudioClient.m
+++ b/bsnes/gb/Cocoa/GBAudioClient.m
@@ -90,7 +90,7 @@ static OSStatus render(
{
OSErr err = AudioOutputUnitStart(audioUnit);
NSAssert1(err == noErr, @"Error starting unit: %hd", err);
- _playing = YES;
+ _playing = true;
}
@@ -98,7 +98,7 @@ static OSStatus render(
-(void) stop
{
AudioOutputUnitStop(audioUnit);
- _playing = NO;
+ _playing = false;
}
-(void) dealloc
@@ -108,4 +108,4 @@ static OSStatus render(
AudioComponentInstanceDispose(audioUnit);
}
-@end
\ No newline at end of file
+@end
diff --git a/bsnes/gb/Cocoa/GBBorderView.m b/bsnes/gb/Cocoa/GBBorderView.m
index a5f5e817..d992e298 100644
--- a/bsnes/gb/Cocoa/GBBorderView.m
+++ b/bsnes/gb/Cocoa/GBBorderView.m
@@ -5,12 +5,12 @@
- (void)awakeFromNib
{
- self.wantsLayer = YES;
+ self.wantsLayer = true;
}
- (BOOL)wantsUpdateLayer
{
- return YES;
+ return true;
}
- (void)updateLayer
diff --git a/bsnes/gb/Cocoa/GBCheatTextFieldCell.m b/bsnes/gb/Cocoa/GBCheatTextFieldCell.m
index 611cadeb..1fdafea0 100644
--- a/bsnes/gb/Cocoa/GBCheatTextFieldCell.m
+++ b/bsnes/gb/Cocoa/GBCheatTextFieldCell.m
@@ -114,7 +114,7 @@
return _fieldEditor;
}
_fieldEditor = [[GBCheatTextView alloc] initWithFrame:controlView.frame];
- _fieldEditor.fieldEditor = YES;
+ _fieldEditor.fieldEditor = true;
_fieldEditor.usesAddressFormat = self.usesAddressFormat;
return _fieldEditor;
}
diff --git a/bsnes/gb/Cocoa/GBCheatWindowController.m b/bsnes/gb/Cocoa/GBCheatWindowController.m
index c10e2a94..5cc8f595 100644
--- a/bsnes/gb/Cocoa/GBCheatWindowController.m
+++ b/bsnes/gb/Cocoa/GBCheatWindowController.m
@@ -52,7 +52,7 @@
if (row >= cheatCount) {
switch (columnIndex) {
case 0:
- return @(YES);
+ return @YES;
case 1:
return @NO;
@@ -67,7 +67,7 @@
switch (columnIndex) {
case 0:
- return @(NO);
+ return @NO;
case 1:
return @(cheats[row]->enabled);
diff --git a/bsnes/gb/Cocoa/GBColorCell.m b/bsnes/gb/Cocoa/GBColorCell.m
index 0ad102a6..761ad43b 100644
--- a/bsnes/gb/Cocoa/GBColorCell.m
+++ b/bsnes/gb/Cocoa/GBColorCell.m
@@ -13,13 +13,13 @@ static inline double scale_channel(uint8_t x)
- (void)setObjectValue:(id)objectValue
{
-
_integerValue = [objectValue integerValue];
uint8_t r = _integerValue & 0x1F,
g = (_integerValue >> 5) & 0x1F,
b = (_integerValue >> 10) & 0x1F;
super.objectValue = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"$%04x", (uint16_t)(_integerValue & 0x7FFF)] attributes:@{
- NSForegroundColorAttributeName: r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor]
+ NSForegroundColorAttributeName: r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor],
+ NSFontAttributeName: [NSFont userFixedPitchFontOfSize:12]
}];
}
@@ -36,13 +36,14 @@ static inline double scale_channel(uint8_t x)
- (NSColor *) backgroundColor
{
+ /* Todo: color correction */
uint16_t color = self.integerValue;
return [NSColor colorWithRed:scale_channel(color) green:scale_channel(color >> 5) blue:scale_channel(color >> 10) alpha:1.0];
}
- (BOOL)drawsBackground
{
- return YES;
+ return true;
}
@end
diff --git a/bsnes/gb/Cocoa/GBOpenGLView.m b/bsnes/gb/Cocoa/GBOpenGLView.m
index 90ebf8d5..2e4eb70f 100644
--- a/bsnes/gb/Cocoa/GBOpenGLView.m
+++ b/bsnes/gb/Cocoa/GBOpenGLView.m
@@ -34,6 +34,6 @@
- (void) filterChanged
{
self.shader = nil;
- [self setNeedsDisplay:YES];
+ [self setNeedsDisplay:true];
}
@end
diff --git a/bsnes/gb/Cocoa/GBPreferencesWindow.h b/bsnes/gb/Cocoa/GBPreferencesWindow.h
index 260ebf99..e11c5d3c 100644
--- a/bsnes/gb/Cocoa/GBPreferencesWindow.h
+++ b/bsnes/gb/Cocoa/GBPreferencesWindow.h
@@ -28,4 +28,5 @@
@property (nonatomic, weak) IBOutlet NSButton *autoUpdatesCheckbox;
@property (weak) IBOutlet NSSlider *volumeSlider;
@property (weak) IBOutlet NSButton *OSDCheckbox;
+@property (weak) IBOutlet NSButton *screenshotFilterCheckbox;
@end
diff --git a/bsnes/gb/Cocoa/GBPreferencesWindow.m b/bsnes/gb/Cocoa/GBPreferencesWindow.m
index 47302dd6..60df2dde 100644
--- a/bsnes/gb/Cocoa/GBPreferencesWindow.m
+++ b/bsnes/gb/Cocoa/GBPreferencesWindow.m
@@ -2,6 +2,7 @@
#import "NSString+StringForKey.h"
#import "GBButtons.h"
#import "BigSurToolbar.h"
+#import "GBViewMetal.h"
#import
@implementation GBPreferencesWindow
@@ -32,6 +33,7 @@
NSSlider *_volumeSlider;
NSButton *_autoUpdatesCheckbox;
NSButton *_OSDCheckbox;
+ NSButton *_screenshotFilterCheckbox;
}
+ (NSArray *)filterList
@@ -67,8 +69,8 @@
- (void)close
{
joystick_configuration_state = -1;
- [self.configureJoypadButton setEnabled:YES];
- [self.skipButton setEnabled:NO];
+ [self.configureJoypadButton setEnabled:true];
+ [self.skipButton setEnabled:false];
[self.configureJoypadButton setTitle:@"Configure Controller"];
[super close];
}
@@ -266,12 +268,12 @@
dispatch_async(dispatch_get_main_queue(), ^{
is_button_being_modified = true;
button_being_modified = row;
- tableView.enabled = NO;
- self.playerListButton.enabled = NO;
+ tableView.enabled = false;
+ self.playerListButton.enabled = false;
[tableView reloadData];
[self makeFirstResponder:self];
});
- return NO;
+ return false;
}
-(void)keyDown:(NSEvent *)theEvent
@@ -287,8 +289,8 @@
[[NSUserDefaults standardUserDefaults] setInteger:theEvent.keyCode
forKey:button_to_preference_name(button_being_modified, self.playerListButton.selectedTag)];
- self.controlsTableView.enabled = YES;
- self.playerListButton.enabled = YES;
+ self.controlsTableView.enabled = true;
+ self.playerListButton.enabled = true;
[self.controlsTableView reloadData];
[self makeFirstResponder:self.controlsTableView];
}
@@ -408,8 +410,8 @@
- (IBAction) configureJoypad:(id)sender
{
- [self.configureJoypadButton setEnabled:NO];
- [self.skipButton setEnabled:YES];
+ [self.configureJoypadButton setEnabled:false];
+ [self.skipButton setEnabled:true];
joystick_being_configured = nil;
[self advanceConfigurationStateMachine];
}
@@ -430,8 +432,8 @@
}
else {
joystick_configuration_state = -1;
- [self.configureJoypadButton setEnabled:YES];
- [self.skipButton setEnabled:NO];
+ [self.configureJoypadButton setEnabled:true];
+ [self.skipButton setEnabled:false];
[self.configureJoypadButton setTitle:@"Configure Joypad"];
}
}
@@ -563,8 +565,8 @@
- (IBAction)selectOtherBootROMFolder:(id)sender
{
NSOpenPanel *panel = [[NSOpenPanel alloc] init];
- [panel setCanChooseDirectories:YES];
- [panel setCanChooseFiles:NO];
+ [panel setCanChooseDirectories:true];
+ [panel setCanChooseFiles:false];
[panel setPrompt:@"Select"];
[panel setDirectoryURL:[[NSUserDefaults standardUserDefaults] URLForKey:@"GBBootROMsFolder"]];
[panel beginSheetModalForWindow:self completionHandler:^(NSModalResponse result) {
@@ -588,12 +590,12 @@
[self.bootROMsFolderItem setTitle:[url lastPathComponent]];
NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[url path]];
[icon setSize:NSMakeSize(16, 16)];
- [self.bootROMsFolderItem setHidden:NO];
+ [self.bootROMsFolderItem setHidden:false];
[self.bootROMsFolderItem setImage:icon];
[self.bootROMsButton selectItemAtIndex:1];
}
else {
- [self.bootROMsFolderItem setHidden:YES];
+ [self.bootROMsFolderItem setHidden:true];
[self.bootROMsButton selectItemAtIndex:0];
}
}
@@ -766,4 +768,27 @@
forKey:@"GBOSDEnabled"];
}
+
+- (IBAction)changeFilterScreenshots:(id)sender
+{
+ [[NSUserDefaults standardUserDefaults] setBool:[(NSButton *)sender state] == NSOnState
+ forKey:@"GBFilterScreenshots"];
+}
+
+- (NSButton *)screenshotFilterCheckbox
+{
+ return _screenshotFilterCheckbox;
+}
+
+- (void)setScreenshotFilterCheckbox:(NSButton *)screenshotFilterCheckbox
+{
+ _screenshotFilterCheckbox = screenshotFilterCheckbox;
+ if (![GBViewMetal isSupported]) {
+ [_screenshotFilterCheckbox setEnabled:false];
+ }
+ else {
+ [_screenshotFilterCheckbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBFilterScreenshots"]];
+ }
+}
+
@end
diff --git a/bsnes/gb/Cocoa/GBSplitView.m b/bsnes/gb/Cocoa/GBSplitView.m
index a56c24e6..d24d5806 100644
--- a/bsnes/gb/Cocoa/GBSplitView.m
+++ b/bsnes/gb/Cocoa/GBSplitView.m
@@ -8,7 +8,7 @@
- (void)setDividerColor:(NSColor *)color
{
_dividerColor = color;
- [self setNeedsDisplay:YES];
+ [self setNeedsDisplay:true];
}
- (NSColor *)dividerColor
diff --git a/bsnes/gb/Cocoa/GBTerminalTextFieldCell.m b/bsnes/gb/Cocoa/GBTerminalTextFieldCell.m
index c1ed2036..e1ba9577 100644
--- a/bsnes/gb/Cocoa/GBTerminalTextFieldCell.m
+++ b/bsnes/gb/Cocoa/GBTerminalTextFieldCell.m
@@ -17,7 +17,7 @@
return field_editor;
}
field_editor = [[GBTerminalTextView alloc] init];
- [field_editor setFieldEditor:YES];
+ [field_editor setFieldEditor:true];
field_editor.gb = self.gb;
return field_editor;
}
@@ -109,7 +109,7 @@
[self updateReverseSearch];
}
else {
- [self setNeedsDisplay:YES];
+ [self setNeedsDisplay:true];
reverse_search_mode = true;
}
diff --git a/bsnes/gb/Cocoa/GBView.h b/bsnes/gb/Cocoa/GBView.h
index cd6a539a..01481a7d 100644
--- a/bsnes/gb/Cocoa/GBView.h
+++ b/bsnes/gb/Cocoa/GBView.h
@@ -18,7 +18,7 @@ typedef enum {
@property (nonatomic, weak) IBOutlet Document *document;
@property (nonatomic) GB_gameboy_t *gb;
@property (nonatomic) GB_frame_blending_mode_t frameBlendingMode;
-@property (nonatomic, getter=isMouseHidingEnabled) BOOL mouseHidingEnabled;
+@property (nonatomic, getter=isMouseHidingEnabled) bool mouseHidingEnabled;
@property (nonatomic) bool isRewinding;
@property (nonatomic, strong) NSView *internalView;
@property (weak) GBOSDView *osdView;
@@ -27,4 +27,5 @@ typedef enum {
- (uint32_t *)previousBuffer;
- (void)screenSizeChanged;
- (void)setRumble: (double)amp;
+- (NSImage *)renderToImage;
@end
diff --git a/bsnes/gb/Cocoa/GBView.m b/bsnes/gb/Cocoa/GBView.m
index 1e584e41..6c92c3f0 100644
--- a/bsnes/gb/Cocoa/GBView.m
+++ b/bsnes/gb/Cocoa/GBView.m
@@ -106,9 +106,9 @@ static const uint8_t workboy_vk_to_key[] = {
{
uint32_t *image_buffers[3];
unsigned char current_buffer;
- BOOL mouse_hidden;
+ bool mouse_hidden;
NSTrackingArea *tracking_area;
- BOOL _mouseHidingEnabled;
+ bool _mouseHidingEnabled;
bool axisActive[2];
bool underclockKeyDown;
double clockMultiplier;
@@ -183,7 +183,7 @@ static const uint8_t workboy_vk_to_key[] = {
- (void) setFrameBlendingMode:(GB_frame_blending_mode_t)frameBlendingMode
{
_frameBlendingMode = frameBlendingMode;
- [self setNeedsDisplay:YES];
+ [self setNeedsDisplay:true];
}
@@ -585,7 +585,7 @@ static const uint8_t workboy_vk_to_key[] = {
- (BOOL)acceptsFirstResponder
{
- return YES;
+ return true;
}
- (void)mouseEntered:(NSEvent *)theEvent
@@ -610,7 +610,7 @@ static const uint8_t workboy_vk_to_key[] = {
[super mouseExited:theEvent];
}
-- (void)setMouseHidingEnabled:(BOOL)mouseHidingEnabled
+- (void)setMouseHidingEnabled:(bool)mouseHidingEnabled
{
if (mouseHidingEnabled == _mouseHidingEnabled) return;
@@ -625,7 +625,7 @@ static const uint8_t workboy_vk_to_key[] = {
}
}
-- (BOOL)isMouseHidingEnabled
+- (bool)isMouseHidingEnabled
{
return _mouseHidingEnabled;
}
@@ -658,7 +658,7 @@ static const uint8_t workboy_vk_to_key[] = {
if ( [[pboard types] containsObject:NSURLPboardType] ) {
NSURL *fileURL = [NSURL URLFromPasteboard:pboard];
- if (GB_is_stave_state(fileURL.fileSystemRepresentation)) {
+ if (GB_is_save_state(fileURL.fileSystemRepresentation)) {
return NSDragOperationGeneric;
}
}
@@ -677,4 +677,10 @@ static const uint8_t workboy_vk_to_key[] = {
return false;
}
+- (NSImage *)renderToImage;
+{
+ /* Not going to support this on OpenGL, OpenGL is too much of a terrible API for me
+ to bother figuring out how the hell something so trivial can be done. */
+ return nil;
+}
@end
diff --git a/bsnes/gb/Cocoa/GBViewGL.m b/bsnes/gb/Cocoa/GBViewGL.m
index b80973e4..dda85843 100644
--- a/bsnes/gb/Cocoa/GBViewGL.m
+++ b/bsnes/gb/Cocoa/GBViewGL.m
@@ -19,7 +19,7 @@
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil];
self.internalView = [[GBOpenGLView alloc] initWithFrame:self.frame pixelFormat:pf];
- ((GBOpenGLView *)self.internalView).wantsBestResolutionOpenGLSurface = YES;
+ ((GBOpenGLView *)self.internalView).wantsBestResolutionOpenGLSurface = true;
((GBOpenGLView *)self.internalView).openGLContext = context;
}
@@ -27,8 +27,8 @@
{
[super flip];
dispatch_async(dispatch_get_main_queue(), ^{
- [self.internalView setNeedsDisplay:YES];
- [self setNeedsDisplay:YES];
+ [self.internalView setNeedsDisplay:true];
+ [self setNeedsDisplay:true];
});
}
diff --git a/bsnes/gb/Cocoa/GBViewMetal.m b/bsnes/gb/Cocoa/GBViewMetal.m
index 580db2ca..ae7443f6 100644
--- a/bsnes/gb/Cocoa/GBViewMetal.m
+++ b/bsnes/gb/Cocoa/GBViewMetal.m
@@ -1,3 +1,4 @@
+#import
#import "GBViewMetal.h"
#pragma clang diagnostic ignored "-Wpartial-availability"
@@ -51,8 +52,9 @@ static const vector_float2 rect[] =
MTKView *view = [[MTKView alloc] initWithFrame:self.frame device:(device = MTLCreateSystemDefaultDevice())];
view.delegate = self;
self.internalView = view;
- view.paused = YES;
- view.enableSetNeedsDisplay = YES;
+ view.paused = true;
+ view.enableSetNeedsDisplay = true;
+ view.framebufferOnly = false;
vertices = [device newBufferWithBytes:rect
length:sizeof(rect)
@@ -92,7 +94,7 @@ static const vector_float2 rect[] =
withString:scaler_source];
MTLCompileOptions *options = [[MTLCompileOptions alloc] init];
- options.fastMathEnabled = YES;
+ options.fastMathEnabled = true;
id library = [device newLibraryWithSource:shader_source
options:options
error:&error];
@@ -208,8 +210,23 @@ static const vector_float2 rect[] =
{
[super flip];
dispatch_async(dispatch_get_main_queue(), ^{
- [(MTKView *)self.internalView setNeedsDisplay:YES];
+ [(MTKView *)self.internalView setNeedsDisplay:true];
});
}
+- (NSImage *)renderToImage
+{
+ CIImage *ciImage = [CIImage imageWithMTLTexture:[[(MTKView *)self.internalView currentDrawable] texture]
+ options:@{
+ kCIImageColorSpace: (__bridge_transfer id)CGColorSpaceCreateDeviceRGB()
+ }];
+ ciImage = [ciImage imageByApplyingTransform:CGAffineTransformTranslate(CGAffineTransformMakeScale(1, -1),
+ 0, ciImage.extent.size.height)];
+ CIContext *context = [CIContext context];
+ CGImageRef cgImage = [context createCGImage:ciImage fromRect:ciImage.extent];
+ NSImage *ret = [[NSImage alloc] initWithCGImage:cgImage size:self.internalView.bounds.size];
+ CGImageRelease(cgImage);
+ return ret;
+}
+
@end
diff --git a/bsnes/gb/Cocoa/GBWarningPopover.m b/bsnes/gb/Cocoa/GBWarningPopover.m
index 411e3883..74f6444d 100644
--- a/bsnes/gb/Cocoa/GBWarningPopover.m
+++ b/bsnes/gb/Cocoa/GBWarningPopover.m
@@ -10,7 +10,7 @@ static GBWarningPopover *lastPopover;
lastPopover = [[self alloc] init];
[lastPopover setBehavior:NSPopoverBehaviorApplicationDefined];
- [lastPopover setAnimates:YES];
+ [lastPopover setAnimates:true];
lastPopover.contentViewController = [[NSViewController alloc] initWithNibName:@"PopoverView" bundle:nil];
NSTextField *field = (NSTextField *)lastPopover.contentViewController.view;
[field setStringValue:contents];
@@ -20,7 +20,7 @@ static GBWarningPopover *lastPopover;
[lastPopover setContentSize:textSize];
if (!view.window.isVisible) {
- [view.window setIsVisible:YES];
+ [view.window setIsVisible:true];
}
[lastPopover showRelativeToRect:view.bounds
diff --git a/bsnes/gb/Cocoa/MainMenu.xib b/bsnes/gb/Cocoa/MainMenu.xib
index 04bcf8f8..348e9605 100644
--- a/bsnes/gb/Cocoa/MainMenu.xib
+++ b/bsnes/gb/Cocoa/MainMenu.xib
@@ -316,6 +316,23 @@
+
+
+
+
-
+
@@ -650,8 +662,8 @@
-
-
+
+
@@ -659,8 +671,8 @@
-
-
+
+
@@ -675,8 +687,8 @@
-
-
+
+
@@ -707,8 +719,8 @@
-
-
+
+
@@ -725,8 +737,8 @@
-
+
-
+
-
-
+
+