diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index 9edf52b..286b92e 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -186,12 +186,14 @@ D57D795629F300E100BB2CF8 /* CustomTintColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A817AF29DF4E6E00904AFE /* CustomTintColor.swift */; }; D57D795F29F315F700BB2CF8 /* FeatureDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54A4BB229E4D27E004C7D57 /* FeatureDetailView.swift */; }; D57D796029F315F700BB2CF8 /* ExperimentalFeaturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C00229DDED6D00A8D610 /* ExperimentalFeaturesView.swift */; }; + D57D796129F31E7500BB2CF8 /* VariableFastForward.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */; }; D5864970297734280081477E /* CheatMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = D586496F297734280081477E /* CheatMetadata.swift */; }; D586497229774ABD0081477E /* CheatBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D586497129774ABD0081477E /* CheatBase.swift */; }; D5864978297756CE0081477E /* CheatBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5864977297756CE0081477E /* CheatBaseView.swift */; }; D5A817B329DF6C6C00904AFE /* ExperimentalFeatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A817B229DF6C6C00904AFE /* ExperimentalFeatures.swift */; }; D5A98CE2284EF14B00E023E5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A98CE1284EF14B00E023E5 /* SceneDelegate.swift */; }; D5A9C00329DDED6D00A8D610 /* ExperimentalFeaturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C00229DDED6D00A8D610 /* ExperimentalFeaturesView.swift */; }; + D5A9C01D29DE058C00A8D610 /* VariableFastForward.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */; }; D5AAF27729884F8600F21ACF /* CheatDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AAF27629884F8600F21ACF /* CheatDevice.swift */; }; D5D797E6298D946200738869 /* Contributor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D797E5298D946200738869 /* Contributor.swift */; }; D5D797E9298DCC7300738869 /* cheatbase.zip in Resources */ = {isa = PBXBuildFile; fileRef = D5D797E7298DC9E200738869 /* cheatbase.zip */; }; @@ -447,6 +449,7 @@ D5A9BFFD29DDECF100A8D610 /* Feature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feature.swift; sourceTree = ""; }; D5A9C00229DDED6D00A8D610 /* ExperimentalFeaturesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExperimentalFeaturesView.swift; sourceTree = ""; }; D5A9C01929DDFBDD00A8D610 /* SettingsName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsName.swift; sourceTree = ""; }; + D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VariableFastForward.swift; sourceTree = ""; }; D5AAF27629884F8600F21ACF /* CheatDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheatDevice.swift; sourceTree = ""; }; D5D797E5298D946200738869 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = ""; }; D5D797E7298DC9E200738869 /* cheatbase.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = cheatbase.zip; sourceTree = ""; }; @@ -1044,6 +1047,7 @@ isa = PBXGroup; children = ( D5A817B229DF6C6C00904AFE /* ExperimentalFeatures.swift */, + D58F39CB29E0A9C8008B4100 /* Features */, ); path = "Experimental Features"; sourceTree = ""; @@ -1060,6 +1064,14 @@ path = Cheats; sourceTree = ""; }; + D58F39CB29E0A9C8008B4100 /* Features */ = { + isa = PBXGroup; + children = ( + D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */, + ); + path = Features; + sourceTree = ""; + }; D5A9BFFF29DDECF500A8D610 /* Experimental Features */ = { isa = PBXGroup; children = ( @@ -1485,6 +1497,7 @@ BF59428E1E09BCFB0051894B /* ImportController.swift in Sources */, BF13A7581D5D2FD9000BB055 /* EmulatorCore+Cheats.swift in Sources */, BF48F74E219A16DA00BC2FC1 /* SyncingServicesViewController.swift in Sources */, + D5A9C01D29DE058C00A8D610 /* VariableFastForward.swift in Sources */, BFE593CA21F3F8B7003412A6 /* GameSave.swift in Sources */, BF63A1B521A4B76E00EE8F61 /* RecordVersionsViewController.swift in Sources */, BF6424831F5B8F3F00D6AB44 /* ListMenuViewController.swift in Sources */, @@ -1599,6 +1612,7 @@ D57D795F29F315F700BB2CF8 /* FeatureDetailView.swift in Sources */, D51CB7A629EDC15900B59678 /* ExperimentalFeatures.swift in Sources */, D57D796029F315F700BB2CF8 /* ExperimentalFeaturesView.swift in Sources */, + D57D796129F31E7500BB2CF8 /* VariableFastForward.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Delta/Experimental Features/ExperimentalFeatures.swift b/Delta/Experimental Features/ExperimentalFeatures.swift index c2d67c3..3a6125a 100644 --- a/Delta/Experimental Features/ExperimentalFeatures.swift +++ b/Delta/Experimental Features/ExperimentalFeatures.swift @@ -12,6 +12,11 @@ struct ExperimentalFeatures: FeatureContainer { static let shared = ExperimentalFeatures() + @Feature(name: "Variable Fast Forward", + description: "Change the preferred Fast Foward speed per-system. You can also change it by long-pressing the Fast Forward button from the Pause Menu.", + options: VariableFastForwardOptions()) + var variableFastForward + private init() { self.prepareFeatures() diff --git a/Delta/Experimental Features/Features/VariableFastForward.swift b/Delta/Experimental Features/Features/VariableFastForward.swift new file mode 100644 index 0000000..c33fb59 --- /dev/null +++ b/Delta/Experimental Features/Features/VariableFastForward.swift @@ -0,0 +1,73 @@ +// +// VariableFastForward.swift +// Delta +// +// Created by Riley Testut on 4/5/23. +// Copyright © 2023 Riley Testut. All rights reserved. +// + +import SwiftUI + +import DeltaFeatures + +enum FastForwardSpeed: Double, CaseIterable, CustomStringConvertible +{ + case x2 = 2 + case x3 = 3 + case x4 = 4 + case x8 = 8 + + var description: String { + if #available(iOS 15, *) + { + let formattedText = self.rawValue.formatted(.number.decimalSeparator(strategy: .automatic)) + return "\(formattedText)x" + } + else + { + return "\(self.rawValue)x" + } + } +} + +extension FastForwardSpeed: LocalizedOptionValue +{ + var localizedDescription: Text { + Text(self.description) + } + + static var localizedNilDescription: Text { + Text("Maximum") + } +} + +struct VariableFastForwardOptions +{ + // Alternatively, this feature could be implemented with single hidden dictionary @Option mapping preferred speeds to systems, + // because we support changing these values by long-pressing the Fast Forward button in the pause menu. + // However, we want to also show these options in Delta's settings, which requires us to explicitly define them one-by-one. + // + // @Option // No name = hidden + // var preferredSpeedsBySystem: [String: Double] = [:] + + @Option(name: "Nintendo", description: "Preferred NES fast forward speed.", values: FastForwardSpeed.allCases) + var nes: FastForwardSpeed? + + @Option(name: "Super Nintendo", description: "Preferred SNES fast forward speed.", values: FastForwardSpeed.allCases) + var snes: FastForwardSpeed? + + @Option(name: "Sega Genesis", description: "Preferred Genesis fast forward speed.", values: FastForwardSpeed.allCases) + var genesis: FastForwardSpeed? + + @Option(name: "Nintendo 64", description: "Preferred N64 fast forward speed.", values: FastForwardSpeed.allCases) + var n64: FastForwardSpeed? + + @Option(name: "Game Boy Color", description: "Preferred GBC fast forward speed.", values: FastForwardSpeed.allCases) + var gbc: FastForwardSpeed? + + @Option(name: "Game Boy Advance", description: "Preferred GBA fast forward speed.", values: FastForwardSpeed.allCases) + var gba: FastForwardSpeed? + + @Option(name: "Nintendo DS", description: "Preferred DS fast forward speed.", values: FastForwardSpeed.allCases) + var ds: FastForwardSpeed? +} diff --git a/DeltaPreviews/Experimental Features/ExperimentalFeatures.swift b/DeltaPreviews/Experimental Features/ExperimentalFeatures.swift index 26f6e63..f14f5d8 100644 --- a/DeltaPreviews/Experimental Features/ExperimentalFeatures.swift +++ b/DeltaPreviews/Experimental Features/ExperimentalFeatures.swift @@ -22,6 +22,11 @@ struct ExperimentalFeatures: FeatureContainer options: CustomTintColorOptions()) var customTintColor + @Feature(name: "Variable Fast Forward", + description: "Change the preferred Fast Foward speed per-system. You can also change it by long-pressing the Fast Forward button from the Pause Menu.", + options: VariableFastForwardOptions()) + var variableFastForward + private init() { self.prepareFeatures()