Add JIT detection and Lower memory plus other changes

This commit is contained in:
Stossy11 2024-12-02 22:49:35 +11:00
parent bb4e7314a5
commit 300efe5f55
6 changed files with 202 additions and 28 deletions

View 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);

View 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
}
}

View File

@ -7,6 +7,7 @@
import Foundation
class MTLHud {
var canMetalHud: Bool {

View File

@ -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
}
}

View File

@ -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: ", ")