Adds ability to import games & controller skins from other apps
This commit is contained in:
parent
03ddd7e7a6
commit
062abf6dbe
@ -1 +1 @@
|
|||||||
Subproject commit e936f39a694d0e1631ddceaccba6adcfda09474a
|
Subproject commit e2e166d01c4e866c9707944fd6df53556335056b
|
||||||
@ -83,6 +83,7 @@
|
|||||||
BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63BDE91D389EEB00FCB040 /* GameViewController.swift */; };
|
BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63BDE91D389EEB00FCB040 /* GameViewController.swift */; };
|
||||||
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; };
|
BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; };
|
||||||
|
BFC314771E0C8CFC0056E3A8 /* GameType+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */; };
|
||||||
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
|
BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */; };
|
||||||
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
|
BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; };
|
||||||
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
|
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; };
|
||||||
@ -186,6 +187,7 @@
|
|||||||
BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
BF9F4FCE1AAD7B87004C9500 /* DeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
||||||
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
BFC134E01AAD82460087AD7B /* SNESDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SNESDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameType+Delta.swift"; sourceTree = "<group>"; };
|
||||||
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = "<group>"; };
|
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = "<group>"; };
|
||||||
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
|
BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = "<group>"; };
|
||||||
BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = "<group>"; };
|
BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -234,6 +236,7 @@
|
|||||||
BF5942901E09BD1A0051894B /* NSFetchedResultsController+Conveniences.m */,
|
BF5942901E09BD1A0051894B /* NSFetchedResultsController+Conveniences.m */,
|
||||||
BF5942911E09BD1A0051894B /* NSManagedObject+Conveniences.swift */,
|
BF5942911E09BD1A0051894B /* NSManagedObject+Conveniences.swift */,
|
||||||
BF5942921E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift */,
|
BF5942921E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift */,
|
||||||
|
BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -736,6 +739,7 @@
|
|||||||
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
|
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
|
||||||
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
|
BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */,
|
||||||
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */,
|
BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */,
|
||||||
|
BFC314771E0C8CFC0056E3A8 /* GameType+Delta.swift in Sources */,
|
||||||
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
|
BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */,
|
||||||
BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */,
|
BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */,
|
||||||
BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */,
|
BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */,
|
||||||
|
|||||||
@ -69,7 +69,42 @@ class AppDelegate: UIResponder, UIApplicationDelegate
|
|||||||
{
|
{
|
||||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AppDelegate
|
||||||
|
{
|
||||||
|
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool
|
||||||
|
{
|
||||||
|
return self.openURL(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult fileprivate func openURL(_ url: URL) -> Bool
|
||||||
|
{
|
||||||
|
guard url.isFileURL else { return false }
|
||||||
|
|
||||||
|
let gameType = GameType.gameType(forFileExtension: url.pathExtension)
|
||||||
|
if gameType != .unknown
|
||||||
|
{
|
||||||
|
return self.importGame(at: url)
|
||||||
|
}
|
||||||
|
else if url.pathExtension.lowercased() == "deltaskin"
|
||||||
|
{
|
||||||
|
return self.importControllerSkin(at: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func importGame(at url: URL) -> Bool
|
||||||
|
{
|
||||||
|
DatabaseManager.shared.importGames(at: [url], completion: nil)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func importControllerSkin(at url: URL) -> Bool
|
||||||
|
{
|
||||||
|
DatabaseManager.shared.importControllerSkins(at: [url], completion: nil)
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class ImportController: NSObject
|
|||||||
{
|
{
|
||||||
self.presentingViewController = presentingViewController
|
self.presentingViewController = presentingViewController
|
||||||
|
|
||||||
var documentTypes = Game.supportedTypes.map { $0.rawValue }
|
var documentTypes = GameType.supportedTypes.map { $0.rawValue }
|
||||||
documentTypes.append(kUTTypeDeltaControllerSkin as String)
|
documentTypes.append(kUTTypeDeltaControllerSkin as String)
|
||||||
|
|
||||||
// Add GBA4iOS's exported UTIs in case user has GBA4iOS installed (which may override Delta's UTI declarations)
|
// Add GBA4iOS's exported UTIs in case user has GBA4iOS installed (which may override Delta's UTI declarations)
|
||||||
@ -69,10 +69,10 @@ class ImportController: NSObject
|
|||||||
let contents = try FileManager.default.contentsOfDirectory(at: documentsDirectoryURL, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
|
let contents = try FileManager.default.contentsOfDirectory(at: documentsDirectoryURL, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
|
||||||
|
|
||||||
DatabaseManager.shared.performBackgroundTask { (context) in
|
DatabaseManager.shared.performBackgroundTask { (context) in
|
||||||
let controllerSkinURLs = contents.filter { $0.pathExtension == "deltaskin" }
|
let controllerSkinURLs = contents.filter { $0.pathExtension.lowercased() == "deltaskin" }
|
||||||
self.importControllerSkins(at: controllerSkinURLs)
|
self.importControllerSkins(at: controllerSkinURLs)
|
||||||
|
|
||||||
let gameURLs = contents.filter { GameCollection.gameSystemCollectionForPathExtension($0.pathExtension, inManagedObjectContext: context).identifier != GameType.delta.rawValue }
|
let gameURLs = contents.filter { GameType.gameType(forFileExtension: $0.pathExtension) != .unknown }
|
||||||
self.importGames(at: gameURLs)
|
self.importGames(at: gameURLs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ class ImportController: NSObject
|
|||||||
{
|
{
|
||||||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)
|
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)
|
||||||
{
|
{
|
||||||
if url.pathExtension == "deltaskin"
|
if url.pathExtension.lowercased() == "deltaskin"
|
||||||
{
|
{
|
||||||
self.importControllerSkins(at: [url])
|
self.importControllerSkins(at: [url])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,7 +77,7 @@ private extension DatabaseManager
|
|||||||
{
|
{
|
||||||
self.performBackgroundTask { (context) in
|
self.performBackgroundTask { (context) in
|
||||||
|
|
||||||
for gameType in Game.supportedTypes
|
for gameType in GameType.supportedTypes
|
||||||
{
|
{
|
||||||
guard let deltaControllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: gameType) else { continue }
|
guard let deltaControllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: gameType) else { continue }
|
||||||
|
|
||||||
|
|||||||
@ -63,11 +63,3 @@ extension Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Game
|
|
||||||
{
|
|
||||||
class var supportedTypes: Set<GameType>
|
|
||||||
{
|
|
||||||
return [GameType.snes, GameType.gba]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -29,24 +29,16 @@ public class GameCollection: _GameCollection
|
|||||||
|
|
||||||
class func gameSystemCollectionForPathExtension(_ pathExtension: String?, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> GameCollection
|
class func gameSystemCollectionForPathExtension(_ pathExtension: String?, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> GameCollection
|
||||||
{
|
{
|
||||||
let identifier: String
|
let gameType = GameType.gameType(forFileExtension: pathExtension ?? "")
|
||||||
|
let identifier = gameType.rawValue
|
||||||
|
|
||||||
let index: Int16
|
let index: Int16
|
||||||
|
|
||||||
switch pathExtension ?? ""
|
switch gameType
|
||||||
{
|
{
|
||||||
case "smc": fallthrough
|
case GameType.snes: index = 1990
|
||||||
case "sfc": fallthrough
|
case GameType.gba: index = 2001
|
||||||
case "fig":
|
default: index = Int16(INT16_MAX)
|
||||||
identifier = GameType.snes.rawValue
|
|
||||||
index = 1990
|
|
||||||
|
|
||||||
case "gba":
|
|
||||||
identifier = GameType.gba.rawValue
|
|
||||||
index = 2001
|
|
||||||
|
|
||||||
default:
|
|
||||||
identifier = GameType.delta.rawValue
|
|
||||||
index = Int16(INT16_MAX)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let predicate = NSPredicate(format: "%K == %@", #keyPath(GameCollection.identifier), identifier)
|
let predicate = NSPredicate(format: "%K == %@", #keyPath(GameCollection.identifier), identifier)
|
||||||
|
|||||||
31
Delta/Extensions/GameType+Delta.swift
Normal file
31
Delta/Extensions/GameType+Delta.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// GameType+Delta.swift
|
||||||
|
// Delta
|
||||||
|
//
|
||||||
|
// Created by Riley Testut on 12/22/16.
|
||||||
|
// Copyright © 2016 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import DeltaCore
|
||||||
|
|
||||||
|
extension GameType
|
||||||
|
{
|
||||||
|
static var supportedTypes: Set<GameType>
|
||||||
|
{
|
||||||
|
return [GameType.snes, GameType.gba]
|
||||||
|
}
|
||||||
|
|
||||||
|
static func gameType(forFileExtension fileExtension: String) -> GameType
|
||||||
|
{
|
||||||
|
let gameType: GameType
|
||||||
|
|
||||||
|
switch fileExtension
|
||||||
|
{
|
||||||
|
case "smc", "sfc", "fig": gameType = GameType.snes
|
||||||
|
case "gba": gameType = GameType.gba
|
||||||
|
default: gameType = GameType.unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameType
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,7 +16,7 @@ extension GameType
|
|||||||
{
|
{
|
||||||
case GameType.snes: return NSLocalizedString("Super Nintendo Entertainment System", comment: "")
|
case GameType.snes: return NSLocalizedString("Super Nintendo Entertainment System", comment: "")
|
||||||
case GameType.gba: return NSLocalizedString("Game Boy Advance", comment: "")
|
case GameType.gba: return NSLocalizedString("Game Boy Advance", comment: "")
|
||||||
case GameType.delta: return NSLocalizedString("Unsupported System", comment: "")
|
case GameType.unknown: return NSLocalizedString("Unsupported System", comment: "")
|
||||||
default: return NSLocalizedString("Unknown", comment: "")
|
default: return NSLocalizedString("Unknown", comment: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ extension GameType
|
|||||||
{
|
{
|
||||||
case GameType.snes: return NSLocalizedString("SNES", comment: "")
|
case GameType.snes: return NSLocalizedString("SNES", comment: "")
|
||||||
case GameType.gba: return NSLocalizedString("GBA", comment: "")
|
case GameType.gba: return NSLocalizedString("GBA", comment: "")
|
||||||
case GameType.delta: return NSLocalizedString("Unsupported", comment: "")
|
case GameType.unknown: return NSLocalizedString("Unsupported", comment: "")
|
||||||
default: return NSLocalizedString("Unknown", comment: "")
|
default: return NSLocalizedString("Unknown", comment: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user