From 93493534e0c2bdbe0c49ab000c85546e7c73b006 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Sun, 30 Apr 2017 21:39:13 -0700 Subject: [PATCH] Adds support for GBC games Adds System enum to represent supported game systems, simplifying the process to add future game systems. --- .gitmodules | 3 + Cores/GBCDeltaCore | 1 + Delta.xcodeproj/project.pbxproj | 34 ++++-- Delta.xcworkspace/contents.xcworkspacedata | 3 + Delta/AppDelegate.swift | 8 +- .../Importing/ImportController.swift | 4 +- Delta/Database/DatabaseManager.swift | 36 +++--- .../Database/Model/Human/GameCollection.swift | 44 ++------ Delta/Emulation/GameViewController.swift | 8 +- .../Extensions/DeltaCoreProtocol+Delta.swift | 10 +- Delta/Extensions/GameType+Delta.swift | 31 ------ Delta/Extensions/GameType+Localization.swift | 34 ------ .../UIAlertController+Importing.swift | 1 + .../ControllerSkinsViewController.swift | 8 +- ...SystemControllerSkinsViewController.swift} | 22 ++-- Delta/Settings/Settings.storyboard | 57 ++++++---- Delta/Settings/Settings.swift | 30 +++-- Delta/Settings/SettingsViewController.swift | 39 +++++-- Delta/Supporting Files/Info.plist | 54 +++++++-- Delta/Systems/System.swift | 103 ++++++++++++++++++ 20 files changed, 315 insertions(+), 215 deletions(-) create mode 160000 Cores/GBCDeltaCore delete mode 100644 Delta/Extensions/GameType+Delta.swift delete mode 100644 Delta/Extensions/GameType+Localization.swift rename Delta/Settings/Controller Skins/{GameTypeControllerSkinsViewController.swift => SystemControllerSkinsViewController.swift} (85%) create mode 100644 Delta/Systems/System.swift diff --git a/.gitmodules b/.gitmodules index 8996cfa..8c6f712 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "Cores/GBADeltaCore"] path = Cores/GBADeltaCore url = git@github.com:rileytestut/GBADeltaCore.git +[submodule "Cores/GBCDeltaCore"] + path = Cores/GBCDeltaCore + url = git@github.com:rileytestut/GBCDeltaCore.git diff --git a/Cores/GBCDeltaCore b/Cores/GBCDeltaCore new file mode 160000 index 0000000..0e622c7 --- /dev/null +++ b/Cores/GBCDeltaCore @@ -0,0 +1 @@ +Subproject commit 0e622c7887e781363e36f6c7bfcd67fba3cb00ac diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index b4b9486..fbdddf2 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -27,12 +27,11 @@ BF0418151D01E93400E85BCF /* GBADeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BF0418131D01E93400E85BCF /* GBADeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BF04E6FF1DB8625C000F35D3 /* ControllerSkinsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF04E6FE1DB8625C000F35D3 /* ControllerSkinsViewController.swift */; }; BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF107EC31BF413F000E0C32C /* GamesViewController.swift */; }; - BF11734D1DA32A5200047DF8 /* GameType+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF11734C1DA32A5200047DF8 /* GameType+Localization.swift */; }; BF1173501DA32CF600047DF8 /* ControllersSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF11734F1DA32CF600047DF8 /* ControllersSettingsViewController.swift */; }; BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF13A7551D5D29B0000BB055 /* PreviewGameViewController.swift */; }; BF13A7581D5D2FD9000BB055 /* EmulatorCore+Cheats.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF13A7571D5D2FD9000BB055 /* EmulatorCore+Cheats.swift */; }; BF18B61F1E2985F900F70067 /* UIAlertController+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF18B61E1E2985F900F70067 /* UIAlertController+Importing.swift */; }; - BF1DAD5D1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1DAD5C1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift */; }; + BF1DAD5D1D9F576000E752A7 /* SystemControllerSkinsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1DAD5C1D9F576000E752A7 /* SystemControllerSkinsViewController.swift */; }; BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF6BB2451BB73FE800CCF94A /* Assets.xcassets */; }; BF2B98E61C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2B98E51C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift */; }; BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF31878A1D489AAA00BD020D /* CheatValidator.swift */; }; @@ -76,6 +75,7 @@ BF797A2D1C2D339F00F1A000 /* UILabel+FontSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */; }; BF7AE8081C2E858400B1B5BC /* PauseMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8041C2E858400B1B5BC /* PauseMenuViewController.swift */; }; BF7AE80A1C2E8C7600B1B5BC /* UIColor+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */; }; + BF930FFD1EB6D6FF00E8DBA0 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF930FFC1EB6D6FF00E8DBA0 /* System.swift */; }; BF95E2771E4977BF0030E7AD /* GameMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF95E2761E4977BF0030E7AD /* GameMetadata.swift */; }; BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF95E2781E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift */; }; BF99A5971DC2F9C400468E9E /* ControllerSkinTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF99A5961DC2F9C400468E9E /* ControllerSkinTableViewCell.swift */; }; @@ -86,7 +86,6 @@ BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF63BDE91D389EEB00FCB040 /* GameViewController.swift */; }; BFAA1FED1B8AA4FA00495943 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFAA1FEC1B8AA4FA00495943 /* Settings.swift */; }; BFBAB2E31EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBAB2E21EB685A2004E0B0E /* DeltaCoreProtocol+Delta.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 */; }; BFCEA67E1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */; }; BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3540041C5DA70400C1184C /* SaveStatesViewController.swift */; }; @@ -94,6 +93,8 @@ BFE4269E1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */; }; BFEC732D1AAECC4A00650035 /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; }; BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFEC732C1AAECC4A00650035 /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + BFF0742C1E9DC17500ACDF4A /* GBCDeltaCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */; }; + BFF0742D1E9DC17500ACDF4A /* GBCDeltaCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; BFF93AA01E0FB036005EC865 /* InputStreamOutputWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF93A9F1E0FB036005EC865 /* InputStreamOutputWriter.swift */; }; BFFA4C091E8A24D600D87934 /* GameMetadataTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA4C081E8A24D600D87934 /* GameMetadataTableViewCell.swift */; }; BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; }; @@ -114,6 +115,7 @@ dstSubfolderSpec = 10; files = ( BF9F4FD01AAD7B87004C9500 /* DeltaCore.framework in Embed Frameworks */, + BFF0742D1E9DC17500ACDF4A /* GBCDeltaCore.framework in Embed Frameworks */, BFEC732E1AAECC4A00650035 /* Roxas.framework in Embed Frameworks */, BF70798D1B6B464B0019077C /* ZipZap.framework in Embed Frameworks */, BF0418151D01E93400E85BCF /* GBADeltaCore.framework in Embed Frameworks */, @@ -133,12 +135,11 @@ BF04E6FE1DB8625C000F35D3 /* ControllerSkinsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllerSkinsViewController.swift; path = "Controller Skins/ControllerSkinsViewController.swift"; sourceTree = ""; }; BF090CF11B490D8300DCAB45 /* Delta-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Delta-Bridging-Header.h"; sourceTree = ""; }; BF107EC31BF413F000E0C32C /* GamesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesViewController.swift; sourceTree = ""; }; - BF11734C1DA32A5200047DF8 /* GameType+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameType+Localization.swift"; sourceTree = ""; }; BF11734F1DA32CF600047DF8 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllersSettingsViewController.swift; path = Controllers/ControllersSettingsViewController.swift; sourceTree = ""; }; BF13A7551D5D29B0000BB055 /* PreviewGameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewGameViewController.swift; sourceTree = ""; }; BF13A7571D5D2FD9000BB055 /* EmulatorCore+Cheats.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EmulatorCore+Cheats.swift"; sourceTree = ""; }; BF18B61E1E2985F900F70067 /* UIAlertController+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Importing.swift"; sourceTree = ""; }; - BF1DAD5C1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameTypeControllerSkinsViewController.swift; path = "Controller Skins/GameTypeControllerSkinsViewController.swift"; sourceTree = ""; }; + BF1DAD5C1D9F576000E752A7 /* SystemControllerSkinsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SystemControllerSkinsViewController.swift; path = "Controller Skins/SystemControllerSkinsViewController.swift"; sourceTree = ""; }; BF27CC861BC9E3C600A20D89 /* Delta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Delta.entitlements; sourceTree = ""; }; BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pods.framework; path = "Pods/../build/Debug-appletvos/Pods.framework"; sourceTree = ""; }; BF27CC941BCB7B7A00A20D89 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; @@ -188,6 +189,7 @@ BF797A2C1C2D339F00F1A000 /* UILabel+FontSize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+FontSize.swift"; sourceTree = ""; }; BF7AE8041C2E858400B1B5BC /* PauseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseMenuViewController.swift; path = "Pause Menu/PauseMenuViewController.swift"; sourceTree = ""; }; BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Delta.swift"; sourceTree = ""; }; + BF930FFC1EB6D6FF00E8DBA0 /* System.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = System.swift; path = Systems/System.swift; sourceTree = ""; }; BF95E2761E4977BF0030E7AD /* GameMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameMetadata.swift; path = Database/OpenVGDB/GameMetadata.swift; sourceTree = ""; }; BF95E2781E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GamesDatabaseBrowserViewController.swift; path = Database/OpenVGDB/GamesDatabaseBrowserViewController.swift; sourceTree = ""; }; BF99A5961DC2F9C400468E9E /* ControllerSkinTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllerSkinTableViewCell.swift; path = "Controller Skins/ControllerSkinTableViewCell.swift"; sourceTree = ""; }; @@ -195,12 +197,12 @@ BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; BFBAB2E21EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DeltaCoreProtocol+Delta.swift"; sourceTree = ""; }; 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 = ""; }; BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatsViewController.swift; path = "Pause Menu/Cheats/CheatsViewController.swift"; sourceTree = ""; }; BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContextTransitioning+Conveniences.swift"; sourceTree = ""; }; BFDD04F01D5E2C27002D450E /* GameCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameCollectionViewController.swift; sourceTree = ""; }; BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SaveStatesStoryboardSegue.swift; path = Segues/SaveStatesStoryboardSegue.swift; sourceTree = ""; }; BFEC732C1AAECC4A00650035 /* Roxas.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Roxas.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = GBCDeltaCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BFF93A9F1E0FB036005EC865 /* InputStreamOutputWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InputStreamOutputWriter.swift; path = Components/Importing/InputStreamOutputWriter.swift; sourceTree = ""; }; BFFA4C081E8A24D600D87934 /* GameMetadataTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameMetadataTableViewCell.swift; path = Database/OpenVGDB/GameMetadataTableViewCell.swift; sourceTree = ""; }; BFFA71D71AAC406100EE9DD1 /* Delta.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Delta.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -226,6 +228,7 @@ BF99C6941D0A9AA600BA92BC /* SNESDeltaCore.framework in Frameworks */, BF70798C1B6B464B0019077C /* ZipZap.framework in Frameworks */, BF0418141D01E93400E85BCF /* GBADeltaCore.framework in Frameworks */, + BFF0742C1E9DC17500ACDF4A /* GBCDeltaCore.framework in Frameworks */, 4FE8465FD28810191C3E5212 /* Pods_Delta.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -240,13 +243,11 @@ BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */, BFCEA67D1D56FF640061A534 /* UIViewControllerContextTransitioning+Conveniences.swift */, BF13A7571D5D2FD9000BB055 /* EmulatorCore+Cheats.swift */, - BF11734C1DA32A5200047DF8 /* GameType+Localization.swift */, BF6866161DCAC8B900BF2D06 /* ControllerSkin+Configuring.swift */, BF59428F1E09BD1A0051894B /* NSFetchedResultsController+Conveniences.h */, BF5942901E09BD1A0051894B /* NSFetchedResultsController+Conveniences.m */, BF5942911E09BD1A0051894B /* NSManagedObject+Conveniences.swift */, BF5942921E09BD1A0051894B /* NSManagedObjectContext+Conveniences.swift */, - BFC314761E0C8CFC0056E3A8 /* GameType+Delta.swift */, BFBAB2E21EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift */, BF18B61E1E2985F900F70067 /* UIAlertController+Importing.swift */, ); @@ -264,7 +265,7 @@ BF1DAD5B1D9F574900E752A7 /* Controller Skins */ = { isa = PBXGroup; children = ( - BF1DAD5C1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift */, + BF1DAD5C1D9F576000E752A7 /* SystemControllerSkinsViewController.swift */, BF04E6FE1DB8625C000F35D3 /* ControllerSkinsViewController.swift */, BF99A5961DC2F9C400468E9E /* ControllerSkinTableViewCell.swift */, ); @@ -422,6 +423,14 @@ name = Segues; sourceTree = ""; }; + BF930FFB1EB6D6EC00E8DBA0 /* Systems */ = { + isa = PBXGroup; + children = ( + BF930FFC1EB6D6FF00E8DBA0 /* System.swift */, + ); + name = Systems; + sourceTree = ""; + }; BF95E2751E49763D0030E7AD /* OpenVGDB */ = { isa = PBXGroup; children = ( @@ -436,6 +445,7 @@ BF9F4FCD1AAD7B25004C9500 /* Frameworks */ = { isa = PBXGroup; children = ( + BFF0742B1E9DC17500ACDF4A /* GBCDeltaCore.framework */, BF0418131D01E93400E85BCF /* GBADeltaCore.framework */, BF27CC941BCB7B7A00A20D89 /* GameController.framework */, BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */, @@ -512,6 +522,7 @@ BF7AE7FA1C2E851F00B1B5BC /* Pause Menu */, BFAA1FEB1B8AA4E800495943 /* Settings */, BF59426C1E09BC450051894B /* Database */, + BF930FFB1EB6D6EC00E8DBA0 /* Systems */, BF5942571E09BB5D0051894B /* Components */, BF696B7E1D9B2AE6009639E0 /* Theming */, BF090CEE1B490C1A00DCAB45 /* Extensions */, @@ -733,6 +744,7 @@ BF59428A1E09BC8B0051894B /* _SaveState.swift in Sources */, BF5942801E09BC830051894B /* SaveState.swift in Sources */, BF59428E1E09BCFB0051894B /* ImportController.swift in Sources */, + BF930FFD1EB6D6FF00E8DBA0 /* System.swift in Sources */, BF13A7581D5D2FD9000BB055 /* EmulatorCore+Cheats.swift in Sources */, BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */, BFFC46201D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift in Sources */, @@ -747,14 +759,13 @@ BF04E6FF1DB8625C000F35D3 /* ControllerSkinsViewController.swift in Sources */, BF5942891E09BC8B0051894B /* _GameCollection.swift in Sources */, BF34FA111CF1899D006624C7 /* CheatTextView.swift in Sources */, - BF1DAD5D1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift in Sources */, + BF1DAD5D1D9F576000E752A7 /* SystemControllerSkinsViewController.swift in Sources */, BFFA4C091E8A24D600D87934 /* GameMetadataTableViewCell.swift in Sources */, BFFC46231D5984A000AF2CC6 /* LaunchViewController.swift in Sources */, BF5942701E09BC5D0051894B /* GamesDatabase.swift in Sources */, BF34FA071CF0F510006624C7 /* EditCheatViewController.swift in Sources */, BF5942881E09BC8B0051894B /* _Game.swift in Sources */, BF95E2771E4977BF0030E7AD /* GameMetadata.swift in Sources */, - BF11734D1DA32A5200047DF8 /* GameType+Localization.swift in Sources */, BFFC461F1D59823500AF2CC6 /* GamesStoryboardSegue.swift in Sources */, BF2B98E61C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift in Sources */, BFC9B7391CEFCD34008629BB /* CheatsViewController.swift in Sources */, @@ -768,7 +779,6 @@ BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */, BFD097211D3A01B8005A44C2 /* SaveStatesViewController.swift in Sources */, BF3540021C5DA3D500C1184C /* PauseStoryboardSegue.swift in Sources */, - BFC314771E0C8CFC0056E3A8 /* GameType+Delta.swift in Sources */, BF107EC41BF413F000E0C32C /* GamesViewController.swift in Sources */, BF59426F1E09BC5D0051894B /* DatabaseManager.swift in Sources */, BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */, diff --git a/Delta.xcworkspace/contents.xcworkspacedata b/Delta.xcworkspace/contents.xcworkspacedata index 6e7a98d..f51f87a 100644 --- a/Delta.xcworkspace/contents.xcworkspacedata +++ b/Delta.xcworkspace/contents.xcworkspacedata @@ -13,6 +13,9 @@ + + diff --git a/Delta/AppDelegate.swift b/Delta/AppDelegate.swift index 73ec644..02e2800 100644 --- a/Delta/AppDelegate.swift +++ b/Delta/AppDelegate.swift @@ -9,8 +9,6 @@ import UIKit import DeltaCore -import SNESDeltaCore -import GBADeltaCore @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate @@ -21,8 +19,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Settings.registerDefaults() - Delta.register(SNES.core) - Delta.register(GBA.core) + System.supportedSystems.forEach { Delta.register($0.deltaCore) } self.configureAppearance() @@ -92,8 +89,7 @@ extension AppDelegate { guard url.isFileURL else { return false } - let gameType = GameType.gameType(forFileExtension: url.pathExtension) - if gameType != .unknown || url.pathExtension.lowercased() == "zip" + if GameType(fileExtension: url.pathExtension) != nil || url.pathExtension.lowercased() == "zip" { return self.importGame(at: url) } diff --git a/Delta/Components/Importing/ImportController.swift b/Delta/Components/Importing/ImportController.swift index ae3864d..0991ec5 100644 --- a/Delta/Components/Importing/ImportController.swift +++ b/Delta/Components/Importing/ImportController.swift @@ -40,7 +40,7 @@ class ImportController: NSObject { self.presentingViewController = presentingViewController - var documentTypes = GameType.supportedTypes.map { $0.rawValue } + var documentTypes = System.supportedSystems.map { $0.gameType.rawValue } documentTypes.append(kUTTypeDeltaControllerSkin as String) documentTypes.append(kUTTypeZipArchive as String) @@ -75,7 +75,7 @@ class ImportController: NSObject let controllerSkinURLs = contents.filter { $0.pathExtension.lowercased() == "deltaskin" } self.importControllerSkins(at: Set(controllerSkinURLs)) - let gameURLs = contents.filter { GameType.gameType(forFileExtension: $0.pathExtension) != .unknown || $0.pathExtension.lowercased() == "zip" } + let gameURLs = contents.filter { GameType(fileExtension: $0.pathExtension) != nil || $0.pathExtension.lowercased() == "zip" } self.importGames(at: Set(gameURLs)) } diff --git a/Delta/Database/DatabaseManager.swift b/Delta/Database/DatabaseManager.swift index 2db6281..61a69e5 100644 --- a/Delta/Database/DatabaseManager.swift +++ b/Delta/Database/DatabaseManager.swift @@ -22,6 +22,7 @@ extension DatabaseManager { case doesNotExist(URL) case invalid(URL) + case unsupported(URL) case unknown(URL, NSError) case saveFailed(Set, NSError) @@ -30,8 +31,9 @@ extension DatabaseManager { case .doesNotExist: return 0 case .invalid: return 1 - case .unknown: return 2 - case .saveFailed: return 3 + case .unsupported: return 2 + case .unknown: return 3 + case .saveFailed: return 4 } } @@ -41,10 +43,12 @@ extension DatabaseManager { case (let .doesNotExist(url1), let .doesNotExist(url2)) where url1 == url2: return true case (let .invalid(url1), let .invalid(url2)) where url1 == url2: return true + case (let .unsupported(url1), let .unsupported(url2)) where url1 == url2: return true case (let .unknown(url1, error1), let .unknown(url2, error2)) where url1 == url2 && error1 == error2: return true case (let .saveFailed(urls1, error1), let .saveFailed(urls2, error2)) where urls1 == urls2 && error1 == error2: return true case (.doesNotExist, _): return false case (.invalid, _): return false + case (.unsupported, _): return false case (.unknown, _): return false case (.saveFailed, _): return false } @@ -99,9 +103,9 @@ private extension DatabaseManager { self.performBackgroundTask { (context) in - for gameType in GameType.supportedTypes + for system in System.supportedSystems { - guard let deltaControllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: gameType) else { continue } + guard let deltaControllerSkin = DeltaCore.ControllerSkin.standardControllerSkin(for: system.gameType) else { continue } let controllerSkin = ControllerSkin(context: context) controllerSkin.isStandard = true @@ -173,21 +177,27 @@ extension DatabaseManager continue } - let identifier = FileHash.sha1HashOfFile(atPath: url.path) as String + guard let gameType = GameType(fileExtension: url.pathExtension), let system = System(gameType: gameType) else { + errors.insert(.unsupported(url)) + continue + } + let identifier = FileHash.sha1HashOfFile(atPath: url.path) as String let filename = identifier + "." + url.pathExtension - let game = Game.insertIntoManagedObjectContext(context) + let game = Game(context: context) game.identifier = identifier + game.type = gameType game.filename = filename let databaseMetadata = self.gamesDatabase?.metadata(for: game) game.name = databaseMetadata?.name ?? url.deletingPathExtension().lastPathComponent game.artworkURL = databaseMetadata?.artworkURL - - let gameCollection = GameCollection.gameSystemCollectionForPathExtension(url.pathExtension, inManagedObjectContext: context) - game.type = GameType(rawValue: gameCollection.identifier) - game.gameCollections.insert(gameCollection) + + let gameCollection = GameCollection(context: context) + gameCollection.identifier = gameType.rawValue + gameCollection.index = Int16(system.year) + gameCollection.games.insert(game) do { @@ -212,7 +222,6 @@ extension DatabaseManager errors.insert(.unknown(url, error)) } - } do @@ -328,9 +337,8 @@ extension DatabaseManager guard !entry.fileName.contains("/") else { continue } let fileExtension = (entry.fileName as NSString).pathExtension - let gameType = GameType.gameType(forFileExtension: fileExtension) - - guard gameType != .unknown else { continue } + + guard GameType(fileExtension: fileExtension) != nil else { continue } // At least one entry is a valid game file, so we set archiveContainsValidGameFile to true // This will result in this archive being considered valid, and thus we will not return an ImportError.invalid error for the archive diff --git a/Delta/Database/Model/Human/GameCollection.swift b/Delta/Database/Model/Human/GameCollection.swift index bfa5635..6e5fca4 100644 --- a/Delta/Database/Model/Human/GameCollection.swift +++ b/Delta/Database/Model/Human/GameCollection.swift @@ -9,48 +9,22 @@ import CoreData import DeltaCore -import SNESDeltaCore -import GBADeltaCore @objc(GameCollection) -public class GameCollection: _GameCollection +public class GameCollection: _GameCollection { - var name: String - { - let gameType = GameType(rawValue: self.identifier) - return gameType.localizedName + var name: String { + return self.system?.localizedName ?? NSLocalizedString("Unknown", comment: "") } - var shortName: String - { - let gameType = GameType(rawValue: self.identifier) - return gameType.localizedShortName + var shortName: String { + return self.system?.localizedShortName ?? NSLocalizedString("Unknown", comment: "") } - class func gameSystemCollectionForPathExtension(_ pathExtension: String?, inManagedObjectContext managedObjectContext: NSManagedObjectContext) -> GameCollection - { - let gameType = GameType.gameType(forFileExtension: pathExtension ?? "") - let identifier = gameType.rawValue + var system: System? { + let gameType = GameType(rawValue: self.identifier) - let index: Int16 - - switch gameType - { - case GameType.snes: index = 1990 - case GameType.gba: index = 2001 - default: index = Int16(INT16_MAX) - } - - let predicate = NSPredicate(format: "%K == %@", #keyPath(GameCollection.identifier), identifier) - - var gameCollection = GameCollection.instancesWithPredicate(predicate, inManagedObjectContext: managedObjectContext, type: GameCollection.self).first - if gameCollection == nil - { - gameCollection = GameCollection.insertIntoManagedObjectContext(managedObjectContext) - gameCollection?.identifier = identifier - gameCollection?.index = index - } - - return gameCollection! + let system = System(gameType: gameType) + return system } } diff --git a/Delta/Emulation/GameViewController.swift b/Delta/Emulation/GameViewController.swift index 10ac1bd..120f844 100644 --- a/Delta/Emulation/GameViewController.swift +++ b/Delta/Emulation/GameViewController.swift @@ -391,11 +391,11 @@ private extension GameViewController func updateControllerSkin() { - guard let game = self.game else { return } + guard let game = self.game, let system = System(gameType: game.type) else { return } let traits = DeltaCore.ControllerSkin.Traits.defaults(for: self.view) - let controllerSkin = Settings.preferredControllerSkin(for: game.type, traits: traits) + let controllerSkin = Settings.preferredControllerSkin(for: system, traits: traits) self.controllerView.controllerSkin = controllerSkin if controllerSkin?.isTranslucent(for: traits) ?? false @@ -807,12 +807,12 @@ private extension GameViewController case .preferredControllerSkin: guard - let gameType = notification.userInfo?[Settings.NotificationUserInfoKey.gameType] as? GameType, + let system = notification.userInfo?[Settings.NotificationUserInfoKey.system] as? System, let traits = notification.userInfo?[Settings.NotificationUserInfoKey.traits] as? DeltaCore.ControllerSkin.Traits else { return } let currentTraits = DeltaCore.ControllerSkin.Traits.defaults(for: self.view) - if gameType == self.game?.type && traits == currentTraits + if system.gameType == self.game?.type && traits == currentTraits { self.updateControllerSkin() } diff --git a/Delta/Extensions/DeltaCoreProtocol+Delta.swift b/Delta/Extensions/DeltaCoreProtocol+Delta.swift index 06aad27..a11418a 100644 --- a/Delta/Extensions/DeltaCoreProtocol+Delta.swift +++ b/Delta/Extensions/DeltaCoreProtocol+Delta.swift @@ -7,15 +7,17 @@ // import DeltaCore -import GBADeltaCore extension DeltaCoreProtocol { var supportedRates: ClosedRange { - switch self.gameType + guard let system = System(gameType: self.gameType) else { return 1...1 } + + switch system { - case GameType.gba: return 1...3 - default: return 1...4 + case .snes: return 1...4 + case .gba: return 1...3 + case .gbc: return 1...4 } } } diff --git a/Delta/Extensions/GameType+Delta.swift b/Delta/Extensions/GameType+Delta.swift deleted file mode 100644 index 7911dd2..0000000 --- a/Delta/Extensions/GameType+Delta.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// 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 - { - return [GameType.snes, GameType.gba] - } - - static func gameType(forFileExtension fileExtension: String) -> GameType - { - let gameType: GameType - - switch fileExtension.lowercased() - { - case "smc", "sfc", "fig": gameType = GameType.snes - case "gba": gameType = GameType.gba - default: gameType = GameType.unknown - } - - return gameType - } -} diff --git a/Delta/Extensions/GameType+Localization.swift b/Delta/Extensions/GameType+Localization.swift deleted file mode 100644 index c176238..0000000 --- a/Delta/Extensions/GameType+Localization.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// GameType+Localization.swift -// Delta -// -// Created by Riley Testut on 10/3/16. -// Copyright © 2016 Riley Testut. All rights reserved. -// - -import DeltaCore - -extension GameType -{ - var localizedName: String - { - switch self - { - case GameType.snes: return NSLocalizedString("Super Nintendo Entertainment System", comment: "") - case GameType.gba: return NSLocalizedString("Game Boy Advance", comment: "") - case GameType.unknown: return NSLocalizedString("Unsupported System", comment: "") - default: return NSLocalizedString("Unknown", comment: "") - } - } - - var localizedShortName: String - { - switch self - { - case GameType.snes: return NSLocalizedString("SNES", comment: "") - case GameType.gba: return NSLocalizedString("GBA", comment: "") - case GameType.unknown: return NSLocalizedString("Unsupported", comment: "") - default: return NSLocalizedString("Unknown", comment: "") - } - } -} diff --git a/Delta/Extensions/UIAlertController+Importing.swift b/Delta/Extensions/UIAlertController+Importing.swift index adac8c1..f326d36 100644 --- a/Delta/Extensions/UIAlertController+Importing.swift +++ b/Delta/Extensions/UIAlertController+Importing.swift @@ -38,6 +38,7 @@ extension UIAlertController { case .doesNotExist(let url): urls.insert(url) case .invalid(let url): urls.insert(url) + case .unsupported(let url): urls.insert(url) case .unknown(let url, _): urls.insert(url) case .saveFailed(let errorURLs, _): urls.formUnion(errorURLs) } diff --git a/Delta/Settings/Controller Skins/ControllerSkinsViewController.swift b/Delta/Settings/Controller Skins/ControllerSkinsViewController.swift index e6c8fa5..25bf6d7 100644 --- a/Delta/Settings/Controller Skins/ControllerSkinsViewController.swift +++ b/Delta/Settings/Controller Skins/ControllerSkinsViewController.swift @@ -23,7 +23,7 @@ extension ControllerSkinsViewController class ControllerSkinsViewController: UITableViewController { - var gameType: GameType! { + var system: System! { didSet { self.updateDataSource() } @@ -67,12 +67,12 @@ private extension ControllerSkinsViewController //MARK: - Update func updateDataSource() { - guard let gameType = self.gameType, let traits = self.traits else { return } + guard let system = self.system, let traits = self.traits else { return } let configuration = ControllerSkinConfigurations(traits: traits) let fetchRequest: NSFetchRequest = ControllerSkin.fetchRequest() - fetchRequest.predicate = NSPredicate(format: "%K == %@ AND (%K & %d) == %d", #keyPath(ControllerSkin.gameType), gameType.rawValue, #keyPath(ControllerSkin.supportedConfigurations), configuration.rawValue, configuration.rawValue) + fetchRequest.predicate = NSPredicate(format: "%K == %@ AND (%K & %d) == %d", #keyPath(ControllerSkin.gameType), system.gameType.rawValue, #keyPath(ControllerSkin.supportedConfigurations), configuration.rawValue, configuration.rawValue) fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(ControllerSkin.isStandard), ascending: false), NSSortDescriptor(key: #keyPath(ControllerSkin.name), ascending: true)] self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: #keyPath(ControllerSkin.name), cacheName: nil) @@ -159,7 +159,7 @@ extension ControllerSkinsViewController override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let controllerSkin = self.dataSource.item(at: indexPath) - Settings.setPreferredControllerSkin(controllerSkin, for: self.gameType, traits: self.traits) + Settings.setPreferredControllerSkin(controllerSkin, for: self.system, traits: self.traits) _ = self.navigationController?.popViewController(animated: true) } diff --git a/Delta/Settings/Controller Skins/GameTypeControllerSkinsViewController.swift b/Delta/Settings/Controller Skins/SystemControllerSkinsViewController.swift similarity index 85% rename from Delta/Settings/Controller Skins/GameTypeControllerSkinsViewController.swift rename to Delta/Settings/Controller Skins/SystemControllerSkinsViewController.swift index f162cc7..87e3870 100644 --- a/Delta/Settings/Controller Skins/GameTypeControllerSkinsViewController.swift +++ b/Delta/Settings/Controller Skins/SystemControllerSkinsViewController.swift @@ -1,5 +1,5 @@ // -// GameTypeControllerSkinsViewController.swift +// SystemControllerSkinsViewController.swift // Delta // // Created by Riley Testut on 9/30/16. @@ -10,7 +10,7 @@ import UIKit import DeltaCore -extension GameTypeControllerSkinsViewController +extension SystemControllerSkinsViewController { fileprivate enum Section: Int { @@ -19,21 +19,21 @@ extension GameTypeControllerSkinsViewController } } -class GameTypeControllerSkinsViewController: UITableViewController +class SystemControllerSkinsViewController: UITableViewController { - var gameType: GameType! + var system: System! @IBOutlet fileprivate var portraitImageView: UIImageView! @IBOutlet fileprivate var landscapeImageView: UIImageView! } -extension GameTypeControllerSkinsViewController +extension SystemControllerSkinsViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = self.gameType.localizedShortName + self.title = self.system.localizedShortName } override func viewWillAppear(_ animated: Bool) @@ -53,7 +53,7 @@ extension GameTypeControllerSkinsViewController guard let cell = sender as? UITableViewCell, let indexPath = self.tableView.indexPath(for: cell) else { return } let controllerSkinsViewController = segue.destination as! ControllerSkinsViewController - controllerSkinsViewController.gameType = self.gameType + controllerSkinsViewController.system = self.system var traits = DeltaCore.ControllerSkin.Traits.defaults(for: self.view) @@ -68,7 +68,7 @@ extension GameTypeControllerSkinsViewController } } -extension GameTypeControllerSkinsViewController +extension SystemControllerSkinsViewController { override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { @@ -98,15 +98,15 @@ extension GameTypeControllerSkinsViewController } } -private extension GameTypeControllerSkinsViewController +private extension SystemControllerSkinsViewController { func updateControllerSkins() { let portraitTraits = DeltaCore.ControllerSkin.Traits(deviceType: .iphone, displayMode: DeltaCore.ControllerSkin.DisplayMode.fullScreen, orientation: .portrait) let landscapeTraits = DeltaCore.ControllerSkin.Traits(deviceType: .iphone, displayMode: DeltaCore.ControllerSkin.DisplayMode.fullScreen, orientation: .landscape) - let portraitControllerSkin = Settings.preferredControllerSkin(for: self.gameType, traits: portraitTraits) - let landscapeControllerSkin = Settings.preferredControllerSkin(for: self.gameType, traits: landscapeTraits) + let portraitControllerSkin = Settings.preferredControllerSkin(for: self.system, traits: portraitTraits) + let landscapeControllerSkin = Settings.preferredControllerSkin(for: self.system, traits: landscapeTraits) self.portraitImageView.image = portraitControllerSkin?.image(for: portraitTraits, preferredSize: UIScreen.main.defaultControllerSkinSize) self.landscapeImageView.image = landscapeControllerSkin?.image(for: landscapeTraits, preferredSize: UIScreen.main.defaultControllerSkinSize) diff --git a/Delta/Settings/Settings.storyboard b/Delta/Settings/Settings.storyboard index 52357dc..73450e5 100644 --- a/Delta/Settings/Settings.storyboard +++ b/Delta/Settings/Settings.storyboard @@ -1,11 +1,11 @@ - + - + @@ -21,8 +21,8 @@ - - + + @@ -45,8 +45,8 @@ - - + + @@ -69,8 +69,8 @@ - - + + @@ -93,8 +93,8 @@ - - + + @@ -121,14 +121,14 @@ - - + + - - - + + - + - + + + + + + + + + +