forked from MeloNX/MeloNX
implement an all-swift approach for detecting JIT (adds support for detecting JIT on iOS 18.4+), adds an easter egg, and more
This commit is contained in:
parent
527ac3fb23
commit
8df465a959
@ -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 = "<group>"; };
|
||||
5650564A2D2A758600C8BB1E /* dotnet.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = dotnet.xcconfig; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
/* 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;
|
||||
|
Binary file not shown.
@ -14,8 +14,6 @@
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#import "utils.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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<vm_region_basic_info_64>.size / MemoryLayout<integer_t>.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<T>(_ value: T) -> Int {
|
||||
return MemoryLayout<T>.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
|
||||
}
|
||||
|
@ -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);
|
@ -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 <UIKit/UIKit.h>
|
||||
|
||||
__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
|
||||
}
|
||||
|
||||
}
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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" : "")")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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}");
|
||||
|
@ -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()
|
||||
|
@ -601,7 +601,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (supportsExtDynamicState)
|
||||
{
|
||||
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||
// dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||
}
|
||||
|
||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||
|
@ -319,7 +319,7 @@ namespace Ryujinx.Headless.SDL2
|
||||
var result = Parser.Default.ParseArguments<Options>(args)
|
||||
.WithParsed(options =>
|
||||
{
|
||||
Load(options); // Load is called with the parsed options
|
||||
Load(options);
|
||||
})
|
||||
.WithNotParsed(errors => errors.Output());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user