testing with stuff

This commit is contained in:
Ben Lawrence 2024-12-01 10:55:02 +13:00
parent d0d5e92def
commit a59b4e05f2
No known key found for this signature in database
GPG Key ID: 0CC165DA94B90568

View File

@ -16,185 +16,230 @@ struct MoltenVKSettings: Codable, Hashable {
} }
struct ContentView: View { struct ContentView: View {
@State public var theWindow: UIWindow? = nil // MARK: - Properties
@State private var theWindow: UIWindow?
@State private var virtualController: GCVirtualController? @State private var virtualController: GCVirtualController?
@State var game: URL? = nil @State private var game: URL?
@State var controllersList: [Controller] = [] @State private var controllersList: [Controller] = []
@State var currentControllers: [Controller] = [] @State private var currentControllers: [Controller] = []
@State var config: Ryujinx.Configuration = Ryujinx.Configuration(gamepath: "") @State private var config: Ryujinx.Configuration
@State private var settings: [MoltenVKSettings]
@State var settings: [MoltenVKSettings] = [ @State private var isVirtualControllerActive: Bool = false
// MoltenVKSettings(string: "MVK_CONFIG_SYNCHRONOUS_QUEUE_SUBMITS", value: ""),
// MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "1"),
MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "1024"),
MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", value: "1"),
MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1")
]
// MARK: - Initialization
init() { init() {
// Initialize SDL let defaultConfig = Ryujinx.Configuration(gamepath: "")
DispatchQueue.main.async { [self] in _config = State(initialValue: defaultConfig)
setMoltenVKSettings()
SDL_SetMainReady() let defaultSettings: [MoltenVKSettings] = [
SDL_iPhoneSetEventPump(SDL_TRUE) MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "1024"),
SDL_Init(SDL_INIT_VIDEO) MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", value: "1"),
patchMakeKeyAndVisible() MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1")
]
_settings = State(initialValue: defaultSettings)
initializeSDL()
}
// MARK: - Body
var body: some View {
iOSNav {
if let game {
emulationView
} else {
mainMenuView
}
}
.onChange(of: isVirtualControllerActive) { newValue in
if newValue {
createVirtualController()
} else {
destroyVirtualController()
}
} }
} }
func setupVirtualController() { // MARK: - View Components
private var emulationView: some View {
ZStack {}
.onAppear {
setupEmulation()
}
}
private var mainMenuView: some View {
HStack {
GameListView(startemu: $game)
.onAppear {
createVirtualController()
refreshControllersList()
}
settingsListView
}
}
private var settingsListView: some View {
List {
Section("Settings") {
NavigationLink("Config") {
SettingsView(config: $config, MoltenVKSettings: $settings)
}
}
Section("Controller") {
Button("Refresh", action: refreshControllersList)
ForEach(controllersList, id: \.self) { controller in
if controller.name != "Apple Touch Controller" {
controllerRow(for: controller)
}
}
}
}
}
private func controllerRow(for controller: Controller) -> some View {
HStack {
Button(controller.name) {
toggleController(controller)
}
Spacer()
if currentControllers.contains(where: { $0.id == controller.id }) {
Image(systemName: "checkmark.circle.fill")
}
}
}
// MARK: - Controller Management
private func createVirtualController() {
let configuration = GCVirtualController.Configuration() let configuration = GCVirtualController.Configuration()
configuration.elements = [ configuration.elements = [
/*
GCInputLeftThumbstick, GCInputLeftThumbstick,
GCInputRightThumbstick, GCInputRightThumbstick,
GCInputButtonA, GCInputButtonA,
GCInputButtonB, GCInputButtonB,
GCInputButtonX, GCInputButtonX,
GCInputButtonY GCInputButtonY,
*/
] ]
let controller = GCVirtualController(configuration: configuration) virtualController = GCVirtualController(configuration: configuration)
self.virtualController = controller virtualController?.connect()
self.virtualController?.connect()
controllersList.removeAll(where: { $0.name == "Apple Touch Controller" })
} }
var body: some View { private func destroyVirtualController() {
iOSNav { virtualController?.disconnect()
virtualController = nil
// Remove virtual controller from current controllers
controllersList.removeAll(where: { $0.name == "Apple Touch Controller" })
}
// MARK: - Helper Methods
private func initializeSDL() {
DispatchQueue.main.async {
setMoltenVKSettings()
SDL_SetMainReady()
SDL_iPhoneSetEventPump(SDL_TRUE)
SDL_Init(SDL_INIT_VIDEO)
}
}
private func setupEmulation() {
virtualController?.disconnect()
controllerCallback = {
DispatchQueue.main.async {
// controllersList = Ryujinx.shared.getConnectedControllers()
currentControllers.removeAll(where: { $0.name == "Apple Touch Controller" })
if controllersList.count == 2,
controllersList.contains(where: { $0.name == "Apple Touch Controller" }) {
currentControllers.append(controllersList[1])
}
print(currentControllers)
start(displayid: 1)
}
}
showVirtualController()
}
private func refreshControllersList() {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
// controllersList = Ryujinx.shared.getConnectedControllers()
controllersList.removeAll(where: { $0.id == "0" })
if let game { controllersList.removeAll(where: { $0.name == "Apple Touch Controller" })
ZStack {
if let controller = controllersList.first, !controllersList.isEmpty {
} currentControllers.append(controller)
.onAppear {
start(displayid: 0)
}
} else {
HStack {
GameListView(startemu: $game)
// .onAppear() {
// Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
// controllersList = Ryujinx.shared.getConnectedControllers()
// controllersList.removeAll(where: { $0.id == "0" })
// }
// }
List {
Section("Settings") {
NavigationLink {
SettingsView(config: $config, MoltenVKSettings: $settings)
} label: {
Text("Config")
}
}
Section("Controller") {
Button {
controllersList = Ryujinx.shared.getConnectedControllers()
controllersList.removeAll(where: { $0.id == "0" })
} label: {
Text("Refresh")
}
ForEach(controllersList, id: \.self) { controller in
HStack {
Button {
if currentControllers.contains(where: { $0.id == controller.id }) {
currentControllers.removeAll(where: { $0.id == controller.id })
} else {
currentControllers.append(controller)
}
} label: {
Text(controller.name)
}
Spacer()
if currentControllers.contains(where: { $0.id == controller.id }) {
Image(systemName: "checkmark.circle.fill")
}
}
}
}
}
}
} }
} }
} }
func start(displayid: UInt32) { private func toggleController(_ controller: Controller) {
if currentControllers.contains(where: { $0.id == controller.id }) {
if let game { currentControllers.removeAll(where: { $0.id == controller.id })
self.config.gamepath = game.path
self.config.inputids = currentControllers.map(\.id)
allocateSixGB()
// Start the emulation
print("Is MetalHud Enabled? " + (MTLHud.shared.isEnabled ? "yeah" : "nope"))
do {
setupVirtualController()
try Ryujinx.shared.start(with: config)
} catch {
print("Error \(error.localizedDescription)")
}
} else { } else {
currentControllers.append(controller)
} }
} }
func allocateSixGB() -> UnsafeMutableRawPointer? { private func start(displayid: UInt32) {
guard let game else { return }
config.gamepath = game.path
config.inputids = currentControllers.map(\.id)
allocateMemory()
do {
try Ryujinx.shared.start(with: config)
} catch {
print("Error: \(error.localizedDescription)")
}
}
private func allocateMemory() {
let physicalMemory = ProcessInfo.processInfo.physicalMemory let physicalMemory = ProcessInfo.processInfo.physicalMemory
let totalMemoryInGB = Double(physicalMemory) / (1024 * 1024 * 1024) let totalMemoryInGB = Double(physicalMemory) / (1024 * 1024 * 1024)
let mem = totalMemoryInGB
print(mem) let pointer = UnsafeMutableRawPointer.allocate(
// Allocate memory byteCount: Int(totalMemoryInGB),
let pointer = UnsafeMutableRawPointer.allocate(byteCount: Int(mem), alignment: MemoryLayout<UInt8>.alignment) alignment: MemoryLayout<UInt8>.alignment
)
// Optionally initialize the memory pointer.initializeMemory(as: UInt8.self, repeating: 0, count: Int(totalMemoryInGB))
pointer.initializeMemory(as: UInt8.self, repeating: 0, count: Int(mem))
print("Successfully allocated 6GB of memory.")
return pointer
} }
func patchMakeKeyAndVisible() {
let uiwindowClass = UIWindow.self
if let m1 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.makeKeyAndVisible)),
let m2 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.wdb_makeKeyAndVisible)) {
method_exchangeImplementations(m1, m2)
}
}
private func setMoltenVKSettings() { private func setMoltenVKSettings() {
if let configs = loadSettings() { if let configs = loadSettings() {
self.config = configs self.config = configs
print(configs)
} }
settings.forEach { setting in settings.forEach { setting in
setenv(setting.string, setting.value, 1) setenv(setting.string, setting.value, 1)
} }
} }
} }
// MARK: - Helper Functions
func loadSettings() -> Ryujinx.Configuration? { func loadSettings() -> Ryujinx.Configuration? {
guard let jsonString = UserDefaults.standard.string(forKey: "config") else { guard let jsonString = UserDefaults.standard.string(forKey: "config"),
let data = jsonString.data(using: .utf8) else {
return nil return nil
} }
do { do {
let decoder = JSONDecoder() return try JSONDecoder().decode(Ryujinx.Configuration.self, from: data)
if let data = jsonString.data(using: .utf8) {
return try decoder.decode(Ryujinx.Configuration.self, from: data)
}
} catch { } catch {
print("Failed to load settings: \(error)") print("Failed to load settings: \(error)")
return nil
} }
return nil
} }