This commit is contained in:
stossy11 2024-11-01 15:56:05 +11:00
parent 56f47c4ede
commit d667178aa5
9 changed files with 143 additions and 25 deletions

View File

@ -389,11 +389,14 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
); );
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX; PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/Header/MeloNX-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
@ -437,11 +440,14 @@
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries", "$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
); );
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX; PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/Header/MeloNX-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };

View File

@ -15,8 +15,8 @@
filePath = "MeloNX/Core/Ryujinx.swift" filePath = "MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807" startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "117" startingLineNumber = "111"
endingLineNumber = "117" endingLineNumber = "111"
landmarkName = "startWithRunLoop(config:)" landmarkName = "startWithRunLoop(config:)"
landmarkType = "7"> landmarkType = "7">
<Actions> <Actions>
@ -40,8 +40,8 @@
filePath = "MeloNX/Core/Ryujinx.swift" filePath = "MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807" startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "126" startingLineNumber = "120"
endingLineNumber = "126" endingLineNumber = "120"
landmarkName = "startWithRunLoop(config:)" landmarkName = "startWithRunLoop(config:)"
landmarkType = "7"> landmarkType = "7">
<Actions> <Actions>

View File

@ -22,7 +22,22 @@ struct ContentView: View {
var body: some View { var body: some View {
ZStack { 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)]
)
showVirtualController(url: gameUrl, ryuconfig: config)
}
}
VStack { VStack {
Text("NX iOS") Text("NX iOS")
@ -50,15 +65,6 @@ struct ContentView: View {
if let gameUrl { if let gameUrl {
Button { Button {
emulationStarted = true emulationStarted = true
gameUrl.startAccessingSecurityScopedResource()
let config = RyujinxEmulator.Configuration(
inputPath: gameUrl.path,
mainThread: mainThread,
graphicsBackend: "Vulkan"
)
showVirtualController(url: gameUrl, ryuconfig: config)
} label: { } label: {
Text("Go!") Text("Go!")
} }
@ -86,9 +92,6 @@ func startEmulation(game: URL, config: RyujinxEmulator.Configuration) {
let config = config let config = config
// patchMakeKeyAndVisible() // patchMakeKeyAndVisible()
SDL_SetMainReady()
SDL_iPhoneSetEventPump(SDL_TRUE)
print(SDL_Init(SDL_INIT_VIDEO))
let window = SDL_CreateWindow("Ryujinx", Int32(SDL_WINDOWPOS_CENTERED_MASK), Int32(SDL_WINDOWPOS_CENTERED_MASK), 640, 480, SDL_WINDOW_SHOWN.rawValue | SDL_WINDOW_ALLOW_HIGHDPI.rawValue) let window = SDL_CreateWindow("Ryujinx", Int32(SDL_WINDOWPOS_CENTERED_MASK), Int32(SDL_WINDOWPOS_CENTERED_MASK), 640, 480, SDL_WINDOW_SHOWN.rawValue | SDL_WINDOW_ALLOW_HIGHDPI.rawValue)
if window == nil { if window == nil {

View File

@ -0,0 +1,22 @@
//
// Ryujinx.h
// MeloNX
//
// Created by Stossy11 on 1/11/2024.
//
#ifndef RyujinxSDL_h
#define RyujinxSDL_h
#ifdef __cplusplus
extern "C" {
#endif
// Declare the main_ryujinx_sdl function, matching the signature
int main_ryujinx_sdl(int argc, char **argv);
#ifdef __cplusplus
}
#endif
#endif /* RyujinxSDL_h */

View File

@ -8,12 +8,6 @@
import Foundation import Foundation
import SwiftUI import SwiftUI
// Create a bridging header for the C function
private let ryujinxMain: @convention(c) (Int32, UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>) -> Int32 = {
let sym = dlsym(dlopen("Ryujinx.Headless.SDL2.dylib", RTLD_NOW), "main_ryujinx_sdl")
return unsafeBitCast(sym, to: (@convention(c) (Int32, UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>) -> Int32).self)
}()
enum RyujinxError: Error { enum RyujinxError: Error {
case libraryLoadError case libraryLoadError
case executionError(code: Int32) case executionError(code: Int32)
@ -89,7 +83,7 @@ class RyujinxEmulator {
var argvPtrs = cArgs var argvPtrs = cArgs
let result = ryujinxMain(Int32(args.count), &argvPtrs) let result = main_ryujinx_sdl(Int32(args.count), &argvPtrs)
if result != 0 { if result != 0 {
throw RyujinxError.executionError(code: result) throw RyujinxError.executionError(code: result)

View File

@ -0,0 +1,8 @@
//
// MeloNX-Bridging-Header.h
// MeloNX
//
// Created by Stossy11 on 1/11/2024.
//
#import "../Core/Ryujinx.h"

View File

@ -8,6 +8,90 @@
import SwiftUI import SwiftUI
import Metal import Metal
import MetalKit import MetalKit
import UIKit
import SDL2
struct VulkanSDLViewRepresentable: UIViewRepresentable {
let configure: (Uint32) -> Void
func makeUIView(context: Context) -> VulkanSDLView {
let view = VulkanSDLView(frame: .zero)
configure(SDL_GetWindowID(view.sdlWindow))
return view
}
func updateUIView(_ uiView: VulkanSDLView, context: Context) {
// Handle any updates if needed
}
}
class VulkanSDLView: UIView {
var sdlWindow: OpaquePointer?
var metalView: UnsafeMutableRawPointer?
override init(frame: CGRect) {
super.init(frame: frame)
initializeSDL()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initializeSDL()
}
private func initializeSDL() {
SDL_SetMainReady()
SDL_iPhoneSetEventPump(SDL_TRUE)
// print(SDL_Init(SDL_INIT_VIDEO))
// Initialize SDL with video support
if SDL_Init(SDL_INIT_VIDEO) < 0 {
print("Unable to initialize SDL: \(String(cString: SDL_GetError()))")
return
}
// Create an SDL window with Metal support
sdlWindow = SDL_CreateWindow(
"Ryujinx",
Int32(SDL_WINDOWPOS_CENTERED_MASK),
Int32(SDL_WINDOWPOS_CENTERED_MASK),
Int32(frame.width),
Int32(frame.height),
SDL_WINDOW_SHOWN.rawValue | SDL_WINDOW_ALLOW_HIGHDPI.rawValue | SDL_WINDOW_METAL.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
}
if let metalLayerPointer = SDL_Metal_GetLayer(metalView) {
let metalLayer = Unmanaged<CAMetalLayer>.fromOpaque(metalLayerPointer).takeUnretainedValue()
metalLayer.device = MTLCreateSystemDefaultDevice()
metalLayer.pixelFormat = .bgra8Unorm
layer.addSublayer(metalLayer)
}
}
deinit {
if let metalView = metalView {
SDL_Metal_DestroyView(metalView)
}
if let sdlWindow = sdlWindow {
SDL_DestroyWindow(sdlWindow)
}
SDL_Quit()
}
}
struct MetalView: UIViewRepresentable { struct MetalView: UIViewRepresentable {
let device: MTLDevice? let device: MTLDevice?

View File

@ -185,7 +185,8 @@ namespace Ryujinx.Headless.SDL2
FullscreenFlag = SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP; 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);
//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) if (WindowHandle == IntPtr.Zero)
{ {