Adds support for GBC games

Adds System enum to represent supported game systems, simplifying the process to add future game systems.
This commit is contained in:
Riley Testut 2017-04-30 21:39:13 -07:00
parent d7db69925e
commit 93493534e0
20 changed files with 315 additions and 215 deletions

3
.gitmodules vendored
View File

@ -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

1
Cores/GBCDeltaCore Submodule

@ -0,0 +1 @@
Subproject commit 0e622c7887e781363e36f6c7bfcd67fba3cb00ac

View File

@ -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 = "<group>"; };
BF090CF11B490D8300DCAB45 /* Delta-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Delta-Bridging-Header.h"; sourceTree = "<group>"; };
BF107EC31BF413F000E0C32C /* GamesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesViewController.swift; sourceTree = "<group>"; };
BF11734C1DA32A5200047DF8 /* GameType+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GameType+Localization.swift"; sourceTree = "<group>"; };
BF11734F1DA32CF600047DF8 /* ControllersSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllersSettingsViewController.swift; path = Controllers/ControllersSettingsViewController.swift; sourceTree = "<group>"; };
BF13A7551D5D29B0000BB055 /* PreviewGameViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewGameViewController.swift; sourceTree = "<group>"; };
BF13A7571D5D2FD9000BB055 /* EmulatorCore+Cheats.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EmulatorCore+Cheats.swift"; sourceTree = "<group>"; };
BF18B61E1E2985F900F70067 /* UIAlertController+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+Importing.swift"; sourceTree = "<group>"; };
BF1DAD5C1D9F576000E752A7 /* GameTypeControllerSkinsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameTypeControllerSkinsViewController.swift; path = "Controller Skins/GameTypeControllerSkinsViewController.swift"; sourceTree = "<group>"; };
BF1DAD5C1D9F576000E752A7 /* SystemControllerSkinsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SystemControllerSkinsViewController.swift; path = "Controller Skins/SystemControllerSkinsViewController.swift"; sourceTree = "<group>"; };
BF27CC861BC9E3C600A20D89 /* Delta.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Delta.entitlements; sourceTree = "<group>"; };
BF27CC8A1BC9FE4D00A20D89 /* Pods.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pods.framework; path = "Pods/../build/Debug-appletvos/Pods.framework"; sourceTree = "<group>"; };
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 = "<group>"; };
BF7AE8041C2E858400B1B5BC /* PauseMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseMenuViewController.swift; path = "Pause Menu/PauseMenuViewController.swift"; sourceTree = "<group>"; };
BF7AE8091C2E8C7600B1B5BC /* UIColor+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Delta.swift"; sourceTree = "<group>"; };
BF930FFC1EB6D6FF00E8DBA0 /* System.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = System.swift; path = Systems/System.swift; sourceTree = "<group>"; };
BF95E2761E4977BF0030E7AD /* GameMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameMetadata.swift; path = Database/OpenVGDB/GameMetadata.swift; sourceTree = "<group>"; };
BF95E2781E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GamesDatabaseBrowserViewController.swift; path = Database/OpenVGDB/GamesDatabaseBrowserViewController.swift; sourceTree = "<group>"; };
BF99A5961DC2F9C400468E9E /* ControllerSkinTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllerSkinTableViewCell.swift; path = "Controller Skins/ControllerSkinTableViewCell.swift"; sourceTree = "<group>"; };
@ -195,12 +197,12 @@
BFAA1FEC1B8AA4FA00495943 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
BFBAB2E21EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DeltaCoreProtocol+Delta.swift"; sourceTree = "<group>"; };
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>"; };
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>"; };
BFE4269D1D9C68E600DC913F /* SaveStatesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SaveStatesStoryboardSegue.swift; path = Segues/SaveStatesStoryboardSegue.swift; sourceTree = "<group>"; };
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 = "<group>"; };
BFFA4C081E8A24D600D87934 /* GameMetadataTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GameMetadataTableViewCell.swift; path = Database/OpenVGDB/GameMetadataTableViewCell.swift; sourceTree = "<group>"; };
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 = "<group>";
};
BF930FFB1EB6D6EC00E8DBA0 /* Systems */ = {
isa = PBXGroup;
children = (
BF930FFC1EB6D6FF00E8DBA0 /* System.swift */,
);
name = Systems;
sourceTree = "<group>";
};
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 */,

View File

@ -13,6 +13,9 @@
<FileRef
location = "group:Cores/GBADeltaCore/GBADeltaCore.xcodeproj">
</FileRef>
<FileRef
location = "group:Cores/GBCDeltaCore/GBCDeltaCore.xcodeproj">
</FileRef>
<FileRef
location = "group:External/Roxas/Roxas.xcodeproj">
</FileRef>

View File

@ -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)
}

View File

@ -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))
}

View File

@ -22,6 +22,7 @@ extension DatabaseManager
{
case doesNotExist(URL)
case invalid(URL)
case unsupported(URL)
case unknown(URL, NSError)
case saveFailed(Set<URL>, 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

View File

@ -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
}
}

View File

@ -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()
}

View File

@ -7,15 +7,17 @@
//
import DeltaCore
import GBADeltaCore
extension DeltaCoreProtocol
{
var supportedRates: ClosedRange<Double> {
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
}
}
}

View File

@ -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<GameType>
{
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
}
}

View File

@ -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: "")
}
}
}

View File

@ -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)
}

View File

@ -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> = 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)
}

View File

@ -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)

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11760" systemVersion="16B2657" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ssH-mM-uG6">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="ssH-mM-uG6">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11755"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -21,8 +21,8 @@
<sections>
<tableViewSection headerTitle="Inputs" id="c6K-sJ-0vW">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="tls-Hv-Rx2" detailTextLabel="vJP-Ie-a9H" style="IBUITableViewCellStyleValue1" id="jvV-ZB-Rq1">
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="tls-Hv-Rx2" detailTextLabel="vJP-Ie-a9H" style="IBUITableViewCellStyleValue1" id="jvV-ZB-Rq1">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jvV-ZB-Rq1" id="AVi-6C-eIS">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
@ -45,8 +45,8 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="e3u-x9-IEC" detailTextLabel="2OP-A1-VYo" style="IBUITableViewCellStyleValue1" id="1Fv-H5-0oH">
<rect key="frame" x="0.0" y="100" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="e3u-x9-IEC" detailTextLabel="2OP-A1-VYo" style="IBUITableViewCellStyleValue1" id="1Fv-H5-0oH">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1Fv-H5-0oH" id="kFJ-zK-MLZ">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
@ -69,8 +69,8 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Cdn-11-xZe" detailTextLabel="wWc-NY-Bsd" style="IBUITableViewCellStyleValue1" id="EcC-Be-jV5">
<rect key="frame" x="0.0" y="144" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="Cdn-11-xZe" detailTextLabel="wWc-NY-Bsd" style="IBUITableViewCellStyleValue1" id="EcC-Be-jV5">
<rect key="frame" x="0.0" y="143.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="EcC-Be-jV5" id="9ZS-um-scR">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
@ -93,8 +93,8 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Hls-3b-EaS" detailTextLabel="hNf-uc-PLR" style="IBUITableViewCellStyleValue1" id="hO9-Ov-vsA">
<rect key="frame" x="0.0" y="188" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="DetailCell" textLabel="Hls-3b-EaS" detailTextLabel="hNf-uc-PLR" style="IBUITableViewCellStyleValue1" id="hO9-Ov-vsA">
<rect key="frame" x="0.0" y="187.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hO9-Ov-vsA" id="MRi-re-XI7">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
@ -121,14 +121,14 @@
</tableViewSection>
<tableViewSection headerTitle="Controller Skins" id="Nch-k1-6pR">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="mBC-YU-BVK" style="IBUITableViewCellStyleDefault" id="ICf-ug-NwS">
<rect key="frame" x="0.0" y="289" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="mBC-YU-BVK" style="IBUITableViewCellStyleDefault" id="ICf-ug-NwS">
<rect key="frame" x="0.0" y="287.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ICf-ug-NwS" id="7se-sE-x9e">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Super Nintendo" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mBC-YU-BVK">
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="System Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="mBC-YU-BVK">
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -138,14 +138,31 @@
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="MFD-lC-Vfk" style="IBUITableViewCellStyleDefault" id="4Sh-Mb-vqu">
<rect key="frame" x="0.0" y="333" width="375" height="44"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="Dxs-Me-IVU" style="IBUITableViewCellStyleDefault" id="Hqy-yc-Jef">
<rect key="frame" x="0.0" y="331.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="4Sh-Mb-vqu" id="cJG-Gr-n6q">
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Hqy-yc-Jef" id="wJL-kh-qW0">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Game Boy Advance" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MFD-lC-Vfk">
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="System Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Dxs-Me-IVU">
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Cell" textLabel="o9x-Kn-6bC" style="IBUITableViewCellStyleDefault" id="jFa-Qk-1cj">
<rect key="frame" x="0.0" y="375.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jFa-Qk-1cj" id="rFR-qL-fNQ">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="System Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="o9x-Kn-6bC">
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -160,10 +177,10 @@
<tableViewSection headerTitle="Controller Opacity" footerTitle="Determines how translucent the controller appears, if supported by the controller skin." id="SwK-m9-8gt">
<cells>
<tableViewCell contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="Xxk-vo-eu4">
<rect key="frame" x="0.0" y="441" width="375" height="44"/>
<rect key="frame" x="0.0" y="483" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" tableViewCell="Xxk-vo-eu4" id="vxt-Ex-b4b">
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="whi-If-wFf">
@ -276,7 +293,7 @@
<!--Game Boy Advance-->
<scene sceneID="pkL-Te-puh">
<objects>
<tableViewController id="56e-ul-z6v" customClass="GameTypeControllerSkinsViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<tableViewController id="56e-ul-z6v" customClass="SystemControllerSkinsViewController" customModule="Delta" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="fdQ-n7-kUL">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>

View File

@ -9,8 +9,6 @@
import Foundation
import DeltaCore
import SNESDeltaCore
import GBADeltaCore
import Roxas
@ -25,7 +23,7 @@ extension Settings
{
case name
case gameType
case system
case traits
}
@ -72,9 +70,9 @@ struct Settings
UserDefaults.standard.register(defaults: defaults)
}
static func preferredControllerSkin(for gameType: GameType, traits: DeltaCore.ControllerSkin.Traits) -> ControllerSkin?
static func preferredControllerSkin(for system: System, traits: DeltaCore.ControllerSkin.Traits) -> ControllerSkin?
{
guard let userDefaultsKey = self.preferredControllerSkinKey(for: gameType, traits: traits) else { return nil }
guard let userDefaultsKey = self.preferredControllerSkinKey(for: system, traits: traits) else { return nil }
let identifier = UserDefaults.standard.string(forKey: userDefaultsKey)
@ -86,7 +84,7 @@ struct Settings
if let identifier = identifier
{
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND %K == %@", #keyPath(ControllerSkin.gameType), gameType.rawValue, #keyPath(ControllerSkin.identifier), identifier)
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND %K == %@", #keyPath(ControllerSkin.gameType), system.gameType.rawValue, #keyPath(ControllerSkin.identifier), identifier)
if let controllerSkin = try DatabaseManager.shared.viewContext.fetch(fetchRequest).first
{
@ -96,11 +94,11 @@ struct Settings
// Controller skin doesn't exist, so fall back to standard controller skin
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND %K == YES", #keyPath(ControllerSkin.gameType), gameType.rawValue, #keyPath(ControllerSkin.isStandard))
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND %K == YES", #keyPath(ControllerSkin.gameType), system.gameType.rawValue, #keyPath(ControllerSkin.isStandard))
if let controllerSkin = try DatabaseManager.shared.viewContext.fetch(fetchRequest).first
{
Settings.setPreferredControllerSkin(controllerSkin, for: gameType, traits: traits)
Settings.setPreferredControllerSkin(controllerSkin, for: system, traits: traits)
return controllerSkin
}
}
@ -112,26 +110,26 @@ struct Settings
return nil
}
static func setPreferredControllerSkin(_ controllerSkin: ControllerSkin, for gameType: GameType, traits: DeltaCore.ControllerSkin.Traits)
static func setPreferredControllerSkin(_ controllerSkin: ControllerSkin, for system: System, traits: DeltaCore.ControllerSkin.Traits)
{
guard let userDefaultKey = self.preferredControllerSkinKey(for: gameType, traits: traits) else { return }
guard let userDefaultKey = self.preferredControllerSkinKey(for: system, traits: traits) else { return }
UserDefaults.standard.set(controllerSkin.identifier, forKey: userDefaultKey)
NotificationCenter.default.post(name: .settingsDidChange, object: controllerSkin, userInfo: [NotificationUserInfoKey.name: Name.preferredControllerSkin, NotificationUserInfoKey.gameType: gameType, NotificationUserInfoKey.traits: traits])
NotificationCenter.default.post(name: .settingsDidChange, object: controllerSkin, userInfo: [NotificationUserInfoKey.name: Name.preferredControllerSkin, NotificationUserInfoKey.system: system, NotificationUserInfoKey.traits: traits])
}
}
private extension Settings
{
static func preferredControllerSkinKey(for gameType: GameType, traits: DeltaCore.ControllerSkin.Traits) -> String?
static func preferredControllerSkinKey(for system: System, traits: DeltaCore.ControllerSkin.Traits) -> String?
{
let systemName: String
switch gameType
switch system
{
case GameType.snes: systemName = "snes"
case GameType.gba: systemName = "gba"
default: return nil
case .snes: systemName = "snes"
case .gba: systemName = "gba"
case .gbc: systemName = "gbc"
}
let orientation: String

View File

@ -7,22 +7,32 @@
//
import UIKit
import DeltaCore
extension SettingsViewController
import Roxas
fileprivate extension SettingsViewController
{
fileprivate enum Section: Int
enum Section: Int
{
case controllers
case controllerSkins
case controllerOpacity
}
fileprivate enum Segue: String
enum Segue: String
{
case controllers = "controllersSegue"
case controllerSkins = "controllerSkinsSegue"
}
enum ControllerSkinsRow: Int
{
case snes
case gba
case gbc
}
}
class SettingsViewController: UITableViewController
@ -79,13 +89,14 @@ class SettingsViewController: UITableViewController
controllersSettingsViewController.playerIndex = indexPath.row
case Segue.controllerSkins:
let gameTypeControllerSkinsViewController = segue.destination as! GameTypeControllerSkinsViewController
let systemControllerSkinsViewController = segue.destination as! SystemControllerSkinsViewController
switch indexPath.row
let row = ControllerSkinsRow(rawValue: indexPath.row)!
switch row
{
case 0: gameTypeControllerSkinsViewController.gameType = .snes
case 1: gameTypeControllerSkinsViewController.gameType = .gba
default: break
case .snes: systemControllerSkinsViewController.system = .snes
case .gba: systemControllerSkinsViewController.system = .gba
case .gbc: systemControllerSkinsViewController.system = .gbc
}
}
}
@ -162,6 +173,7 @@ extension SettingsViewController
switch section
{
case .controllers: return 1 // Temporarily hide other controller indexes until controller logic is finalized
case .controllerSkins: return System.supportedSystems.count
default: return super.tableView(tableView, numberOfRowsInSection: sectionIndex)
}
}
@ -169,9 +181,11 @@ extension SettingsViewController
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = super.tableView(tableView, cellForRowAt: indexPath)
if indexPath.section == Section.controllers.rawValue
let section = Section(rawValue: indexPath.section)!
switch section
{
case .controllers:
if indexPath.row == Settings.localControllerPlayerIndex
{
cell.detailTextLabel?.text = UIDevice.current.name
@ -185,8 +199,11 @@ extension SettingsViewController
{
cell.detailTextLabel?.text = nil
}
case .controllerSkins: cell.textLabel?.text = System.supportedSystems[indexPath.row].localizedName
default: break
}
return cell
}

View File

@ -60,6 +60,20 @@
<string>com.pkware.zip-archive</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>GBC Game</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.rileytestut.delta.game.gbc</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
@ -82,17 +96,17 @@
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>gamefaqs.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
<dict>
<key>gamefaqs.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
<key>UIFileSharingEnabled</key>
<true/>
@ -179,6 +193,24 @@
<string>deltaskin</string>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>com.rileytestut.delta.game</string>
</array>
<key>UTTypeDescription</key>
<string>GBC Game</string>
<key>UTTypeIdentifier</key>
<string>com.rileytestut.delta.game.gbc</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>gbc</string>
<string>gb</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

103
Delta/Systems/System.swift Normal file
View File

@ -0,0 +1,103 @@
//
// System.swift
// Delta
//
// Created by Riley Testut on 4/30/17.
// Copyright © 2017 Riley Testut. All rights reserved.
//
import DeltaCore
import SNESDeltaCore
import GBADeltaCore
import GBCDeltaCore
extension GameType
{
init?(fileExtension: String)
{
switch fileExtension
{
case "smc", "sfc", "fig": self = .snes
case "gba": self = .gba
case "gbc", "gb": self = .gbc
default: return nil
}
}
}
enum System
{
case snes
case gba
case gbc
static var supportedSystems: [System] {
return [.snes, .gba, .gbc]
}
}
extension System
{
var localizedName: String {
switch self
{
case .snes: return NSLocalizedString("Super Nintendo Entertainment System", comment: "")
case .gba: return NSLocalizedString("Game Boy Advance", comment: "")
case .gbc: return NSLocalizedString("Game Boy Color", comment: "")
}
}
var localizedShortName: String {
switch self
{
case .snes: return NSLocalizedString("SNES", comment: "")
case .gba: return NSLocalizedString("GBA", comment: "")
case .gbc: return NSLocalizedString("GBC", comment: "")
}
}
var year: Int {
switch self
{
case .snes: return 1990
case .gba: return 2001
case .gbc: return 1998
}
}
}
extension System
{
var deltaCore: DeltaCoreProtocol {
switch self
{
case .snes: return SNES.core
case .gba: return GBA.core
case .gbc: return GBC.core
}
}
}
extension System
{
var gameType: GameType {
switch self
{
case .snes: return .snes
case .gba: return .gba
case .gbc: return .gbc
}
}
init?(gameType: GameType)
{
switch gameType
{
case GameType.snes: self = .snes
case GameType.gba: self = .gba
case GameType.gbc: self = .gbc
default: return nil
}
}
}