From 23be667c7b19340e495aade6feed6f9a3396b8b6 Mon Sep 17 00:00:00 2001 From: Daniil Vinogradov Date: Sat, 1 Mar 2025 11:26:18 +0100 Subject: [PATCH] WIP: Message bridge --- src/MeloNX/MeloNX.xcodeproj/project.pbxproj | 13 +- .../UserInterfaceState.xcuserstate | Bin 0 -> 135824 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 116 +++++++++++++++ .../xcschemes/xcschememanagement.plist | 24 ++++ .../MeloNX/App/Core/Ryujinx/Ryujinx.swift | 9 +- .../App/Core/Ryujinx/RyujinxBridge.swift | 45 ++++++ .../App/Views/SettingsView/SettingsView.swift | 113 +++++---------- .../troll.imageset/Contents.json | 12 ++ .../troll.imageset/Troll-Face.svg | 16 +++ .../Headers/RyujinxBridge.h | 18 +++ .../RyujinxBridge.framework/Headers/bridge.h | 8 ++ .../RyujinxBridge.framework/Info.plist | Bin 0 -> 755 bytes .../Modules/module.modulemap | 6 + .../RyujinxBridge.framework/RyujinxBridge | Bin 0 -> 52864 bytes .../_CodeSignature/CodeResources | 135 ++++++++++++++++++ src/MeloNX/MeloNX/MeloNX.entitlements | 2 + .../MessageBridge-iOS.cs | 41 ++++++ src/Ryujinx.Headless.SDL2/Program.cs | 12 +- src/Ryujinx.Headless.SDL2/WindowBase.cs | 4 +- 19 files changed, 490 insertions(+), 84 deletions(-) create mode 100644 src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/daniilvinogradov.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 src/MeloNX/MeloNX.xcodeproj/xcuserdata/daniilvinogradov.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 src/MeloNX/MeloNX.xcodeproj/xcuserdata/daniilvinogradov.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift create mode 100644 src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json create mode 100644 src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg create mode 100644 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/RyujinxBridge.h create mode 100644 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/bridge.h create mode 100644 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Info.plist create mode 100644 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Modules/module.modulemap create mode 100755 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/RyujinxBridge create mode 100644 src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/_CodeSignature/CodeResources create mode 100644 src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj index 567e8252e..1066d412b 100644 --- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj +++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj @@ -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"; diff --git a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/daniilvinogradov.xcuserdatad/UserInterfaceState.xcuserstate b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/daniilvinogradov.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..5faef418f60b943f1298de212618e5fe5b254fe1 GIT binary patch literal 135824 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/MeloNX/MeloNX.xcodeproj/xcuserdata/daniilvinogradov.xcuserdatad/xcschemes/xcschememanagement.plist b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/daniilvinogradov.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 000000000..91a670474 --- /dev/null +++ b/src/MeloNX/MeloNX.xcodeproj/xcuserdata/daniilvinogradov.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,24 @@ + + + + + SchemeUserState + + MeloNX.xcscheme_^#shared#^_ + + orderHint + 0 + + Ryujinx.xcscheme_^#shared#^_ + + orderHint + 2 + + com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_ + + orderHint + 1 + + + + diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift index bd09f1b74..da4f73c3b 100644 --- a/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift +++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/Ryujinx.swift @@ -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") diff --git a/src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift b/src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift new file mode 100644 index 000000000..b2a5d640f --- /dev/null +++ b/src/MeloNX/MeloNX/App/Core/Ryujinx/RyujinxBridge.swift @@ -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 { + 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)") + } +} diff --git a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift index 2b6ca4f19..cc83ca518 100644 --- a/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift +++ b/src/MeloNX/MeloNX/App/Views/SettingsView/SettingsView.swift @@ -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 - } - } -} diff --git a/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json b/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json new file mode 100644 index 000000000..52f67def1 --- /dev/null +++ b/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Troll-Face.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg b/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg new file mode 100644 index 000000000..e3b3f7785 --- /dev/null +++ b/src/MeloNX/MeloNX/Assets/Assets.xcassets/troll.imageset/Troll-Face.svg @@ -0,0 +1,16 @@ + + .str0 {stroke:black;stroke-width:0.238063} + .fil0 {fill:black} + .fil2 {fill:#050707} + .fil3 {fill:#881846} + .fil5 {fill:#F6BCD6} + .fil1 {fill:#F9DD56} + .fil4 {fill:#FDFCFD} + + + + + Layer 1 + + image/svg+xmlOpenclipartTrollface2011-04-03T12:59:21http://encyclopediadramatica.com/Trollfacehttps://openclipart.org/detail/130795/trollface-by-ronesronesfacememetrolltrollface + \ No newline at end of file diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/RyujinxBridge.h b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/RyujinxBridge.h new file mode 100644 index 000000000..545a63aeb --- /dev/null +++ b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/RyujinxBridge.h @@ -0,0 +1,18 @@ +// +// RyujinxBridge.h +// RyujinxBridge +// +// Created by Daniil Vinogradov on 17/02/2025. +// + +#import + +//! 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 +#import + diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/bridge.h b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/bridge.h new file mode 100644 index 000000000..4248a16c7 --- /dev/null +++ b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Headers/bridge.h @@ -0,0 +1,8 @@ +// +// bridge.h +// RyujinxBridge +// +// Created by Daniil Vinogradov on 17/02/2025. +// + +void (*messageDelegate)(const char*); diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Info.plist b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..61bc1974564b1f1f6d7c75b9fb6a43a99cbd2975 GIT binary patch literal 755 zcmY*W%Wl&^6!i>HN-2%o5So^jzIYc|wn;4(u!&8iC=E?xrwu5?Ozep>bo{6vRU+UA z*zo}@%9;&7zz?uO>K=(d-~*6w5?d*=IrrRi&gjmajz>ul^87D02jGQ^m!>XHUzxc& zdu=Ym&M#!I=WZ3hW{VM_W)&Gd;@~}X#B_E^E)^rk zq*%cxn7W>gov@BA;yOCJkZRBS*oZ>Zq4-?0Y{pj7CD_;5)zn#bx~@WuFwP@?aDe?F zu3D-30@?8m*_76hafB?a4ZOI!oOaco>xW5F4SnKR=f%kLVi}t?io&kz+kwtz(qs~P zrD(EidxQ=r%P3lE9lf|c;p1uMCyhy7RVpL*OGS&zq47}BnucrQR)Wd;*eY>|9oc(o z5^guj@g|9ZOUNd4ptCEDavdK>#K-1XkdcQvgp!cppdl6%iLYblb$t-MB~HKS6Vr;f zkvCkM>y!BTeeOR=l{j82RSzqw!11TInxxiqhu^s`=}-jw&d}6*a-iIGyWkBt0ulHCK7!BSEBFC^f-~?N{DlBc!5KIUb8rzp eg)-cQ`>+iSNTCalVE`j$bRZZb^C-at;Jbgw(C4H8 literal 0 HcmV?d00001 diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Modules/module.modulemap b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Modules/module.modulemap new file mode 100644 index 000000000..0373427d1 --- /dev/null +++ b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module RyujinxBridge { + umbrella header "RyujinxBridge.h" + export * + + module * { export * } +} diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/RyujinxBridge b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/RyujinxBridge.framework/RyujinxBridge new file mode 100755 index 0000000000000000000000000000000000000000..a2fdd7864f9334d42d82f9e3f6d2844dcdf0558c GIT binary patch literal 52864 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 + + + + files + + Headers/RyujinxBridge.h + + DKD2r8aJ47TZL7v48UVEfod716g= + + Headers/bridge.h + + p75HJMB/G5CAZ+yTApMWmoQP7Lg= + + Info.plist + + mWbK0knhX+Q4WAm+hZd8SF0ioS0= + + Modules/module.modulemap + + +to1dvHz+3pPZcmBu4qsYsrvt4Y= + + + files2 + + Headers/RyujinxBridge.h + + hash2 + + xIPdWru4HW7sRYRg6G+ehIk9V4nX3Uv7kIlE2c/TnjM= + + + Headers/bridge.h + + hash2 + + kA+OGSf2EzopJ1KM/+Lp8qHheuFQQYlkkOdMg/ywzH8= + + + Modules/module.modulemap + + hash2 + + ZTC6KjLczI++298LFW6y9c8aoPQ1LrrsJrDJfrPnZUU= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/src/MeloNX/MeloNX/MeloNX.entitlements b/src/MeloNX/MeloNX/MeloNX.entitlements index 99f471672..8f5046f7d 100644 --- a/src/MeloNX/MeloNX/MeloNX.entitlements +++ b/src/MeloNX/MeloNX/MeloNX.entitlements @@ -2,6 +2,8 @@ + com.apple.developer.kernel.increased-debugging-memory-limit + com.apple.developer.kernel.increased-memory-limit diff --git a/src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs b/src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs new file mode 100644 index 000000000..32a247b7a --- /dev/null +++ b/src/Ryujinx.Headless.SDL2/MessageBridge-iOS.cs @@ -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 model) + { + string jsonString = JsonConvert.SerializeObject(new BridgePayload(typeof(T).Name, model)); + SendMessage(jsonString); + } + } + + public struct BridgePayload(string type, T model) + { + [JsonProperty("type")] + private string Type { get; set; } = type; + + [JsonProperty("model")] + private T Model { get; set; } = model; + } +} diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 3fd96ecef..db6c3e344 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -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] 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(); } diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs index 13c18ac8f..6d94fe6fa 100644 --- a/src/Ryujinx.Headless.SDL2/WindowBase.cs +++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs @@ -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; }