1
0
forked from MeloNX/MeloNX

Compare commits

..

22 Commits

Author SHA1 Message Date
stossy11
18b9baa943 Let Ryujinx make the window 2024-11-02 22:33:54 +11:00
stossy11
02901a5a14 Put everything on the main thread for testing. 2024-11-02 12:37:08 +11:00
stossy11
60cfb86774 Make SDL Init on the Main Thread 2024-11-02 11:42:28 +11:00
stossy11
f632f16449 Fix 2024-11-02 08:51:53 +11:00
stossy11
d667178aa5 new code 2024-11-01 15:56:05 +11:00
stossy11
56f47c4ede Push changes (idk) 2024-10-31 01:30:35 +11:00
stossy11
5511d1885c Creating an SDLWindow in swift just makes it magically work 2024-10-30 22:25:15 +11:00
Tech Guy
16a2c8a463
Update README.md 2024-10-30 10:54:56 +00:00
Tech Guy
a520db39d0
Update Logo 2024-10-28 11:46:11 +00:00
Tech Guy
a32424f3a3
Update README.md
Remove discord
2024-10-28 06:49:40 +00:00
Tech Guy
0302e7c2ca
Update README.md 2024-10-28 06:49:20 +00:00
Tech Guy
2775841321
Update README.md 2024-10-28 06:47:19 +00:00
Tech Guy
f4f42dbf41
Update README.md 2024-10-28 06:45:30 +00:00
Tech Guy
57583a333b
Update README.md 2024-10-28 06:42:10 +00:00
Tech Guy
32c21d92a2
Update README.md 2024-10-28 06:40:58 +00:00
Tech Guy
ff25ab666f
Update README.md 2024-10-28 06:39:09 +00:00
stossy11
748236311d pushed idk 2024-10-28 17:07:05 +11:00
stossy11
b41251e360 cool 2024-10-28 10:22:25 +11:00
Tech Guy
ac3958a363
Update README.md 2024-10-27 16:07:48 +00:00
stossy11
f85b49d33b Add iOS Project (again) 2024-10-27 20:47:00 +11:00
stossy11
9d6ae7d35b Revert "Add iOS XcodeProject"
This reverts commit 68a126a9dcbc9cc57c5dc01715e116a798ae775c.
2024-10-27 20:45:59 +11:00
stossy11
68a126a9dc Add iOS XcodeProject 2024-10-27 20:31:25 +11:00
726 changed files with 2341 additions and 102715 deletions

View File

@ -1,21 +0,0 @@
name: Notify API on Release
on:
release:
types: [published]
jobs:
notify-api:
runs-on: debian-trixie
steps:
- name: Send API Call for New Release
run: |
curl -X POST http://melonx.org/api/new_release \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${{ secrets.MELONX_GITEA_API_KEY }}" \
-d '{
"version_number": "${{ github.event.release.tag_name }}",
"download_link": "${{ github.event.release.html_url }}",
"changelog": "${{ github.event.release.body }}",
"is_latest": true
}'

4
.gitignore vendored
View File

@ -10,8 +10,6 @@
# Build results # Build results
dotnet.xcconfig
[Dd]ebug/ [Dd]ebug/
[Rr]elease/ [Rr]elease/
x64/ x64/
@ -175,4 +173,4 @@ PublishProfiles/
# Glade backup files # Glade backup files
*.glade~ *.glade~
src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib MeloNX-XC/MeloNX/Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib

View File

@ -1,72 +0,0 @@
# Compiling MeloNX on macOS
## Prerequisites
Before you begin, ensure you have the following installed:
- [**.NET 8.0**](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
- A Mac running **macOS**
## Compilation Steps
### 1. Clone the Repository and Build Ryujinx
Open a terminal and run:
```sh
git clone https://git.743378673.xyz/MeloNX/MeloNX.git
cd MeloNX
./compile.sh
```
You may need to run this command if compilation fails, then run the `./compile.sh` command again (You will need to put in your user password. Your password will not be shown at all.)
```
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
```
However, if you only need to update MeloNX, make sure you have cd into the directory then run this then skip to step 5
```
git pull
./compile.sh
```
### 2. Open the Xcode Project
Navigate to the **Xcode project file** located at:
```
src/MeloNX/MeloNX.xcodeproj
```
Double-click to open it in **Xcode**.
### 3. Configure the Project Settings
- In **Xcode**, select the **MeloNX** project.
- Under the **General** tab, find `Ryujinx.Headless.SDL2.dylib`.
- Set its **Embed setting** to **"Embed & Sign"**.
### 4. Configure Signing & Capabilities
- In **Xcode**, go to **Signing & Capabilities**.
- Set the **Team** to your **Apple Developer account** (free or paid).
- Change the **Bundle Identifier** to:
```
com.<your-name>.MeloNX
```
*(Replace `<your-name>` with your actual name or identifier.)*
### 5. Connect Your Device
Ensure your **iPhone/iPad** is **connected** and **recognized** in Xcode.
### 6. Build and Run
Click the **Run (▶️) button** in Xcode to compile and launch MeloNX.
---
Now you're all set! 🚀 If you encounter issues, please join the discord at https://melonx.org
```

View File

@ -33,15 +33,15 @@
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.1" /> <PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.1" />
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" /> <PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.3" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" /> <PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.28.1-build28" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />
<PackageVersion Include="SixLabors.ImageSharp" Version="1.0.4" /> <PackageVersion Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" /> <PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" /> <PackageVersion Include="SPB" Version="0.0.4-build28" />

View File

@ -1,15 +1,9 @@
MeloNX License MIT License
Copyright (c) MeloNX Team and Contributors Copyright (c) Ryujinx Team and Contributors
Permission is hereby granted, free of charge, to any person (except anyone who has previously attempted or is currently attempting to merge MeloNX with Pomelo) obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. Every file is under this license, and all copies must be redistributed under the same license. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Anyone who attempts or has attempted to merge MeloNX with Pomelo, or otherwise use this source code in conjunction with Pomelo, is prohibited from using, copying, modifying, or distributing the source code without first obtaining explicit, written permission from Stossy11.
Additionally, the names of the developers or contributors to this project may not be used to endorse or promote products derived from this software without specific, prior written permission from the respective developer(s).
Ryujinx is licensed under the MIT License. Copyright (c) Ryujinx contributors. All rights to Ryujinx are held by its respective copyright holders, and its use is subject to the terms of the MIT License.

View File

@ -0,0 +1,499 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 77;
objects = {
/* Begin PBXBuildFile section */
4E87E2F32CCE315100F54325 /* SDL in Frameworks */ = {isa = PBXBuildFile; productRef = 4E87E2F22CCE315100F54325 /* SDL */; };
4E87E2F62CCE33B500F54325 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E87E2F52CCE33B500F54325 /* GameController.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
4E87E2CA2CCE2D8E00F54325 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
4E87E28C2CCE2C1000F54325 /* MeloNX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeloNX.app; sourceTree = BUILT_PRODUCTS_DIR; };
4E87E2F52CCE33B500F54325 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
4E87E3022CCE3E0700F54325 /* Exceptions for "MeloNX" folder in "MeloNX" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 4E87E28B2CCE2C1000F54325 /* MeloNX */;
};
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */
4E87E2CB2CCE2D8E00F54325 /* Exceptions for "MeloNX" folder in "Embed Frameworks" phase from "MeloNX" target */ = {
isa = PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet;
attributesByRelativePath = {
"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib" = (CodeSignOnCopy, );
"Dependencies/Dynamic Libraries/libMoltenVK.dylib" = (CodeSignOnCopy, );
Dependencies/XCFrameworks/MoltenVK.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/SDL2.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_Globalization_Native.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_IO_Compression_Native.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_IO_Ports_Native.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_Native.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_Net_Security_Native.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/System_Security_Cryptography_Native_Apple.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/clrjit.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
Dependencies/XCFrameworks/coreclr.xcframework = (CodeSignOnCopy, RemoveHeadersOnCopy, );
};
buildPhase = 4E87E2CA2CCE2D8E00F54325 /* Embed Frameworks */;
membershipExceptions = (
"Dependencies/Dynamic Libraries/libMoltenVK.dylib",
"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib",
Dependencies/XCFrameworks/clrjit.xcframework,
Dependencies/XCFrameworks/coreclr.xcframework,
Dependencies/XCFrameworks/MoltenVK.xcframework,
Dependencies/XCFrameworks/SDL2.xcframework,
Dependencies/XCFrameworks/System_Globalization_Native.xcframework,
Dependencies/XCFrameworks/System_IO_Compression_Native.xcframework,
Dependencies/XCFrameworks/System_IO_Ports_Native.xcframework,
Dependencies/XCFrameworks/System_Native.xcframework,
Dependencies/XCFrameworks/System_Net_Security_Native.xcframework,
Dependencies/XCFrameworks/System_Security_Cryptography_Native_Apple.xcframework,
);
};
/* End PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
4E87E28E2CCE2C1000F54325 /* MeloNX */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
4E87E3022CCE3E0700F54325 /* Exceptions for "MeloNX" folder in "MeloNX" target */,
4E87E2CB2CCE2D8E00F54325 /* Exceptions for "MeloNX" folder in "Embed Frameworks" phase from "MeloNX" target */,
);
path = MeloNX;
sourceTree = "<group>";
};
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
4E87E2892CCE2C1000F54325 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4E87E2F62CCE33B500F54325 /* GameController.framework in Frameworks */,
4E87E2F32CCE315100F54325 /* SDL in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4E87E2832CCE2C1000F54325 = {
isa = PBXGroup;
children = (
4E87E28E2CCE2C1000F54325 /* MeloNX */,
4E87E2F42CCE33B500F54325 /* Frameworks */,
4E87E28D2CCE2C1000F54325 /* Products */,
);
sourceTree = "<group>";
};
4E87E28D2CCE2C1000F54325 /* Products */ = {
isa = PBXGroup;
children = (
4E87E28C2CCE2C1000F54325 /* MeloNX.app */,
);
name = Products;
sourceTree = "<group>";
};
4E87E2F42CCE33B500F54325 /* Frameworks */ = {
isa = PBXGroup;
children = (
4E87E2F52CCE33B500F54325 /* GameController.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
4E87E28B2CCE2C1000F54325 /* MeloNX */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4E87E29A2CCE2C1100F54325 /* Build configuration list for PBXNativeTarget "MeloNX" */;
buildPhases = (
4ECF0AD52CD0FB5B00A3820B /* ShellScript */,
4E87E2882CCE2C1000F54325 /* Sources */,
4E87E2892CCE2C1000F54325 /* Frameworks */,
4E87E28A2CCE2C1000F54325 /* Resources */,
4E87E2CA2CCE2D8E00F54325 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
4E87E28E2CCE2C1000F54325 /* MeloNX */,
);
name = MeloNX;
packageProductDependencies = (
4E87E2F22CCE315100F54325 /* SDL */,
);
productName = MeloNX;
productReference = 4E87E28C2CCE2C1000F54325 /* MeloNX.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
4E87E2842CCE2C1000F54325 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1600;
LastUpgradeCheck = 1600;
TargetAttributes = {
4E87E28B2CCE2C1000F54325 = {
CreatedOnToolsVersion = 16.0;
};
};
};
buildConfigurationList = 4E87E2872CCE2C1000F54325 /* Build configuration list for PBXProject "MeloNX" */;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 4E87E2832CCE2C1000F54325;
minimizedProjectReferenceProxies = 1;
packageReferences = (
4E87E2F12CCE315100F54325 /* XCRemoteSwiftPackageReference "SwiftSDL2" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 4E87E28D2CCE2C1000F54325 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
4E87E28B2CCE2C1000F54325 /* MeloNX */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
4E87E28A2CCE2C1000F54325 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
4ECF0AD52CD0FB5B00A3820B /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "
";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
4E87E2882CCE2C1000F54325 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
4E87E2982CCE2C1100F54325 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
4E87E2992CCE2C1100F54325 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
4E87E29B2CCE2C1100F54325 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MeloNX/MeloNX.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 95J8WZ4TN8;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = MeloNX/Info.plist;
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(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",
"$(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;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/Header/MeloNX-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
4E87E29C2CCE2C1100F54325 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MeloNX/MeloNX.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = 95J8WZ4TN8;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = MeloNX/Info.plist;
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(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",
"$(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;
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "MeloNX/Header/MeloNX-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
4E87E2872CCE2C1000F54325 /* Build configuration list for PBXProject "MeloNX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4E87E2982CCE2C1100F54325 /* Debug */,
4E87E2992CCE2C1100F54325 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4E87E29A2CCE2C1100F54325 /* Build configuration list for PBXNativeTarget "MeloNX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4E87E29B2CCE2C1100F54325 /* Debug */,
4E87E29C2CCE2C1100F54325 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
4E87E2F12CCE315100F54325 /* XCRemoteSwiftPackageReference "SwiftSDL2" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ctreffs/SwiftSDL2";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.4.1;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
4E87E2F22CCE315100F54325 /* SDL */ = {
isa = XCSwiftPackageProductDependency;
package = 4E87E2F12CCE315100F54325 /* XCRemoteSwiftPackageReference "SwiftSDL2" */;
productName = SDL;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 4E87E2842CCE2C1000F54325 /* Project object */;
}

View File

@ -0,0 +1,15 @@
{
"originHash" : "188cbfb6a5b52c41d3df0f972db675022d152bd432fecbf1b5a68f66e3956cb5",
"pins" : [
{
"identity" : "swiftsdl2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ctreffs/SwiftSDL2",
"state" : {
"revision" : "30a2886bd68e43fc19ba29b63ffe230ac0e4db7a",
"version" : "1.4.1"
}
}
],
"version" : 3
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1610" LastUpgradeVersion = "1600"
version = "1.7"> version = "1.7">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@ -15,7 +15,7 @@
buildForAnalyzing = "YES"> buildForAnalyzing = "YES">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "4E80A98C2CD6F54500029585" BlueprintIdentifier = "4E87E28B2CCE2C1000F54325"
BuildableName = "MeloNX.app" BuildableName = "MeloNX.app"
BlueprintName = "MeloNX" BlueprintName = "MeloNX"
ReferencedContainer = "container:MeloNX.xcodeproj"> ReferencedContainer = "container:MeloNX.xcodeproj">
@ -29,33 +29,9 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES" shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES"> shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E80A99C2CD6F54700029585"
BuildableName = "MeloNXTests.xctest"
BlueprintName = "MeloNXTests"
ReferencedContainer = "container:MeloNX.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E80A9A62CD6F54700029585"
BuildableName = "MeloNXUITests.xctest"
BlueprintName = "MeloNXUITests"
ReferencedContainer = "container:MeloNX.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0" launchStyle = "0"
@ -63,14 +39,12 @@
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES" debugDocumentVersioning = "YES"
debugServiceExtension = "internal" debugServiceExtension = "internal"
enableGPUValidationMode = "1"
showGraphicsOverview = "Yes"
allowLocationSimulation = "YES"> allowLocationSimulation = "YES">
<BuildableProductRunnable <BuildableProductRunnable
runnableDebuggingMode = "0"> runnableDebuggingMode = "0">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "4E80A98C2CD6F54500029585" BlueprintIdentifier = "4E87E28B2CCE2C1000F54325"
BuildableName = "MeloNX.app" BuildableName = "MeloNX.app"
BlueprintName = "MeloNX" BlueprintName = "MeloNX"
ReferencedContainer = "container:MeloNX.xcodeproj"> ReferencedContainer = "container:MeloNX.xcodeproj">
@ -87,7 +61,7 @@
runnableDebuggingMode = "0"> runnableDebuggingMode = "0">
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
BlueprintIdentifier = "4E80A98C2CD6F54500029585" BlueprintIdentifier = "4E87E28B2CCE2C1000F54325"
BuildableName = "MeloNX.app" BuildableName = "MeloNX.app"
BlueprintName = "MeloNX" BlueprintName = "MeloNX"
ReferencedContainer = "container:MeloNX.xcodeproj"> ReferencedContainer = "container:MeloNX.xcodeproj">

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "64A8AF27-6696-4D7A-8C62-06216A95ECF0"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "C2C839C6-26A1-468A-9479-A00FD57EA17C"
shouldBeEnabled = "Yes"
nameForDebugger = "ignore-sigusr1"
ignoreCount = "0"
continueAfterRunningActions = "Yes"
filePath = "MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "111"
endingLineNumber = "111"
landmarkName = "startWithRunLoop(config:)"
landmarkType = "7">
<Actions>
<BreakpointActionProxy
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
<ActionContent
consoleCommand = "process handle SIGUSR1 -n true -p true -s false">
</ActionContent>
</BreakpointActionProxy>
</Actions>
<Locations>
<Location
uuid = "C2C839C6-26A1-468A-9479-A00FD57EA17C - e09e330dd17da5b1"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "MeloNX.RyujinxEmulator.startWithRunLoop(config: MeloNX.RyujinxEmulator.Configuration) throws -&gt; ()"
moduleName = "MeloNX.debug.dylib"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/stossy11/MeloNX/MeloNX-XC/MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "111"
endingLineNumber = "111">
</Location>
<Location
uuid = "C2C839C6-26A1-468A-9479-A00FD57EA17C - a8ffb78cb80274ea"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #2 @Sendable () -&gt; () in MeloNX.RyujinxEmulator.startWithRunLoop(config: MeloNX.RyujinxEmulator.Configuration) throws -&gt; ()"
moduleName = "MeloNX.debug.dylib"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/stossy11/MeloNX/MeloNX-XC/MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "112"
endingLineNumber = "112">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "5A4DEE32-2E63-4404-BFDE-AD7F1337DA66"
shouldBeEnabled = "Yes"
nameForDebugger = "ignore-sigusr1"
ignoreCount = "0"
continueAfterRunningActions = "Yes"
filePath = "MeloNX/Core/Ryujinx.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "120"
endingLineNumber = "120"
landmarkName = "startWithRunLoop(config:)"
landmarkType = "7">
<Actions>
<BreakpointActionProxy
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
<ActionContent
consoleCommand = "process handle SIGUSR1 -n true -p true -s false">
</ActionContent>
</BreakpointActionProxy>
</Actions>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -9,15 +9,13 @@
<key>orderHint</key> <key>orderHint</key>
<integer>0</integer> <integer>0</integer>
</dict> </dict>
<key>Ryujinx.xcscheme_^#shared#^_</key> </dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>4E87E28B2CCE2C1000F54325</key>
<dict> <dict>
<key>orderHint</key> <key>primary</key>
<integer>1</integer> <true/>
</dict>
<key>com.Stossy11.MeloNX.RyujinxAg.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict> </dict>
</dict> </dict>
</dict> </dict>

View File

@ -1,7 +1,6 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "nxgradientpng.png",
"idiom" : "universal", "idiom" : "universal",
"platform" : "ios", "platform" : "ios",
"size" : "1024x1024" "size" : "1024x1024"

View File

@ -0,0 +1,168 @@
//
// ContentView.swift
// MeloNX
//
// Created by Stossy11 on 27/10/2024.
//
import SwiftUI
import SDL2
import GameController
var theWindow: UIWindow? = nil
struct ContentView: View {
@State var device: MTLDevice? = MTLCreateSystemDefaultDevice()
@State var gameUrl: URL?
@State var showFileImporter: Bool = false
@State var emulationStarted: Bool = false
@State var mainThread: Bool = true
@State var debugmode: Int = 0
init() {
DispatchQueue.main.async {
SDL_SetMainReady()
SDL_iPhoneSetEventPump(SDL_TRUE)
}
}
var body: some View {
ZStack {
if let gameUrl, emulationStarted {
VulkanSDLViewRepresentable { // displayid in
let config = RyujinxEmulator.Configuration(
inputPath: gameUrl.path,
mainThread: mainThread,
graphicsBackend: "Vulkan",
additionalArgs: [
//"--display-id", String(displayid),
// "--fullscreen", "true"
]
)
showVirtualController(url: gameUrl, ryuconfig: config)
}
}
VStack {
Text("NX iOS")
.font(.largeTitle)
.onTapGesture {
debugmode += 1
}
.padding()
if debugmode > 9 {
Text("Debug Mode:")
.font(.title)
Text("Is on Main Thread?: \(mainThread)")
.font(.title2)
Toggle(isOn: $mainThread) {
Text("Use Main Thread")
}
}
Button {
showFileImporter.toggle()
} label: {
Text("Select Game")
}
if let gameUrl {
Button {
emulationStarted = true
} label: {
Text("Go!")
}
.padding(8)
}
}
}
.padding()
.fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.item]) { result in
switch result {
case .success(let url):
gameUrl = url
case .failure(let err):
print(err.localizedDescription)
}
}
}
}
func startEmulation(game: URL, config: RyujinxEmulator.Configuration) {
setenv("DOTNET_EnableDiagnostics", "0", 1)
setenv("HOME", String(validatingUTF8: getenv("HOME"))! + "/Documents", 1)
setenv("MVK_CONFIG_LOG_LEVEL", "4", 1)
let config = config
patchMakeKeyAndVisible()
// SDL_Init(SDL_INIT_VIDEO)
DispatchQueue.main.async {
let emulator = RyujinxEmulator()
do {
try emulator.startWithRunLoop(config: config)
} catch {
print(error)
}
}
}
func patchMakeKeyAndVisible() {
DispatchQueue.main.async {
let uiwindowClass = UIWindow.self
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() {
DispatchQueue.main.async {
print("Making window key and visible...")
if #available(iOS 13.0, *) {
self.windowScene = (UIApplication.shared.connectedScenes.first! as! UIWindowScene)
}
self.wdb_makeKeyAndVisible()
theWindow = self
}
}
}
@available(iOS 15.0, *)
var g_gcVirtualController: GCVirtualController!
@available(iOS 15.0, *)
func showVirtualController(url: URL, ryuconfig: RyujinxEmulator.Configuration) {
DispatchQueue.main.async {
print("Showing virtual controller...")
let config = GCVirtualController.Configuration()
config.elements = [
GCInputDirectionalDpad, GCInputButtonA, GCInputButtonB, GCInputButtonX, GCInputButtonY,
]
g_gcVirtualController = GCVirtualController(configuration: config)
g_gcVirtualController.connect { err in
print("Controller connect: \(String(describing: err))")
DispatchQueue.main.async {
startEmulation(game: url, config: ryuconfig)
}
}
}
}
@available(iOS 15.0, *)
func reconnectVirtualController() {
print("Reconnecting virtual controller...")
g_gcVirtualController.disconnect()
DispatchQueue.main.async {
g_gcVirtualController.connect { err in
print("Reconnected: err \(String(describing: err))")
}
}
}

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

@ -0,0 +1,368 @@
//
// Ryujinx.swift
// MeloNX
//
// Created by Stossy11 on 27/10/2024.
//
import Foundation
import SwiftUI
enum RyujinxError: Error {
case libraryLoadError
case executionError(code: Int32)
case alreadyRunning
case notRunning
}
class RyujinxEmulator {
private var isRunning = false
private var emulationThread: Thread?
struct Configuration {
let inputPath: String
let mainThread: Bool // i don't know why i added this
let graphicsBackend: String
var additionalArgs: [String]
init(
inputPath: String,
mainThread: Bool = true,
graphicsBackend: String = "Vulkan",
additionalArgs: [String] = []
) {
self.inputPath = inputPath
self.mainThread = mainThread
self.graphicsBackend = graphicsBackend
self.additionalArgs = additionalArgs
}
}
private static func start(with config: Configuration) throws {
var args: [String] = []
// Taken from the POC
/*
var args: [String] = [
"--enable-debug-logs", "false", "--enable-trace-logs", "false", "--memory-manager-mode",
"SoftwarePageTable",
"--graphics-backend",
"Vulkan",
//"--enable-fs-integrity-checks", "false",
"--input-id-1", "0",
// "--list-inputs-ids", "true",
config.inputPath,
]
*/
args.append(config.inputPath)
args.append("--graphics-backend")
args.append(config.graphicsBackend)
// args.append(contentsOf: ["--memory-manager-mode", "SoftwarePageTable"])
// args.append(contentsOf: ["--fullscreen", "true"])
args.append(contentsOf: ["--enable-debug-logs", "true"])
args.append(contentsOf: ["--enable-trace-logs", "true"])
// args.append(contentsOf: ["--list-inputs-ids", "true"])
args.append(contentsOf: ["--input-id-1", "1-47150005-05ac-0000-0100-00004f066d01"])
// args.append("--input-path")
args.append(contentsOf: config.additionalArgs)
let cArgs = args.map { strdup($0) }
defer {
cArgs.forEach { ptr in
if let ptr = ptr {
free(ptr)
}
}
}
var argvPtrs = cArgs
let result = main_ryujinx_sdl(Int32(args.count), &argvPtrs)
if result != 0 {
throw RyujinxError.executionError(code: result)
}
}
// cray z
func startWithRunLoop(config: Configuration) throws {
guard !isRunning else {
throw RyujinxError.alreadyRunning
}
isRunning = true
DispatchQueue.main.async {
do {
try Self.start(with: config)
} catch {
Self.log("Emulation failed to start: \(error)")
self.isRunning = false
return
}
}
emulationThread = Thread {
let runLoop = RunLoop.current
let port = Port()
runLoop.add(port, forMode: .default)
print(config.mainThread ? "Running on the main thread" : "Running on the background thread")
/*
if config.mainThread {
DispatchQueue.main.async {
do {
try Self.start(with: config)
} catch {
Self.log("Emulation failed to start: \(error)")
self.isRunning = false
return
}
}
} else {
do {
try Self.start(with: config)
} catch {
Self.log("Emulation failed to start: \(error)")
self.isRunning = false
return
}
}
*/
while self.isRunning && runLoop.run(mode: .default, before: .distantFuture) {
autoreleasepool { }
}
Self.log("Emulation loop ended")
}
emulationThread?.name = "RyujinxEmulationThread"
emulationThread?.qualityOfService = .userInteractive
emulationThread?.threadPriority = 0.9
// emulationThread?.start()
}
func quickStart(romPath: String) throws {
let config = Configuration(inputPath: romPath)
try startWithRunLoop(config: config)
}
/// Stops the emulator
func stop() throws {
guard isRunning else {
throw RyujinxError.notRunning
}
isRunning = false
emulationThread?.cancel()
emulationThread = nil
}
var running: Bool {
return isRunning
}
static func log(_ message: String) {
print("[Ryujinx] \(message)")
}
}
extension RyujinxEmulator.Configuration {
var toCommandLineArgs: [String] {
var args: [String] = []
args.append(inputPath)
// if enableKeyboard {
// args.append("--enable-keyboard")
// }
args.append("--graphics-backend")
args.append(graphicsBackend)
args.append(contentsOf: additionalArgs)
return args
}
/// Create configuration from command line arguments
static func fromCommandLineArgs(_ args: [String]) -> RyujinxEmulator.Configuration? {
var inputPath: String?
var enableKeyboard = false
var graphicsBackend = "Vulkan"
var additionalArgs: [String] = []
var i = 0
while i < args.count {
switch args[i] {
case "--enable-keyboard":
enableKeyboard = true
case "--graphics-backend":
i += 1
if i < args.count {
graphicsBackend = args[i]
}
default:
additionalArgs.append(args[i])
}
i += 1
}
guard let inputPath = inputPath else {
return nil
}
return RyujinxEmulator.Configuration(
inputPath: inputPath,
mainThread: enableKeyboard,
graphicsBackend: graphicsBackend,
additionalArgs: additionalArgs
)
}
}
// MARK: - Code Taken from POC
var g_HookMmapReserved4GB: UnsafeMutableRawPointer! = nil
var g_HookMmapReservedJitCache: UnsafeMutableRawPointer! = nil
func initHookMmap() -> Bool {
// Hack: if out of memory, you can reserve less (e.g. around 0xc000_0000 or even 0x8000_0000) but it'll crash later
let reserve4GBSize = 0x1_0000_0000
g_HookMmapReserved4GB = mmap(
nil, reserve4GBSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
if g_HookMmapReserved4GB == MAP_FAILED {
print("can't allocate 4gb")
return false
}
let reserveJitCacheSize = 0x8000_0000
g_HookMmapReservedJitCache = mmap(
nil, reserveJitCacheSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
if g_HookMmapReservedJitCache == MAP_FAILED {
print("can't allocate jit cache")
return false
}
if !reallocateAreaWithOwnership(address: g_HookMmapReserved4GB, size: reserve4GBSize) {
print("can't reallocate area with ownership for 4gb")
return false
}
if !reallocateAreaWithOwnership(address: g_HookMmapReservedJitCache, size: reserveJitCacheSize) {
print("can't reallocate area with ownership for jitcache")
return false
}
print("Allocated Needed Ram")
return true
}
func hookMmap(
addr: UnsafeMutableRawPointer?, len: Int, prot: Int32, flags: Int32, fd: Int32, offset: off_t
) -> UnsafeMutableRawPointer! {
print("mmap hook! \(String(describing: addr)) \(len) \(prot) \(flags)")
// TODO(zhuowei): threads?
if g_HookMmapReserved4GB != nil && len == 0x1_0000_0000 {
let ret = g_HookMmapReserved4GB
g_HookMmapReserved4GB = nil
print("returning 4gb: \(ret!)")
return ret
}
if g_HookMmapReservedJitCache != nil && len == 0x7ff0_0000 {
// Hack: it wants 2GB; give it smaller
let ret = g_HookMmapReservedJitCache
g_HookMmapReservedJitCache = nil
print("returning jitcache: \(ret!)")
return ret
}
return mmap(addr, len, prot, flags, fd, offset)
}
func reallocateAreaWithOwnership(address: UnsafeMutableRawPointer, size: Int) -> Bool {
let addressBase: mach_vm_address_t = mach_vm_address_t(UInt(bitPattern: address))
let mapChunkSize = 128 * 1024 * 1024
for off in stride(from: 0, to: size, by: mapChunkSize) {
let targetSize = memory_object_size_t(min(mapChunkSize, size - off))
var memoryObjectSize = targetSize
var memoryObjectPort: mach_port_t = 0
let err = mach_make_memory_entry_64(
mach_task_self_, &memoryObjectSize, 0,
MAP_MEM_NAMED_CREATE | MAP_MEM_LEDGER_TAGGED | VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE,
&memoryObjectPort, /*parent_entry=*/ 0)
if err != 0 {
print("mach_make_memory_entry_64 returned error: \(String(cString: mach_error_string(err)!))")
return false
}
defer { mach_port_deallocate(mach_task_self_, memoryObjectPort) }
if memoryObjectSize != targetSize {
print("size is wrong?! \(memoryObjectSize) \(targetSize)")
return false
}
let err2 = mach_memory_entry_ownership(
memoryObjectPort, TASK_NULL, VM_LEDGER_TAG_DEFAULT, VM_LEDGER_FLAG_NO_FOOTPRINT)
if err2 != 0 {
print(
"mach_memory_entry_ownership returned error: \(String(cString: mach_error_string(err2)!))")
return false
}
let targetMapAddress: vm_address_t = vm_address_t(addressBase) + vm_address_t(off)
var mapAddress = targetMapAddress
let err3 = vm_map(
mach_task_self_, &mapAddress, vm_size_t(memoryObjectSize), /*mask=*/ 0, /*flags=*/
VM_FLAGS_OVERWRITE,
memoryObjectPort, /*offset=*/ 0, /*copy=*/ 0, VM_PROT_READ | VM_PROT_WRITE,
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE, VM_INHERIT_COPY)
if err3 != 0 {
print("vm_map returned error: \(String(cString: mach_error_string(err3)!))")
return false
}
if mapAddress != targetMapAddress {
print("map address wrong")
return false
}
}
return true
}
typealias SystemNative_Open_Type = @convention(c) (
_ path: UnsafePointer<CChar>, _ flags: Int32, _ mode: Int32
) -> Int
var real_SystemNative_Open: SystemNative_Open_Type!
func hook_SystemNative_Open(path: UnsafePointer<CChar>, flags: Int32, mode: Int32) -> Int {
let fileName = String(cString: path)
print("opening \(fileName)")
return real_SystemNative_Open(path, flags, mode)
}
func pInvokeOverride(libraryName: UnsafePointer<CChar>!, entrypointName: UnsafePointer<CChar>!)
-> UnsafeRawPointer?
{
let libraryName = String(cString: libraryName)
let entrypointName = String(cString: entrypointName)
// print(libraryName, entrypointName)
if entrypointName == "mmap" {
typealias MmapType = @convention(c) (
_: UnsafeMutableRawPointer?, _: Int, _: Int32, _: Int32, _: Int32, _: off_t
) -> UnsafeMutableRawPointer?
return unsafeBitCast(hookMmap as MmapType, to: UnsafeRawPointer.self)
} else if entrypointName == "SystemNative_Open" {
let handle = dlopen("libSystem.Native.dylib", RTLD_LOCAL | RTLD_LAZY)
real_SystemNative_Open = unsafeBitCast(
dlsym(handle, "SystemNative_Open"), to: SystemNative_Open_Type.self)
return unsafeBitCast(
hook_SystemNative_Open as SystemNative_Open_Type, to: UnsafeRawPointer.self)
}
return nil
}

Some files were not shown because too many files have changed in this diff Show More