Adds Nintendo DS AirPlay settings to customize how games appear on TV
* Top Screen Only = Shows just the top screen on TV * Layout Horizontally = Places screens side-by-side on TV (instead of stacked vertically)
This commit is contained in:
parent
32e7c1f93e
commit
1137189b57
@ -1 +1 @@
|
||||
Subproject commit 4b5084c75149dc0fc7b4abb4e6ab4f41df025ecd
|
||||
Subproject commit 3ce43f3103c637dfdb27f85fc0d0041c8a37292b
|
||||
@ -196,6 +196,8 @@
|
||||
D5A9C00329DDED6D00A8D610 /* ExperimentalFeaturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C00229DDED6D00A8D610 /* ExperimentalFeaturesView.swift */; };
|
||||
D5A9C01D29DE058C00A8D610 /* VariableFastForward.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */; };
|
||||
D5AAF27729884F8600F21ACF /* CheatDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AAF27629884F8600F21ACF /* CheatDevice.swift */; };
|
||||
D5ADD12229F33FBF00CE0560 /* Features.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ADD12129F33FBF00CE0560 /* Features.swift */; };
|
||||
D5D78AE529F9BC3700E064F0 /* DSAirPlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D78AE429F9BC3700E064F0 /* DSAirPlay.swift */; };
|
||||
D5D797E6298D946200738869 /* Contributor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D797E5298D946200738869 /* Contributor.swift */; };
|
||||
D5D797E9298DCC7300738869 /* cheatbase.zip in Resources */ = {isa = PBXBuildFile; fileRef = D5D797E7298DC9E200738869 /* cheatbase.zip */; };
|
||||
D5D7C1F929E60EA500663793 /* UserDefaults+OptionValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58F39C829E0A702008B4100 /* UserDefaults+OptionValues.swift */; };
|
||||
@ -453,6 +455,8 @@
|
||||
D5A9C01929DDFBDD00A8D610 /* SettingsName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsName.swift; sourceTree = "<group>"; };
|
||||
D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VariableFastForward.swift; sourceTree = "<group>"; };
|
||||
D5AAF27629884F8600F21ACF /* CheatDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheatDevice.swift; sourceTree = "<group>"; };
|
||||
D5ADD12129F33FBF00CE0560 /* Features.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Features.swift; sourceTree = "<group>"; };
|
||||
D5D78AE429F9BC3700E064F0 /* DSAirPlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DSAirPlay.swift; sourceTree = "<group>"; };
|
||||
D5D797E5298D946200738869 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = "<group>"; };
|
||||
D5D797E7298DC9E200738869 /* cheatbase.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = cheatbase.zip; sourceTree = "<group>"; };
|
||||
D5D7C1E629E5F90200663793 /* OptionValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionValue.swift; sourceTree = "<group>"; };
|
||||
@ -845,6 +849,7 @@
|
||||
BF11734E1DA32CEC00047DF8 /* Controllers */,
|
||||
BF1DAD5B1D9F574900E752A7 /* Controller Skins */,
|
||||
BF48F74C219A16C100BC2FC1 /* Syncing */,
|
||||
D5D78AE329F9BC0200E064F0 /* Features */,
|
||||
D5A9BFFF29DDECF500A8D610 /* Experimental Features */,
|
||||
D5D797E4298D944C00738869 /* Contributors */,
|
||||
);
|
||||
@ -1092,6 +1097,15 @@
|
||||
path = "Experimental Features";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D5D78AE329F9BC0200E064F0 /* Features */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D5ADD12129F33FBF00CE0560 /* Features.swift */,
|
||||
D5D78AE429F9BC3700E064F0 /* DSAirPlay.swift */,
|
||||
);
|
||||
path = Features;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D5D797E4298D944C00738869 /* Contributors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1519,11 +1533,13 @@
|
||||
D560BD8629EDC45600289847 /* ExternalDisplaySceneDelegate.swift in Sources */,
|
||||
BFFC46201D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift in Sources */,
|
||||
BF15AF841F54B43B009B6AAB /* ActionInput.swift in Sources */,
|
||||
D5D78AE529F9BC3700E064F0 /* DSAirPlay.swift in Sources */,
|
||||
BF4828841F9027B600028B97 /* Delta.xcdatamodeld in Sources */,
|
||||
BF5942951E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift in Sources */,
|
||||
BFC3628021ADE2BA00EF2BE6 /* UIAlertController+Error.swift in Sources */,
|
||||
BF353FF91C5D870B00C1184C /* MenuItem.swift in Sources */,
|
||||
D5D797E6298D946200738869 /* Contributor.swift in Sources */,
|
||||
D5ADD12229F33FBF00CE0560 /* Features.swift in Sources */,
|
||||
BFDB3418219E4B1700595A62 /* SyncStatusViewController.swift in Sources */,
|
||||
BF18B61F1E2985F900F70067 /* UIAlertController+Importing.swift in Sources */,
|
||||
D586497229774ABD0081477E /* CheatBase.swift in Sources */,
|
||||
|
||||
@ -1956,10 +1956,80 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="AirPlay" id="Bci-L3-OeH">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="SwitchCell" id="Jq5-oz-Tdi" customClass="SwitchTableViewCell">
|
||||
<rect key="frame" x="0.0" y="291.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jq5-oz-Tdi" id="rg7-TQ-4w8">
|
||||
<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="Show Top Screen Only" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="leX-Hk-FtK">
|
||||
<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="erK-Wq-1Lx">
|
||||
<rect key="frame" x="310" y="6.5" width="51" height="31"/>
|
||||
<color key="onTintColor" name="Purple"/>
|
||||
<connections>
|
||||
<action selector="toggleTopScreenOnly:" destination="OwL-4c-EEA" eventType="valueChanged" id="Muw-Xa-Wy1"/>
|
||||
</connections>
|
||||
</switch>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="erK-Wq-1Lx" firstAttribute="leading" secondItem="leX-Hk-FtK" secondAttribute="trailing" constant="8" symbolic="YES" id="3bQ-fs-dhn"/>
|
||||
<constraint firstItem="leX-Hk-FtK" firstAttribute="centerY" secondItem="rg7-TQ-4w8" secondAttribute="centerY" id="DdR-vJ-3hz"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="erK-Wq-1Lx" secondAttribute="trailing" id="Yn5-qu-rZ7"/>
|
||||
<constraint firstItem="leX-Hk-FtK" firstAttribute="leading" secondItem="rg7-TQ-4w8" secondAttribute="leadingMargin" id="gaA-Aj-Y45"/>
|
||||
<constraint firstItem="erK-Wq-1Lx" firstAttribute="centerY" secondItem="rg7-TQ-4w8" secondAttribute="centerY" id="tsz-wz-mVz"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="switchView" destination="erK-Wq-1Lx" id="55W-CO-LbT"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="SwitchCell" id="Wfb-f8-j84" customClass="SwitchTableViewCell">
|
||||
<rect key="frame" x="0.0" y="335.5" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Wfb-f8-j84" id="bVY-An-mBJ">
|
||||
<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="Arrange Screens Horizontally" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="agM-Sz-8Jc">
|
||||
<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="F3O-5s-93H">
|
||||
<rect key="frame" x="310" y="6.5" width="51" height="31"/>
|
||||
<color key="onTintColor" name="Purple"/>
|
||||
<connections>
|
||||
<action selector="toggleLayoutHorizontally:" destination="OwL-4c-EEA" eventType="valueChanged" id="Wnh-tj-Z01"/>
|
||||
</connections>
|
||||
</switch>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="F3O-5s-93H" secondAttribute="trailing" id="4A1-e1-ByX"/>
|
||||
<constraint firstItem="F3O-5s-93H" firstAttribute="centerY" secondItem="bVY-An-mBJ" secondAttribute="centerY" id="Ede-Sv-5JJ"/>
|
||||
<constraint firstItem="agM-Sz-8Jc" firstAttribute="leading" secondItem="bVY-An-mBJ" secondAttribute="leadingMargin" id="lcT-KV-Mes"/>
|
||||
<constraint firstItem="agM-Sz-8Jc" firstAttribute="centerY" secondItem="bVY-An-mBJ" secondAttribute="centerY" id="oOf-ri-9Rb"/>
|
||||
<constraint firstItem="F3O-5s-93H" firstAttribute="leading" secondItem="agM-Sz-8Jc" secondAttribute="trailing" constant="8" symbolic="YES" id="rXK-nP-M6x"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="switchView" destination="F3O-5s-93H" id="ZiQ-7p-Qb8"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<rect key="frame" x="0.0" y="443" 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"/>
|
||||
@ -1997,7 +2067,7 @@ Delta uses OpenVGDB to provide automatic artwork for imported games.</string>
|
||||
<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="408" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="578.5" 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"/>
|
||||
@ -2020,7 +2090,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="452" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="622.5" 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"/>
|
||||
@ -2043,7 +2113,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="496" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="666.5" 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"/>
|
||||
@ -2070,7 +2140,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="620" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="802" 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"/>
|
||||
@ -2093,7 +2163,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="664" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="846" 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"/>
|
||||
@ -2116,7 +2186,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="708" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="890" 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"/>
|
||||
@ -2139,7 +2209,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="752" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="934" 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"/>
|
||||
@ -2166,7 +2236,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="861.5" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="1053.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"/>
|
||||
|
||||
@ -90,6 +90,11 @@ extension ControllerSkin: ControllerSkinProtocol
|
||||
{
|
||||
return self.controllerSkin?.aspectRatio(for: traits)
|
||||
}
|
||||
|
||||
public func contentSize(for traits: DeltaCore.ControllerSkin.Traits) -> CGSize?
|
||||
{
|
||||
return self.controllerSkin?.contentSize(for: traits)
|
||||
}
|
||||
}
|
||||
|
||||
extension ControllerSkin: Syncable
|
||||
|
||||
@ -670,6 +670,12 @@ private extension GameViewController
|
||||
{
|
||||
var touchControllerSkin = TouchControllerSkin(controllerSkin: controllerSkin)
|
||||
|
||||
if UIApplication.shared.isExternalDisplayConnected
|
||||
{
|
||||
// Only show touch screen if external display is connected.
|
||||
touchControllerSkin.screenPredicate = { $0.isTouchScreen }
|
||||
}
|
||||
|
||||
if self.view.bounds.width > self.view.bounds.height
|
||||
{
|
||||
touchControllerSkin.screenLayoutAxis = .horizontal
|
||||
@ -1119,8 +1125,10 @@ private extension GameViewController
|
||||
// We need to receive gameViewController(_:didUpdateGameViews) callback.
|
||||
scene.gameViewController.delegate = self
|
||||
|
||||
self.updateGameViews()
|
||||
self.updateExternalDisplay()
|
||||
self.updateControllerSkin()
|
||||
|
||||
// Implicitly called from updateControllerSkin()
|
||||
// self.updateExternalDisplay()
|
||||
}
|
||||
|
||||
func updateExternalDisplay()
|
||||
@ -1132,7 +1140,37 @@ private extension GameViewController
|
||||
scene.game = self.game
|
||||
}
|
||||
|
||||
self.updateExternalDisplayGameViews()
|
||||
var controllerSkin: ControllerSkinProtocol?
|
||||
|
||||
if let game = self.game, let traits = scene.gameViewController.controllerView.controllerSkinTraits
|
||||
{
|
||||
if let standardSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: game.type), standardSkin.supports(traits)
|
||||
{
|
||||
if standardSkin.hasTouchScreen(for: traits)
|
||||
{
|
||||
// Only use TouchControllerSkin for standard controller skins with touch screens.
|
||||
|
||||
var touchControllerSkin = DeltaCore.TouchControllerSkin(controllerSkin: standardSkin)
|
||||
touchControllerSkin.screenLayoutAxis = Settings.features.dsAirPlay.layoutAxis
|
||||
|
||||
if Settings.features.dsAirPlay.topScreenOnly
|
||||
{
|
||||
touchControllerSkin.screenPredicate = { !$0.isTouchScreen }
|
||||
}
|
||||
|
||||
controllerSkin = touchControllerSkin
|
||||
}
|
||||
else
|
||||
{
|
||||
controllerSkin = standardSkin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene.gameViewController.controllerView.controllerSkin = controllerSkin
|
||||
|
||||
// Implicitly called when assigning controllerSkin.
|
||||
// self.updateExternalDisplayGameViews()
|
||||
}
|
||||
|
||||
func updateExternalDisplayGameViews()
|
||||
@ -1154,7 +1192,7 @@ private extension GameViewController
|
||||
self.emulatorCore?.remove(gameView)
|
||||
}
|
||||
|
||||
self.updateGameViews()
|
||||
self.updateControllerSkin() // Reset TouchControllerSkin + GameViews
|
||||
}
|
||||
}
|
||||
|
||||
@ -1317,6 +1355,10 @@ private extension GameViewController
|
||||
|
||||
case .syncingService, .isAltJITEnabled: break
|
||||
|
||||
case Settings.features.dsAirPlay.$topScreenOnly.settingsKey: fallthrough
|
||||
case Settings.features.dsAirPlay.$layoutAxis.settingsKey:
|
||||
self.updateExternalDisplay()
|
||||
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,12 +23,19 @@ private extension MelonDSCoreSettingsViewController
|
||||
enum Section: Int
|
||||
{
|
||||
case general
|
||||
case airPlay
|
||||
case performance
|
||||
case dsBIOS
|
||||
case dsiBIOS
|
||||
case changeCore
|
||||
}
|
||||
|
||||
enum AirPlayRow: Int, CaseIterable
|
||||
{
|
||||
case topScreenOnly
|
||||
case layoutHorizontally
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
enum BIOSError: LocalizedError
|
||||
{
|
||||
@ -265,6 +272,32 @@ private extension MelonDSCoreSettingsViewController
|
||||
Settings.isAltJITEnabled = sender.isOn
|
||||
}
|
||||
|
||||
@IBAction func toggleTopScreenOnly(_ sender: UISwitch)
|
||||
{
|
||||
Settings.features.dsAirPlay.topScreenOnly = sender.isOn
|
||||
|
||||
self.tableView.performBatchUpdates({
|
||||
let layoutHorizontallyIndexPath = IndexPath(row: AirPlayRow.layoutHorizontally.rawValue, section: Section.airPlay.rawValue)
|
||||
if sender.isOn
|
||||
{
|
||||
self.tableView.deleteRows(at: [layoutHorizontallyIndexPath], with: .automatic)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.tableView.insertRows(at: [layoutHorizontallyIndexPath], with: .automatic)
|
||||
}
|
||||
}) { _ in
|
||||
self.tableView.reloadSections([Section.airPlay.rawValue], with: .none)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func toggleLayoutHorizontally(_ sender: UISwitch)
|
||||
{
|
||||
Settings.features.dsAirPlay.layoutAxis = sender.isOn ? .horizontal : .vertical
|
||||
|
||||
self.tableView.reloadSections([Section.airPlay.rawValue], with: .none)
|
||||
}
|
||||
|
||||
@objc func willEnterForeground(_ notification: Notification)
|
||||
{
|
||||
self.tableView.reloadData()
|
||||
@ -277,13 +310,11 @@ extension MelonDSCoreSettingsViewController
|
||||
{
|
||||
let section = Section(rawValue: sectionIndex)!
|
||||
|
||||
if isSectionHidden(section)
|
||||
switch section
|
||||
{
|
||||
return 0
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.tableView(tableView, numberOfRowsInSection: sectionIndex)
|
||||
case _ where isSectionHidden(section): return 0
|
||||
case .airPlay where Settings.features.dsAirPlay.topScreenOnly: return 1 // Layout axis is irrelevant if only AirPlaying top screen.
|
||||
default: return super.tableView(tableView, numberOfRowsInSection: sectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,6 +344,16 @@ extension MelonDSCoreSettingsViewController
|
||||
|
||||
cell.contentView.isHidden = (item == nil)
|
||||
|
||||
case .airPlay:
|
||||
let cell = cell as! SwitchTableViewCell
|
||||
|
||||
let row = AirPlayRow.allCases[indexPath.row]
|
||||
switch row
|
||||
{
|
||||
case .topScreenOnly: cell.switchView.isOn = Settings.features.dsAirPlay.topScreenOnly
|
||||
case .layoutHorizontally: cell.switchView.isOn = (Settings.features.dsAirPlay.layoutAxis == .horizontal)
|
||||
}
|
||||
|
||||
case .performance:
|
||||
let cell = cell as! SwitchTableViewCell
|
||||
cell.switchView.isOn = Settings.isAltJITEnabled
|
||||
@ -396,7 +437,7 @@ extension MelonDSCoreSettingsViewController
|
||||
case .changeCore:
|
||||
self.changeCore()
|
||||
|
||||
case .performance: break
|
||||
case .airPlay, .performance: break
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,14 +458,18 @@ extension MelonDSCoreSettingsViewController
|
||||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
|
||||
{
|
||||
let section = Section(rawValue: section)!
|
||||
switch section
|
||||
{
|
||||
case _ where isSectionHidden(section): return nil
|
||||
case .airPlay:
|
||||
switch (Settings.features.dsAirPlay.topScreenOnly, Settings.features.dsAirPlay.layoutAxis)
|
||||
{
|
||||
case (true, _): return NSLocalizedString("When AirPlaying DS games, only the top screen will appear on the external display.", comment: "")
|
||||
case (false, .vertical): return NSLocalizedString("When AirPlaying DS games, both screens will be stacked vertically on the external display.", comment: "")
|
||||
case (false, .horizontal): return NSLocalizedString("When AirPlaying DS games, both screens will be placed side-by-side on the external display.", comment: "")
|
||||
}
|
||||
|
||||
if isSectionHidden(section)
|
||||
{
|
||||
return nil
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.tableView(tableView, titleForFooterInSection: section.rawValue)
|
||||
default: return super.tableView(tableView, titleForFooterInSection: section.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
23
Delta/Settings/Features/DSAirPlay.swift
Normal file
23
Delta/Settings/Features/DSAirPlay.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// DSAirPlay.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 4/26/23.
|
||||
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
import DeltaFeatures
|
||||
import DeltaCore
|
||||
|
||||
extension TouchControllerSkin.LayoutAxis: OptionValue {}
|
||||
|
||||
struct DSAirPlayOptions
|
||||
{
|
||||
@Option
|
||||
var topScreenOnly: Bool = true
|
||||
|
||||
@Option
|
||||
var layoutAxis: TouchControllerSkin.LayoutAxis = .vertical
|
||||
}
|
||||
25
Delta/Settings/Features/Features.swift
Normal file
25
Delta/Settings/Features/Features.swift
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Features.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 4/21/23.
|
||||
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import DeltaFeatures
|
||||
|
||||
extension Settings
|
||||
{
|
||||
struct Features: FeatureContainer
|
||||
{
|
||||
static let shared = Features()
|
||||
|
||||
@Feature(name: "DS AirPlay", options: DSAirPlayOptions())
|
||||
var dsAirPlay
|
||||
|
||||
private init()
|
||||
{
|
||||
self.prepareFeatures()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,8 @@ extension Settings
|
||||
|
||||
struct Settings
|
||||
{
|
||||
static let features = Features.shared
|
||||
|
||||
static func registerDefaults()
|
||||
{
|
||||
let defaults = [#keyPath(UserDefaults.translucentControllerSkinOpacity): 0.7,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user