Compare commits

..

1 Commits

Author SHA1 Message Date
Libretro Updater 9916fbdd88 Update libretro branch to v1.0.1 2025-04-04 21:30:59 +00:00
138 changed files with 946 additions and 2580 deletions

View File

@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, ubuntu-22.04]
os: [macos-latest, ubuntu-latest, ubuntu-20.04]
cc: [gcc, clang]
include:
- os: macos-latest

182
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,182 @@
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
##############################################################################
################################# BOILERPLATE ################################
##############################################################################
# Core definitions
.core-defs:
variables:
JNI_PATH: libretro
MAKEFILE_PATH: libretro
CORENAME: sameboy
before_script:
- export BOOTROMS_DIR=$(pwd)/BootROMs/prebuilt
# Inclusion templates, required for the build to work
include:
################################## DESKTOPS ################################
# Windows 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-x64-mingw.yml'
# Windows 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-i686-mingw.yml'
# Linux 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-x64.yml'
# Linux 32-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-i686.yml'
# MacOS 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-x64.yml'
# MacOS ARM 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/osx-arm64.yml'
################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/android-jni.yml'
# iOS
- project: 'libretro-infrastructure/ci-templates'
file: '/ios-arm64.yml'
# iOS (armv7)
- project: 'libretro-infrastructure/ci-templates'
file: '/ios9.yml'
################################## CONSOLES ################################
# Nintendo WiiU
- project: 'libretro-infrastructure/ci-templates'
file: '/wiiu-static.yml'
# Nintendo Switch
- project: 'libretro-infrastructure/ci-templates'
file: '/libnx-static.yml'
# PlayStation Vita
- project: 'libretro-infrastructure/ci-templates'
file: '/vita-static.yml'
# tvOS (AppleTV)
- project: 'libretro-infrastructure/ci-templates'
file: '/tvos-arm64.yml'
#################################### MISC ##################################
# Stages for building
stages:
- build-prepare
- build-shared
- build-static
##############################################################################
#################################### STAGES ##################################
##############################################################################
#
################################### DESKTOPS #################################
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-windows-x64-mingw-make-default
- .core-defs
# Windows 32-bit
libretro-build-windows-i686:
extends:
- .libretro-windows-i686-mingw-make-default
- .core-defs
# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-linux-x64-make-default
- .core-defs
# Linux 32-bit
libretro-build-linux-i686:
extends:
- .libretro-linux-i686-make-default
- .core-defs
# MacOS 64-bit
libretro-build-osx-x64:
extends:
- .libretro-osx-x64-make-10-7
- .core-defs
# MacOS ARM 64-bit
libretro-build-osx-arm64:
extends:
- .libretro-osx-arm64-make-default
- .core-defs
################################### CELLULAR #################################
# Android ARMv7a
android-armeabi-v7a:
extends:
- .libretro-android-jni-armeabi-v7a
- .core-defs
# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-android-jni-arm64-v8a
- .core-defs
# Android 64-bit x86
android-x86_64:
extends:
- .libretro-android-jni-x86_64
- .core-defs
# Android 32-bit x86
android-x86:
extends:
- .libretro-android-jni-x86
- .core-defs
# iOS
libretro-build-ios-arm64:
extends:
- .libretro-ios-arm64-make-default
- .core-defs
# iOS (armv7) [iOS 9 and up]
libretro-build-ios9:
extends:
- .libretro-ios9-make-default
- .core-defs
# tvOS
libretro-build-tvos-arm64:
extends:
- .libretro-tvos-arm64-make-default
- .core-defs
################################### CONSOLES #################################
# Nintendo WiiU
libretro-build-wiiu:
extends:
- .libretro-wiiu-static-retroarch-master
- .core-defs
# Nintendo Switch
libretro-build-libnx-aarch64:
extends:
- .libretro-libnx-static-retroarch-master
- .core-defs
# PlayStation Vita
libretro-build-vita:
extends:
- .libretro-vita-static-retroarch-master
- .core-defs

View File

@ -22,9 +22,9 @@ BESS works by appending a detectable footer at the end of an existing save state
BESS uses a block format where each block contains the following header:
| Offset | Content |
|--------|-----------------------------------------------------------|
| 0 | A four-letter ASCII identifier |
| 4 | Length of the block as a 32-bit integer, excluding header |
|--------|---------------------------------------|
| 0 | A four-letter ASCII identifier |
| 4 | Length of the block, excluding header |
Every block is followed by another block, until the END block is reached. If an implementation encounters an unsupported block, it should be completely ignored (Should not have any effect and should not trigger a failure).
@ -256,4 +256,4 @@ Other than previously specified required fail conditions, an implementation is f
* An invalid length of MBC (not a multiple of 3)
* A write outside the $0000-$7FFF and $A000-$BFFF ranges in the MBC block
* An SGB block on a save state targeting another model
* An END block with non-zero length
* An END block with non-zero length

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 584 B

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -103,7 +103,7 @@
</tableHeaderView>
</scrollView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KdM-lW-WbP">
<rect key="frame" x="371" y="24" width="96" height="32"/>
<rect key="frame" x="371" y="25" width="96" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="push" title="Search" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="t4Y-Ud-mJm">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -113,30 +113,30 @@
<action selector="search:" target="-2" id="7pG-JY-vEF"/>
</connections>
</button>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fTv-nr-5FT">
<rect key="frame" x="6" y="95" width="124" height="17"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fTv-nr-5FT">
<rect key="frame" x="6" y="96" width="124" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" alignment="right" title="Search Condition:" id="9C2-Xp-JIA">
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Search Condition:" id="9C2-Xp-JIA">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vMd-zb-8jT">
<rect key="frame" x="6" y="64" width="124" height="17"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vMd-zb-8jT">
<rect key="frame" x="6" y="67" width="124" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" alignment="right" title="Expression:" id="Jgg-sA-jjs">
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Expression:" id="Jgg-sA-jjs">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Db-vP-S60">
<rect key="frame" x="133" y="120" width="197" height="25"/>
<rect key="frame" x="133" y="119" width="197" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<popUpButtonCell key="cell" type="push" title="8-Bit" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="al4-Jb-OJB" id="dkg-V5-wsX">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="e5r-qR-pg7">
<items>
<menuItem title="8-Bit" state="on" id="al4-Jb-OJB"/>
@ -151,7 +151,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<popUpButtonCell key="cell" type="push" title="Is Equal To…" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Vfb-Dg-Jkb" id="DPm-QO-c64">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="Kg9-Rd-1GQ">
<items>
<menuItem title="Any" id="cEg-eI-4hb"/>
@ -173,7 +173,7 @@
<action selector="conditionChanged:" target="-2" id="KF9-vz-yNC"/>
</connections>
</popUpButton>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Q42-Vu-TJW">
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Q42-Vu-TJW">
<rect key="frame" x="334" y="93" width="126" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" continuous="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="$0" drawsBackground="YES" usesSingleLineMode="YES" id="WDs-GG-7Lc">
@ -189,8 +189,8 @@
<outlet property="delegate" destination="-2" id="1bO-hp-igc"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XN7-BO-THS">
<rect key="frame" x="136" y="62" width="324" height="21"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XN7-BO-THS">
<rect key="frame" x="136" y="64" width="324" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" enabled="NO" sendsActionOnEndEditing="YES" borderStyle="bezel" title="new == ($0)" drawsBackground="YES" usesSingleLineMode="YES" id="Krh-8w-4ug">
<font key="font" metaFont="system"/>
@ -205,7 +205,7 @@
</connections>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tBa-6c-9AY">
<rect key="frame" x="13" y="24" width="96" height="32"/>
<rect key="frame" x="13" y="25" width="96" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pge-SU-Y1n">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -215,7 +215,7 @@
<action selector="reset:" target="-2" id="KCy-Ob-tlg"/>
</connections>
</button>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wbN-MX-lEy">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wbN-MX-lEy">
<rect key="frame" x="-3" y="4" width="486" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Status" id="CM3-4U-qao">
@ -225,7 +225,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="o1I-5D-V4k">
<rect key="frame" x="264" y="24" width="110" height="32"/>
<rect key="frame" x="264" y="25" width="110" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="push" title="Add Cheat" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GGV-nm-ASn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -235,10 +235,10 @@
<action selector="addCheat:" target="-2" id="7ax-kM-TeV"/>
</connections>
</button>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="veO-Qn-0Sz">
<rect key="frame" x="6" y="126" width="124" height="17"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="veO-Qn-0Sz">
<rect key="frame" x="6" y="126" width="124" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Data Type:" id="KuT-rz-eHm">
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Data Type:" id="KuT-rz-eHm">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 433 B

View File

@ -3,7 +3,6 @@
#import "GBImageView.h"
#import "GBSplitView.h"
#import "GBVisualizerView.h"
#import "GBCPUView.h"
#import "GBOSDView.h"
#import "GBDebuggerButton.h"
@ -85,8 +84,6 @@ enum model {
@property IBOutlet NSScrollView *debuggerScrollView;
@property IBOutlet NSView *debugBar;
@property IBOutlet GBCPUView *cpuView;
@property IBOutlet NSTextField *cpuCounter;
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale;
- (void) performAtomicBlock: (void (^)())block;

View File

@ -288,7 +288,6 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
GB_set_user_data(&_gb, (__bridge void *)(self));
GB_set_boot_rom_load_callback(&_gb, (GB_boot_rom_load_callback_t)boot_rom_load);
GB_set_vblank_callback(&_gb, (GB_vblank_callback_t) vblank);
GB_set_enable_skipped_frame_vblank_callbacks(&_gb, true);
GB_set_log_callback(&_gb, (GB_log_callback_t) consoleLog);
GB_set_input_callback(&_gb, (GB_input_callback_t) consoleInput);
GB_set_async_input_callback(&_gb, (GB_input_callback_t) asyncConsoleInput);
@ -346,12 +345,6 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
[self observeStandardDefaultsKey:@"GBDebuggerFontSize" withBlock:^(NSString *value) {
[weakSelf updateFonts];
}];
[self observeStandardDefaultsKey:@"GBTurboCap" withBlock:^(NSNumber *value) {
if (!_master) {
GB_set_turbo_cap(gb, value.doubleValue);
}
}];
}
- (void)updateMinSize
@ -366,29 +359,11 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
- (void)vblankWithType:(GB_vblank_type_t)type
{
if (type == GB_VBLANK_TYPE_SKIPPED_FRAME) {
double frameUsage = GB_debugger_get_frame_cpu_usage(&_gb);
[_cpuView addSample:frameUsage];
return;
}
if (_gbsVisualizer) {
dispatch_async(dispatch_get_main_queue(), ^{
[_gbsVisualizer setNeedsDisplay:true];
});
}
double frameUsage = GB_debugger_get_frame_cpu_usage(&_gb);
[_cpuView addSample:frameUsage];
if (self.consoleWindow.visible) {
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
dispatch_async(dispatch_get_main_queue(), ^{
[_cpuView setNeedsDisplay:true];
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
});
}
if (type != GB_VBLANK_TYPE_REPEAT) {
[self.view flip];
if (_borderModeChanged) {
@ -755,12 +730,11 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
if (old_width != GB_get_screen_width(&_gb)) {
[self.view screenSizeChanged];
}
[self updateMinSize];
[self start];
if (_gbsTracks) {
[self changeGBSTrack:sender];
}
if (_hexController) {
/* Verify bank sanity, especially when switching models. */
@ -885,7 +859,7 @@ again:;
{
[super windowControllerDidLoadNib:aController];
// Interface Builder bug?
[self.consoleWindow setContentSize:self.consoleWindow.frame.size];
[self.consoleWindow setContentSize:self.consoleWindow.minSize];
/* Close Open Panels, if any */
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
if ([window isKindOfClass:[NSOpenPanel class]]) {
@ -923,16 +897,9 @@ again:;
[self.vramWindow setFrame:vram_window_rect display:true animate:false];
if (@available(macOS 11.0, *)) {
self.consoleWindow.subtitle = [self.fileURL.path lastPathComponent];
self.memoryWindow.subtitle = [self.fileURL.path lastPathComponent];
self.vramWindow.subtitle = [self.fileURL.path lastPathComponent];
}
else {
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console %@", [self.fileURL.path lastPathComponent]];
self.memoryWindow.title = [NSString stringWithFormat:@"Memory %@", [self.fileURL.path lastPathComponent]];
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer %@", [self.fileURL.path lastPathComponent]];
}
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console %@", [self.fileURL.path lastPathComponent]];
self.memoryWindow.title = [NSString stringWithFormat:@"Memory %@", [self.fileURL.path lastPathComponent]];
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer %@", [self.fileURL.path lastPathComponent]];
self.consoleWindow.level = NSNormalWindowLevel;
@ -1185,17 +1152,6 @@ again:;
if (@available(macOS 10.10, *)) {
_mainWindow.titlebarAppearsTransparent = true;
}
if (@available(macOS 26.0, *)) {
// There's a new minimum width for segmented controls in Solarium
NSRect frame = _gbsNextPrevButton.frame;
frame.origin.x -= 16;
_gbsNextPrevButton.frame = frame;
frame = _gbsTracks.frame;
frame.size.width -= 16;
_gbsTracks.frame = frame;
}
}
- (bool)isCartContainer
@ -1360,7 +1316,6 @@ static bool is_path_writeable(const char *path)
[self.vramWindow close];
[self.printerFeedWindow close];
[self.cheatsWindow close];
[_cheatSearchController.window close];
[super close];
}
@ -1370,8 +1325,6 @@ static bool is_path_writeable(const char *path)
GB_debugger_break(&_gb);
[self start];
[self.consoleWindow makeKeyAndOrderFront:nil];
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
[self.consoleInput becomeFirstResponder];
}
@ -1453,9 +1406,6 @@ static bool is_path_writeable(const char *path)
else if ([anItem action] == @selector(decreaseWindowSize:)) {
return [self newRect:NULL forWindow:_mainWindow action:GBWindowResizeActionDecrease];
}
else if ([anItem action] == @selector(reloadROM:)) {
return !_gbsTracks;
}
return [super validateUserInterfaceItem:anItem];
}
@ -1597,9 +1547,7 @@ enum GBWindowResizeAction
[self reloadVRAMData: nil];
[textView.textStorage appendAttributedString:_pendingConsoleOutput];
if (!_logToSideView) {
[textView scrollToEndOfDocument:nil];
}
[textView scrollToEndOfDocument:nil];
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
[self.consoleWindow orderFront:nil];
}
@ -1657,9 +1605,7 @@ enum GBWindowResizeAction
- (IBAction)showConsoleWindow:(id)sender
{
[self.consoleWindow orderFront:nil];
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
[self.consoleWindow orderBack:nil];
}
- (void)queueDebuggerCommand:(NSString *)command
@ -2009,130 +1955,124 @@ enum GBWindowResizeAction
- (IBAction)hexGoTo:(id)sender
{
NSString *expression = [sender stringValue];
__block uint16_t addr = 0;
__block uint16_t bank = 0;
__block bool fail = false;
NSString *error = [self captureOutputForBlock:^{
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
fail = true;
uint16_t addr;
uint16_t bank;
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
return;
}
}];
if (error) {
NSBeep();
[GBWarningPopover popoverWithContents:error onView:sender];
}
if (fail) return;
if (bank != (typeof(bank))-1) {
GB_memory_mode_t mode = [(GBMemoryByteArray *)(_hexController.byteArray) mode];
if (addr < 0x4000) {
if (bank == 0) {
if (mode != GBMemoryROM && mode != GBMemoryEntireSpace) {
if (bank != (typeof(bank))-1) {
GB_memory_mode_t mode = [(GBMemoryByteArray *)(_hexController.byteArray) mode];
if (addr < 0x4000) {
if (bank == 0) {
if (mode != GBMemoryROM && mode != GBMemoryEntireSpace) {
mode = GBMemoryEntireSpace;
}
}
else {
addr |= 0x4000;
mode = GBMemoryROM;
}
}
else if (addr < 0x8000) {
mode = GBMemoryROM;
}
else if (addr < 0xA000) {
mode = GBMemoryVRAM;
}
else if (addr < 0xC000) {
mode = GBMemoryExternalRAM;
}
else if (addr < 0xD000) {
if (mode != GBMemoryRAM && mode != GBMemoryEntireSpace) {
mode = GBMemoryEntireSpace;
}
}
else {
addr |= 0x4000;
mode = GBMemoryROM;
else if (addr < 0xE000) {
mode = GBMemoryRAM;
}
}
else if (addr < 0x8000) {
mode = GBMemoryROM;
}
else if (addr < 0xA000) {
mode = GBMemoryVRAM;
}
else if (addr < 0xC000) {
mode = GBMemoryExternalRAM;
}
else if (addr < 0xD000) {
if (mode != GBMemoryRAM && mode != GBMemoryEntireSpace) {
else {
mode = GBMemoryEntireSpace;
}
[_memorySpaceButton selectItemAtIndex:mode];
[self hexUpdateSpace:_memorySpaceButton.cell];
[_memoryBankInput setStringValue:[NSString stringWithFormat:@"$%02x", bank]];
[self hexUpdateBank:_memoryBankInput];
}
else if (addr < 0xE000) {
mode = GBMemoryRAM;
}
else {
mode = GBMemoryEntireSpace;
}
[_memorySpaceButton selectItemAtIndex:mode];
[self hexUpdateSpace:_memorySpaceButton.cell];
[_memoryBankInput setStringValue:[NSString stringWithFormat:@"$%02x", bank]];
[self hexUpdateBank:_memoryBankInput];
}
addr -= _lineRep.valueOffset;
if (addr >= _hexController.byteArray.length) {
GB_log(&_gb, "Value $%04x is out of range.\n", addr);
return;
}
[_hexController setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(addr, 0)]]];
[_hexController _ensureVisibilityOfLocation:addr];
for (HFRepresenter *representer in _hexController.representers) {
if ([representer isKindOfClass:[HFHexTextRepresenter class]]) {
[self.memoryWindow makeFirstResponder:representer.view];
break;
addr -= _lineRep.valueOffset;
if (addr >= _hexController.byteArray.length) {
GB_log(&_gb, "Value $%04x is out of range.\n", addr);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[_hexController setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(addr, 0)]]];
[_hexController _ensureVisibilityOfLocation:addr];
for (HFRepresenter *representer in _hexController.representers) {
if ([representer isKindOfClass:[HFHexTextRepresenter class]]) {
[self.memoryWindow makeFirstResponder:representer.view];
break;
}
}
});
}];
if (error) {
NSBeep();
[GBWarningPopover popoverWithContents:error onView:sender];
}
}
- (void)hexUpdateBank:(NSControl *)sender ignoreErrors: (bool)ignore_errors
{
NSString *expression = [sender stringValue];
__block uint16_t addr, bank;
__block bool fail = false;
NSString *error = [self captureOutputForBlock:^{
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
fail = true;
uint16_t addr, bank;
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
return;
}
if (bank == (uint16_t) -1) {
bank = addr;
}
uint16_t n_banks = 1;
switch ([(GBMemoryByteArray *)(_hexController.byteArray) mode]) {
case GBMemoryROM: {
size_t rom_size;
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, &rom_size, NULL);
n_banks = rom_size / 0x4000;
break;
}
case GBMemoryVRAM:
n_banks = GB_is_cgb(&_gb) ? 2 : 1;
break;
case GBMemoryExternalRAM: {
size_t ram_size;
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_CART_RAM, &ram_size, NULL);
n_banks = (ram_size + 0x1FFF) / 0x2000;
break;
}
case GBMemoryRAM:
n_banks = GB_is_cgb(&_gb) ? 8 : 1;
break;
case GBMemoryEntireSpace:
break;
}
bank %= n_banks;
[sender setStringValue:[NSString stringWithFormat:@"$%x", bank]];
[(GBMemoryByteArray *)(_hexController.byteArray) setSelectedBank:bank];
_statusRep.bankForDescription = bank;
dispatch_async(dispatch_get_main_queue(), ^{
[_hexController reloadData];
});
}];
if (error && !ignore_errors) {
NSBeep();
[GBWarningPopover popoverWithContents:error onView:sender];
}
if (fail) return;
if (bank == (uint16_t) -1) {
bank = addr;
}
uint16_t n_banks = 1;
switch ([(GBMemoryByteArray *)(_hexController.byteArray) mode]) {
case GBMemoryROM: {
size_t rom_size;
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, &rom_size, NULL);
n_banks = rom_size / 0x4000;
break;
}
case GBMemoryVRAM:
n_banks = GB_is_cgb(&_gb) ? 2 : 1;
break;
case GBMemoryExternalRAM: {
size_t ram_size;
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_CART_RAM, &ram_size, NULL);
n_banks = (ram_size + 0x1FFF) / 0x2000;
break;
}
case GBMemoryRAM:
n_banks = GB_is_cgb(&_gb) ? 8 : 1;
break;
case GBMemoryEntireSpace:
break;
}
bank %= n_banks;
[(GBMemoryByteArray *)(_hexController.byteArray) setSelectedBank:bank];
_statusRep.bankForDescription = bank;
[sender setStringValue:[NSString stringWithFormat:@"$%x", bank]];
[_hexController reloadData];
}
- (IBAction)hexUpdateBank:(NSControl *)sender
@ -2170,8 +2110,9 @@ enum GBWindowResizeAction
}
byteArray.selectedBank = bank;
_statusRep.bankForDescription = bank;
[self.memoryBankInput setStringValue:(bank == (uint16_t)-1)? @"" :
[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
if (bank != (uint16_t)-1) {
[self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
}
[_hexController reloadData];
for (NSView *view in self.memoryView.subviews) {
@ -2511,16 +2452,9 @@ enum GBWindowResizeAction
- (void)setFileURL:(NSURL *)fileURL
{
[super setFileURL:fileURL];
if (@available(macOS 11.0, *)) {
self.consoleWindow.subtitle = [self.fileURL.path lastPathComponent];
self.memoryWindow.subtitle = [self.fileURL.path lastPathComponent];
self.vramWindow.subtitle = [self.fileURL.path lastPathComponent];
}
else {
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console %@", [self.fileURL.path lastPathComponent]];
self.memoryWindow.title = [NSString stringWithFormat:@"Memory %@", [self.fileURL.path lastPathComponent]];
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer %@", [self.fileURL.path lastPathComponent]];
}
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console %@", [[fileURL path] lastPathComponent]];
self.memoryWindow.title = [NSString stringWithFormat:@"Memory %@", [[fileURL path] lastPathComponent]];
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer %@", [[fileURL path] lastPathComponent]];
}
- (BOOL)splitView:(GBSplitView *)splitView canCollapseSubview:(NSView *)subview;
@ -2592,8 +2526,6 @@ enum GBWindowResizeAction
}
GB_set_turbo_mode(&_gb, false, false);
GB_set_turbo_mode(&partner->_gb, false, false);
GB_set_turbo_cap(&_gb, [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"]);
GB_set_turbo_cap(&partner->_gb, [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"]);
}
}
@ -2609,7 +2541,6 @@ enum GBWindowResizeAction
GB_set_turbo_mode(&partner->_gb, true, true);
_slave = partner;
partner->_master = self;
GB_set_turbo_cap(&partner->_gb, 0);
_linkOffset = 0;
GB_set_serial_transfer_bit_start_callback(&_gb, _linkCableBitStart);
GB_set_serial_transfer_bit_start_callback(&partner->_gb, _linkCableBitStart);

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
<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>
@ -15,8 +15,6 @@
<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="cpuCounter" destination="xdx-GC-Tb8" id="oSn-U3-qvg"/>
<outlet property="cpuView" destination="aBf-yU-8M0" id="RIb-Fj-lvt"/>
<outlet property="debugBar" destination="sah-kv-6KJ" id="24d-aM-rs5"/>
<outlet property="debuggerBackstepButton" destination="E87-Uq-f2l" id="PI7-Wu-f0v"/>
<outlet property="debuggerContinueButton" destination="ybQ-jy-NgI" id="fRF-S3-xSh"/>
@ -56,7 +54,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="xOd-HO-29H" userLabel="Window" customClass="GBWindow">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="xOd-HO-29H" userLabel="Window">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="160" height="144"/>
@ -93,38 +91,38 @@
<window title="Debug Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="21F-Ah-yHX" customClass="GBPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" utility="YES" HUD="YES"/>
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="921" height="480"/>
<rect key="contentRect" x="0.0" y="0.0" width="921" height="400"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<value key="minSize" type="size" width="921" height="400"/>
<view key="contentView" id="dCP-E5-7Fi" customClass="GBOptionalVisualEffectView">
<rect key="frame" x="0.0" y="0.0" width="921" height="480"/>
<rect key="frame" x="0.0" y="0.0" width="921" height="400"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<box horizontalHuggingPriority="750" boxType="separator" id="7bR-gM-1At">
<rect key="frame" x="590" y="0.0" width="5" height="481"/>
<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="0.0" width="921" height="481"/>
<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="481"/>
<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="52" width="591" height="429"/>
<rect key="frame" x="0.0" y="52" width="591" height="349"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="EQe-Ad-L7S">
<rect key="frame" x="0.0" y="0.0" width="591" height="429"/>
<rect key="frame" x="0.0" y="0.0" width="591" height="349"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView 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="429"/>
<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.0" green="0.0" blue="0.0" alpha="0.25" colorSpace="custom" customColorSpace="sRGB"/>
<size key="minSize" width="591" height="429"/>
<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,7 +136,7 @@
<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="429"/>
<rect key="frame" x="575" y="0.0" width="16" height="349"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
@ -162,7 +160,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ybQ-jy-NgI" customClass="GBDebuggerButton">
<rect key="frame" x="4" y="0.0" width="26" height="26"/>
<rect key="frame" x="0.0" y="0.0" 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="Yd7-kY-21r">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -175,7 +173,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jdD-yP-Nr6" customClass="GBDebuggerButton">
<rect key="frame" x="80" y="0.0" width="26" height="26"/>
<rect key="frame" x="76" y="0.0" 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="16t-ix-lOh">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -187,7 +185,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tTP-Zs-Ohu" customClass="GBDebuggerButton">
<rect key="frame" x="30" y="0.0" width="26" height="26"/>
<rect key="frame" x="26" y="0.0" 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="835-qy-CNq">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -199,7 +197,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E87-Uq-f2l" customClass="GBDebuggerButton">
<rect key="frame" x="104" y="0.0" width="26" height="26"/>
<rect key="frame" x="100" y="0.0" width="26" height="26"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<buttonCell key="cell" type="bevel" title="Step Backward" alternateTitle="backstep" bezelStyle="rounded" image="BackstepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="yr5-aU-Fli">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -211,7 +209,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fsQ-dD-A8C" customClass="GBDebuggerButton">
<rect key="frame" x="56" y="0.0" width="26" height="26"/>
<rect key="frame" x="52" y="0.0" 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="lau-41-TYH">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -231,7 +229,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</box>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Jt-TO-8CM" customClass="GBDebuggerButton">
<rect key="frame" x="561" y="0.0" width="26" height="26"/>
<rect key="frame" x="565" y="0.0" 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="fVh-bT-eYs">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -247,11 +245,11 @@
</subviews>
</customView>
<customView fixedFrame="YES" id="4Z2-33-dYY" customClass="GBOptionalVisualEffectView">
<rect key="frame" x="592" y="0.0" width="329" height="481"/>
<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="418" width="329" height="63"/>
<rect key="frame" x="0.0" y="338" width="329" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="YHx-TM-zIC">
<rect key="frame" x="0.0" y="0.0" width="329" height="63"/>
@ -281,22 +279,22 @@
</scroller>
</scrollView>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5qI-qZ-nkh">
<rect key="frame" x="0.0" y="415" width="329" height="5"/>
<rect key="frame" x="0.0" y="336" 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="78" width="329" height="339"/>
<rect key="frame" x="0.0" y="0.0" width="329" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="Cs9-3x-ATg">
<rect key="frame" x="0.0" y="0.0" width="329" height="339"/>
<rect key="frame" x="0.0" y="0.0" width="329" height="338"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView 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="339"/>
<rect key="frame" x="0.0" y="0.0" width="329" height="338"/>
<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="339"/>
<size key="minSize" width="329" height="338"/>
<size key="maxSize" width="1160" height="10000000"/>
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
@ -311,38 +309,10 @@
<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="339"/>
<rect key="frame" x="313" y="0.0" width="16" height="338"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="wC1-WG-WRf">
<rect key="frame" x="0.0" y="75" width="329" height="5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</box>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aBf-yU-8M0" customClass="GBCPUView">
<rect key="frame" x="0.0" y="0.0" width="329" height="77"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F9b-AT-CdX">
<rect key="frame" x="2" y="59" width="100" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="CPU Load" id="ai6-8E-Let">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xdx-GC-Tb8">
<rect key="frame" x="2" y="2" width="100" height="16"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="100%" id="set-AM-fVX">
<font key="font" metaFont="smallSystemBold"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</customView>
</subviews>
</customView>
</subviews>
@ -370,20 +340,20 @@
<rect key="frame" x="0.0" y="0.0" width="528" height="320"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<toolbar key="toolbar" implicitIdentifier="D857E961-E523-4295-83F8-0849316E827C" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconAndLabel" sizeMode="regular" id="82v-uB-RPi">
<toolbar key="toolbar" implicitIdentifier="D857E961-E523-4295-83F8-0849316E827C" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="regular" id="82v-uB-RPi">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="WUk-8p-S6B"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="E3z-um-6KG"/>
<toolbarItem implicitItemIdentifier="4F6AAE25-1E9D-4111-9E5B-91F0792E56CD" label="Address Space" paletteLabel="Address Space" id="VTy-lj-K0H">
<nil key="toolTip"/>
<size key="minSize" width="160" height="25"/>
<size key="maxSize" width="160" height="25"/>
<size key="minSize" width="100" height="25"/>
<size key="maxSize" width="130" height="25"/>
<popUpButton key="view" verticalHuggingPriority="750" id="vfJ-vu-gqJ">
<rect key="frame" x="0.0" y="14" width="160" height="25"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bpD-j9-omo" customClass="GBToolbarPopUpButtonCell">
<rect key="frame" x="0.0" y="14" width="128" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bpD-j9-omo">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="gTX-6Z-mOH">
<items>
<menuItem title="Entire Space" id="Zp5-J9-dd3"/>
@ -402,29 +372,31 @@
<toolbarItem implicitItemIdentifier="D16C64D2-2F0D-4033-A1EC-A1E699522ECE" label="Bank" paletteLabel="Bank" id="bWC-FW-IYP">
<nil key="toolTip"/>
<size key="minSize" width="64" height="22"/>
<size key="maxSize" width="80" height="22"/>
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="rdV-q6-hc6">
<size key="maxSize" width="64" height="22"/>
<textField key="view" verticalHuggingPriority="750" id="rdV-q6-hc6">
<rect key="frame" x="0.0" y="14" width="64" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" placeholderString="Bank" id="JCn-Y1-eHS" customClass="GBToolbarFieldCell">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" id="JCn-Y1-eHS">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="hexUpdateBank:" target="-2" id="Mx9-WI-wgO"/>
</connections>
</textField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="F9723DA8-D79F-43AB-876B-783DD0204AA6" label="Go To" paletteLabel="Go To" id="rLO-D7-zRG">
<toolbarItem implicitItemIdentifier="F9723DA8-D79F-43AB-876B-783DD0204AA6" label="Go to" paletteLabel="Go to" id="rLO-D7-zRG">
<nil key="toolTip"/>
<size key="minSize" width="160" height="22"/>
<size key="maxSize" width="160" height="22"/>
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="EJd-jG-hmH">
<rect key="frame" x="0.0" y="14" width="160" height="22"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" placeholderString="Address" bezelStyle="round" id="vg5-Nn-abb" customClass="GBToolbarFieldCell">
<size key="minSize" width="96" height="22"/>
<size key="maxSize" width="128" height="22"/>
<textField key="view" verticalHuggingPriority="750" id="EJd-jG-hmH">
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" bezelStyle="round" id="vg5-Nn-abb">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="hexGoTo:" target="-2" id="7WG-8C-SK8"/>
@ -450,7 +422,7 @@
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="512" height="432"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<view key="contentView" misplaced="YES" id="GYW-dv-Um1">
<view key="contentView" id="GYW-dv-Um1">
<rect key="frame" x="0.0" y="0.0" width="512" height="432"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -458,7 +430,7 @@
<rect key="frame" x="0.0" y="406" width="512" height="5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</box>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6vK-IP-PmP">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6vK-IP-PmP">
<rect key="frame" x="-2" y="4" width="516" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="umk-4r-VNg">
@ -591,7 +563,7 @@
</connections>
</popUpButton>
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YIJ-Qc-SIZ">
<rect key="frame" x="135" y="412" width="100" height="17"/>
<rect key="frame" x="135" y="412" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundRect" title="Effective Tilemap" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="XRF-Vj-3gs" id="3W1-Db-wDn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -609,7 +581,7 @@
</connections>
</popUpButton>
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="k4c-Vg-MBu">
<rect key="frame" x="239" y="412" width="100" height="17"/>
<rect key="frame" x="235" y="412" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundRect" title="Effective Tileset" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="CRe-dX-rzY" id="h53-sb-Odg">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -677,19 +649,21 @@
</tabView>
</subviews>
</view>
<toolbar key="toolbar" implicitIdentifier="7FF8B5E5-F61B-408C-9634-A5D496FE5E70" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconOnly" sizeMode="regular" id="SVR-To-n7n">
<toolbar key="toolbar" implicitIdentifier="7FF8B5E5-F61B-408C-9634-A5D496FE5E70" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="regular" id="SVR-To-n7n">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="hnI-48-dYt"/>
<toolbarItem implicitItemIdentifier="B9D3CF98-8020-4389-9372-F99361440794" label="" paletteLabel="" sizingBehavior="auto" id="fmK-Jl-Koj">
<toolbarItem implicitItemIdentifier="B9D3CF98-8020-4389-9372-F99361440794" label="" paletteLabel="" id="fmK-Jl-Koj">
<nil key="toolTip"/>
<size key="minSize" width="100" height="25"/>
<size key="maxSize" width="268" height="25"/>
<segmentedControl key="view" verticalHuggingPriority="750" id="Aul-vO-dCK">
<rect key="frame" x="0.0" y="14" width="268" height="25"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="HhR-ky-5NN">
<font key="font" metaFont="system"/>
<segments>
<segment label="Tileset" selected="YES"/>
<segment label="Tilemap"/>
<segment label="Tilemap" tag="1"/>
<segment label="Objects"/>
<segment label="Palettes"/>
</segments>
@ -712,7 +686,7 @@
</connections>
<point key="canvasLocation" x="182" y="760"/>
</window>
<window title="Printer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="NdE-0B-WCf" customClass="GBPanel">
<window title="Printer Feed" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="NdE-0B-WCf" customClass="GBPanel">
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="320" height="288"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
@ -728,7 +702,7 @@
</imageView>
</subviews>
</view>
<toolbar key="toolbar" implicitIdentifier="1FF86A2B-6637-4EE6-A25A-7298D79AE84E" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconAndLabel" sizeMode="regular" id="gH3-SH-7il">
<toolbar key="toolbar" implicitIdentifier="1FF86A2B-6637-4EE6-A25A-7298D79AE84E" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="regular" id="gH3-SH-7il">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="15EB8D49-8C6E-42F2-9F7F-F7D7A0BBDAAF" label="Save" paletteLabel="Save" tag="-1" image="NSFolder" id="CBz-1N-o0Q">
<size key="minSize" width="22" height="22"/>
@ -780,7 +754,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" id="mzf-yu-RID">
<rect key="frame" x="1" y="1" width="604" height="257"/>
<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" rowHeight="24" headerView="pvX-uJ-qK5" id="tA3-8T-bxb">
<rect key="frame" x="0.0" y="0.0" width="604" height="240"/>
@ -860,8 +834,8 @@
<rect key="frame" x="-1" y="0.0" width="308" height="135"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="hqi-ob-NW9">
<rect key="frame" x="20" y="52" width="176" height="18"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="hqi-ob-NW9">
<rect key="frame" x="20" y="51" width="176" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="To value:" id="Ycx-oE-aA4">
<font key="font" metaFont="system"/>
@ -870,7 +844,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kq8-6F-9GK">
<rect key="frame" x="42" y="22" width="152" height="18"/>
<rect key="frame" x="42" y="21" width="152" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<buttonCell key="cell" type="check" title="Only if old value was: " bezelStyle="regularSquare" imagePosition="left" alignment="right" state="on" inset="2" id="LkB-WQ-9Qd">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
@ -880,8 +854,8 @@
<action selector="updateCheat:" target="v7q-gT-jHT" id="kNc-cj-bmF"/>
</connections>
</button>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C6E-oI-hDC">
<rect key="frame" x="22" y="113" width="276" height="21"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C6E-oI-hDC">
<rect key="frame" x="22" y="112" width="276" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="2uR-9N-hBb">
<font key="font" metaFont="system"/>
@ -892,7 +866,7 @@
<outlet property="delegate" destination="v7q-gT-jHT" id="zyw-h0-hRP"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="qHx-1z-daR">
<textField verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="qHx-1z-daR">
<rect key="frame" x="202" y="82" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="edq-46-JeP" customClass="GBCheatTextFieldCell">
@ -907,7 +881,7 @@
<outlet property="delegate" destination="v7q-gT-jHT" id="79v-33-R1X"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="N3I-PP-X85">
<textField verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="N3I-PP-X85">
<rect key="frame" x="202" y="51" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="CV2-D9-WsB" customClass="GBCheatTextFieldCell">
@ -922,7 +896,7 @@
<outlet property="delegate" destination="v7q-gT-jHT" id="P69-nT-oOt"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="S6O-LB-gSj">
<textField verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="S6O-LB-gSj">
<rect key="frame" x="202" y="20" width="96" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="tpM-ys-MEO" customClass="GBCheatTextFieldCell">
@ -937,8 +911,8 @@
<outlet property="delegate" destination="v7q-gT-jHT" id="6RH-dg-SL7"/>
</connections>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="uFo-ly-Veq">
<rect key="frame" x="18" y="83" width="178" height="18"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="uFo-ly-Veq">
<rect key="frame" x="18" y="82" width="178" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Change byte at address:" id="xwa-TF-eY1">
<font key="font" metaFont="system"/>
@ -948,8 +922,8 @@
</textField>
</subviews>
</customView>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r5T-ol-Dod">
<rect key="frame" x="316" y="116" width="270" height="16"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r5T-ol-Dod">
<rect key="frame" x="316" y="115" width="270" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Import GameShark or Game Genie cheat:" id="0mf-EN-cKc">
<font key="font" metaFont="system"/>
@ -957,7 +931,7 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X7K-nJ-alF">
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X7K-nJ-alF">
<rect key="frame" x="351" y="82" width="233" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Code" drawsBackground="YES" usesSingleLineMode="YES" id="2bz-dT-7Fi">
@ -972,7 +946,7 @@
<action selector="selectText:" target="KHj-uX-Wbk" id="11z-0U-tMA"/>
</connections>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KHj-uX-Wbk">
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KHj-uX-Wbk">
<rect key="frame" x="351" y="51" width="233" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="50d-va-Cen">
@ -985,7 +959,7 @@
</connections>
</textField>
<button verticalHuggingPriority="750" id="C3V-Ep-bMj">
<rect key="frame" x="508" y="13" width="83" height="32"/>
<rect key="frame" x="508" y="12" width="83" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
<buttonCell key="cell" type="push" title="Import" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mMP-KW-YNy">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -996,7 +970,7 @@
</connections>
</button>
<box horizontalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="P90-u5-8ko">
<rect key="frame" x="302" y="12" width="5" height="123"/>
<rect key="frame" x="304" y="12" width="5" height="123"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</box>
</subviews>
@ -1026,7 +1000,7 @@
<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="20" height="20"/>
<image name="NSStopProgressFreestandingTemplate" width="15" height="15"/>
<image name="NextTemplate" width="14" height="14"/>
<image name="StepTemplate" width="14" height="14"/>
<image name="printer" catalog="system" width="18" height="16"/>

View File

@ -8,15 +8,9 @@
#import <JoyKit/JoyKit.h>
#import <WebKit/WebKit.h>
#import <mach-o/dyld.h>
#include <sys/mount.h>
#include <sys/xattr.h>
#define UPDATE_SERVER "https://sameboy.github.io"
@interface NSToolbarItem(private)
- (NSButton *)_view;
@end
static uint32_t color_to_int(NSColor *color)
{
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
@ -46,14 +40,7 @@ static uint32_t color_to_int(NSColor *color)
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
// Refresh icon if launched via a software update
if (@available(macOS 26.0, *)) {
// Severely broken on macOS 26
}
else {
NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[[NSBundle mainBundle] bundlePath]];
icon.size = [NSApplication sharedApplication].applicationIconImage.size;
[NSApplication sharedApplication].applicationIconImage = icon;
}
[NSApplication sharedApplication].applicationIconImage = [NSImage imageNamed:@"AppIcon"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
for (unsigned i = 0; i < GBKeyboardButtonCount; i++) {
@ -106,9 +93,6 @@ static uint32_t color_to_int(NSColor *color)
@"GBDebuggerFont": hasSFMono? @"SF Mono" : @"Menlo",
@"GBDebuggerFontSize": @12,
@"GBColorPalette": @1,
@"GBTurboCap": @0,
// Default themes
@"GBThemes": @{
@"Canyon": @{
@ -342,8 +326,9 @@ static uint32_t color_to_int(NSColor *color)
#ifndef UPDATE_SUPPORT
[_preferencesWindow.toolbar removeItemAtIndex:4];
#endif
for (unsigned i = _preferencesWindow.toolbar.items.count; i--;) {
[_preferencesWindow.toolbar.items[i] _view].imageScaling = NSImageScaleNone;
if (@available(macOS 11.0, *)) {
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:0];
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:_preferencesWindow.toolbar.items.count];
}
}
[_preferencesWindow makeKeyAndOrderFront:self];
@ -403,12 +388,7 @@ static uint32_t color_to_int(NSColor *color)
else {
self.updateChanges.preferences.standardFontFamily = @"Lucida Grande";
}
if (@available(macOS 10.15, *)) {
self.updateChanges.preferences.fixedFontFamily = [NSFont monospacedSystemFontOfSize:12 weight:NSFontWeightRegular].displayName;
}
else {
self.updateChanges.preferences.fixedFontFamily = @"Menlo";
}
self.updateChanges.preferences.fixedFontFamily = @"Menlo";
self.updateChanges.drawsBackground = false;
[self.updateChanges.mainFrame loadHTMLString:html baseURL:nil];
});
@ -664,14 +644,6 @@ static uint32_t color_to_int(NSColor *color)
}
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
[[NSFileManager defaultManager] removeItemAtPath:contentsTempPath error:nil];
// Remove the quarantine flag so we don't have to escape translocation
NSString *bundlePath = [NSBundle mainBundle].bundlePath;
removexattr(bundlePath.UTF8String, "com.apple.quarantine", 0);
for (NSString *path in [[NSFileManager defaultManager] enumeratorAtPath:bundlePath]) {
removexattr([bundlePath stringByAppendingPathComponent:path].UTF8String, "com.apple.quarantine", 0);
};
_downloadDirectory = nil;
atexit_b(^{
execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL);
@ -791,27 +763,4 @@ static uint32_t color_to_int(NSColor *color)
- (IBAction)nop:(id)sender
{
}
/* This runs before C constructors. If we need to escape translocation, we should
do it ASAP to minimize our launch time. */
+ (void)load
{
if (@available(macOS 10.12, *)) {
/* Detect and escape translocation so we can safely update ourselves */
if ([[[NSBundle mainBundle] bundlePath] containsString:@"/AppTranslocation/"]) {
const char *mountPath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent].UTF8String;
struct statfs *mntbuf;
int mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
for (unsigned i = 0; i < mntsize; i++) {
if (strcmp(mntbuf[i].f_mntonname, mountPath) == 0) {
NSBundle *origBundle = [NSBundle bundleWithPath:@(mntbuf[i].f_mntfromname)];
execl(origBundle.executablePath.UTF8String, origBundle.executablePath.UTF8String, NULL);
break;
}
}
}
}
}
@end

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBCPUView : NSView
- (void)addSample:(double)sample;
@end

View File

@ -1,126 +0,0 @@
#import "GBCPUView.h"
#define SAMPLE_COUNT 0x100 // ~4 seconds
@implementation GBCPUView
{
double _samples[SAMPLE_COUNT];
size_t _position;
}
- (void)drawRect:(NSRect)dirtyRect
{
CGRect bounds = self.bounds;
NSSize size = bounds.size;
unsigned factor = [[self.window screen] backingScaleFactor];
NSBitmapImageRep *maskBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:(unsigned)size.width * factor
pixelsHigh:(unsigned)size.height * factor
bitsPerSample:8
samplesPerPixel:2
hasAlpha:true
isPlanar:false
colorSpaceName:NSDeviceWhiteColorSpace
bytesPerRow:size.width * 2 * factor
bitsPerPixel:16];
NSGraphicsContext *mainContext = [NSGraphicsContext currentContext];
NSColor *greenColor, *redColor;
if (@available(macOS 10.10, *)) {
greenColor = [NSColor systemGreenColor];
redColor = [NSColor systemRedColor];
}
else {
greenColor = [NSColor colorWithRed:3.0 / 16 green:0.5 blue:5.0 / 16 alpha:1.0];
redColor = [NSColor colorWithRed:13.0 / 16 green:0.25 blue:0.25 alpha:1.0];
}
NSBitmapImageRep *colorBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:SAMPLE_COUNT
pixelsHigh:1
bitsPerSample:8
samplesPerPixel:3
hasAlpha:false
isPlanar:false
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:SAMPLE_COUNT * 4
bitsPerPixel:32];
unsigned lastFill = 0;
NSBezierPath *line = [NSBezierPath bezierPath];
bool isRed = false;
{
double sample = _samples[_position % SAMPLE_COUNT];
[line moveToPoint:NSMakePoint(0,
(sample * (size.height - 1) + 0.5) * factor)];
isRed = sample == 1;
}
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:colorBitmap]];
for (unsigned i = 1; i < SAMPLE_COUNT; i++) {
double sample = _samples[(i + _position) % SAMPLE_COUNT];
[line lineToPoint:NSMakePoint(size.width * i * factor / (SAMPLE_COUNT - 1),
(sample * (size.height - 1) + 0.5) * factor)];
if (isRed != (sample == 1)) {
// Color changed
[(isRed? redColor : greenColor) setFill];
NSRectFill(CGRectMake(lastFill, 0, i - lastFill, 1));
lastFill = i;
isRed ^= true;
}
}
[(isRed? redColor : greenColor) setFill];
NSRectFill(CGRectMake(lastFill, 0, SAMPLE_COUNT - lastFill, 1));
NSBezierPath *fill = [line copy];
[fill lineToPoint:NSMakePoint(size.width * factor, 0)];
[fill lineToPoint:NSMakePoint(0, 0)];
NSColor *strokeColor = [NSColor whiteColor];
NSColor *fillColor = [strokeColor colorWithAlphaComponent:1 / 3.0];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:maskBitmap]];
[fillColor setFill];
[fill fill];
[strokeColor setStroke];
[line setLineWidth:factor];
[line stroke];
CGContextRef maskContext = CGContextRetain([NSGraphicsContext currentContext].graphicsPort);
[NSGraphicsContext setCurrentContext:mainContext];
CGContextSaveGState(mainContext.graphicsPort);
CGImageRef maskImage = CGBitmapContextCreateImage(maskContext);
CGContextClipToMask(mainContext.graphicsPort, bounds, maskImage);
CGImageRelease(maskImage);
NSImage *colors = [[NSImage alloc] initWithSize:NSMakeSize(SAMPLE_COUNT, 1)];
[colors addRepresentation:colorBitmap];
[colors drawInRect:bounds];
CGContextRestoreGState(mainContext.graphicsPort);
CGContextRelease(maskContext);
[super drawRect:dirtyRect];
}
- (void)addSample:(double)sample
{
_samples[_position++] = sample;
if (_position == SAMPLE_COUNT) {
_position = 0;
}
}
@end

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBColorTextCell : NSTextFieldCell
@end

View File

@ -1,19 +0,0 @@
#import "GBColorTextCell.h"
@implementation GBColorTextCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[self.backgroundColor set];
NSRectFill(cellFrame);
NSBezierPath *path = [NSBezierPath bezierPathWithRect:cellFrame];
path.lineWidth = 2;
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
[path addClip];
[path stroke];
[self drawInteriorWithFrame:cellFrame inView:controlView];
}
@end

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBDisabledButton : NSButton
@end

View File

@ -1,8 +0,0 @@
#import "GBDisabledButton.h"
@implementation GBDisabledButton
- (void)mouseDown:(NSEvent *)event
{
}
@end

View File

@ -136,7 +136,7 @@
if (!_gb) {
return [NSString stringWithFormat:@"$%llX", offset];
}
return @(GB_debugger_describe_address(_gb, offset + _baseAddress, offset < 0x4000? -1 :_bankForDescription, false, isRangeEnd));
return @(GB_debugger_describe_address(_gb, offset + _baseAddress, _bankForDescription, false, isRangeEnd));
}

View File

@ -46,29 +46,17 @@
-(void)drawKnob:(NSRect)knobRect
{
[super drawKnob:knobRect];
NSBezierPath *path = nil;
if (@available(macos 26.0, *)) {
NSRect peekRect = knobRect;
peekRect.size.height /= 2;
peekRect.size.width -= peekRect.size.height;
peekRect.origin.x += peekRect.size.height / 2;
peekRect.origin.y += peekRect.size.height / 2;
path = [NSBezierPath bezierPathWithRoundedRect:peekRect xRadius:peekRect.size.height / 2 yRadius:peekRect.size.height / 2];
}
else {
NSRect peekRect = knobRect;
peekRect.size.width /= 2;
peekRect.size.height = peekRect.size.width;
peekRect.origin.x += peekRect.size.width / 2;
peekRect.origin.y += peekRect.size.height / 2;
path = [NSBezierPath bezierPathWithOvalInRect:peekRect];
}
NSRect peekRect = knobRect;
peekRect.size.width /= 2;
peekRect.size.height = peekRect.size.width;
peekRect.origin.x += peekRect.size.width / 2;
peekRect.origin.y += peekRect.size.height / 2;
NSColor *color = self.colorValue;
if (!self.enabled) {
color = [color colorWithAlphaComponent:0.5];
}
[color setFill];
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:peekRect];
[path fill];
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
[path setLineWidth:0.5];

View File

@ -44,8 +44,7 @@
}
if (parent.displayScrollRect) {
// CGRectInfinite in NSBezierPath is broken in newer macOS versions
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectMake(-0x4000, -0x4000, 0x8000, 0x8000)];
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectInfinite];
for (unsigned x = 0; x < 2; x++) {
for (unsigned y = 0; y < 2; y++) {
NSRect rect = parent.scrollRect;

View File

@ -16,7 +16,7 @@
static GBJoyConManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[super allocWithZone:nil] _init];
manager = [[self alloc] _init];
});
return manager;
}
@ -32,16 +32,6 @@
return ret;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
+ (instancetype)alloc
{
return [self sharedInstance];
}
- (instancetype)init
{
return [self.class sharedInstance];

View File

@ -399,16 +399,10 @@ static double blend(double from, double to, double position)
[sender.window.sheetParent endSheet:sender.window];
}
+ (instancetype)alloc
- (instancetype)init
{
static id singleton = nil;
if (singleton) return singleton;
return (singleton = [super allocWithZone:nil]);
return (singleton = [super init]);
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
return [self alloc];
}
@end

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -22,44 +22,44 @@
<rect key="frame" x="0.0" y="0.0" width="512" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
<rect key="frame" x="131" y="0.0" width="95" height="24"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
<rect key="frame" x="131" y="0.0" width="96" height="24"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="sKu-Uy-2LG" customClass="GBColorTextCell">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="sKu-Uy-2LG">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
<rect key="frame" x="226" y="0.0" width="95" height="24"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
<rect key="frame" x="226" y="0.0" width="96" height="24"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="9LH-TF-W1L" customClass="GBColorTextCell">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="9LH-TF-W1L">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
<rect key="frame" x="321" y="0.0" width="95" height="24"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
<rect key="frame" x="321" y="0.0" width="96" height="24"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="arE-i5-zCC" customClass="GBColorTextCell">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="arE-i5-zCC">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
<rect key="frame" x="416" y="0.0" width="95" height="24"/>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
<rect key="frame" x="416" y="0.0" width="96" height="24"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="ZbU-nE-FsE" customClass="GBColorTextCell">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="ZbU-nE-FsE">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
<rect key="frame" x="8" y="0.0" width="121" height="20"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
<rect key="frame" x="4" y="0.0" width="121" height="20"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Background 0" id="qM4-cY-SDE">
<font key="font" usesAppearanceFont="YES"/>

View File

@ -19,9 +19,6 @@
@property IBOutlet NSPopUpButton *colorPalettePopupButton;
@property IBOutlet NSPopUpButton *hotkey1PopupButton;
@property IBOutlet NSPopUpButton *hotkey2PopupButton;
@property IBOutlet NSButton *turboCapButton;
@property IBOutlet NSSlider *turboCapSlider;
@property IBOutlet NSTextField *turboCapLabel;
@property IBOutlet GBTitledPopUpButton *fontPopupButton;
@property IBOutlet NSStepper *fontSizeStepper;

View File

@ -20,7 +20,7 @@
- (NSWindowToolbarStyle)toolbarStyle
{
return NSWindowToolbarStylePreference;
return NSWindowToolbarStyleExpanded;
}
- (void)close
@ -342,13 +342,6 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
_fontSizeStepper.intValue = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"];
[self updateFonts];
double cap = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"];
if (cap) {
_turboCapSlider.intValue = round(cap * 100);
_turboCapButton.state = NSOnState;
}
[self turboCapToggled:_turboCapButton];
}
- (IBAction)fontSizeChanged:(id)sender
@ -562,35 +555,4 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
[GBJoyConManager sharedInstance].arrangementMode = false;
}
- (IBAction)turboCapToggled:(NSButton *)sender
{
if (sender.state) {
_turboCapSlider.enabled = true;
[self turboCapChanged:_turboCapSlider];
if (@available(macOS 10.10, *)) {
_turboCapLabel.textColor = [NSColor labelColor];
}
else {
_turboCapLabel.textColor = [NSColor blackColor];
}
}
else {
_turboCapSlider.enabled = false;
_turboCapLabel.enabled = false;
[[NSUserDefaults standardUserDefaults] setDouble:0 forKey:@"GBTurboCap"];
if (@available(macOS 10.10, *)) {
_turboCapLabel.textColor = [NSColor disabledControlTextColor];
}
else {
_turboCapLabel.textColor = [NSColor colorWithWhite:0 alpha:0.25];
}
}
}
- (IBAction)turboCapChanged:(NSSlider *)sender
{
_turboCapLabel.stringValue = [NSString stringWithFormat:@"%d%%", sender.intValue];
[[NSUserDefaults standardUserDefaults] setDouble:sender.doubleValue / 100.0 forKey:@"GBTurboCap"];
}
@end

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -25,7 +25,7 @@
<rect key="frame" x="0.0" y="0.0" width="332" height="221"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
<rect key="frame" x="18" y="192" width="296" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Title" id="BwZ-Zj-sP6">
@ -34,7 +34,7 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
<rect key="frame" x="18" y="166" width="296" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Author" id="IgT-r1-T38">
@ -59,7 +59,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="YJh-dI-A5D">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="message"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="Knp-Ok-Pb4"/>
</popUpButtonCell>
<connections>
@ -67,7 +67,7 @@
</connections>
</popUpButton>
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRS-M5-VVL">
<rect key="frame" x="247" y="128" width="68" height="25"/>
<rect key="frame" x="247" y="129" width="68" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="cmq-I8-cFL">
<font key="font" metaFont="system"/>
@ -94,7 +94,7 @@
</customView>
</subviews>
</customView>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
<rect key="frame" x="18" y="5" width="296" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Copyright" id="nM9-oF-OV9">

View File

@ -11,23 +11,23 @@
@implementation GBTerminalTextFieldCell
{
GBTerminalTextView *_fieldEditor;
GBTerminalTextView *field_editor;
}
- (NSTextView *)fieldEditorForView:(NSTextField *)controlView
{
if (_fieldEditor) {
_fieldEditor.gb = self.gb;
return _fieldEditor;
if (field_editor) {
field_editor.gb = self.gb;
return field_editor;
}
_fieldEditor = [[GBTerminalTextView alloc] init];
[_fieldEditor setFieldEditor:true];
_fieldEditor.gb = self.gb;
_fieldEditor->_field = (NSTextField *)controlView;
field_editor = [[GBTerminalTextView alloc] init];
[field_editor setFieldEditor:true];
field_editor.gb = self.gb;
field_editor->_field = (NSTextField *)controlView;
((NSTextFieldCell *)controlView.cell).textInset =
_fieldEditor.textContainerInset =
NSMakeSize(7, 2);
return _fieldEditor;
field_editor.textContainerInset =
NSMakeSize(0, 2);
return field_editor;
}
@end

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBToolbarFieldCell : NSSearchFieldCell
@end

View File

@ -1,40 +0,0 @@
#import "GBToolbarFieldCell.h"
#import <objc/runtime.h>
@interface NSTextFieldCell()
- (void)textDidChange:(id)sender;
@end
@implementation GBToolbarFieldCell
- (void)textDidChange:(id)sender
{
IMP imp = [NSTextFieldCell instanceMethodForSelector:_cmd];
method_setImplementation(class_getInstanceMethod([GBToolbarFieldCell class], _cmd), imp);
((void(*)(id, SEL, id))imp)(self, _cmd, sender);
}
- (void)endEditing:(NSText *)textObj
{
IMP imp = [NSTextFieldCell instanceMethodForSelector:_cmd];
method_setImplementation(class_getInstanceMethod([GBToolbarFieldCell class], _cmd), imp);
((void(*)(id, SEL, id))imp)(self, _cmd, textObj);
}
- (void)resetSearchButtonCell
{
}
- (void)resetCancelButtonCell
{
}
// We only need this hack on Solarium, avoid regressions
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
if (@available(macOS 26.0, *)) {
return [super allocWithZone:zone];
}
return (id)[NSTextFieldCell allocWithZone:zone];
}
@end

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBToolbarPopUpButtonCell : NSPopUpButtonCell
@end

View File

@ -1,17 +0,0 @@
#import "GBToolbarPopUpButtonCell.h"
@implementation GBToolbarPopUpButtonCell
-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[super drawInteriorWithFrame:CGRectInset(cellFrame, 5, 0) inView:controlView];
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
if (@available(macOS 26.0, *)) {
return [super allocWithZone:zone];
}
return (id)[NSPopUpButtonCell allocWithZone:zone];
}
@end

View File

@ -148,9 +148,6 @@ static const uint8_t workboy_vk_to_key[] = {
[self observeStandardDefaultsKey:@"GBAspectRatioUnkept" withBlock:^(id newValue) {
[weakSelf setFrame:weakSelf.superview.frame];
}];
[self observeStandardDefaultsKey:@"GBForceIntegerScale" withBlock:^(id newValue) {
[weakSelf setFrame:weakSelf.superview.frame];
}];
[self observeStandardDefaultsKey:@"JoyKitDefaultControllers" withBlock:^(id newValue) {
[weakSelf reassignControllers];
}];
@ -285,9 +282,7 @@ static const uint8_t workboy_vk_to_key[] = {
- (void)setFrame:(NSRect)frame
{
NSView *superview = self.superview;
if (GB_unlikely(!superview)) return;
frame = superview.frame;
frame = self.superview.frame;
if (_gb && ![[NSUserDefaults standardUserDefaults] boolForKey:@"GBAspectRatioUnkept"]) {
double ratio = frame.size.width / frame.size.height;
double width = GB_get_screen_width(_gb);
@ -305,19 +300,6 @@ static const uint8_t workboy_vk_to_key[] = {
frame.origin.x = 0;
}
}
if (_gb && [[NSUserDefaults standardUserDefaults] boolForKey:@"GBForceIntegerScale"]) {
double factor = self.window.backingScaleFactor;
double width = GB_get_screen_width(_gb) / factor;
double height = GB_get_screen_height(_gb) / factor;
double new_width = floor(frame.size.width / width) * width;
double new_height = floor(frame.size.height / height) * height;
frame.origin.x += floor((frame.size.width - new_width) / 2);
frame.origin.y += floor((frame.size.height - new_height) / 2);
frame.size.width = new_width;
frame.size.height = new_height;
}
[super setFrame:frame];
}

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBWindow : NSWindow
@end

View File

@ -1,22 +0,0 @@
#import "GBWindow.h"
@interface NSWindow(private)
- (void)_zoomFill:(id)sender;
@end
/*
For some reason, Apple replaced the alt + zoom button behavior to be "fill" rather than zoom.
I don't like that. It prevents SameBoy's integer scaling from working. Let's restore it.
*/
@implementation GBWindow
- (void)_zoomFill:(id)sender
{
if (sender == [self standardWindowButton:NSWindowZoomButton] &&
((self.currentEvent.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagOption)) {
[self zoom:sender];
return;
}
[super _zoomFill:sender];
}
@end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -113,9 +113,7 @@
<key>CFBundleExecutable</key>
<string>SameBoy</string>
<key>CFBundleIconFile</key>
<string>AppIcon</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<string>AppIcon.icns</string>
<key>CFBundleIdentifier</key>
<string>com.github.liji32.sameboy</string>
<key>LSApplicationCategoryType</key>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 689 B

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.9" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.9"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@ -82,7 +82,7 @@
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Hot Swap Cartridge…" secondaryImage="arrow.down.left.arrow.up.right" catalog="system" keyEquivalent="o" id="Rik-p8-QCf">
<menuItem title="Hot Swap Cartridge…" keyEquivalent="o" id="Rik-p8-QCf">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="cartSwap:" target="-1" id="iXS-Ol-IS0"/>
@ -102,7 +102,7 @@
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="New Cartridge Instance…" secondaryImage="plus.square.on.square" catalog="system" keyEquivalent="n" id="Vld-be-NZu">
<menuItem title="New Cartridge Instance…" keyEquivalent="n" id="Vld-be-NZu">
<connections>
<action selector="newCartridgeInstance:" target="-1" id="GJc-xU-ZEr"/>
</connections>
@ -158,7 +158,7 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Aru-vr-frG"/>
<menuItem title="Find" secondaryImage="text.page.badge.magnifyingglass" catalog="system" id="efg-jw-GVP">
<menuItem title="Find" id="efg-jw-GVP">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="4R6-IU-Jq6">
<items>
@ -197,23 +197,23 @@
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Emulation" id="HyV-fh-RgO">
<items>
<menuItem title="Reset" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" keyEquivalent="r" id="p0i-Lt-sTg">
<menuItem title="Reset" keyEquivalent="r" id="p0i-Lt-sTg">
<connections>
<action selector="reset:" target="-1" id="DKW-Bd-h3v"/>
</connections>
</menuItem>
<menuItem title="Quick Reset" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" tag="-1" alternate="YES" keyEquivalent="r" id="uPG-01-49E">
<menuItem title="Quick Reset" tag="-1" alternate="YES" keyEquivalent="r" id="uPG-01-49E">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="reset:" target="-1" id="VV1-VP-L7g"/>
</connections>
</menuItem>
<menuItem title="Reload ROM" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" alternate="YES" keyEquivalent="R" id="eQP-Fb-nkz">
<menuItem title="Reload ROM" alternate="YES" keyEquivalent="R" id="eQP-Fb-nkz">
<connections>
<action selector="reloadROM:" target="-1" id="BpN-8V-Csg"/>
</connections>
</menuItem>
<menuItem title="Pause" secondaryImage="pause" catalog="system" keyEquivalent="p" id="4K4-hw-R7Q">
<menuItem title="Pause" keyEquivalent="p" id="4K4-hw-R7Q">
<connections>
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
</connections>
@ -263,7 +263,7 @@
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="QIS-av-Byy"/>
<menuItem title="Save State" secondaryImage="square.and.arrow.down" catalog="system" id="Hdz-ut-okE">
<menuItem title="Save State" id="Hdz-ut-okE">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Save State" id="Mxx-u1-M9D">
<items>
@ -320,7 +320,7 @@
</items>
</menu>
</menuItem>
<menuItem title="Load State" secondaryImage="square.and.arrow.up" catalog="system" id="EXD-SL-cz4">
<menuItem title="Load State" id="EXD-SL-cz4">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Load State" id="l9D-Ej-sh2">
<items>
@ -388,7 +388,7 @@
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="5GS-tt-E0a"/>
<menuItem title="Save Screenshot" secondaryImage="photo" catalog="system" keyEquivalent="s" id="0J3-yf-iXs">
<menuItem title="Save Screenshot" keyEquivalent="s" id="0J3-yf-iXs">
<connections>
<action selector="saveScreenshot:" target="-1" id="gJd-ml-J8p"/>
</connections>
@ -405,12 +405,12 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="DPb-Sh-5tg"/>
<menuItem title="Start Audio Recording…" secondaryImage="record.circle" catalog="system" keyEquivalent="A" id="1UK-8n-QPP">
<menuItem title="Start Audio Recording…" keyEquivalent="A" id="1UK-8n-QPP">
<connections>
<action selector="toggleAudioRecording:" target="-1" id="YE5-mi-Yzd"/>
</connections>
</menuItem>
<menuItem title="Mute Sound" secondaryImage="speaker.slash" catalog="system" keyEquivalent="m" id="zo0-Rh-wTu">
<menuItem title="Mute Sound" keyEquivalent="m" id="zo0-Rh-wTu">
<connections>
<action selector="mute:" target="-1" id="eK3-ea-ExJ"/>
</connections>
@ -433,7 +433,7 @@
<action selector="showCheats:" target="-1" id="stn-Ei-aFE"/>
</connections>
</menuItem>
<menuItem title="Search Cheats" secondaryImage="text.page.badge.magnifyingglass" catalog="system" id="LZV-QK-YXi">
<menuItem title="Search Cheats" id="LZV-QK-YXi">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showCheatSearch:" target="-1" id="eI1-x0-ykn"/>
@ -442,9 +442,9 @@
</items>
</menu>
</menuItem>
<menuItem title="Connect" id="IcW-ZC-4wb">
<menuItem title="Connectivity" id="IcW-ZC-4wb">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Connect" id="BDM-Cv-BOm">
<menu key="submenu" title="Connectivity" id="BDM-Cv-BOm">
<items>
<menuItem title="None" id="SiH-Q4-OBY">
<modifierMask key="keyEquivalentModifierMask"/>
@ -452,7 +452,7 @@
<action selector="disconnectAllAccessories:" target="-1" id="5hY-9U-nRn"/>
</connections>
</menuItem>
<menuItem title="Game Link Cable &amp; Infrared" secondaryImage="cable.connector.horizontal" catalog="system" id="V4S-Fo-xJK">
<menuItem title="Game Link Cable &amp; Infrared" id="V4S-Fo-xJK">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Game Link Cable &amp; Infrared" id="6sJ-Wz-QLj">
<connections>
@ -463,13 +463,13 @@
<action selector="nop:" target="-3" id="Bpa-0C-lkN"/>
</connections>
</menuItem>
<menuItem title="Game Boy Printer" secondaryImage="printer" catalog="system" id="zHR-Ha-pOR">
<menuItem title="Game Boy Printer" id="zHR-Ha-pOR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="connectPrinter:" target="-1" id="tl1-CL-tAw"/>
</connections>
</menuItem>
<menuItem title="Workboy" secondaryImage="keyboard" catalog="system" id="lo9-CX-BJj">
<menuItem title="Workboy" id="lo9-CX-BJj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="connectWorkboy:" target="-1" id="6vS-bq-wAX"/>
@ -482,14 +482,14 @@
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Develop" id="UVb-cc-at0">
<items>
<menuItem title="Developer Mode" secondaryImage="wrench.and.screwdriver" catalog="system" id="Qx6-Tt-zZR">
<menuItem title="Developer Mode" id="Qx6-Tt-zZR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleDeveloperMode:" target="-3" id="PIc-o3-bzb"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="66c-T0-8pW"/>
<menuItem title="Show Console" secondaryImage="apple.terminal" catalog="system" id="Wse-UY-Y9l">
<menuItem title="Show Console" id="Wse-UY-Y9l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showConsoleWindow:" target="-1" id="mFf-4i-jLG"/>
@ -501,14 +501,14 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="3If-Yf-U7B"/>
<menuItem title="Break Debugger" secondaryImage="pause" catalog="system" keyEquivalent="c" id="uBD-GY-Doi">
<menuItem title="Break Debugger" keyEquivalent="c" id="uBD-GY-Doi">
<modifierMask key="keyEquivalentModifierMask" control="YES"/>
<connections>
<action selector="interrupt:" target="-1" id="ZmB-wG-fTs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="M6n-8G-LZS"/>
<menuItem title="Audio Channels" secondaryImage="speaker.wave.3" catalog="system" id="Cib-LN-Y4o">
<menuItem title="Audio Channels" id="Cib-LN-Y4o">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Audio Channels" id="l22-4p-yTK">
<items>
@ -540,13 +540,13 @@
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="v5c-ri-BoZ"/>
<menuItem title="Show Background and Window" state="on" secondaryImage="mountain.2" catalog="system" id="yfD-Qd-zoz">
<menuItem title="Show Background and Window" state="on" id="yfD-Qd-zoz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleDisplayBackground:" target="-1" id="p5b-1n-SPR"/>
</connections>
</menuItem>
<menuItem title="Show Objects" state="on" secondaryImage="cube" catalog="system" id="OWx-a0-vQk">
<menuItem title="Show Objects" state="on" id="OWx-a0-vQk">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleDisplayObjects:" target="-1" id="8ie-ey-739"/>
@ -620,24 +620,4 @@
<point key="canvasLocation" x="140" y="260"/>
</menu>
</objects>
<resources>
<image name="apple.terminal" catalog="system" width="18" height="14"/>
<image name="arrow.down.left.arrow.up.right" catalog="system" width="18" height="17"/>
<image name="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" width="16" height="15"/>
<image name="cable.connector.horizontal" catalog="system" width="19" height="7"/>
<image name="cube" catalog="system" width="16" height="17"/>
<image name="keyboard" catalog="system" width="19" height="13"/>
<image name="mountain.2" catalog="system" width="25" height="14"/>
<image name="pause" catalog="system" width="9" height="13"/>
<image name="photo" catalog="system" width="18" height="14"/>
<image name="plus.square.on.square" catalog="system" width="17" height="16"/>
<image name="printer" catalog="system" width="18" height="16"/>
<image name="record.circle" catalog="system" width="15" height="15"/>
<image name="speaker.slash" catalog="system" width="14" height="16"/>
<image name="speaker.wave.3" catalog="system" width="22" height="15"/>
<image name="square.and.arrow.down" catalog="system" width="15" height="17"/>
<image name="square.and.arrow.up" catalog="system" width="15" height="18"/>
<image name="text.page.badge.magnifyingglass" catalog="system" width="15" height="18"/>
<image name="wrench.and.screwdriver" catalog="system" width="19" height="18"/>
</resources>
</document>

View File

@ -3,8 +3,8 @@
#import <objc/runtime.h>
@interface NSTextFieldCell ()
- (CGRect)_textLayerDrawingRectForCellFrame:(CGRect)rect;
@property NSSize textInset;
- (bool)_isEditingInView:(NSView *)view;
@end
@implementation NSTextFieldCell (Inset)
@ -19,59 +19,21 @@
return [objc_getAssociatedObject(self, _cmd) sizeValue];
}
- (void)drawWithFrameHook:(NSRect)cellFrame inView:(NSView *)controlView
- (CGRect)_textLayerDrawingRectForCellFrameHook:(CGRect)rect
{
CGRect ret = [self _textLayerDrawingRectForCellFrameHook:rect];
NSSize inset = self.textInset;
if (self.drawsBackground) {
[self.backgroundColor setFill];
if ([self _isEditingInView:controlView]) {
NSRectFill(cellFrame);
}
else {
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y,
cellFrame.size.width, inset.height));
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + cellFrame.size.height - inset.height,
cellFrame.size.width, inset.height));
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + inset.height,
inset.width, cellFrame.size.height - inset.height * 2));
NSRectFill(NSMakeRect(cellFrame.origin.x + cellFrame.size.width - inset.width, cellFrame.origin.y + inset.height,
inset.width, cellFrame.size.height - inset.height * 2));
}
}
cellFrame.origin.x += inset.width;
cellFrame.origin.y += inset.height;
cellFrame.size.width -= inset.width * 2;
cellFrame.size.height -= inset.height * 2;
[self drawWithFrameHook:cellFrame inView:controlView];
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(drawWithFrame:inView:)),
class_getInstanceMethod(self, @selector(drawWithFrameHook:inView:)));
}
@end
@implementation NSTextField (Inset)
- (bool)wantsUpdateLayerHook
{
CGSize inset = ((NSTextFieldCell *)self.cell).textInset;
if (inset.width || inset.height) return false;
return [self wantsUpdateLayerHook];
}
+ (void)load
{
Method method = class_getInstanceMethod(self, @selector(wantsUpdateLayer));
if (class_addMethod(self, @selector(wantsUpdateLayer), method_getImplementation(method), method_getTypeEncoding(method))) {
method = class_getInstanceMethod(self, @selector(wantsUpdateLayer));
}
method_exchangeImplementations(method,
class_getInstanceMethod(self, @selector(wantsUpdateLayerHook)));
method_exchangeImplementations(class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrame:)),
class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrameHook:)));
}
@end

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>

View File

@ -1,168 +0,0 @@
#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>
// Comment out to debug
#define NSLog(...)
// Solarium has weird proportions, we need to fix them.
@implementation NSControl (SolariumFixer)
- (void)awakeFromNib
{
if (@available(macOS 26.0, *)) {
if ([self.superview isKindOfClass:objc_getClass("NSToolbarItemViewer")]) return;
if ([self isKindOfClass:[NSStepper class]]) {
NSLog(@"Stepper needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
CGRect frame = self.frame;
frame.origin.y += 1;
self.frame = frame;
return;
}
if (self.controlSize != NSControlSizeRegular) return;
if ([self isKindOfClass:[NSPopUpButton class]] ) {
NSLog(@"Popup button needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
CGRect frame = self.frame;
if (frame.size.height != 25) {
NSLog(@"%@ in window %@ has the wrong height!", ((NSButton *)self).title, self.window.title);
return;
}
frame.size.width -= 2 + 5; // Remove 5 from the right and 2 from the left
frame.origin.x += 2;
frame.origin.y += 2;
self.frame = frame;
}
else if ([self isKindOfClass:[NSSegmentedControl class]] ) {
NSLog(@"Segmented button needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
CGRect frame = self.frame;
if (frame.size.height != 25) {
NSLog(@"%s in window %@ has the wrong height!", sel_getName(self.action), self.window.title);
return;
}
frame.origin.x += 8;
frame.origin.y += 1;
self.frame = frame;
}
else if ([self isKindOfClass:[NSTextField class]]) {
NSTextField *field = (id)self;
if (![field isBezeled]) return;
NSLog(@"Text field needs adjustment: %@ in window %@", ((NSTextField *)self).placeholderString, self.window.title);
CGRect frame = self.frame;
if (frame.size.height == 21) {
frame.size.height = 24;
}
else {
NSLog(@"%@ in window %@ has the wrong height!", ((NSTextField *)self).placeholderString, self.window.title);
return;
}
frame.size.width -= 1 + 1; // Remove 1 from the right and 1 from the left
frame.origin.x += 1;
frame.origin.y -= 1;
self.frame = frame;
}
else if ([self isKindOfClass:[NSButton class]]) {
NSLog(@"Button: %@ in window %@", @(sel_getName(self.action)), self.window.title);
NSButton *button = (id)self;
if (!button.isBordered) return;
if (button.bezelStyle == NSBezelStylePush) {
NSLog(@"Button needs adjustment: %@ in window %@", @(sel_getName(self.action)), self.window.title);
CGRect frame = self.frame;
frame.size.width -= 7 + 7; // Remove 7 from the right and 7 from the left
frame.origin.x += 7;
frame.origin.y += 5;
if (frame.size.height == 32) {
frame.size.height = 25;
}
else {
NSLog(@"%@ in window %@ has the wrong height!", @(sel_getName(self.action)), self.window.title);
} self.frame = frame;
}
else if (button.bezelStyle == NSBezelStyleRegularSquare) {
CGRect frame = self.frame;
if (frame.size.height != 18) return;
NSLog(@"Check/Radio needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
frame.size.width -= 2;
frame.origin.x += 2;
frame.origin.y += 1;
frame.size.height = 16;
self.frame = frame;
}
else if (button.bezelStyle == NSBezelStyleHelpButton) {
CGRect frame = self.frame;
NSLog(@"Help button needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
frame.origin.y += 2;
self.frame = frame;
}
}
else if ([self isKindOfClass:[NSSlider class]]) {
NSLog(@"Slider needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
CGRect frame = self.frame;
frame.origin.y += 3;
self.frame = frame;
}
}
}
@end
@implementation NSToolbarItem (SolariumFixer)
static CGSize minSizeHook(id self, SEL _cmd)
{
return CGSizeMake(8, 0);
}
- (void)awakeFromNib
{
if (@available(macOS 26.0, *)) {
NSLog(@"Toolbar item %@ has view %@", self.label, self.view);
if ([self.view isKindOfClass:[NSTextField class]]) {
NSLog(@"Handling (Text field)");
self.bordered = true;
NSSize maxSize = self.maxSize;
maxSize.height = 36;
self.maxSize = maxSize;
NSSize minSize = self.minSize;
minSize.height = 36;
self.minSize = minSize;
((NSTextField *)self.view).backgroundColor = [NSColor clearColor];
((NSTextField *)self.view).bezeled = false;
((NSTextField *)self.view).bordered = true;
// Work around even more AppKit bugs
self.toolbar.displayMode++;
self.toolbar.displayMode--;
}
else if ([self.view isKindOfClass:[NSPopUpButton class]]) {
NSLog(@"Handling (Pop up button)");
self.bordered = true;
NSSize maxSize = self.maxSize;
maxSize.height = 28;
self.maxSize = maxSize;
NSSize minSize = self.minSize;
minSize.height = 28;
self.minSize = minSize;
}
}
else if (@available(macOS 11.0, *)) { // While at it, make macOS 11-15 a bit more consistent
if ([self.view isKindOfClass:[NSTextField class]]) {
((NSTextField *)self.view).bezelStyle = NSTextFieldRoundedBezel;
}
}
}
+ (void)load
{
if (@available(macOS 26.0, *)) {
method_setImplementation(class_getInstanceMethod(objc_getClass("NSToolbarFlexibleSpaceItem"), @selector(minSize)),
(void *)minSizeHook);
}
}
@end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 B

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 801 B

View File

@ -6,7 +6,7 @@
#include <stdlib.h>
#include "gb.h"
/* Band limited synthesis loosely based on: http://www.slack.net/~ant/bl-synth/ */
/* Band limited synthesis based on: http://www.slack.net/~ant/bl-synth/ */
static int32_t band_limited_steps[GB_BAND_LIMITED_PHASES][GB_BAND_LIMITED_WIDTH];
static void __attribute__((constructor)) band_limited_init(void)
@ -15,42 +15,37 @@ static void __attribute__((constructor)) band_limited_init(void)
double *master = malloc(master_size * sizeof(*master));
memset(master, 0, master_size * sizeof(*master));
const double lowpass = 15.0 / 16.0; // 1.0 means using Nyquist as the exact cutoff
const double to_angle = M_PI / GB_BAND_LIMITED_PHASES * lowpass;
double sum = 0;
nounroll for (signed i = 0; i < master_size; i++) {
// Exact Blackman window
const double a0 = 7938 / 18608.0;
const double a1 = 9240 / 18608.0;
const double a2 = 1430 / 18608.0;
double window_angle = (2.0 * M_PI * i) / (master_size);
double window = a0 - a1 * cos(window_angle) + a2 * cos(2 * window_angle);
double angle = (i - (signed)master_size / 2) * to_angle;
sum += master[i] = (angle == 0? 1 : sin(angle) / angle) * window;
const unsigned sine_size = 256 * GB_BAND_LIMITED_PHASES + 2;
const unsigned max_harmonic = sine_size / 2 / GB_BAND_LIMITED_PHASES;
nounroll for (unsigned harmonic = 1; harmonic <= max_harmonic; harmonic += 2) {
double amplitude = 1.0 / harmonic / 2;
double to_angle = M_PI * 2 / sine_size * harmonic;
nounroll for (unsigned i = 0; i < master_size; i++) {
master[i] += sin(((signed)(i + 1) - (signed)master_size / 2) * to_angle) * amplitude;
}
}
nounroll for (signed i = 0; i < master_size; i++) {
master[i] /= sum;
// Normalize master waveform
nounroll for (unsigned i = 0; i < master_size - 1; i++) {
master[i] += master[master_size - 1];
master[i] /= master[master_size - 1] * 2;
}
master[master_size - 1] = 1;
nounroll for (signed phase = 0; phase < GB_BAND_LIMITED_PHASES; phase++) {
nounroll for (unsigned phase = 0; phase < GB_BAND_LIMITED_PHASES; phase++) {
int32_t error = GB_BAND_LIMITED_ONE;
nounroll for (signed i = 0; i < GB_BAND_LIMITED_WIDTH; i++) {
double sum = 0;
nounroll for (signed j = 0; j < GB_BAND_LIMITED_PHASES; j++) {
signed index = i * GB_BAND_LIMITED_PHASES - phase + j;
if (index >= 0) {
sum += master[index];
}
}
int32_t cur = sum * GB_BAND_LIMITED_ONE;
error -= cur;
band_limited_steps[phase][i] = cur;
int32_t prev = 0;
nounroll for (unsigned i = 0; i < GB_BAND_LIMITED_WIDTH; i++) {
int32_t cur = master[(GB_BAND_LIMITED_PHASES - 1 - phase) + i * GB_BAND_LIMITED_PHASES] * GB_BAND_LIMITED_ONE;
int32_t delta = cur - prev;
error = error - delta;
prev = cur;
band_limited_steps[phase][i] = delta;
}
// Make sure the deltas sum to 1.0
band_limited_steps[phase][GB_BAND_LIMITED_WIDTH / 2] += error;
band_limited_steps[phase][GB_BAND_LIMITED_WIDTH / 2 - 1] += error / 2;
band_limited_steps[phase][0] += error - (error / 2);
}
free(master);
}
@ -61,9 +56,7 @@ static void band_limited_update(GB_band_limited_t *band_limited, const GB_sample
unsigned delay = phase / GB_BAND_LIMITED_PHASES;
phase = phase & (GB_BAND_LIMITED_PHASES - 1);
struct {
signed left, right;
} delta = {
GB_sample_t delta = {
.left = input->left - band_limited->input.left,
.right = input->right - band_limited->input.right,
};
@ -80,9 +73,7 @@ static void band_limited_update_unfiltered(GB_band_limited_t *band_limited, cons
{
if (input->packed == band_limited->input.packed) return;
struct {
signed left, right;
} delta = {
GB_sample_t delta = {
.left = input->left - band_limited->input.left,
.right = input->right - band_limited->input.right,
};
@ -103,39 +94,6 @@ static void band_limited_read(GB_band_limited_t *band_limited, GB_sample_t *outp
output->left = band_limited->output.left * multiplier / GB_BAND_LIMITED_ONE;
output->right = band_limited->output.right * multiplier / GB_BAND_LIMITED_ONE;
/* This hueristic will mute the channel if it's only playing an amplitude of 1 or 2 units, usually
caused by rounding errors when the channel is playing a single frequency above Nyquist. */
unsigned diff = abs(output->left - band_limited->last_output.left);
if (diff > 4) {
band_limited->silence_detection = 0;
band_limited->last_output.packed = output->packed;
return;
}
diff = abs(output->right - band_limited->last_output.right);
if (diff > 4) {
band_limited->silence_detection = 0;
band_limited->last_output.packed = output->packed;
return;
}
if (band_limited->silence_detection == 4000) {
output->packed = band_limited->last_output.packed;
}
else {
band_limited->silence_detection++;
}
}
static inline uint32_t sample_fraction_multiply(GB_gameboy_t *gb, unsigned multiplier)
{
if (unlikely(multiplier == 0)) return 0;
if (likely(multiplier < GB_QUICK_MULTIPLY_COUNT + 1)) {
return gb->apu_output.quick_fraction_multiply_cache[multiplier - 1];
}
return gb->apu_output.quick_fraction_multiply_cache[0] * multiplier;
}
static const uint8_t duties[] = {
@ -206,7 +164,7 @@ static void update_sample(GB_gameboy_t *gb, GB_channel_t index, int8_t value, un
if (index == GB_WAVE) {
/* For some reason, channel 3 is inverted on the AGB, and has a different "silence" value */
value ^= 0xF;
silence = 7 * 2;
silence = 7;
}
uint8_t bias = agb_bias_for_channel(gb, index);
@ -215,8 +173,8 @@ static void update_sample(GB_gameboy_t *gb, GB_channel_t index, int8_t value, un
bool right = gb->io_registers[GB_IO_NR51] & (1 << index);
GB_sample_t output = {
.left = (0xF - (left? value * 2 + bias : silence)) * left_volume,
.right = (0xF - (right? value * 2 + bias : silence)) * right_volume
.left = (0xF - (left? value : silence) * 2 + bias) * left_volume,
.right = (0xF - (right? value : silence) * 2 + bias) * right_volume
};
if (unlikely(gb->apu_output.channel_muted[index])) {
@ -229,7 +187,7 @@ static void update_sample(GB_gameboy_t *gb, GB_channel_t index, int8_t value, un
else {
band_limited_update(&gb->apu_output.band_limited[index],
&output,
(((gb->apu_output.sample_fraction + sample_fraction_multiply(gb, cycles_offset)) >> 8) * GB_BAND_LIMITED_PHASES) >> 20);
(gb->apu_output.cycles_since_render + cycles_offset) * GB_BAND_LIMITED_PHASES / gb->apu_output.max_cycles_per_sample);
}
}
@ -264,7 +222,7 @@ static void update_sample(GB_gameboy_t *gb, GB_channel_t index, int8_t value, un
else {
band_limited_update(&gb->apu_output.band_limited[index],
&output,
(((gb->apu_output.sample_fraction + sample_fraction_multiply(gb, cycles_offset)) >> 8) * GB_BAND_LIMITED_PHASES) >> 20);
(gb->apu_output.cycles_since_render + cycles_offset) * GB_BAND_LIMITED_PHASES / gb->apu_output.max_cycles_per_sample);
}
}
}
@ -349,12 +307,6 @@ static void render(GB_gameboy_t *gb)
output.right += channel_output.right;
}
gb->apu_output.cycles_since_render = 0;
if (unlikely(gb->apu_output.sample_fraction < (1 << 28))) {
gb->apu_output.sample_fraction = 0;
}
else {
gb->apu_output.sample_fraction -= 1 << 28;
}
if (gb->sgb && gb->sgb->intro_animation < GB_SGB_INTRO_ANIMATION_LENGTH) return;
@ -1012,8 +964,6 @@ restart:;
if (gb->apu_output.sample_rate) {
gb->apu_output.cycles_since_render += cycles;
gb->apu_output.sample_fraction += sample_fraction_multiply(gb, cycles);
assert(gb->apu_output.sample_fraction < (4 << 28));
if (gb->apu_output.sample_cycles >= clock_rate) {
gb->apu_output.sample_cycles -= clock_rate;
@ -1810,10 +1760,6 @@ void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate)
if (sample_rate) {
gb->apu_output.highpass_rate = pow(0.999958, GB_get_clock_rate(gb) / (double)sample_rate);
gb->apu_output.max_cycles_per_sample = ceil(GB_get_clock_rate(gb) / 2.0 / sample_rate);
gb->apu_output.quick_fraction_multiply_cache[0] = round(sample_rate * 2.0 / GB_get_clock_rate(gb) * (1 << 28));
for (unsigned i = 1; i < GB_QUICK_MULTIPLY_COUNT; i++) {
gb->apu_output.quick_fraction_multiply_cache[i] = gb->apu_output.quick_fraction_multiply_cache[0] * (i + 1);
}
}
else {
gb->apu_output.max_cycles_per_sample = 0x400;
@ -1830,11 +1776,6 @@ void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, double cycles_per_sample)
gb->apu_output.sample_rate = GB_get_clock_rate(gb) / cycles_per_sample * 2;
gb->apu_output.highpass_rate = pow(0.999958, cycles_per_sample);
gb->apu_output.max_cycles_per_sample = ceil(cycles_per_sample / 4);
gb->apu_output.quick_fraction_multiply_cache[0] = round(gb->apu_output.sample_rate * 2.0 / GB_get_clock_rate(gb) * (1 << 28));
for (unsigned i = 1; i < GB_QUICK_MULTIPLY_COUNT; i++) {
gb->apu_output.quick_fraction_multiply_cache[i] = gb->apu_output.quick_fraction_multiply_cache[0] * (i + 1);
}
}
unsigned GB_get_sample_rate(GB_gameboy_t *gb)

View File

@ -5,10 +5,8 @@
#include <stdio.h>
#include "defs.h"
#define GB_BAND_LIMITED_WIDTH 64
#define GB_BAND_LIMITED_PHASES 256
#define GB_QUICK_MULTIPLY_COUNT 64
#define GB_BAND_LIMITED_WIDTH 16
#define GB_BAND_LIMITED_PHASES 512
#ifdef GB_INTERNAL
#define GB_BAND_LIMITED_ONE 0x10000 // fixed point value equal to 1
@ -173,8 +171,6 @@ typedef struct {
} buffer[GB_BAND_LIMITED_WIDTH * 2], output;
uint8_t pos;
GB_sample_t input;
GB_sample_t last_output;
unsigned silence_detection;
} GB_band_limited_t;
typedef struct {
@ -184,9 +180,6 @@ typedef struct {
unsigned max_cycles_per_sample;
uint32_t cycles_since_render;
uint32_t sample_fraction; // Counter in 1 / sample_rate, in 4.28 fixed format
uint32_t quick_fraction_multiply_cache[GB_QUICK_MULTIPLY_COUNT];
GB_band_limited_t band_limited[GB_N_CHANNELS];
double dac_discharge[GB_N_CHANNELS];
bool channel_muted[GB_N_CHANNELS];

View File

@ -73,7 +73,7 @@ bool GB_cheat_search_filter(GB_gameboy_t *gb, const char *expression, GB_cheat_s
}
skip:;
old_data++;
if (new_data == gb->ram + gb->ram_size - 1 && gb->mbc_ram_size) {
if (new_data == gb->ram + gb->ram_size - 1) {
new_data = gb->mbc_ram;
}
else if (new_data == gb->mbc_ram + gb->mbc_ram_size - 1) {

View File

@ -155,19 +155,15 @@ const GB_cheat_t *GB_import_cheat(GB_gameboy_t *gb, const char *cheat, const cha
uint8_t dummy;
/* GameShark */
if (strlen(cheat) == 8) {
#ifdef _WIN32
// The hh modifier is not supported on old MSVCRT, it's completely ignored
uint32_t bank = 0;
uint32_t value = 0;
#pragma GCC diagnostic ignored "-Wformat"
#else
uint8_t bank;
uint8_t value;
#endif
uint16_t address;
if (sscanf(cheat, "%02hhx%02hhx%04hx%c", &bank, &value, &address, &dummy) == 3) {
if (bank >= 0x80) {
bank &= 0xF;
}
address = __builtin_bswap16(address);
return GB_add_cheat(gb, description, address, bank == 1? GB_CHEAT_ANY_BANK : (bank & 0xF), value, 0, false, enabled);
return GB_add_cheat(gb, description, address, bank, value, 0, false, enabled);
}
}
@ -185,13 +181,8 @@ const GB_cheat_t *GB_import_cheat(GB_gameboy_t *gb, const char *cheat, const cha
stripped_cheat[7] = stripped_cheat[8];
stripped_cheat[8] = 0;
#ifdef _WIN32
uint32_t old_value = 0;
uint32_t value = 0;
#else
uint8_t old_value;
uint8_t value;
#endif
uint16_t address;
if (strlen(stripped_cheat) != 8 && strlen(stripped_cheat) != 6) {
return NULL;

View File

@ -128,7 +128,7 @@ static inline void switch_banking_state(GB_gameboy_t *gb, uint16_t bank)
}
}
static const char *value_to_string(GB_gameboy_t *gb, uint16_t value, bool prefer_name, bool prefer_local, bool prefer_no_padding)
static const char *value_to_string(GB_gameboy_t *gb, uint16_t value, bool prefer_name, bool prefer_local)
{
static __thread char output[256];
const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, value, prefer_local);
@ -138,13 +138,9 @@ static const char *value_to_string(GB_gameboy_t *gb, uint16_t value, bool prefer
}
if (!symbol) {
if (prefer_no_padding) {
snprintf(output, sizeof(output), "$%x", value);
}
else {
snprintf(output, sizeof(output), "$%04x", value);
}
snprintf(output, sizeof(output), "$%04x", value);
}
else if (symbol->addr == value) {
if (prefer_name) {
snprintf(output, sizeof(output), "%s ($%04x)", symbol->name, value);
@ -175,7 +171,7 @@ static GB_symbol_map_t *get_symbol_map(GB_gameboy_t *gb, uint16_t bank)
static const char *debugger_value_to_string(GB_gameboy_t *gb, value_t value, bool prefer_name, bool prefer_local)
{
if (!value.has_bank) return value_to_string(gb, value.value, prefer_name, prefer_local, false);
if (!value.has_bank) return value_to_string(gb, value.value, prefer_name, prefer_local);
static __thread char output[256];
const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, value.bank), value.value, prefer_local);
@ -905,11 +901,11 @@ static bool registers(GB_gameboy_t *gb, char *arguments, char *modifiers, const
(gb->f & GB_HALF_CARRY_FLAG)? 'H' : '-',
(gb->f & GB_SUBTRACT_FLAG)? 'N' : '-',
(gb->f & GB_ZERO_FLAG)? 'Z' : '-');
GB_log(gb, "BC = %s\n", value_to_string(gb, gb->bc, false, false, false));
GB_log(gb, "DE = %s\n", value_to_string(gb, gb->de, false, false, false));
GB_log(gb, "HL = %s\n", value_to_string(gb, gb->hl, false, false, false));
GB_log(gb, "SP = %s\n", value_to_string(gb, gb->sp, false, false, false));
GB_log(gb, "PC = %s\n", value_to_string(gb, gb->pc, false, false, false));
GB_log(gb, "BC = %s\n", value_to_string(gb, gb->bc, false, false));
GB_log(gb, "DE = %s\n", value_to_string(gb, gb->de, false, false));
GB_log(gb, "HL = %s\n", value_to_string(gb, gb->hl, false, false));
GB_log(gb, "SP = %s\n", value_to_string(gb, gb->sp, false, false));
GB_log(gb, "PC = %s\n", value_to_string(gb, gb->pc, false, false));
GB_log(gb, "IME = %s\n", gb->ime? "Enabled" : "Disabled");
return true;
}
@ -1466,10 +1462,10 @@ static bool print(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
return true;
}
if (!modifiers) {
modifiers = "";
if (!modifiers || !modifiers[0]) {
modifiers = "a";
}
else if (modifiers[0] && modifiers[1]) {
else if (modifiers[1]) {
print_usage(gb, command);
return true;
}
@ -1478,12 +1474,6 @@ static bool print(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
value_t result = debugger_evaluate(gb, arguments, (unsigned)strlen(arguments), &error, NULL);
if (!error) {
switch (modifiers[0]) {
case '\0':
if (!result.has_bank) {
GB_log(gb, "=%s\n", value_to_string(gb, result.value, false, false, true));
break;
}
// fallthrough
case 'a':
GB_log(gb, "=%s\n", debugger_value_to_string(gb, result, false, false));
break;
@ -1513,7 +1503,6 @@ static bool print(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
break;
}
default:
print_usage(gb, command);
break;
}
}
@ -1739,49 +1728,6 @@ static bool ticks(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
return true;
}
double GB_debugger_get_frame_cpu_usage(GB_gameboy_t *gb)
{
if (gb->last_frame_busy_cycles || gb->last_frame_idle_cycles) {
return (double)gb->last_frame_busy_cycles / (gb->last_frame_busy_cycles + gb->last_frame_idle_cycles);
}
return 0;
}
double GB_debugger_get_second_cpu_usage(GB_gameboy_t *gb)
{
if (gb->last_second_busy_cycles || gb->last_second_idle_cycles) {
return (double)gb->last_second_busy_cycles / (gb->last_second_busy_cycles + gb->last_second_idle_cycles);
}
return 0;
}
double GB_debugger_get_second_cpu_usage(GB_gameboy_t *gb);
static bool usage(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->last_frame_busy_cycles || gb->last_frame_idle_cycles) {
GB_log(gb, "CPU usage (last frame): %.2f%%\n", (double)gb->last_frame_busy_cycles / (gb->last_frame_busy_cycles + gb->last_frame_idle_cycles) * 100);
}
else {
GB_log(gb, "CPU usage (last frame): N/A\n");
}
if (gb->last_second_busy_cycles || gb->last_second_idle_cycles) {
GB_log(gb, "CPU usage (last 60 frames): %.2f%%\n", (double)gb->last_second_busy_cycles / (gb->last_second_busy_cycles + gb->last_second_idle_cycles) * 100);
}
else {
GB_log(gb, "CPU usage (last 60 frames): N/A\n");
}
return true;
}
static bool palettes(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugger_command_t *command)
{
@ -2212,7 +2158,7 @@ static const debugger_command_t commands[] = {
{"backtrace", 2, backtrace, "Display the current call stack"},
{"bt", 2, }, /* Alias */
{"print", 1, print, "Evaluate and print an expression. "
"Use modifier to format as an address (a) or as a number in "
"Use modifier to format as an address (a, default) or as a number in "
"decimal (d), hexadecimal (x), octal (o) or binary (b).",
"<expression>", "format", .argument_completer = symbol_completer, .modifiers_completer = format_completer},
{"eval", 2, }, /* Alias */
@ -2238,7 +2184,6 @@ static const debugger_command_t commands[] = {
{"ticks", 2, ticks, "Display the number of CPU ticks since the last time 'ticks' was "
"used. Use 'keep' as an argument to display ticks without reseeting "
"the count.", "(keep)", .argument_completer = keep_completer},
{"usage", 2, usage, "Display CPU usage"},
{"cartridge", 2, mbc, "Display information about the MBC and cartridge"},
{"mbc", 3, }, /* Alias */
{"apu", 3, apu, "Display information about the current state of the audio processing unit",
@ -2385,10 +2330,10 @@ static void test_watchpoint(GB_gameboy_t *gb, uint16_t addr, uint8_t flags, uint
condition_ok:
GB_debugger_break(gb);
if (flags == WATCHPOINT_READ) {
GB_log(gb, "Watchpoint %u: [%s]\n", watchpoint->id, value_to_string(gb, addr, true, false, false));
GB_log(gb, "Watchpoint %u: [%s]\n", watchpoint->id, value_to_string(gb, addr, true, false));
}
else {
GB_log(gb, "Watchpoint %u: [%s] = $%02x\n", watchpoint->id, value_to_string(gb, addr, true, false, false), value);
GB_log(gb, "Watchpoint %u: [%s] = $%02x\n", watchpoint->id, value_to_string(gb, addr, true, false), value);
}
return;
}
@ -2588,7 +2533,7 @@ next_command:
unsigned breakpoint_id = 0;
if (gb->breakpoints && !gb->debug_stopped && (breakpoint_id = should_break(gb, gb->pc, false))) {
GB_debugger_break(gb);
GB_log(gb, "Breakpoint %u: PC = %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false, false));
GB_log(gb, "Breakpoint %u: PC = %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false));
GB_cpu_disassemble(gb, gb->pc, 5);
}
@ -2599,7 +2544,7 @@ next_command:
bool should_delete_state = true;
if (jump_to_result == JUMP_TO_BREAK) {
GB_debugger_break(gb);
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, address, true, false, false));
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, address, true, false));
GB_cpu_disassemble(gb, gb->pc, 5);
gb->non_trivial_jump_breakpoint_occured = false;
}
@ -2609,7 +2554,7 @@ next_command:
}
else {
gb->non_trivial_jump_breakpoint_occured = true;
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false, false));
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false));
GB_load_state_from_buffer(gb, gb->nontrivial_jump_state, -1);
GB_rewind_push(gb);
GB_cpu_disassemble(gb, gb->pc, 5);
@ -2775,9 +2720,6 @@ const char *GB_debugger_describe_address(GB_gameboy_t *gb,
if (bank == (uint16_t)-1) {
bank = bank_for_addr(gb, addr);
}
if ((addr >> 12) == 0xC) {
bank = 0;
}
if (exact_match) {
const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, bank), addr, prefer_local);
if (symbol && symbol->addr == addr) return symbol->name;

View File

@ -25,9 +25,6 @@ void GB_debugger_set_disabled(GB_gameboy_t *gb, bool disabled);
void GB_debugger_clear_symbols(GB_gameboy_t *gb);
void GB_debugger_set_reload_callback(GB_gameboy_t *gb, GB_debugger_reload_callback_t callback);
double GB_debugger_get_frame_cpu_usage(GB_gameboy_t *gb);
double GB_debugger_get_second_cpu_usage(GB_gameboy_t *gb);
#ifdef GB_INTERNAL
internal void GB_debugger_run(GB_gameboy_t *gb);
internal void GB_debugger_handle_async_commands(GB_gameboy_t *gb);

View File

@ -4,18 +4,13 @@
#define GB_unlikely(x) __builtin_expect((bool)(x), 0)
#define GB_inline_const(type, ...) (*({static const typeof(type) _= __VA_ARGS__; &_;}))
#if !defined(typeof)
#if defined(__cplusplus) || __STDC_VERSION__ < 202311
#define typeof __typeof__
#endif
#endif
#ifdef GB_INTERNAL
// "Keyword" definitions
#define likely(x) GB_likely(x)
#define unlikely(x) GB_unlikely(x)
#define inline_const GB_inline_const
#define typeof __typeof__
#if !defined(MIN)
#define MIN(A, B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })

View File

@ -176,34 +176,13 @@ void GB_display_vblank(GB_gameboy_t *gb, GB_vblank_type_t type)
gb->cycles_since_vblank_callback = 0;
gb->lcd_disabled_outside_of_vblank = false;
#ifndef GB_DISABLE_DEBUGGER
gb->last_frame_idle_cycles = gb->current_frame_idle_cycles;
gb->last_frame_busy_cycles = gb->current_frame_busy_cycles;
gb->current_frame_idle_cycles = 0;
gb->current_frame_busy_cycles = 0;
if (gb->usage_frame_count++ == 60) {
gb->last_second_idle_cycles = gb->current_second_idle_cycles;
gb->last_second_busy_cycles = gb->current_second_busy_cycles;
gb->current_second_idle_cycles = 0;
gb->current_second_busy_cycles = 0;
gb->usage_frame_count = 0;
}
#endif
/* TODO: Slow in turbo mode! */
if (GB_is_hle_sgb(gb)) {
GB_sgb_render(gb);
}
if (gb->turbo) {
#ifndef GB_DISABLE_DEBUGGER
if (unlikely(gb->backstep_instructions)) return;
#endif
if (GB_timing_sync_turbo(gb)) {
if (gb->vblank_callback && gb->enable_skipped_frame_vblank_callbacks) {
gb->vblank_callback(gb, GB_VBLANK_TYPE_SKIPPED_FRAME);
}
return;
}
}
@ -2491,8 +2470,3 @@ double GB_get_usual_frame_rate(GB_gameboy_t *gb)
{
return GB_get_clock_rate(gb) / (double)LCDC_PERIOD;
}
void GB_set_enable_skipped_frame_vblank_callbacks(GB_gameboy_t *gb, bool enable)
{
gb->enable_skipped_frame_vblank_callbacks = enable;
}

View File

@ -20,7 +20,6 @@ typedef enum {
GB_VBLANK_TYPE_LCD_OFF, // An artificial frame pushed while the LCD was off
GB_VBLANK_TYPE_ARTIFICIAL, // An artificial frame pushed for some other reason
GB_VBLANK_TYPE_REPEAT, // A frame that would not render on actual hardware, but the screen should retain the previous frame
GB_VBLANK_TYPE_SKIPPED_FRAME, // If enabled via GB_set_enable_skipped_frame_vblank_callbacks, called on skipped frames during turbo mode
} GB_vblank_type_t;
typedef void (*GB_vblank_callback_t)(GB_gameboy_t *gb, GB_vblank_type_t type);
@ -96,7 +95,6 @@ static const GB_color_correction_mode_t __attribute__((deprecated("Use GB_COLOR_
static const GB_color_correction_mode_t __attribute__((deprecated("Use GB_COLOR_CORRECTION_MODERN_BOOST_CONTRAST instead"))) GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS = GB_COLOR_CORRECTION_MODERN_BOOST_CONTRAST;
void GB_set_vblank_callback(GB_gameboy_t *gb, GB_vblank_callback_t callback);
void GB_set_enable_skipped_frame_vblank_callbacks(GB_gameboy_t *gb, bool enable);
void GB_set_rgb_encode_callback(GB_gameboy_t *gb, GB_rgb_encode_callback_t callback);
void GB_set_palette(GB_gameboy_t *gb, const GB_palette_t *palette);
const GB_palette_t *GB_get_palette(GB_gameboy_t *gb);

View File

@ -1222,10 +1222,8 @@ uint64_t GB_run_frame(GB_gameboy_t *gb)
/* Configure turbo temporarily, the user wants to handle FPS capping manually. */
bool old_turbo = gb->turbo;
bool old_dont_skip = gb->turbo_dont_skip;
double old_turbo_cap = gb->turbo_cap_multiplier;
gb->turbo = true;
gb->turbo_dont_skip = true;
gb->turbo_cap_multiplier = 0;
gb->cycles_since_last_sync = 0;
while (true) {
@ -1236,7 +1234,6 @@ uint64_t GB_run_frame(GB_gameboy_t *gb)
}
gb->turbo = old_turbo;
gb->turbo_dont_skip = old_dont_skip;
gb->turbo_cap_multiplier = old_turbo_cap;
return gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
}
@ -1421,11 +1418,6 @@ void GB_set_turbo_mode(GB_gameboy_t *gb, bool on, bool no_frame_skip)
gb->turbo_dont_skip = no_frame_skip;
}
void GB_set_turbo_cap(GB_gameboy_t *gb, double multiplier)
{
gb->turbo_cap_multiplier = multiplier;
}
void GB_set_rendering_disabled(GB_gameboy_t *gb, bool disabled)
{
gb->disable_rendering = disabled;

View File

@ -697,7 +697,6 @@ struct GB_gameboy_internal_s {
/* Timing */
uint64_t last_sync;
uint64_t last_render;
uint64_t cycles_since_last_sync; // In 8MHz units
GB_rtc_mode_t rtc_mode;
uint32_t rtc_second_length;
@ -783,14 +782,6 @@ struct GB_gameboy_internal_s {
/* Callbacks */
GB_debugger_reload_callback_t debugger_reload_callback;
/* CPU usage */
uint32_t current_frame_idle_cycles, current_frame_busy_cycles;
uint32_t last_frame_idle_cycles, last_frame_busy_cycles;
uint32_t current_second_idle_cycles, current_second_busy_cycles;
uint32_t last_second_idle_cycles, last_second_busy_cycles;
uint8_t usage_frame_count;
#endif
#ifndef GB_DISABLE_REWIND
@ -831,8 +822,6 @@ struct GB_gameboy_internal_s {
/* Misc */
bool turbo;
bool turbo_dont_skip;
double turbo_cap_multiplier;
bool enable_skipped_frame_vblank_callbacks;
bool disable_rendering;
uint8_t boot_rom[0x900];
bool vblank_just_occured; // For slow operations involving syscalls; these should only run once per vblank
@ -952,7 +941,6 @@ void GB_load_battery_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t
int GB_load_battery(GB_gameboy_t *gb, const char *path);
void GB_set_turbo_mode(GB_gameboy_t *gb, bool on, bool no_frame_skip);
void GB_set_turbo_cap(GB_gameboy_t *gb, double multiplier); // Use 0 to use no cap
void GB_set_rendering_disabled(GB_gameboy_t *gb, bool disabled);
void GB_log(GB_gameboy_t *gb, const char *fmt, ...) __printflike(2, 3);

View File

@ -551,7 +551,6 @@ static const uint8_t *get_header_bank(GB_gameboy_t *gb)
static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file, bool append_bess)
{
errno = 0;
if (file->write(file, GB_GET_SECTION(gb, header), GB_SECTION_SIZE(header)) != GB_SECTION_SIZE(header)) goto error;
if (!DUMP_SECTION(gb, file, core_state)) goto error;
if (!DUMP_SECTION(gb, file, dma )) goto error;
@ -839,10 +838,8 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file, bool appe
goto error;
}
return 0;;
error:
if (errno == 0) return EIO;
return errno;
return 0;
}
int GB_save_state(GB_gameboy_t *gb, const char *path)

View File

@ -47,10 +47,10 @@ bool GB_timing_sync_turbo(GB_gameboy_t *gb)
#endif
if (!gb->turbo_dont_skip) {
int64_t nanoseconds = get_nanoseconds();
if (nanoseconds <= gb->last_render + 1000000000 / 60) {
if (nanoseconds <= gb->last_sync + (1000000000LL * LCDC_PERIOD / GB_get_clock_rate(gb))) {
return true;
}
gb->last_render = nanoseconds;
gb->last_sync = nanoseconds;
}
return false;
}
@ -63,32 +63,23 @@ void GB_timing_sync(GB_gameboy_t *gb)
/* Prevent syncing if not enough time has passed.*/
if (gb->cycles_since_last_sync < LCDC_PERIOD / 3) return;
unsigned target_clock_rate;
if (gb->turbo) {
if (gb->turbo_cap_multiplier) {
target_clock_rate = GB_get_clock_rate(gb) * gb->turbo_cap_multiplier;
gb->cycles_since_last_sync = 0;
if (gb->update_input_hint_callback) {
gb->update_input_hint_callback(gb);
}
else {
gb->cycles_since_last_sync = 0;
if (gb->update_input_hint_callback) {
gb->update_input_hint_callback(gb);
}
return;
}
}
else {
target_clock_rate = GB_get_clock_rate(gb);
return;
}
uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / 2 / target_clock_rate; /* / 2 because we use 8MHz units */
uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
int64_t nanoseconds = get_nanoseconds();
int64_t time_to_sleep = target_nanoseconds + gb->last_sync - nanoseconds;
if (time_to_sleep > 0 && time_to_sleep < LCDC_PERIOD * 1200000000LL / target_clock_rate) { // +20% to be more forgiving
if (time_to_sleep > 0 && time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) { // +20% to be more forgiving
nsleep(time_to_sleep);
gb->last_sync += target_nanoseconds;
}
else {
if (time_to_sleep < 0 && -time_to_sleep < LCDC_PERIOD * 1200000000LL / target_clock_rate) {
if (time_to_sleep < 0 && -time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) {
// We're running a bit too slow, but the difference is small enough,
// just skip this sync and let it even out
return;
@ -481,8 +472,6 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
#ifndef GB_DISABLE_DEBUGGER
gb->absolute_debugger_ticks += cycles;
*((gb->halted || gb->stopped)? &gb->current_frame_idle_cycles : &gb->current_frame_busy_cycles) += cycles;
*((gb->halted || gb->stopped)? &gb->current_second_idle_cycles : &gb->current_second_busy_cycles) += cycles;
#endif
// Not affected by speed boost

View File

@ -473,7 +473,7 @@ static inline Class preferredByteArrayClass(void) {
}
- (void)_setSingleSelectedContentsRange:(HFRange)newSelection {
if (!HFRangeIsSubrangeOfRange(newSelection, HFRangeMake(0, [self contentsLength]))) return;
HFASSERT(HFRangeIsSubrangeOfRange(newSelection, HFRangeMake(0, [self contentsLength])));
BOOL selectionChanged;
if ([selectedContentsRanges count] == 1) {
selectionChanged = ! HFRangeEqualsRange([selectedContentsRanges[0] HFRange], newSelection);

View File

@ -36,14 +36,10 @@ else
DEFAULT := sdl
endif
NULL := /dev/null
ifeq ($(PLATFORM),windows32)
ifneq ($(shell echo /dev/null*),/dev/null)
# Windows shell is not "aware" of /dev/null, use NUL and pray
NULL := NUL
endif
endif
PREFIX ?= /usr/local
ifneq ($(shell which xdg-open 2> $(NULL))$(FREEDESKTOP),)
@ -100,8 +96,15 @@ else
CPPP_FLAGS += -UGB_DISABLE_CHEAT_SEARCH
endif
ifneq ($(CORE_FILTER)$(DISABLE_TIMEKEEPING),)
ifneq ($(MAKECMDGOALS),lib)
$(error SameBoy features can only be disabled when compiling the 'lib' target)
endif
endif
CPPP_FLAGS += -UGB_INTERNAL
include version.mk
COPYRIGHT_YEAR := $(shell grep -oE "20[2-9][0-9]" LICENSE)
export VERSION
@ -114,12 +117,6 @@ LIBDIR := build/lib
PKGCONF_DIR := $(LIBDIR)/pkgconfig
PKGCONF_FILE := $(PKGCONF_DIR)/sameboy.pc
ifneq ($(CORE_FILTER)$(DISABLE_TIMEKEEPING),)
ifneq ($(filter-out lib headers $(LIBDIR)/% $(INC)/%,$(MAKECMDGOALS)),)
$(error SameBoy features can only be disabled when compiling the 'lib' target)
endif
endif
BOOTROMS_DIR ?= $(BIN)/BootROMs
ifdef DATA_DIR
@ -135,8 +132,6 @@ CC := clang
endif
endif
IBTOOL ?= ibtool
# Find libraries with pkg-config if available.
ifneq (, $(shell which pkg-config 2> $(NULL)))
# But not on macOS, it's annoying, and not on Haiku, where OpenGL is broken
@ -215,10 +210,9 @@ CFLAGS += -DUPDATE_SUPPORT
endif
ifeq (,$(PKG_CONFIG))
ifneq ($(PLATFORM),windows32)
SDL_CFLAGS := $(shell sdl2-config --cflags)
SDL_LDFLAGS := $(shell sdl2-config --libs) -lpthread
endif
ifeq ($(PLATFORM),Darwin)
SDL_LDFLAGS += -framework AppKit
endif
@ -288,13 +282,11 @@ sdl: $(BIN)/SDL/xaudio2_9redist.dll
endif
else
LDFLAGS += -lc -lm
# libdl is not available as a standalone library in Haiku or OpenBSD
# libdl is not available as a standalone library in Haiku
ifneq ($(PLATFORM),Haiku)
ifneq ($(PLATFORM),OpenBSD)
LDFLAGS += -ldl
endif
endif
endif
ifeq ($(MAKECMDGOALS),_ios)
OBJ := build/obj-ios
@ -437,8 +429,7 @@ SDL_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(SDL_SOURCES))
TESTER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(TESTER_SOURCES))
XDG_THUMBNAILER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(XDG_THUMBNAILER_SOURCES)) $(OBJ)/XdgThumbnailer/resources.c.o
lib: headers
headers: $(PUBLIC_HEADERS)
lib: $(PUBLIC_HEADERS)
# Automatic dependency generation
@ -550,10 +541,9 @@ $(OBJ)/installer: iOS/installer.m
# Cocoa Port
$(BIN)/SameBoy.app: $(BIN)/SameBoy.app/Contents/MacOS/SameBoy \
$(shell ls Cocoa/*.icns Cocoa/*.png Cocoa/*.car) \
$(shell ls Cocoa/*.icns Cocoa/*.png) \
Cocoa/License.html \
Cocoa/Info.plist \
Cocoa/SameBoy.entitlements \
Misc/registers.sym \
$(BIN)/SameBoy.app/Contents/Resources/dmg_boot.bin \
$(BIN)/SameBoy.app/Contents/Resources/mgb_boot.bin \
@ -568,13 +558,15 @@ $(BIN)/SameBoy.app: $(BIN)/SameBoy.app/Contents/MacOS/SameBoy \
$(BIN)/SameBoy.app/Contents/PlugIns/Previewer.appex \
Shaders
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Resources
cp Cocoa/*.icns Cocoa/*.png Cocoa/*.car Misc/registers.sym $(BIN)/SameBoy.app/Contents/Resources/
cp Cocoa/*.icns Cocoa/*.png Misc/registers.sym $(BIN)/SameBoy.app/Contents/Resources/
sed "s/@VERSION/$(VERSION)/;s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < Cocoa/Info.plist > $(BIN)/SameBoy.app/Contents/Info.plist
sed "s/@COPYRIGHT_YEAR/$(COPYRIGHT_YEAR)/" < Cocoa/License.html > $(BIN)/SameBoy.app/Contents/Resources/Credits.html
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Resources/Shaders
cp Shaders/*.fsh Shaders/*.metal $(BIN)/SameBoy.app/Contents/Resources/Shaders
$(MKDIR) -p $(BIN)/SameBoy.app/Contents/Library/QuickLook/
$(CODESIGN) $@ --entitlements Cocoa/SameBoy.entitlements
ifeq ($(CONF), release)
$(CODESIGN) $@
endif
# We place the dylib inside the Quick Look plugin, because Quick Look plugins run in a very strict sandbox
@ -591,10 +583,10 @@ ifeq ($(CONF), release)
endif
$(BIN)/SameBoy.app/Contents/Resources/%.nib: Cocoa/%.xib
$(IBTOOL) --target-device mac --minimum-deployment-target 10.9 --compile $@ $^ 2>&1 | cat -
ibtool --target-device mac --minimum-deployment-target 10.9 --compile $@ $^ 2>&1 | cat -
$(BIN)/SameBoy-iOS.app/%.storyboardc: iOS/%.storyboard
$(IBTOOL) --target-device iphone --target-device ipad --minimum-deployment-target $(IOS_MIN) --compile $@ $^ 2>&1 | cat -
ibtool --target-device iphone --target-device ipad --minimum-deployment-target $(IOS_MIN) --compile $@ $^ 2>&1 | cat -
# Quick Look generators
@ -674,11 +666,11 @@ $(BIN)/SDL/sameboy.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.
$(BIN)/SDL/sameboy_debugger.txt:
echo Looking for sameboy_debugger.exe? > $@
echo >> $@
echo\>> $@
echo Starting with SameBoy v1.0.1, sameboy.exe and sameboy_debugger.exe >> $@
echo have been merged into a single executable. You can open a debugger >> $@
echo console at any time by pressing Ctrl+C to interrupt the currently >> $@
echo open ROM. Once you\'re done debugging, you can close the debugger >> $@
echo open ROM. Once you're done debugging, you can close the debugger >> $@
echo console and resume normal execution. >> $@
ifneq ($(USE_WINDRES),)
@ -691,13 +683,13 @@ $(OBJ)/%.res: %.rc
rc /fo $@ /dVERSION=\"$(VERSION)\" /dCOPYRIGHT_YEAR=\"$(COPYRIGHT_YEAR)\" $^
%.o: %.res
cvtres /MACHINE:X64 /OUT:"$@" $^
cvtres /OUT:"$@" $^
endif
# Copy required DLL files for the Windows port
$(BIN)/SDL/%.dll:
-@$(MKDIR) -p $(dir $@)
@$(eval MATCH := $(shell where "$(lib)":$(notdir $@)))
@$(eval MATCH := $(shell where $$LIB:$(notdir $@)))
cp "$(MATCH)" $@
# Tester
@ -789,7 +781,7 @@ install: $(BIN)/XdgThumbnailer/sameboy-thumbnailer sdl $(shell find FreeDesktop)
install -d $(DESTDIR)$(DATA_DIR)/BootROMs
install -d $(DESTDIR)$(PREFIX)/bin
install -d $(DESTDIR)$(PREFIX)/share/thumbnailers
install -d $(DESTDIR)$(PREFIX)/share/mime/packages
install -d $(DESTDIR)$(PREFIX)/share/mime
install -d $(DESTDIR)$(PREFIX)/share/applications
(cd $(BIN)/SDL && find . \! -name sameboy -type f -exec install -m 644 {} "$(abspath $(DESTDIR))$(DATA_DIR)/{}" \; )
@ -805,7 +797,7 @@ ifeq ($(DESTDIR),)
xdg-icon-resource install --novendor --theme hicolor --size $$size --context mimetypes FreeDesktop/ColorCartridge/$${size}x$${size}.png x-gameboy-color-rom; \
done
else
install -m 644 FreeDesktop/sameboy.xml $(DESTDIR)$(PREFIX)/share/mime/packages/sameboy.xml
install -m 644 FreeDesktop/sameboy.xml $(DESTDIR)$(PREFIX)/share/mime/sameboy.xml
install -m 644 FreeDesktop/sameboy.desktop $(DESTDIR)$(PREFIX)/share/applications/sameboy.desktop
for size in 16x16 32x32 64x64 128x128 256x256 512x512; do \
install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/$$size/apps; \

View File

@ -47,9 +47,8 @@ SameBoy requires the following tools and libraries to build:
On Windows, SameBoy also requires:
* Visual Studio (For headers, etc.)
* [Git Bash](https://git-scm.com/downloads/win) or another distribution of basic Unix utilities
* Git Bash does not include make, you can get it [here](https://sourceforge.net/projects/ezwinports/files/make-4.4.1-without-guile-w32-bin.zip/download).
* Running `vcvars64.bat` or `vcvarsx86_amd64.bat` before running make. Make sure all required tools, libraries, and headers are in %PATH%, %lib%, and %include%`, respectively. (see [Build FAQ](https://github.com/LIJI32/SameBoy/blob/master/build-faq.md) for more details on Windows compilation)
* [GnuWin](http://gnuwin32.sourceforge.net/)
* Running vcvars64 before running make. Make sure all required tools and libraries are in %PATH% and %lib%, respectively. (see [Build FAQ](https://github.com/LIJI32/SameBoy/blob/master/build-faq.md) for more details on Windows compilation)
To compile, simply run `make`. The targets are:
* `cocoa` (Default for macOS)

View File

@ -161,10 +161,6 @@ typedef struct {
/* v1.0.1 */
bool disable_rounded_corners; // Windows only
bool use_faux_analog_inputs;
/* v1.0.2 */
int8_t vsync_mode;
uint8_t turbo_cap;
};
} configuration_t;

View File

@ -1173,45 +1173,6 @@ static const char *current_agb_revision_string(unsigned index)
return "CPU AGB A (AGB)";
}
static void cycle_turbo_cap(unsigned index)
{
if (configuration.turbo_cap >= 16) { // 400%
configuration.turbo_cap = 0; // uncapped
}
else if (configuration.turbo_cap == 0) { // uncapped
configuration.turbo_cap = 6; // 150%
}
else {
configuration.turbo_cap++;
}
}
static void cycle_turbo_cap_backwards(unsigned index)
{
if (configuration.turbo_cap == 0) { // uncapped
configuration.turbo_cap = 16; // 400%
}
else if (configuration.turbo_cap == 6) { // 150%
configuration.turbo_cap = 0; // uncapped
}
else {
configuration.turbo_cap--;
}
}
static const char *current_turbo_cap_string(unsigned index)
{
if (configuration.turbo_cap == 0) {
return "Uncapped";
}
static char ret[5];
snprintf(ret, sizeof(ret), "%d%%", configuration.turbo_cap * 25);
return ret;
}
static const struct menu_item emulation_menu[] = {
{"Emulated Model:", cycle_model, current_model_string, cycle_model_backwards},
{"SGB Revision:", cycle_sgb_revision, current_sgb_revision_string, cycle_sgb_revision_backwards},
@ -1220,7 +1181,6 @@ static const struct menu_item emulation_menu[] = {
{"Boot ROMs Folder:", toggle_bootrom, current_bootrom_string, toggle_bootrom},
{"Rewind Length:", cycle_rewind, current_rewind_string, cycle_rewind_backwards},
{"Real Time Clock:", toggle_rtc_mode, current_rtc_mode_string, toggle_rtc_mode},
{"Turbo speed cap:", cycle_turbo_cap, current_turbo_cap_string, cycle_turbo_cap_backwards},
{"Back", enter_options_menu},
{NULL,}
};
@ -1638,40 +1598,6 @@ static const char *current_osd_mode(unsigned index)
return configuration.osd? "Enabled" : "Disabled";
}
static const char *current_vsync_mode(unsigned index)
{
switch (configuration.vsync_mode) {
default:
case 0: return "Disabled";
case 1: return "Enabled";
case -1: return "Adaptive";
}
}
static void cycle_vsync(unsigned index)
{
retry:
configuration.vsync_mode++;
if (configuration.vsync_mode == 2) {
configuration.vsync_mode = -1;
}
if (SDL_GL_SetSwapInterval(configuration.vsync_mode) && configuration.vsync_mode != 0) {
goto retry;
}
}
static void cycle_vsync_backwards(unsigned index)
{
retry:
configuration.vsync_mode--;
if (configuration.vsync_mode == -2) {
configuration.vsync_mode = 1;
}
if (SDL_GL_SetSwapInterval(configuration.vsync_mode) && configuration.vsync_mode != 0) {
goto retry;
}
}
#ifdef _WIN32
// Don't use the standard header definitions because we might not have the newest headers
@ -1726,7 +1652,6 @@ static const struct menu_item graphics_menu[] = {
{"Mono Palette:", cycle_palette, current_palette, cycle_palette_backwards},
{"Display Border:", cycle_border_mode, current_border_mode, cycle_border_mode_backwards},
{"On-Screen Display:", toggle_osd, current_osd_mode, toggle_osd},
{"Vsync Mode:", cycle_vsync, current_vsync_mode, cycle_vsync_backwards},
#ifdef _WIN32
{"Window Corners:", toggle_corners, current_corner_mode, toggle_corners},
#endif
@ -2391,10 +2316,6 @@ void run_gui(bool is_running)
case SDL_SCANCODE_LEFT:
case SDL_SCANCODE_UP:
case SDL_SCANCODE_DOWN:
case SDL_SCANCODE_H:
case SDL_SCANCODE_J:
case SDL_SCANCODE_K:
case SDL_SCANCODE_L:
break;
default:
@ -2782,16 +2703,12 @@ void run_gui(bool is_running)
}
}
else if (gui_state == SHOWING_MENU) {
if ((event.key.keysym.scancode == SDL_SCANCODE_DOWN ||
event.key.keysym.scancode == SDL_SCANCODE_J) &&
current_menu[current_selection + 1].string) {
if (event.key.keysym.scancode == SDL_SCANCODE_DOWN && current_menu[current_selection + 1].string) {
current_selection++;
mouse_scroling = false;
should_render = true;
}
else if ((event.key.keysym.scancode == SDL_SCANCODE_UP ||
event.key.keysym.scancode == SDL_SCANCODE_K) &&
current_selection) {
else if (event.key.keysym.scancode == SDL_SCANCODE_UP && current_selection) {
current_selection--;
mouse_scroling = false;
should_render = true;
@ -2815,15 +2732,11 @@ void run_gui(bool is_running)
return;
}
}
else if ((event.key.keysym.scancode == SDL_SCANCODE_RIGHT ||
event.key.keysym.scancode == SDL_SCANCODE_L) &&
current_menu[current_selection].backwards_handler) {
else if (event.key.keysym.scancode == SDL_SCANCODE_RIGHT && current_menu[current_selection].backwards_handler) {
current_menu[current_selection].handler(current_selection);
should_render = true;
}
else if ((event.key.keysym.scancode == SDL_SCANCODE_LEFT ||
event.key.keysym.scancode == SDL_SCANCODE_H) &&
current_menu[current_selection].backwards_handler) {
else if (event.key.keysym.scancode == SDL_SCANCODE_LEFT && current_menu[current_selection].backwards_handler) {
current_menu[current_selection].backwards_handler(current_selection);
should_render = true;
}

View File

@ -277,7 +277,6 @@ static void open_menu(void)
GB_set_highpass_filter_mode(&gb, configuration.highpass_mode);
GB_set_rewind_length(&gb, configuration.rewind_length);
GB_set_rtc_mode(&gb, configuration.rtc_mode);
GB_set_turbo_cap(&gb, configuration.turbo_cap / 4.0);
if (previous_width != GB_get_screen_width(&gb)) {
signed current_window_width, current_window_height;
SDL_GetWindowSize(window, &current_window_width, &current_window_height);
@ -382,7 +381,6 @@ static void handle_events(GB_gameboy_t *gb)
GB_audio_clear_queue();
turbo_down = event.type == SDL_JOYBUTTONDOWN;
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
SDL_GL_SetSwapInterval(turbo_down? 0 : configuration.vsync_mode);
}
else if (button == JOYPAD_BUTTON_SLOW_MOTION) {
underclock_down = event.type == SDL_JOYBUTTONDOWN;
@ -393,7 +391,6 @@ static void handle_events(GB_gameboy_t *gb)
rewind_paused = false;
}
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
SDL_GL_SetSwapInterval(turbo_down? 0 : configuration.vsync_mode);
}
else if (button == JOYPAD_BUTTON_MENU && event.type == SDL_JOYBUTTONDOWN) {
open_menu();
@ -613,7 +610,6 @@ static void handle_events(GB_gameboy_t *gb)
turbo_down = event.type == SDL_KEYDOWN;
GB_audio_clear_queue();
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
SDL_GL_SetSwapInterval(turbo_down? 0 : configuration.vsync_mode);
}
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_REWIND]) {
rewind_down = event.type == SDL_KEYDOWN;
@ -621,7 +617,6 @@ static void handle_events(GB_gameboy_t *gb)
rewind_paused = false;
}
GB_set_turbo_mode(gb, turbo_down, turbo_down && rewind_down);
SDL_GL_SetSwapInterval(turbo_down? 0 : configuration.vsync_mode);
}
else if (event.key.keysym.scancode == configuration.keys_2[GB_CONF_KEYS2_UNDERCLOCK]) {
underclock_down = event.type == SDL_KEYDOWN;
@ -742,23 +737,15 @@ static void debugger_reset(int ignore)
#endif
static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample)
{
{
if (turbo_down) {
static unsigned skip = 0;
skip++;
if (skip == GB_audio_get_frequency() / 8) {
skip = 0;
}
if (configuration.turbo_cap) {
if (skip > GB_audio_get_frequency() / 8 * 4 / configuration.turbo_cap) {
return;
}
}
else {
if (skip > GB_audio_get_frequency() / 16) {
return;
}
if (skip > GB_audio_get_frequency() / 16) {
return;
}
}
@ -1108,7 +1095,6 @@ restart:;
GB_set_highpass_filter_mode(&gb, configuration.highpass_mode);
GB_set_rewind_length(&gb, configuration.rewind_length);
GB_set_rtc_mode(&gb, configuration.rtc_mode);
GB_set_turbo_cap(&gb, configuration.turbo_cap / 4.0);
GB_set_update_input_hint_callback(&gb, handle_events);
GB_apu_set_sample_callback(&gb, gb_audio_callback);
@ -1396,9 +1382,7 @@ int main(int argc, char **argv)
signal(SIGUSR1, debugger_reset);
#endif
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO) < 0) {
fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
}
SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO);
// This is, essentially, best-effort.
// This function will not be called if the process is terminated in any way, anyhow.
atexit(SDL_Quit);
@ -1552,8 +1536,6 @@ int main(int argc, char **argv)
}
#endif
SDL_GL_SetSwapInterval(configuration.vsync_mode);
if (filename == NULL) {
stop_on_start = false;
run_gui(false);

View File

@ -26,9 +26,9 @@ The following examples will be referenced later:
After downloading [rgbds](https://github.com/gbdev/rgbds/releases/), ensure that it is added to the `%PATH%`. This may be done by adding it to the user's or SYSTEM's Environment Variables, or may be added to the command line at compilation time via `set path=%path%;C:\path\to\rgbds`.
### Git Bash & Make
### GnuWin
Ensure that the `Git\usr\bin` directory is included in `%PATH%`. Like rgbds above, this may instead be manually included on the command line before installation: `set path=%path%;C:\path\to\Git\usr\bin`. Similarly, make sure that the directory containing `make.exe` is also included.
Ensure that the `gnuwin32\bin\` directory is included in `%PATH%`. Like rgbds above, this may instead be manually included on the command line before installation: `set path=%path%;C:\path\to\gnuwin32\bin`.
## Building
@ -40,5 +40,18 @@ set lib=%lib%;C:\SDL2\lib\x64
set include=%include%;C:\SDL2\include
make
```
On some versions of Visual Studio, you might need to use `vcvarsx86_amd64` instead of `vcvars64`. Please note that these directories (`C:\SDL2\*`) are the examples given within the "SDL Port" section above. Ensure that your `%PATH%` properly includes `rgbds` and `Git\usr\bin`, and that the `lib` and `include` paths include the appropriate SDL2 directories.
Please note that these directories (`C:\SDL2\*`) are the examples given within the "SDL Port" section above. Ensure that your `%PATH%` properly includes `rgbds` and `gnuwin32\bin`, and that the `lib` and `include` paths include the appropriate SDL2 directories.
## Common Errors
### Error -1073741819
If encountering an error that appears as follows:
``` make: *** [build/bin/BootROMs/dmg_boot.bin] Error -1073741819```
Simply run `make` again, and the process will continue. This appears to happen occasionally with `build/bin/BootROMs/dmg_boot.bin` and `build/bin/BootROMs/sgb2_boot.bin`. It does not affect the compiled output. This appears to be an issue with GnuWin.
### The system cannot find the file specified (`usr/bin/mkdir`)
If errors arise (i.e., particularly with the `CREATE_PROCESS('usr/bin/mkdir')` calls, also verify that Git for Windows has not been installed with full Linux support. If it has, remove `C:\Program Files\Git\usr\bin` from the SYSTEM %PATH% until after compilation. This happens because the Git for Windows version of `which` is used instead of the GnuWin one, and it returns a Unix-style path instead of a Windows one.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -24,8 +24,7 @@
if (section == 0) return 1;
size_t count;
GB_get_cheats(_gb, &count);
self.toolbarItems[0].enabled = count;
((UIButton *)(self.toolbarItems[0].customView.subviews[0])).enabled = count;
self.toolbarItems.firstObject.enabled = count;
return count;
}
@ -92,11 +91,11 @@
}
else {
alertController.title = @"Invalid cheat code entered";
[self presentViewController:alertController animated:true completion:nil];
[self presentViewController:alertController animated:YES completion:nil];
}
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alertController animated:true completion:nil];
[self presentViewController:alertController animated:YES completion:nil];
}
+ (UIBarButtonItem *)buttonWithLabel:(NSString *)label
@ -120,17 +119,9 @@
[button sizeToFit];
CGRect frame = button.frame;
frame.size.width = ceil(frame.size.width + (label? 4 : 0));
if (@available(iOS 19.0, *)) {
if (label) {
frame.size.width += 12;
}
}
frame.size.height = 28;
button.frame = frame;
UIView *wrapper = [[UIView alloc] initWithFrame:button.bounds];
[wrapper addSubview:button];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:wrapper];
return item;
return [[UIBarButtonItem alloc] initWithCustomView:button];
}
return [[UIBarButtonItem alloc] initWithTitle:label style:UIBarButtonItemStylePlain target:target action:action];
}
@ -162,7 +153,9 @@
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:@[url]
applicationActivities:nil];
controller.popoverPresentationController.barButtonItem = self.toolbarItems.firstObject;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
controller.popoverPresentationController.barButtonItem = self.toolbarItems.firstObject;
}
[self presentViewController:controller
animated:true
@ -185,38 +178,28 @@
hasSFSymbols = true;
}
UIBarButtonItem *export = hasSFSymbols?
[self.class buttonWithLabel:nil
imageWithName:@"square.and.arrow.up"
self.toolbarItems = @[
hasSFSymbols?
[self.class buttonWithLabel:nil
imageWithName:@"square.and.arrow.up"
target:self
action:@selector(exportCheats)] :
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:@selector(exportCheats)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:NULL],
[self.class buttonWithLabel:@"Import"
imageWithName:@"square.and.arrow.down"
target:self
action:@selector(exportCheats)] :
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:@selector(exportCheats)];
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:NULL];
UIBarButtonItem *import = [self.class buttonWithLabel:@"Import"
imageWithName:@"square.and.arrow.down"
target:self
action:@selector(importCheats)];
UIBarButtonItem *add = [self.class buttonWithLabel:@"Add"
imageWithName:@"plus"
target:self
action:@selector(addCheat)];
if (@available(iOS 19.0, *)) {
self.toolbarItems = @[export,
flexItem,
import, [UIBarButtonItem fixedSpaceItemOfWidth:0], add];
}
else {
self.toolbarItems = @[export,
flexItem,
import, add];
}
action:@selector(importCheats)],
[self.class buttonWithLabel:@"Add"
imageWithName:@"plus"
target:self
action:@selector(addCheat)],
];
_gb = gb;
return self;

View File

@ -12,9 +12,6 @@ static double StatusBarHeight(void)
UIEdgeInsets insets = window.safeAreaInsets;
ret = MAX(MAX(insets.left, insets.right), MAX(insets.top, insets.bottom)) ?: 20;
[window setHidden:true];
if (!ret && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
ret = 32; // iPadOS is buggy af
}
}
});
return ret;
@ -50,7 +47,7 @@ static bool HasHomeBar(void)
}
_minY = StatusBarHeight() * _factor;
_cutout = (_minY <= 24 * _factor || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)? 0 : _minY;
_cutout = _minY <= 24 * _factor? 0 : _minY;
if (HasHomeBar()) {
_homeBar = 21 * _factor;

View File

@ -2,6 +2,4 @@
@interface GBMenuViewController : UIAlertController
+ (instancetype)menu;
@property (nonatomic) NSInteger selectedButtonIndex;
@property (nonatomic, strong) NSArray<UIButton *> *menuButtons;
@end

View File

@ -29,7 +29,6 @@ static NSString *const tips[] = {
{
UILabel *_tipLabel;
UIVisualEffectView *_effectView;
NSMutableArray<UIButton *> *_buttons;
}
+ (instancetype)menu
@ -42,8 +41,6 @@ static NSString *const tips[] = {
[ret addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
ret.selectedButtonIndex = -1;
ret->_buttons = [[NSMutableArray alloc] init];
return ret;
}
@ -53,7 +50,6 @@ static NSString *const tips[] = {
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:true];
if (_effectView) return;
static const struct {
NSString *label;
NSString *image;
@ -84,7 +80,6 @@ static NSString *const tips[] = {
button.frame = CGRectMake(round(width * x), height * y, round(width), height);
button.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:button];
[_buttons addObject:button];
if (!buttons[i].selector) {
button.enabled = false;
@ -107,23 +102,10 @@ static NSString *const tips[] = {
[button addTarget:block action:@selector(invoke) forControlEvents:UIControlEventTouchUpInside];
}
self.menuButtons = [_buttons copy];
[self updateSelectedButton];
UIVisualEffect *effect = nil;
/*
// Unfortunately, UIGlassEffect is still very buggy.
if (@available(iOS 19.0, *)) {
effect = [[objc_getClass("UIGlassEffect") alloc] init];
}
else */ {
effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleProminent];
}
_effectView = [[UIVisualEffectView alloc] initWithEffect:nil];
_effectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleProminent]];
_effectView.layer.cornerRadius = 8;
_effectView.layer.masksToBounds = true;
[self.view.window addSubview:_effectView];
[self.view.superview addSubview:_effectView];
_tipLabel = [[UILabel alloc] init];
unsigned tipIndex = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBTipIndex"];
_tipLabel.text = tips[tipIndex % (sizeof(tips) / sizeof(tips[0]))];
@ -131,23 +113,20 @@ static NSString *const tips[] = {
_tipLabel.textColor = [UIColor labelColor];
}
_tipLabel.font = [UIFont systemFontOfSize:14];
_tipLabel.alpha = 0;
_tipLabel.alpha = 0.8;
[[NSUserDefaults standardUserDefaults] setInteger:tipIndex + 1 forKey:@"GBTipIndex"];
_tipLabel.lineBreakMode = NSLineBreakByWordWrapping;
_tipLabel.numberOfLines = 3;
[_effectView.contentView addSubview:_tipLabel];
[self layoutTip];
_effectView.alpha = 0;
[UIView animateWithDuration:0.25 animations:^{
_effectView.effect = effect;
_tipLabel.alpha = 0.8;
_effectView.alpha = 1.0;
}];
}
- (void)layoutTip
{
[_effectView.superview addSubview:_effectView];
UIView *view = self.view.superview;
CGSize outerSize = view.frame.size;
CGSize size = [_tipLabel textRectForBounds:(CGRect){{0, 0},
@ -156,12 +135,8 @@ static NSString *const tips[] = {
limitedToNumberOfLines:3].size;
size.width = ceil(size.width);
_tipLabel.frame = (CGRect){{8, 8}, size};
unsigned topInset = view.window.safeAreaInsets.top;
if (!topInset && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
topInset = 32; // iPadOS is buggy af
}
_effectView.frame = (CGRect) {
{round((outerSize.width - size.width - 16) / 2), topInset + 12},
{round((outerSize.width - size.width - 16) / 2), view.window.safeAreaInsets.top + 12},
{size.width + 16, size.height + 16}
};
}
@ -170,10 +145,7 @@ static NSString *const tips[] = {
- (void)viewWillDisappear:(BOOL)animated
{
[UIView animateWithDuration:0.25 animations:^{
_effectView.effect = nil;
_tipLabel.alpha = 0;
} completion:^(BOOL finished) {
[_effectView removeFromSuperview];
_effectView.alpha = 0;
}];
[super viewWillDisappear:animated];
}
@ -217,116 +189,4 @@ static NSString *const tips[] = {
return [[UIViewController alloc] init];
}
#pragma mark - Vim Navigation
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (NSArray<UIKeyCommand *> *)keyCommands
{
return @[
[UIKeyCommand keyCommandWithInput:@"h" modifierFlags:0 action:@selector(moveLeft)],
[UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow modifierFlags:0 action:@selector(moveLeft)],
[UIKeyCommand keyCommandWithInput:@"j" modifierFlags:0 action:@selector(moveDown)],
[UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow modifierFlags:0 action:@selector(moveDown)],
[UIKeyCommand keyCommandWithInput:@"k" modifierFlags:0 action:@selector(moveUp)],
[UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow modifierFlags:0 action:@selector(moveUp)],
[UIKeyCommand keyCommandWithInput:@"l" modifierFlags:0 action:@selector(moveRight)],
[UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow modifierFlags:0 action:@selector(moveRight)],
[UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:0 action:@selector(activateSelected)],
[UIKeyCommand keyCommandWithInput:@" " modifierFlags:0 action:@selector(activateSelected)],
[UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:0 action:@selector(dismissSelf)],
];
}
- (void)moveLeft
{
if (self.selectedButtonIndex == -1) {
self.selectedButtonIndex = 0;
}
else if (self.selectedButtonIndex % 4 > 0) {
self.selectedButtonIndex--;
}
[self updateSelectedButton];
}
- (void)moveRight
{
if (self.selectedButtonIndex == -1) {
self.selectedButtonIndex = 0;
}
else if (self.selectedButtonIndex % 4 < 3 && self.selectedButtonIndex + 1 < self.menuButtons.count) {
self.selectedButtonIndex++;
}
[self updateSelectedButton];
}
- (void)moveUp
{
if (self.selectedButtonIndex == -1) {
self.selectedButtonIndex = 0;
}
else if (self.selectedButtonIndex >= 4) {
self.selectedButtonIndex -= 4;
}
[self updateSelectedButton];
}
- (void)moveDown
{
if (self.selectedButtonIndex == -1) {
self.selectedButtonIndex = 0;
}
else if (self.selectedButtonIndex + 4 < self.menuButtons.count) {
self.selectedButtonIndex += 4;
}
[self updateSelectedButton];
}
- (void)activateSelected
{
if (self.selectedButtonIndex >= 0 && self.selectedButtonIndex < self.menuButtons.count) {
UIButton *button = self.menuButtons[self.selectedButtonIndex];
if (button.enabled) {
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
}
- (void)updateSelectedButton
{
for (NSInteger i = 0; i < self.menuButtons.count; i++) {
UIButton *button = self.menuButtons[i];
if (i == self.selectedButtonIndex) {
button.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.3];
button.layer.borderWidth = 2.0;
button.layer.borderColor = [UIColor systemBlueColor].CGColor;
if (@available(iOS 19.0, *)) {
button.layer.cornerRadius = 32.0;
}
else {
button.layer.cornerRadius = 8.0;
}
}
else {
button.backgroundColor = [UIColor clearColor];
button.layer.borderWidth = 0.0;
button.layer.borderColor = [UIColor clearColor].CGColor;
}
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
- (void)dismissSelf
{
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
}
@end

View File

@ -10,7 +10,6 @@
@property (readonly) NSString *batterySaveFile;
@property (readonly) NSString *autosaveStateFile;
@property (readonly) NSString *cheatsFile;
@property (readonly) NSArray <NSString *> *forbiddenNames;
@property (readonly) NSString *localRoot;
- (NSString *)stateFile:(unsigned)index;

Some files were not shown because too many files have changed in this diff Show More