forked from MeloNX/MeloNX
Create the window in swift again
This commit is contained in:
parent
10e45533e1
commit
05880cc8a5
Binary file not shown.
@ -63,7 +63,6 @@
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
@ -98,7 +98,9 @@ class Ryujinx {
|
||||
// Fixes the Stubs.DispatchLoop Crash
|
||||
args.append(contentsOf: ["--memory-manager-mode", "SoftwarePageTable"])
|
||||
if config.fullscreen {
|
||||
args.append(contentsOf: ["--fullscreen", String(config.fullscreen)])
|
||||
// args.append(contentsOf: ["--fullscreen", String(config.fullscreen)])
|
||||
args.append(contentsOf: ["--exclusive-fullscreen", String(config.fullscreen)])
|
||||
// exclusive-fullscreen
|
||||
}
|
||||
// Debug Logs
|
||||
args.append(contentsOf: ["--enable-debug-logs", String(config.debuglogs)])
|
||||
|
@ -10,16 +10,19 @@ import SDL2
|
||||
import GameController
|
||||
|
||||
struct ContentView: View {
|
||||
@State public var theWindow: UIWindow? = nil
|
||||
@State private var virtualController: GCVirtualController?
|
||||
@State var game: URL? = nil
|
||||
|
||||
init() {
|
||||
// Initialize SDL
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.async { [self] in
|
||||
SDL_SetMainReady()
|
||||
SDL_iPhoneSetEventPump(SDL_TRUE)
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO)
|
||||
|
||||
// Apply the window patch early
|
||||
patchMakeKeyAndVisible()
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,8 +34,7 @@ struct ContentView: View {
|
||||
GCInputButtonA,
|
||||
GCInputButtonB,
|
||||
GCInputButtonX,
|
||||
GCInputButtonY,
|
||||
//GCInputDirectionPad
|
||||
GCInputButtonY
|
||||
]
|
||||
|
||||
let controller = GCVirtualController(configuration: configuration)
|
||||
@ -41,24 +43,66 @@ struct ContentView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
||||
|
||||
if let game {
|
||||
SDLViewRepresentable {
|
||||
|
||||
SDLViewRepresentable { displayid in
|
||||
start(displayid: displayid)
|
||||
}
|
||||
} else {
|
||||
GameListView(startemu: $game)
|
||||
}
|
||||
}
|
||||
|
||||
func start(displayid: UInt32) {
|
||||
setupVirtualController()
|
||||
|
||||
if theWindow == nil {
|
||||
// Ensure theWindow is set
|
||||
theWindow = UIApplication.shared.windows.first
|
||||
}
|
||||
|
||||
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
|
||||
let config = Ryujinx.Configuration(
|
||||
gamepath: game!.path,
|
||||
additionalArgs: [
|
||||
"--display-id", String(displayid)
|
||||
],
|
||||
debuglogs: true,
|
||||
tracelogs: true,
|
||||
listinputids: false,
|
||||
inputids: ["1-47150005-05ac-0000-0100-00004f066d01"],
|
||||
ryufullscreen: true
|
||||
)
|
||||
// Start the emulation
|
||||
do {
|
||||
try Ryujinx().start(with: config)
|
||||
} catch {
|
||||
print("Error \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GameListView(startemu: $game)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.wdb_makeKeyAndVisible()
|
||||
|
||||
// Update ContentView's reference to this window instance
|
||||
if let rootView = self.rootViewController as? UIHostingController<ContentView> {
|
||||
rootView.rootView.theWindow = self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,50 +11,57 @@ import SDL2
|
||||
|
||||
class SDLView: UIView {
|
||||
var sdlwin: OpaquePointer?
|
||||
private var sdlWindowID: UInt32 = 1 // Adjust this ID based on Ryujinx window ID
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
startSDLWindowRetrieval()
|
||||
DispatchQueue.main.async { [self] in
|
||||
makeSDLWindow()
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
startSDLWindowRetrieval()
|
||||
DispatchQueue.main.async { [self] in
|
||||
makeSDLWindow()
|
||||
}
|
||||
}
|
||||
|
||||
private func startSDLWindowRetrieval() {
|
||||
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
|
||||
self.makeSDLWindow()
|
||||
|
||||
// Stop the timer once the window is successfully retrieved
|
||||
if self.sdlwin != nil {
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
func getWindowFlags() -> UInt32 {
|
||||
return SDL_WINDOW_VULKAN.rawValue
|
||||
}
|
||||
|
||||
private func makeSDLWindow() {
|
||||
// Attempt to retrieve the SDL window created by Ryujinx
|
||||
sdlwin = SDL_GetWindowFromID(sdlWindowID)
|
||||
let width: Int32 = 1280 // Replace with the desired width
|
||||
let height: Int32 = 720 // Replace with the desired height
|
||||
|
||||
let defaultFlags: UInt32 = SDL_WINDOW_SHOWN.rawValue
|
||||
let fullscreenFlag: UInt32 = SDL_WINDOW_FULLSCREEN.rawValue // Or SDL_WINDOW_FULLSCREEN_DESKTOP if needed
|
||||
|
||||
// Create the SDL window
|
||||
sdlwin = SDL_CreateWindow(
|
||||
"Ryujinx",
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
defaultFlags | fullscreenFlag | getWindowFlags()
|
||||
)
|
||||
|
||||
// Check if we successfully retrieved the SDL window
|
||||
guard sdlwin != nil else {
|
||||
print("Error getting SDL window: \(String(cString: SDL_GetError()))")
|
||||
print("Error creating SDL window: \(String(cString: SDL_GetError()))")
|
||||
return
|
||||
}
|
||||
|
||||
print("SDL window retrieved successfully.")
|
||||
print("SDL window created 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)
|
||||
@ -65,7 +72,6 @@ class SDLView: UIView {
|
||||
|
||||
// Bring SDL window to the front
|
||||
SDL_RaiseWindow(sdlwin)
|
||||
}
|
||||
|
||||
print("SDL window positioned over SDLView.")
|
||||
}
|
||||
|
@ -7,13 +7,14 @@
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
import SDL2
|
||||
|
||||
struct SDLViewRepresentable: UIViewRepresentable {
|
||||
let configure: () -> Void
|
||||
let configure: (UInt32) -> Void
|
||||
func makeUIView(context: Context) -> SDLView {
|
||||
// Configure (start ryu) before initialsing SDLView so SDLView can get the SDL_Window from Ryu
|
||||
configure()
|
||||
let view = SDLView(frame: .zero)
|
||||
configure(SDL_GetWindowID(view.sdlwin))
|
||||
return view
|
||||
|
||||
}
|
||||
|
@ -185,7 +185,8 @@ namespace Ryujinx.Headless.SDL2
|
||||
FullscreenFlag = SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | GetWindowFlags());
|
||||
WindowHandle = SDL_GetWindowFromID(1);
|
||||
// WindowHandle = SDL_CreateWindow($"Ryujinx {Program.Version}{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}", SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(DisplayId), Width, Height, DefaultFlags | FullscreenFlag | GetWindowFlags());
|
||||
|
||||
if (WindowHandle == IntPtr.Zero)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user