forked from MeloNX/MeloNX
WIP: Message bridge
This commit is contained in:
parent
e924da52ec
commit
23be667c7b
@ -108,6 +108,10 @@
|
||||
"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib" = (
|
||||
CodeSignOnCopy,
|
||||
);
|
||||
"Dependencies/Dynamic Libraries/RyujinxBridge.framework" = (
|
||||
CodeSignOnCopy,
|
||||
RemoveHeadersOnCopy,
|
||||
);
|
||||
"Dependencies/Dynamic Libraries/RyujinxKeyboard.framework" = (
|
||||
CodeSignOnCopy,
|
||||
RemoveHeadersOnCopy,
|
||||
@ -169,6 +173,7 @@
|
||||
"Dependencies/Dynamic Libraries/libavutil.dylib",
|
||||
"Dependencies/Dynamic Libraries/libMoltenVK.dylib",
|
||||
"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib",
|
||||
"Dependencies/Dynamic Libraries/RyujinxBridge.framework",
|
||||
"Dependencies/Dynamic Libraries/RyujinxKeyboard.framework",
|
||||
Dependencies/XCFrameworks/libavcodec.xcframework,
|
||||
Dependencies/XCFrameworks/libavfilter.xcframework,
|
||||
@ -633,7 +638,7 @@
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = 95J8WZ4TN8;
|
||||
DEVELOPMENT_TEAM = D59DHVRS87;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
ENABLE_TESTABILITY = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@ -763,7 +768,7 @@
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.xitrix.MeloNX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/App/Core/Headers/Ryujinx-Header.h";
|
||||
@ -781,7 +786,7 @@
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = 95J8WZ4TN8;
|
||||
DEVELOPMENT_TEAM = D59DHVRS87;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@ -911,7 +916,7 @@
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.xitrix.MeloNX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/App/Core/Headers/Ryujinx-Header.h";
|
||||
|
Binary file not shown.
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "56EBE536-1F4C-4BCE-853B-D3E000BE57CD"
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "71A20387-E5D5-42A9-99A1-7D1B6BEB6A04"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "Yes"
|
||||
symbolName = "UIApplicationMain"
|
||||
moduleName = "">
|
||||
<Actions>
|
||||
<BreakpointActionProxy
|
||||
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
|
||||
<ActionContent
|
||||
consoleCommand = "process handle SIGUSR1 -n true -p true -s false">
|
||||
</ActionContent>
|
||||
</BreakpointActionProxy>
|
||||
</Actions>
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "71A20387-E5D5-42A9-99A1-7D1B6BEB6A04 - dc2f8c5e001177f0"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "UIApplicationMain"
|
||||
moduleName = "UIKitCore"
|
||||
usesParentBreakpointCondition = "Yes">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "2A095BA1-FC06-4890-9989-2C4A83A0F028"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "Yes"
|
||||
symbolName = "UIApplicationMain"
|
||||
moduleName = "">
|
||||
<Actions>
|
||||
<BreakpointActionProxy
|
||||
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
|
||||
<ActionContent
|
||||
consoleCommand = "process handle SIGBUS -n true -p true -s false">
|
||||
</ActionContent>
|
||||
</BreakpointActionProxy>
|
||||
</Actions>
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "2A095BA1-FC06-4890-9989-2C4A83A0F028 - dc2f8c5e001177f0"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "UIApplicationMain"
|
||||
moduleName = "UIKitCore"
|
||||
usesParentBreakpointCondition = "Yes">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "A363121B-631E-4ADE-8A05-D3D9538EE31D"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeloNX/App/Core/Ryujinx/RyujinxBridge.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "43"
|
||||
endingLineNumber = "43"
|
||||
landmarkName = "parseMessage(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "482C1F2E-138F-49D2-A590-8B98AC9B790E"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeloNX/App/Core/Ryujinx/RyujinxBridge.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "32"
|
||||
endingLineNumber = "32"
|
||||
landmarkName = "parseMessage(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "FF32B294-2681-4A6E-9DFA-0D13DA242EAF"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeloNX/App/Core/Ryujinx/RyujinxBridge.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "30"
|
||||
endingLineNumber = "30"
|
||||
landmarkName = "parseMessage(_:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>MeloNX.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Ryujinx.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>2</integer>
|
||||
</dict>
|
||||
<key>com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
@ -8,6 +8,7 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import GameController
|
||||
import RyujinxBridge
|
||||
|
||||
struct Controller: Identifiable, Hashable {
|
||||
var id: String
|
||||
@ -49,6 +50,13 @@ class Ryujinx {
|
||||
static let shared = Ryujinx()
|
||||
|
||||
private init() {
|
||||
messageDelegate = { messagePtr in
|
||||
guard let messagePtr else { return }
|
||||
let message = String(cString: messagePtr)
|
||||
RyujinxBridgeHelper.parseMessage(message)
|
||||
print("Message: \(message)")
|
||||
}
|
||||
|
||||
self.games = loadGames()
|
||||
}
|
||||
|
||||
@ -513,7 +521,6 @@ class Ryujinx {
|
||||
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")
|
||||
|
45
src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift
Normal file
45
src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// RyujinxBridge.swift
|
||||
// MeloNX
|
||||
//
|
||||
// Created by Daniil Vinogradov on 17/02/2025.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
struct BridgeAlertMessage: Codable {
|
||||
var title: String?
|
||||
var type: String?
|
||||
var metadata: String?
|
||||
}
|
||||
|
||||
struct BridgePayload<T> {
|
||||
var type: String
|
||||
var model: T
|
||||
}
|
||||
|
||||
enum RyujinxBridgeHelper {
|
||||
static func parseMessage(_ message: String) {
|
||||
guard let data = message.data(using: .utf8),
|
||||
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
||||
let type = json["type"] as? String,
|
||||
let model = json["model"],
|
||||
let modelData = try? JSONSerialization.data(withJSONObject: model)
|
||||
else { return }
|
||||
|
||||
switch type {
|
||||
case "BridgeAlertMessage":
|
||||
guard let model = try? JSONDecoder().decode(BridgeAlertMessage.self, from: modelData)
|
||||
else { return }
|
||||
|
||||
DispatchQueue.main.async {
|
||||
// let alertVC = UIAlertController(title: model.title, message: model.type, preferredStyle: .alert)
|
||||
// alertVC.addAction(.init(title: "OK", style: .cancel))
|
||||
print("ALERT!!!! \(model.title) \(model.type) \(model.metadata)")
|
||||
// UIApplication.shared.windows.first?.rootViewController?.present(alertVC, animated: true)
|
||||
}
|
||||
default: break
|
||||
}
|
||||
print("Type: \(type)")
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SwiftSVG
|
||||
//import SwiftSVG
|
||||
|
||||
struct SettingsView: View {
|
||||
@Binding var config: Ryujinx.Configuration
|
||||
@ -439,36 +439,42 @@ struct SettingsView: View {
|
||||
}
|
||||
.tint(.blue)
|
||||
|
||||
if #available(iOS 17.0.1, *) {
|
||||
Toggle(isOn: $jitStreamerEB) {
|
||||
labelWithIcon("JitStreamer EB", iconName: "bolt.heart")
|
||||
}
|
||||
.tint(.blue)
|
||||
.contextMenu {
|
||||
Button {
|
||||
if let mainWindow = UIApplication.shared.windows.last {
|
||||
let alertController = UIAlertController(title: "About JitStreamer EB", message: "JitStreamer EB is an Amazing Application to Enable JIT on the go, made by one of the best iOS developers of all time jkcoxson <3", preferredStyle: .alert)
|
||||
|
||||
let learnMoreButton = UIAlertAction(title: "Learn More", style: .default) {_ in
|
||||
UIApplication.shared.open(URL(string: "https://jkcoxson.com/jitstreamer")!)
|
||||
}
|
||||
alertController.addAction(learnMoreButton)
|
||||
|
||||
let doneButton = UIAlertAction(title: "Done", style: .cancel, handler: nil)
|
||||
alertController.addAction(doneButton)
|
||||
|
||||
mainWindow.rootViewController?.present(alertController, animated: true)
|
||||
}
|
||||
} label: {
|
||||
Text("About")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if #available(iOS 17.0.1, *) {
|
||||
// Toggle(isOn: $jitStreamerEB) {
|
||||
// labelWithIcon("JitStreamer EB", iconName: "bolt.heart")
|
||||
// }
|
||||
// .tint(.blue)
|
||||
// .contextMenu {
|
||||
// Button {
|
||||
// if let mainWindow = UIApplication.shared.windows.last {
|
||||
// let alertController = UIAlertController(title: "About JitStreamer EB", message: "JitStreamer EB is an Amazing Application to Enable JIT on the go, made by one of the best iOS developers of all time jkcoxson <3", preferredStyle: .alert)
|
||||
//
|
||||
// let learnMoreButton = UIAlertAction(title: "Learn More", style: .default) {_ in
|
||||
// UIApplication.shared.open(URL(string: "https://jkcoxson.com/jitstreamer")!)
|
||||
// }
|
||||
// alertController.addAction(learnMoreButton)
|
||||
//
|
||||
// let doneButton = UIAlertAction(title: "Done", style: .cancel, handler: nil)
|
||||
// alertController.addAction(doneButton)
|
||||
//
|
||||
// mainWindow.rootViewController?.present(alertController, animated: true)
|
||||
// }
|
||||
// } label: {
|
||||
// Text("About")
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
Toggle(isOn: $useTrollStore) {
|
||||
labelWithIcon("TrollStore JIT", iconName: "troll.svg")
|
||||
HStack(spacing: 8) {
|
||||
Image("troll")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.foregroundStyle(.blue)
|
||||
Text("TrollStore JIT")
|
||||
}
|
||||
.font(.body)
|
||||
}
|
||||
.tint(.blue)
|
||||
}
|
||||
// }
|
||||
|
||||
Toggle(isOn: $syncqsubmits) {
|
||||
labelWithIcon("MVK: Synchronous Queue Submits", iconName: "line.diagonal")
|
||||
@ -695,56 +701,11 @@ struct SettingsView: View {
|
||||
@ViewBuilder
|
||||
private func labelWithIcon(_ text: String, iconName: String, flipimage: Bool? = nil) -> some View {
|
||||
HStack(spacing: 8) {
|
||||
if iconName.hasSuffix(".svg"){
|
||||
if let flipimage, flipimage {
|
||||
SVGView(svgName: iconName, color: .blue)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 20, height: 20)
|
||||
.rotation3DEffect(.degrees(180), axis: (x: 0, y: 1, z: 0))
|
||||
} else {
|
||||
SVGView(svgName: iconName, color: .blue)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.frame(width: 20, height: 20)
|
||||
}
|
||||
} else if !iconName.isEmpty {
|
||||
Image(systemName: iconName)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.foregroundStyle(.blue)
|
||||
}
|
||||
Image(systemName: iconName)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.foregroundStyle(.blue)
|
||||
Text(text)
|
||||
}
|
||||
.font(.body)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct SVGView: UIViewRepresentable {
|
||||
var svgName: String
|
||||
var color: Color = Color.black
|
||||
|
||||
func makeUIView(context: Context) -> UIView {
|
||||
var svgName = svgName
|
||||
var hammock = UIView()
|
||||
|
||||
if svgName.hasSuffix(".svg") {
|
||||
svgName.removeLast(4)
|
||||
}
|
||||
|
||||
|
||||
|
||||
let svgLayer = UIView(SVGNamed: svgName) { svgLayer in
|
||||
svgLayer.fillColor = UIColor(color).cgColor // Apply the provided color
|
||||
svgLayer.resizeToFit(hammock.frame)
|
||||
hammock.layer.addSublayer(svgLayer)
|
||||
}
|
||||
|
||||
return hammock
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UIView, context: Context) {
|
||||
// Update the SVG view's fill color when the color changes
|
||||
if let svgLayer = uiView.layer.sublayers?.first as? CAShapeLayer {
|
||||
svgLayer.fillColor = UIColor(color).cgColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json
vendored
Normal file
12
src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Troll-Face.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
16
src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg
vendored
Normal file
16
src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,18 @@
|
||||
//
|
||||
// RyujinxBridge.h
|
||||
// RyujinxBridge
|
||||
//
|
||||
// Created by Daniil Vinogradov on 17/02/2025.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for RyujinxBridge.
|
||||
FOUNDATION_EXPORT double RyujinxBridgeVersionNumber;
|
||||
|
||||
//! Project version string for RyujinxBridge.
|
||||
FOUNDATION_EXPORT const unsigned char RyujinxBridgeVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <RyujinxBridge/PublicHeader.h>
|
||||
#import <RyujinxBridge/bridge.h>
|
||||
|
@ -0,0 +1,8 @@
|
||||
//
|
||||
// bridge.h
|
||||
// RyujinxBridge
|
||||
//
|
||||
// Created by Daniil Vinogradov on 17/02/2025.
|
||||
//
|
||||
|
||||
void (*messageDelegate)(const char*);
|
Binary file not shown.
@ -0,0 +1,6 @@
|
||||
framework module RyujinxBridge {
|
||||
umbrella header "RyujinxBridge.h"
|
||||
export *
|
||||
|
||||
module * { export * }
|
||||
}
|
Binary file not shown.
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Headers/RyujinxBridge.h</key>
|
||||
<data>
|
||||
DKD2r8aJ47TZL7v48UVEfod716g=
|
||||
</data>
|
||||
<key>Headers/bridge.h</key>
|
||||
<data>
|
||||
p75HJMB/G5CAZ+yTApMWmoQP7Lg=
|
||||
</data>
|
||||
<key>Info.plist</key>
|
||||
<data>
|
||||
mWbK0knhX+Q4WAm+hZd8SF0ioS0=
|
||||
</data>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<data>
|
||||
+to1dvHz+3pPZcmBu4qsYsrvt4Y=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Headers/RyujinxBridge.h</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
xIPdWru4HW7sRYRg6G+ehIk9V4nX3Uv7kIlE2c/TnjM=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Headers/bridge.h</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
kA+OGSf2EzopJ1KM/+Lp8qHheuFQQYlkkOdMg/ywzH8=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
ZTC6KjLczI++298LFW6y9c8aoPQ1LrrsJrDJfrPnZUU=
|
||||
</data>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.kernel.increased-debugging-memory-limit</key>
|
||||
<true/>
|
||||
<key>com.apple.developer.kernel.increased-memory-limit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
41
src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs
Normal file
41
src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Headless.SDL2
|
||||
{
|
||||
struct BridgeAlertMessage(string title, string message, string metadata = null)
|
||||
{
|
||||
[JsonProperty("title")]
|
||||
string Title { get; set; } = title;
|
||||
|
||||
[JsonProperty("message")]
|
||||
string Message { get; set; } = message;
|
||||
|
||||
[JsonProperty("metadata")]
|
||||
string Metadata { get; set; } = metadata;
|
||||
}
|
||||
|
||||
public static class MessageBridge
|
||||
{
|
||||
[DllImport("RyujinxBridge.framework/RyujinxBridge", CallingConvention = CallingConvention.Cdecl, EntryPoint="sendMessage")]
|
||||
private static extern void SendMessage(string json);
|
||||
|
||||
public static void SendPayload<T>(T model)
|
||||
{
|
||||
string jsonString = JsonConvert.SerializeObject(new BridgePayload<T>(typeof(T).Name, model));
|
||||
SendMessage(jsonString);
|
||||
}
|
||||
}
|
||||
|
||||
public struct BridgePayload<T>(string type, T model)
|
||||
{
|
||||
[JsonProperty("type")]
|
||||
private string Type { get; set; } = type;
|
||||
|
||||
[JsonProperty("model")]
|
||||
private T Model { get; set; } = model;
|
||||
}
|
||||
}
|
@ -37,7 +37,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
||||
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||
@ -85,6 +84,7 @@ using ARMeilleure.Translation;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Tools.FsSystem.NcaUtils;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using Newtonsoft.Json;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
@ -94,6 +94,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using SDL2;
|
||||
using JsonException = System.Text.Json.JsonException;
|
||||
|
||||
namespace Ryujinx.Headless.SDL2
|
||||
{
|
||||
@ -117,6 +118,13 @@ namespace Ryujinx.Headless.SDL2
|
||||
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
|
||||
// [UnmanagedCallersOnly(EntryPoint = "get_dlc_nca_list")]
|
||||
// public static unsafe void CDeclCombine(delegate* unmanaged[Cdecl]<void> combinator) =>
|
||||
// combinator(left, right);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void TestDelegate(int a, int b);
|
||||
|
||||
[UnmanagedCallersOnly(EntryPoint = "main_ryujinx_sdl")]
|
||||
public static unsafe int MainExternal(int argCount, IntPtr* pArgs)
|
||||
{
|
||||
@ -403,6 +411,8 @@ namespace Ryujinx.Headless.SDL2
|
||||
[UnmanagedCallersOnly(EntryPoint = "get_game_info")]
|
||||
public static GameInfoNative GetGameInfoNative(int descriptor, IntPtr extensionPtr)
|
||||
{
|
||||
MessageBridge.SendPayload(new BridgeAlertMessage("Text", "Alalallala"));
|
||||
|
||||
if (_virtualFileSystem == null) {
|
||||
_virtualFileSystem = VirtualFileSystem.CreateInstance();
|
||||
}
|
||||
|
@ -477,8 +477,8 @@ namespace Ryujinx.Headless.SDL2
|
||||
|
||||
public bool DisplayMessageDialog(string title, string message)
|
||||
{
|
||||
SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_INFORMATION, title, message, WindowHandle);
|
||||
|
||||
// SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_INFORMATION, title, message, WindowHandle);
|
||||
MessageBridge.SendPayload(new BridgeAlertMessage(title, message, "controllerApplet"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user