diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
index 531ce3111..066587266 100644
--- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
+++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
@@ -25,6 +25,7 @@
/* Begin PBXBuildFile section */
4E0DED342D05695D00FEF007 /* SwiftUIJoystick in Frameworks */ = {isa = PBXBuildFile; productRef = 4E0DED332D05695D00FEF007 /* SwiftUIJoystick */; };
+ 4E8A80772D5FDD2D0041B48F /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E80AA622CD7122800029585 /* GameController.framework */; };
4EA5AE822D16807500AD0B9F /* SwiftSVG in Frameworks */ = {isa = PBXBuildFile; productRef = 4EA5AE812D16807500AD0B9F /* SwiftSVG */; };
CA8F9C322D3F5AB200D7E586 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E80AA622CD7122800029585 /* GameController.framework */; };
/* End PBXBuildFile section */
@@ -197,6 +198,7 @@
4E0DED342D05695D00FEF007 /* SwiftUIJoystick in Frameworks */,
CA8F9C322D3F5AB200D7E586 /* GameController.framework in Frameworks */,
4EA5AE822D16807500AD0B9F /* SwiftSVG in Frameworks */,
+ 4E8A80772D5FDD2D0041B48F /* GameController.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -656,10 +658,15 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
GCC_OPTIMIZATION_LEVEL = fast;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = MeloNX/Info.plist;
+ INFOPLIST_KEY_GCSupportsControllerUserInteraction = YES;
INFOPLIST_KEY_GCSupportsGameMode = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
@@ -670,7 +677,7 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -710,6 +717,14 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
MARKETING_VERSION = 1.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
@@ -755,10 +770,15 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
GCC_OPTIMIZATION_LEVEL = fast;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = MeloNX/Info.plist;
+ INFOPLIST_KEY_GCSupportsControllerUserInteraction = YES;
INFOPLIST_KEY_GCSupportsGameMode = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
@@ -769,7 +789,7 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 15.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -809,6 +829,14 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+ "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
);
MARKETING_VERSION = 1.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
diff --git a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate
index 6b56913a2..ae985c98a 100644
Binary files a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate and b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist
index fbd8d81c1..8ff6cf524 100644
--- a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -12,12 +12,12 @@
Ryujinx.xcscheme_^#shared#^_
orderHint
- 3
+ 2
com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_
orderHint
- 4
+ 1
SuppressBuildableAutocreation
diff --git a/src/MeloNX/MeloNX/App/Core/Entitlements/EntitlementChecker.swift b/src/MeloNX/MeloNX/App/Core/Entitlements/EntitlementChecker.swift
new file mode 100644
index 000000000..4caed0c8d
--- /dev/null
+++ b/src/MeloNX/MeloNX/App/Core/Entitlements/EntitlementChecker.swift
@@ -0,0 +1,58 @@
+//
+// EntitlementChecker.swift
+// MeloNX
+//
+// Created by Stossy11 on 15/02/2025.
+//
+
+import Foundation
+import Security
+
+typealias SecTaskRef = OpaquePointer
+
+@_silgen_name("SecTaskCopyValueForEntitlement")
+func SecTaskCopyValueForEntitlement(
+ _ task: SecTaskRef,
+ _ entitlement: NSString,
+ _ error: NSErrorPointer
+) -> CFTypeRef?
+
+@_silgen_name("SecTaskCreateFromSelf")
+func SecTaskCreateFromSelf(
+ _ allocator: CFAllocator?
+) -> SecTaskRef?
+
+@_silgen_name("SecTaskCopyValuesForEntitlements")
+func SecTaskCopyValuesForEntitlements(
+ _ task: SecTaskRef,
+ _ entitlements: CFArray,
+ _ error: UnsafeMutablePointer?>?
+) -> CFDictionary?
+
+func checkAppEntitlements(_ ents: [String]) -> [String: Any]? {
+ guard let task = SecTaskCreateFromSelf(nil) else {
+ print("Failed to create SecTask")
+ return nil
+ }
+
+ guard let entitlements = SecTaskCopyValuesForEntitlements(task, ents as CFArray, nil) else {
+ print("Failed to get entitlements")
+ return nil
+ }
+
+ return entitlements as? [String: Any]
+}
+
+func checkAppEntitlement(_ ent: String) -> Bool? {
+ guard let task = SecTaskCreateFromSelf(nil) else {
+ print("Failed to create SecTask")
+ return nil
+ }
+
+ guard let entitlements = SecTaskCopyValueForEntitlement(task, ent as NSString, nil) else {
+ print("Failed to get entitlements")
+ return nil
+ }
+
+ return entitlements.boolValue != nil && entitlements.boolValue
+}
diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/Display/AspectRatio.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/Display/AspectRatio.swift
new file mode 100644
index 000000000..30db0a1fd
--- /dev/null
+++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/Display/AspectRatio.swift
@@ -0,0 +1,28 @@
+//
+// AspectRatio.swift
+// MeloNX
+//
+// Created by Stossy11 on 16/02/2025.
+//
+
+import Foundation
+
+public enum AspectRatio: String, Codable, CaseIterable {
+ case fixed4x3 = "Fixed4x3"
+ case fixed16x9 = "Fixed16x9"
+ case fixed16x10 = "Fixed16x10"
+ case fixed21x9 = "Fixed21x9"
+ case fixed32x9 = "Fixed32x9"
+ case stretched = "Stretched"
+
+ var displayName: String {
+ switch self {
+ case .fixed4x3: return "4:3"
+ case .fixed16x9: return "16:9 (Default)"
+ case .fixed16x10: return "16:10"
+ case .fixed21x9: return "21:9"
+ case .fixed32x9: return "32:9"
+ case .stretched: return "Stretched (Full Screen)"
+ }
+ }
+}
diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Language.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Language.swift
new file mode 100644
index 000000000..ff3732f25
--- /dev/null
+++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Language.swift
@@ -0,0 +1,52 @@
+//
+// Language.swift
+// MeloNX
+//
+// Created by Stossy11 on 16/02/2025.
+//
+
+import Foundation
+
+public enum SystemLanguage: String, Codable, CaseIterable {
+ case japanese = "Japanese"
+ case americanEnglish = "AmericanEnglish"
+ case french = "French"
+ case german = "German"
+ case italian = "Italian"
+ case spanish = "Spanish"
+ case chinese = "Chinese"
+ case korean = "Korean"
+ case dutch = "Dutch"
+ case portuguese = "Portuguese"
+ case russian = "Russian"
+ case taiwanese = "Taiwanese"
+ case britishEnglish = "BritishEnglish"
+ case canadianFrench = "CanadianFrench"
+ case latinAmericanSpanish = "LatinAmericanSpanish"
+ case simplifiedChinese = "SimplifiedChinese"
+ case traditionalChinese = "TraditionalChinese"
+ case brazilianPortuguese = "BrazilianPortuguese"
+
+ var displayName: String {
+ switch self {
+ case .japanese: return "Japanese"
+ case .americanEnglish: return "American English"
+ case .french: return "French"
+ case .german: return "German"
+ case .italian: return "Italian"
+ case .spanish: return "Spanish"
+ case .chinese: return "Chinese"
+ case .korean: return "Korean"
+ case .dutch: return "Dutch"
+ case .portuguese: return "Portuguese"
+ case .russian: return "Russian"
+ case .taiwanese: return "Taiwanese"
+ case .britishEnglish: return "British English"
+ case .canadianFrench: return "Canadian French"
+ case .latinAmericanSpanish: return "Latin American Spanish"
+ case .simplifiedChinese: return "Simplified Chinese"
+ case .traditionalChinese: return "Traditional Chinese"
+ case .brazilianPortuguese: return "Brazilian Portuguese"
+ }
+ }
+}
diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Region.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Region.swift
new file mode 100644
index 000000000..249f03912
--- /dev/null
+++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/Enums/LanguageAndRegion/Region.swift
@@ -0,0 +1,31 @@
+//
+// Region.swift
+// MeloNX
+//
+// Created by Stossy11 on 16/02/2025.
+//
+
+import Foundation
+
+public enum SystemRegionCode: String, Codable, CaseIterable {
+ case japan = "Japan"
+ case usa = "USA"
+ case europe = "Europe"
+ case australia = "Australia"
+ case china = "China"
+ case korea = "Korea"
+ case taiwan = "Taiwan"
+
+ var displayName: String {
+ switch self {
+ case .japan: return "Japan"
+ case .usa: return "United States"
+ case .europe: return "Europe"
+ case .australia: return "Australia"
+ case .china: return "China"
+ case .korea: return "Korea"
+ case .taiwan: return "Taiwan"
+ }
+ }
+}
+
diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift
index 76b038b5a..ab226fce7 100644
--- a/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift
+++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift
@@ -28,26 +28,6 @@ struct iOSNav: View {
}
}
-public enum AspectRatio: String, Codable, CaseIterable {
- case fixed4x3 = "Fixed4x3"
- case fixed16x9 = "Fixed16x9"
- case fixed16x10 = "Fixed16x10"
- case fixed21x9 = "Fixed21x9"
- case fixed32x9 = "Fixed32x9"
- case stretched = "Stretched"
-
- var displayName: String {
- switch self {
- case .fixed4x3: return "4:3"
- case .fixed16x9: return "16:9 (Default)"
- case .fixed16x10: return "16:10"
- case .fixed21x9: return "21:9"
- case .fixed32x9: return "32:9"
- case .stretched: return "Stretched (Full Screen)"
- }
- }
-}
-
class Ryujinx {
private var isRunning = false
@@ -60,6 +40,8 @@ class Ryujinx {
@Published var emulationUIView = UIView()
@Published var games: [Game] = []
+ @Published var defMLContentSize: CGFloat?
+
var shouldMetal: Bool {
metalLayer == nil
}
@@ -93,6 +75,8 @@ class Ryujinx {
var dfsIntegrityChecks: Bool
var disablePTC: Bool
var disablevsync: Bool
+ var language: SystemLanguage
+ var regioncode: SystemRegionCode
init(gamepath: String,
@@ -116,7 +100,9 @@ class Ryujinx {
expandRam: Bool = false,
dfsIntegrityChecks: Bool = false,
disablePTC: Bool = false,
- disablevsync: Bool = false
+ disablevsync: Bool = false,
+ language: SystemLanguage = .americanEnglish,
+ regioncode: SystemRegionCode = .usa
) {
self.gamepath = gamepath
self.inputids = inputids
@@ -140,6 +126,8 @@ class Ryujinx {
self.dfsIntegrityChecks = dfsIntegrityChecks
self.disablePTC = disablePTC
self.disablevsync = disablevsync
+ self.language = language
+ self.regioncode = regioncode
}
}
@@ -262,6 +250,10 @@ class Ryujinx {
// We don't need this. Ryujinx should handle it fine :3
// this also causes crashes in some games :3
+ args.append(contentsOf: ["--system-language", config.language.rawValue])
+
+ args.append(contentsOf: ["--system-region", config.regioncode.rawValue])
+
args.append(contentsOf: ["--aspect-ratio", config.aspectRatio.rawValue])
if config.nintendoinput {
@@ -276,7 +268,7 @@ class Ryujinx {
args.append("--disable-vsync")
}
-
+
if config.hypervisor {
args.append("--use-hypervisor")
}
@@ -295,7 +287,8 @@ class Ryujinx {
}
if config.ignoreMissingServices {
- args.append(contentsOf: ["--ignore-missing-services", String(config.maxAnisotropy)])
+ // args.append(contentsOf: ["--ignore-missing-services"])
+ args.append("--ignore-missing-services")
}
if config.maxAnisotropy != 0 {
@@ -318,15 +311,15 @@ class Ryujinx {
}
if config.debuglogs {
- args.append(contentsOf: ["--enable-debug-logs"])
+ args.append("--enable-debug-logs")
}
if config.tracelogs {
- args.append(contentsOf: ["--enable-trace-logs"])
+ args.append("--enable-trace-logs")
}
// List the input ids
if config.listinputids {
- args.append(contentsOf: ["--list-inputs-ids"])
+ args.append("--list-inputs-ids")
}
// Append the input ids (limit to 4 just in case)
diff --git a/src/MeloNX/MeloNX/App/Views/ContentView.swift b/src/MeloNX/MeloNX/App/Views/ContentView.swift
index 6ee4d3f7d..cc4c695ff 100644
--- a/src/MeloNX/MeloNX/App/Views/ContentView.swift
+++ b/src/MeloNX/MeloNX/App/Views/ContentView.swift
@@ -42,7 +42,7 @@ struct ContentView: View {
@AppStorage("quit") var quit: Bool = false
@State var quits: Bool = false
@AppStorage("MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS") var mVKPreFillBuffer: Bool = true
- @AppStorage("MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS") var syncqsubmits: Bool = false
+ @AppStorage("MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS") var syncqsubmits: Bool = true
// Loading Animation
@State private var clumpOffset: CGFloat = -100
diff --git a/src/MeloNX/MeloNX/App/Views/ControllerView/ControllerView.swift b/src/MeloNX/MeloNX/App/Views/ControllerView/ControllerView.swift
index d778d8c2c..a11f2f484 100644
--- a/src/MeloNX/MeloNX/App/Views/ControllerView/ControllerView.swift
+++ b/src/MeloNX/MeloNX/App/Views/ControllerView/ControllerView.swift
@@ -129,6 +129,8 @@ struct ControllerView: View {
struct ShoulderButtonsViewLeft: View {
@State var width: CGFloat = 160
@State var height: CGFloat = 20
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
+
var body: some View {
HStack {
ButtonView(button: .leftTrigger)
@@ -142,6 +144,9 @@ struct ShoulderButtonsViewLeft: View {
width *= 1.2
height *= 1.2
}
+
+ width *= CGFloat(controllerScale)
+ height *= CGFloat(controllerScale)
}
}
}
@@ -149,6 +154,8 @@ struct ShoulderButtonsViewLeft: View {
struct ShoulderButtonsViewRight: View {
@State var width: CGFloat = 160
@State var height: CGFloat = 20
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
+
var body: some View {
HStack {
ButtonView(button: .rightShoulder)
@@ -162,12 +169,16 @@ struct ShoulderButtonsViewRight: View {
width *= 1.2
height *= 1.2
}
+
+ width *= CGFloat(controllerScale)
+ height *= CGFloat(controllerScale)
}
}
}
struct DPadView: View {
@State var size: CGFloat = 145
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
var body: some View {
VStack {
ButtonView(button: .dPadUp)
@@ -184,12 +195,16 @@ struct DPadView: View {
if UIDevice.current.systemName.contains("iPadOS") {
size *= 1.2
}
+
+ size *= CGFloat(controllerScale)
}
}
}
struct ABXYView: View {
@State var size: CGFloat = 145
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
+
var body: some View {
VStack {
ButtonView(button: .X)
@@ -206,6 +221,8 @@ struct ABXYView: View {
if UIDevice.current.systemName.contains("iPadOS") {
size *= 1.2
}
+
+ size *= CGFloat(controllerScale)
}
}
}
@@ -218,6 +235,7 @@ struct ButtonView: View {
@AppStorage("onscreenhandheld") var onscreenjoy: Bool = false
@Environment(\.colorScheme) var colorScheme
@Environment(\.presentationMode) var presentationMode
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
@@ -256,6 +274,9 @@ struct ButtonView: View {
width *= 1.2
height *= 1.2
}
+
+ width *= CGFloat(controllerScale)
+ height *= CGFloat(controllerScale)
}
}
diff --git a/src/MeloNX/MeloNX/App/Views/ControllerView/Joystick/JoystickView.swift b/src/MeloNX/MeloNX/App/Views/ControllerView/Joystick/JoystickView.swift
index dc1db3d8c..7747719c2 100644
--- a/src/MeloNX/MeloNX/App/Views/ControllerView/Joystick/JoystickView.swift
+++ b/src/MeloNX/MeloNX/App/Views/ControllerView/Joystick/JoystickView.swift
@@ -13,11 +13,14 @@ public struct Joystick: View {
@State var iscool: Bool? = nil
@ObservedObject public var joystickMonitor = JoystickMonitor()
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
var dragDiameter: CGFloat {
var selfs = CGFloat(160)
+ selfs *= controllerScale
if UIDevice.current.systemName.contains("iPadOS") {
return selfs * 1.2
}
+
return selfs
}
private let shape: JoystickShape = .circle
diff --git a/src/MeloNX/MeloNX/App/Views/Emulation/EmulationView/EmulationView.swift b/src/MeloNX/MeloNX/App/Views/Emulation/EmulationView/EmulationView.swift
index c8a4c1590..ac577a973 100644
--- a/src/MeloNX/MeloNX/App/Views/Emulation/EmulationView/EmulationView.swift
+++ b/src/MeloNX/MeloNX/App/Views/Emulation/EmulationView/EmulationView.swift
@@ -11,16 +11,18 @@ import SwiftUI
struct EmulationView: View {
@AppStorage("isVirtualController") var isVCA: Bool = true
@AppStorage("showScreenShotButton") var ssb: Bool = false
+ @State var isPresentedThree: Bool = false
@State var isAirplaying = Air.shared.connected
+ @Environment(\.scenePhase) var scenePhase
var body: some View {
ZStack {
if isAirplaying {
Text("")
.onAppear {
- Air.play(AnyView(MetalView(airplay: true).ignoresSafeArea()))
+ Air.play(AnyView(MetalView().ignoresSafeArea()))
}
} else {
- MetalView(airplay: false) // The Emulation View
+ MetalView() // The Emulation View
.ignoresSafeArea()
.edgesIgnoringSafeArea(.all)
}
@@ -31,6 +33,7 @@ struct EmulationView: View {
ControllerView() // Virtual Controller
}
+
if ssb {
Group {
VStack {
diff --git a/src/MeloNX/MeloNX/App/Views/Emulation/MetalView/MetalView.swift b/src/MeloNX/MeloNX/App/Views/Emulation/MetalView/MetalView.swift
index 11e4f4963..59fcb1a70 100644
--- a/src/MeloNX/MeloNX/App/Views/Emulation/MetalView/MetalView.swift
+++ b/src/MeloNX/MeloNX/App/Views/Emulation/MetalView/MetalView.swift
@@ -10,7 +10,7 @@ import MetalKit
struct MetalView: UIViewRepresentable {
- var airplay: Bool // just in case :3
+ var airplay: Bool = Air.shared.connected // just in case :3
func makeUIView(context: Context) -> UIView {
let metalLayer = Ryujinx.shared.metalLayer!
diff --git a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift
index 24548b067..980b94dda 100644
--- a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift
+++ b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift
@@ -40,9 +40,11 @@ struct SettingsView: View {
@AppStorage("oldWindowCode") var windowCode: Bool = false
+ @AppStorage("On-ScreenControllerScale") var controllerScale: Double = 1.0
@State private var showResolutionInfo = false
@State private var showAnisotropicInfo = false
+ @State private var showControllerInfo = false
@State private var searchText = ""
var filteredMemoryModes: [(String, String)] {
@@ -270,6 +272,35 @@ struct SettingsView: View {
Text("Select input devices and on-screen controls to play with. ")
}
+ // Language and Region Settings
+ Section {
+ Picker(selection: $config.language) {
+ ForEach(SystemLanguage.allCases, id: \.self) { ratio in
+ Text(ratio.displayName).tag(ratio)
+ }
+ } label: {
+ labelWithIcon("Language", iconName: "character.bubble")
+ }
+
+ Picker(selection: $config.regioncode) {
+ ForEach(SystemRegionCode.allCases, id: \.self) { ratio in
+ Text(ratio.displayName).tag(ratio)
+ }
+ } label: {
+ labelWithIcon("Region", iconName: "globe")
+ }
+
+
+ // globe
+ } header: {
+ Text("Language and Region Settings")
+ .font(.title3.weight(.semibold))
+ .textCase(nil)
+ .headerProminence(.increased)
+ } footer: {
+ Text("Configure the System Language and the Region.")
+ }
+
// Input Settings
Section {
@@ -283,6 +314,46 @@ struct SettingsView: View {
}
.tint(.blue)
.disabled(true)
+
+ VStack(alignment: .leading, spacing: 10) {
+ HStack {
+ labelWithIcon("On-Screen Controller Scale", iconName: "magnifyingglass")
+ .font(.headline)
+ Spacer()
+ Button {
+ showControllerInfo.toggle()
+ } label: {
+ Image(systemName: "info.circle")
+ .symbolRenderingMode(.hierarchical)
+ .foregroundStyle(.secondary)
+ }
+ .buttonStyle(.plain)
+ .help("Learn more about On-Screen Controller Scale")
+ .alert(isPresented: $showControllerInfo) {
+ Alert(
+ title: Text("On-Screen Controller Scale"),
+ message: Text("Adjust the On-Screen Controller size."),
+ dismissButton: .default(Text("OK"))
+ )
+ }
+ }
+
+ Slider(value: $controllerScale, in: 0.1...3.0, step: 0.05) {
+ Text("Resolution Scale")
+ } minimumValueLabel: {
+ Text("0.1x")
+ .font(.footnote)
+ .foregroundColor(.secondary)
+ } maximumValueLabel: {
+ Text("3.0x")
+ .font(.footnote)
+ .foregroundColor(.secondary)
+ }
+ Text("\(controllerScale, specifier: "%.2f")x")
+ .font(.subheadline)
+ .foregroundColor(.secondary)
+ }
+ .padding(.vertical, 8)
} header: {
Text("Input Settings")
.font(.title3.weight(.semibold))
diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib
index b64e5535f..c1b12b543 100755
Binary files a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib and b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib differ
diff --git a/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK b/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK
index b64e5535f..495d9fb19 100755
Binary files a/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK and b/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK differ
diff --git a/src/MeloNX/MeloNX/Info.plist b/src/MeloNX/MeloNX/Info.plist
index 0cf82243f..bb9bd4980 100644
--- a/src/MeloNX/MeloNX/Info.plist
+++ b/src/MeloNX/MeloNX/Info.plist
@@ -15,6 +15,17 @@
+ GCSupportedGameControllers
+
+
+ ProfileName
+ ExtendedGamepad
+
+
+ ProfileName
+ MicroGamepad
+
+
LSApplicationQueriesSchemes
melonx
@@ -25,6 +36,11 @@
LaunchGameIntent
+ UIBackgroundModes
+
+ audio
+ processing
+
UIFileSharingEnabled
UTExportedTypeDeclarations
diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs
index 2809334c2..54c1aee82 100644
--- a/src/Ryujinx.Headless.SDL2/Program.cs
+++ b/src/Ryujinx.Headless.SDL2/Program.cs
@@ -319,7 +319,6 @@ namespace Ryujinx.Headless.SDL2
if (_window != null)
{
-
_window.Exit();
_emulationContext.Dispose();
_emulationContext = null;
@@ -332,6 +331,7 @@ namespace Ryujinx.Headless.SDL2
if (_virtualFileSystem == null) {
_virtualFileSystem = VirtualFileSystem.CreateInstance();
}
+
var extension = Marshal.PtrToStringAnsi(extensionPtr);
var stream = OpenFile(descriptor);
diff --git a/src/Ryujinx.Memory/PageTable.cs b/src/Ryujinx.Memory/PageTable.cs
index ff22d028e..8b77b6fb8 100644
--- a/src/Ryujinx.Memory/PageTable.cs
+++ b/src/Ryujinx.Memory/PageTable.cs
@@ -4,7 +4,7 @@ namespace Ryujinx.Memory
{
public const int PageBits = 12;
public const int PageSize = 1 << PageBits;
- public const int PageMask = PageSize - 1;
+ public const int PageMask = PageSize - 2;
private const int PtLevelBits = 9; // 9 * 4 + 12 = 48 (max address space size)
private const int PtLevelSize = 1 << PtLevelBits;