diff --git a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate index c3855c670..7e812551b 100644 Binary files a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate and b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/src/MeloNX/MeloNX.xcodeproj/xcshareddata/xcschemes/MeloNX.xcscheme b/src/MeloNX/MeloNX.xcodeproj/xcshareddata/xcschemes/MeloNX.xcscheme new file mode 100644 index 000000000..327ff8d71 --- /dev/null +++ b/src/MeloNX/MeloNX.xcodeproj/xcshareddata/xcschemes/MeloNX.xcscheme @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 000000000..5cede85d8 --- /dev/null +++ b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist index 940154f32..10d539f04 100644 --- a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/stossy11.xcuserdatad/xcschemes/xcschememanagement.plist @@ -10,5 +10,23 @@ 0 + SuppressBuildableAutocreation + + 4E80A98C2CD6F54500029585 + + primary + + + 4E80A99C2CD6F54700029585 + + primary + + + 4E80A9A62CD6F54700029585 + + primary + + + diff --git a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift index 3a1c8c454..4e453773b 100644 --- a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift +++ b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift @@ -17,14 +17,16 @@ class Ryujinx { let debuglogs: Bool let tracelogs: Bool let listinputids: Bool + let fullscreen: Bool var additionalArgs: [String] - init(gamepath: String, additionalArgs: [String] = [], debuglogs: Bool = false, tracelogs: Bool = false, listinputids: Bool = false, inputids: [String] = []) { + init(gamepath: String, additionalArgs: [String] = [], debuglogs: Bool = false, tracelogs: Bool = false, listinputids: Bool = false, inputids: [String] = [], ryufullscreen: Bool = false) { self.gamepath = gamepath self.debuglogs = debuglogs self.tracelogs = tracelogs self.inputids = inputids self.listinputids = listinputids + self.fullscreen = ryufullscreen self.additionalArgs = additionalArgs } } @@ -87,7 +89,7 @@ class Ryujinx { private func buildCommandLineArgs(from config: Configuration) -> [String] { var args: [String] = [] - + // Add the game path args.append(config.gamepath) // Starts with vulkan @@ -95,7 +97,9 @@ class Ryujinx { args.append("Vulkan") // Fixes the Stubs.DispatchLoop Crash args.append(contentsOf: ["--memory-manager-mode", "SoftwarePageTable"]) - args.append(contentsOf: ["--fullscreen", "true"]) + if config.fullscreen { + args.append(contentsOf: ["--fullscreen", String(config.fullscreen)]) + } // Debug Logs args.append(contentsOf: ["--enable-debug-logs", String(config.debuglogs)]) args.append(contentsOf: ["--enable-trace-logs", String(config.tracelogs)]) diff --git a/src/MeloNX/MeloNX/Views/ContentView.swift b/src/MeloNX/MeloNX/Views/ContentView.swift index 3652fbb4e..d5e386651 100644 --- a/src/MeloNX/MeloNX/Views/ContentView.swift +++ b/src/MeloNX/MeloNX/Views/ContentView.swift @@ -49,7 +49,7 @@ struct ContentView: View { setupVirtualController() - let config = Ryujinx.Configuration(gamepath: game.path, debuglogs: true, tracelogs: true, listinputids: false, inputids: ["1-47150005-05ac-0000-0100-00004f066d01"]) + let config = Ryujinx.Configuration(gamepath: game.path, debuglogs: true, tracelogs: true, listinputids: false, inputids: ["1-47150005-05ac-0000-0100-00004f066d01"], ryufullscreen: true) // Starts the emulation do { try Ryujinx().start(with: config) diff --git a/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift b/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift index 07a7f910e..a6544d35f 100644 --- a/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift +++ b/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift @@ -11,43 +11,68 @@ import SDL2 class SDLView: UIView { var sdlwin: OpaquePointer? - var mtkview: UnsafeMutableRawPointer? - + private var sdlWindowID: UInt32 = 1 // Adjust this ID based on Ryujinx window ID + override init(frame: CGRect) { super.init(frame: frame) - makeSDLWindow() + startSDLWindowRetrieval() } required init?(coder: NSCoder) { super.init(coder: coder) - makeSDLWindow() - + startSDLWindowRetrieval() } - private func makeSDLWindow() { - DispatchQueue.main.async { [self] in + private func startSDLWindowRetrieval() { + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + self.makeSDLWindow() - // Gets window created from Ryujinx - sdlwin = SDL_GetWindowFromID(1) - - // Check if it got the window. - guard sdlwin != nil else { - print("Error getting SDL window: \(String(cString: SDL_GetError()))") - return - } - // Create metal View from the Window - mtkview = SDL_Metal_CreateView(sdlwin) - if mtkview == nil { - print("Failed to create SDL Metal view.") - return - } - - // Convert Metal View to Sublayer - if let metalLayerPointer = SDL_Metal_GetLayer(mtkview) { - let metalLayer = Unmanaged.fromOpaque(metalLayerPointer).takeUnretainedValue() - metalLayer.device = MTLCreateSystemDefaultDevice() - layer.addSublayer(metalLayer) + // Stop the timer once the window is successfully retrieved + if self.sdlwin != nil { + timer.invalidate() } } } + + private func makeSDLWindow() { + // Attempt to retrieve the SDL window created by Ryujinx + sdlwin = SDL_GetWindowFromID(sdlWindowID) + + // Check if we successfully retrieved the SDL window + guard sdlwin != nil else { + print("Error getting SDL window: \(String(cString: SDL_GetError()))") + return + } + + print("SDL window retrieved successfully.") + + // Position SDL window over this UIView + DispatchQueue.main.async { + self.syncSDLWindowPosition() + } + } + + private func syncSDLWindowPosition() { + guard let sdlwin = sdlwin else { return } + DispatchQueue.main.async { + + // Get the frame of the UIView in screen coordinates + let viewFrameInWindow = self.convert(self.bounds, to: nil) + + // Set the SDL window position and size to match the UIView frame + SDL_SetWindowPosition(sdlwin, Int32(viewFrameInWindow.origin.x), Int32(viewFrameInWindow.origin.y)) + SDL_SetWindowSize(sdlwin, Int32(viewFrameInWindow.width), Int32(viewFrameInWindow.height)) + + // Bring SDL window to the front + SDL_RaiseWindow(sdlwin) + } + + print("SDL window positioned over SDLView.") + } + + override func layoutSubviews() { + super.layoutSubviews() + // Adjust SDL window whenever layout changes + syncSDLWindowPosition() + } }