forked from MeloNX/MeloNX
Put everything on the main thread for testing.
This commit is contained in:
parent
60cfb86774
commit
02901a5a14
Binary file not shown.
@ -41,20 +41,23 @@ struct ContentView: View {
|
||||
ZStack {
|
||||
if let gameUrl, emulationStarted {
|
||||
VulkanSDLViewRepresentable { displayid in
|
||||
gameUrl.startAccessingSecurityScopedResource()
|
||||
|
||||
let config = RyujinxEmulator.Configuration(
|
||||
inputPath: gameUrl.path,
|
||||
mainThread: mainThread,
|
||||
graphicsBackend: "Vulkan",
|
||||
additionalArgs: [
|
||||
"--display-id", String(displayid),
|
||||
"--fullscreen", "true"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
showVirtualController(url: gameUrl, ryuconfig: config)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
gameUrl.startAccessingSecurityScopedResource()
|
||||
|
||||
let config = RyujinxEmulator.Configuration(
|
||||
inputPath: gameUrl.path,
|
||||
mainThread: mainThread,
|
||||
graphicsBackend: "Vulkan",
|
||||
additionalArgs: [
|
||||
"--display-id", String(displayid),
|
||||
"--fullscreen", "true"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
showVirtualController(url: gameUrl, ryuconfig: config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,32 +113,38 @@ func startEmulation(game: URL, config: RyujinxEmulator.Configuration) {
|
||||
|
||||
let config = config
|
||||
|
||||
// patchMakeKeyAndVisible()
|
||||
patchMakeKeyAndVisible()
|
||||
// SDL_Init(SDL_INIT_VIDEO)
|
||||
|
||||
let emulator = RyujinxEmulator()
|
||||
do {
|
||||
try emulator.startWithRunLoop(config: config)
|
||||
} catch {
|
||||
print(error)
|
||||
DispatchQueue.main.async {
|
||||
let emulator = RyujinxEmulator()
|
||||
do {
|
||||
try emulator.startWithRunLoop(config: config)
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func patchMakeKeyAndVisible() {
|
||||
let uiwindowClass = UIWindow.self
|
||||
let m1 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.makeKeyAndVisible))!
|
||||
let m2 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.wdb_makeKeyAndVisible))!
|
||||
method_exchangeImplementations(m1, m2)
|
||||
DispatchQueue.main.async {
|
||||
let uiwindowClass = UIWindow.self
|
||||
let m1 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.makeKeyAndVisible))!
|
||||
let m2 = class_getInstanceMethod(uiwindowClass, #selector(UIWindow.wdb_makeKeyAndVisible))!
|
||||
method_exchangeImplementations(m1, m2)
|
||||
}
|
||||
}
|
||||
|
||||
extension UIWindow {
|
||||
@objc func wdb_makeKeyAndVisible() {
|
||||
print("Making window key and visible...")
|
||||
if #available(iOS 13.0, *) {
|
||||
self.windowScene = (UIApplication.shared.connectedScenes.first! as! UIWindowScene)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
print("Making window key and visible...")
|
||||
if #available(iOS 13.0, *) {
|
||||
self.windowScene = (UIApplication.shared.connectedScenes.first! as! UIWindowScene)
|
||||
}
|
||||
self.wdb_makeKeyAndVisible()
|
||||
theWindow = self
|
||||
}
|
||||
self.wdb_makeKeyAndVisible()
|
||||
theWindow = self
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,15 +152,20 @@ extension UIWindow {
|
||||
var g_gcVirtualController: GCVirtualController!
|
||||
@available(iOS 15.0, *)
|
||||
func showVirtualController(url: URL, ryuconfig: RyujinxEmulator.Configuration) {
|
||||
print("Showing virtual controller...")
|
||||
let config = GCVirtualController.Configuration()
|
||||
config.elements = [
|
||||
GCInputDirectionalDpad, GCInputButtonA, GCInputButtonB, GCInputButtonX, GCInputButtonY,
|
||||
]
|
||||
g_gcVirtualController = GCVirtualController(configuration: config)
|
||||
g_gcVirtualController.connect { err in
|
||||
print("Controller connect: \(String(describing: err))")
|
||||
startEmulation(game: url, config: ryuconfig)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
print("Showing virtual controller...")
|
||||
let config = GCVirtualController.Configuration()
|
||||
config.elements = [
|
||||
GCInputDirectionalDpad, GCInputButtonA, GCInputButtonB, GCInputButtonX, GCInputButtonY,
|
||||
]
|
||||
g_gcVirtualController = GCVirtualController(configuration: config)
|
||||
g_gcVirtualController.connect { err in
|
||||
print("Controller connect: \(String(describing: err))")
|
||||
DispatchQueue.main.async {
|
||||
startEmulation(game: url, config: ryuconfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,16 @@ class RyujinxEmulator {
|
||||
|
||||
isRunning = true
|
||||
|
||||
DispatchQueue.main.async {
|
||||
do {
|
||||
try Self.start(with: config)
|
||||
} catch {
|
||||
Self.log("Emulation failed to start: \(error)")
|
||||
self.isRunning = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
emulationThread = Thread {
|
||||
let runLoop = RunLoop.current
|
||||
|
||||
@ -105,6 +115,7 @@ class RyujinxEmulator {
|
||||
runLoop.add(port, forMode: .default)
|
||||
|
||||
print(config.mainThread ? "Running on the main thread" : "Running on the background thread")
|
||||
/*
|
||||
if config.mainThread {
|
||||
DispatchQueue.main.async {
|
||||
do {
|
||||
@ -124,6 +135,8 @@ class RyujinxEmulator {
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
@ -138,7 +151,7 @@ class RyujinxEmulator {
|
||||
emulationThread?.name = "RyujinxEmulationThread"
|
||||
emulationThread?.qualityOfService = .userInteractive
|
||||
emulationThread?.threadPriority = 0.9
|
||||
emulationThread?.start()
|
||||
// emulationThread?.start()
|
||||
}
|
||||
|
||||
func quickStart(romPath: String) throws {
|
||||
|
@ -18,8 +18,11 @@ struct VulkanSDLViewRepresentable: UIViewRepresentable {
|
||||
let configure: (Uint32) -> Void
|
||||
func makeUIView(context: Context) -> VulkanSDLView {
|
||||
let view = VulkanSDLView(frame: .zero)
|
||||
configure(SDL_GetWindowID(view.sdlWindow))
|
||||
DispatchQueue.main.async { [self] in
|
||||
configure(SDL_GetWindowID(view.sdlWindow))
|
||||
}
|
||||
return view
|
||||
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: VulkanSDLView, context: Context) {
|
||||
@ -33,19 +36,24 @@ class VulkanSDLView: UIView {
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initializeSDL()
|
||||
DispatchQueue.main.async { [self] in
|
||||
initializeSDL()
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initializeSDL()
|
||||
DispatchQueue.main.async { [self] in
|
||||
initializeSDL()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func initializeSDL() {
|
||||
// Initialize SDL with video support
|
||||
|
||||
|
||||
|
||||
|
||||
// Create an SDL window with Metal support
|
||||
DispatchQueue.main.async { [self] in
|
||||
sdlWindow = SDL_CreateWindow(
|
||||
@ -57,25 +65,31 @@ class VulkanSDLView: UIView {
|
||||
SDL_WINDOW_SHOWN.rawValue | SDL_WINDOW_ALLOW_HIGHDPI.rawValue | SDL_WINDOW_VULKAN.rawValue
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
guard sdlWindow != nil else {
|
||||
print("Error creating SDL window: \(String(cString: SDL_GetError()))")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Create SDL Metal view and attach to this UIView
|
||||
metalView = SDL_Metal_CreateView(sdlWindow)
|
||||
if metalView == nil {
|
||||
print("Failed to create SDL Metal view.")
|
||||
return
|
||||
DispatchQueue.main.async { [self] in
|
||||
metalView = SDL_Metal_CreateView(sdlWindow)
|
||||
if metalView == nil {
|
||||
print("Failed to create SDL Metal view.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let metalLayerPointer = SDL_Metal_GetLayer(metalView) {
|
||||
let metalLayer = Unmanaged<CAMetalLayer>.fromOpaque(metalLayerPointer).takeUnretainedValue()
|
||||
metalLayer.device = MTLCreateSystemDefaultDevice()
|
||||
metalLayer.pixelFormat = .bgra8Unorm
|
||||
layer.addSublayer(metalLayer)
|
||||
DispatchQueue.main.async { [self] in
|
||||
layer.addSublayer(metalLayer)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
Loading…
x
Reference in New Issue
Block a user