diff --git a/Cores/DeltaCore b/Cores/DeltaCore
index 97e51f6..3373709 160000
--- a/Cores/DeltaCore
+++ b/Cores/DeltaCore
@@ -1 +1 @@
-Subproject commit 97e51f6ea5935d3ce2d15be796b189bcc70dbbb3
+Subproject commit 3373709956dc2be70563582ba7e308677bb964fa
diff --git a/Cores/GBADeltaCore b/Cores/GBADeltaCore
index acbcf2b..6c763da 160000
--- a/Cores/GBADeltaCore
+++ b/Cores/GBADeltaCore
@@ -1 +1 @@
-Subproject commit acbcf2baf8f01302f2a7c6e60783b887160aa163
+Subproject commit 6c763da1513fbe762edbca2cf33cec556ce9536e
diff --git a/Cores/GBCDeltaCore b/Cores/GBCDeltaCore
index c8084ce..4dcb34a 160000
--- a/Cores/GBCDeltaCore
+++ b/Cores/GBCDeltaCore
@@ -1 +1 @@
-Subproject commit c8084cee111501c0daffd113f5892050d7738519
+Subproject commit 4dcb34a47e71b81a099bff4dc0ebd28c217ef85b
diff --git a/Cores/NESDeltaCore b/Cores/NESDeltaCore
index 7ed452b..4dc0f28 160000
--- a/Cores/NESDeltaCore
+++ b/Cores/NESDeltaCore
@@ -1 +1 @@
-Subproject commit 7ed452b7dff25a68cd503610bee1f3e36216a871
+Subproject commit 4dc0f283116aadf6397c88c1f7fdabcac32367a6
diff --git a/Cores/SNESDeltaCore b/Cores/SNESDeltaCore
index d794f67..dc0ec5b 160000
--- a/Cores/SNESDeltaCore
+++ b/Cores/SNESDeltaCore
@@ -1 +1 @@
-Subproject commit d794f67cdba072f8a9977fb76e8ccaaac09946c0
+Subproject commit dc0ec5b74c0e47e0e35912dfd63dd70f2a3d932e
diff --git a/Delta/Base.lproj/Settings.storyboard b/Delta/Base.lproj/Settings.storyboard
index a2b7c9f..1174492 100644
--- a/Delta/Base.lproj/Settings.storyboard
+++ b/Delta/Base.lproj/Settings.storyboard
@@ -372,7 +372,7 @@
-
+
diff --git a/Delta/Database/Model/Human/ControllerSkin.swift b/Delta/Database/Model/Human/ControllerSkin.swift
index 6bd7b4d..c63d2cd 100644
--- a/Delta/Database/Model/Human/ControllerSkin.swift
+++ b/Delta/Database/Model/Human/ControllerSkin.swift
@@ -66,6 +66,11 @@ extension ControllerSkin: ControllerSkinProtocol
return self.controllerSkin?.image(for: traits, preferredSize: preferredSize)
}
+ public func thumbstick(for item: DeltaCore.ControllerSkin.Item, traits: DeltaCore.ControllerSkin.Traits, preferredSize: DeltaCore.ControllerSkin.Size) -> (UIImage, CGSize)?
+ {
+ return self.controllerSkin?.thumbstick(for: item, traits: traits, preferredSize: preferredSize)
+ }
+
public func inputs(for traits: DeltaCore.ControllerSkin.Traits, at point: CGPoint) -> [Input]?
{
return self.controllerSkin?.inputs(for: traits, at: point)
diff --git a/Delta/Emulation/GameViewController.swift b/Delta/Emulation/GameViewController.swift
index 18c3aba..19fdd5d 100644
--- a/Delta/Emulation/GameViewController.swift
+++ b/Delta/Emulation/GameViewController.swift
@@ -114,9 +114,7 @@ class GameViewController: DeltaCore.GameViewController
}
private var _isLoadingSaveState = false
-
- private var context = CIContext(options: [.workingColorSpace: NSNull()])
-
+
// Sustain Buttons
private var isSelectingSustainedButtons = false
private var sustainInputsMapping: SustainInputsMapping?
@@ -124,6 +122,7 @@ class GameViewController: DeltaCore.GameViewController
private var sustainButtonsContentView: UIView!
private var sustainButtonsBlurView: UIVisualEffectView!
private var sustainButtonsBackgroundView: RSTPlaceholderView!
+ private var inputsToSustain = [AnyInput: Double]()
private var isGyroActive = false
private var presentedGyroAlert = false
@@ -168,9 +167,9 @@ class GameViewController: DeltaCore.GameViewController
}
// MARK: - GameControllerReceiver -
- override func gameController(_ gameController: GameController, didActivate input: Input)
+ override func gameController(_ gameController: GameController, didActivate input: Input, value: Double)
{
- super.gameController(gameController, didActivate: input)
+ super.gameController(gameController, didActivate: input, value: value)
if self.isSelectingSustainedButtons
{
@@ -178,7 +177,7 @@ class GameViewController: DeltaCore.GameViewController
if input != StandardGameControllerInput.menu
{
- gameController.sustain(input)
+ self.inputsToSustain[AnyInput(input)] = value
}
}
else if self.emulatorCore?.state == .running
@@ -198,15 +197,23 @@ class GameViewController: DeltaCore.GameViewController
{
super.gameController(gameController, didDeactivate: input)
- guard !self.isSelectingSustainedButtons else { return }
-
- guard let actionInput = ActionInput(input: input) else { return }
-
- switch actionInput
+ if self.isSelectingSustainedButtons
{
- case .quickSave: break
- case .quickLoad: break
- case .fastForward: self.performFastForwardAction(activate: false)
+ if input.isContinuous
+ {
+ self.inputsToSustain[AnyInput(input)] = nil
+ }
+ }
+ else
+ {
+ guard let actionInput = ActionInput(input: input) else { return }
+
+ switch actionInput
+ {
+ case .quickSave: break
+ case .quickLoad: break
+ case .fastForward: self.performFastForwardAction(activate: false)
+ }
}
}
}
@@ -320,7 +327,7 @@ extension GameViewController
pauseViewController.sustainButtonsItem?.isSelected = gameController.sustainedInputs.count > 0
pauseViewController.sustainButtonsItem?.action = { [unowned self, unowned pauseViewController] item in
- for input in gameController.sustainedInputs
+ for input in gameController.sustainedInputs.keys
{
gameController.unsustain(input)
}
@@ -650,10 +657,7 @@ extension GameViewController: SaveStatesViewControllerDelegate
self.emulatorCore?.saveSaveState(to: saveState.fileURL)
}
- if
- let outputImage = self.gameView.outputImage,
- let quartzImage = self.context.createCGImage(outputImage, from: outputImage.extent),
- let data = UIImage(cgImage: quartzImage).pngData()
+ if let snapshot = self.gameView.snapshot(), let data = snapshot.pngData()
{
do
{
@@ -803,10 +807,10 @@ private extension GameViewController
self.updateControllers()
self.sustainInputsMapping = nil
- // Reactivate all sustained inputs, since they will now be mapped to game inputs.
- for input in gameController.sustainedInputs
+ // Activate all sustained inputs, since they will now be mapped to game inputs.
+ for (input, value) in self.inputsToSustain
{
- gameController.activate(input)
+ gameController.sustain(input, value: value)
}
let blurEffect = self.sustainButtonsBlurView.effect
@@ -818,6 +822,8 @@ private extension GameViewController
self.sustainButtonsContentView.isHidden = true
self.sustainButtonsBlurView.effect = blurEffect
}
+
+ self.inputsToSustain = [:]
}
}
diff --git a/Delta/Settings/Controllers/ControllerInputsViewController.swift b/Delta/Settings/Controllers/ControllerInputsViewController.swift
index c7bc2ba..b4a8cb3 100644
--- a/Delta/Settings/Controllers/ControllerInputsViewController.swift
+++ b/Delta/Settings/Controllers/ControllerInputsViewController.swift
@@ -123,6 +123,7 @@ private extension ControllerInputsViewController
// Update controller view's controller skin.
self.gameViewController.controllerView.controllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: self.system.gameType)
+ self.gameViewController.view.setNeedsUpdateConstraints()
// Fetch input mapping if it hasn't already been fetched.
if let gameController = self.gameController, let playerIndex = gameController.playerIndex, self.inputMappings[self.system] == nil
@@ -417,31 +418,32 @@ private extension ControllerInputsViewController
{
case .standard: itemFrame = item.frame
case let .directional(up, down, left, right):
+ let frame = (item.kind == .thumbstick) ? item.extendedFrame : item.frame
switch input.stringValue
{
case up.stringValue:
- itemFrame = CGRect(x: item.frame.minX + item.frame.width / 3,
- y: item.frame.minY,
- width: item.frame.width / 3,
- height: item.frame.height / 3)
+ itemFrame = CGRect(x: frame.minX + frame.width / 3,
+ y: frame.minY,
+ width: frame.width / 3,
+ height: frame.height / 3)
case down.stringValue:
- itemFrame = CGRect(x: item.frame.minX + item.frame.width / 3,
- y: item.frame.minY + (item.frame.height / 3) * 2,
- width: item.frame.width / 3,
- height: item.frame.height / 3)
+ itemFrame = CGRect(x: frame.minX + frame.width / 3,
+ y: frame.minY + (frame.height / 3) * 2,
+ width: frame.width / 3,
+ height: frame.height / 3)
case left.stringValue:
- itemFrame = CGRect(x: item.frame.minX,
- y: item.frame.minY + (item.frame.height / 3),
- width: item.frame.width / 3,
- height: item.frame.height / 3)
+ itemFrame = CGRect(x: frame.minX,
+ y: frame.minY + (frame.height / 3),
+ width: frame.width / 3,
+ height: frame.height / 3)
case right.stringValue:
- itemFrame = CGRect(x: item.frame.minX + (item.frame.width / 3) * 2,
- y: item.frame.minY + (item.frame.height / 3),
- width: item.frame.width / 3,
- height: item.frame.height / 3)
+ itemFrame = CGRect(x: frame.minX + (frame.width / 3) * 2,
+ y: frame.minY + (frame.height / 3),
+ width: frame.width / 3,
+ height: frame.height / 3)
default: itemFrame = nil
}
@@ -478,7 +480,7 @@ private extension ControllerInputsViewController
extension ControllerInputsViewController: GameControllerReceiver
{
- func gameController(_ gameController: GameController, didActivate controllerInput: DeltaCore.Input)
+ func gameController(_ gameController: GameController, didActivate controllerInput: DeltaCore.Input, value: Double)
{
guard self.isViewLoaded else { return }