forked from MeloNX/MeloNX
Add JIT detection and Lower memory plus other changes
This commit is contained in:
parent
bb4e7314a5
commit
300efe5f55
Binary file not shown.
27
src/MeloNX/MeloNX/Core/DetectJIT/utils.h
Normal file
27
src/MeloNX/MeloNX/Core/DetectJIT/utils.h
Normal file
@ -0,0 +1,27 @@
|
||||
#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);
|
91
src/MeloNX/MeloNX/Core/DetectJIT/utils.m
Normal file
91
src/MeloNX/MeloNX/Core/DetectJIT/utils.m
Normal file
@ -0,0 +1,91 @@
|
||||
#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 (isJITEnabled()) {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setBool:YES forKey:@"JIT"];
|
||||
[defaults synchronize]; // Ensure the value is saved immediately
|
||||
} else {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setBool:NO forKey:@"JIT"];
|
||||
[defaults synchronize]; // Ensure the value is saved immediately
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class MTLHud {
|
||||
|
||||
var canMetalHud: Bool {
|
||||
|
@ -8,6 +8,8 @@
|
||||
import SwiftUI
|
||||
import SDL2
|
||||
import GameController
|
||||
import Darwin
|
||||
import UIKit
|
||||
|
||||
struct MoltenVKSettings: Codable, Hashable {
|
||||
let string: String
|
||||
@ -26,19 +28,24 @@ struct ContentView: View {
|
||||
@State private var settings: [MoltenVKSettings]
|
||||
@State private var isVirtualControllerActive: Bool = false
|
||||
@State var onscreencontroller: Controller = Controller(id: "", name: "")
|
||||
@AppStorage("JIT") var isJITEnabled: Bool = false
|
||||
@AppStorage("ignoreJIT") var ignoreJIT: Bool = false
|
||||
|
||||
// MARK: - Initialization
|
||||
init() {
|
||||
let defaultConfig = Ryujinx.Configuration(gamepath: "")
|
||||
let defaultConfig = loadSettings() ?? Ryujinx.Configuration(gamepath: "")
|
||||
_config = State(initialValue: defaultConfig)
|
||||
|
||||
let defaultSettings: [MoltenVKSettings] = [
|
||||
MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "1024"),
|
||||
MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "2048"),
|
||||
MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", value: "1"),
|
||||
MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1")
|
||||
]
|
||||
|
||||
_settings = State(initialValue: defaultSettings)
|
||||
|
||||
print("JIT Enabled: \(isJITEnabled)")
|
||||
|
||||
initializeSDL()
|
||||
}
|
||||
|
||||
@ -91,12 +98,18 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
|
||||
Section("Controller") {
|
||||
|
||||
Section {
|
||||
Button("Refresh", action: refreshControllersList)
|
||||
Divider()
|
||||
ForEach(controllersList, id: \.self) { controller in
|
||||
controllerRow(for: controller)
|
||||
}
|
||||
} header: {
|
||||
Text("Controllers")
|
||||
} footer: {
|
||||
Text("If no controllers are selected, the keyboard will be used.")
|
||||
.font(.footnote)
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -148,34 +161,52 @@ struct ContentView: View {
|
||||
}
|
||||
|
||||
private func setupEmulation() {
|
||||
if !isJITEnabled {
|
||||
virtualController?.disconnect()
|
||||
|
||||
guard let game = game else { return }
|
||||
|
||||
if controllersList.first(where: { $0 == onscreencontroller}) != nil {
|
||||
controllerCallback = {
|
||||
DispatchQueue.main.async {
|
||||
controllersList = Ryujinx.shared.getConnectedControllers()
|
||||
|
||||
print(currentControllers)
|
||||
start(displayid: 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showVirtualController()
|
||||
} else {
|
||||
showAlert(title: "JIT Not Enabled", message: "JIT is Required for Emulation. Please use a JIT enabler to Enable JIT", showOk: true) { pressedok in
|
||||
if pressedok, !ignoreJIT {
|
||||
game = nil
|
||||
} else if pressedok, ignoreJIT {
|
||||
virtualController?.disconnect()
|
||||
controllerCallback = {
|
||||
DispatchQueue.main.async {
|
||||
controllersList = Ryujinx.shared.getConnectedControllers()
|
||||
|
||||
print(currentControllers)
|
||||
start(displayid: 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showVirtualController()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func refreshControllersList() {
|
||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
|
||||
DispatchQueue.main.async {
|
||||
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
|
||||
controllersList = Ryujinx.shared.getConnectedControllers()
|
||||
var controller = controllersList.first(where: { $0.name.hasPrefix("Apple")})
|
||||
self.onscreencontroller = (controller ?? Controller(id: "", name: ""))
|
||||
|
||||
if let onscreen = controllersList.first(where: { $0.name.hasPrefix("Apple")}) {
|
||||
self.onscreencontroller = onscreen
|
||||
}
|
||||
|
||||
controllersList.removeAll(where: { $0.id == "0"})
|
||||
|
||||
if controllersList.count > 2 {
|
||||
let controller = controllersList[2]
|
||||
currentControllers.append(controller)
|
||||
@ -184,7 +215,6 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleController(_ controller: Controller) {
|
||||
if currentControllers.contains(where: { $0.id == controller.id }) {
|
||||
@ -194,12 +224,37 @@ 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) {
|
||||
guard let game else { return }
|
||||
|
||||
config.gamepath = game.path
|
||||
config.inputids = currentControllers.map(\.id)
|
||||
config.inputids = Array(Set(currentControllers.map(\.id)))
|
||||
|
||||
if config.inputids.isEmpty {
|
||||
config.inputids.append("0")
|
||||
}
|
||||
|
||||
do {
|
||||
try Ryujinx.shared.start(with: config)
|
||||
@ -210,9 +265,6 @@ struct ContentView: View {
|
||||
|
||||
|
||||
private func setMoltenVKSettings() {
|
||||
if let configs = loadSettings() {
|
||||
self.config = configs
|
||||
}
|
||||
|
||||
settings.forEach { setting in
|
||||
setenv(setting.string, setting.value, 1)
|
||||
@ -234,3 +286,4 @@ func loadSettings() -> Ryujinx.Configuration? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import SwiftUI
|
||||
struct SettingsView: View {
|
||||
@Binding var config: Ryujinx.Configuration
|
||||
@Binding var MoltenVKSettings: [MoltenVKSettings]
|
||||
@AppStorage("ignoreJIT") var ignoreJIT: Bool = false
|
||||
|
||||
var memoryManagerModes = [
|
||||
("HostMapped", "Host (fast)"),
|
||||
@ -31,6 +32,7 @@ struct SettingsView: View {
|
||||
Toggle("Enable Texture Recompression", isOn: $config.enableTextureRecompression)
|
||||
Toggle("Disable Docked Mode", isOn: $config.disableDockedMode)
|
||||
Resolution(value: $config.resscale)
|
||||
|
||||
Toggle("Enable Metal HUD", isOn: $metalHUDEnabled)
|
||||
.onChange(of: metalHUDEnabled) { newValue in
|
||||
if newValue {
|
||||
@ -70,7 +72,7 @@ struct SettingsView: View {
|
||||
//TextField("Game Path", text: $config.gamepath)
|
||||
|
||||
Text("PageSize \(String(Int(getpagesize())))")
|
||||
|
||||
Toggle("Ignore JIT Enabeld Popup", isOn: $ignoreJIT)
|
||||
TextField("Additional Arguments", text: Binding(
|
||||
get: {
|
||||
config.additionalArgs.joined(separator: ", ")
|
||||
|
Loading…
x
Reference in New Issue
Block a user