Merge branch 'altjit' into develop

# Conflicts:
#	Delta.xcodeproj/project.pbxproj
This commit is contained in:
Riley Testut 2022-05-31 17:41:37 -07:00
commit b134c73301
15 changed files with 404 additions and 22 deletions

View File

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 52;
objects = {
/* Begin PBXAggregateTarget section */
@ -165,6 +165,9 @@
BFFDF03723E3BB2600931B96 /* libSnes9x.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFFDF03623E3BB2600931B96 /* libSnes9x.a */; };
BFFDF03F23E3C28A00931B96 /* libGambatte.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFFDF03D23E3C0F000931B96 /* libGambatte.a */; };
BFFDF04623E3D3A600931B96 /* libMupen64Plus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFFDF04523E3D3A600931B96 /* libMupen64Plus.a */; };
D524F4A1273DE9A100D500B2 /* AltKit in Frameworks */ = {isa = PBXBuildFile; productRef = D524F4A0273DE9A100D500B2 /* AltKit */; };
D524F4A3273DE9C000D500B2 /* ProcessInfo+JIT.swift in Sources */ = {isa = PBXBuildFile; fileRef = D524F4A2273DE9C000D500B2 /* ProcessInfo+JIT.swift */; };
D524F4A5273DEBB400D500B2 /* ServerManager+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = D524F4A4273DEBB400D500B2 /* ServerManager+Delta.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -358,6 +361,8 @@
BFFDF03D23E3C0F000931B96 /* libGambatte.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libGambatte.a; sourceTree = BUILT_PRODUCTS_DIR; };
BFFDF04523E3D3A600931B96 /* libMupen64Plus.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libMupen64Plus.a; sourceTree = BUILT_PRODUCTS_DIR; };
C786AF1D2DDB6223BE2063CC /* Pods-Delta.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Delta.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Delta/Pods-Delta.debug.xcconfig"; sourceTree = "<group>"; };
D524F4A2273DE9C000D500B2 /* ProcessInfo+JIT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+JIT.swift"; sourceTree = "<group>"; };
D524F4A4273DEBB400D500B2 /* ServerManager+Delta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ServerManager+Delta.swift"; sourceTree = "<group>"; };
DC866E433B3BA9AE18ABA1EC /* libPods-Delta.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Delta.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@ -373,6 +378,7 @@
BFDCA1E6244EBAA900B8FBDB /* liblibDeSmuME.a in Frameworks */,
BFCADF1E25D22FE2008D78FB /* Systems.framework in Frameworks */,
BF69FBC923E3A8380051BEEA /* libNestopia.a in Frameworks */,
D524F4A1273DE9A100D500B2 /* AltKit in Frameworks */,
1FA4ABA79AB72914FE414A61 /* libPods-Delta.a in Frameworks */,
BFFDF03F23E3C28A00931B96 /* libGambatte.a in Frameworks */,
BFFDF03723E3BB2600931B96 /* libSnes9x.a in Frameworks */,
@ -403,6 +409,8 @@
BF647A6922FB8FCE0061D76D /* Bundle+SwizzleBundleID.swift */,
BFD1EF3F2336BD8800D197CF /* UIDevice+Processor.swift */,
BFE56E1823EB7BE00014FECD /* UIImage+SymbolFallback.swift */,
D524F4A2273DE9C000D500B2 /* ProcessInfo+JIT.swift */,
D524F4A4273DEBB400D500B2 /* ServerManager+Delta.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -908,6 +916,7 @@
);
name = Delta;
packageProductDependencies = (
D524F4A0273DE9A100D500B2 /* AltKit */,
);
productName = Delta;
productReference = BFFA71D71AAC406100EE9DD1 /* Delta.app */;
@ -957,6 +966,9 @@
Base,
);
mainGroup = BFFA71CE1AAC406100EE9DD1;
packageReferences = (
D524F49F273DE9A100D500B2 /* XCRemoteSwiftPackageReference "AltKit" */,
);
productRefGroup = BFFA71D81AAC406100EE9DD1 /* Products */;
projectDirPath = "";
projectRoot = "";
@ -1148,6 +1160,7 @@
BF04E6FF1DB8625C000F35D3 /* ControllerSkinsViewController.swift in Sources */,
BF5942891E09BC8B0051894B /* _GameCollection.swift in Sources */,
BF34FA111CF1899D006624C7 /* CheatTextView.swift in Sources */,
D524F4A5273DEBB400D500B2 /* ServerManager+Delta.swift in Sources */,
BF1F45AD21AF57BA00EF9895 /* HarmonyMetadataKey+Keys.swift in Sources */,
BFD1EF402336BD8800D197CF /* UIDevice+Processor.swift in Sources */,
BF71CF871FE90006001F1613 /* AppIconShortcutsViewController.swift in Sources */,
@ -1179,6 +1192,7 @@
BF6EE5E91F7C5F860051AD6C /* _GameControllerInputMapping.swift in Sources */,
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */,
D524F4A3273DE9C000D500B2 /* ProcessInfo+JIT.swift in Sources */,
BFDCA1E9244F7E1000B8FBDB /* Delta5ToDelta6.xcmappingmodel in Sources */,
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
BF6EE5EB1F7C5F8F0051AD6C /* GameControllerInputMapping.swift in Sources */,
@ -1407,7 +1421,8 @@
PRODUCT_BUNDLE_IDENTIFIER = com.rileytestut.Delta;
PRODUCT_NAME = Delta;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
@ -1462,9 +1477,10 @@
PROVISIONING_PROFILE_SPECIFIER = "";
STRIP_INSTALLED_PRODUCT = YES;
STRIP_STYLE = "non-global";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_INCLUDE_PATHS = "$(inherited) \"$(SRCROOT)/Cores/GPGXDeltaCore/Sources/GPGXBridge\"";
SWIFT_OBJC_BRIDGING_HEADER = "Delta/Supporting Files/Delta-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
};
name = Release;
@ -1510,6 +1526,25 @@
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
D524F49F273DE9A100D500B2 /* XCRemoteSwiftPackageReference "AltKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/rileytestut/AltKit.git";
requirement = {
kind = revision;
revision = 2fd376df1c79ec06a5c80cc8933da027f65b3148;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
D524F4A0273DE9A100D500B2 /* AltKit */ = {
isa = XCSwiftPackageProductDependency;
package = D524F49F273DE9A100D500B2 /* XCRemoteSwiftPackageReference "AltKit" */;
productName = AltKit;
};
/* End XCSwiftPackageProductDependency section */
/* Begin XCVersionGroup section */
BF4828811F9027B600028B97 /* Delta.xcdatamodeld */ = {
isa = XCVersionGroup;

View File

@ -1,6 +1,15 @@
{
"object": {
"pins": [
{
"package": "AltKit",
"repositoryURL": "https://github.com/rileytestut/AltKit.git",
"state": {
"branch": null,
"revision": "2fd376df1c79ec06a5c80cc8933da027f65b3148",
"version": null
}
},
{
"package": "DeltaCore",
"repositoryURL": "https://github.com/rileytestut/DeltaCore.git",

View File

@ -10,6 +10,7 @@ import UIKit
import DeltaCore
import Harmony
import AltKit
import Fabric
import Crashlytics
@ -63,6 +64,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate
// Controllers
ExternalGameControllerManager.shared.startMonitoring()
// JIT
ServerManager.shared.prepare()
// Notifications
let center = CFNotificationCenterGetDarwinNotifyCenter()
CFNotificationCenterAddObserver(center, nil, ReceivedApplicationState, CFNotificationName.altstoreRequestAppState.rawValue, nil, .deliverImmediately)

View File

@ -1861,10 +1861,48 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Performance" footerTitle="When enabled, Delta will automatically enable JIT when on the same WiFi network as AltServer." id="MyM-jI-qtY" userLabel="Performance">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="SwitchCell" id="uXJ-qB-E2e" customClass="SwitchTableViewCell">
<rect key="frame" x="0.0" y="284" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="uXJ-qB-E2e" id="mkz-9w-FlW">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Use AltJIT" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XPc-dG-N6R">
<rect key="frame" x="16" y="11.5" width="286" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4Y4-gY-MaX">
<rect key="frame" x="310" y="6.5" width="51" height="31"/>
<color key="onTintColor" name="Purple"/>
<connections>
<action selector="toggleAltJITEnabled:" destination="OwL-4c-EEA" eventType="valueChanged" id="lfe-xg-J5o"/>
<action selector="togglePreviewsEnabled:" destination="eHi-aO-uGS" eventType="primaryActionTriggered" id="BKJ-dV-k7X"/>
</connections>
</switch>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="4Y4-gY-MaX" secondAttribute="trailing" id="6Rs-qs-gFM"/>
<constraint firstItem="XPc-dG-N6R" firstAttribute="leading" secondItem="mkz-9w-FlW" secondAttribute="leadingMargin" id="BBM-mW-kez"/>
<constraint firstItem="4Y4-gY-MaX" firstAttribute="centerY" secondItem="mkz-9w-FlW" secondAttribute="centerY" id="CY7-Kt-ggC"/>
<constraint firstItem="4Y4-gY-MaX" firstAttribute="leading" secondItem="XPc-dG-N6R" secondAttribute="trailing" constant="8" symbolic="YES" id="Qce-jc-vX3"/>
<constraint firstItem="XPc-dG-N6R" firstAttribute="centerY" secondItem="mkz-9w-FlW" secondAttribute="centerY" id="Xzp-aR-4Dz"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="switchView" destination="4Y4-gY-MaX" id="NDr-Y9-9RS"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="DS BIOS Files" footerTitle="Delta requires these BIOS files in order to play Nintendo DS games. Tap one to import it from Files." id="ObZ-cl-5sV">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="Bfp-iA-wWE" detailTextLabel="Xpe-sd-GRy" style="IBUITableViewCellStyleValue1" id="ian-1X-SOi">
<rect key="frame" x="0.0" y="284" width="375" height="44"/>
<rect key="frame" x="0.0" y="408" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ian-1X-SOi" id="nE9-5Y-G2k">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -1887,7 +1925,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="fgD-y0-55T" detailTextLabel="b8s-cx-IgW" style="IBUITableViewCellStyleValue1" id="dwT-0T-gFD">
<rect key="frame" x="0.0" y="328" width="375" height="44"/>
<rect key="frame" x="0.0" y="452" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dwT-0T-gFD" id="KEg-18-WYZ">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -1910,7 +1948,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="SIu-zD-qfE" detailTextLabel="CW8-h0-YST" style="IBUITableViewCellStyleValue1" id="Tll-tX-97T">
<rect key="frame" x="0.0" y="372" width="375" height="44"/>
<rect key="frame" x="0.0" y="496" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Tll-tX-97T" id="4ca-AM-jBE">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -1937,7 +1975,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
<tableViewSection headerTitle="DSi BIOS Files" footerTitle="Delta requires these BIOS files in order to play Nintendo DSi games. Tap one to import it from Files." id="SAz-hG-O4G">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="QKd-rm-101" detailTextLabel="pJb-OR-TGs" style="IBUITableViewCellStyleValue1" id="jwN-8n-xgM">
<rect key="frame" x="0.0" y="496" width="375" height="44"/>
<rect key="frame" x="0.0" y="620" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jwN-8n-xgM" id="b29-V1-qt3">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -1960,7 +1998,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="6OX-32-izR" detailTextLabel="2bc-8r-epB" style="IBUITableViewCellStyleValue1" id="3ka-mn-QqR">
<rect key="frame" x="0.0" y="540" width="375" height="44"/>
<rect key="frame" x="0.0" y="664" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="3ka-mn-QqR" id="4ya-QS-s5w">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -1983,7 +2021,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="Czu-qN-Luq" detailTextLabel="eVw-7r-BEf" style="IBUITableViewCellStyleValue1" id="4FF-9a-jq2">
<rect key="frame" x="0.0" y="584" width="375" height="44"/>
<rect key="frame" x="0.0" y="708" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4FF-9a-jq2" id="emb-d3-TgY">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -2006,7 +2044,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="VWi-nu-uMv" detailTextLabel="8JD-uT-eoA" style="IBUITableViewCellStyleValue1" id="we3-0h-uKq">
<rect key="frame" x="0.0" y="628" width="375" height="44"/>
<rect key="frame" x="0.0" y="752" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="we3-0h-uKq" id="cG1-a2-Nez">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="44"/>
@ -2033,7 +2071,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
<tableViewSection headerTitle="" footerTitle="Changing cores may improve performance at the cost of additional features." id="hbM-mL-bIr">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="gray" indentationWidth="10" reuseIdentifier="ChangeCell" textLabel="Jmx-Jw-278" style="IBUITableViewCellStyleDefault" id="p1T-4d-fC3">
<rect key="frame" x="0.0" y="737.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="861.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="p1T-4d-fC3" id="3bs-Bp-nd4">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>

View File

@ -10,11 +10,13 @@ import UIKit
import DeltaCore
import GBADeltaCore
import MelonDSDeltaCore
import Systems
import struct DSDeltaCore.DS
import Roxas
import AltKit
private var kvoContext = 0
@ -167,6 +169,8 @@ class GameViewController: DeltaCore.GameViewController
private var isGyroActive = false
private var presentedGyroAlert = false
private var presentedJITAlert = false
override var shouldAutorotate: Bool {
return !self.isGyroActive
}
@ -205,6 +209,8 @@ class GameViewController: DeltaCore.GameViewController
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.didDeactivateGyro(with:)), name: GBA.didDeactivateGyroNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.emulationDidQuit(with:)), name: EmulatorCore.emulationDidQuitNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.didEnableJIT(with:)), name: ServerManager.didEnableJITNotification, object: nil)
}
deinit
@ -330,6 +336,10 @@ extension GameViewController
UserDefaults.standard.desmumeDeprecatedAlertCount += 1
}
else if self.emulatorCore?.deltaCore == MelonDS.core, ProcessInfo.processInfo.isJITAvailable
{
self.showJITEnabledAlert()
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
@ -474,6 +484,13 @@ extension GameViewController
}
self._isLoadingSaveState = false
if self.emulatorCore?.deltaCore == MelonDS.core, ProcessInfo.processInfo.isJITAvailable
{
self.transitionCoordinator?.animate(alongsideTransition: nil, completion: { (context) in
self.showJITEnabledAlert()
})
}
}
case "unwindToGames":
@ -1085,6 +1102,48 @@ private extension GameViewController
toastView.presentationEdge = .top
toastView.show(in: self.view, duration: duration)
}
func showJITEnabledAlert()
{
guard !self.presentedJITAlert, self.presentedViewController == nil, self.game != nil else { return }
self.presentedJITAlert = true
func presentToastView()
{
let detailText: String?
let duration: TimeInterval
if UserDefaults.standard.jitEnabledAlertCount < 3
{
detailText = NSLocalizedString("You can now Fast Forward DS games up to 3x speed.", comment: "")
duration = 5.0
}
else
{
detailText = nil
duration = 2.0
}
let toastView = RSTToastView(text: NSLocalizedString("JIT Compilation Enabled", comment: ""), detailText: detailText)
toastView.edgeOffset.vertical = 8
self.show(toastView, duration: duration)
UserDefaults.standard.jitEnabledAlertCount += 1
}
DispatchQueue.main.async {
if let transitionCoordinator = self.transitionCoordinator
{
transitionCoordinator.animate(alongsideTransition: nil) { (context) in
presentToastView()
}
}
else
{
presentToastView()
}
}
}
}
//MARK: - Notifications -
@ -1129,7 +1188,7 @@ private extension GameViewController
case .translucentControllerSkinOpacity: self.controllerView.translucentControllerSkinOpacity = Settings.translucentControllerSkinOpacity
case .syncingService: break
case .syncingService, .isAltJITEnabled: break
}
}
@ -1207,6 +1266,60 @@ private extension GameViewController
self.isGyroActive = false
}
@objc func didEnableJIT(with notification: Notification)
{
DispatchQueue.main.async {
self.showJITEnabledAlert()
}
DispatchQueue.global(qos: .utility).async {
guard let emulatorCore = self.emulatorCore, let emulatorBridge = emulatorCore.deltaCore.emulatorBridge as? MelonDSEmulatorBridge, !emulatorBridge.isJITEnabled
else { return }
guard emulatorCore.state != .stopped else {
// Emulator core is not running, which means we can set
// isJITEnabled to true without resetting the core.
emulatorBridge.isJITEnabled = true
return
}
let isVideoEnabled = emulatorCore.videoManager.isEnabled
emulatorCore.videoManager.isEnabled = false
let isRunning = (emulatorCore.state == .running)
if isRunning
{
self.pauseEmulation()
}
let temporaryFileURL = FileManager.default.uniqueTemporaryURL()
let saveState = emulatorCore.saveSaveState(to: temporaryFileURL)
emulatorCore.stop()
emulatorBridge.isJITEnabled = true
emulatorCore.start()
emulatorCore.pause()
do
{
try emulatorCore.load(saveState)
}
catch
{
print("Failed to load save state after enabling JIT.", error)
}
if isRunning
{
self.resumeEmulation()
}
emulatorCore.videoManager.isEnabled = isVideoEnabled
}
}
@objc func emulationDidQuit(with notification: Notification)
{
DispatchQueue.main.async {
@ -1231,4 +1344,6 @@ private extension GameViewController
private extension UserDefaults
{
@NSManaged var desmumeDeprecatedAlertCount: Int
@NSManaged var jitEnabledAlertCount: Int
}

View File

@ -0,0 +1,41 @@
//
// ProcessInfo+JIT.swift
// Delta
//
// Created by Riley Testut on 9/14/21.
// Copyright © 2021 Riley Testut. All rights reserved.
//
import UIKit
private let CS_OPS_STATUS: UInt32 = 0 /* OK */
private let CS_DEBUGGED: UInt32 = 0x10000000 /* Process is or has been attached to debugger. */
@_silgen_name("csops")
func csops(_ pid: pid_t, _ ops: UInt32, _ useraddr: UnsafeMutableRawPointer?, _ usersize: Int) -> Int
extension ProcessInfo
{
static var isJITDisabled = false
var isDebugging: Bool {
var flags: UInt32 = 0
let result = csops(getpid(), CS_OPS_STATUS, &flags, MemoryLayout<UInt32>.size)
let isDebugging = result == 0 && (flags & CS_DEBUGGED == CS_DEBUGGED)
return isDebugging
}
var isJITAvailable: Bool {
guard UIDevice.current.supportsJIT && !ProcessInfo.isJITDisabled else { return false }
let ios14_4 = OperatingSystemVersion(majorVersion: 14, minorVersion: 4, patchVersion: 0)
if #available(iOS 14.2, *), !ProcessInfo.processInfo.isOperatingSystemAtLeast(ios14_4)
{
// JIT is always available on supported devices running iOS 14.2 - 14.3.
return true
}
return self.isDebugging
}
}

View File

@ -0,0 +1,104 @@
//
// ServerManager+Delta.swift
// Delta
//
// Created by Riley Testut on 9/15/21.
// Copyright © 2021 Riley Testut. All rights reserved.
//
import AltKit
extension ServerManager
{
static let didEnableJITNotification = Notification.Name("didEnableJITNotification")
}
extension ServerManager
{
func prepare()
{
NotificationCenter.default.addObserver(self, selector: #selector(ServerManager.didChangeJITMode(_:)), name: .settingsDidChange, object: nil)
#if DEBUG
if ProcessInfo.processInfo.isDebugging
{
// Debugger is attached at app launch, so we assume
// we're connected to Xcode for debugging purposes.
// In that case, we manually treat JIT as unavailable
// until AltServer is discovered to simulate real-world use.
ProcessInfo.isJITDisabled = true
}
#endif
self.start()
}
}
private extension ServerManager
{
func start()
{
guard Settings.isAltJITEnabled && !ProcessInfo.processInfo.isJITAvailable else { return }
self.startDiscovering()
self.autoconnect()
}
func autoconnect()
{
self.autoconnect { result in
switch result
{
case .failure(let error):
print("Could not auto-connect to server.", error)
self.autoconnect()
case .success(let connection):
func finish(result: Result<Void, Error>)
{
switch result
{
case .failure(ALTServerError.unknownRequest), .failure(ALTServerError.deviceNotFound):
// Try connecting to a different server.
self.autoconnect()
case .failure(let error):
print("Could not enable JIT compilation.", error)
case .success:
print("Successfully enabled JIT compilation!")
NotificationCenter.default.post(name: ServerManager.didEnableJITNotification, object: nil)
self.stopDiscovering()
}
connection.disconnect()
}
if ProcessInfo.isJITDisabled
{
ProcessInfo.isJITDisabled = false
finish(result: .success(()))
}
else
{
connection.enableUnsignedCodeExecution(completion: finish)
}
}
}
}
@objc func didChangeJITMode(_ notification: Notification)
{
guard let name = notification.userInfo?[Settings.NotificationUserInfoKey.name] as? Settings.Name, name == Settings.Name.isAltJITEnabled else { return }
if Settings.isAltJITEnabled
{
self.start()
}
else
{
self.stopDiscovering()
}
}
}

View File

@ -26,12 +26,9 @@ extension UIDevice
}
var supportsJIT: Bool {
// As of iOS 14.4 beta 2, JIT is no longer supported :(
// Hopefully this change is reversed before the public release...
let ios14_4 = OperatingSystemVersion(majorVersion: 14, minorVersion: 4, patchVersion: 0)
guard #available(iOS 14.2, *), !ProcessInfo.processInfo.isOperatingSystemAtLeast(ios14_4) else { return false }
guard #available(iOS 14.0, *) else { return false }
// JIT is supported on devices with an A12 processor or better running iOS 14.2 or later.
// JIT is supported on devices with an A12 processor or better running iOS 14.0 or later.
// ARKit 3 is only supported by devices with an A12 processor or better, according to the documentation.
return ARBodyTrackingConfiguration.isSupported
}

View File

@ -180,7 +180,7 @@ extension GameCollectionViewController
emulatorBridge.systemType = .ds
}
emulatorBridge.isJITEnabled = UIDevice.current.supportsJIT
emulatorBridge.isJITEnabled = ProcessInfo.processInfo.isJITAvailable
}
if let saveState = self.activeSaveState
@ -843,7 +843,7 @@ extension GameCollectionViewController: UIViewControllerPreviewingDelegate
emulatorBridge.systemType = .ds
}
emulatorBridge.isJITEnabled = UIDevice.current.supportsJIT
emulatorBridge.isJITEnabled = ProcessInfo.processInfo.isJITAvailable
}
let actions = self.actions(for: game).previewActions

View File

@ -14,7 +14,7 @@ import DeltaCore
import Roxas
@objc(SwitchTableViewCell)
private class SwitchTableViewCell: UITableViewCell
class SwitchTableViewCell: UITableViewCell
{
@IBOutlet var switchView: UISwitch!
}

View File

@ -23,6 +23,7 @@ private extension MelonDSCoreSettingsViewController
enum Section: Int
{
case general
case performance
case dsBIOS
case dsiBIOS
case changeCore
@ -149,6 +150,10 @@ private extension MelonDSCoreSettingsViewController
switch section
{
case .performance:
guard Settings.preferredCore(for: .ds) == MelonDS.core else { return true }
return !UIDevice.current.supportsJIT
case .dsBIOS where Settings.preferredCore(for: .ds) == DS.core:
// Using DeSmuME core, which doesn't require BIOS.
return true
@ -252,6 +257,11 @@ private extension MelonDSCoreSettingsViewController
}
}
@IBAction func toggleAltJITEnabled(_ sender: UISwitch)
{
Settings.isAltJITEnabled = sender.isOn
}
@objc func willEnterForeground(_ notification: Notification)
{
self.tableView.reloadData()
@ -300,6 +310,10 @@ extension MelonDSCoreSettingsViewController
cell.contentView.isHidden = (item == nil)
case .performance:
let cell = cell as! SwitchTableViewCell
cell.switchView.isOn = Settings.isAltJITEnabled
case .dsBIOS:
let bios = DSBIOS.allCases[indexPath.row]
@ -378,6 +392,8 @@ extension MelonDSCoreSettingsViewController
case .changeCore:
self.changeCore()
case .performance: break
}
}

View File

@ -38,6 +38,7 @@ extension Settings
case syncingService
case isButtonHapticFeedbackEnabled
case isThumbstickHapticFeedbackEnabled
case isAltJITEnabled
}
}
@ -60,6 +61,7 @@ struct Settings
#keyPath(UserDefaults.isThumbstickHapticFeedbackEnabled): true,
#keyPath(UserDefaults.sortSaveStatesByOldestFirst): true,
#keyPath(UserDefaults.isPreviewsEnabled): true,
#keyPath(UserDefaults.isAltJITEnabled): true,
Settings.preferredCoreSettingsKey(for: .ds): MelonDS.core.identifier] as [String : Any]
UserDefaults.standard.register(defaults: defaults)
@ -195,6 +197,17 @@ extension Settings
}
}
static var isAltJITEnabled: Bool {
get {
let isAltJITEnabled = UserDefaults.standard.isAltJITEnabled
return isAltJITEnabled
}
set {
UserDefaults.standard.isAltJITEnabled = newValue
NotificationCenter.default.post(name: .settingsDidChange, object: nil, userInfo: [NotificationUserInfoKey.name: Name.isAltJITEnabled])
}
}
static func preferredCore(for gameType: GameType) -> DeltaCoreProtocol?
{
let key = self.preferredCoreSettingsKey(for: gameType)
@ -390,4 +403,6 @@ private extension UserDefaults
@NSManaged var sortSaveStatesByOldestFirst: Bool
@NSManaged var isPreviewsEnabled: Bool
@NSManaged var isAltJITEnabled: Bool
}

View File

@ -290,7 +290,7 @@ private extension SettingsViewController
self.tableView.selectRow(at: selectedIndexPath, animated: true, scrollPosition: .none)
}
case .localControllerPlayerIndex, .preferredControllerSkin, .translucentControllerSkinOpacity, .isButtonHapticFeedbackEnabled, .isThumbstickHapticFeedbackEnabled: break
case .localControllerPlayerIndex, .preferredControllerSkin, .translucentControllerSkinOpacity, .isButtonHapticFeedbackEnabled, .isThumbstickHapticFeedbackEnabled, .isAltJITEnabled: break
}
}

View File

@ -400,5 +400,13 @@
</dict>
</dict>
</array>
<key>NSBonjourServices</key>
<array>
<string>_altserver._tcp</string>
</array>
<key>ALTDeviceID</key>
<string>00008110-000A68390A82801E</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Delta uses the local network to communicate with AltServer and enable JIT.</string>
</dict>
</plist>

View File

@ -72,7 +72,7 @@ extension DeltaCoreProtocol
case GBA.core: return 3
case N64.core where UIDevice.current.hasA11ProcessorOrBetter: return 3
case N64.core where UIDevice.current.hasA9ProcessorOrBetter: return 1.5
case MelonDS.core where UIDevice.current.supportsJIT: return 3
case MelonDS.core where ProcessInfo.processInfo.isJITAvailable: return 3
case MelonDS.core where UIDevice.current.hasA11ProcessorOrBetter: return 1.5
case GPGX.core: return 4
default: return 1