diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj index 6fe365843..810fdc7c8 100644 --- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj +++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj @@ -83,7 +83,7 @@ 4E80A99D2CD6F54700029585 /* MeloNXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeloNXTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4E80A9A72CD6F54700029585 /* MeloNXUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeloNXUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4E80AA622CD7122800029585 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; - 5650564A2D2A758600C8BB1E /* dotnet.xcconfig.example */ = {isa = PBXFileReference; lastKnownFileType = text; path = dotnet.xcconfig.example; sourceTree = ""; }; + 5650564A2D2A758600C8BB1E /* dotnet.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = dotnet.xcconfig; sourceTree = ""; }; BD43C6282D1B2514003BBC42 /* Ryujinx.Headless.SDL2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = Ryujinx.Headless.SDL2.dylib; path = "MeloNX/Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -222,7 +222,7 @@ 4E80A9842CD6F54500029585 = { isa = PBXGroup; children = ( - 5650564A2D2A758600C8BB1E /* dotnet.xcconfig.example */, + 5650564A2D2A758600C8BB1E /* dotnet.xcconfig */, BD43C6282D1B2514003BBC42 /* Ryujinx.Headless.SDL2.dylib */, 4E80A98F2CD6F54500029585 /* MeloNX */, 4E80A9A02CD6F54700029585 /* MeloNXTests */, @@ -260,7 +260,7 @@ buildConfigurationList = BD43C61E2D1B23AB003BBC42 /* Build configuration list for PBXLegacyTarget "Ryujinx" */; buildPhases = ( ); - buildToolPath = "$(DOTNET_PATH)"; + buildToolPath = /usr/local/share/dotnet/dotnet; buildWorkingDirectory = "$(SRCROOT)/../.."; dependencies = ( ); @@ -666,6 +666,12 @@ "$(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", ); GCC_OPTIMIZATION_LEVEL = fast; GENERATE_INFOPLIST_FILE = YES; @@ -737,6 +743,18 @@ "$(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", + "$(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.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX; @@ -790,6 +808,12 @@ "$(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", ); GCC_OPTIMIZATION_LEVEL = fast; GENERATE_INFOPLIST_FILE = YES; @@ -861,6 +885,18 @@ "$(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", + "$(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.2.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 65a102bc9..8132f3bc6 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/App/Core/Headers/Ryujinx-Header.h b/src/MeloNX/MeloNX/App/Core/Headers/Ryujinx-Header.h index 10a6e7b54..3871afe5f 100644 --- a/src/MeloNX/MeloNX/App/Core/Headers/Ryujinx-Header.h +++ b/src/MeloNX/MeloNX/App/Core/Headers/Ryujinx-Header.h @@ -14,8 +14,6 @@ #include #include -#import "utils.h" - #ifdef __cplusplus extern "C" { diff --git a/src/MeloNX/MeloNX/App/Core/JIT/IsJITEnabled.swift b/src/MeloNX/MeloNX/App/Core/JIT/IsJITEnabled.swift index ebb447708..29c614a7c 100644 --- a/src/MeloNX/MeloNX/App/Core/JIT/IsJITEnabled.swift +++ b/src/MeloNX/MeloNX/App/Core/JIT/IsJITEnabled.swift @@ -5,15 +5,49 @@ // Created by Stossy11 on 10/02/2025. // +import Foundation +func checkMemoryPermissions(at address: UnsafeRawPointer) -> Bool { + var region: vm_address_t = vm_address_t(UInt(bitPattern: address)) + var regionSize: vm_size_t = 0 + var info = vm_region_basic_info_64() + var infoCount = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size) + var objectName: mach_port_t = UInt32(MACH_PORT_NULL) + + let result = withUnsafeMutablePointer(to: &info) { + $0.withMemoryRebound(to: integer_t.self, capacity: Int(infoCount)) { + vm_region_64(mach_task_self_, ®ion, ®ionSize, VM_REGION_BASIC_INFO_64, $0, &infoCount, &objectName) + } + } + + if result != KERN_SUCCESS { + print("Failed to reach \(address)") + return false + } + + return info.protection & VM_PROT_EXECUTE != 0 +} func isJITEnabled() -> Bool { - var flags: Int = 0 + let pageSize = sysconf(_SC_PAGESIZE) + let code: [UInt32] = [0x52800540, 0xD65F03C0] - csops(getpid(), 0, &flags, sizeof(flags)) - return (Int32(flags) & CS_DEBUGGED) != 0; -} - -func sizeof(_ value: T) -> Int { - return MemoryLayout.size + guard let jitMemory = mmap(nil, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0), jitMemory != MAP_FAILED else { + return false + } + + defer { + munmap(jitMemory, pageSize) + } + + + memcpy(jitMemory, code, code.count) + + if mprotect(jitMemory, pageSize, PROT_READ | PROT_EXEC) != 0 { + return false + } + + let checkMem = checkMemoryPermissions(at: jitMemory) + + return checkMem } diff --git a/src/MeloNX/MeloNX/App/Core/JIT/utils.h b/src/MeloNX/MeloNX/App/Core/JIT/utils.h deleted file mode 100644 index 380d18050..000000000 --- a/src/MeloNX/MeloNX/App/Core/JIT/utils.h +++ /dev/null @@ -1,27 +0,0 @@ -#if __has_feature(modules) -@import UIKit; -@import Foundation; -#else -#import "UIKit/UIKit.h" -#import "Foundation/Foundation.h" -#endif - -#define DISPATCH_ASYNC_START dispatch_async(dispatch_get_main_queue(), ^{ -#define DISPATCH_ASYNC_CLOSE }); - -#define PT_TRACE_ME 0 -extern int ptrace(int, pid_t, caddr_t, int); - -#define CS_DEBUGGED 0x10000000 -extern int csops( - pid_t pid, - unsigned int ops, - void *useraddr, - size_t usersize - ); - -extern BOOL getEntitlementValue(NSString *key); -extern BOOL isJITEnabled(void); - -#define DLOG(format, ...) ShowAlert(@"DEBUG", [NSString stringWithFormat:@"\n %s [Line %d] \n %@", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:format, ##__VA_ARGS__]]) -void ShowAlert(NSString* title, NSString* message, _Bool* showok); diff --git a/src/MeloNX/MeloNX/App/Core/JIT/utils.m b/src/MeloNX/MeloNX/App/Core/JIT/utils.m deleted file mode 100644 index a7449cd36..000000000 --- a/src/MeloNX/MeloNX/App/Core/JIT/utils.m +++ /dev/null @@ -1,82 +0,0 @@ -#import "utils.h" - -typedef struct __SecTask * SecTaskRef; -extern CFTypeRef SecTaskCopyValueForEntitlement( - SecTaskRef task, - NSString* entitlement, - CFErrorRef _Nullable *error - ) - __attribute__((weak_import)); - -extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator) - __attribute__((weak_import)); - -BOOL getEntitlementValue(NSString *key) -{ - if (SecTaskCreateFromSelf == NULL || SecTaskCopyValueForEntitlement == NULL) - return NO; - SecTaskRef sec_task = SecTaskCreateFromSelf(NULL); - if(!sec_task) return NO; - CFTypeRef value = SecTaskCopyValueForEntitlement(sec_task, key, nil); - if (value != nil) - { - CFRelease(value); - } - CFRelease(sec_task); - return value != nil && [(__bridge id)value boolValue]; -} - -BOOL isJITEnabled(void) -{ - if (getEntitlementValue(@"dynamic-codesigning")) - { - return YES; - } - - int flags; - csops(getpid(), 0, &flags, sizeof(flags)); - return (flags & CS_DEBUGGED) != 0; -} - -void ShowAlert(NSString* title, NSString* message, _Bool* showok) -{ - DISPATCH_ASYNC_START - UIWindow* mainWindow = [[UIApplication sharedApplication] windows].lastObject; - UIAlertController *alert = [UIAlertController alertControllerWithTitle:title - message:message - preferredStyle:UIAlertControllerStyleAlert]; - if (showok) { - [alert addAction:[UIAlertAction actionWithTitle:@"ok!" - style:UIAlertActionStyleDefault - handler:nil]]; - } - [mainWindow.rootViewController presentViewController:alert - animated:true - completion:nil]; - DISPATCH_ASYNC_CLOSE -} - -#import - -__attribute__((constructor)) static void entry(int argc, char **argv) -{ - - if (getEntitlementValue(@"com.apple.developer.kernel.increased-memory-limit")) { - NSLog(@"Entitlement Does Exist"); - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setBool:YES forKey:@"increased-memory-limit"]; - [defaults synchronize]; // Ensure the value is saved immediately - } - - if (getEntitlementValue(@"com.apple.developer.kernel.increased-debugging-memory-limit")) { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setBool:YES forKey:@"increased-debugging-memory-limit"]; - [defaults synchronize]; // Ensure the value is saved immediately - } - if (getEntitlementValue(@"com.apple.developer.kernel.extended-virtual-addressing")) { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setBool:YES forKey:@"extended-virtual-addressing"]; - [defaults synchronize]; // Ensure the value is saved immediately - } - -} diff --git a/src/MeloNX/MeloNX/App/Views/ContentView.swift b/src/MeloNX/MeloNX/App/Views/ContentView.swift index 9e365c251..9741c208a 100644 --- a/src/MeloNX/MeloNX/App/Views/ContentView.swift +++ b/src/MeloNX/MeloNX/App/Views/ContentView.swift @@ -57,25 +57,17 @@ struct ContentView: View { let defaultConfig = loadSettings() ?? Ryujinx.Configuration(gamepath: "") _config = State(initialValue: defaultConfig) - let defaultSettings: [MoltenVKSettings] = [ - // MoltenVKSettings(string: "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS", value: "1"), - // MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "2"), - // Metal Private API isn't needed and causes more stutters + let defaultSettings: [MoltenVKSettings] = [ // Default MoltenVK Settings. MoltenVKSettings(string: "MVK_USE_METAL_PRIVATE_API", value: "1"), MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_PRIVATE_API", value: "1"), MoltenVKSettings(string: "MVK_DEBUG", value: "0"), MoltenVKSettings(string: "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS", value: "0"), - // MoltenVKSettings(string: "MVK_CONFIG_LOG_LEVEL", value: "0"), - // MVK_CONFIG_LOG_LEVEL - //MVK_DEBUG - // Uses more ram but makes performance higher, may add an option in settings to change or enable / disable this value (default 64 or 192 depending on what i decide) - MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "1024"), + // Uses more ram but makes performance higher, may add an option in settings to change or enable / disable this value (default 64) + MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "128"), ] _settings = State(initialValue: defaultSettings) - print("JIT Enabled: \(isJITEnabled())") - initializeSDL() } @@ -91,20 +83,6 @@ struct ContentView: View { } else { ZStack { emulationView - .onAppear() { - // This is fro the old exiting game feature that didn't work properly. will look into it and figure out a better alternative - /* - Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in - timer.invalidate() - quits = quit - - if quits { - quit = false - timer.invalidate() - } - } - */ - } } } } else { @@ -116,10 +94,11 @@ struct ContentView: View { isAnimating = false } } else { - VStack { - - } - + EmulationView() + .persistentSystemOverlays(.hidden) + .onAppear() { + isAnimating = false + } } } } else { @@ -197,14 +176,12 @@ struct ContentView: View { let containerWidth = min(screenGeometry.size.width * 0.35, 350) ZStack(alignment: .leading) { - // Background track Rectangle() .cornerRadius(10) .frame(width: containerWidth, height: min(screenGeometry.size.height * 0.015, 12)) .foregroundColor(.gray.opacity(0.3)) .shadow(color: .black.opacity(0.2), radius: 4, x: 0, y: 2) - // Animated loading bar Rectangle() .cornerRadius(10) .frame(width: clumpWidth, height: min(screenGeometry.size.height * 0.015, 12)) @@ -272,15 +249,9 @@ struct ContentView: View { )) let isJIT = isJITEnabled() - - if !isJIT, useTrollStore { - askForJIT() + if !isJIT { + useTrollStore ? askForJIT() : enableJITEB() } - - if !isJIT, jitStreamerEB { - enableJITEB() - } - } } @@ -289,7 +260,7 @@ struct ContentView: View { private func initializeSDL() { setMoltenVKSettings() SDL_SetMainReady() // Sets SDL Ready - SDL_iPhoneSetEventPump(SDL_TRUE) // Set iOS Event Pump to true (Check out SDL2 Documentation here) + SDL_iPhoneSetEventPump(SDL_TRUE) // Set iOS Event Pump to true SDL_Init(SdlInitFlags) // Initialises SDL2 initialize() } @@ -327,27 +298,6 @@ struct ContentView: View { } } - - - func showAlert(title: String, message: String, showOk: Bool, completion: @escaping (Bool) -> Void) { - DispatchQueue.main.async { - if let mainWindow = UIApplication.shared.windows.last { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - - if showOk { - let okAction = UIAlertAction(title: "OK", style: .default) { _ in - completion(true) - } - - alert.addAction(okAction) - } else { - completion(false) - } - - mainWindow.rootViewController?.present(alert, animated: true, completion: nil) - } - } - } private func start(displayid: UInt32) { diff --git a/src/MeloNX/MeloNX/App/Views/GamesList/GameListView.swift b/src/MeloNX/MeloNX/App/Views/GamesList/GameListView.swift index 320556ab9..721734ef7 100644 --- a/src/MeloNX/MeloNX/App/Views/GamesList/GameListView.swift +++ b/src/MeloNX/MeloNX/App/Views/GamesList/GameListView.swift @@ -424,6 +424,8 @@ struct GameListRow: View { @State var showGameDeleteConfirmation: Bool = false @Environment(\.colorScheme) var colorScheme + @AppStorage("portal") var gamepo = false + var body: some View { Button(action: { startemu = game @@ -478,6 +480,12 @@ struct GameListRow: View { Button { gameInfo = game isViewingGameInfo.toggle() + + if game.titleName.lowercased() == "portal" { + gamepo = true + } else if game.titleName.lowercased() == "portal 2" { + gamepo = true + } } label: { Label("Game Info", systemImage: "info.circle") } @@ -499,6 +507,7 @@ struct GameListRow: View { } } + Section { Button(role: .destructive) { gametoDelete = game diff --git a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift index a7fa63405..f2dc83bac 100644 --- a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift +++ b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift @@ -46,6 +46,7 @@ struct SettingsView: View { @State private var showAnisotropicInfo = false @State private var showControllerInfo = false @State private var searchText = "" + @AppStorage("portal") var gamepo = false var filteredMemoryModes: [(String, String)] { guard !searchText.isEmpty else { return memoryManagerModes } @@ -391,7 +392,7 @@ struct SettingsView: View { .onAppear() { print("CPU Info: \(cpuInfo)") } - } else if getEntitlementValue("com.apple.private.hypervisor") { + } else if checkAppEntitlement("com.apple.private.hypervisor") { Toggle(isOn: $config.hypervisor) { labelWithIcon("Hypervisor", iconName: "bolt") } @@ -530,12 +531,10 @@ struct SettingsView: View { // Advanced Section { - if #unavailable(iOS 17) { - Toggle(isOn: $windowCode) { - labelWithIcon("SDL Window", iconName: "macwindow.on.rectangle") - } - .tint(.blue) + Toggle(isOn: $windowCode) { + labelWithIcon("SDL Window", iconName: "macwindow.on.rectangle") } + .tint(.blue) DisclosureGroup { @@ -588,9 +587,9 @@ struct SettingsView: View { .headerProminence(.increased) } footer: { if #available(iOS 17, *) { - Text("For advanced users. See page size or add custom arguments for experimental features. (Please don't touch this if you don't know what you're doing).") + Text("For advanced users. See page size or add custom arguments for experimental features. (Please don't touch this if you don't know what you're doing). \n \n\(gamepo ? "the cake is a lie" : "")") } else { - Text("For advanced users. See page size or add custom arguments for experimental features. (Please don't touch this if you don't know what you're doing). If the emulation is not showing (you may hear audio in some games), try enabling \"SDL Window\"") + Text("For advanced users. See page size or add custom arguments for experimental features. (Please don't touch this if you don't know what you're doing). If the emulation is not showing (you may hear audio in some games), try enabling \"SDL Window\" \n \n\(gamepo ? "the cake is a lie" : "")") } } diff --git a/src/MeloNX/MeloNX/App/Views/Updates/GameUpdateManagerSheet.swift b/src/MeloNX/MeloNX/App/Views/Updates/GameUpdateManagerSheet.swift index 0d7e8fa68..6ea8f6ceb 100644 --- a/src/MeloNX/MeloNX/App/Views/Updates/GameUpdateManagerSheet.swift +++ b/src/MeloNX/MeloNX/App/Views/Updates/GameUpdateManagerSheet.swift @@ -118,10 +118,10 @@ struct UpdateManagerSheet: View { Ryujinx.shared.games = Ryujinx.shared.loadGames() } - func saveJSON(selectedItem: String) { + func saveJSON(selectedItem: String?) { guard let jsonURL = jsonURL else { return } do { - let jsonDict = ["paths": items, "selected": selectedItem] as [String: Any] + let jsonDict = ["paths": items, "selected": selectedItem ?? self.selectedItem ?? ""] as [String: Any] let newData = try JSONSerialization.data(withJSONObject: jsonDict, options: .prettyPrinted) try newData.write(to: jsonURL) } catch { diff --git a/src/MeloNX/dotnet.xcconfig.example b/src/MeloNX/dotnet.xcconfig.example deleted file mode 100644 index c9d6d4fad..000000000 --- a/src/MeloNX/dotnet.xcconfig.example +++ /dev/null @@ -1,11 +0,0 @@ -// -// dotnet.xcconfig -// MeloNX -// -// Created by June P on 12/25/24. -// - -// Configuration settings file format documentation can be found at: -// https://help.apple.com/xcode/#/dev745c5c974 - -DOTNET_PATH = $(HOME)/.dotnet/dotnet diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs index c0a49b5f7..2e963cdda 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs @@ -26,10 +26,16 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { return $"lib{libraryName}.so.{version}"; } - else if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS()) // TODO: ffmpeg on ios + else if (OperatingSystem.IsMacOS()) { return $"lib{libraryName}.{version}.dylib"; } + else if (OperatingSystem.IsIOS()) + { + string libName = $"lib{libraryName}.{version}.dylib"; + Console.WriteLine($"[iOS] Required firmware library: {libName}"); + return libName; + } else { throw new NotImplementedException($"Unsupported OS for FFmpeg: {RuntimeInformation.RuntimeIdentifier}"); diff --git a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs index f973746fa..b46ead9f9 100644 --- a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs +++ b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs @@ -9,10 +9,10 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK [SupportedOSPlatform("ios")] public static partial class MVKInitialization { - [LibraryImport("MoltenVK.framework/MoltenVK")] + [LibraryImport("libMoltenVK.dylib")] private static partial Result vkGetMoltenVKConfigurationMVK(IntPtr unusedInstance, out MVKConfiguration config, in IntPtr configSize); - [LibraryImport("MoltenVK.framework/MoltenVK")] + [LibraryImport("libMoltenVK.dylib")] private static partial Result vkSetMoltenVKConfigurationMVK(IntPtr unusedInstance, in MVKConfiguration config, in IntPtr configSize); public static void Initialize() diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 11f532510..cb5f6b3b2 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -601,7 +601,7 @@ namespace Ryujinx.Graphics.Vulkan if (supportsExtDynamicState) { - dynamicStates[8] = DynamicState.VertexInputBindingStrideExt; + // dynamicStates[8] = DynamicState.VertexInputBindingStrideExt; } var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index f8756b313..3fd96ecef 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -319,7 +319,7 @@ namespace Ryujinx.Headless.SDL2 var result = Parser.Default.ParseArguments(args) .WithParsed(options => { - Load(options); // Load is called with the parsed options + Load(options); }) .WithNotParsed(errors => errors.Output());