forked from MeloNX/MeloNX
Add new SwiftUI Emulation View
This commit is contained in:
parent
a2c3f6d624
commit
f57d24706b
@ -618,7 +618,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = 4TD3JXVDW7;
|
DEVELOPMENT_TEAM = 95J8WZ4TN8;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
ENABLE_TESTABILITY = NO;
|
ENABLE_TESTABILITY = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -628,6 +628,10 @@
|
|||||||
"$(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",
|
||||||
|
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||||
|
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||||
);
|
);
|
||||||
GCC_OPTIMIZATION_LEVEL = fast;
|
GCC_OPTIMIZATION_LEVEL = fast;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -659,9 +663,17 @@
|
|||||||
"$(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",
|
||||||
|
"$(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 = 0.0.8;
|
MARKETING_VERSION = 0.0.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = xyz.belladev.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/App/Core/Headers/Ryujinx-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/App/Core/Headers/Ryujinx-Header.h";
|
||||||
@ -679,7 +691,7 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = 4TD3JXVDW7;
|
DEVELOPMENT_TEAM = 95J8WZ4TN8;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -689,6 +701,10 @@
|
|||||||
"$(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",
|
||||||
|
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||||
|
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||||
);
|
);
|
||||||
GCC_OPTIMIZATION_LEVEL = fast;
|
GCC_OPTIMIZATION_LEVEL = fast;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@ -720,9 +736,17 @@
|
|||||||
"$(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",
|
||||||
|
"$(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 = 0.0.8;
|
MARKETING_VERSION = 0.0.8;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = xyz.belladev.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/App/Core/Headers/Ryujinx-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/App/Core/Headers/Ryujinx-Header.h";
|
||||||
|
Binary file not shown.
@ -12,12 +12,12 @@
|
|||||||
<key>Ryujinx.xcscheme_^#shared#^_</key>
|
<key>Ryujinx.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>2</integer>
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_</key>
|
<key>com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>1</integer>
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_syswm.h>
|
||||||
#import "utils.h"
|
#import "utils.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// VirtualController.swift
|
|
||||||
// MeloNX
|
|
||||||
//
|
|
||||||
// Created by Stossy11 on 28/11/2024.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import GameController
|
|
||||||
import UIKit
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
var hostingController: UIHostingController<ControllerView>? // Store reference to prevent deallocation
|
|
||||||
|
|
||||||
// Swts up a timer that adds subview to the Window and Repeats until the ControllerView is found in the Window to ensure that the controller shows.
|
|
||||||
func waitForController() {
|
|
||||||
guard let window = theWindow else { return }
|
|
||||||
|
|
||||||
// Function to search for an existing UIHostingController with ControllerView
|
|
||||||
func findGCControllerView(in view: UIView) -> UIHostingController<ControllerView>? {
|
|
||||||
if let hostingVC = view.next as? UIHostingController<ControllerView> {
|
|
||||||
return hostingVC
|
|
||||||
}
|
|
||||||
|
|
||||||
for subview in view.subviews {
|
|
||||||
if let found = findGCControllerView(in: subview) {
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let controllerView = ControllerView()
|
|
||||||
let newHostingController = UIHostingController(rootView: controllerView)
|
|
||||||
|
|
||||||
hostingController = newHostingController
|
|
||||||
|
|
||||||
let containerView = newHostingController.view!
|
|
||||||
containerView.backgroundColor = .clear
|
|
||||||
containerView.frame = window.bounds
|
|
||||||
containerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
||||||
|
|
||||||
// Timer for controller
|
|
||||||
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
|
|
||||||
if findGCControllerView(in: window) == nil {
|
|
||||||
// Adds Virtual Controller Subview
|
|
||||||
window.addSubview(containerView)
|
|
||||||
window.bringSubviewToFront(containerView)
|
|
||||||
|
|
||||||
if let sdlWindow = SDL_GetWindowFromID(1) {
|
|
||||||
SDL_SetWindowPosition(sdlWindow, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.invalidate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TransparentHostingContainerView: UIView {
|
|
||||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
||||||
// Check if the point is within the subviews of this container
|
|
||||||
let view = super.hitTest(point, with: event)
|
|
||||||
print(view)
|
|
||||||
|
|
||||||
// Return nil if the touch is outside visible content (passes through to views below)
|
|
||||||
return view === self ? nil : view
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,17 +17,11 @@ extension UIWindow {
|
|||||||
// Also waits for the window to append the on-screen controller
|
// Also waits for the window to append the on-screen controller
|
||||||
@objc func wdb_makeKeyAndVisible() {
|
@objc func wdb_makeKeyAndVisible() {
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
self.windowScene = (UIApplication.shared.connectedScenes.first! as! UIWindowScene)
|
// self.windowScene = (UIApplication.shared.connectedScenes.first! as! UIWindowScene)
|
||||||
}
|
}
|
||||||
self.wdb_makeKeyAndVisible()
|
self.wdb_makeKeyAndVisible()
|
||||||
theWindow = self
|
theWindow = self
|
||||||
|
Ryujinx.shared.repeatuntilfindLayer()
|
||||||
|
|
||||||
if UserDefaults.standard.bool(forKey: "isVirtualController") {
|
|
||||||
if let window = theWindow {
|
|
||||||
waitForController()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,12 @@ class Ryujinx {
|
|||||||
let virtualController = VirtualController()
|
let virtualController = VirtualController()
|
||||||
|
|
||||||
@Published var controllerMap: [Controller] = []
|
@Published var controllerMap: [Controller] = []
|
||||||
@State var firmwareversion = "0"
|
@Published var metalLayer: CAMetalLayer? = nil
|
||||||
|
@Published var firmwareversion = "0"
|
||||||
|
|
||||||
|
var shouldMetal: Bool {
|
||||||
|
metalLayer == nil
|
||||||
|
}
|
||||||
|
|
||||||
static let shared = Ryujinx()
|
static let shared = Ryujinx()
|
||||||
|
|
||||||
@ -400,6 +405,63 @@ class Ryujinx {
|
|||||||
print("Error removing folder: \(error)")
|
print("Error removing folder: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func repeatuntilfindLayer() {
|
||||||
|
DispatchQueue.global(qos: .background).async {
|
||||||
|
while self.metalLayer == nil {
|
||||||
|
let layer = self.getMetalLayer(nil)
|
||||||
|
|
||||||
|
if layer != nil {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.metalLayer = layer
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(forTimeInterval: 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func getMetalLayer(_ window: OpaquePointer?) -> CAMetalLayer? {
|
||||||
|
var window = window
|
||||||
|
if window == nil {
|
||||||
|
window = SDL_GetWindowFromID(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var windowInfo = SDL_SysWMinfo()
|
||||||
|
SDL_GetWindowWMInfo(window, &windowInfo)
|
||||||
|
|
||||||
|
|
||||||
|
guard let uiWindow = windowInfo.info.uikit.window,
|
||||||
|
let rootView = uiWindow.takeUnretainedValue().rootViewController?.view else {
|
||||||
|
print("Unable to get root view")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findMetalLayer(in view: UIView) -> CAMetalLayer? {
|
||||||
|
if let metalLayer = view.layer as? CAMetalLayer {
|
||||||
|
return metalLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
for subview in view.subviews {
|
||||||
|
if let metalLayer = findMetalLayer(in: subview) {
|
||||||
|
return metalLayer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let existingLayer = findMetalLayer(in: rootView) {
|
||||||
|
print("Found Metal Layer")
|
||||||
|
return existingLayer
|
||||||
|
}
|
||||||
|
print("found nothing")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ struct ContentView: View {
|
|||||||
// MARK: - Body
|
// MARK: - Body
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if game != nil, quits == false {
|
if game != nil, quits == false {
|
||||||
if isLoading {
|
if Ryujinx.shared.metalLayer == nil {
|
||||||
emulationView
|
emulationView
|
||||||
.onAppear() {
|
.onAppear() {
|
||||||
// This is fro the old exiting game feature that didn't work properly. will look into it and figure out a better alternative
|
// This is fro the old exiting game feature that didn't work properly. will look into it and figure out a better alternative
|
||||||
@ -93,12 +93,10 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is when the game starts to stop the animation
|
// This is when the game starts to stop the animation
|
||||||
VStack {
|
EmulationView()
|
||||||
|
.onAppear() {
|
||||||
}
|
isAnimating = false
|
||||||
.onAppear() {
|
}
|
||||||
isAnimating = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This is the main menu view that includes the Settings and the Game Selector
|
// This is the main menu view that includes the Settings and the Game Selector
|
||||||
@ -234,7 +232,7 @@ struct ContentView: View {
|
|||||||
private func initializeSDL() {
|
private func initializeSDL() {
|
||||||
setMoltenVKSettings()
|
setMoltenVKSettings()
|
||||||
SDL_SetMainReady() // Sets SDL Ready
|
SDL_SetMainReady() // Sets SDL Ready
|
||||||
SDL_iPhoneSetEventPump(SDL_TRUE) // Allow iOS Set Event Pump (Check out SDL2 Documentation here)
|
SDL_iPhoneSetEventPump(SDL_TRUE) // Set iOS Event Pump to true (Check out SDL2 Documentation here)
|
||||||
SDL_Init(SdlInitFlags) // Initialises SDL2
|
SDL_Init(SdlInitFlags) // Initialises SDL2
|
||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// EmulationView.swift
|
||||||
|
// MeloNX
|
||||||
|
//
|
||||||
|
// Created by Stossy11 on 09/02/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
// Emulation View
|
||||||
|
struct EmulationView: View {
|
||||||
|
@AppStorage("isVirtualController") var isVCA: Bool = true
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
MetalView() // The Emulation View
|
||||||
|
.ignoresSafeArea()
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
|
||||||
|
// Above Emulation View
|
||||||
|
|
||||||
|
if isVCA {
|
||||||
|
ControllerView() // Virtual Controller
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MetalView.swift
|
||||||
|
// MeloNX
|
||||||
|
//
|
||||||
|
// Created by Stossy11 on 09/02/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import MetalKit
|
||||||
|
|
||||||
|
struct MetalView: UIViewRepresentable {
|
||||||
|
|
||||||
|
func makeUIView(context: Context) -> UIView {
|
||||||
|
let view = UIView()
|
||||||
|
|
||||||
|
let metalLayer = Ryujinx.shared.metalLayer!
|
||||||
|
metalLayer.frame = view.bounds
|
||||||
|
view.contentScaleFactor = metalLayer.contentsScale // Right size and Fix Touch :3
|
||||||
|
view.layer.addSublayer(metalLayer)
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIView(_ uiView: UIView, context: Context) {
|
||||||
|
// nothin
|
||||||
|
}
|
||||||
|
}
|
@ -9,15 +9,15 @@
|
|||||||
<key>UTExportedTypeDeclarations</key>
|
<key>UTExportedTypeDeclarations</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
<key>UTTypeIdentifier</key>
|
|
||||||
<string>com.nintendo.switch-package</string>
|
|
||||||
<key>UTTypeDescription</key>
|
|
||||||
<string>Nintendo Switch Package</string>
|
|
||||||
<key>UTTypeConformsTo</key>
|
<key>UTTypeConformsTo</key>
|
||||||
<array>
|
<array>
|
||||||
<string>public.data</string>
|
<string>public.data</string>
|
||||||
<string>public.archive</string>
|
<string>public.archive</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Switch Package</string>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.nintendo.switch-package</string>
|
||||||
<key>UTTypeTagSpecification</key>
|
<key>UTTypeTagSpecification</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>public.filename-extension</key>
|
<key>public.filename-extension</key>
|
||||||
@ -29,15 +29,15 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>UTTypeIdentifier</key>
|
|
||||||
<string>com.nintendo.switch-cartridge</string>
|
|
||||||
<key>UTTypeDescription</key>
|
|
||||||
<string>Nintendo Switch Cartridge</string>
|
|
||||||
<key>UTTypeConformsTo</key>
|
<key>UTTypeConformsTo</key>
|
||||||
<array>
|
<array>
|
||||||
<string>public.data</string>
|
<string>public.data</string>
|
||||||
<string>public.archive</string>
|
<string>public.archive</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UTTypeDescription</key>
|
||||||
|
<string>Nintendo Switch Cartridge</string>
|
||||||
|
<key>UTTypeIdentifier</key>
|
||||||
|
<string>com.nintendo.switch-cartridge</string>
|
||||||
<key>UTTypeTagSpecification</key>
|
<key>UTTypeTagSpecification</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>public.filename-extension</key>
|
<key>public.filename-extension</key>
|
||||||
|
@ -21,7 +21,7 @@ struct MeloNXApp: App {
|
|||||||
if bool {
|
if bool {
|
||||||
print("Ryujinx Files Initialized Successfully")
|
print("Ryujinx Files Initialized Successfully")
|
||||||
} else {
|
} else {
|
||||||
exit(0)
|
// exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ struct MeloNXApp: App {
|
|||||||
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
|
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
|
||||||
InitializeRyujinx() { bool in
|
InitializeRyujinx() { bool in
|
||||||
if !bool {
|
if !bool {
|
||||||
exit(0)
|
// exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -144,8 +144,9 @@ func InitializeRyujinx(completion: @escaping (Bool) -> Void) {
|
|||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
let task = URLSession.shared.dataTask(with: URL(string: addFolders(path)!)!) { data, _, _ in
|
let task = URLSession.shared.dataTask(with: URL(string: addFolders(path)!)!) { data, response, error in
|
||||||
let text = String(data: data ?? Data(), encoding: .utf8) ?? ""
|
let text = String(data: data ?? Data(), encoding: .utf8) ?? ""
|
||||||
|
print(text)
|
||||||
completion(text.contains("true"))
|
completion(text.contains("true"))
|
||||||
}
|
}
|
||||||
task.resume()
|
task.resume()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user