diff --git a/Cores/DeltaCore b/Cores/DeltaCore index ff014ba..6e0ec5a 160000 --- a/Cores/DeltaCore +++ b/Cores/DeltaCore @@ -1 +1 @@ -Subproject commit ff014bab5c42e5c0a5fcbacb5c3c737ef33564e7 +Subproject commit 6e0ec5aedac746d1a5ea05d450884f1a9ad7b509 diff --git a/Delta/Emulation/GameViewController.swift b/Delta/Emulation/GameViewController.swift index 546bca2..1af9092 100644 --- a/Delta/Emulation/GameViewController.swift +++ b/Delta/Emulation/GameViewController.swift @@ -385,11 +385,14 @@ private extension GameViewController { @objc func updateControllers() { - guard let emulatorCore = self.emulatorCore, let game = self.game else { return } + let isExternalGameControllerConnected = ExternalGameControllerManager.shared.connectedControllers.contains(where: { $0.playerIndex != nil }) + if !isExternalGameControllerConnected && Settings.localControllerPlayerIndex == nil + { + Settings.localControllerPlayerIndex = 0 + } - let controllers = [self.controllerView as GameController] + ExternalGameControllerManager.shared.connectedControllers - - if let index = Settings.localControllerPlayerIndex + // If Settings.localControllerPlayerIndex is non-nil, and there isn't a connected controller with same playerIndex, show controller view. + if let index = Settings.localControllerPlayerIndex, !ExternalGameControllerManager.shared.connectedControllers.contains { $0.playerIndex == index } { self.controllerView.playerIndex = index self.controllerView.isHidden = false @@ -398,32 +401,39 @@ private extension GameViewController { self.controllerView.playerIndex = nil self.controllerView.isHidden = true - } - - for gameController in controllers - { - if gameController.playerIndex != nil - { - if let inputMapping = GameControllerInputMapping.inputMapping(for: gameController, gameType: game.type, in: DatabaseManager.shared.viewContext) - { - gameController.addReceiver(self, inputMapping: inputMapping) - gameController.addReceiver(emulatorCore, inputMapping: inputMapping) - } - else - { - gameController.addReceiver(self) - gameController.addReceiver(emulatorCore) - } - } - else - { - gameController.removeReceiver(self) - gameController.removeReceiver(emulatorCore) - } + + Settings.localControllerPlayerIndex = nil } self.view.setNeedsLayout() self.view.layoutIfNeeded() + + if let emulatorCore = self.emulatorCore, let game = self.game + { + let controllers = [self.controllerView as GameController] + ExternalGameControllerManager.shared.connectedControllers + + for gameController in controllers + { + if gameController.playerIndex != nil + { + if let inputMapping = GameControllerInputMapping.inputMapping(for: gameController, gameType: game.type, in: DatabaseManager.shared.viewContext) + { + gameController.addReceiver(self, inputMapping: inputMapping) + gameController.addReceiver(emulatorCore, inputMapping: inputMapping) + } + else + { + gameController.addReceiver(self) + gameController.addReceiver(emulatorCore) + } + } + else + { + gameController.removeReceiver(self) + gameController.removeReceiver(emulatorCore) + } + } + } } func updateControllerSkin() @@ -751,7 +761,7 @@ extension GameViewController do { - if let quickSaveState = try fetchRequest.execute().first + if let quickSaveState = try DatabaseManager.shared.viewContext.fetch(fetchRequest).first { self.load(quickSaveState) } diff --git a/Delta/Settings/Controllers/ControllersSettingsViewController.swift b/Delta/Settings/Controllers/ControllersSettingsViewController.swift index 6ca78e5..8b6d954 100644 --- a/Delta/Settings/Controllers/ControllersSettingsViewController.swift +++ b/Delta/Settings/Controllers/ControllersSettingsViewController.swift @@ -22,7 +22,6 @@ extension ControllersSettingsViewController } } - private class LocalDeviceController: NSObject, GameController { var name: String { @@ -49,8 +48,17 @@ class ControllersSettingsViewController: UITableViewController fileprivate var gameController: GameController? { didSet { - oldValue?.playerIndex = nil - self.gameController?.playerIndex = self.playerIndex + // Order matters since localDeviceController changes Settings.localControllerPlayerIndex, which sends out NSNotification. + if oldValue == self.localDeviceController + { + self.gameController?.playerIndex = self.playerIndex + oldValue?.playerIndex = nil + } + else + { + oldValue?.playerIndex = nil + self.gameController?.playerIndex = self.playerIndex + } } } @@ -150,7 +158,7 @@ private extension ControllersSettingsViewController cell.accessoryType = .checkmark } else - { + { if let playerIndex = controller.playerIndex { cell.detailTextLabel?.text = NSLocalizedString("Player \(playerIndex + 1)", comment: "") @@ -183,14 +191,29 @@ private extension ControllersSettingsViewController if let index = self.connectedControllers.index(where: { $0 == controller }) { + self.tableView.beginUpdates() + if self.connectedControllers.count == 1 { self.tableView.insertSections(IndexSet(integer: Section.externalControllers.rawValue), with: .fade) + + if self.connectedControllers.first?.playerIndex == self.playerIndex + { + self.tableView.insertSections(IndexSet(integer: Section.customizeControls.rawValue), with: .fade) + } } else { self.tableView.insertRows(at: [IndexPath(row: index, section: Section.externalControllers.rawValue)], with: .automatic) } + + self.tableView.endUpdates() + } + + if controller.playerIndex == self.playerIndex + { + self.tableView.reloadSections(IndexSet(integer: Section.none.rawValue), with: .none) + self.tableView.reloadSections(IndexSet(integer: Section.localDevice.rawValue), with: .none) } } @@ -202,19 +225,29 @@ private extension ControllersSettingsViewController { self.connectedControllers.remove(at: index) + self.tableView.beginUpdates() + if self.connectedControllers.count == 0 { self.tableView.deleteSections(IndexSet(integer: Section.externalControllers.rawValue), with: .fade) + + if controller.playerIndex != nil + { + self.tableView.deleteSections(IndexSet(integer: Section.customizeControls.rawValue), with: .fade) + } } else { self.tableView.deleteRows(at: [IndexPath(row: index, section: Section.externalControllers.rawValue)], with: .automatic) } + + self.tableView.endUpdates() } if controller.playerIndex == self.playerIndex { self.tableView.reloadSections(IndexSet(integer: Section.none.rawValue), with: .none) + self.tableView.reloadSections(IndexSet(integer: Section.localDevice.rawValue), with: .none) } } } @@ -240,7 +273,7 @@ extension ControllersSettingsViewController { switch Section(rawValue: section)! { - case .none: return 1 + case .none: return 0 case .localDevice: return 1 case .externalControllers: return self.connectedControllers.count case .customizeControls: return 1 @@ -266,6 +299,16 @@ extension ControllersSettingsViewController case .customizeControls: return nil } } + + override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat + { + if section == Section.none.rawValue + { + return 1 + } + + return UITableViewAutomaticDimension + } } extension ControllersSettingsViewController @@ -315,8 +358,7 @@ extension ControllersSettingsViewController } self.tableView.reloadRows(at: [indexPath], with: .none) - - + if self.numberOfSections(in: self.tableView) > self.tableView.numberOfSections { self.tableView.insertSections(IndexSet(integer: Section.customizeControls.rawValue), with: .fade) diff --git a/Delta/Settings/Settings.swift b/Delta/Settings/Settings.swift index aba0493..5a6269c 100644 --- a/Delta/Settings/Settings.swift +++ b/Delta/Settings/Settings.swift @@ -40,12 +40,14 @@ struct Settings /// Controllers static var localControllerPlayerIndex: Int? = 0 { didSet { + guard self.localControllerPlayerIndex != oldValue else { return } NotificationCenter.default.post(name: .settingsDidChange, object: nil, userInfo: [NotificationUserInfoKey.name: Name.localControllerPlayerIndex]) } } static var translucentControllerSkinOpacity: CGFloat { set { + guard newValue != self.translucentControllerSkinOpacity else { return } UserDefaults.standard.translucentControllerSkinOpacity = newValue NotificationCenter.default.post(name: .settingsDidChange, object: nil, userInfo: [NotificationUserInfoKey.name: Name.translucentControllerSkinOpacity]) } @@ -113,6 +115,9 @@ struct Settings static func setPreferredControllerSkin(_ controllerSkin: ControllerSkin, for system: System, traits: DeltaCore.ControllerSkin.Traits) { guard let userDefaultKey = self.preferredControllerSkinKey(for: system, traits: traits) else { return } + + guard UserDefaults.standard.string(forKey: userDefaultKey) != controllerSkin.identifier else { return } + UserDefaults.standard.set(controllerSkin.identifier, forKey: userDefaultKey) NotificationCenter.default.post(name: .settingsDidChange, object: controllerSkin, userInfo: [NotificationUserInfoKey.name: Name.preferredControllerSkin, NotificationUserInfoKey.system: system, NotificationUserInfoKey.traits: traits]) diff --git a/Delta/Settings/SettingsViewController.swift b/Delta/Settings/SettingsViewController.swift index 97cb7f4..3f64c4a 100644 --- a/Delta/Settings/SettingsViewController.swift +++ b/Delta/Settings/SettingsViewController.swift @@ -42,6 +42,8 @@ class SettingsViewController: UITableViewController fileprivate var selectionFeedbackGenerator: UISelectionFeedbackGenerator? + fileprivate var previousSelectedRowIndexPath: IndexPath? + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) @@ -62,7 +64,7 @@ class SettingsViewController: UITableViewController { super.viewWillAppear(animated) - if let indexPath = self.tableView.indexPathForSelectedRow + if let indexPath = self.previousSelectedRowIndexPath { if indexPath.section == Section.controllers.rawValue { @@ -89,6 +91,8 @@ class SettingsViewController: UITableViewController let indexPath = self.tableView.indexPath(for: cell) else { return } + self.previousSelectedRowIndexPath = indexPath + switch segueType { case Segue.controllers: