1
0
forked from MeloNX/MeloNX

Compare commits

...

200 Commits

Author SHA1 Message Date
Emmanuel Hansen
0f1b737b07 android - close file handles in performance monitor 2024-01-22 22:55:54 +00:00
Emmanuel Hansen
29332c44ab fix nce bad rebase 2024-01-22 22:55:54 +00:00
Emmanuel Hansen
e926499e32 android - add performance stats 2024-01-22 22:55:50 +00:00
Emmanuel Hansen
96c4edb697 android - set isStarted check early 2024-01-22 22:55:49 +00:00
Emmanuel Hansen
ba3438f24a fix arm jit rebase 2024-01-22 22:55:48 +00:00
Emmanuel Hansen
956c5fe4fd android - update dependencies 2024-01-22 22:55:46 +00:00
Emmanuel Hansen
15baf43a7c fix rebase 2024-01-22 22:55:45 +00:00
Emmanuel Hansen
aec0b99f8a remove dotnet previews nuget source 2024-01-22 22:55:44 +00:00
Isaac Marovitz
16f77936e0 Start GameInfoNative 2024-01-22 22:55:44 +00:00
Isaac Marovitz
5f18d19f23 Expand InitializeDeviceNative Signature 2024-01-22 22:55:44 +00:00
Isaac Marovitz
29a0c1caed Expose InstallFirmware 2024-01-22 22:55:43 +00:00
Isaac Marovitz
97e3fc60ca Expose GetInstalledFirmwareVersion 2024-01-22 22:55:43 +00:00
Isaac Marovitz
1a4f506991 Don’t crash if no firmware is installed 2024-01-22 22:55:43 +00:00
Isaac Marovitz
af4f7b9ee7 Expose Accelerometer & Gyro Functions 2024-01-22 22:55:43 +00:00
Isaac Marovitz
a6a75a4208 iOS - Disable StdErrAdapter
Enabling fills the logs with uneeded spam
2024-01-22 22:55:42 +00:00
Isaac Marovitz
d6e88e3cc9 iOS - Set Silk.NET SearchPathContainer 2024-01-22 22:55:42 +00:00
Isaac Marovitz
66e58aa6a7 iOS - Platform Checks
Co-authored-by: riperiperi <rhy3756547@hotmail.com>
2024-01-22 22:55:42 +00:00
Isaac Marovitz
5d919039d9 iOS - Linker Fixes 2024-01-22 22:55:42 +00:00
Emmanuel Hansen
cdf188a434 android - change game stats background color 2024-01-22 22:55:41 +00:00
Emmanuel Hansen
f403484276 android - move title updates support to SAF 2024-01-22 22:55:41 +00:00
Emmanuel Hansen
7955b4f287 android - fix dpad input on generic android controllers 2024-01-22 22:55:41 +00:00
Emmanuel Hansen
047ee4554e android - remote developer name from grid items 2024-01-22 22:55:41 +00:00
Emmanuel Hansen
e0c5953ce0 android - add option to disable motion 2024-01-22 22:55:41 +00:00
Emmanuel Hansen
b81643352e android - add basic software keyboard support 2024-01-22 22:55:40 +00:00
Emmanuel Hansen
c12da6d650 android - add option to swap button layouts to nintendo style 2024-01-22 22:55:40 +00:00
Emmanuel Hansen
c74ad70c3d android - set controller event as handled 2024-01-22 22:55:40 +00:00
Emmanuel Hansen
1ea1a0ba68 android - fix stick showing as dpad 2024-01-22 22:55:40 +00:00
Emmanuel Hansen
8e25994391 android - add hack to fix orientation issue 2024-01-22 22:55:40 +00:00
Emmanuel Hansen
52f5142305 android - fix settings app action buttons. fix dlc manager add button missing 2024-01-22 22:55:39 +00:00
Emmanuel Hansen
80d1ac212e android - ensure controller respects users controller visibility settings at launch 2024-01-22 22:55:39 +00:00
TSR Berry
a8fcf22b89 cmake: Use FetchContent to include adrenotools 2024-01-22 22:55:39 +00:00
Emmanuel Hansen
aa87b4abd8 android - implement firmware installation 2024-01-22 22:55:39 +00:00
Emmanuel Hansen
60f320bc07 android - add motion support 2024-01-22 22:55:38 +00:00
Emmanuel Hansen
521403b0ea android - add support for nro 2024-01-22 22:55:38 +00:00
Emmanuel Hansen
9680ecd820 android - allow sensor to change orientation during emulation 2024-01-22 22:55:38 +00:00
Emmanuel Hansen
3bc415053e android - add button to open ryujinx app folder 2024-01-22 22:55:38 +00:00
Emmanuel Hansen
e7ac8bf333 android - add log settings 2024-01-22 22:55:38 +00:00
Emmanuel Hansen
819c7671bb android - add log export, providers to browse app data 2024-01-22 22:55:37 +00:00
Emmanuel Hansen
990ad3d133 android - bump version 2024-01-22 22:55:37 +00:00
Emmanuel Hansen
923d0a5bd1 android - bump version 2024-01-22 22:55:37 +00:00
Emmanuel Hansen
024a6cdbb2 android - set nativeaot instruction set support 2024-01-22 22:55:37 +00:00
Emmanuel Hansen
5028673968 android - reload list if game folder changed, fix game updates scanning 2024-01-22 22:55:36 +00:00
Emmanuel Hansen
d7b139a4a8 update opentk packages 2024-01-22 22:55:36 +00:00
Emmanuel Hansen
9765f7a388 android - adjust grid view design, remove bottom app bar 2024-01-22 22:55:35 +00:00
Emmanuel Hansen
bc6e5de507 android - add grid list option 2024-01-22 22:55:35 +00:00
Emmanuel Hansen
e5d54d5374 rebase with upstream 2024-01-22 22:55:35 +00:00
Emmanuel Hansen
038ee1a6dd android - remove oboe 2024-01-22 22:55:34 +00:00
Emmanuel Hansen
c6e2e16e0b android - bumb version, rebase over master 2024-01-22 22:55:34 +00:00
Emmanuel Hansen
74f45c486f android - bumb version 2024-01-22 22:55:33 +00:00
Emmanuel Hansen
4fc253384b android - fixes a few crashes in the user and home views 2024-01-22 22:55:33 +00:00
Emmanuel Hansen
71f3d22db8 android - add string map 2024-01-22 22:55:33 +00:00
Emmanuel Hansen
fdb7320031 android - drop game activity, replace with compose view 2024-01-22 22:55:33 +00:00
Emmanuel Hansen
f6850bcc1a rebase fix 2024-01-22 22:55:32 +00:00
Emmanuel Hansen
946079f5e3 android - make settings view scrollable, bump version 2024-01-22 22:55:32 +00:00
Emmanuel Hansen
14d6e280f7 android - improve game update selection 2024-01-22 22:55:31 +00:00
Emmanuel Hansen
2240d87902 android - fix crash when no user is available at launch 2024-01-22 22:55:31 +00:00
Emmanuel Hansen
5b1a928e1b android - add crash handler 2024-01-22 22:55:31 +00:00
Emmanuel Hansen
04850674d0 android - fix game update icon, add app icon 2024-01-22 22:55:31 +00:00
Emmanuel Hansen
f560431792 android - fix app menu 2024-01-22 22:55:31 +00:00
Emmanuel Hansen
ba745514a1 android - add basic user management 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
8e2eb5fd26 clean main ui, add option to import app data 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
34e52880da load firmware version at launch 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
a2b7dc5aca update to rc2, rebase update rd 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
28af479e2a improve async loading. add game load progress 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
c0091c838d use file descriptors to load game list 2024-01-22 22:55:30 +00:00
Emmanuel Hansen
4c0d21ede4 sanitize stick input 2024-01-22 22:55:30 +00:00
Gabriel A
e3a81cfdee Extend Adreno binding workaround to buffer textures 2024-01-22 22:55:29 +00:00
Gabriel A
698ac0413b Support ballot operations with divergent control flow on Adreno 2024-01-22 22:55:29 +00:00
Emmanuel Hansen
dca4091930 don't request storage usage for surface on bionic 2024-01-22 22:55:28 +00:00
Gabriel A
f1814ca542 Add spin lock to prevent waiting for fences on multiple threads at once on Adreno 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
3e6ec4aea8 fix rd.xml 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
fdc5ceea41 fix rebase 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
091d9d4546 create a copy of updates when added 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
7a2fadb499 some optimizations. apply current transform to native window instead of defaulting to Identity 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
c732a9fbb6 enable hardware accel for activity 2024-01-22 22:55:28 +00:00
Emmanuel Hansen
6f48a6a24d reduced virtual controller deadzone 2024-01-22 22:55:27 +00:00
Emmanuel Hansen
e6ceb70114 fix manifest error 2024-01-22 22:55:27 +00:00
Emmanuel Hansen
83c9e4fcb2 move game view to new activity 2024-01-22 22:55:27 +00:00
Emmanuel Hansen
8c0bd460d9 add bottom popup ingame 2024-01-22 22:55:27 +00:00
Emmanuel Hansen
0bf93ef754 add game searching 2024-01-22 22:55:27 +00:00
Emmanuel Hansen
8f8f9e996a switch to using stream base game loading 2024-01-22 22:55:26 +00:00
TSR Berry
3f8d269719 Fix gradle build issues when multiple configurations are present 2024-01-22 22:55:26 +00:00
TSR Berry
6a8fce261e Update Android gradle plugins 2024-01-22 22:55:26 +00:00
Emmanuel Hansen
44315541c3 fix AsFlags rename conflict 2024-01-22 22:55:26 +00:00
Emmanuel Hansen
7a85dc2e76 add dlc manager 2024-01-22 22:55:26 +00:00
Emmanuel Hansen
fb562c8077 safely close audio on game exit 2024-01-22 22:55:26 +00:00
Emmanuel Hansen
2999275ed2 add closing emulation(starting a new one is still broken), disabled audio 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
a050e5c6c0 separate game loading from surface creation 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
398fb78a31 refactor virtual pad composition 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
f0b0f3b796 fix unzip code 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
7d7e1ce639 fix adreno hooking 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
f8c1e745ca fix adreno hooking 2024-01-22 22:55:25 +00:00
Emmanuel Hansen
a0c9d3b7de restore driver selection 2024-01-22 22:55:24 +00:00
Emmanuel Hansen
108fb2380a test 2024-01-22 22:55:24 +00:00
Emmanuel Hansen
9b4d988d8c add adrenotools module 2024-01-22 22:55:24 +00:00
TSR Berry
fae788f698 Replace Helpers.getPath() with file.getAbsolutePath() 2024-01-22 22:55:24 +00:00
TSR Berry
fa16c9c3bd Add more debug information when loading game files 2024-01-22 22:55:23 +00:00
TSR Berry
979db1def3 Cleanup RyujinxAndroid 2024-01-22 22:55:23 +00:00
TSR Berry
300b23cf9b Cleanup LibRyujinx and add more verbose logging 2024-01-22 22:55:23 +00:00
TSR Berry
ee4e18ff0d Fix PATH variable on Windows
I spent ~7 hours debugging this.
I searched for a bug in the Exec task and found nothing.
I tried different ways to invoke the dotnet command
to make sure PATH is always set before.
I also modified Microsoft.NETCore.Native.Unix.targets to echo PATH via Exec and via Text.
But in the end I was confused about seeing two PATH variables
when checking the dotnet.exe subprocess with ProcessHacker.
This made me try setting the Path variable instead of PATH
and to my surprise this just worked.
Turns out Windows environment variables are case-sensitive and
Windows uses Path instead of PATH like Unix.

God, I love Microsoft Windows. :)
2024-01-22 22:55:22 +00:00
TSR Berry
14cf6efa60 Add toolchain path to output 2024-01-22 22:55:22 +00:00
TSR Berry
35641ee3ca Only build LibRyujinx if source or project files changed 2024-01-22 22:55:22 +00:00
TSR Berry
853ef9ff8f Fix OS detection 2024-01-22 22:55:22 +00:00
TSR Berry
03ec861e03 Make dotnet executable path configurable 2024-01-22 22:55:21 +00:00
TSR Berry
9d8e02dd0e Add toolchain path to all operating systems correctly 2024-01-22 22:55:21 +00:00
TSR Berry
733f13fe0e Add preBuild dependency on libryujinx for app 2024-01-22 22:55:21 +00:00
TSR Berry
5070e14317 Suppress Google Play permission warning 2024-01-22 22:55:21 +00:00
TSR Berry
c247830f78 Fix AndroidManifest.xml warnings 2024-01-22 22:55:21 +00:00
TSR Berry
853b6f29ce Fix file trees 2024-01-22 22:55:21 +00:00
TSR Berry
4d2add5264 Preserve other jni libraries 2024-01-22 22:55:20 +00:00
TSR Berry
4728c1e96c Make stripSymbols a gradle property 2024-01-22 22:55:20 +00:00
TSR Berry
dd31c40f4e Raise minSdk to 30 to fix linter errors 2024-01-22 22:55:20 +00:00
TSR Berry
bda6617571 Update dependencies 2024-01-22 22:55:20 +00:00
TSR Berry
7fd44e32d0 Add gradle module for libryujinx 2024-01-22 22:55:16 +00:00
TSR Berry
fb592277a7 Keep libryujinx symbols 2024-01-22 22:55:15 +00:00
TSR Berry
826c64ddfe Switch to Java 17 LTS 2024-01-22 22:55:14 +00:00
TSR Berry
beba6d1422 Cleanup gitignore and project file structure 2024-01-22 22:55:13 +00:00
Emmanuel Hansen
5708f700ec remove safe area margins 2024-01-22 22:55:11 +00:00
Emmanuel Hansen
918b0fa302 fix touch, add toggle for virtual gamepad 2024-01-22 22:55:11 +00:00
Emmanuel Hansen
ffaa4d8ac1 expand full screen to behind cutouts 2024-01-22 22:55:11 +00:00
Emmanuel Hansen
ff3099e4a1 add performance hints 2024-01-22 22:55:11 +00:00
Emmanuel Hansen
61ba5e7bff add physical controller support 2024-01-22 22:55:10 +00:00
Gabriel A
4f1bf2d0cc Rebase fix: ReplayIfDirty was being called twice 2024-01-22 22:55:10 +00:00
Gabriel A
93cf57913c Remove address space mirror and tweak address space layout when host has small adress space 2024-01-22 22:55:10 +00:00
Gabriel A
2ad3605cdb Use alternate stack for the segfault handler too 2024-01-22 22:55:09 +00:00
Gabriel A
7925581e72 Ensure we don't set graphics state if there was no graphics pipeline bound before 2024-01-22 22:55:09 +00:00
Gabriel A
2814fa60bf Work around Adreno compute dispatch crash when changing grpahics state with a compute pipeline bound 2024-01-22 22:55:09 +00:00
Emmanuel Hansen
437bfdbd5a add native helper to create jni string 2024-01-22 22:55:09 +00:00
Gabriel A
375691b0e0 Allocate NCE patch region dynamically to avoid not having enough space 2024-01-22 22:55:08 +00:00
Emmanuel Hansen
517277a11f adjust game list item margins 2024-01-22 22:55:08 +00:00
Gabriel A
8e23eb88bb Rewrite NceAsmTable using dynamic generation instead to be more robust, fix bugs 2024-01-22 22:55:08 +00:00
Gabriel A
c694d5774d Fix incorrect AslrRegionStart when using NCE 2024-01-22 22:55:07 +00:00
Emmanuel Hansen
25b31b559a fix title updates again 2024-01-22 22:55:07 +00:00
Emmanuel Hansen
f3531394d5 fix title updates data being missing 2024-01-22 22:55:07 +00:00
Emmanuel Hansen
976514fdcc drop game stats class. directly call stats methods 2024-01-22 22:55:07 +00:00
Emmanuel Hansen
953559c71c initial work on multi driver selection 2024-01-22 22:55:06 +00:00
Emmanuel Hansen
d6ba9ad8f5 move android related file to subfolder 2024-01-22 22:55:06 +00:00
Emmanuel Hansen
4eb8e27517 fix native file logs 2024-01-22 22:55:05 +00:00
Emmanuel Hansen
6262bd1730 use int game controller ids 2024-01-22 22:55:05 +00:00
Emmanuel Hansen
e9c7564a03 add more options, fix vsync option 2024-01-22 22:55:05 +00:00
Emmanuel Hansen
7b1ce437ef add settings view 2024-01-22 22:55:05 +00:00
Gabriel A
21a78f173e Add work around for Adreno batched texture + sampler descriptor updates bug 2024-01-22 22:55:05 +00:00
Emmanuel Hansen
e54e18dab8 move android kotlin project over 2024-01-22 22:55:05 +00:00
Emmanuel Hansen
2d39deba26 add more parameters to initialize device 2024-01-22 22:55:04 +00:00
Emmanuel Hansen
28eb812018 add overload for loading game info from path 2024-01-22 22:55:04 +00:00
Emmanuel Hansen
9c510fec3e add android bionic nce support 2024-01-22 22:55:03 +00:00
gdk
44551a0409 Add back IsApplication flag 2024-01-22 22:55:03 +00:00
gdk
0970972f0d Add NCE code 2024-01-22 22:55:02 +00:00
gdk
a1e34041fa Minor refactoring of KPageTableBase to make custom address space layouts easier to implement 2024-01-22 22:55:01 +00:00
Emmanuel Hansen
c5bcdc06f5 add game stats helper 2024-01-22 22:55:01 +00:00
Emmanuel Hansen
c8d6f786c5 add option to enable debug logs 2024-01-22 22:55:01 +00:00
Emmanuel Hansen
c0a2cc5f6c disable optional logs 2024-01-22 22:54:59 +00:00
Emmanuel Hansen
db9111b895 add file logs 2024-01-22 22:54:58 +00:00
Emmanuel Hansen
159d1f0eae disable network change notification on bionic 2024-01-22 22:54:57 +00:00
Emmanuel Hansen
07caf24936 add steam based loaders 2024-01-22 22:54:57 +00:00
Emmanuel Hansen
56a6ac2a65 add interface fore loading games from storage 2024-01-22 22:54:56 +00:00
Emmanuel Hansen
145cd0b2b1 fix build on newer ndk versions 2024-01-22 22:54:56 +00:00
Emmanuel Hansen
333401b71d add helper to get new surface on android, still crashes when screen resizes 2024-01-22 22:54:55 +00:00
Emmanuel Hansen
5b9b17ef24 attempt to recreate surface if lost 2024-01-22 22:54:55 +00:00
Emmanuel Hansen
ba8028d1d0 add audio support for android 2024-01-22 22:54:55 +00:00
Emmanuel Hansen
a57cad5d5e add sdl audio backend as default audio 2024-01-22 22:54:54 +00:00
Emmanuel Hansen
9bb70e5ac2 enable release optimizations on aot 2024-01-22 22:54:54 +00:00
Emmanuel Hansen
416f40bddc remove spirv compilation option from native aot project 2024-01-22 22:54:54 +00:00
Emmanuel Hansen
3af84d0715 fix release bionic crash 2024-01-22 22:54:54 +00:00
Emmanuel Hansen
d988dfa781 use procontroller as default libryujinx controller type 2024-01-22 22:54:53 +00:00
Emmanuel Hansen
fd05b76554 make applet manager reflection free 2024-01-22 22:54:53 +00:00
Emmanuel Hansen
6828fe6270 fix android bionic log 2024-01-22 22:54:53 +00:00
Emmanuel Hansen
4d06f19fe7 add bionic nativeaot support 2024-01-22 22:54:52 +00:00
Emmanuel Hansen
ad0f9a7fc7 add helper for checking bionic 2024-01-22 22:54:52 +00:00
Mary
1835e16045 armeilleure: Do not call GCSettings.LargeObjectHeapCompactionMode on Android
Mono only support Default as argument and will throw otherwise.
2024-01-22 22:54:51 +00:00
Mary
0a666d9c5b armeilleure: Add Android to GetOSPlatform for PTC 2024-01-22 22:54:51 +00:00
Mary
b7d08e5050 armeilleure: Add Android signal handler 2024-01-22 22:54:51 +00:00
Mary
8a8db6244d armeilleure: Add support for Android in HardwareCapabilities 2024-01-22 22:54:51 +00:00
Mary
0b14eb3a61 memory: Add Android support 2024-01-22 22:54:50 +00:00
Emmanuel Hansen
c27a12df2c add basic touch and button input interface 2024-01-22 22:54:50 +00:00
Emmanuel Hansen
24b8d7c981 remove armeilleire reference in rd file 2024-01-22 22:54:50 +00:00
Emmanuel Hansen
8535b6c2f6 libryujinx - disable shader cache 2024-01-22 22:54:50 +00:00
Emmanuel Hansen
cb8837e1b8 remove redundant project reference 2024-01-22 22:54:49 +00:00
gdk
0e3c224b8d Make GetFunctionPointerForDelegate as explicit as possible 2024-01-22 22:54:49 +00:00
Emmanuel Hansen
1694303e4c add nativaot libryujinx project 2024-01-22 22:54:49 +00:00
Emmanuel Hansen
cea50d80c9 remove usage of reflection in device state 2024-01-22 22:54:49 +00:00
Emmanuel Hansen
c3a3adbaeb add hle service generator 2024-01-22 22:54:49 +00:00
gdkchan
4df22eb867
Fix missing data for new copy dependency textures with mismatching size (#6161) 2024-01-22 17:42:26 -03:00
gdkchan
f241f88558
Add a separate device memory manager (#6153)
* Add a separate device memory manager

* Still need this

* Device writes are always tracked

* Device writes are always tracked (2)

* Rename more instances of gmm to mm
2024-01-22 17:14:46 -03:00
riperiperi
90455a05e6
Input: Improve controller identification (#6029)
* Input: Improve controller identification

Controllers were identified before by a combination of their _global_ index in the list of controllers and their GUID. The problem is, disconnecting and reconnecting a controller can change its global index; the controller can appear at the end. This would give it another ID, and the controller would need to be reconfigured.

This happened to me a lot with a switch pro controller and a USB game controller, it was essentially random which appeared first. Now, it consistently detects them.

This PR changes the controller identification to be a combination of an index of controllers with the same GUID (generally 0), and its GUID. It also reworks managing the list of controllers to properly consider instance IDs.

This also changes the NpadManager to attempt to reuse old controllers when refreshing input configuration, which can prevent input from going dead for seconds whenever a controller connects or disconnects (and the switch pro controller just entirely dying).

Testing with different controller types, OS and Avalonia is welcome. Remember that the target is connecting a ton of controllers, and pulling/reconnecting them.

* Remove double empty line
2024-01-22 17:02:44 -03:00
gdkchan
edc76883db
Fix integer overflow on downsample surround to stereo (#6160) 2024-01-21 21:11:46 +01:00
gdkchan
427b7d06b5
Implement a new JIT for Arm devices (#6057)
* Implement a new JIT for Arm devices

* Auto-format

* Make a lot of Assembler members read-only

* More read-only

* Fix more warnings

* ObjectDisposedException.ThrowIf

* New JIT cache for platforms that enforce W^X, currently unused

* Remove unused using

* Fix assert

* Pass memory manager type around

* Safe memory manager mode support + other improvements

* Actual safe memory manager mode masking support

* PR feedback
2024-01-20 11:11:28 -03:00
riperiperi
331c07807f
Vulkan: Use templates for descriptor updates (#6014)
* WIP: Descriptor template update

* Make configurable

* Wording

* Simplify template creation

* Whitespace

* UTF-8 whatever

* Leave only templated path, better template updater
2024-01-20 11:07:33 -03:00
Steveice10
a772b073ec
Support portable mode using the macOS app bundle. (#6147)
* Support portable mode using the macOS app bundle.

* Apply suggestion

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

---------

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
2024-01-20 03:09:51 +01:00
gdkchan
870d9599cc
Change shader cache init wait method (#6131)
* Change shader cache init wait method

* Make field readonly
2024-01-18 14:17:38 -03:00
gdkchan
2dbbc9bc05
Move most of signal handling to Ryujinx.Cpu project (#6128)
* Move most of signal handling to Ryujinx.Cpu project

* Format whitespace

* Remove unused member

* Format whitespace

* This does not need to be public anymore
2024-01-18 14:08:40 -03:00
Isaac Marovitz
72634c80f4
Ava UI: Update Ava & Friends (#6109)
* Update Ava & Friends

* FA 2.0.5

* Ava 11.0.7

* Fix
2024-01-17 23:50:31 +01:00
riperiperi
bebd8eb822
Vulkan: Cache delegate for EndRenderPass (#6132)
This prevents a small allocation each time this method is called. This is a top 3 SOH allocation during gameplay in most games, and eliminating it is pretty free.
2024-01-16 13:22:20 +01:00
gdkchan
f4b74e9ce1
Fix vertex buffer size when switching between inline and state draw parameters (#6101)
* Fix vertex buffer size when switching between inline and state draw parameters

* Format whitespace
2024-01-14 09:37:19 +01:00
Isaac Marovitz
4e19b36ad7
CI: Dependabot Groups (#6110)
* CI: Dependabot Groups

* NUnit

* Limit of 10

* Whoops

* Missing wildcard

* Remove Ryujank group
2024-01-13 15:28:57 +01:00
gdkchan
b16923a902
Revert Apple hypervisor force ordered memory change (#6068) 2024-01-13 11:58:09 +01:00
TSRBerry
7e58b21f3d
Fix Amiibo regression and some minor code improvements (#6107)
* Remove redundant code and fix small issues

* Log amiibo exceptions

* Add more checks when getting Amiibo data

* Fall back to online data if local file is inaccessible

* Make dotnet format happy
2024-01-13 11:45:38 +01:00
Isaac Marovitz
4fbc978e73
Switch to Microsoft.IdentityModel.JsonWebTokens (#6108)
* Switch to `Microsoft.IdentityModel.JsonWebTokens`

* Formatting
2024-01-13 11:39:00 +01:00
Isaac Marovitz
1a45dc8df8
Ava UI: RTL Language Support (#5619)
* Add Hebrew locale files to ItemGroups

* Align all windows RTL for testing

This should be controlled with a binding that selects the appropriate layout based on current language

* Update FlowDirection as Locale changes

* Fix Settings NavigationViewItem FlowDirection

* Fix remaining text

* Fix input menu directionality

* Fix RTL not rendering

* Fix rebase errors
2024-01-13 01:42:42 +01:00
Isaac Marovitz
f037fcba9a
Ava UI: Better Controller Applet (#5756)
* Start work on better Controller Applet

* Don’t require title

* UI improvements

* Border around TBD area

* Formatting

* Better SVGs

* Add missing margin

* Use Locale

* Rename function

* Make buttons ourselves

* Make the buttons do shit

* Formatting

* Adjust SVGs

* Fix Open Settings Window

* Make field readonly

* Final tweaks

* Update src/Ryujinx.Ava/UI/Applet/AvaHostUiHandler.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update src/Ryujinx.Ava/UI/Applet/ControllerAppletDialog.axaml.cs

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Move icons to Ava project

* Reorder arguments

* Try to focus Settings Window

* Fix icons

Project shenangians

* Add ContentDialogHelper.ShowWindowAsync method

* Fix closed SettingsWindow reference in MainWindow

* Fix SettingsWindow dialog

* Suggestion

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
2024-01-13 01:41:57 +01:00
470 changed files with 68076 additions and 2402 deletions

View File

@ -13,7 +13,7 @@ updates:
- package-ecosystem: nuget
directory: /
open-pull-requests-limit: 5
open-pull-requests-limit: 10
schedule:
interval: daily
labels:
@ -22,3 +22,19 @@ updates:
- marysaka
commit-message:
prefix: nuget
groups:
Avalonia:
patterns:
- "*Avalonia*"
Silk.NET:
patterns:
- "Silk.NET*"
OpenTK:
patterns:
- "OpenTK*"
SixLabors:
patterns:
- "SixLabors*"
NUnit:
patterns:
- "NUnit*"

2
.gitignore vendored
View File

@ -45,7 +45,6 @@ build/
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
@ -173,3 +172,4 @@ PublishProfiles/
# Glade backup files
*.glade~

View File

@ -3,34 +3,35 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Avalonia" Version="11.0.5" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.5" />
<PackageVersion Include="Avalonia.Desktop" Version="11.0.5" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.5" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.5" />
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.3" />
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.3" />
<PackageVersion Include="Avalonia" Version="11.0.7" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.7" />
<PackageVersion Include="Avalonia.Desktop" Version="11.0.7" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.7" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.7" />
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.10" />
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.10" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="Concentus" Version="1.1.7" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageVersion Include="DynamicData" Version="7.14.2" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.4" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" />
<PackageVersion Include="LibHac" Version="0.19.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.2.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
<PackageVersion Include="NetCoreServer" Version="7.0.0" />
<PackageVersion Include="NUnit" Version="3.13.3" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
<PackageVersion Include="OpenTK.Core" Version="4.8.1" />
<PackageVersion Include="OpenTK.Graphics" Version="4.8.1" />
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.1" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.1" />
<PackageVersion Include="OpenTK.Core" Version="4.8.2" />
<PackageVersion Include="OpenTK.Graphics" Version="4.8.2" />
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
<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.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
@ -39,16 +40,16 @@
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.17.1" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.17.1" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.17.1" />
<PackageVersion Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageVersion Include="SPB" Version="0.0.4-build28" />
<PackageVersion Include="System.Drawing.Common" Version="8.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="System.Management" Version="8.0.0" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="Rxmxnx.PInvoke.Extensions" Version="1.0.1" />
</ItemGroup>
</Project>
</Project>

View File

@ -87,6 +87,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon", "src\Ryuj
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Generators", "src\Ryujinx.Horizon.Kernel.Generators\Ryujinx.Horizon.Kernel.Generators.csproj", "{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibRyujinx.Shared", "src\LibRyujinx\LibRyujinx.csproj", "{5BBF478C-A520-41E7-9B88-890AD26766B8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{C75176EB-C44E-449A-8077-A48AD94534EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibRyujinx.NativeSample", "src\LibRyujinx.NativeSample\LibRyujinx.NativeSample.csproj", "{63D2C96B-5194-4592-BC91-30BEB11C06BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -249,6 +255,18 @@ Global
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F55A45D-4E1D-4A36-ADD3-87F29A285AA2}.Release|Any CPU.Build.0 = Release|Any CPU
{5BBF478C-A520-41E7-9B88-890AD26766B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BBF478C-A520-41E7-9B88-890AD26766B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BBF478C-A520-41E7-9B88-890AD26766B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BBF478C-A520-41E7-9B88-890AD26766B8}.Release|Any CPU.Build.0 = Release|Any CPU
{C75176EB-C44E-449A-8077-A48AD94534EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C75176EB-C44E-449A-8077-A48AD94534EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C75176EB-C44E-449A-8077-A48AD94534EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C75176EB-C44E-449A-8077-A48AD94534EE}.Release|Any CPU.Build.0 = Release|Any CPU
{63D2C96B-5194-4592-BC91-30BEB11C06BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63D2C96B-5194-4592-BC91-30BEB11C06BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63D2C96B-5194-4592-BC91-30BEB11C06BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63D2C96B-5194-4592-BC91-30BEB11C06BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -2,6 +2,7 @@
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="nuget"
value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@ -20,7 +20,7 @@ namespace ARMeilleure.CodeGen.Arm64
LinuxFeatureInfoHwCap2 = (LinuxFeatureFlagsHwCap2)getauxval(AT_HWCAP2);
}
if (OperatingSystem.IsMacOS())
if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
{
for (int i = 0; i < _sysctlNames.Length; i++)
{
@ -124,12 +124,13 @@ namespace ARMeilleure.CodeGen.Arm64
#endregion
#region macOS
#region Darwin
[LibraryImport("libSystem.dylib", SetLastError = true)]
private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
[SupportedOSPlatform("macos")]
[SupportedOSPlatform("ios")]
private static bool CheckSysctlName(string name)
{
ulong size = sizeof(int);

View File

@ -9,7 +9,7 @@ namespace ARMeilleure.Common
/// Represents a table of guest address to a value.
/// </summary>
/// <typeparam name="TEntry">Type of the value</typeparam>
unsafe class AddressTable<TEntry> : IDisposable where TEntry : unmanaged
public unsafe class AddressTable<TEntry> : IDisposable where TEntry : unmanaged
{
/// <summary>
/// Represents a level in an <see cref="AddressTable{TEntry}"/>.

View File

@ -4,7 +4,5 @@ namespace ARMeilleure.Memory
{
IJitMemoryBlock Allocate(ulong size);
IJitMemoryBlock Reserve(ulong size);
ulong GetPageSize();
}
}

View File

@ -8,6 +8,7 @@ namespace ARMeilleure.Memory
void Commit(ulong offset, ulong size);
void MapAsRw(ulong offset, ulong size);
void MapAsRx(ulong offset, ulong size);
void MapAsRwx(ulong offset, ulong size);
}

View File

@ -31,7 +31,7 @@ namespace ARMeilleure.Memory
HostMappedUnsafe,
}
static class MemoryManagerTypeExtensions
public static class MemoryManagerTypeExtensions
{
public static bool IsHostMapped(this MemoryManagerType type)
{

View File

@ -2,7 +2,7 @@ using System;
namespace ARMeilleure.Memory
{
class ReservedRegion
public class ReservedRegion
{
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.

View File

@ -5,7 +5,8 @@ using System.Runtime.Versioning;
namespace ARMeilleure.Native
{
[SupportedOSPlatform("macos")]
internal static partial class JitSupportDarwin
[SupportedOSPlatform("ios")]
static partial class JitSupportDarwin
{
[LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")]
public static partial void Copy(IntPtr dst, IntPtr src, ulong n);

View File

@ -1,63 +1,14 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Memory;
using ARMeilleure.Translation;
using ARMeilleure.Translation.Cache;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Signal
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SignalHandlerRange
public static class NativeSignalHandlerGenerator
{
public int IsActive;
public nuint RangeAddress;
public nuint RangeEndAddress;
public IntPtr ActionPointer;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SignalHandlerConfig
{
/// <summary>
/// The byte offset of the faulting address in the SigInfo or ExceptionRecord struct.
/// </summary>
public int StructAddressOffset;
/// <summary>
/// The byte offset of the write flag in the SigInfo or ExceptionRecord struct.
/// </summary>
public int StructWriteOffset;
/// <summary>
/// The sigaction handler that was registered before this one. (unix only)
/// </summary>
public nuint UnixOldSigaction;
/// <summary>
/// The type of the previous sigaction. True for the 3 argument variant. (unix only)
/// </summary>
public int UnixOldSigaction3Arg;
public SignalHandlerRange Range0;
public SignalHandlerRange Range1;
public SignalHandlerRange Range2;
public SignalHandlerRange Range3;
public SignalHandlerRange Range4;
public SignalHandlerRange Range5;
public SignalHandlerRange Range6;
public SignalHandlerRange Range7;
}
public static class NativeSignalHandler
{
private delegate void UnixExceptionHandler(int sig, IntPtr info, IntPtr ucontext);
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate int VectoredExceptionHandler(IntPtr exceptionInfo);
private const int MaxTrackedRanges = 8;
public const int MaxTrackedRanges = 8;
private const int StructAddressOffset = 0;
private const int StructWriteOffset = 4;
@ -70,125 +21,10 @@ namespace ARMeilleure.Signal
private const uint EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
private static ulong _pageSize;
private static ulong _pageMask;
private static readonly IntPtr _handlerConfig;
private static IntPtr _signalHandlerPtr;
private static IntPtr _signalHandlerHandle;
private static readonly object _lock = new();
private static bool _initialized;
static NativeSignalHandler()
private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite, int rangeStructSize, ulong pageSize)
{
_handlerConfig = Marshal.AllocHGlobal(Unsafe.SizeOf<SignalHandlerConfig>());
ref SignalHandlerConfig config = ref GetConfigRef();
ulong pageMask = pageSize - 1;
config = new SignalHandlerConfig();
}
public static void Initialize(IJitMemoryAllocator allocator)
{
JitCache.Initialize(allocator);
}
public static void InitializeSignalHandler(ulong pageSize, Func<IntPtr, IntPtr, IntPtr> customSignalHandlerFactory = null)
{
if (_initialized)
{
return;
}
lock (_lock)
{
if (_initialized)
{
return;
}
_pageSize = pageSize;
_pageMask = pageSize - 1;
ref SignalHandlerConfig config = ref GetConfigRef();
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
_signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateUnixSignalHandler(_handlerConfig));
if (customSignalHandlerFactory != null)
{
_signalHandlerPtr = customSignalHandlerFactory(UnixSignalHandlerRegistration.GetSegfaultExceptionHandler().sa_handler, _signalHandlerPtr);
}
var old = UnixSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr);
config.UnixOldSigaction = (nuint)(ulong)old.sa_handler;
config.UnixOldSigaction3Arg = old.sa_flags & 4;
}
else
{
config.StructAddressOffset = 40; // ExceptionInformation1
config.StructWriteOffset = 32; // ExceptionInformation0
_signalHandlerPtr = Marshal.GetFunctionPointerForDelegate(GenerateWindowsSignalHandler(_handlerConfig));
if (customSignalHandlerFactory != null)
{
_signalHandlerPtr = customSignalHandlerFactory(IntPtr.Zero, _signalHandlerPtr);
}
_signalHandlerHandle = WindowsSignalHandlerRegistration.RegisterExceptionHandler(_signalHandlerPtr);
}
_initialized = true;
}
}
private static unsafe ref SignalHandlerConfig GetConfigRef()
{
return ref Unsafe.AsRef<SignalHandlerConfig>((void*)_handlerConfig);
}
public static unsafe bool AddTrackedRegion(nuint address, nuint endAddress, IntPtr action)
{
var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0;
for (int i = 0; i < MaxTrackedRanges; i++)
{
if (ranges[i].IsActive == 0)
{
ranges[i].RangeAddress = address;
ranges[i].RangeEndAddress = endAddress;
ranges[i].ActionPointer = action;
ranges[i].IsActive = 1;
return true;
}
}
return false;
}
public static unsafe bool RemoveTrackedRegion(nuint address)
{
var ranges = &((SignalHandlerConfig*)_handlerConfig)->Range0;
for (int i = 0; i < MaxTrackedRanges; i++)
{
if (ranges[i].IsActive == 1 && ranges[i].RangeAddress == address)
{
ranges[i].IsActive = 0;
return true;
}
}
return false;
}
private static Operand EmitGenericRegionCheck(EmitterContext context, IntPtr signalStructPtr, Operand faultAddress, Operand isWrite)
{
Operand inRegionLocal = context.AllocateLocal(OperandType.I32);
context.Copy(inRegionLocal, Const(0));
@ -196,7 +32,7 @@ namespace ARMeilleure.Signal
for (int i = 0; i < MaxTrackedRanges; i++)
{
ulong rangeBaseOffset = (ulong)(RangeOffset + i * Unsafe.SizeOf<SignalHandlerRange>());
ulong rangeBaseOffset = (ulong)(RangeOffset + i * rangeStructSize);
Operand nextLabel = Label();
@ -210,13 +46,12 @@ namespace ARMeilleure.Signal
// Is the fault address within this tracked region?
Operand inRange = context.BitwiseAnd(
context.ICompare(faultAddress, rangeAddress, Comparison.GreaterOrEqualUI),
context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI)
);
context.ICompare(faultAddress, rangeEndAddress, Comparison.LessUI));
// Only call tracking if in range.
context.BranchIfFalse(nextLabel, inRange, BasicBlockFrequency.Cold);
Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~_pageMask));
Operand offset = context.BitwiseAnd(context.Subtract(faultAddress, rangeAddress), Const(~pageMask));
// Call the tracking action, with the pointer's relative offset to the base address.
Operand trackingActionPtr = context.Load(OperandType.I64, Const((ulong)signalStructPtr + rangeBaseOffset + 20));
@ -227,7 +62,7 @@ namespace ARMeilleure.Signal
// Tracking action should be non-null to call it, otherwise assume false return.
context.BranchIfFalse(skipActionLabel, trackingActionPtr);
Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(_pageSize), isWrite);
Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(pageSize), isWrite);
context.Copy(inRegionLocal, result);
context.MarkLabel(skipActionLabel);
@ -252,13 +87,13 @@ namespace ARMeilleure.Signal
private static Operand GenerateUnixFaultAddress(EmitterContext context, Operand sigInfoPtr)
{
ulong structAddressOffset = OperatingSystem.IsMacOS() ? 24ul : 16ul; // si_addr
ulong structAddressOffset = (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS()) ? 24ul : 16ul; // si_addr
return context.Load(OperandType.I64, context.Add(sigInfoPtr, Const(structAddressOffset)));
}
private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand ucontextPtr)
{
if (OperatingSystem.IsMacOS())
if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
{
const ulong McontextOffset = 48; // uc_mcontext
Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(McontextOffset)));
@ -269,8 +104,7 @@ namespace ARMeilleure.Signal
Operand esr = context.Load(OperandType.I64, context.Add(ctxPtr, Const(EsrOffset)));
return context.BitwiseAnd(esr, Const(0x40ul));
}
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
{
const ulong ErrOffset = 4; // __es.__err
Operand err = context.Load(OperandType.I64, context.Add(ctxPtr, Const(ErrOffset)));
@ -310,8 +144,7 @@ namespace ARMeilleure.Signal
Operand esr = context.Load(OperandType.I64, context.Add(auxPtr, Const(8ul)));
return context.BitwiseAnd(esr, Const(0x40ul));
}
if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
{
const int ErrOffset = 192; // uc_mcontext.gregs[REG_ERR]
Operand err = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(ErrOffset)));
@ -322,7 +155,7 @@ namespace ARMeilleure.Signal
throw new PlatformNotSupportedException();
}
private static UnixExceptionHandler GenerateUnixSignalHandler(IntPtr signalStructPtr)
public static byte[] GenerateUnixSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize)
{
EmitterContext context = new();
@ -335,7 +168,7 @@ namespace ARMeilleure.Signal
Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1.
Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite);
Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize);
Operand endLabel = Label();
@ -367,10 +200,10 @@ namespace ARMeilleure.Signal
OperandType[] argTypes = new OperandType[] { OperandType.I32, OperandType.I64, OperandType.I64 };
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<UnixExceptionHandler>();
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code;
}
private static VectoredExceptionHandler GenerateWindowsSignalHandler(IntPtr signalStructPtr)
public static byte[] GenerateWindowsSignalHandler(IntPtr signalStructPtr, int rangeStructSize, ulong pageSize)
{
EmitterContext context = new();
@ -399,7 +232,7 @@ namespace ARMeilleure.Signal
Operand isWrite = context.ICompareNotEqual(writeFlag, Const(0L)); // Normalize to 0/1.
Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite);
Operand isInRegion = EmitGenericRegionCheck(context, signalStructPtr, faultAddress, isWrite, rangeStructSize, pageSize);
Operand endLabel = Label();
@ -421,7 +254,7 @@ namespace ARMeilleure.Signal
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<VectoredExceptionHandler>();
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code;
}
}
}

View File

@ -1,83 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Signal
{
static partial class UnixSignalHandlerRegistration
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct SigSet
{
fixed long sa_mask[16];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SigAction
{
public IntPtr sa_handler;
public SigSet sa_mask;
public int sa_flags;
public IntPtr sa_restorer;
}
private const int SIGSEGV = 11;
private const int SIGBUS = 10;
private const int SA_SIGINFO = 0x00000004;
[LibraryImport("libc", SetLastError = true)]
private static partial int sigaction(int signum, ref SigAction sigAction, out SigAction oldAction);
[LibraryImport("libc", SetLastError = true)]
private static partial int sigaction(int signum, IntPtr sigAction, out SigAction oldAction);
[LibraryImport("libc", SetLastError = true)]
private static partial int sigemptyset(ref SigSet set);
public static SigAction GetSegfaultExceptionHandler()
{
int result = sigaction(SIGSEGV, IntPtr.Zero, out SigAction old);
if (result != 0)
{
throw new InvalidOperationException($"Could not get SIGSEGV sigaction. Error: {result}");
}
return old;
}
public static SigAction RegisterExceptionHandler(IntPtr action)
{
SigAction sig = new()
{
sa_handler = action,
sa_flags = SA_SIGINFO,
};
sigemptyset(ref sig.sa_mask);
int result = sigaction(SIGSEGV, ref sig, out SigAction old);
if (result != 0)
{
throw new InvalidOperationException($"Could not register SIGSEGV sigaction. Error: {result}");
}
if (OperatingSystem.IsMacOS())
{
result = sigaction(SIGBUS, ref sig, out _);
if (result != 0)
{
throw new InvalidOperationException($"Could not register SIGBUS sigaction. Error: {result}");
}
}
return old;
}
public static bool RestoreExceptionHandler(SigAction oldAction)
{
return sigaction(SIGSEGV, ref oldAction, out SigAction _) == 0 && (!OperatingSystem.IsMacOS() || sigaction(SIGBUS, ref oldAction, out SigAction _) == 0);
}
}
}

View File

@ -2,7 +2,7 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using Ryujinx.Common.Memory.PartialUnmaps;
using System;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Signal
@ -10,8 +10,28 @@ namespace ARMeilleure.Signal
/// <summary>
/// Methods to handle signals caused by partial unmaps. See the structs for C# implementations of the methods.
/// </summary>
internal static class WindowsPartialUnmapHandler
internal static partial class WindowsPartialUnmapHandler
{
[LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")]
private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
[LibraryImport("kernel32.dll", SetLastError = true)]
private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
private static IntPtr _getCurrentThreadIdPtr;
public static IntPtr GetCurrentThreadIdFunc()
{
if (_getCurrentThreadIdPtr == IntPtr.Zero)
{
IntPtr handle = LoadLibrary("kernel32.dll");
_getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId");
}
return _getCurrentThreadIdPtr;
}
public static Operand EmitRetryFromAccessViolation(EmitterContext context)
{
IntPtr partialRemapStatePtr = PartialUnmapState.GlobalState;
@ -20,7 +40,7 @@ namespace ARMeilleure.Signal
// Get the lock first.
EmitNativeReaderLockAcquire(context, IntPtr.Add(partialRemapStatePtr, PartialUnmapState.PartialUnmapLockOffset));
IntPtr getCurrentThreadId = WindowsSignalHandlerRegistration.GetCurrentThreadIdFunc();
IntPtr getCurrentThreadId = GetCurrentThreadIdFunc();
Operand threadId = context.Call(Const((ulong)getCurrentThreadId), OperandType.I32);
Operand threadIndex = EmitThreadLocalMapIntGetOrReserve(context, localCountsPtr, threadId, Const(0));
@ -137,17 +157,6 @@ namespace ARMeilleure.Signal
return context.Add(structsPtr, context.SignExtend32(OperandType.I64, offset));
}
#pragma warning disable IDE0051 // Remove unused private member
private static void EmitThreadLocalMapIntRelease(EmitterContext context, IntPtr threadLocalMapPtr, Operand threadId, Operand index)
{
Operand offset = context.Multiply(index, Const(sizeof(int)));
Operand idsPtr = Const((ulong)IntPtr.Add(threadLocalMapPtr, ThreadLocalMap<int>.ThreadIdsOffset));
Operand idPtr = context.Add(idsPtr, context.SignExtend32(OperandType.I64, offset));
context.CompareAndSwap(idPtr, threadId, Const(0));
}
#pragma warning restore IDE0051
private static void EmitAtomicAddI32(EmitterContext context, Operand ptr, Operand additive)
{
Operand loop = Label();

View File

@ -1,44 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Signal
{
unsafe partial class WindowsSignalHandlerRegistration
{
[LibraryImport("kernel32.dll")]
private static partial IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler);
[LibraryImport("kernel32.dll")]
private static partial ulong RemoveVectoredExceptionHandler(IntPtr handle);
[LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")]
private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
[LibraryImport("kernel32.dll", SetLastError = true)]
private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
private static IntPtr _getCurrentThreadIdPtr;
public static IntPtr RegisterExceptionHandler(IntPtr action)
{
return AddVectoredExceptionHandler(1, action);
}
public static bool RemoveExceptionHandler(IntPtr handle)
{
return RemoveVectoredExceptionHandler(handle) != 0;
}
public static IntPtr GetCurrentThreadIdFunc()
{
if (_getCurrentThreadIdPtr == IntPtr.Zero)
{
IntPtr handle = LoadLibrary("kernel32.dll");
_getCurrentThreadIdPtr = GetProcAddress(handle, "GetCurrentThreadId");
}
return _getCurrentThreadIdPtr;
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.Translation
{
@ -11,11 +10,10 @@ namespace ARMeilleure.Translation
public IntPtr FuncPtr { get; }
public DelegateInfo(Delegate dlg)
public DelegateInfo(Delegate dlg, IntPtr funcPtr)
{
_dlg = dlg;
FuncPtr = Marshal.GetFunctionPointerForDelegate<Delegate>(dlg);
FuncPtr = funcPtr;
}
}
}

View File

@ -3,6 +3,7 @@ using ARMeilleure.State;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ARMeilleure.Translation
{
@ -64,11 +65,11 @@ namespace ARMeilleure.Translation
return index;
}
private static void SetDelegateInfo(Delegate dlg)
private static void SetDelegateInfo(Delegate dlg, IntPtr funcPtr)
{
string key = GetKey(dlg.Method);
_delegates.Add(key, new DelegateInfo(dlg)); // ArgumentException (key).
_delegates.Add(key, new DelegateInfo(dlg, funcPtr)); // ArgumentException (key).
}
private static string GetKey(MethodInfo info)
@ -82,179 +83,353 @@ namespace ARMeilleure.Translation
{
_delegates = new SortedList<string, DelegateInfo>();
SetDelegateInfo(new MathAbs(Math.Abs));
SetDelegateInfo(new MathCeiling(Math.Ceiling));
SetDelegateInfo(new MathFloor(Math.Floor));
SetDelegateInfo(new MathRound(Math.Round));
SetDelegateInfo(new MathTruncate(Math.Truncate));
var dlgMathAbs = new MathAbs(Math.Abs);
var dlgMathCeiling = new MathCeiling(Math.Ceiling);
var dlgMathFloor = new MathFloor(Math.Floor);
var dlgMathRound = new MathRound(Math.Round);
var dlgMathTruncate = new MathTruncate(Math.Truncate);
SetDelegateInfo(new MathFAbs(MathF.Abs));
SetDelegateInfo(new MathFCeiling(MathF.Ceiling));
SetDelegateInfo(new MathFFloor(MathF.Floor));
SetDelegateInfo(new MathFRound(MathF.Round));
SetDelegateInfo(new MathFTruncate(MathF.Truncate));
var dlgMathFAbs = new MathFAbs(MathF.Abs);
var dlgMathFCeiling = new MathFCeiling(MathF.Ceiling);
var dlgMathFFloor = new MathFFloor(MathF.Floor);
var dlgMathFRound = new MathFRound(MathF.Round);
var dlgMathFTruncate = new MathFTruncate(MathF.Truncate);
SetDelegateInfo(new NativeInterfaceBreak(NativeInterface.Break));
SetDelegateInfo(new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization));
SetDelegateInfo(new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit));
SetDelegateInfo(new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0));
SetDelegateInfo(new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0));
SetDelegateInfo(new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0));
SetDelegateInfo(new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0));
SetDelegateInfo(new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0));
SetDelegateInfo(new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress));
SetDelegateInfo(new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine));
SetDelegateInfo(new NativeInterfaceReadByte(NativeInterface.ReadByte));
SetDelegateInfo(new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16));
SetDelegateInfo(new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32));
SetDelegateInfo(new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64));
SetDelegateInfo(new NativeInterfaceReadVector128(NativeInterface.ReadVector128));
SetDelegateInfo(new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking));
SetDelegateInfo(new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall));
SetDelegateInfo(new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess));
SetDelegateInfo(new NativeInterfaceUndefined(NativeInterface.Undefined));
SetDelegateInfo(new NativeInterfaceWriteByte(NativeInterface.WriteByte));
SetDelegateInfo(new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16));
SetDelegateInfo(new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32));
SetDelegateInfo(new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64));
SetDelegateInfo(new NativeInterfaceWriteVector128(NativeInterface.WriteVector128));
var dlgNativeInterfaceBreak = new NativeInterfaceBreak(NativeInterface.Break);
var dlgNativeInterfaceCheckSynchronization = new NativeInterfaceCheckSynchronization(NativeInterface.CheckSynchronization);
var dlgNativeInterfaceEnqueueForRejit = new NativeInterfaceEnqueueForRejit(NativeInterface.EnqueueForRejit);
var dlgNativeInterfaceGetCntfrqEl0 = new NativeInterfaceGetCntfrqEl0(NativeInterface.GetCntfrqEl0);
var dlgNativeInterfaceGetCntpctEl0 = new NativeInterfaceGetCntpctEl0(NativeInterface.GetCntpctEl0);
var dlgNativeInterfaceGetCntvctEl0 = new NativeInterfaceGetCntvctEl0(NativeInterface.GetCntvctEl0);
var dlgNativeInterfaceGetCtrEl0 = new NativeInterfaceGetCtrEl0(NativeInterface.GetCtrEl0);
var dlgNativeInterfaceGetDczidEl0 = new NativeInterfaceGetDczidEl0(NativeInterface.GetDczidEl0);
var dlgNativeInterfaceGetFunctionAddress = new NativeInterfaceGetFunctionAddress(NativeInterface.GetFunctionAddress);
var dlgNativeInterfaceInvalidateCacheLine = new NativeInterfaceInvalidateCacheLine(NativeInterface.InvalidateCacheLine);
var dlgNativeInterfaceReadByte = new NativeInterfaceReadByte(NativeInterface.ReadByte);
var dlgNativeInterfaceReadUInt16 = new NativeInterfaceReadUInt16(NativeInterface.ReadUInt16);
var dlgNativeInterfaceReadUInt32 = new NativeInterfaceReadUInt32(NativeInterface.ReadUInt32);
var dlgNativeInterfaceReadUInt64 = new NativeInterfaceReadUInt64(NativeInterface.ReadUInt64);
var dlgNativeInterfaceReadVector128 = new NativeInterfaceReadVector128(NativeInterface.ReadVector128);
var dlgNativeInterfaceSignalMemoryTracking = new NativeInterfaceSignalMemoryTracking(NativeInterface.SignalMemoryTracking);
var dlgNativeInterfaceSupervisorCall = new NativeInterfaceSupervisorCall(NativeInterface.SupervisorCall);
var dlgNativeInterfaceThrowInvalidMemoryAccess = new NativeInterfaceThrowInvalidMemoryAccess(NativeInterface.ThrowInvalidMemoryAccess);
var dlgNativeInterfaceUndefined = new NativeInterfaceUndefined(NativeInterface.Undefined);
var dlgNativeInterfaceWriteByte = new NativeInterfaceWriteByte(NativeInterface.WriteByte);
var dlgNativeInterfaceWriteUInt16 = new NativeInterfaceWriteUInt16(NativeInterface.WriteUInt16);
var dlgNativeInterfaceWriteUInt32 = new NativeInterfaceWriteUInt32(NativeInterface.WriteUInt32);
var dlgNativeInterfaceWriteUInt64 = new NativeInterfaceWriteUInt64(NativeInterface.WriteUInt64);
var dlgNativeInterfaceWriteVector128 = new NativeInterfaceWriteVector128(NativeInterface.WriteVector128);
SetDelegateInfo(new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns));
SetDelegateInfo(new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros));
SetDelegateInfo(new SoftFallbackCrc32b(SoftFallback.Crc32b));
SetDelegateInfo(new SoftFallbackCrc32cb(SoftFallback.Crc32cb));
SetDelegateInfo(new SoftFallbackCrc32ch(SoftFallback.Crc32ch));
SetDelegateInfo(new SoftFallbackCrc32cw(SoftFallback.Crc32cw));
SetDelegateInfo(new SoftFallbackCrc32cx(SoftFallback.Crc32cx));
SetDelegateInfo(new SoftFallbackCrc32h(SoftFallback.Crc32h));
SetDelegateInfo(new SoftFallbackCrc32w(SoftFallback.Crc32w));
SetDelegateInfo(new SoftFallbackCrc32x(SoftFallback.Crc32x));
SetDelegateInfo(new SoftFallbackDecrypt(SoftFallback.Decrypt));
SetDelegateInfo(new SoftFallbackEncrypt(SoftFallback.Encrypt));
SetDelegateInfo(new SoftFallbackFixedRotate(SoftFallback.FixedRotate));
SetDelegateInfo(new SoftFallbackHashChoose(SoftFallback.HashChoose));
SetDelegateInfo(new SoftFallbackHashLower(SoftFallback.HashLower));
SetDelegateInfo(new SoftFallbackHashMajority(SoftFallback.HashMajority));
SetDelegateInfo(new SoftFallbackHashParity(SoftFallback.HashParity));
SetDelegateInfo(new SoftFallbackHashUpper(SoftFallback.HashUpper));
SetDelegateInfo(new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns));
SetDelegateInfo(new SoftFallbackMixColumns(SoftFallback.MixColumns));
SetDelegateInfo(new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128));
SetDelegateInfo(new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32));
SetDelegateInfo(new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64));
SetDelegateInfo(new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32));
SetDelegateInfo(new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64));
SetDelegateInfo(new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32));
SetDelegateInfo(new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64));
SetDelegateInfo(new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32));
SetDelegateInfo(new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64));
SetDelegateInfo(new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1));
SetDelegateInfo(new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2));
SetDelegateInfo(new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1));
SetDelegateInfo(new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2));
SetDelegateInfo(new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64));
SetDelegateInfo(new SoftFallbackTbl1(SoftFallback.Tbl1));
SetDelegateInfo(new SoftFallbackTbl2(SoftFallback.Tbl2));
SetDelegateInfo(new SoftFallbackTbl3(SoftFallback.Tbl3));
SetDelegateInfo(new SoftFallbackTbl4(SoftFallback.Tbl4));
SetDelegateInfo(new SoftFallbackTbx1(SoftFallback.Tbx1));
SetDelegateInfo(new SoftFallbackTbx2(SoftFallback.Tbx2));
SetDelegateInfo(new SoftFallbackTbx3(SoftFallback.Tbx3));
SetDelegateInfo(new SoftFallbackTbx4(SoftFallback.Tbx4));
SetDelegateInfo(new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64));
var dlgSoftFallbackCountLeadingSigns = new SoftFallbackCountLeadingSigns(SoftFallback.CountLeadingSigns);
var dlgSoftFallbackCountLeadingZeros = new SoftFallbackCountLeadingZeros(SoftFallback.CountLeadingZeros);
var dlgSoftFallbackCrc32b = new SoftFallbackCrc32b(SoftFallback.Crc32b);
var dlgSoftFallbackCrc32cb = new SoftFallbackCrc32cb(SoftFallback.Crc32cb);
var dlgSoftFallbackCrc32ch = new SoftFallbackCrc32ch(SoftFallback.Crc32ch);
var dlgSoftFallbackCrc32cw = new SoftFallbackCrc32cw(SoftFallback.Crc32cw);
var dlgSoftFallbackCrc32cx = new SoftFallbackCrc32cx(SoftFallback.Crc32cx);
var dlgSoftFallbackCrc32h = new SoftFallbackCrc32h(SoftFallback.Crc32h);
var dlgSoftFallbackCrc32w = new SoftFallbackCrc32w(SoftFallback.Crc32w);
var dlgSoftFallbackCrc32x = new SoftFallbackCrc32x(SoftFallback.Crc32x);
var dlgSoftFallbackDecrypt = new SoftFallbackDecrypt(SoftFallback.Decrypt);
var dlgSoftFallbackEncrypt = new SoftFallbackEncrypt(SoftFallback.Encrypt);
var dlgSoftFallbackFixedRotate = new SoftFallbackFixedRotate(SoftFallback.FixedRotate);
var dlgSoftFallbackHashChoose = new SoftFallbackHashChoose(SoftFallback.HashChoose);
var dlgSoftFallbackHashLower = new SoftFallbackHashLower(SoftFallback.HashLower);
var dlgSoftFallbackHashMajority = new SoftFallbackHashMajority(SoftFallback.HashMajority);
var dlgSoftFallbackHashParity = new SoftFallbackHashParity(SoftFallback.HashParity);
var dlgSoftFallbackHashUpper = new SoftFallbackHashUpper(SoftFallback.HashUpper);
var dlgSoftFallbackInverseMixColumns = new SoftFallbackInverseMixColumns(SoftFallback.InverseMixColumns);
var dlgSoftFallbackMixColumns = new SoftFallbackMixColumns(SoftFallback.MixColumns);
var dlgSoftFallbackPolynomialMult64_128 = new SoftFallbackPolynomialMult64_128(SoftFallback.PolynomialMult64_128);
var dlgSoftFallbackSatF32ToS32 = new SoftFallbackSatF32ToS32(SoftFallback.SatF32ToS32);
var dlgSoftFallbackSatF32ToS64 = new SoftFallbackSatF32ToS64(SoftFallback.SatF32ToS64);
var dlgSoftFallbackSatF32ToU32 = new SoftFallbackSatF32ToU32(SoftFallback.SatF32ToU32);
var dlgSoftFallbackSatF32ToU64 = new SoftFallbackSatF32ToU64(SoftFallback.SatF32ToU64);
var dlgSoftFallbackSatF64ToS32 = new SoftFallbackSatF64ToS32(SoftFallback.SatF64ToS32);
var dlgSoftFallbackSatF64ToS64 = new SoftFallbackSatF64ToS64(SoftFallback.SatF64ToS64);
var dlgSoftFallbackSatF64ToU32 = new SoftFallbackSatF64ToU32(SoftFallback.SatF64ToU32);
var dlgSoftFallbackSatF64ToU64 = new SoftFallbackSatF64ToU64(SoftFallback.SatF64ToU64);
var dlgSoftFallbackSha1SchedulePart1 = new SoftFallbackSha1SchedulePart1(SoftFallback.Sha1SchedulePart1);
var dlgSoftFallbackSha1SchedulePart2 = new SoftFallbackSha1SchedulePart2(SoftFallback.Sha1SchedulePart2);
var dlgSoftFallbackSha256SchedulePart1 = new SoftFallbackSha256SchedulePart1(SoftFallback.Sha256SchedulePart1);
var dlgSoftFallbackSha256SchedulePart2 = new SoftFallbackSha256SchedulePart2(SoftFallback.Sha256SchedulePart2);
var dlgSoftFallbackSignedShrImm64 = new SoftFallbackSignedShrImm64(SoftFallback.SignedShrImm64);
var dlgSoftFallbackTbl1 = new SoftFallbackTbl1(SoftFallback.Tbl1);
var dlgSoftFallbackTbl2 = new SoftFallbackTbl2(SoftFallback.Tbl2);
var dlgSoftFallbackTbl3 = new SoftFallbackTbl3(SoftFallback.Tbl3);
var dlgSoftFallbackTbl4 = new SoftFallbackTbl4(SoftFallback.Tbl4);
var dlgSoftFallbackTbx1 = new SoftFallbackTbx1(SoftFallback.Tbx1);
var dlgSoftFallbackTbx2 = new SoftFallbackTbx2(SoftFallback.Tbx2);
var dlgSoftFallbackTbx3 = new SoftFallbackTbx3(SoftFallback.Tbx3);
var dlgSoftFallbackTbx4 = new SoftFallbackTbx4(SoftFallback.Tbx4);
var dlgSoftFallbackUnsignedShrImm64 = new SoftFallbackUnsignedShrImm64(SoftFallback.UnsignedShrImm64);
SetDelegateInfo(new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert));
SetDelegateInfo(new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert));
var dlgSoftFloat16_32FPConvert = new SoftFloat16_32FPConvert(SoftFloat16_32.FPConvert);
var dlgSoftFloat16_64FPConvert = new SoftFloat16_64FPConvert(SoftFloat16_64.FPConvert);
SetDelegateInfo(new SoftFloat32FPAdd(SoftFloat32.FPAdd));
SetDelegateInfo(new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPCompare(SoftFloat32.FPCompare));
SetDelegateInfo(new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ));
SetDelegateInfo(new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE));
SetDelegateInfo(new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT));
SetDelegateInfo(new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE));
SetDelegateInfo(new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT));
SetDelegateInfo(new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPDiv(SoftFloat32.FPDiv));
SetDelegateInfo(new SoftFloat32FPMax(SoftFloat32.FPMax));
SetDelegateInfo(new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum));
SetDelegateInfo(new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMin(SoftFloat32.FPMin));
SetDelegateInfo(new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMinNum(SoftFloat32.FPMinNum));
SetDelegateInfo(new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMul(SoftFloat32.FPMul));
SetDelegateInfo(new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd));
SetDelegateInfo(new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMulSub(SoftFloat32.FPMulSub));
SetDelegateInfo(new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPMulX(SoftFloat32.FPMulX));
SetDelegateInfo(new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd));
SetDelegateInfo(new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub));
SetDelegateInfo(new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate));
SetDelegateInfo(new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep)); // A32 only.
SetDelegateInfo(new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused));
SetDelegateInfo(new SoftFloat32FPRecpX(SoftFloat32.FPRecpX));
SetDelegateInfo(new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate));
SetDelegateInfo(new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep)); // A32 only.
SetDelegateInfo(new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused));
SetDelegateInfo(new SoftFloat32FPSqrt(SoftFloat32.FPSqrt));
SetDelegateInfo(new SoftFloat32FPSub(SoftFloat32.FPSub));
var dlgSoftFloat32FPAdd = new SoftFloat32FPAdd(SoftFloat32.FPAdd);
var dlgSoftFloat32FPAddFpscr = new SoftFloat32FPAddFpscr(SoftFloat32.FPAddFpscr); // A32 only.
var dlgSoftFloat32FPCompare = new SoftFloat32FPCompare(SoftFloat32.FPCompare);
var dlgSoftFloat32FPCompareEQ = new SoftFloat32FPCompareEQ(SoftFloat32.FPCompareEQ);
var dlgSoftFloat32FPCompareEQFpscr = new SoftFloat32FPCompareEQFpscr(SoftFloat32.FPCompareEQFpscr); // A32 only.
var dlgSoftFloat32FPCompareGE = new SoftFloat32FPCompareGE(SoftFloat32.FPCompareGE);
var dlgSoftFloat32FPCompareGEFpscr = new SoftFloat32FPCompareGEFpscr(SoftFloat32.FPCompareGEFpscr); // A32 only.
var dlgSoftFloat32FPCompareGT = new SoftFloat32FPCompareGT(SoftFloat32.FPCompareGT);
var dlgSoftFloat32FPCompareGTFpscr = new SoftFloat32FPCompareGTFpscr(SoftFloat32.FPCompareGTFpscr); // A32 only.
var dlgSoftFloat32FPCompareLE = new SoftFloat32FPCompareLE(SoftFloat32.FPCompareLE);
var dlgSoftFloat32FPCompareLEFpscr = new SoftFloat32FPCompareLEFpscr(SoftFloat32.FPCompareLEFpscr); // A32 only.
var dlgSoftFloat32FPCompareLT = new SoftFloat32FPCompareLT(SoftFloat32.FPCompareLT);
var dlgSoftFloat32FPCompareLTFpscr = new SoftFloat32FPCompareLTFpscr(SoftFloat32.FPCompareLTFpscr); // A32 only.
var dlgSoftFloat32FPDiv = new SoftFloat32FPDiv(SoftFloat32.FPDiv);
var dlgSoftFloat32FPMax = new SoftFloat32FPMax(SoftFloat32.FPMax);
var dlgSoftFloat32FPMaxFpscr = new SoftFloat32FPMaxFpscr(SoftFloat32.FPMaxFpscr); // A32 only.
var dlgSoftFloat32FPMaxNum = new SoftFloat32FPMaxNum(SoftFloat32.FPMaxNum);
var dlgSoftFloat32FPMaxNumFpscr = new SoftFloat32FPMaxNumFpscr(SoftFloat32.FPMaxNumFpscr); // A32 only.
var dlgSoftFloat32FPMin = new SoftFloat32FPMin(SoftFloat32.FPMin);
var dlgSoftFloat32FPMinFpscr = new SoftFloat32FPMinFpscr(SoftFloat32.FPMinFpscr); // A32 only.
var dlgSoftFloat32FPMinNum = new SoftFloat32FPMinNum(SoftFloat32.FPMinNum);
var dlgSoftFloat32FPMinNumFpscr = new SoftFloat32FPMinNumFpscr(SoftFloat32.FPMinNumFpscr); // A32 only.
var dlgSoftFloat32FPMul = new SoftFloat32FPMul(SoftFloat32.FPMul);
var dlgSoftFloat32FPMulFpscr = new SoftFloat32FPMulFpscr(SoftFloat32.FPMulFpscr); // A32 only.
var dlgSoftFloat32FPMulAdd = new SoftFloat32FPMulAdd(SoftFloat32.FPMulAdd);
var dlgSoftFloat32FPMulAddFpscr = new SoftFloat32FPMulAddFpscr(SoftFloat32.FPMulAddFpscr); // A32 only.
var dlgSoftFloat32FPMulSub = new SoftFloat32FPMulSub(SoftFloat32.FPMulSub);
var dlgSoftFloat32FPMulSubFpscr = new SoftFloat32FPMulSubFpscr(SoftFloat32.FPMulSubFpscr); // A32 only.
var dlgSoftFloat32FPMulX = new SoftFloat32FPMulX(SoftFloat32.FPMulX);
var dlgSoftFloat32FPNegMulAdd = new SoftFloat32FPNegMulAdd(SoftFloat32.FPNegMulAdd);
var dlgSoftFloat32FPNegMulSub = new SoftFloat32FPNegMulSub(SoftFloat32.FPNegMulSub);
var dlgSoftFloat32FPRecipEstimate = new SoftFloat32FPRecipEstimate(SoftFloat32.FPRecipEstimate);
var dlgSoftFloat32FPRecipEstimateFpscr = new SoftFloat32FPRecipEstimateFpscr(SoftFloat32.FPRecipEstimateFpscr); // A32 only.
var dlgSoftFloat32FPRecipStep = new SoftFloat32FPRecipStep(SoftFloat32.FPRecipStep); // A32 only.
var dlgSoftFloat32FPRecipStepFused = new SoftFloat32FPRecipStepFused(SoftFloat32.FPRecipStepFused);
var dlgSoftFloat32FPRecpX = new SoftFloat32FPRecpX(SoftFloat32.FPRecpX);
var dlgSoftFloat32FPRSqrtEstimate = new SoftFloat32FPRSqrtEstimate(SoftFloat32.FPRSqrtEstimate);
var dlgSoftFloat32FPRSqrtEstimateFpscr = new SoftFloat32FPRSqrtEstimateFpscr(SoftFloat32.FPRSqrtEstimateFpscr); // A32 only.
var dlgSoftFloat32FPRSqrtStep = new SoftFloat32FPRSqrtStep(SoftFloat32.FPRSqrtStep); // A32 only.
var dlgSoftFloat32FPRSqrtStepFused = new SoftFloat32FPRSqrtStepFused(SoftFloat32.FPRSqrtStepFused);
var dlgSoftFloat32FPSqrt = new SoftFloat32FPSqrt(SoftFloat32.FPSqrt);
var dlgSoftFloat32FPSub = new SoftFloat32FPSub(SoftFloat32.FPSub);
SetDelegateInfo(new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert));
var dlgSoftFloat32_16FPConvert = new SoftFloat32_16FPConvert(SoftFloat32_16.FPConvert);
SetDelegateInfo(new SoftFloat64FPAdd(SoftFloat64.FPAdd));
SetDelegateInfo(new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPCompare(SoftFloat64.FPCompare));
SetDelegateInfo(new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ));
SetDelegateInfo(new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE));
SetDelegateInfo(new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT));
SetDelegateInfo(new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE));
SetDelegateInfo(new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT));
SetDelegateInfo(new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPDiv(SoftFloat64.FPDiv));
SetDelegateInfo(new SoftFloat64FPMax(SoftFloat64.FPMax));
SetDelegateInfo(new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum));
SetDelegateInfo(new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMin(SoftFloat64.FPMin));
SetDelegateInfo(new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMinNum(SoftFloat64.FPMinNum));
SetDelegateInfo(new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMul(SoftFloat64.FPMul));
SetDelegateInfo(new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd));
SetDelegateInfo(new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMulSub(SoftFloat64.FPMulSub));
SetDelegateInfo(new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPMulX(SoftFloat64.FPMulX));
SetDelegateInfo(new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd));
SetDelegateInfo(new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub));
SetDelegateInfo(new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate));
SetDelegateInfo(new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep)); // A32 only.
SetDelegateInfo(new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused));
SetDelegateInfo(new SoftFloat64FPRecpX(SoftFloat64.FPRecpX));
SetDelegateInfo(new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate));
SetDelegateInfo(new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep)); // A32 only.
SetDelegateInfo(new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused));
SetDelegateInfo(new SoftFloat64FPSqrt(SoftFloat64.FPSqrt));
SetDelegateInfo(new SoftFloat64FPSub(SoftFloat64.FPSub));
var dlgSoftFloat64FPAdd = new SoftFloat64FPAdd(SoftFloat64.FPAdd);
var dlgSoftFloat64FPAddFpscr = new SoftFloat64FPAddFpscr(SoftFloat64.FPAddFpscr); // A32 only.
var dlgSoftFloat64FPCompare = new SoftFloat64FPCompare(SoftFloat64.FPCompare);
var dlgSoftFloat64FPCompareEQ = new SoftFloat64FPCompareEQ(SoftFloat64.FPCompareEQ);
var dlgSoftFloat64FPCompareEQFpscr = new SoftFloat64FPCompareEQFpscr(SoftFloat64.FPCompareEQFpscr); // A32 only.
var dlgSoftFloat64FPCompareGE = new SoftFloat64FPCompareGE(SoftFloat64.FPCompareGE);
var dlgSoftFloat64FPCompareGEFpscr = new SoftFloat64FPCompareGEFpscr(SoftFloat64.FPCompareGEFpscr); // A32 only.
var dlgSoftFloat64FPCompareGT = new SoftFloat64FPCompareGT(SoftFloat64.FPCompareGT);
var dlgSoftFloat64FPCompareGTFpscr = new SoftFloat64FPCompareGTFpscr(SoftFloat64.FPCompareGTFpscr); // A32 only.
var dlgSoftFloat64FPCompareLE = new SoftFloat64FPCompareLE(SoftFloat64.FPCompareLE);
var dlgSoftFloat64FPCompareLEFpscr = new SoftFloat64FPCompareLEFpscr(SoftFloat64.FPCompareLEFpscr); // A32 only.
var dlgSoftFloat64FPCompareLT = new SoftFloat64FPCompareLT(SoftFloat64.FPCompareLT);
var dlgSoftFloat64FPCompareLTFpscr = new SoftFloat64FPCompareLTFpscr(SoftFloat64.FPCompareLTFpscr); // A32 only.
var dlgSoftFloat64FPDiv = new SoftFloat64FPDiv(SoftFloat64.FPDiv);
var dlgSoftFloat64FPMax = new SoftFloat64FPMax(SoftFloat64.FPMax);
var dlgSoftFloat64FPMaxFpscr = new SoftFloat64FPMaxFpscr(SoftFloat64.FPMaxFpscr); // A32 only.
var dlgSoftFloat64FPMaxNum = new SoftFloat64FPMaxNum(SoftFloat64.FPMaxNum);
var dlgSoftFloat64FPMaxNumFpscr = new SoftFloat64FPMaxNumFpscr(SoftFloat64.FPMaxNumFpscr); // A32 only.
var dlgSoftFloat64FPMin = new SoftFloat64FPMin(SoftFloat64.FPMin);
var dlgSoftFloat64FPMinFpscr = new SoftFloat64FPMinFpscr(SoftFloat64.FPMinFpscr); // A32 only.
var dlgSoftFloat64FPMinNum = new SoftFloat64FPMinNum(SoftFloat64.FPMinNum);
var dlgSoftFloat64FPMinNumFpscr = new SoftFloat64FPMinNumFpscr(SoftFloat64.FPMinNumFpscr); // A32 only.
var dlgSoftFloat64FPMul = new SoftFloat64FPMul(SoftFloat64.FPMul);
var dlgSoftFloat64FPMulFpscr = new SoftFloat64FPMulFpscr(SoftFloat64.FPMulFpscr); // A32 only.
var dlgSoftFloat64FPMulAdd = new SoftFloat64FPMulAdd(SoftFloat64.FPMulAdd);
var dlgSoftFloat64FPMulAddFpscr = new SoftFloat64FPMulAddFpscr(SoftFloat64.FPMulAddFpscr); // A32 only.
var dlgSoftFloat64FPMulSub = new SoftFloat64FPMulSub(SoftFloat64.FPMulSub);
var dlgSoftFloat64FPMulSubFpscr = new SoftFloat64FPMulSubFpscr(SoftFloat64.FPMulSubFpscr); // A32 only.
var dlgSoftFloat64FPMulX = new SoftFloat64FPMulX(SoftFloat64.FPMulX);
var dlgSoftFloat64FPNegMulAdd = new SoftFloat64FPNegMulAdd(SoftFloat64.FPNegMulAdd);
var dlgSoftFloat64FPNegMulSub = new SoftFloat64FPNegMulSub(SoftFloat64.FPNegMulSub);
var dlgSoftFloat64FPRecipEstimate = new SoftFloat64FPRecipEstimate(SoftFloat64.FPRecipEstimate);
var dlgSoftFloat64FPRecipEstimateFpscr = new SoftFloat64FPRecipEstimateFpscr(SoftFloat64.FPRecipEstimateFpscr); // A32 only.
var dlgSoftFloat64FPRecipStep = new SoftFloat64FPRecipStep(SoftFloat64.FPRecipStep); // A32 only.
var dlgSoftFloat64FPRecipStepFused = new SoftFloat64FPRecipStepFused(SoftFloat64.FPRecipStepFused);
var dlgSoftFloat64FPRecpX = new SoftFloat64FPRecpX(SoftFloat64.FPRecpX);
var dlgSoftFloat64FPRSqrtEstimate = new SoftFloat64FPRSqrtEstimate(SoftFloat64.FPRSqrtEstimate);
var dlgSoftFloat64FPRSqrtEstimateFpscr = new SoftFloat64FPRSqrtEstimateFpscr(SoftFloat64.FPRSqrtEstimateFpscr); // A32 only.
var dlgSoftFloat64FPRSqrtStep = new SoftFloat64FPRSqrtStep(SoftFloat64.FPRSqrtStep); // A32 only.
var dlgSoftFloat64FPRSqrtStepFused = new SoftFloat64FPRSqrtStepFused(SoftFloat64.FPRSqrtStepFused);
var dlgSoftFloat64FPSqrt = new SoftFloat64FPSqrt(SoftFloat64.FPSqrt);
var dlgSoftFloat64FPSub = new SoftFloat64FPSub(SoftFloat64.FPSub);
SetDelegateInfo(new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert));
var dlgSoftFloat64_16FPConvert = new SoftFloat64_16FPConvert(SoftFloat64_16.FPConvert);
SetDelegateInfo(dlgMathAbs, Marshal.GetFunctionPointerForDelegate<MathAbs>(dlgMathAbs));
SetDelegateInfo(dlgMathCeiling, Marshal.GetFunctionPointerForDelegate<MathCeiling>(dlgMathCeiling));
SetDelegateInfo(dlgMathFloor, Marshal.GetFunctionPointerForDelegate<MathFloor>(dlgMathFloor));
SetDelegateInfo(dlgMathRound, Marshal.GetFunctionPointerForDelegate<MathRound>(dlgMathRound));
SetDelegateInfo(dlgMathTruncate, Marshal.GetFunctionPointerForDelegate<MathTruncate>(dlgMathTruncate));
SetDelegateInfo(dlgMathFAbs, Marshal.GetFunctionPointerForDelegate<MathFAbs>(dlgMathFAbs));
SetDelegateInfo(dlgMathFCeiling, Marshal.GetFunctionPointerForDelegate<MathFCeiling>(dlgMathFCeiling));
SetDelegateInfo(dlgMathFFloor, Marshal.GetFunctionPointerForDelegate<MathFFloor>(dlgMathFFloor));
SetDelegateInfo(dlgMathFRound, Marshal.GetFunctionPointerForDelegate<MathFRound>(dlgMathFRound));
SetDelegateInfo(dlgMathFTruncate, Marshal.GetFunctionPointerForDelegate<MathFTruncate>(dlgMathFTruncate));
SetDelegateInfo(dlgNativeInterfaceBreak, Marshal.GetFunctionPointerForDelegate<NativeInterfaceBreak>(dlgNativeInterfaceBreak));
SetDelegateInfo(dlgNativeInterfaceCheckSynchronization, Marshal.GetFunctionPointerForDelegate<NativeInterfaceCheckSynchronization>(dlgNativeInterfaceCheckSynchronization));
SetDelegateInfo(dlgNativeInterfaceEnqueueForRejit, Marshal.GetFunctionPointerForDelegate<NativeInterfaceEnqueueForRejit>(dlgNativeInterfaceEnqueueForRejit));
SetDelegateInfo(dlgNativeInterfaceGetCntfrqEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntfrqEl0>(dlgNativeInterfaceGetCntfrqEl0));
SetDelegateInfo(dlgNativeInterfaceGetCntpctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntpctEl0>(dlgNativeInterfaceGetCntpctEl0));
SetDelegateInfo(dlgNativeInterfaceGetCntvctEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCntvctEl0>(dlgNativeInterfaceGetCntvctEl0));
SetDelegateInfo(dlgNativeInterfaceGetCtrEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetCtrEl0>(dlgNativeInterfaceGetCtrEl0));
SetDelegateInfo(dlgNativeInterfaceGetDczidEl0, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetDczidEl0>(dlgNativeInterfaceGetDczidEl0));
SetDelegateInfo(dlgNativeInterfaceGetFunctionAddress, Marshal.GetFunctionPointerForDelegate<NativeInterfaceGetFunctionAddress>(dlgNativeInterfaceGetFunctionAddress));
SetDelegateInfo(dlgNativeInterfaceInvalidateCacheLine, Marshal.GetFunctionPointerForDelegate<NativeInterfaceInvalidateCacheLine>(dlgNativeInterfaceInvalidateCacheLine));
SetDelegateInfo(dlgNativeInterfaceReadByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadByte>(dlgNativeInterfaceReadByte));
SetDelegateInfo(dlgNativeInterfaceReadUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt16>(dlgNativeInterfaceReadUInt16));
SetDelegateInfo(dlgNativeInterfaceReadUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt32>(dlgNativeInterfaceReadUInt32));
SetDelegateInfo(dlgNativeInterfaceReadUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadUInt64>(dlgNativeInterfaceReadUInt64));
SetDelegateInfo(dlgNativeInterfaceReadVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceReadVector128>(dlgNativeInterfaceReadVector128));
SetDelegateInfo(dlgNativeInterfaceSignalMemoryTracking, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSignalMemoryTracking>(dlgNativeInterfaceSignalMemoryTracking));
SetDelegateInfo(dlgNativeInterfaceSupervisorCall, Marshal.GetFunctionPointerForDelegate<NativeInterfaceSupervisorCall>(dlgNativeInterfaceSupervisorCall));
SetDelegateInfo(dlgNativeInterfaceThrowInvalidMemoryAccess, Marshal.GetFunctionPointerForDelegate<NativeInterfaceThrowInvalidMemoryAccess>(dlgNativeInterfaceThrowInvalidMemoryAccess));
SetDelegateInfo(dlgNativeInterfaceUndefined, Marshal.GetFunctionPointerForDelegate<NativeInterfaceUndefined>(dlgNativeInterfaceUndefined));
SetDelegateInfo(dlgNativeInterfaceWriteByte, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteByte>(dlgNativeInterfaceWriteByte));
SetDelegateInfo(dlgNativeInterfaceWriteUInt16, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt16>(dlgNativeInterfaceWriteUInt16));
SetDelegateInfo(dlgNativeInterfaceWriteUInt32, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt32>(dlgNativeInterfaceWriteUInt32));
SetDelegateInfo(dlgNativeInterfaceWriteUInt64, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteUInt64>(dlgNativeInterfaceWriteUInt64));
SetDelegateInfo(dlgNativeInterfaceWriteVector128, Marshal.GetFunctionPointerForDelegate<NativeInterfaceWriteVector128>(dlgNativeInterfaceWriteVector128));
SetDelegateInfo(dlgSoftFallbackCountLeadingSigns, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingSigns>(dlgSoftFallbackCountLeadingSigns));
SetDelegateInfo(dlgSoftFallbackCountLeadingZeros, Marshal.GetFunctionPointerForDelegate<SoftFallbackCountLeadingZeros>(dlgSoftFallbackCountLeadingZeros));
SetDelegateInfo(dlgSoftFallbackCrc32b, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32b>(dlgSoftFallbackCrc32b));
SetDelegateInfo(dlgSoftFallbackCrc32cb, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cb>(dlgSoftFallbackCrc32cb));
SetDelegateInfo(dlgSoftFallbackCrc32ch, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32ch>(dlgSoftFallbackCrc32ch));
SetDelegateInfo(dlgSoftFallbackCrc32cw, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cw>(dlgSoftFallbackCrc32cw));
SetDelegateInfo(dlgSoftFallbackCrc32cx, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32cx>(dlgSoftFallbackCrc32cx));
SetDelegateInfo(dlgSoftFallbackCrc32h, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32h>(dlgSoftFallbackCrc32h));
SetDelegateInfo(dlgSoftFallbackCrc32w, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32w>(dlgSoftFallbackCrc32w));
SetDelegateInfo(dlgSoftFallbackCrc32x, Marshal.GetFunctionPointerForDelegate<SoftFallbackCrc32x>(dlgSoftFallbackCrc32x));
SetDelegateInfo(dlgSoftFallbackDecrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackDecrypt>(dlgSoftFallbackDecrypt));
SetDelegateInfo(dlgSoftFallbackEncrypt, Marshal.GetFunctionPointerForDelegate<SoftFallbackEncrypt>(dlgSoftFallbackEncrypt));
SetDelegateInfo(dlgSoftFallbackFixedRotate, Marshal.GetFunctionPointerForDelegate<SoftFallbackFixedRotate>(dlgSoftFallbackFixedRotate));
SetDelegateInfo(dlgSoftFallbackHashChoose, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashChoose>(dlgSoftFallbackHashChoose));
SetDelegateInfo(dlgSoftFallbackHashLower, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashLower>(dlgSoftFallbackHashLower));
SetDelegateInfo(dlgSoftFallbackHashMajority, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashMajority>(dlgSoftFallbackHashMajority));
SetDelegateInfo(dlgSoftFallbackHashParity, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashParity>(dlgSoftFallbackHashParity));
SetDelegateInfo(dlgSoftFallbackHashUpper, Marshal.GetFunctionPointerForDelegate<SoftFallbackHashUpper>(dlgSoftFallbackHashUpper));
SetDelegateInfo(dlgSoftFallbackInverseMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackInverseMixColumns>(dlgSoftFallbackInverseMixColumns));
SetDelegateInfo(dlgSoftFallbackMixColumns, Marshal.GetFunctionPointerForDelegate<SoftFallbackMixColumns>(dlgSoftFallbackMixColumns));
SetDelegateInfo(dlgSoftFallbackPolynomialMult64_128, Marshal.GetFunctionPointerForDelegate<SoftFallbackPolynomialMult64_128>(dlgSoftFallbackPolynomialMult64_128));
SetDelegateInfo(dlgSoftFallbackSatF32ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS32>(dlgSoftFallbackSatF32ToS32));
SetDelegateInfo(dlgSoftFallbackSatF32ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToS64>(dlgSoftFallbackSatF32ToS64));
SetDelegateInfo(dlgSoftFallbackSatF32ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU32>(dlgSoftFallbackSatF32ToU32));
SetDelegateInfo(dlgSoftFallbackSatF32ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF32ToU64>(dlgSoftFallbackSatF32ToU64));
SetDelegateInfo(dlgSoftFallbackSatF64ToS32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS32>(dlgSoftFallbackSatF64ToS32));
SetDelegateInfo(dlgSoftFallbackSatF64ToS64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToS64>(dlgSoftFallbackSatF64ToS64));
SetDelegateInfo(dlgSoftFallbackSatF64ToU32, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU32>(dlgSoftFallbackSatF64ToU32));
SetDelegateInfo(dlgSoftFallbackSatF64ToU64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSatF64ToU64>(dlgSoftFallbackSatF64ToU64));
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart1>(dlgSoftFallbackSha1SchedulePart1));
SetDelegateInfo(dlgSoftFallbackSha1SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha1SchedulePart2>(dlgSoftFallbackSha1SchedulePart2));
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart1, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart1>(dlgSoftFallbackSha256SchedulePart1));
SetDelegateInfo(dlgSoftFallbackSha256SchedulePart2, Marshal.GetFunctionPointerForDelegate<SoftFallbackSha256SchedulePart2>(dlgSoftFallbackSha256SchedulePart2));
SetDelegateInfo(dlgSoftFallbackSignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackSignedShrImm64>(dlgSoftFallbackSignedShrImm64));
SetDelegateInfo(dlgSoftFallbackTbl1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl1>(dlgSoftFallbackTbl1));
SetDelegateInfo(dlgSoftFallbackTbl2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl2>(dlgSoftFallbackTbl2));
SetDelegateInfo(dlgSoftFallbackTbl3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl3>(dlgSoftFallbackTbl3));
SetDelegateInfo(dlgSoftFallbackTbl4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbl4>(dlgSoftFallbackTbl4));
SetDelegateInfo(dlgSoftFallbackTbx1, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx1>(dlgSoftFallbackTbx1));
SetDelegateInfo(dlgSoftFallbackTbx2, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx2>(dlgSoftFallbackTbx2));
SetDelegateInfo(dlgSoftFallbackTbx3, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx3>(dlgSoftFallbackTbx3));
SetDelegateInfo(dlgSoftFallbackTbx4, Marshal.GetFunctionPointerForDelegate<SoftFallbackTbx4>(dlgSoftFallbackTbx4));
SetDelegateInfo(dlgSoftFallbackUnsignedShrImm64, Marshal.GetFunctionPointerForDelegate<SoftFallbackUnsignedShrImm64>(dlgSoftFallbackUnsignedShrImm64));
SetDelegateInfo(dlgSoftFloat16_32FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_32FPConvert>(dlgSoftFloat16_32FPConvert));
SetDelegateInfo(dlgSoftFloat16_64FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat16_64FPConvert>(dlgSoftFloat16_64FPConvert));
SetDelegateInfo(dlgSoftFloat32FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAdd>(dlgSoftFloat32FPAdd));
SetDelegateInfo(dlgSoftFloat32FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPAddFpscr>(dlgSoftFloat32FPAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompare>(dlgSoftFloat32FPCompare));
SetDelegateInfo(dlgSoftFloat32FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQ>(dlgSoftFloat32FPCompareEQ));
SetDelegateInfo(dlgSoftFloat32FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareEQFpscr>(dlgSoftFloat32FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGE>(dlgSoftFloat32FPCompareGE));
SetDelegateInfo(dlgSoftFloat32FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGEFpscr>(dlgSoftFloat32FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGT>(dlgSoftFloat32FPCompareGT));
SetDelegateInfo(dlgSoftFloat32FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareGTFpscr>(dlgSoftFloat32FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLE>(dlgSoftFloat32FPCompareLE));
SetDelegateInfo(dlgSoftFloat32FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLEFpscr>(dlgSoftFloat32FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLT>(dlgSoftFloat32FPCompareLT));
SetDelegateInfo(dlgSoftFloat32FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPCompareLTFpscr>(dlgSoftFloat32FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPDiv>(dlgSoftFloat32FPDiv));
SetDelegateInfo(dlgSoftFloat32FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMax>(dlgSoftFloat32FPMax));
SetDelegateInfo(dlgSoftFloat32FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxFpscr>(dlgSoftFloat32FPMaxFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNum>(dlgSoftFloat32FPMaxNum));
SetDelegateInfo(dlgSoftFloat32FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMaxNumFpscr>(dlgSoftFloat32FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMin>(dlgSoftFloat32FPMin));
SetDelegateInfo(dlgSoftFloat32FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinFpscr>(dlgSoftFloat32FPMinFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNum>(dlgSoftFloat32FPMinNum));
SetDelegateInfo(dlgSoftFloat32FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMinNumFpscr>(dlgSoftFloat32FPMinNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMul>(dlgSoftFloat32FPMul));
SetDelegateInfo(dlgSoftFloat32FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulFpscr>(dlgSoftFloat32FPMulFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAdd>(dlgSoftFloat32FPMulAdd));
SetDelegateInfo(dlgSoftFloat32FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulAddFpscr>(dlgSoftFloat32FPMulAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSub>(dlgSoftFloat32FPMulSub));
SetDelegateInfo(dlgSoftFloat32FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulSubFpscr>(dlgSoftFloat32FPMulSubFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPMulX>(dlgSoftFloat32FPMulX));
SetDelegateInfo(dlgSoftFloat32FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulAdd>(dlgSoftFloat32FPNegMulAdd));
SetDelegateInfo(dlgSoftFloat32FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPNegMulSub>(dlgSoftFloat32FPNegMulSub));
SetDelegateInfo(dlgSoftFloat32FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimate>(dlgSoftFloat32FPRecipEstimate));
SetDelegateInfo(dlgSoftFloat32FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipEstimateFpscr>(dlgSoftFloat32FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStep>(dlgSoftFloat32FPRecipStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecipStepFused>(dlgSoftFloat32FPRecipStepFused));
SetDelegateInfo(dlgSoftFloat32FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRecpX>(dlgSoftFloat32FPRecpX));
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimate>(dlgSoftFloat32FPRSqrtEstimate));
SetDelegateInfo(dlgSoftFloat32FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtEstimateFpscr>(dlgSoftFloat32FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStep>(dlgSoftFloat32FPRSqrtStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat32FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPRSqrtStepFused>(dlgSoftFloat32FPRSqrtStepFused));
SetDelegateInfo(dlgSoftFloat32FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSqrt>(dlgSoftFloat32FPSqrt));
SetDelegateInfo(dlgSoftFloat32FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat32FPSub>(dlgSoftFloat32FPSub));
SetDelegateInfo(dlgSoftFloat32_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat32_16FPConvert>(dlgSoftFloat32_16FPConvert));
SetDelegateInfo(dlgSoftFloat64FPAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAdd>(dlgSoftFloat64FPAdd));
SetDelegateInfo(dlgSoftFloat64FPAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPAddFpscr>(dlgSoftFloat64FPAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompare, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompare>(dlgSoftFloat64FPCompare));
SetDelegateInfo(dlgSoftFloat64FPCompareEQ, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQ>(dlgSoftFloat64FPCompareEQ));
SetDelegateInfo(dlgSoftFloat64FPCompareEQFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareEQFpscr>(dlgSoftFloat64FPCompareEQFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareGE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGE>(dlgSoftFloat64FPCompareGE));
SetDelegateInfo(dlgSoftFloat64FPCompareGEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGEFpscr>(dlgSoftFloat64FPCompareGEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareGT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGT>(dlgSoftFloat64FPCompareGT));
SetDelegateInfo(dlgSoftFloat64FPCompareGTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareGTFpscr>(dlgSoftFloat64FPCompareGTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareLE, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLE>(dlgSoftFloat64FPCompareLE));
SetDelegateInfo(dlgSoftFloat64FPCompareLEFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLEFpscr>(dlgSoftFloat64FPCompareLEFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPCompareLT, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLT>(dlgSoftFloat64FPCompareLT));
SetDelegateInfo(dlgSoftFloat64FPCompareLTFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPCompareLTFpscr>(dlgSoftFloat64FPCompareLTFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPDiv, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPDiv>(dlgSoftFloat64FPDiv));
SetDelegateInfo(dlgSoftFloat64FPMax, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMax>(dlgSoftFloat64FPMax));
SetDelegateInfo(dlgSoftFloat64FPMaxFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxFpscr>(dlgSoftFloat64FPMaxFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMaxNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNum>(dlgSoftFloat64FPMaxNum));
SetDelegateInfo(dlgSoftFloat64FPMaxNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMaxNumFpscr>(dlgSoftFloat64FPMaxNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMin, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMin>(dlgSoftFloat64FPMin));
SetDelegateInfo(dlgSoftFloat64FPMinFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinFpscr>(dlgSoftFloat64FPMinFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMinNum, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNum>(dlgSoftFloat64FPMinNum));
SetDelegateInfo(dlgSoftFloat64FPMinNumFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMinNumFpscr>(dlgSoftFloat64FPMinNumFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMul, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMul>(dlgSoftFloat64FPMul));
SetDelegateInfo(dlgSoftFloat64FPMulFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulFpscr>(dlgSoftFloat64FPMulFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAdd>(dlgSoftFloat64FPMulAdd));
SetDelegateInfo(dlgSoftFloat64FPMulAddFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulAddFpscr>(dlgSoftFloat64FPMulAddFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSub>(dlgSoftFloat64FPMulSub));
SetDelegateInfo(dlgSoftFloat64FPMulSubFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulSubFpscr>(dlgSoftFloat64FPMulSubFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPMulX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPMulX>(dlgSoftFloat64FPMulX));
SetDelegateInfo(dlgSoftFloat64FPNegMulAdd, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulAdd>(dlgSoftFloat64FPNegMulAdd));
SetDelegateInfo(dlgSoftFloat64FPNegMulSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPNegMulSub>(dlgSoftFloat64FPNegMulSub));
SetDelegateInfo(dlgSoftFloat64FPRecipEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimate>(dlgSoftFloat64FPRecipEstimate));
SetDelegateInfo(dlgSoftFloat64FPRecipEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipEstimateFpscr>(dlgSoftFloat64FPRecipEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRecipStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStep>(dlgSoftFloat64FPRecipStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRecipStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecipStepFused>(dlgSoftFloat64FPRecipStepFused));
SetDelegateInfo(dlgSoftFloat64FPRecpX, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRecpX>(dlgSoftFloat64FPRecpX));
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimate, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimate>(dlgSoftFloat64FPRSqrtEstimate));
SetDelegateInfo(dlgSoftFloat64FPRSqrtEstimateFpscr, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtEstimateFpscr>(dlgSoftFloat64FPRSqrtEstimateFpscr)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRSqrtStep, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStep>(dlgSoftFloat64FPRSqrtStep)); // A32 only.
SetDelegateInfo(dlgSoftFloat64FPRSqrtStepFused, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPRSqrtStepFused>(dlgSoftFloat64FPRSqrtStepFused));
SetDelegateInfo(dlgSoftFloat64FPSqrt, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSqrt>(dlgSoftFloat64FPSqrt));
SetDelegateInfo(dlgSoftFloat64FPSub, Marshal.GetFunctionPointerForDelegate<SoftFloat64FPSub>(dlgSoftFloat64FPSub));
SetDelegateInfo(dlgSoftFloat64_16FPConvert, Marshal.GetFunctionPointerForDelegate<SoftFloat64_16FPConvert>(dlgSoftFloat64_16FPConvert));
}
private delegate double MathAbs(double value);

View File

@ -8,7 +8,7 @@ namespace ARMeilleure.Translation
/// </summary>
/// <typeparam name="TK">Key</typeparam>
/// <typeparam name="TV">Value</typeparam>
class IntervalTree<TK, TV> where TK : IComparable<TK>
public class IntervalTree<TK, TV> where TK : IComparable<TK>
{
private const int ArrayGrowthSize = 32;

View File

@ -413,8 +413,6 @@ namespace ARMeilleure.Translation.PTC
finally
{
ResetCarriersIfNeeded();
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
}
_waitEvent.Set();
@ -790,8 +788,6 @@ namespace ARMeilleure.Translation.PTC
{
ResetCarriersIfNeeded();
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
return;
}
@ -1004,6 +1000,7 @@ namespace ARMeilleure.Translation.PTC
osPlatform |= (OperatingSystem.IsLinux() ? 1u : 0u) << 1;
osPlatform |= (OperatingSystem.IsMacOS() ? 1u : 0u) << 2;
osPlatform |= (OperatingSystem.IsWindows() ? 1u : 0u) << 3;
osPlatform |= (Ryujinx.Common.PlatformInfo.IsBionic ? 1u : 0u) << 4;
#pragma warning restore IDE0055
return osPlatform;

View File

@ -57,9 +57,6 @@ namespace ARMeilleure.Translation
private Thread[] _backgroundTranslationThreads;
private volatile int _threadCount;
// FIXME: Remove this once the init logic of the emulator will be redone.
public static readonly ManualResetEvent IsReadyForTranslation = new(false);
public Translator(IJitMemoryAllocator allocator, IMemoryManager memory, bool for64Bits)
{
_allocator = allocator;
@ -76,14 +73,9 @@ namespace ARMeilleure.Translation
CountTable = new EntryTable<uint>();
Functions = new TranslatorCache<TranslatedFunction>();
FunctionTable = new AddressTable<ulong>(for64Bits ? _levels64Bit : _levels32Bit);
Stubs = new TranslatorStubs(this);
Stubs = new TranslatorStubs(FunctionTable);
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
if (memory.Type.IsHostMapped())
{
NativeSignalHandler.InitializeSignalHandler(allocator.GetPageSize());
}
}
public IPtcLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
@ -105,8 +97,6 @@ namespace ARMeilleure.Translation
{
if (Interlocked.Increment(ref _threadCount) == 1)
{
IsReadyForTranslation.WaitOne();
if (_ptc.State == PtcState.Enabled)
{
Debug.Assert(Functions.Count == 0);

View File

@ -1,3 +1,4 @@
using ARMeilleure.Common;
using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
@ -14,11 +15,11 @@ namespace ARMeilleure.Translation
/// </summary>
class TranslatorStubs : IDisposable
{
private static readonly Lazy<IntPtr> _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
private readonly Lazy<IntPtr> _slowDispatchStub;
private bool _disposed;
private readonly Translator _translator;
private readonly AddressTable<ulong> _functionTable;
private readonly Lazy<IntPtr> _dispatchStub;
private readonly Lazy<DispatcherFunction> _dispatchLoop;
private readonly Lazy<WrapperFunction> _contextWrapper;
@ -83,13 +84,14 @@ namespace ARMeilleure.Translation
/// Initializes a new instance of the <see cref="TranslatorStubs"/> class with the specified
/// <see cref="Translator"/> instance.
/// </summary>
/// <param name="translator"><see cref="Translator"/> instance to use</param>
/// <param name="functionTable">Function table used to store pointers to the functions that the guest code will call</param>
/// <exception cref="ArgumentNullException"><paramref name="translator"/> is null</exception>
public TranslatorStubs(Translator translator)
public TranslatorStubs(AddressTable<ulong> functionTable)
{
ArgumentNullException.ThrowIfNull(translator);
ArgumentNullException.ThrowIfNull(functionTable);
_translator = translator;
_functionTable = functionTable;
_slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
_dispatchStub = new(GenerateDispatchStub, isThreadSafe: true);
_dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true);
_contextWrapper = new(GenerateContextWrapper, isThreadSafe: true);
@ -151,15 +153,15 @@ namespace ARMeilleure.Translation
context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())));
// Check if guest address is within range of the AddressTable.
Operand masked = context.BitwiseAnd(guestAddress, Const(~_translator.FunctionTable.Mask));
Operand masked = context.BitwiseAnd(guestAddress, Const(~_functionTable.Mask));
context.BranchIfTrue(lblFallback, masked);
Operand index = default;
Operand page = Const((long)_translator.FunctionTable.Base);
Operand page = Const((long)_functionTable.Base);
for (int i = 0; i < _translator.FunctionTable.Levels.Length; i++)
for (int i = 0; i < _functionTable.Levels.Length; i++)
{
ref var level = ref _translator.FunctionTable.Levels[i];
ref var level = ref _functionTable.Levels[i];
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
// be encoded as an immediate on x86's bitwise and operation.
@ -167,7 +169,7 @@ namespace ARMeilleure.Translation
index = context.BitwiseAnd(context.ShiftRightUI(guestAddress, Const(level.Index)), mask);
if (i < _translator.FunctionTable.Levels.Length - 1)
if (i < _functionTable.Levels.Length - 1)
{
page = context.Load(OperandType.I64, context.Add(page, context.ShiftLeft(index, Const(3))));
context.BranchIfFalse(lblFallback, page);
@ -196,7 +198,7 @@ namespace ARMeilleure.Translation
/// Generates a <see cref="SlowDispatchStub"/>.
/// </summary>
/// <returns>Generated <see cref="SlowDispatchStub"/></returns>
private static IntPtr GenerateSlowDispatchStub()
private IntPtr GenerateSlowDispatchStub()
{
var context = new EmitterContext();
@ -205,8 +207,7 @@ namespace ARMeilleure.Translation
Operand guestAddress = context.Load(OperandType.I64,
context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())));
MethodInfo getFuncAddress = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress));
Operand hostAddress = context.Call(getFuncAddress, guestAddress);
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext);
var cfg = context.GetControlFlowGraph();

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenTK" />
<PackageReference Include="Ryujinx.SDL2-CS" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace LibRyujinx.Sample
{
internal static class LibRyujinxInterop
{
private const string dll = "LibRyujinx.dll";
[DllImport(dll, EntryPoint = "initialize")]
public extern static bool Initialize(IntPtr path);
[DllImport(dll, EntryPoint = "graphics_initialize")]
public extern static bool InitializeGraphics(GraphicsConfiguration graphicsConfiguration);
[DllImport(dll, EntryPoint = "device_initialize")]
internal extern static bool InitializeDevice();
[DllImport(dll, EntryPoint = "graphics_initialize_renderer")]
internal extern static bool InitializeGraphicsRenderer(GraphicsBackend backend, NativeGraphicsInterop nativeGraphicsInterop);
[DllImport(dll, EntryPoint = "device_load")]
internal extern static bool LoadApplication(IntPtr pathPtr);
[DllImport(dll, EntryPoint = "graphics_renderer_run_loop")]
internal extern static void RunLoop();
[DllImport(dll, EntryPoint = "graphics_renderer_set_size")]
internal extern static void SetRendererSize(int width, int height);
[DllImport(dll, EntryPoint = "graphics_renderer_set_swap_buffer_callback")]
internal extern static void SetSwapBuffersCallback(IntPtr swapBuffers);
[DllImport(dll, EntryPoint = "graphics_renderer_set_vsync")]
internal extern static void SetVsyncState(bool enabled);
[DllImport(dll, EntryPoint = "input_initialize")]
internal extern static void InitializeInput(int width, int height);
[DllImport(dll, EntryPoint = "input_set_client_size")]
internal extern static void SetClientSize(int width, int height);
[DllImport(dll, EntryPoint = "input_set_touch_point")]
internal extern static void SetTouchPoint(int x, int y);
[DllImport(dll, EntryPoint = "input_release_touch_point")]
internal extern static void ReleaseTouchPoint();
[DllImport(dll, EntryPoint = "input_update")]
internal extern static void UpdateInput();
[DllImport(dll, EntryPoint = "input_set_button_pressed")]
public extern static void SetButtonPressed(GamepadButtonInputId button, IntPtr idPtr);
[DllImport(dll, EntryPoint = "input_set_button_released")]
public extern static void SetButtonReleased(GamepadButtonInputId button, IntPtr idPtr);
[DllImport(dll, EntryPoint = "input_set_stick_axis")]
public extern static void SetStickAxis(StickInputId stick, Vector2 axes, IntPtr idPtr);
[DllImport(dll, EntryPoint = "input_connect_gamepad")]
public extern static IntPtr ConnectGamepad(int index);
}
[StructLayout(LayoutKind.Sequential)]
public struct GraphicsConfiguration
{
public float ResScale = 1f;
public float MaxAnisotropy = -1;
public bool FastGpuTime = true;
public bool Fast2DCopy = true;
public bool EnableMacroJit = false;
public bool EnableMacroHLE = true;
public bool EnableShaderCache = true;
public bool EnableTextureRecompression = false;
public BackendThreading BackendThreading = BackendThreading.Auto;
public AspectRatio AspectRatio = AspectRatio.Fixed16x9;
public GraphicsConfiguration()
{
}
}
public enum GraphicsBackend
{
Vulkan,
OpenGl
}
public enum BackendThreading
{
Auto,
Off,
On
}
public struct NativeGraphicsInterop
{
public IntPtr GlGetProcAddress;
public IntPtr VkNativeContextLoader;
public IntPtr VkCreateSurface;
public IntPtr VkRequiredExtensions;
public int VkRequiredExtensionsCount;
}
public enum AspectRatio
{
Fixed4x3,
Fixed16x9,
Fixed16x10,
Fixed21x9,
Fixed32x9,
Stretched
}
/// <summary>
/// Represent a button from a gamepad.
/// </summary>
public enum GamepadButtonInputId : byte
{
Unbound,
A,
B,
X,
Y,
LeftStick,
RightStick,
LeftShoulder,
RightShoulder,
// Likely axis
LeftTrigger,
// Likely axis
RightTrigger,
DpadUp,
DpadDown,
DpadLeft,
DpadRight,
// Special buttons
Minus,
Plus,
Back = Minus,
Start = Plus,
Guide,
Misc1,
// Xbox Elite paddle
Paddle1,
Paddle2,
Paddle3,
Paddle4,
// PS5 touchpad button
Touchpad,
// Virtual buttons for single joycon
SingleLeftTrigger0,
SingleRightTrigger0,
SingleLeftTrigger1,
SingleRightTrigger1,
Count
}
public enum StickInputId : byte
{
Unbound,
Left,
Right,
Count
}
}

View File

@ -0,0 +1,249 @@
using LibRyujinx.Sample;
using OpenTK.Graphics.OpenGL;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework;
using System.Runtime.InteropServices;
namespace LibRyujinx.NativeSample
{
internal class NativeWindow : OpenTK.Windowing.Desktop.NativeWindow
{
private nint del;
public delegate void SwapBuffersCallback();
public delegate IntPtr GetProcAddress(string name);
public delegate IntPtr CreateSurface(IntPtr instance);
private bool _run;
private bool _isVulkan;
private Vector2 _lastPosition;
private bool _mousePressed;
private nint _gamepadIdPtr;
private string? _gamepadId;
public NativeWindow(NativeWindowSettings nativeWindowSettings) : base(nativeWindowSettings)
{
_isVulkan = true;
}
internal unsafe void Start(string gamePath)
{
if (!_isVulkan)
{
MakeCurrent();
}
var getProcAddress = Marshal.GetFunctionPointerForDelegate<GetProcAddress>(x => GLFW.GetProcAddress(x));
var createSurface = Marshal.GetFunctionPointerForDelegate<CreateSurface>( x =>
{
VkHandle surface;
GLFW.CreateWindowSurface(new VkHandle(x) ,this.WindowPtr, null, out surface);
return surface.Handle;
});
var vkExtensions = GLFW.GetRequiredInstanceExtensions();
var pointers = new IntPtr[vkExtensions.Length];
for (int i = 0; i < vkExtensions.Length; i++)
{
pointers[i] = Marshal.StringToHGlobalAnsi(vkExtensions[i]);
}
fixed (IntPtr* ptr = pointers)
{
var nativeGraphicsInterop = new NativeGraphicsInterop()
{
GlGetProcAddress = getProcAddress,
VkRequiredExtensions = (nint)ptr,
VkRequiredExtensionsCount = pointers.Length,
VkCreateSurface = createSurface
};
var success = LibRyujinxInterop.InitializeGraphicsRenderer(_isVulkan ? GraphicsBackend.Vulkan : GraphicsBackend.OpenGl, nativeGraphicsInterop);
success = LibRyujinxInterop.InitializeDevice();
LibRyujinxInterop.InitializeInput(ClientSize.X, ClientSize.Y);
var path = Marshal.StringToHGlobalAnsi(gamePath);
var loaded = LibRyujinxInterop.LoadApplication(path);
LibRyujinxInterop.SetRendererSize(Size.X, Size.Y);
Marshal.FreeHGlobal(path);
}
_gamepadIdPtr = LibRyujinxInterop.ConnectGamepad(0);
_gamepadId = Marshal.PtrToStringAnsi(_gamepadIdPtr);
if (!_isVulkan)
{
Context.MakeNoneCurrent();
}
_run = true;
var thread = new Thread(new ThreadStart(RunLoop));
thread.Start();
UpdateLoop();
thread.Join();
foreach(var ptr in pointers)
{
Marshal.FreeHGlobal(ptr);
}
Marshal.FreeHGlobal(_gamepadIdPtr);
}
public void RunLoop()
{
del = Marshal.GetFunctionPointerForDelegate<SwapBuffersCallback>(SwapBuffers);
LibRyujinxInterop.SetSwapBuffersCallback(del);
if (!_isVulkan)
{
MakeCurrent();
Context.SwapInterval = 0;
}
/* Task.Run(async () =>
{
await Task.Delay(1000);
LibRyujinxInterop.SetVsyncState(true);
});*/
LibRyujinxInterop.RunLoop();
_run = false;
if (!_isVulkan)
{
Context.MakeNoneCurrent();
}
}
private void SwapBuffers()
{
if (!_isVulkan)
{
this.Context.SwapBuffers();
}
}
protected override void OnMouseMove(MouseMoveEventArgs e)
{
base.OnMouseMove(e);
_lastPosition = e.Position;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if(e.Button == MouseButton.Left)
{
_mousePressed = true;
}
}
protected override void OnResize(ResizeEventArgs e)
{
base.OnResize(e);
if (_run)
{
LibRyujinxInterop.SetRendererSize(e.Width, e.Height);
LibRyujinxInterop.SetClientSize(e.Width, e.Height);
}
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButton.Left)
{
_mousePressed = false;
}
}
protected override void OnKeyUp(KeyboardKeyEventArgs e)
{
base.OnKeyUp(e);
if (_gamepadIdPtr != IntPtr.Zero)
{
var key = GetKeyMapping(e.Key);
LibRyujinxInterop.SetButtonReleased(key, _gamepadIdPtr);
}
}
protected override void OnKeyDown(KeyboardKeyEventArgs e)
{
base.OnKeyDown(e);
if (_gamepadIdPtr != IntPtr.Zero)
{
var key = GetKeyMapping(e.Key);
LibRyujinxInterop.SetButtonPressed(key, _gamepadIdPtr);
}
}
public void UpdateLoop()
{
while(_run)
{
ProcessWindowEvents(true);
ProcessInputEvents();
ProcessWindowEvents(IsEventDriven);
if (_mousePressed)
{
LibRyujinxInterop.SetTouchPoint((int)_lastPosition.X, (int)_lastPosition.Y);
}
else
{
LibRyujinxInterop.ReleaseTouchPoint();
}
LibRyujinxInterop.UpdateInput();
Thread.Sleep(1);
}
}
public GamepadButtonInputId GetKeyMapping(Keys key)
{
if(_keyMapping.TryGetValue(key, out var mapping))
{
return mapping;
}
return GamepadButtonInputId.Unbound;
}
private Dictionary<Keys, GamepadButtonInputId> _keyMapping = new Dictionary<Keys, GamepadButtonInputId>()
{
{Keys.A, GamepadButtonInputId.A },
{Keys.S, GamepadButtonInputId.B },
{Keys.Z, GamepadButtonInputId.X },
{Keys.X, GamepadButtonInputId.Y },
{Keys.Equal, GamepadButtonInputId.Plus },
{Keys.Minus, GamepadButtonInputId.Minus },
{Keys.Q, GamepadButtonInputId.LeftShoulder },
{Keys.D1, GamepadButtonInputId.LeftTrigger },
{Keys.W, GamepadButtonInputId.RightShoulder },
{Keys.D2, GamepadButtonInputId.RightTrigger },
{Keys.E, GamepadButtonInputId.LeftStick },
{Keys.R, GamepadButtonInputId.RightStick },
{Keys.Up, GamepadButtonInputId.DpadUp },
{Keys.Down, GamepadButtonInputId.DpadDown },
{Keys.Left, GamepadButtonInputId.DpadLeft },
{Keys.Right, GamepadButtonInputId.DpadRight },
{Keys.U, GamepadButtonInputId.SingleLeftTrigger0 },
{Keys.D7, GamepadButtonInputId.SingleLeftTrigger1 },
{Keys.O, GamepadButtonInputId.SingleRightTrigger0 },
{Keys.D9, GamepadButtonInputId.SingleRightTrigger1 }
};
}
}

View File

@ -0,0 +1,33 @@
using LibRyujinx.Sample;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
namespace LibRyujinx.NativeSample
{
internal class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
var success = LibRyujinxInterop.Initialize(IntPtr.Zero);
success = LibRyujinxInterop.InitializeGraphics(new GraphicsConfiguration());
var nativeWindowSettings = new NativeWindowSettings()
{
Size = new Vector2i(800, 600),
Title = "Ryujinx",
API = ContextAPI.NoAPI,
IsEventDriven = false,
// This is needed to run on macos
Flags = ContextFlags.ForwardCompatible,
};
using var window = new NativeWindow(nativeWindowSettings);
window.IsVisible = true;
window.Start(args[0]);
}
}
}
}

View File

@ -0,0 +1,49 @@
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Formatters;
using Ryujinx.Common.Logging.Targets;
using System;
namespace LibRyujinx
{
public class AndroidLogTarget : ILogTarget
{
private readonly string _name;
private readonly DefaultLogFormatter _formatter;
string ILogTarget.Name { get => _name; }
public AndroidLogTarget(string name)
{
_name = name;
_formatter = new DefaultLogFormatter();
}
public void Log(object sender, LogEventArgs args)
{
Logcat.AndroidLogPrint(GetLogLevel(args.Level), _name, _formatter.Format(args));
}
private static Logcat.LogLevel GetLogLevel(LogLevel logLevel)
{
return logLevel switch
{
LogLevel.Debug => Logcat.LogLevel.Debug,
LogLevel.Stub => Logcat.LogLevel.Info,
LogLevel.Info => Logcat.LogLevel.Info,
LogLevel.Warning => Logcat.LogLevel.Warn,
LogLevel.Error => Logcat.LogLevel.Error,
LogLevel.Guest => Logcat.LogLevel.Info,
LogLevel.AccessLog => Logcat.LogLevel.Info,
LogLevel.Notice => Logcat.LogLevel.Info,
LogLevel.Trace => Logcat.LogLevel.Verbose,
_ => throw new NotImplementedException(),
};
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
}

View File

@ -0,0 +1,136 @@
using LibHac.Tools.Fs;
using Ryujinx.Common.Logging;
using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
using Ryujinx.HLE.Ui;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LibRyujinx.Android
{
internal class AndroidUiHandler : IHostUiHandler, IDisposable
{
public IHostUiTheme HostUiTheme => throw new NotImplementedException();
public ManualResetEvent _waitEvent;
public ManualResetEvent _responseEvent;
private bool _isDisposed;
private bool _isOkPressed;
private long _input;
public AndroidUiHandler()
{
_waitEvent = new ManualResetEvent(false);
_responseEvent = new ManualResetEvent(false);
}
public IDynamicTextInputHandler CreateDynamicTextInputHandler()
{
throw new NotImplementedException();
}
public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText)
{
LibRyujinx.setUiHandlerTitle(LibRyujinx.storeString(title ?? ""));
LibRyujinx.setUiHandlerMessage(LibRyujinx.storeString(message ?? ""));
LibRyujinx.setUiHandlerType(1);
_responseEvent.Reset();
Set();
_responseEvent.WaitOne();
return _isOkPressed;
}
public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText)
{
LibRyujinx.setUiHandlerTitle(LibRyujinx.storeString("Software Keyboard"));
LibRyujinx.setUiHandlerMessage(LibRyujinx.storeString(args.HeaderText ?? ""));
LibRyujinx.setUiHandlerWatermark(LibRyujinx.storeString(args.GuideText ?? ""));
LibRyujinx.setUiHandlerSubtitle(LibRyujinx.storeString(args.SubtitleText ?? ""));
LibRyujinx.setUiHandlerInitialText(LibRyujinx.storeString(args.InitialText ?? ""));
LibRyujinx.setUiHandlerMinLength(args.StringLengthMin);
LibRyujinx.setUiHandlerMaxLength(args.StringLengthMax);
LibRyujinx.setUiHandlerType(2);
LibRyujinx.setUiHandlerKeyboardMode((int)args.KeyboardMode);
_responseEvent.Reset();
Set();
_responseEvent.WaitOne();
userText = _input != -1 ? LibRyujinx.GetStoredString(_input) : "";
return _isOkPressed;
}
public bool DisplayMessageDialog(string title, string message)
{
LibRyujinx.setUiHandlerTitle(LibRyujinx.storeString(title ?? ""));
LibRyujinx.setUiHandlerMessage(LibRyujinx.storeString(message ?? ""));
LibRyujinx.setUiHandlerType(1);
_responseEvent.Reset();
Set();
_responseEvent.WaitOne();
return _isOkPressed;
}
public bool DisplayMessageDialog(ControllerAppletUiArgs args)
{
string playerCount = args.PlayerCountMin == args.PlayerCountMax ? $"exactly {args.PlayerCountMin}" : $"{args.PlayerCountMin}-{args.PlayerCountMax}";
string message = $"Application requests **{playerCount}** player(s) with:\n\n"
+ $"**TYPES:** {args.SupportedStyles}\n\n"
+ $"**PLAYERS:** {string.Join(", ", args.SupportedPlayers)}\n\n"
+ (args.IsDocked ? "Docked mode set. `Handheld` is also invalid.\n\n" : "")
+ "_Please reconfigure Input now and then press OK._";
return DisplayMessageDialog("Controller Applet", message);
}
public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
{
// throw new NotImplementedException();
}
internal void Wait()
{
if (_isDisposed)
return;
_waitEvent.Reset();
_waitEvent.WaitOne();
_waitEvent.Reset();
}
internal void Set()
{
if (_isDisposed)
return;
_waitEvent.Set();
}
internal void SetResponse(bool isOkPressed, long input)
{
if (_isDisposed)
return;
_isOkPressed = isOkPressed;
_input = input;
_responseEvent.Set();
}
public void Dispose()
{
_isDisposed = true;
_waitEvent.Set();
_waitEvent.Set();
_responseEvent.Dispose();
_waitEvent.Dispose();
}
}
}

View File

@ -0,0 +1,18 @@
namespace LibRyujinx.Shared.Audio.Oboe
{
internal class OboeAudioBuffer
{
public readonly ulong DriverIdentifier;
public readonly ulong SampleCount;
public readonly byte[] Data;
public ulong SamplePlayed;
public OboeAudioBuffer(ulong driverIdentifier, byte[] data, ulong sampleCount)
{
DriverIdentifier = driverIdentifier;
Data = data;
SampleCount = sampleCount;
SamplePlayed = 0;
}
}
}

View File

@ -0,0 +1,105 @@
using Ryujinx.Audio;
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Integration;
using Ryujinx.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
namespace LibRyujinx.Shared.Audio.Oboe
{
internal class OboeHardwareDeviceDriver : IHardwareDeviceDriver
{
private readonly ManualResetEvent _updateRequiredEvent;
private readonly ManualResetEvent _pauseEvent;
private readonly ConcurrentDictionary<OboeHardwareDeviceSession, byte> _sessions;
public OboeHardwareDeviceDriver()
{
_updateRequiredEvent = new ManualResetEvent(false);
_pauseEvent = new ManualResetEvent(true);
_sessions = new ConcurrentDictionary<OboeHardwareDeviceSession, byte>();
}
public static bool IsSupported => true;
public ManualResetEvent GetUpdateRequiredEvent()
{
return _updateRequiredEvent;
}
public ManualResetEvent GetPauseEvent()
{
return _pauseEvent;
}
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume)
{
if (channelCount == 0)
{
channelCount = 2;
}
if (sampleRate == 0)
{
sampleRate = Constants.TargetSampleRate;
}
if (direction != Direction.Output)
{
throw new NotImplementedException("Input direction is currently not implemented on Oboe backend!");
}
OboeHardwareDeviceSession session = new OboeHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount, volume);
_sessions.TryAdd(session, 0);
return session;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
foreach (OboeHardwareDeviceSession session in _sessions.Keys)
{
session.Dispose();
}
_pauseEvent.Dispose();
_sessions.Clear();
}
}
public bool SupportsSampleRate(uint sampleRate)
{
return true;
}
public bool SupportsSampleFormat(SampleFormat sampleFormat)
{
return sampleFormat != SampleFormat.Adpcm;
}
public bool SupportsChannelCount(uint channelCount)
{
return channelCount == 1 || channelCount == 2 || channelCount == 4 || channelCount == 6;
}
public bool SupportsDirection(Direction direction)
{
return direction == Direction.Output;
}
}
}

View File

@ -0,0 +1,189 @@
using Ryujinx.Audio.Backends.Common;
using Ryujinx.Audio.Common;
using Ryujinx.Memory;
using System;
using System.Collections.Generic;
using System.Threading;
namespace LibRyujinx.Shared.Audio.Oboe
{
internal class OboeHardwareDeviceSession : HardwareDeviceSessionOutputBase
{
private OboeHardwareDeviceDriver _driver;
private bool _isClosed;
private bool _isWorkerActive;
private Queue<OboeAudioBuffer> _queuedBuffers;
private bool _isActive;
private ulong _playedSampleCount;
private Thread _workerThread;
private ManualResetEvent _updateRequiredEvent;
private IntPtr _session;
private object _queueLock = new object();
private object _trackLock = new object();
public OboeHardwareDeviceSession(OboeHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
{
_driver = driver;
_isActive = false;
_playedSampleCount = 0;
_isWorkerActive = true;
_queuedBuffers = new Queue<OboeAudioBuffer>();
_updateRequiredEvent = driver.GetUpdateRequiredEvent();
_session = OboeInterop.CreateSession((int)requestedSampleFormat, requestedSampleRate, requestedChannelCount);
_workerThread = new Thread(Update);
_workerThread.Name = $"HardwareDeviceSession.Android.Track";
_workerThread.Start();
SetVolume(requestedVolume);
}
public override void UnregisterBuffer(AudioBuffer buffer) { }
public unsafe void Update(object ignored)
{
while (_isWorkerActive)
{
bool needUpdate = false;
bool hasBuffer;
OboeAudioBuffer buffer;
lock (_queueLock)
{
hasBuffer = _queuedBuffers.TryPeek(out buffer);
}
while (hasBuffer)
{
StartIfNotPlaying();
if (_isClosed)
break;
fixed(byte* ptr = buffer.Data)
OboeInterop.WriteToSession(_session, (ulong)ptr, buffer.SampleCount);
lock (_queueLock)
{
_playedSampleCount += buffer.SampleCount;
_queuedBuffers.TryDequeue(out _);
}
needUpdate = true;
lock (_queueLock)
{
hasBuffer = _queuedBuffers.TryPeek(out buffer);
}
}
if (needUpdate)
{
_updateRequiredEvent.Set();
}
// No work
Thread.Sleep(5);
}
}
public override void Dispose()
{
if (_session == 0)
return;
PrepareToClose();
OboeInterop.CloseSession(_session);
_session = 0;
}
public override void PrepareToClose()
{
_isClosed = true;
_isWorkerActive = false;
_workerThread?.Join();
Stop();
}
private void StartIfNotPlaying()
{
lock (_trackLock)
{
if (_isClosed)
return;
if (OboeInterop.IsPlaying(_session) == 0)
{
Start();
}
}
}
public override void QueueBuffer(AudioBuffer buffer)
{
lock (_queueLock)
{
OboeAudioBuffer driverBuffer = new OboeAudioBuffer(buffer.DataPointer, buffer.Data, GetSampleCount(buffer));
_queuedBuffers.Enqueue(driverBuffer);
if (_isActive)
{
StartIfNotPlaying();
}
}
}
public override float GetVolume()
{
return OboeInterop.GetSessionVolume(_session);
}
public override ulong GetPlayedSampleCount()
{
lock (_queueLock)
{
return _playedSampleCount;
}
}
public override void SetVolume(float volume)
{
volume = 1;
OboeInterop.SetSessionVolume(_session, volume);
}
public override void Start()
{
if (_isClosed)
return;
OboeInterop.StartSession(_session);
}
public override void Stop()
{
OboeInterop.StopSession(_session);
}
public override bool WasBufferFullyConsumed(AudioBuffer buffer)
{
lock (_queueLock)
{
if (!_queuedBuffers.TryPeek(out OboeAudioBuffer driverBuffer))
{
return true;
}
return driverBuffer.DriverIdentifier != buffer.DataPointer;
}
}
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace LibRyujinx.Shared.Audio.Oboe
{
internal static partial class OboeInterop
{
private const string InteropLib = "libryujinxjni";
[LibraryImport(InteropLib, EntryPoint = "create_session")]
public static partial IntPtr CreateSession(int sample_format,
uint sample_rate,
uint channel_count);
[LibraryImport(InteropLib, EntryPoint = "start_session")]
public static partial void StartSession(IntPtr session);
[LibraryImport(InteropLib, EntryPoint = "stop_session")]
public static partial void StopSession(IntPtr session);
[LibraryImport(InteropLib, EntryPoint = "close_session")]
public static partial void CloseSession(IntPtr session);
[LibraryImport(InteropLib, EntryPoint = "set_session_volume")]
public static partial void SetSessionVolume(IntPtr session, float volume);
[LibraryImport(InteropLib, EntryPoint = "get_session_volume")]
public static partial float GetSessionVolume(IntPtr session);
[LibraryImport(InteropLib, EntryPoint = "is_playing")]
public static partial int IsPlaying(IntPtr session);
[LibraryImport(InteropLib, EntryPoint = "write_to_session")]
public static partial void WriteToSession(IntPtr session, ulong data, ulong samples);
}
}

View File

@ -0,0 +1,799 @@
using LibRyujinx.Jni;
using LibRyujinx.Jni.Pointers;
using LibRyujinx.Jni.Primitives;
using LibRyujinx.Jni.References;
using LibRyujinx.Jni.Values;
using LibRyujinx.Shared.Audio.Oboe;
using Rxmxnx.PInvoke;
using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input;
using Silk.NET.Core.Loader;
using Silk.NET.Vulkan;
using Silk.NET.Vulkan.Extensions.KHR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
private static ManualResetEvent _surfaceEvent;
private static long _surfacePtr;
private static long _window = 0;
public static VulkanLoader? VulkanLoader { get; private set; }
[DllImport("libryujinxjni")]
private extern static IntPtr getStringPointer(JEnvRef jEnv, JStringLocalRef s);
[DllImport("libryujinxjni")]
private extern static JStringLocalRef createString(JEnvRef jEnv, IntPtr ch);
[DllImport("libryujinxjni")]
internal extern static long storeString(string ch);
[DllImport("libryujinxjni")]
internal extern static IntPtr getString(long id);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerTitle(long title);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerMessage(long message);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerWatermark(long watermark);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerInitialText(long text);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerSubtitle(long text);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerType(int type);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerKeyboardMode(int mode);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerMinLength(int lenght);
[DllImport("libryujinxjni")]
internal extern static long setUiHandlerMaxLength(int lenght);
internal static string GetStoredString(long id)
{
var pointer = getString(id);
if (pointer != IntPtr.Zero)
{
var str = Marshal.PtrToStringAnsi(pointer) ?? "";
Marshal.FreeHGlobal(pointer);
return str;
}
return "";
}
[DllImport("libryujinxjni")]
internal extern static void setRenderingThread();
[DllImport("libryujinxjni")]
internal extern static void debug_break(int code);
[DllImport("libryujinxjni")]
internal extern static void onFrameEnd(double time);
[DllImport("libryujinxjni")]
internal extern static void setProgressInfo(IntPtr info, float progress);
[DllImport("libryujinxjni")]
internal extern static void setCurrentTransform(long native_window, int transform);
public delegate IntPtr JniCreateSurface(IntPtr native_surface, IntPtr instance);
[UnmanagedCallersOnly(EntryPoint = "JNI_OnLoad")]
internal static int LoadLibrary(JavaVMRef vm, IntPtr unknown)
{
return 0x00010006; //JNI_VERSION_1_6
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_initialize")]
public static JBoolean JniInitialize(JEnvRef jEnv, JObjectLocalRef jObj, JLong jpathId)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
PlatformInfo.IsBionic = true;
Logger.AddTarget(
new AsyncLogTargetWrapper(
new AndroidLogTarget("RyujinxLog"),
1000,
AsyncLogTargetOverflowAction.Block
));
var path = GetStoredString(jpathId);
var init = Initialize(path);
_surfaceEvent?.Set();
_surfaceEvent = new ManualResetEvent(false);
return init;
}
private static string? GetString(JEnvRef jEnv, JStringLocalRef jString)
{
var stringPtr = getStringPointer(jEnv, jString);
var s = Marshal.PtrToStringAnsi(stringPtr);
Marshal.FreeHGlobal(stringPtr);
return s;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceReloadFilesystem")]
public static void JniReloadFileSystem()
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SwitchDevice?.ReloadFileSystem();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceInitialize")]
public static JBoolean JniInitializeDeviceNative(JEnvRef jEnv,
JObjectLocalRef jObj,
JBoolean isHostMapped,
JBoolean useNce,
JInt systemLanguage,
JInt regionCode,
JBoolean enableVsync,
JBoolean enableDockedMode,
JBoolean enablePtc,
JBoolean enableInternetAccess,
JLong timeZoneId,
JBoolean ignoreMissingServices)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
AudioDriver = new OpenALHardwareDeviceDriver();//new OboeHardwareDeviceDriver();
return InitializeDevice(isHostMapped,
useNce,
(SystemLanguage)(int)systemLanguage,
(RegionCode)(int)regionCode,
enableVsync,
enableDockedMode,
enablePtc,
enableInternetAccess,
GetStoredString(timeZoneId),
ignoreMissingServices);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetGameFifo")]
public static JDouble JniGetGameFifo(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var stats = SwitchDevice.EmulationContext?.Statistics.GetFifoPercent() ?? 0;
return stats;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetGameFrameTime")]
public static JDouble JniGetGameFrameTime(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var stats = SwitchDevice.EmulationContext?.Statistics.GetGameFrameTime() ?? 0;
return stats;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetGameFrameRate")]
public static JDouble JniGetGameFrameRate(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var stats = SwitchDevice.EmulationContext?.Statistics.GetGameFrameRate() ?? 0;
return stats;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceLoad")]
public static JBoolean JniLoadApplicationNative(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef pathPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
if (SwitchDevice?.EmulationContext == null)
{
return false;
}
var path = GetString(jEnv, pathPtr);
return LoadApplication(path);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceLaunchMiiEditor")]
public static JBoolean JniLaunchMiiEditApplet(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
if (SwitchDevice?.EmulationContext == null)
{
return false;
}
return LaunchMiiEditApplet();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetDlcContentList")]
public static JArrayLocalRef JniGetDlcContentListNative(JEnvRef jEnv, JObjectLocalRef jObj, JLong pathPtr, JLong titleId)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var list = GetDlcContentList(GetStoredString(pathPtr), (ulong)(long)titleId);
debug_break(4);
return CreateStringArray(jEnv, list);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetDlcTitleId")]
public static JLong JniGetDlcTitleIdNative(JEnvRef jEnv, JObjectLocalRef jObj, JLong pathPtr, JLong ncaPath)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
return storeString(GetDlcTitleId(GetStoredString(pathPtr), GetStoredString(ncaPath)));
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceSignalEmulationClose")]
public static void JniSignalEmulationCloseNative(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SignalEmulationClose();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceCloseEmulation")]
public static void JniCloseEmulationNative(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
CloseEmulation();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceLoadDescriptor")]
public static JBoolean JniLoadApplicationNative(JEnvRef jEnv, JObjectLocalRef jObj, JInt descriptor, JInt type, JInt updateDescriptor)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
if (SwitchDevice?.EmulationContext == null)
{
return false;
}
var stream = OpenFile(descriptor);
var update = updateDescriptor == -1 ? null : OpenFile(updateDescriptor);
return LoadApplication(stream, (FileType)(int)type, update);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceVerifyFirmware")]
public static JLong JniVerifyFirmware(JEnvRef jEnv, JObjectLocalRef jObj, JInt descriptor, JBoolean isXci)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var stream = OpenFile(descriptor);
long stringHandle = -1;
try
{
var version = VerifyFirmware(stream, isXci);
if (version != null)
{
stringHandle = storeString(version.VersionString);
}
}
catch(Exception _)
{
}
return stringHandle;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceInstallFirmware")]
public static void JniInstallFirmware(JEnvRef jEnv, JObjectLocalRef jObj, JInt descriptor, JBoolean isXci)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var stream = OpenFile(descriptor);
InstallFirmware(stream, isXci);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetInstalledFirmwareVersion")]
public static JLong JniGetInstalledFirmwareVersion(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var version = GetInstalledFirmwareVersion();
long stringHandle = -1;
if (version != String.Empty)
{
stringHandle = storeString(version);
}
return stringHandle;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsInitialize")]
public static JBoolean JniInitializeGraphicsNative(JEnvRef jEnv, JObjectLocalRef jObj, JObjectLocalRef graphicObject)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
JEnvValue value = jEnv.Environment;
ref JNativeInterface jInterface = ref value.Functions;
IntPtr getObjectClassPtr = jInterface.GetObjectClassPointer;
IntPtr getFieldIdPtr = jInterface.GetFieldIdPointer;
IntPtr getIntFieldPtr = jInterface.GetIntFieldPointer;
IntPtr getLongFieldPtr = jInterface.GetLongFieldPointer;
IntPtr getFloatFieldPtr = jInterface.GetFloatFieldPointer;
IntPtr getBooleanFieldPtr = jInterface.GetBooleanFieldPointer;
var getObjectClass = getObjectClassPtr.GetUnsafeDelegate<GetObjectClassDelegate>();
var getFieldId = getFieldIdPtr.GetUnsafeDelegate<GetFieldIdDelegate>();
var getLongField = getLongFieldPtr.GetUnsafeDelegate<GetLongFieldDelegate>();
var getIntField = getIntFieldPtr.GetUnsafeDelegate<GetIntFieldDelegate>();
var getBooleanField = getBooleanFieldPtr.GetUnsafeDelegate<GetBooleanFieldDelegate>();
var getFloatField = getFloatFieldPtr.GetUnsafeDelegate<GetFloatFieldDelegate>();
var jobject = getObjectClass(jEnv, graphicObject);
GraphicsConfiguration graphicsConfiguration = new()
{
EnableShaderCache = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("EnableShaderCache"), GetCCharSequence("Z"))),
EnableMacroHLE = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("EnableMacroHLE"), GetCCharSequence("Z"))),
EnableMacroJit = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("EnableMacroJit"), GetCCharSequence("Z"))),
EnableTextureRecompression = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("EnableTextureRecompression"), GetCCharSequence("Z"))),
Fast2DCopy = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("Fast2DCopy"), GetCCharSequence("Z"))),
FastGpuTime = getBooleanField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("FastGpuTime"), GetCCharSequence("Z"))),
ResScale = getFloatField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("ResScale"), GetCCharSequence("F"))),
MaxAnisotropy = getFloatField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("MaxAnisotropy"), GetCCharSequence("F"))),
BackendThreading = (BackendThreading)(int)getIntField(jEnv, graphicObject, getFieldId(jEnv, jobject, GetCCharSequence("BackendThreading"), GetCCharSequence("I")))
};
SearchPathContainer.Platform = UnderlyingPlatform.Android;
return InitializeGraphics(graphicsConfiguration);
}
private static CCharSequence GetCCharSequence(string s)
{
return Encoding.UTF8.GetBytes(s).AsSpan();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsSetSurface")]
public static void JniSetSurface(JEnvRef jEnv, JObjectLocalRef jObj, JLong surfacePtr, JLong window)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
_surfacePtr = surfacePtr;
_window = window;
_surfaceEvent.Set();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsInitializeRenderer")]
public unsafe static JBoolean JniInitializeGraphicsRendererNative(JEnvRef jEnv,
JObjectLocalRef jObj,
JArrayLocalRef extensionsArray,
JLong driverHandle)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
if (Renderer != null)
{
return false;
}
JEnvValue value = jEnv.Environment;
ref JNativeInterface jInterface = ref value.Functions;
IntPtr getObjectClassPtr = jInterface.GetObjectClassPointer;
IntPtr getFieldIdPtr = jInterface.GetFieldIdPointer;
IntPtr getLongFieldPtr = jInterface.GetLongFieldPointer;
IntPtr getArrayLengthPtr = jInterface.GetArrayLengthPointer;
IntPtr getObjectArrayElementPtr = jInterface.GetObjectArrayElementPointer;
IntPtr getObjectFieldPtr = jInterface.GetObjectFieldPointer;
var getObjectClass = getObjectClassPtr.GetUnsafeDelegate<GetObjectClassDelegate>();
var getFieldId = getFieldIdPtr.GetUnsafeDelegate<GetFieldIdDelegate>();
var getArrayLength = getArrayLengthPtr.GetUnsafeDelegate<GetArrayLengthDelegate>();
var getObjectArrayElement = getObjectArrayElementPtr.GetUnsafeDelegate<GetObjectArrayElementDelegate>();
var getLongField = getLongFieldPtr.GetUnsafeDelegate<GetLongFieldDelegate>();
var getObjectField = getObjectFieldPtr.GetUnsafeDelegate<GetObjectFieldDelegate>();
List<string?> extensions = new();
var count = getArrayLength(jEnv, extensionsArray);
for (int i = 0; i < count; i++)
{
var obj = getObjectArrayElement(jEnv, extensionsArray, i);
var ext = obj.Transform<JObjectLocalRef, JStringLocalRef>();
extensions.Add(GetString(jEnv, ext));
}
if ((long)driverHandle != 0)
{
VulkanLoader = new VulkanLoader((IntPtr)(long)driverHandle);
}
CreateSurface createSurfaceFunc = instance =>
{
_surfaceEvent.WaitOne();
_surfaceEvent.Reset();
var api = VulkanLoader?.GetApi() ?? Vk.GetApi();
if (api.TryGetInstanceExtension(new Instance(instance), out KhrAndroidSurface surfaceExtension))
{
var createInfo = new AndroidSurfaceCreateInfoKHR
{
SType = StructureType.AndroidSurfaceCreateInfoKhr,
Window = (nint*)_surfacePtr,
};
var result = surfaceExtension.CreateAndroidSurface(new Instance(instance), createInfo, null, out var surface);
return (nint)surface.Handle;
}
return IntPtr.Zero;
};
return InitializeGraphicsRenderer(GraphicsBackend.Vulkan, createSurfaceFunc, extensions.ToArray());
}
private static JArrayLocalRef CreateStringArray(JEnvRef jEnv, List<string> strings)
{
JEnvValue value = jEnv.Environment;
ref JNativeInterface jInterface = ref value.Functions;
IntPtr newObjectArrayPtr = jInterface.NewObjectArrayPointer;
IntPtr findClassPtr = jInterface.FindClassPointer;
IntPtr setObjectArrayElementPtr = jInterface.SetObjectArrayElementPointer;
var newObjectArray = newObjectArrayPtr.GetUnsafeDelegate<NewObjectArrayDelegate>();
var findClass = findClassPtr.GetUnsafeDelegate<FindClassDelegate>();
var setObjectArrayElement = setObjectArrayElementPtr.GetUnsafeDelegate<SetObjectArrayElementDelegate>();
var array = newObjectArray(jEnv, strings.Count, findClass(jEnv, GetCCharSequence("java/lang/String")), CreateString(jEnv, "")._value);
for (int i = 0; i < strings.Count; i++)
{
setObjectArrayElement(jEnv, array, i, CreateString(jEnv, strings[i])._value);
}
return array;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsRendererSetSize")]
public static void JniSetRendererSizeNative(JEnvRef jEnv, JObjectLocalRef jObj, JInt width, JInt height)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
Renderer?.Window?.SetSize(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsRendererRunLoop")]
public static void JniRunLoopNative(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetSwapBuffersCallback(() =>
{
var time = SwitchDevice.EmulationContext.Statistics.GetGameFrameTime();
onFrameEnd(time);
});
RunLoop();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_loggingSetEnabled")]
public static void JniSetLoggingEnabledNative(JEnvRef jEnv, JObjectLocalRef jObj, JInt logLevel, JBoolean enabled)
{
Logger.SetEnable((LogLevel)(int)logLevel, enabled);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetGameInfoFromPath")]
public static JObjectLocalRef JniGetGameInfo(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef path)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var info = GetGameInfo(GetString(jEnv, path));
return GetInfo(jEnv, info);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_deviceGetGameInfo")]
public static JObjectLocalRef JniGetGameInfo(JEnvRef jEnv, JObjectLocalRef jObj, JInt fileDescriptor, JLong extension)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
using var stream = OpenFile(fileDescriptor);
var ext = GetStoredString(extension);
var info = GetGameInfo(stream, ext.ToLower());
return GetInfo(jEnv, info);
}
private static JObjectLocalRef GetInfo(JEnvRef jEnv, GameInfo? info)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var javaClassName = GetCCharSequence("org/ryujinx/android/viewmodels/GameInfo");
JEnvValue value = jEnv.Environment;
ref JNativeInterface jInterface = ref value.Functions;
IntPtr findClassPtr = jInterface.FindClassPointer;
IntPtr newGlobalRefPtr = jInterface.NewGlobalRefPointer;
IntPtr getFieldIdPtr = jInterface.GetFieldIdPointer;
IntPtr getMethodPtr = jInterface.GetMethodIdPointer;
IntPtr newObjectPtr = jInterface.NewObjectPointer;
IntPtr setObjectFieldPtr = jInterface.SetObjectFieldPointer;
IntPtr setDoubleFieldPtr = jInterface.SetDoubleFieldPointer;
var findClass = findClassPtr.GetUnsafeDelegate<FindClassDelegate>();
var newGlobalRef = newGlobalRefPtr.GetUnsafeDelegate<NewGlobalRefDelegate>();
var getFieldId = getFieldIdPtr.GetUnsafeDelegate<GetFieldIdDelegate>();
var getMethod = getMethodPtr.GetUnsafeDelegate<GetMethodIdDelegate>();
var newObject = newObjectPtr.GetUnsafeDelegate<NewObjectDelegate>();
var setObjectField = setObjectFieldPtr.GetUnsafeDelegate<SetObjectFieldDelegate>();
var setDoubleField = setDoubleFieldPtr.GetUnsafeDelegate<SetDoubleFieldDelegate>();
var javaClass = findClass(jEnv, javaClassName);
var newGlobal = newGlobalRef(jEnv, javaClass._value);
var constructor = getMethod(jEnv, javaClass, GetCCharSequence("<init>"), GetCCharSequence("()V"));
var newObj = newObject(jEnv, javaClass, constructor, 0);
setObjectField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("TitleName"), GetCCharSequence("Ljava/lang/String;")), CreateString(jEnv, info?.TitleName)._value);
setObjectField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("TitleId"), GetCCharSequence("Ljava/lang/String;")), CreateString(jEnv, info?.TitleId)._value);
setObjectField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("Developer"), GetCCharSequence("Ljava/lang/String;")), CreateString(jEnv, info?.Developer)._value);
setObjectField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("Version"), GetCCharSequence("Ljava/lang/String;")), CreateString(jEnv, info?.Version)._value);
setObjectField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("Icon"), GetCCharSequence("Ljava/lang/String;")), CreateString(jEnv, Convert.ToBase64String(info?.Icon ?? Array.Empty<byte>()))._value);
setDoubleField(jEnv, newObj, getFieldId(jEnv, javaClass, GetCCharSequence("FileSize"), GetCCharSequence("D")), info?.FileSize ?? 0d);
return newObj;
}
private static JStringLocalRef CreateString(JEnvRef jEnv, string? s)
{
s ??= string.Empty;
var ptr = Marshal.StringToHGlobalAnsi(s);
var str = createString(jEnv, ptr);
Marshal.FreeHGlobal(ptr);
return str;
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsRendererSetVsync")]
public static void JniSetVsyncStateNative(JEnvRef jEnv, JObjectLocalRef jObj, JBoolean enabled)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetVsyncState(enabled);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_graphicsRendererSetSwapBufferCallback")]
public static void JniSetSwapBuffersCallbackNative(JEnvRef jEnv, JObjectLocalRef jObj, IntPtr swapBuffersCallback)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
_swapBuffersCallback = Marshal.GetDelegateForFunctionPointer<SwapBuffersCallback>(swapBuffersCallback);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputInitialize")]
public static void JniInitializeInput(JEnvRef jEnv, JObjectLocalRef jObj, JInt width, JInt height)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
InitializeInput(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetClientSize")]
public static void JniSetClientSize(JEnvRef jEnv, JObjectLocalRef jObj, JInt width, JInt height)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetClientSize(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetTouchPoint")]
public static void JniSetTouchPoint(JEnvRef jEnv, JObjectLocalRef jObj, JInt x, JInt y)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetTouchPoint(x, y);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputReleaseTouchPoint")]
public static void JniReleaseTouchPoint(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
ReleaseTouchPoint();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputUpdate")]
public static void JniUpdateInput(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
UpdateInput();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetButtonPressed")]
public static void JniSetButtonPressed(JEnvRef jEnv, JObjectLocalRef jObj, JInt button, JInt id)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetButtonPressed((GamepadButtonInputId)(int)button, id);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetButtonReleased")]
public static void JniSetButtonReleased(JEnvRef jEnv, JObjectLocalRef jObj, JInt button, JInt id)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetButtonReleased((GamepadButtonInputId)(int)button, id);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetAccelerometerData")]
public static void JniSetAccelerometerData(JEnvRef jEnv, JObjectLocalRef jObj, JFloat x, JFloat y, JFloat z, JInt id)
{
var accel = new Vector3(x, y, z);
SetAccelerometerData(accel, id);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetGyroData")]
public static void JniSetGyroData(JEnvRef jEnv, JObjectLocalRef jObj, JFloat x, JFloat y, JFloat z, JInt id)
{
var gryo = new Vector3(x, y, z);
SetGryoData(gryo, id);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputSetStickAxis")]
public static void JniSetStickAxis(JEnvRef jEnv, JObjectLocalRef jObj, JInt stick, JFloat x, JFloat y, JInt id)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetStickAxis((StickInputId)(int)stick, new Vector2(float.IsNaN(x) ? 0 : x, float.IsNaN(y) ? 0 : y), id);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_inputConnectGamepad")]
public static JInt JniConnectGamepad(JEnvRef jEnv, JObjectLocalRef jObj, JInt index)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
return ConnectGamepad(index);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userGetOpenedUser")]
public static JLong JniGetOpenedUser(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetOpenedUser();
return storeString(userId);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userGetUserPicture")]
public static JLong JniGetUserPicture(JEnvRef jEnv, JObjectLocalRef jObj, JLong userIdPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetStoredString(userIdPtr) ?? "";
return storeString(GetUserPicture(userId));
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userSetUserPicture")]
public static void JniGetUserPicture(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef userIdPtr, JStringLocalRef picturePtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetString(jEnv, userIdPtr) ?? "";
var picture = GetString(jEnv, picturePtr) ?? "";
SetUserPicture(userId, picture);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userGetUserName")]
public static JLong JniGetUserName(JEnvRef jEnv, JObjectLocalRef jObj, JLong userIdPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetStoredString(userIdPtr) ?? "";
return storeString(GetUserName(userId));
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userSetUserName")]
public static void JniSetUserName(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef userIdPtr, JStringLocalRef userNamePtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetString(jEnv, userIdPtr) ?? "";
var userName = GetString(jEnv, userNamePtr) ?? "";
SetUserName(userId, userName);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userGetAllUsers")]
public static JArrayLocalRef JniGetAllUsers(JEnvRef jEnv, JObjectLocalRef jObj)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var users = GetAllUsers();
return CreateStringArray(jEnv, users.ToList());
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userAddUser")]
public static void JniAddUser(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef userNamePtr, JStringLocalRef picturePtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userName = GetString(jEnv, userNamePtr) ?? "";
var picture = GetString(jEnv, picturePtr) ?? "";
AddUser(userName, picture);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userDeleteUser")]
public static void JniDeleteUser(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef userIdPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetString(jEnv, userIdPtr) ?? "";
DeleteUser(userId);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_uiHandlerSetup")]
public static void JniSetupUiHandler(JEnvRef jEnv, JObjectLocalRef jObj)
{
SetupUiHandler();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_uiHandlerWait")]
public static void JniWaitUiHandler(JEnvRef jEnv, JObjectLocalRef jObj)
{
WaitUiHandler();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_uiHandlerStopWait")]
public static void JniStopUiHandlerWait(JEnvRef jEnv, JObjectLocalRef jObj)
{
StopUiHandlerWait();
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_uiHandlerSetResponse")]
public static void JniSetUiHandlerResponse(JEnvRef jEnv, JObjectLocalRef jObj, JBoolean isOkPressed, JLong input)
{
SetUiHandlerResponse(isOkPressed, input);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userOpenUser")]
public static void JniOpenUser(JEnvRef jEnv, JObjectLocalRef jObj, JLong userIdPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetStoredString(userIdPtr) ?? "";
OpenUser(userId);
}
[UnmanagedCallersOnly(EntryPoint = "Java_org_ryujinx_android_RyujinxNative_userCloseUser")]
public static void JniCloseUser(JEnvRef jEnv, JObjectLocalRef jObj, JStringLocalRef userIdPtr)
{
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
var userId = GetString(jEnv, userIdPtr) ?? "";
CloseUser(userId);
}
}
internal static partial class Logcat
{
[LibraryImport("liblog", StringMarshalling = StringMarshalling.Utf8)]
private static partial void __android_log_print(LogLevel level, string? tag, string format, string args, IntPtr ptr);
internal static void AndroidLogPrint(LogLevel level, string? tag, string message) =>
__android_log_print(level, tag, "%s", message, IntPtr.Zero);
internal enum LogLevel
{
Unknown = 0x00,
Default = 0x01,
Verbose = 0x02,
Debug = 0x03,
Info = 0x04,
Warn = 0x05,
Error = 0x06,
Fatal = 0x07,
Silent = 0x08,
}
}
}

View File

@ -0,0 +1,286 @@
using LibRyujinx.Jni.Identifiers;
using LibRyujinx.Jni.Internal.Pointers;
using LibRyujinx.Jni.Pointers;
using LibRyujinx.Jni.Primitives;
using LibRyujinx.Jni.References;
using LibRyujinx.Jni.Values;
using System;
namespace LibRyujinx.Jni
{
internal delegate Int32 GetVersionDelegate(JEnvRef env);
internal delegate JClassLocalRef DefineClassDelegate(JEnvRef env, CCharSequence name, JObjectLocalRef loader, IntPtr binaryData, Int32 len);
internal delegate JClassLocalRef FindClassDelegate(JEnvRef env, CCharSequence name);
internal delegate JMethodId FromReflectedMethodDelegate(JEnvRef env, JObjectLocalRef method);
internal delegate JFieldId FromReflectedFieldIdDelegate(JEnvRef env, JObjectLocalRef field);
internal delegate JObjectLocalRef ToReflectedMethodDelegate(JEnvRef env, JClassLocalRef jClass, JMethodId methodId, Boolean isStatic);
internal delegate JClassLocalRef GetSuperclassDelegate(JEnvRef env, JClassLocalRef sub);
internal delegate Boolean IsAssignableFromDelegate(JEnvRef env, JClassLocalRef sub, JClassLocalRef sup);
internal delegate JObjectLocalRef ToReflectedFieldIdDelegate(JEnvRef env, JClassLocalRef jClass, JFieldId fieldId, Boolean isStatic);
internal delegate JResult ThrowDelegate(JEnvRef env, JThrowableLocalRef obj);
internal delegate JResult ThrowNewDelegate(JEnvRef env, JClassLocalRef jClass, CCharSequence msg);
internal delegate JThrowableLocalRef ExceptionOccurredDelegate(JEnvRef env);
internal delegate void ExceptionDescribeDelegate(JEnvRef env);
internal delegate void ExceptionClearDelegate(JEnvRef env);
internal delegate void FatalErrorDelegate(JEnvRef env, CCharSequence msg);
internal delegate JResult PushLocalFrameDelegate(JEnvRef env, Int32 capacity);
internal delegate JObjectLocalRef PopLocalFrameDelegate(JEnvRef env, JObjectLocalRef result);
internal delegate JGlobalRef NewGlobalRefDelegate(JEnvRef env, JObjectLocalRef lref);
internal delegate void DeleteGlobalRefDelegate(JEnvRef env, JGlobalRef gref);
internal delegate void DeleteLocalRefDelegate(JEnvRef env, JObjectLocalRef lref);
internal delegate Boolean IsSameObjectDelegate(JEnvRef env, JObjectLocalRef obj1, JObjectLocalRef obj2);
internal delegate JObjectLocalRef NewLocalRefDelegate(JEnvRef env, JObjectLocalRef objRef);
internal delegate JResult EnsureLocalCapacityDelegate(JEnvRef env, Int32 capacity);
internal delegate JObjectLocalRef AllocObjectDelegate(JEnvRef env, JClassLocalRef jClass);
internal delegate JObjectLocalRef NewObjectDelegate(JEnvRef env, JClassLocalRef jClass, JMethodId jMethod, IntPtr args);
internal delegate JObjectLocalRef NewObjectVDelegate(JEnvRef env, JClassLocalRef jClass, JMethodId jMethod, ArgIterator args);
internal delegate JObjectLocalRef NewObjectADelegate(JEnvRef env, JClassLocalRef jClass, JMethodId jMethod, JValueSequence args);
internal delegate JClassLocalRef GetObjectClassDelegate(JEnvRef env, JObjectLocalRef obj);
internal delegate Boolean IsInstanceOfDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass);
internal delegate JMethodId GetMethodIdDelegate(JEnvRef env, JClassLocalRef jClass, CCharSequence name, CCharSequence signature);
internal delegate JObjectLocalRef CallObjectMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JObjectLocalRef CallObjectMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JObjectLocalRef CallObjectMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JBoolean CallBooleanMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JBoolean CallBooleanMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JBoolean CallBooleanMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JByte CallByteMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JByte CallByteMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JByte CallByteMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JChar CallCharMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JChar CallCharMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JChar CallCharMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JShort CallShortMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JShort CallShortMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JShort CallShortMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JInt CallIntMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JInt CallIntMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JInt CallIntMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JLong CallLongMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JLong CallLongMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JLong CallLongMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JFloat CallFloatMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JFloat CallFloatMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JFloat CallFloatMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JDouble CallDoubleMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate JDouble CallDoubleMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate JDouble CallDoubleMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate void CallVoidMethodDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, IntPtr args);
internal delegate void CallVoidMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, ArgIterator args);
internal delegate void CallVoidMethodADelegate(JEnvRef env, JObjectLocalRef obj, JMethodId jMethod, JValueSequence args);
internal delegate JObjectLocalRef CallNonVirtualObjectMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JObjectLocalRef CallNonVirtualObjectMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JObjectLocalRef CallNonVirtualObjectMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JBoolean CallNonVirtualBooleanMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JBoolean CallNonVirtualBooleanMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JBoolean CallNonVirtualBooleanMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JByte CallNonVirtualByteMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JByte CallNonVirtualByteMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JByte CallNonVirtualByteMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JChar CallNonVirtualCharMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JChar CallNonVirtualCharMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JChar CallNonVirtualCharMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JShort CallNonVirtualShortMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JShort CallNonVirtualShortMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JShort CallNonVirtualShortMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JInt CallNonVirtualIntMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JInt CallNonVirtualIntMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JInt CallNonVirtualIntMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JLong CallNonVirtualLongMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JLong CallNonVirtualLongMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JLong CallNonVirtualLongMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JFloat CallNonVirtualFloatMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JFloat CallNonVirtualFloatMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JFloat CallNonVirtualFloatMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JDouble CallNonVirtualDoubleMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JDouble CallNonVirtualDoubleMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JDouble CallNonVirtualDoubleMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate void CallNonVirtualVoidMethodDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate void CallNonVirtualVoidMethodVDelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate void CallNonVirtualVoidMethodADelegate(JEnvRef env, JObjectLocalRef obj, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JFieldId GetFieldIdDelegate(JEnvRef env, JClassLocalRef jclass, CCharSequence name, CCharSequence signature);
internal delegate JObjectLocalRef GetObjectFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JBoolean GetBooleanFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JByte GetByteFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JChar GetCharFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JShort GetShortFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JInt GetIntFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JLong GetLongFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JFloat GetFloatFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate JDouble GetDoubleFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField);
internal delegate void SetObjectFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JObjectLocalRef value);
internal delegate void SetBooleanFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JBoolean value);
internal delegate void SetByteFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JByte value);
internal delegate void SetCharFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JChar value);
internal delegate void SetShortFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JShort value);
internal delegate void SetIntFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JInt value);
internal delegate void SetLongFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JLong value);
internal delegate void SetFloatFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JFloat value);
internal delegate void SetDoubleFieldDelegate(JEnvRef env, JObjectLocalRef obj, JFieldId jField, JDouble value);
internal delegate JMethodId GetStaticMethodIdDelegate(JEnvRef env, JClassLocalRef jClass, CCharSequence name, CCharSequence signature);
internal delegate JObjectLocalRef CallStaticObjectMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JObjectLocalRef CallStaticObjectMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JObjectLocalRef CallStaticObjectMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JBoolean CallStaticBooleanMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JBoolean CallStaticBooleanMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JBoolean CallStaticBooleanMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JByte CallStaticByteMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JByte CallStaticByteMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JByte CallStaticByteMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JChar CallStaticCharMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JChar CallStaticCharMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JChar CallStaticCharMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JShort CallStaticShortMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JShort CallStaticShortMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JShort CallStaticShortMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JInt CallStaticIntMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JInt CallStaticIntMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JInt CallStaticIntMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JLong CallStaticLongMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JLong CallStaticLongMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JLong CallStaticLongMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JFloat CallStaticFloatMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JFloat CallStaticFloatMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JFloat CallStaticFloatMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JDouble CallStaticDoubleMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate JDouble CallStaticDoubleMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate JDouble CallStaticDoubleMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate void CallStaticVoidMethodDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, IntPtr args);
internal delegate void CallStaticVoidMethodVDelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, ArgIterator args);
internal delegate void CallStaticVoidMethodADelegate(JEnvRef env, JClassLocalRef jclass, JMethodId jMethod, JValueSequence args);
internal delegate JFieldId GetStaticFieldIdDelegate(JEnvRef env, JClassLocalRef jclass, CCharSequence name, CCharSequence signature);
internal delegate JObjectLocalRef GetStaticObjectFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JBoolean GetStaticBooleanFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JByte GetStaticByteFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JChar GetStaticCharFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JShort GetStaticShortFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JInt GetStaticIntFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JLong GetStaticLongFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JFloat GetStaticFloatFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate JDouble GetStaticDoubleFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField);
internal delegate void SetStaticObjectFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JObjectLocalRef value);
internal delegate void SetStaticBooleanFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JBoolean value);
internal delegate void SetStaticByteFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JByte value);
internal delegate void SetStaticCharFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JChar value);
internal delegate void SetStaticShortFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JShort value);
internal delegate void SetStaticIntFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JInt value);
internal delegate void SetStaticLongFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JLong value);
internal delegate void SetStaticFloatFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JFloat value);
internal delegate void SetStaticDoubleFieldDelegate(JEnvRef env, JClassLocalRef jclass, JFieldId jField, JDouble value);
internal delegate JStringLocalRef NewStringDelegate(JEnvRef env, JCharSequence unicode, Int32 length);
internal delegate Int32 GetStringLengthDelegate(JEnvRef env, JStringLocalRef jString);
internal delegate JCharSequence GetStringCharsDelegate(JEnvRef env, JStringLocalRef jString, JBooleanRef isCopy);
internal delegate void ReleaseStringCharsDelegate(JEnvRef env, JStringLocalRef jString, JCharSequence chars);
internal delegate JStringLocalRef NewStringUtfDelegate(JEnvRef env, CCharSequence unicode);
internal delegate Int32 GetStringUtfLengthDelegate(JEnvRef env, JStringLocalRef jString);
internal delegate CCharSequence GetStringUtfCharsDelegate(JEnvRef env, JStringLocalRef jString, JBooleanRef isCopy);
internal delegate void ReleaseStringUtfCharsDelegate(JEnvRef env, JStringLocalRef jString, CCharSequence chars);
internal delegate Int32 GetArrayLengthDelegate(JEnvRef env, JArrayLocalRef array);
internal delegate JArrayLocalRef NewObjectArrayDelegate(JEnvRef env, Int32 length, JClassLocalRef jClass, JObjectLocalRef init);
internal delegate JObjectLocalRef GetObjectArrayElementDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 index);
internal delegate void SetObjectArrayElementDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 index, JObjectLocalRef obj);
internal delegate JArrayLocalRef NewBooleanArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewByteArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewCharArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewShortArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewIntArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewLongArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewFloatArrayDelegate(JEnvRef env, Int32 length);
internal delegate JArrayLocalRef NewDoubleArrayDelegate(JEnvRef env, Int32 length);
internal delegate IntPtr GetBooleanArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetByteArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetCharArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetShortArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetIntArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetLongArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetFloatArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate IntPtr GetDoubleArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate void ReleaseBooleanArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseByteArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseCharArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseShortArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseIntArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseLongArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseFloatArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void ReleaseDoubleArrayElementsDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate void GetBooleanArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetByteArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetCharArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetShortArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetIntArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetLongArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetFloatArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void GetDoubleArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetBooleanArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetByteArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetCharArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetShortArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetIntArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetLongArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetFloatArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate void SetDoubleArrayRegionDelegate(JEnvRef env, JArrayLocalRef jArray, Int32 startIndex, Int32 length, IntPtr buffer);
internal delegate JResult RegisterNativesDelegate(JEnvRef env, JClassLocalRef jClass, JNativeMethodSequence methods);
internal delegate JResult UnregisterNativesDelegate(JEnvRef env, JClassLocalRef jClass);
internal delegate JResult MonitorEnterDelegate(JEnvRef env, JObjectLocalRef jClass);
internal delegate JResult MonitorExitDelegate(JEnvRef env, JObjectLocalRef jClass);
internal delegate JResult GetJavaVMDelegate(JEnvRef env, ref JavaVMRef jvm);
internal delegate void GetStringRegionDelegate(JEnvRef env, JStringLocalRef jString, Int32 startIndex, Int32 length, JCharSequence buffer);
internal delegate void GetStringUtfRegionDelegate(JEnvRef env, JStringLocalRef jString, Int32 startIndex, Int32 length, CCharSequence buffer);
internal delegate IntPtr GetPrimitiveArrayCriticalDelegate(JEnvRef env, JArrayLocalRef jArray, JBooleanRef isCopy);
internal delegate void ReleasePrimitiveArrayCriticalDelegate(JEnvRef env, JArrayLocalRef jArray, IntPtr elements, JReleaseMode mode);
internal delegate JCharSequence GetStringCriticalDelegate(JEnvRef env, JStringLocalRef jString, JBooleanRef isCopy);
internal delegate void ReleaseStringCriticalDelegate(JEnvRef env, JStringLocalRef jString, JCharSequence chars);
internal delegate JWeakRef NewWeakGlobalRefDelegate(JEnvRef env, JObjectLocalRef obj);
internal delegate void DeleteWeakGlobalRefDelegate(JEnvRef env, JWeakRef jWeak);
internal delegate Boolean ExceptionCheckDelegate(JEnvRef env);
internal delegate JObjectLocalRef NewDirectByteBufferDelegate(JEnvRef env, IntPtr address, Int64 capacity);
internal delegate IntPtr GetDirectBufferAddressDelegate(JEnvRef env, JObjectLocalRef buffObj);
internal delegate Int64 GetDirectBufferCapacityDelegate(JEnvRef env, JObjectLocalRef buffObj);
internal delegate JReferenceType GetObjectRefTypeDelegate(JEnvRef env, JObjectLocalRef obj);
internal delegate JResult DestroyJavaVMDelegate(JavaVMRef vm);
internal delegate JResult AttachCurrentThreadDelegate(JavaVMRef vm, ref JEnvRef env, in JavaVMAttachArgs args);
internal delegate JResult DetachCurrentThreadDelegate(JavaVMRef vm);
internal delegate JResult GetEnvDelegate(JavaVMRef vm, ref JEnvRef env, JInt version);
internal delegate JResult AttachCurrentThreadAsDaemonDelegate(JavaVMRef vm, ref JEnvRef env, in JavaVMAttachArgs args);
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.Identifiers
{
public readonly struct JFieldId : IEquatable<JFieldId>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JFieldId other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JFieldId other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JFieldId a, JFieldId b) => a.Equals(b);
public static Boolean operator !=(JFieldId a, JFieldId b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.Identifiers
{
public readonly struct JMethodId : IEquatable<JMethodId>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JMethodId other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JMethodId other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JMethodId a, JMethodId b) => a.Equals(b);
public static Boolean operator !=(JMethodId a, JMethodId b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace LibRyujinx.Jni
{
public enum JReferenceType : Int32
{
InvalidRefType = 0,
LocalRefType = 1,
GlobalRefType = 2,
WeakGlobalRefType = 3
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace LibRyujinx.Jni
{
public enum JReleaseMode : Int32
{
Free = 0,
Commit = 1,
Abort = 2,
}
}

View File

@ -0,0 +1,14 @@
using System;
namespace LibRyujinx.Jni
{
public enum JResult : Int32
{
Ok = 0,
Error = -1,
DetachedThreadError = -2,
VersionError = -3,
MemoryError = -4,
ExitingVMError = -5,
InvalidArgumentsError = -6,
}
}

View File

@ -0,0 +1,36 @@
using System.Runtime.InteropServices;
using System;
using Rxmxnx.PInvoke;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct CCharSequence : IEquatable<CCharSequence>
{
private readonly IntPtr _value;
private CCharSequence(IntPtr value) => this._value = value;
#region Operators
public static implicit operator CCharSequence(IntPtr value) => new(value);
public static implicit operator CCharSequence(Span<Byte> span) => new(span.GetUnsafeIntPtr());
public static implicit operator CCharSequence(ReadOnlySpan<Byte> readonlySpan) => new(readonlySpan.GetUnsafeIntPtr());
public static CCharSequence operator ++(CCharSequence a) => new(a._value + sizeof(Byte));
public static CCharSequence operator --(CCharSequence a) => new(a._value - sizeof(Byte));
public static Boolean operator ==(CCharSequence a, CCharSequence b) => a._value.Equals(b._value);
public static Boolean operator !=(CCharSequence a, CCharSequence b) => !a._value.Equals(b._value);
#endregion
#region Public Methods
public Boolean Equals(CCharSequence other) => this._value.Equals(other._value);
public String AsString(Int32 length = 0)
=> length == 0 ? Marshal.PtrToStringUTF8(_value) : Marshal.PtrToStringUTF8(_value, length);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is CCharSequence other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,30 @@
using System.Runtime.CompilerServices;
using System;
using LibRyujinx.Jni.Primitives;
using Rxmxnx.PInvoke;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct JBooleanRef
{
private static readonly Int32 JBooleanResultFalse = 0;
private static readonly Int32 JBooleanResultTrue = 1;
#pragma warning disable IDE0052
private readonly IntPtr _value;
#pragma warning restore IDE0052
public JBooleanRef(JBoolean? jBoolean)
=> this._value = jBoolean.HasValue ? GetJBooleanRef(jBoolean.Value) : IntPtr.Zero;
private static IntPtr GetJBooleanRef(Boolean value)
{
// Probably gonna break stuff
var t = JBooleanResultTrue;
var f = JBooleanResultFalse;
return value ? Unsafe.AsRef(ref f).GetUnsafeIntPtr() : Unsafe.AsRef(ref t).GetUnsafeIntPtr();
}
}
}

View File

@ -0,0 +1,33 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct JCharSequence : IEquatable<JCharSequence>
{
private readonly IntPtr _value;
private JCharSequence(IntPtr value) => this._value = value;
#region Operators
public static implicit operator JCharSequence(IntPtr value) => new(value);
public static implicit operator JCharSequence(Span<Char> span) => new(span.GetUnsafeIntPtr());
public static implicit operator JCharSequence(ReadOnlySpan<Char> readonlySpan) => new(readonlySpan.GetUnsafeIntPtr());
public static JCharSequence operator ++(JCharSequence a) => new(a._value + sizeof(Char));
public static JCharSequence operator --(JCharSequence a) => new(a._value - sizeof(Char));
public static Boolean operator ==(JCharSequence a, JCharSequence b) => a._value.Equals(b._value);
public static Boolean operator !=(JCharSequence a, JCharSequence b) => !a._value.Equals(b._value);
#endregion
#region Public Methods
public Boolean Equals(JCharSequence other) => this._value.Equals(other._value);
public String AsString(Int32 length = 0) => this._value.GetUnsafeString(length);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JCharSequence other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,32 @@
using LibRyujinx.Jni.Values;
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct JEnvRef : IEquatable<JEnvRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Operators
public static Boolean operator ==(JEnvRef a, JEnvRef b) => a._value.Equals(b._value);
public static Boolean operator !=(JEnvRef a, JEnvRef b) => !a._value.Equals(b._value);
#endregion
#region Public Properties
internal readonly ref JEnvValue Environment => ref this._value.GetUnsafeReference<JEnvValue>();
#endregion
#region Public Methods
public Boolean Equals(JEnvRef other) => this._value.Equals(other._value);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JEnvRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,33 @@
using LibRyujinx.Jni.Values;
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct JNativeMethodSequence : IEquatable<JNativeMethodSequence>
{
private readonly IntPtr _value;
private JNativeMethodSequence(IntPtr value) => this._value = value;
#region Operators
public static implicit operator JNativeMethodSequence(IntPtr value) => new(value);
public static implicit operator JNativeMethodSequence(ReadOnlySpan<JNativeMethod> readonlySpan) => new(readonlySpan.GetUnsafeIntPtr());
public static JNativeMethodSequence operator ++(JNativeMethodSequence a) => new(a._value + JValue.Size);
public static JNativeMethodSequence operator --(JNativeMethodSequence a) => new(a._value - JValue.Size);
public static Boolean operator ==(JNativeMethodSequence a, JNativeMethodSequence b) => a._value.Equals(b._value);
public static Boolean operator !=(JNativeMethodSequence a, JNativeMethodSequence b) => !a._value.Equals(b._value);
#endregion
#region Public Methods
public Boolean Equals(JNativeMethodSequence other) => this._value.Equals(other._value);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JNativeMethodSequence other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,33 @@
using LibRyujinx.Jni.Values;
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Internal.Pointers
{
internal readonly struct JValueSequence : IEquatable<JValueSequence>
{
private readonly IntPtr _value;
private JValueSequence(IntPtr value) => this._value = value;
internal JValueSequence(ReadOnlySpan<JValue> readonlySpan) : this(readonlySpan.GetUnsafeIntPtr()) { }
#region Operators
public static implicit operator JValueSequence(IntPtr value) => new(value);
public static JValueSequence operator ++(JValueSequence a) => new(a._value + JValue.Size);
public static JValueSequence operator --(JValueSequence a) => new(a._value - JValue.Size);
public static Boolean operator ==(JValueSequence a, JValueSequence b) => a._value.Equals(b._value);
public static Boolean operator !=(JValueSequence a, JValueSequence b) => !a._value.Equals(b._value);
#endregion
#region Public Methods
public Boolean Equals(JValueSequence other) => this._value.Equals(other._value);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JValueSequence other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,25 @@
using System;
namespace LibRyujinx.Jni.Pointers
{
public readonly struct JavaVMRef : IEquatable<JavaVMRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Operators
public static Boolean operator ==(JavaVMRef a, JavaVMRef b) => a._value.Equals(b._value);
public static Boolean operator !=(JavaVMRef a, JavaVMRef b) => !a._value.Equals(b._value);
#endregion
#region Public Methods
public Boolean Equals(JavaVMRef other) => this._value.Equals(other._value);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JavaVMRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,67 @@
using LibRyujinx.Jni.Pointers;
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JBoolean : IComparable<Boolean>, IEquatable<Boolean>
{
internal static readonly Type Type = typeof(JBoolean);
private static readonly Byte trueByte = 1;
private static readonly Byte falseByte = 2;
public static readonly CString Signature = (CString)"Z";
private readonly Byte _value;
private Boolean Value => this._value == trueByte;
private JBoolean(Boolean value) => this._value = value ? trueByte : falseByte;
#region Operators
public static implicit operator JBoolean(Boolean value) => new(value);
public static implicit operator Boolean(JBoolean jValue) => jValue._value == 1;
public static implicit operator JBooleanRef(JBoolean? jValue) => new(jValue);
public static JBoolean operator !(JBoolean a) => new(!a.Value);
public static JBoolean operator |(JBoolean a, JBoolean b) => new(a.Value || b.Value);
public static JBoolean operator |(Boolean a, JBoolean b) => new(a || b.Value);
public static JBoolean operator |(JBoolean a, Boolean b) => new(a.Value || b);
public static JBoolean operator &(JBoolean a, JBoolean b) => new(a.Value && b.Value);
public static JBoolean operator &(Boolean a, JBoolean b) => new(a && b.Value);
public static JBoolean operator &(JBoolean a, Boolean b) => new(a.Value && b);
public static Boolean operator ==(JBoolean a, JBoolean b) => a._value.Equals(b._value);
public static Boolean operator ==(Boolean a, JBoolean b) => a.Equals(b._value);
public static Boolean operator ==(JBoolean a, Boolean b) => a._value.Equals(b);
public static Boolean operator !=(JBoolean a, JBoolean b) => !a._value.Equals(b._value);
public static Boolean operator !=(Boolean a, JBoolean b) => !a.Equals(b._value);
public static Boolean operator !=(JBoolean a, Boolean b) => !a._value.Equals(b);
public static Boolean operator >(JBoolean a, JBoolean b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Boolean a, JBoolean b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JBoolean a, Boolean b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JBoolean a, JBoolean b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Boolean a, JBoolean b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JBoolean a, Boolean b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JBoolean a, JBoolean b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Boolean a, JBoolean b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JBoolean a, Boolean b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JBoolean a, JBoolean b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Boolean a, JBoolean b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JBoolean a, Boolean b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Boolean other) => this._value.CompareTo(other);
public Int32 CompareTo(JBoolean other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JBoolean jvalue ? this.CompareTo(jvalue) : obj is Boolean value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Boolean other) => this._value.Equals(other);
public Boolean Equals(JBoolean other) => this._value.Equals(other._value);
public String ToString(IFormatProvider formatProvider) => this._value.ToString(formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JBoolean jvalue ? this.Equals(jvalue) : obj is Boolean value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,74 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JByte : IComparable<SByte>, IEquatable<SByte>, IFormattable
{
internal static readonly Type Type = typeof(JByte);
public static readonly CString Signature = (CString)"B";
private readonly SByte _value;
private JByte(SByte value) => this._value = value;
private JByte(Int32 value) => this._value = Convert.ToSByte(value);
#region Operators
public static implicit operator JByte(SByte value) => new(value);
public static implicit operator SByte(JByte jValue) => jValue._value;
public static JByte operator +(JByte a) => a;
public static JByte operator ++(JByte a) => new(a._value + 1);
public static JByte operator -(JByte a) => new(-a._value);
public static JByte operator --(JByte a) => new(a._value - 1);
public static JByte operator +(JByte a, JByte b) => new(a._value + b._value);
public static JByte operator +(SByte a, JByte b) => new(a + b._value);
public static JByte operator +(JByte a, SByte b) => new(a._value + b);
public static JByte operator -(JByte a, JByte b) => new(a._value - b._value);
public static JByte operator -(SByte a, JByte b) => new(a - b._value);
public static JByte operator -(JByte a, SByte b) => new(a._value - b);
public static JByte operator *(JByte a, JByte b) => new(a._value * b._value);
public static JByte operator *(SByte a, JByte b) => new(a * b._value);
public static JByte operator *(JByte a, SByte b) => new(a._value * b);
public static JByte operator /(JByte a, JByte b) => new(a._value / b._value);
public static JByte operator /(SByte a, JByte b) => new(a / b._value);
public static JByte operator /(JByte a, SByte b) => new(a._value / b);
public static JByte operator %(JByte a, JByte b) => new(a._value % b._value);
public static JByte operator %(SByte a, JByte b) => new(a % b._value);
public static JByte operator %(JByte a, SByte b) => new(a._value % b);
public static Boolean operator ==(JByte a, JByte b) => a._value.Equals(b._value);
public static Boolean operator ==(SByte a, JByte b) => a.Equals(b._value);
public static Boolean operator ==(JByte a, SByte b) => a._value.Equals(b);
public static Boolean operator !=(JByte a, JByte b) => !a._value.Equals(b._value);
public static Boolean operator !=(SByte a, JByte b) => !a.Equals(b._value);
public static Boolean operator !=(JByte a, SByte b) => !a._value.Equals(b);
public static Boolean operator >(JByte a, JByte b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(SByte a, JByte b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JByte a, SByte b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JByte a, JByte b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(SByte a, JByte b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JByte a, SByte b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JByte a, JByte b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(SByte a, JByte b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JByte a, SByte b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JByte a, JByte b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(SByte a, JByte b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JByte a, SByte b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(SByte other) => this._value.CompareTo(other);
public Int32 CompareTo(JByte other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JByte jValue ? this.CompareTo(jValue) : obj is SByte value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(SByte other) => this._value.Equals(other);
public Boolean Equals(JByte other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JByte jvalue ? this.Equals(jvalue) : obj is SByte value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,56 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JChar : IComparable<Char>, IEquatable<Char>
{
internal static readonly Type Type = typeof(JChar);
public static readonly CString Signature = (CString)"C";
private readonly Char _value;
private JChar(Char value) => this._value = value;
#region Operators
public static implicit operator JChar(Char value) => new(value);
public static explicit operator JChar(Int16 value) => new((Char)value);
public static implicit operator Char(JChar jValue) => jValue._value;
public static explicit operator Int16(JChar jValue) => (Int16)jValue._value;
public static Boolean operator ==(JChar a, JChar b) => a._value.Equals(b._value);
public static Boolean operator ==(Char a, JChar b) => a.Equals(b._value);
public static Boolean operator ==(JChar a, Char b) => a._value.Equals(b);
public static Boolean operator !=(JChar a, JChar b) => !a._value.Equals(b._value);
public static Boolean operator !=(Char a, JChar b) => !a.Equals(b._value);
public static Boolean operator !=(JChar a, Char b) => !a._value.Equals(b);
public static Boolean operator >(JChar a, JChar b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Char a, JChar b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JChar a, Char b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JChar a, JChar b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Char a, JChar b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JChar a, Char b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JChar a, JChar b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Char a, JChar b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JChar a, Char b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JChar a, JChar b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Char a, JChar b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JChar a, Char b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Char other) => this._value.CompareTo(other);
public Int32 CompareTo(JChar other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JChar jvalue ? this.CompareTo(jvalue) : obj is Char value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Char other) => this._value.Equals(other);
public Boolean Equals(JChar other) => this._value.Equals(other._value);
public String ToString(IFormatProvider formatProvider) => this._value.ToString(formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JChar jvalue ? this.Equals(jvalue) : obj is Char value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,70 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JDouble : IComparable<Double>, IEquatable<Double>, IFormattable
{
internal static readonly Type Type = typeof(JDouble);
public static readonly CString Signature = (CString)"D";
private readonly Double _value;
private JDouble(Double value) => this._value = value;
#region Operators
public static implicit operator JDouble(Double value) => new(value);
public static implicit operator Double(JDouble jValue) => jValue._value;
public static JDouble operator +(JDouble a) => a;
public static JDouble operator ++(JDouble a) => new(a._value + 1);
public static JDouble operator -(JDouble a) => new(-a._value);
public static JDouble operator --(JDouble a) => new(a._value - 1);
public static JDouble operator +(JDouble a, JDouble b) => new(a._value + b._value);
public static JDouble operator +(Double a, JDouble b) => new(a + b._value);
public static JDouble operator +(JDouble a, Double b) => new(a._value + b);
public static JDouble operator -(JDouble a, JDouble b) => new(a._value - b._value);
public static JDouble operator -(Double a, JDouble b) => new(a - b._value);
public static JDouble operator -(JDouble a, Double b) => new(a._value - b);
public static JDouble operator *(JDouble a, JDouble b) => new(a._value * b._value);
public static JDouble operator *(Double a, JDouble b) => new(a * b._value);
public static JDouble operator *(JDouble a, Double b) => new(a._value * b);
public static JDouble operator /(JDouble a, JDouble b) => new(a._value / b._value);
public static JDouble operator /(Double a, JDouble b) => new(a / b._value);
public static JDouble operator /(JDouble a, Double b) => new(a._value / b);
public static Boolean operator ==(JDouble a, JDouble b) => a._value.Equals(b._value);
public static Boolean operator ==(Double a, JDouble b) => a.Equals(b._value);
public static Boolean operator ==(JDouble a, Double b) => a._value.Equals(b);
public static Boolean operator !=(JDouble a, JDouble b) => !a._value.Equals(b._value);
public static Boolean operator !=(Double a, JDouble b) => !a.Equals(b._value);
public static Boolean operator !=(JDouble a, Double b) => !a._value.Equals(b);
public static Boolean operator >(JDouble a, JDouble b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Double a, JDouble b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JDouble a, Double b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JDouble a, JDouble b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Double a, JDouble b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JDouble a, Double b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JDouble a, JDouble b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Double a, JDouble b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JDouble a, Double b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JDouble a, JDouble b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Double a, JDouble b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JDouble a, Double b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Double other) => this._value.CompareTo(other);
public Int32 CompareTo(JDouble other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JDouble jvalue ? this.CompareTo(jvalue) : obj is Double value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Double other) => this._value.Equals(other);
public Boolean Equals(JDouble other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JDouble jvalue ? this.Equals(jvalue) : obj is Double value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,70 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JFloat : IComparable<Single>, IEquatable<Single>, IFormattable
{
internal static readonly Type Type = typeof(JFloat);
public static readonly CString Signature = (CString)"F";
private readonly Single _value;
private JFloat(Single value) => this._value = value;
#region Operators
public static implicit operator JFloat(Single value) => new(value);
public static implicit operator Single(JFloat jValue) => jValue._value;
public static JFloat operator +(JFloat a) => a;
public static JFloat operator ++(JFloat a) => new(a._value + 1);
public static JFloat operator -(JFloat a) => new(-a._value);
public static JFloat operator --(JFloat a) => new(a._value - 1);
public static JFloat operator +(JFloat a, JFloat b) => new(a._value + b._value);
public static JFloat operator +(Single a, JFloat b) => new(a + b._value);
public static JFloat operator +(JFloat a, Single b) => new(a._value + b);
public static JFloat operator -(JFloat a, JFloat b) => new(a._value - b._value);
public static JFloat operator -(Single a, JFloat b) => new(a - b._value);
public static JFloat operator -(JFloat a, Single b) => new(a._value - b);
public static JFloat operator *(JFloat a, JFloat b) => new(a._value * b._value);
public static JFloat operator *(Single a, JFloat b) => new(a * b._value);
public static JFloat operator *(JFloat a, Single b) => new(a._value * b);
public static JFloat operator /(JFloat a, JFloat b) => new(a._value / b._value);
public static JFloat operator /(Single a, JFloat b) => new(a / b._value);
public static JFloat operator /(JFloat a, Single b) => new(a._value / b);
public static Boolean operator ==(JFloat a, JFloat b) => a._value.Equals(b._value);
public static Boolean operator ==(Single a, JFloat b) => a.Equals(b._value);
public static Boolean operator ==(JFloat a, Single b) => a._value.Equals(b);
public static Boolean operator !=(JFloat a, JFloat b) => !a._value.Equals(b._value);
public static Boolean operator !=(Single a, JFloat b) => !a.Equals(b._value);
public static Boolean operator !=(JFloat a, Single b) => !a._value.Equals(b);
public static Boolean operator >(JFloat a, JFloat b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Single a, JFloat b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JFloat a, Single b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JFloat a, JFloat b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Single a, JFloat b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JFloat a, Single b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JFloat a, JFloat b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Single a, JFloat b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JFloat a, Single b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JFloat a, JFloat b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Single a, JFloat b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JFloat a, Single b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Single other) => this._value.CompareTo(other);
public Int32 CompareTo(JFloat other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JFloat jvalue ? this.CompareTo(jvalue) : obj is Single value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Single other) => this._value.Equals(other);
public Boolean Equals(JFloat other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JFloat jvalue ? this.Equals(jvalue) : obj is Single value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,73 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JInt : IComparable<Int32>, IEquatable<Int32>, IFormattable
{
internal static readonly Type Type = typeof(JInt);
public static readonly CString Signature = (CString)"I";
private readonly Int32 _value;
private JInt(Int32 value) => this._value = value;
#region Operators
public static implicit operator JInt(Int32 value) => new(value);
public static implicit operator Int32(JInt jValue) => jValue._value;
public static JInt operator +(JInt a) => a;
public static JInt operator ++(JInt a) => new(a._value + 1);
public static JInt operator -(JInt a) => new(-a._value);
public static JInt operator --(JInt a) => new(a._value - 1);
public static JInt operator +(JInt a, JInt b) => new(a._value + b._value);
public static JInt operator +(Int32 a, JInt b) => new(a + b._value);
public static JInt operator +(JInt a, Int32 b) => new(a._value + b);
public static JInt operator -(JInt a, JInt b) => new(a._value - b._value);
public static JInt operator -(Int32 a, JInt b) => new(a - b._value);
public static JInt operator -(JInt a, Int32 b) => new(a._value - b);
public static JInt operator *(JInt a, JInt b) => new(a._value * b._value);
public static JInt operator *(Int32 a, JInt b) => new(a * b._value);
public static JInt operator *(JInt a, Int32 b) => new(a._value * b);
public static JInt operator /(JInt a, JInt b) => new(a._value / b._value);
public static JInt operator /(Int32 a, JInt b) => new(a / b._value);
public static JInt operator /(JInt a, Int32 b) => new(a._value / b);
public static JInt operator %(JInt a, JInt b) => new(a._value % b._value);
public static JInt operator %(Int32 a, JInt b) => new(a % b._value);
public static JInt operator %(JInt a, Int32 b) => new(a._value % b);
public static Boolean operator ==(JInt a, JInt b) => a._value.Equals(b._value);
public static Boolean operator ==(Int32 a, JInt b) => a.Equals(b._value);
public static Boolean operator ==(JInt a, Int32 b) => a._value.Equals(b);
public static Boolean operator !=(JInt a, JInt b) => !a._value.Equals(b._value);
public static Boolean operator !=(Int32 a, JInt b) => !a.Equals(b._value);
public static Boolean operator !=(JInt a, Int32 b) => !a._value.Equals(b);
public static Boolean operator >(JInt a, JInt b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Int32 a, JInt b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JInt a, Int32 b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JInt a, JInt b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Int32 a, JInt b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JInt a, Int32 b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JInt a, JInt b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Int32 a, JInt b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JInt a, Int32 b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JInt a, JInt b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Int32 a, JInt b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JInt a, Int32 b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Int32 other) => this._value.CompareTo(other);
public Int32 CompareTo(JInt other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JInt jValue ? this.CompareTo(jValue) : obj is Int32 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int32 other) => this._value.Equals(other);
public Boolean Equals(JInt other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JInt jvalue ? this.Equals(jvalue) : obj is Int32 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,73 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JLong : IComparable<Int64>, IEquatable<Int64>, IFormattable
{
internal static readonly Type Type = typeof(JLong);
public static readonly CString Signature = (CString)"J";
private readonly Int64 _value;
private JLong(Int64 value) => this._value = value;
#region Operators
public static implicit operator JLong(Int64 value) => new(value);
public static implicit operator Int64(JLong jValue) => jValue._value;
public static JLong operator +(JLong a) => a;
public static JLong operator ++(JLong a) => new(a._value + 1);
public static JLong operator -(JLong a) => new(-a._value);
public static JLong operator --(JLong a) => new(a._value - 1);
public static JLong operator +(JLong a, JLong b) => new(a._value + b._value);
public static JLong operator +(Int64 a, JLong b) => new(a + b._value);
public static JLong operator +(JLong a, Int64 b) => new(a._value + b);
public static JLong operator -(JLong a, JLong b) => new(a._value - b._value);
public static JLong operator -(Int64 a, JLong b) => new(a - b._value);
public static JLong operator -(JLong a, Int64 b) => new(a._value - b);
public static JLong operator *(JLong a, JLong b) => new(a._value * b._value);
public static JLong operator *(Int64 a, JLong b) => new(a * b._value);
public static JLong operator *(JLong a, Int64 b) => new(a._value * b);
public static JLong operator /(JLong a, JLong b) => new(a._value / b._value);
public static JLong operator /(Int64 a, JLong b) => new(a / b._value);
public static JLong operator /(JLong a, Int64 b) => new(a._value / b);
public static JLong operator %(JLong a, JLong b) => new(a._value % b._value);
public static JLong operator %(Int64 a, JLong b) => new(a % b._value);
public static JLong operator %(JLong a, Int64 b) => new(a._value % b);
public static Boolean operator ==(JLong a, JLong b) => a._value.Equals(b._value);
public static Boolean operator ==(Int64 a, JLong b) => a.Equals(b._value);
public static Boolean operator ==(JLong a, Int64 b) => a._value.Equals(b);
public static Boolean operator !=(JLong a, JLong b) => !a._value.Equals(b._value);
public static Boolean operator !=(Int64 a, JLong b) => !a.Equals(b._value);
public static Boolean operator !=(JLong a, Int64 b) => !a._value.Equals(b);
public static Boolean operator >(JLong a, JLong b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Int64 a, JLong b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JLong a, Int64 b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JLong a, JLong b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Int64 a, JLong b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JLong a, Int64 b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JLong a, JLong b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Int64 a, JLong b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JLong a, Int64 b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JLong a, JLong b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Int64 a, JLong b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JLong a, Int64 b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Int64 other) => this._value.CompareTo(other);
public Int32 CompareTo(JLong other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JLong jvalue ? this.CompareTo(jvalue) : obj is Int64 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int64 other) => this._value.Equals(other);
public Boolean Equals(JLong other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JLong jvalue ? this.Equals(jvalue) : obj is Int64 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,74 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Primitives
{
public readonly struct JShort : IComparable<Int16>, IEquatable<Int16>, IFormattable
{
internal static readonly Type Type = typeof(JShort);
public static readonly CString Signature = (CString)"S";
private readonly Int16 _value;
private JShort(Int16 value) => this._value = value;
private JShort(Int32 value) => this._value = Convert.ToInt16(value);
#region Operators
public static implicit operator JShort(Int16 value) => new(value);
public static implicit operator Int16(JShort jValue) => jValue._value;
public static JShort operator +(JShort a) => a;
public static JShort operator ++(JShort a) => new(a._value + 1);
public static JShort operator -(JShort a) => new(-a._value);
public static JShort operator --(JShort a) => new(a._value - 1);
public static JShort operator +(JShort a, JShort b) => new(a._value + b._value);
public static JShort operator +(Int16 a, JShort b) => new(a + b._value);
public static JShort operator +(JShort a, Int16 b) => new(a._value + b);
public static JShort operator -(JShort a, JShort b) => new(a._value - b._value);
public static JShort operator -(Int16 a, JShort b) => new(a - b._value);
public static JShort operator -(JShort a, Int16 b) => new(a._value - b);
public static JShort operator *(JShort a, JShort b) => new(a._value * b._value);
public static JShort operator *(Int16 a, JShort b) => new(a * b._value);
public static JShort operator *(JShort a, Int16 b) => new(a._value * b);
public static JShort operator /(JShort a, JShort b) => new(a._value / b._value);
public static JShort operator /(Int16 a, JShort b) => new(a / b._value);
public static JShort operator /(JShort a, Int16 b) => new(a._value / b);
public static JShort operator %(JShort a, JShort b) => new(a._value % b._value);
public static JShort operator %(Int16 a, JShort b) => new(a % b._value);
public static JShort operator %(JShort a, Int16 b) => new(a._value % b);
public static Boolean operator ==(JShort a, JShort b) => a._value.Equals(b._value);
public static Boolean operator ==(Int16 a, JShort b) => a.Equals(b._value);
public static Boolean operator ==(JShort a, Int16 b) => a._value.Equals(b);
public static Boolean operator !=(JShort a, JShort b) => !a._value.Equals(b._value);
public static Boolean operator !=(Int16 a, JShort b) => !a.Equals(b._value);
public static Boolean operator !=(JShort a, Int16 b) => !a._value.Equals(b);
public static Boolean operator >(JShort a, JShort b) => a._value.CompareTo(b._value) > 0;
public static Boolean operator >(Int16 a, JShort b) => a.CompareTo(b._value) > 0;
public static Boolean operator >(JShort a, Int16 b) => a._value.CompareTo(b) > 0;
public static Boolean operator <(JShort a, JShort b) => a._value.CompareTo(b._value) < 0;
public static Boolean operator <(Int16 a, JShort b) => a.CompareTo(b._value) < 0;
public static Boolean operator <(JShort a, Int16 b) => a._value.CompareTo(b) < 0;
public static Boolean operator >=(JShort a, JShort b) => a._value.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(Int16 a, JShort b) => a.CompareTo(b._value) > 0 || a.Equals(b._value);
public static Boolean operator >=(JShort a, Int16 b) => a._value.CompareTo(b) > 0 || a._value.Equals(b);
public static Boolean operator <=(JShort a, JShort b) => a._value.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(Int16 a, JShort b) => a.CompareTo(b._value) < 0 || a.Equals(b._value);
public static Boolean operator <=(JShort a, Int16 b) => a._value.CompareTo(b) < 0 || a._value.Equals(b);
#endregion
#region Public Methods
public Int32 CompareTo(Int16 other) => this._value.CompareTo(other);
public Int32 CompareTo(JShort other) => this._value.CompareTo(other._value);
public Int32 CompareTo(Object obj) => obj is JShort jvalue ? this.CompareTo(jvalue) : obj is Int16 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int16 other) => this._value.Equals(other);
public Boolean Equals(JShort other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JShort jvalue ? this.Equals(jvalue) : obj is Int16 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JArrayLocalRef : IEquatable<JArrayLocalRef>
{
#pragma warning disable 0649
private readonly JObjectLocalRef _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JArrayLocalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JArrayLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JArrayLocalRef a, JArrayLocalRef b) => a.Equals(b);
public static Boolean operator !=(JArrayLocalRef a, JArrayLocalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JClassLocalRef : IEquatable<JClassLocalRef>
{
#pragma warning disable 0649
public readonly JObjectLocalRef _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JClassLocalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JClassLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JClassLocalRef a, JClassLocalRef b) => a.Equals(b);
public static Boolean operator !=(JClassLocalRef a, JClassLocalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JGlobalRef : IEquatable<JGlobalRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JGlobalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JGlobalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JGlobalRef a, JGlobalRef b) => a.Equals(b);
public static Boolean operator !=(JGlobalRef a, JGlobalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JObjectLocalRef : IEquatable<JObjectLocalRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JObjectLocalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JObjectLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JObjectLocalRef a, JObjectLocalRef b) => a.Equals(b);
public static Boolean operator !=(JObjectLocalRef a, JObjectLocalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JStringLocalRef : IEquatable<JStringLocalRef>
{
#pragma warning disable 0649
public readonly JObjectLocalRef _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JStringLocalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JStringLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JStringLocalRef a, JStringLocalRef b) => a.Equals(b);
public static Boolean operator !=(JStringLocalRef a, JStringLocalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JThrowableLocalRef : IEquatable<JThrowableLocalRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JThrowableLocalRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JThrowableLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JThrowableLocalRef a, JThrowableLocalRef b) => a.Equals(b);
public static Boolean operator !=(JThrowableLocalRef a, JThrowableLocalRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.References
{
public readonly struct JWeakRef : IEquatable<JWeakRef>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Public Methods
public Boolean Equals(JWeakRef other)
=> this._value.Equals(other._value);
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
=> obj is JWeakRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
#region Operators
public static Boolean operator ==(JWeakRef a, JWeakRef b) => a.Equals(b);
public static Boolean operator !=(JWeakRef a, JWeakRef b) => !a.Equals(b);
#endregion
}
}

View File

@ -0,0 +1,30 @@
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Values
{
internal readonly struct JEnvValue : IEquatable<JEnvValue>
{
#pragma warning disable 0649
private readonly IntPtr _value;
#pragma warning restore 0649
#region Operators
public static Boolean operator ==(JEnvValue a, JEnvValue b) => a._value.Equals(b._value);
public static Boolean operator !=(JEnvValue a, JEnvValue b) => !a._value.Equals(b._value);
#endregion
#region Public Properties
internal readonly ref JNativeInterface Functions => ref this._value.GetUnsafeReference<JNativeInterface>();
#endregion
#region Public Methods
public Boolean Equals(JEnvValue other) => this._value.Equals(other._value);
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JEnvValue other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}
}

View File

@ -0,0 +1,20 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.Values
{
[SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "This struct is created only by binary operations.")]
public readonly struct JInvokeInterface
{
#pragma warning disable 0169
private readonly IntPtr _reserved0;
private readonly IntPtr _reserved1;
private readonly IntPtr _reserved2;
#pragma warning restore 0169
internal IntPtr DestroyJavaVMPointer { get; init; }
internal IntPtr AttachCurrentThreadPointer { get; init; }
internal IntPtr DetachCurrentThreadPointer { get; init; }
internal IntPtr GetEnvPointer { get; init; }
internal IntPtr AttachCurrentThreadAsDaemonPointer { get; init; }
}
}

View File

@ -0,0 +1,245 @@
using System.Diagnostics.CodeAnalysis;
using System;
namespace LibRyujinx.Jni.Values
{
[SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "This struct is created only by binary operations.")]
public readonly struct JNativeInterface
{
#pragma warning disable 0169
private readonly IntPtr _reserved0;
private readonly IntPtr _reserved1;
private readonly IntPtr _reserved2;
private readonly IntPtr _reserved3;
#pragma warning restore 0169
internal readonly IntPtr GetVersionPointer { get; init; }
internal readonly IntPtr DefineClassPointer { get; init; }
internal readonly IntPtr FindClassPointer { get; init; }
internal readonly IntPtr FromReflectedMethodPointer { get; init; }
internal readonly IntPtr FromReflectedFieldPointer { get; init; }
internal readonly IntPtr ToReflectedMethodPointer { get; init; }
internal readonly IntPtr GetSuperclassPointer { get; init; }
internal readonly IntPtr IsAssignableFromPointer { get; init; }
internal readonly IntPtr ToReflectedFieldPointer { get; init; }
internal readonly IntPtr ThrowPointer { get; init; }
internal readonly IntPtr ThrowNewPointer { get; init; }
internal readonly IntPtr ExceptionOccurredPointer { get; init; }
internal readonly IntPtr ExceptionDescribePointer { get; init; }
internal readonly IntPtr ExceptionClearPointer { get; init; }
internal readonly IntPtr FatalErrorPointer { get; init; }
internal readonly IntPtr PushLocalFramePointer { get; init; }
internal readonly IntPtr PopLocalFramePointer { get; init; }
internal readonly IntPtr NewGlobalRefPointer { get; init; }
internal readonly IntPtr DeleteGlobalRefPointer { get; init; }
internal readonly IntPtr DeleteLocalRefPointer { get; init; }
internal readonly IntPtr IsSameObjectPointer { get; init; }
internal readonly IntPtr NewLocalRefPointer { get; init; }
internal readonly IntPtr EnsureLocalCapacityPointer { get; init; }
internal readonly IntPtr AllocObjectPointer { get; init; }
internal readonly IntPtr NewObjectPointer { get; init; }
internal readonly IntPtr NewObjectVPointer { get; init; }
internal readonly IntPtr NewObjectAPointer { get; init; }
internal readonly IntPtr GetObjectClassPointer { get; init; }
internal readonly IntPtr IsInstanceOfPointer { get; init; }
internal readonly IntPtr GetMethodIdPointer { get; init; }
internal readonly IntPtr CallObjectMethodPointer { get; init; }
internal readonly IntPtr CallObjectMethodVPointer { get; init; }
internal readonly IntPtr CallObjectMethodAPointer { get; init; }
internal readonly IntPtr CallBooleanMethodPointer { get; init; }
internal readonly IntPtr CallBooleanMethodVPointer { get; init; }
internal readonly IntPtr CallBooleanMethodAPointer { get; init; }
internal readonly IntPtr CallByteMethodPointer { get; init; }
internal readonly IntPtr CallByteMethodVPointer { get; init; }
internal readonly IntPtr CallByteMethodAPointer { get; init; }
internal readonly IntPtr CallCharMethodPointer { get; init; }
internal readonly IntPtr CallCharMethodVPointer { get; init; }
internal readonly IntPtr CallCharMethodAPointer { get; init; }
internal readonly IntPtr CallShortMethodPointer { get; init; }
internal readonly IntPtr CallShortMethodVPointer { get; init; }
internal readonly IntPtr CallShortMethodAPointer { get; init; }
internal readonly IntPtr CallIntMethodPointer { get; init; }
internal readonly IntPtr CallIntMethodVPointer { get; init; }
internal readonly IntPtr CallIntMethodAPointer { get; init; }
internal readonly IntPtr CallLongMethodPointer { get; init; }
internal readonly IntPtr CallLongMethodVPointer { get; init; }
internal readonly IntPtr CallLongMethodAPointer { get; init; }
internal readonly IntPtr CallFloatMethodPointer { get; init; }
internal readonly IntPtr CallFloatMethodVPointer { get; init; }
internal readonly IntPtr CallFloatMethodAPointer { get; init; }
internal readonly IntPtr CallDoubleMethodPointer { get; init; }
internal readonly IntPtr CallDoubleMethodVPointer { get; init; }
internal readonly IntPtr CallDoubleMethodAPointer { get; init; }
internal readonly IntPtr CallVoidMethodPointer { get; init; }
internal readonly IntPtr CallVoidMethodVPointer { get; init; }
internal readonly IntPtr CallVoidMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualObjectMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualObjectMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualObjectMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualBooleanMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualBooleanMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualBooleanMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualByteMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualByteMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualByteMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualCharMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualCharMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualCharMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualShortMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualShortMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualShortMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualIntMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualIntMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualIntMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualLongMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualLongMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualLongMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualFloatMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualFloatMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualFloatMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualDoubleMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualDoubleMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualDoubleMethodAPointer { get; init; }
internal readonly IntPtr CallNonVirtualVoidMethodPointer { get; init; }
internal readonly IntPtr CallNonVirtualVoidMethodVPointer { get; init; }
internal readonly IntPtr CallNonVirtualVoidMethodAPointer { get; init; }
internal readonly IntPtr GetFieldIdPointer { get; init; }
internal readonly IntPtr GetObjectFieldPointer { get; init; }
internal readonly IntPtr GetBooleanFieldPointer { get; init; }
internal readonly IntPtr GetByteFieldPointer { get; init; }
internal readonly IntPtr GetCharFieldPointer { get; init; }
internal readonly IntPtr GetShortFieldPointer { get; init; }
internal readonly IntPtr GetIntFieldPointer { get; init; }
internal readonly IntPtr GetLongFieldPointer { get; init; }
internal readonly IntPtr GetFloatFieldPointer { get; init; }
internal readonly IntPtr GetDoubleFieldPointer { get; init; }
internal readonly IntPtr SetObjectFieldPointer { get; init; }
internal readonly IntPtr SetBooleanFieldPointer { get; init; }
internal readonly IntPtr SetByteFieldPointer { get; init; }
internal readonly IntPtr SetCharFieldPointer { get; init; }
internal readonly IntPtr SetShortFieldPointer { get; init; }
internal readonly IntPtr SetIntFieldPointer { get; init; }
internal readonly IntPtr SetLongFieldPointer { get; init; }
internal readonly IntPtr SetFloatFieldPointer { get; init; }
internal readonly IntPtr SetDoubleFieldPointer { get; init; }
internal readonly IntPtr GetStaticMethodIdPointer { get; init; }
internal readonly IntPtr CallStaticObjectMethodPointer { get; init; }
internal readonly IntPtr CallStaticObjectMethodVPointer { get; init; }
internal readonly IntPtr CallStaticObjectMethodAPointer { get; init; }
internal readonly IntPtr CallStaticBooleanMethodPointer { get; init; }
internal readonly IntPtr CallStaticBooleanMethodVPointer { get; init; }
internal readonly IntPtr CallStaticBooleanMethodAPointer { get; init; }
internal readonly IntPtr CallStaticByteMethodPointer { get; init; }
internal readonly IntPtr CallStaticByteMethodVPointer { get; init; }
internal readonly IntPtr CallStaticByteMethodAPointer { get; init; }
internal readonly IntPtr CallStaticCharMethodPointer { get; init; }
internal readonly IntPtr CallStaticCharMethodVPointer { get; init; }
internal readonly IntPtr CallStaticCharMethodAPointer { get; init; }
internal readonly IntPtr CallStaticShortMethodPointer { get; init; }
internal readonly IntPtr CallStaticShortMethodVPointer { get; init; }
internal readonly IntPtr CallStaticShortMethodAPointer { get; init; }
internal readonly IntPtr CallStaticIntMethodPointer { get; init; }
internal readonly IntPtr CallStaticIntMethodVPointer { get; init; }
internal readonly IntPtr CallStaticIntMethodAPointer { get; init; }
internal readonly IntPtr CallStaticLongMethodPointer { get; init; }
internal readonly IntPtr CallStaticLongMethodVPointer { get; init; }
internal readonly IntPtr CallStaticLongMethodAPointer { get; init; }
internal readonly IntPtr CallStaticFloatMethodPointer { get; init; }
internal readonly IntPtr CallStaticFloatMethodVPointer { get; init; }
internal readonly IntPtr CallStaticFloatMethodAPointer { get; init; }
internal readonly IntPtr CallStaticDoubleMethodPointer { get; init; }
internal readonly IntPtr CallStaticDoubleMethodVPointer { get; init; }
internal readonly IntPtr CallStaticDoubleMethodAPointer { get; init; }
internal readonly IntPtr CallStaticVoidMethodPointer { get; init; }
internal readonly IntPtr CallStaticVoidMethodVPointer { get; init; }
internal readonly IntPtr CallStaticVoidMethodAPointer { get; init; }
internal readonly IntPtr GetStaticFieldIdPointer { get; init; }
internal readonly IntPtr GetStaticObjectFieldPointer { get; init; }
internal readonly IntPtr GetStaticBooleanFieldPointer { get; init; }
internal readonly IntPtr GetStaticByteFieldPointer { get; init; }
internal readonly IntPtr GetStaticCharFieldPointer { get; init; }
internal readonly IntPtr GetStaticShortFieldPointer { get; init; }
internal readonly IntPtr GetStaticIntFieldPointer { get; init; }
internal readonly IntPtr GetStaticLongFieldPointer { get; init; }
internal readonly IntPtr GetStaticFloatFieldPointer { get; init; }
internal readonly IntPtr GetStaticDoubleFieldPointer { get; init; }
internal readonly IntPtr SetStaticObjectFieldPointer { get; init; }
internal readonly IntPtr SetStaticBooleanFieldPointer { get; init; }
internal readonly IntPtr SetStaticByteFieldPointer { get; init; }
internal readonly IntPtr SetStaticCharFieldPointer { get; init; }
internal readonly IntPtr SetStaticShortFieldPointer { get; init; }
internal readonly IntPtr SetStaticIntFieldPointer { get; init; }
internal readonly IntPtr SetStaticLongFieldPointer { get; init; }
internal readonly IntPtr SetStaticFloatFieldPointer { get; init; }
internal readonly IntPtr SetStaticDoubleFieldPointer { get; init; }
internal readonly IntPtr NewStringPointer { get; init; }
internal readonly IntPtr GetStringLengthPointer { get; init; }
internal readonly IntPtr GetStringCharsPointer { get; init; }
internal readonly IntPtr ReleaseStringCharsPointer { get; init; }
internal readonly IntPtr NewStringUtfPointer { get; init; }
internal readonly IntPtr GetStringUtfLengthPointer { get; init; }
internal readonly IntPtr GetStringUtfCharsPointer { get; init; }
internal readonly IntPtr ReleaseStringUtfCharsPointer { get; init; }
internal readonly IntPtr GetArrayLengthPointer { get; init; }
internal readonly IntPtr NewObjectArrayPointer { get; init; }
internal readonly IntPtr GetObjectArrayElementPointer { get; init; }
internal readonly IntPtr SetObjectArrayElementPointer { get; init; }
internal readonly IntPtr NewBooleanArrayPointer { get; init; }
internal readonly IntPtr NewByteArrayPointer { get; init; }
internal readonly IntPtr NewCharArrayPointer { get; init; }
internal readonly IntPtr NewShortArrayPointer { get; init; }
internal readonly IntPtr NewIntArrayPointer { get; init; }
internal readonly IntPtr NewLongArrayPointer { get; init; }
internal readonly IntPtr NewFloatArrayPointer { get; init; }
internal readonly IntPtr NewDoubleArrayPointer { get; init; }
internal readonly IntPtr GetBooleanArrayElementsPointer { get; init; }
internal readonly IntPtr GetByteArrayElementsPointer { get; init; }
internal readonly IntPtr GetCharArrayElementsPointer { get; init; }
internal readonly IntPtr GetShortArrayElementsPointer { get; init; }
internal readonly IntPtr GetIntArrayElementsPointer { get; init; }
internal readonly IntPtr GetLongArrayElementsPointer { get; init; }
internal readonly IntPtr GetFloatArrayElementsPointer { get; init; }
internal readonly IntPtr GetDoubleArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseBooleanArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseByteArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseCharArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseShortArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseIntArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseLongArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseFloatArrayElementsPointer { get; init; }
internal readonly IntPtr ReleaseDoubleArrayElementsPointer { get; init; }
internal readonly IntPtr GetBooleanArrayRegionPointer { get; init; }
internal readonly IntPtr GetByteArrayRegionPointer { get; init; }
internal readonly IntPtr GetCharArrayRegionPointer { get; init; }
internal readonly IntPtr GetShortArrayRegionPointer { get; init; }
internal readonly IntPtr GetIntArrayRegionPointer { get; init; }
internal readonly IntPtr GetLongArrayRegionPointer { get; init; }
internal readonly IntPtr GetFloatArrayRegionPointer { get; init; }
internal readonly IntPtr GetDoubleArrayRegionPointer { get; init; }
internal readonly IntPtr SetBooleanArrayRegionPointer { get; init; }
internal readonly IntPtr SetByteArrayRegionPointer { get; init; }
internal readonly IntPtr SetCharArrayRegionPointer { get; init; }
internal readonly IntPtr SetShortArrayRegionPointer { get; init; }
internal readonly IntPtr SetIntArrayRegionPointer { get; init; }
internal readonly IntPtr SetLongArrayRegionPointer { get; init; }
internal readonly IntPtr SetFloatArrayRegionPointer { get; init; }
internal readonly IntPtr SetDoubleArrayRegionPointer { get; init; }
internal readonly IntPtr RegisterNativesPointer { get; init; }
internal readonly IntPtr UnregisterNativesPointer { get; init; }
internal readonly IntPtr MonitorEnterPointer { get; init; }
internal readonly IntPtr MonitorExitPointer { get; init; }
internal readonly IntPtr GetJavaVMPointer { get; init; }
internal readonly IntPtr GetStringRegionPointer { get; init; }
internal readonly IntPtr GetStringUtfRegionPointer { get; init; }
internal readonly IntPtr GetPrimitiveArrayCriticalPointer { get; init; }
internal readonly IntPtr ReleasePrimitiveArrayCriticalPointer { get; init; }
internal readonly IntPtr GetStringCriticalPointer { get; init; }
internal readonly IntPtr ReleaseStringCriticalPointer { get; init; }
internal readonly IntPtr NewWeakGlobalRefPointer { get; init; }
internal readonly IntPtr DeleteWeakGlobalRefPointer { get; init; }
internal readonly IntPtr ExceptionCheckPointer { get; init; }
internal readonly IntPtr NewDirectByteBufferPointer { get; init; }
internal readonly IntPtr GetDirectBufferAddressPointer { get; init; }
internal readonly IntPtr GetDirectBufferCapacityPointer { get; init; }
internal readonly IntPtr GetObjectRefTypePointer { get; init; }
}
}

View File

@ -0,0 +1,12 @@
using LibRyujinx.Jni.Pointers;
using System;
namespace LibRyujinx.Jni.Values
{
public readonly struct JNativeMethod
{
internal CCharSequence Name { get; init; }
internal CCharSequence Signature { get; init; }
internal IntPtr Pointer { get; init; }
}
}

View File

@ -0,0 +1,47 @@
using System.Runtime.CompilerServices;
using Rxmxnx.PInvoke;
using System;
namespace LibRyujinx.Jni.Values
{
internal readonly struct JValue
{
private delegate Boolean IsDefaultDelegate(in JValue value);
public static readonly Int32 Size = NativeUtilities.SizeOf<JValue>();
private static readonly IsDefaultDelegate isDefault = GetIsDefault();
#pragma warning disable 0649
#pragma warning disable 0169
private readonly Byte _value1;
private readonly Byte _value2;
private readonly Int16 _value3;
private readonly Int32 _value4;
#pragma warning restore 0169
#pragma warning restore 0649
public Boolean IsDefault => isDefault(this);
public static JValue Create(in ReadOnlySpan<Byte> source)
{
Byte[] result = new Byte[Size];
for (Int32 i = 0; i < source.Length; i++)
result[i] = source[i];
return result.ToValue<JValue>();
}
private static IsDefaultDelegate GetIsDefault() => Environment.Is64BitProcess ? DefaultLong : Default;
private static Boolean Default(in JValue jValue)
=> (jValue._value1 + jValue._value2 + jValue._value3) == default
&& jValue._value4 == default;
private static Boolean DefaultLong(in JValue jValue)
{
var jv = jValue;
return Unsafe.AsRef(ref jv).Transform<JValue, Int64>() == default;
}
}
}

View File

@ -0,0 +1,13 @@
using LibRyujinx.Jni.Pointers;
using LibRyujinx.Jni.References;
using System;
namespace LibRyujinx.Jni.Values
{
public readonly struct JavaVMAttachArgs
{
internal Int32 Version { get; init; }
internal CCharSequence Name { get; init; }
internal JObjectLocalRef Group { get; init; }
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace LibRyujinx.Jni.Values
{
public readonly struct JavaVMInitArgs
{
internal Int32 Version { get; init; }
internal Int32 OptionsLenght { get; init; }
internal IntPtr Options { get; init; }
internal Boolean IgnoreUnrecognized { get; init; }
}
}

View File

@ -0,0 +1,11 @@
using LibRyujinx.Jni.Pointers;
using System;
namespace LibRyujinx.Jni.Values
{
public readonly struct JavaVMOption
{
internal CCharSequence Name { get; init; }
internal IntPtr ExtraInfo { get; init; }
}
}

View File

@ -0,0 +1,301 @@
using ARMeilleure.Translation;
using LibHac.Ncm;
using LibHac.Tools.FsSystem.NcaUtils;
using Microsoft.Win32.SafeHandles;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input.HLE;
using Silk.NET.Vulkan;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
[UnmanagedCallersOnly(EntryPoint = "device_initialize")]
public static bool InitializeDeviceNative(bool isHostMapped,
bool useNce,
SystemLanguage systemLanguage,
RegionCode regionCode,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
IntPtr timeZone,
bool ignoreMissingServices)
{
return InitializeDevice(isHostMapped,
useNce,
systemLanguage,
regionCode,
enableVsync,
enableDockedMode,
enablePtc,
enableInternetAccess,
Marshal.PtrToStringAnsi(timeZone),
ignoreMissingServices);
}
[UnmanagedCallersOnly(EntryPoint = "device_reloadFilesystem")]
public static void ReloadFileSystem()
{
SwitchDevice?.ReloadFileSystem();
}
public static bool InitializeDevice(bool isHostMapped,
bool useNce,
SystemLanguage systemLanguage,
RegionCode regionCode,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
string? timeZone,
bool ignoreMissingServices)
{
if (SwitchDevice == null)
{
return false;
}
return SwitchDevice.InitializeContext(isHostMapped,
useNce,
systemLanguage,
regionCode,
enableVsync,
enableDockedMode,
enablePtc,
enableInternetAccess,
timeZone,
ignoreMissingServices);
}
[UnmanagedCallersOnly(EntryPoint = "device_load")]
public static bool LoadApplicationNative(IntPtr pathPtr)
{
if(SwitchDevice?.EmulationContext == null)
{
return false;
}
var path = Marshal.PtrToStringAnsi(pathPtr);
return LoadApplication(path);
}
[UnmanagedCallersOnly(EntryPoint = "device_install_firmware")]
public static void InstallFirmwareNative(int descriptor, bool isXci)
{
var stream = OpenFile(descriptor);
InstallFirmware(stream, isXci);
}
[UnmanagedCallersOnly(EntryPoint = "device_get_installed_firmware_version")]
public static IntPtr GetInstalledFirmwareVersionNative()
{
var result = GetInstalledFirmwareVersion();
return Marshal.StringToHGlobalAnsi(result);
}
public static void InstallFirmware(Stream stream, bool isXci)
{
SwitchDevice?.ContentManager.InstallFirmware(stream, isXci);
}
public static string GetInstalledFirmwareVersion()
{
var version = SwitchDevice?.ContentManager.GetCurrentFirmwareVersion();
if (version != null)
{
return version.VersionString;
}
return String.Empty;
}
public static SystemVersion? VerifyFirmware(Stream stream, bool isXci)
{
return SwitchDevice?.ContentManager?.VerifyFirmwarePackage(stream, isXci) ?? null;
}
public static bool LoadApplication(Stream stream, FileType type, Stream? updateStream = null)
{
var emulationContext = SwitchDevice.EmulationContext;
return type switch
{
FileType.None => false,
FileType.Nsp => emulationContext?.LoadNsp(stream, updateStream) ?? false,
FileType.Xci => emulationContext?.LoadXci(stream, updateStream) ?? false,
FileType.Nro => emulationContext?.LoadProgram(stream, true, "") ?? false,
};
}
public static bool LaunchMiiEditApplet()
{
string contentPath = SwitchDevice.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
return LoadApplication(contentPath);
}
public static bool LoadApplication(string? path)
{
var emulationContext = SwitchDevice.EmulationContext;
if (Directory.Exists(path))
{
string[] romFsFiles = Directory.GetFiles(path, "*.istorage");
if (romFsFiles.Length == 0)
{
romFsFiles = Directory.GetFiles(path, "*.romfs");
}
if (romFsFiles.Length > 0)
{
Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS.");
if (!emulationContext.LoadCart(path, romFsFiles[0]))
{
SwitchDevice.DisposeContext();
return false;
}
}
else
{
Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
if (!emulationContext.LoadCart(path))
{
SwitchDevice.DisposeContext();
return false;
}
}
}
else if (File.Exists(path))
{
switch (Path.GetExtension(path).ToLowerInvariant())
{
case ".xci":
Logger.Info?.Print(LogClass.Application, "Loading as XCI.");
if (!emulationContext.LoadXci(path))
{
SwitchDevice.DisposeContext();
return false;
}
break;
case ".nca":
Logger.Info?.Print(LogClass.Application, "Loading as NCA.");
if (!emulationContext.LoadNca(path))
{
SwitchDevice.DisposeContext();
return false;
}
break;
case ".nsp":
case ".pfs0":
Logger.Info?.Print(LogClass.Application, "Loading as NSP.");
if (!emulationContext.LoadNsp(path))
{
SwitchDevice.DisposeContext();
return false;
}
break;
default:
Logger.Info?.Print(LogClass.Application, "Loading as Homebrew.");
try
{
if (!emulationContext.LoadProgram(path))
{
SwitchDevice.DisposeContext();
return false;
}
}
catch (ArgumentOutOfRangeException)
{
Logger.Error?.Print(LogClass.Application, "The specified file is not supported by Ryujinx.");
SwitchDevice.DisposeContext();
return false;
}
break;
}
}
else
{
Logger.Warning?.Print(LogClass.Application, $"Couldn't load '{path}'. Please specify a valid XCI/NCA/NSP/PFS0/NRO file.");
SwitchDevice.DisposeContext();
return false;
}
return true;
}
public static void SignalEmulationClose()
{
_isStopped = true;
_isActive = false;
debug_break(2);
}
public static void CloseEmulation()
{
if (SwitchDevice == null)
return;
_npadManager?.Dispose();
_npadManager = null;
_touchScreenManager?.Dispose();
_touchScreenManager = null;
SwitchDevice?.InputManager?.Dispose();
SwitchDevice.InputManager = null;
_inputManager = null;
_surfaceEvent?.Set();
if (Renderer != null)
{
_gpuDoneEvent.WaitOne();
_gpuDoneEvent.Dispose();
_gpuDoneEvent = null;
SwitchDevice?.DisposeContext();
Renderer = null;
}
}
private static FileStream OpenFile(int descriptor)
{
var safeHandle = new SafeFileHandle(descriptor, false);
return new FileStream(safeHandle, FileAccess.ReadWrite);
}
public enum FileType
{
None,
Nsp,
Xci,
Nro
}
}
}

View File

@ -0,0 +1,324 @@
using ARMeilleure.Translation;
using LibHac.Bcat;
using LibRyujinx.Shared;
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Configuration;
using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.Gpu;
using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
private static bool _isActive;
private static bool _isStopped;
private static CancellationTokenSource _gpuCancellationTokenSource;
private static SwapBuffersCallback? _swapBuffersCallback;
private static NativeGraphicsInterop _nativeGraphicsInterop;
private static ManualResetEvent _gpuDoneEvent;
public delegate void SwapBuffersCallback();
public delegate IntPtr GetProcAddress(string name);
public delegate IntPtr CreateSurface(IntPtr instance);
public static IRenderer? Renderer { get; set; }
public static GraphicsConfiguration GraphicsConfiguration { get; private set; }
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize")]
public static bool InitializeGraphicsNative(GraphicsConfiguration graphicsConfiguration)
{
if (Ryujinx.Common.PlatformInfo.IsBionic)
{
Silk.NET.Core.Loader.SearchPathContainer.Platform = Silk.NET.Core.Loader.UnderlyingPlatform.Android;
}
else if (OperatingSystem.IsIOS())
{
// Yes, macOS not iOS
Silk.NET.Core.Loader.SearchPathContainer.Platform = Silk.NET.Core.Loader.UnderlyingPlatform.MacOS;
}
return InitializeGraphics(graphicsConfiguration);
}
public static bool InitializeGraphics(GraphicsConfiguration graphicsConfiguration)
{
GraphicsConfig.ResScale = graphicsConfiguration.ResScale;
GraphicsConfig.MaxAnisotropy = graphicsConfiguration.MaxAnisotropy;
GraphicsConfig.FastGpuTime = graphicsConfiguration.FastGpuTime;
GraphicsConfig.Fast2DCopy = graphicsConfiguration.Fast2DCopy;
GraphicsConfig.EnableMacroJit = graphicsConfiguration.EnableMacroJit;
GraphicsConfig.EnableMacroHLE = graphicsConfiguration.EnableMacroHLE;
GraphicsConfig.EnableShaderCache = graphicsConfiguration.EnableShaderCache;
GraphicsConfig.EnableTextureRecompression = graphicsConfiguration.EnableTextureRecompression;
GraphicsConfiguration = graphicsConfiguration;
return true;
}
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize_renderer")]
public unsafe static bool InitializeGraphicsRendererNative(GraphicsBackend graphicsBackend, NativeGraphicsInterop nativeGraphicsInterop)
{
_nativeGraphicsInterop = nativeGraphicsInterop;
if (Renderer != null)
{
return false;
}
List<string> extensions = new List<string>();
var size = Marshal.SizeOf<IntPtr>();
var extPtr = (IntPtr*)nativeGraphicsInterop.VkRequiredExtensions;
for (int i = 0; i < nativeGraphicsInterop.VkRequiredExtensionsCount; i++)
{
var ptr = extPtr[i];
extensions.Add(Marshal.PtrToStringAnsi(ptr) ?? string.Empty);
}
CreateSurface createSurfaceFunc = nativeGraphicsInterop.VkCreateSurface == IntPtr.Zero ? default : Marshal.GetDelegateForFunctionPointer<CreateSurface>(nativeGraphicsInterop.VkCreateSurface);
return InitializeGraphicsRenderer(graphicsBackend, createSurfaceFunc, extensions.ToArray());
}
public static bool InitializeGraphicsRenderer(GraphicsBackend graphicsBackend, CreateSurface createSurfaceFunc, string?[] requiredExtensions)
{
if (Renderer != null)
{
return false;
}
if (graphicsBackend == GraphicsBackend.OpenGl)
{
Renderer = new OpenGLRenderer();
}
else if (graphicsBackend == GraphicsBackend.Vulkan)
{
Renderer = new VulkanRenderer(VulkanLoader?.GetApi() ?? Vk.GetApi(), (instance, vk) => new SurfaceKHR((ulong?)createSurfaceFunc(instance.Handle)),
() => requiredExtensions,
null);
}
else
{
return false;
}
return true;
}
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_size")]
public static void SetRendererSizeNative(int width, int height)
{
SetRendererSize(width, height);
}
public static void SetRendererSize(int width, int height)
{
Renderer?.Window?.SetSize(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_run_loop")]
public static void RunLoopNative()
{
if (Renderer is OpenGLRenderer)
{
var proc = Marshal.GetDelegateForFunctionPointer<GetProcAddress>(_nativeGraphicsInterop.GlGetProcAddress);
GL.LoadBindings(new OpenTKBindingsContext(x => proc!.Invoke(x)));
}
RunLoop();
}
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_vsync")]
public static void SetVsyncStateNative(bool enabled)
{
SetVsyncState(enabled);
}
public static void SetVsyncState(bool enabled)
{
var device = SwitchDevice!.EmulationContext!;
device.EnableDeviceVsync = enabled;
device.Gpu.Renderer.Window.ChangeVSyncMode(enabled);
}
public static void RunLoop()
{
if (Renderer == null)
{
return;
}
var device = SwitchDevice!.EmulationContext!;
_gpuDoneEvent = new ManualResetEvent(true);
device.Gpu.Renderer.Initialize(GraphicsDebugLevel.None);
_gpuCancellationTokenSource = new CancellationTokenSource();
device.Gpu.ShaderCacheStateChanged += LoadProgressStateChangedHandler;
device.Processes.ActiveApplication.DiskCacheLoadState.StateChanged += LoadProgressStateChangedHandler;
try
{
device.Gpu.Renderer.RunLoop(() =>
{
_gpuDoneEvent.Reset();
device.Gpu.SetGpuThread();
device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
_isActive = true;
while (_isActive)
{
if (_isStopped)
{
break;
}
debug_break(1);
if (Ryujinx.Common.PlatformInfo.IsBionic)
{
setRenderingThread();
}
if (device.WaitFifo())
{
device.Statistics.RecordFifoStart();
device.ProcessFrame();
device.Statistics.RecordFifoEnd();
}
while (device.ConsumeFrameAvailable())
{
device.PresentFrame(() =>
{
VulkanRenderer? vk = device.Gpu.Renderer as VulkanRenderer;
if (vk == null)
{
vk = (device.Gpu.Renderer as ThreadedRenderer)?.BaseRenderer as VulkanRenderer;
}
if (vk != null)
{
var transform = vk.CurrentTransform;
setCurrentTransform(_window, (int)transform);
}
_swapBuffersCallback?.Invoke();
});
}
}
if (device.Gpu.Renderer is ThreadedRenderer threaded)
{
threaded.FlushThreadedCommands();
}
_gpuDoneEvent.Set();
});
}
finally
{
device.Gpu.ShaderCacheStateChanged -= LoadProgressStateChangedHandler;
device.Processes.ActiveApplication.DiskCacheLoadState.StateChanged -= LoadProgressStateChangedHandler;
}
}
private static void LoadProgressStateChangedHandler<T>(T state, int current, int total) where T : Enum
{
void SetInfo(string status, float value)
{
var ptr = Marshal.StringToHGlobalAnsi(status);
setProgressInfo(ptr, value);
Marshal.FreeHGlobal(ptr);
}
var status = $"{current} / {total}";
var progress = current / (float)total;
switch (state)
{
case LoadState ptcState:
if (float.IsNaN((progress)))
progress = 0;
switch (ptcState)
{
case LoadState.Unloaded:
case LoadState.Loading:
SetInfo($"Loading PTC {status}", progress);
break;
case LoadState.Loaded:
SetInfo($"PTC Loaded", -1);
break;
}
break;
case ShaderCacheState shaderCacheState:
switch (shaderCacheState)
{
case ShaderCacheState.Start:
case ShaderCacheState.Loading:
SetInfo($"Compiling Shaders {status}", progress);
break;
case ShaderCacheState.Packaging:
SetInfo($"Packaging Shaders {status}", progress);
break;
case ShaderCacheState.Loaded:
SetInfo($"Shaders Loaded", -1);
break;
}
break;
default:
throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}");
}
}
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_swap_buffer_callback")]
public static void SetSwapBuffersCallbackNative(IntPtr swapBuffersCallback)
{
_swapBuffersCallback = Marshal.GetDelegateForFunctionPointer<SwapBuffersCallback>(swapBuffersCallback);
}
public static void SetSwapBuffersCallback(SwapBuffersCallback swapBuffersCallback)
{
_swapBuffersCallback = swapBuffersCallback;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct GraphicsConfiguration
{
public float ResScale = 1f;
public float MaxAnisotropy = -1;
public bool FastGpuTime = true;
public bool Fast2DCopy = true;
public bool EnableMacroJit = false;
public bool EnableMacroHLE = true;
public bool EnableShaderCache = true;
public bool EnableTextureRecompression = false;
public BackendThreading BackendThreading = BackendThreading.Auto;
public AspectRatio AspectRatio = AspectRatio.Fixed16x9;
public GraphicsConfiguration()
{
}
}
public struct NativeGraphicsInterop
{
public IntPtr GlGetProcAddress;
public IntPtr VkNativeContextLoader;
public IntPtr VkCreateSurface;
public IntPtr VkRequiredExtensions;
public int VkRequiredExtensionsCount;
}
}

View File

@ -0,0 +1,602 @@
using DiscordRPC;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.Input;
using Ryujinx.Input.HLE;
using Ryujinx.Ui.Common.Configuration;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
using StickInputId = Ryujinx.Input.StickInputId;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
private static VirtualGamepadDriver? _gamepadDriver;
private static VirtualTouchScreen? _virtualTouchScreen;
private static VirtualTouchScreenDriver? _touchScreenDriver;
private static TouchScreenManager? _touchScreenManager;
private static InputManager? _inputManager;
private static NpadManager? _npadManager;
private static InputConfig[] _configs;
public static void InitializeInput(int width, int height)
{
if(SwitchDevice!.InputManager != null)
{
throw new InvalidOperationException("Input is already initialized");
}
_gamepadDriver = new VirtualGamepadDriver(4);
_configs = new InputConfig[4];
_virtualTouchScreen = new VirtualTouchScreen();
_touchScreenDriver = new VirtualTouchScreenDriver(_virtualTouchScreen);
_inputManager = new InputManager(null, _gamepadDriver);
_inputManager.SetMouseDriver(_touchScreenDriver);
_npadManager = _inputManager.CreateNpadManager();
SwitchDevice!.InputManager = _inputManager;
_touchScreenManager = _inputManager.CreateTouchScreenManager();
_touchScreenManager.Initialize(SwitchDevice!.EmulationContext);
_npadManager.Initialize(SwitchDevice.EmulationContext, new List<InputConfig>(), false, false);
_virtualTouchScreen.ClientSize = new Size(width, height);
}
public static void SetClientSize(int width, int height)
{
_virtualTouchScreen!.ClientSize = new Size(width, height);
}
public static void SetTouchPoint(int x, int y)
{
_virtualTouchScreen?.SetPosition(x, y);
}
public static void ReleaseTouchPoint()
{
_virtualTouchScreen?.ReleaseTouch();
}
public static void SetButtonPressed(GamepadButtonInputId button, int id)
{
_gamepadDriver?.SetButtonPressed(button, id);
}
public static void SetButtonReleased(GamepadButtonInputId button, int id)
{
_gamepadDriver?.SetButtonReleased(button, id);
}
public static void SetAccelerometerData(Vector3 accel, int id)
{
_gamepadDriver?.SetAccelerometerData(accel, id);
}
public static void SetGryoData(Vector3 gyro, int id)
{
_gamepadDriver?.SetGryoData(gyro, id);
}
public static void SetStickAxis(StickInputId stick, Vector2 axes, int deviceId)
{
_gamepadDriver?.SetStickAxis(stick, axes, deviceId);
}
public static int ConnectGamepad(int index)
{
var gamepad = _gamepadDriver?.GetGamepad(index);
if (gamepad != null)
{
var config = CreateDefaultInputConfig();
config.Id = gamepad.Id;
config.PlayerIndex = (PlayerIndex)index;
_configs[index] = config;
}
_npadManager?.ReloadConfiguration(_configs.Where(x => x != null).ToList(), false, false);
return int.TryParse(gamepad?.Id, out var idInt) ? idInt : -1;
}
private static InputConfig CreateDefaultInputConfig()
{
return new StandardControllerInputConfig
{
Version = InputConfig.CurrentVersion,
Backend = InputBackendType.GamepadSDL2,
Id = null,
ControllerType = ControllerType.ProController,
DeadzoneLeft = 0.1f,
DeadzoneRight = 0.1f,
RangeLeft = 1.0f,
RangeRight = 1.0f,
TriggerThreshold = 0.5f,
LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
{
DpadUp = ConfigGamepadInputId.DpadUp,
DpadDown = ConfigGamepadInputId.DpadDown,
DpadLeft = ConfigGamepadInputId.DpadLeft,
DpadRight = ConfigGamepadInputId.DpadRight,
ButtonMinus = ConfigGamepadInputId.Minus,
ButtonL = ConfigGamepadInputId.LeftShoulder,
ButtonZl = ConfigGamepadInputId.LeftTrigger,
ButtonSl = ConfigGamepadInputId.Unbound,
ButtonSr = ConfigGamepadInputId.Unbound,
},
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
{
Joystick = ConfigStickInputId.Left,
StickButton = ConfigGamepadInputId.LeftStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
{
ButtonA = ConfigGamepadInputId.A,
ButtonB = ConfigGamepadInputId.B,
ButtonX = ConfigGamepadInputId.X,
ButtonY = ConfigGamepadInputId.Y,
ButtonPlus = ConfigGamepadInputId.Plus,
ButtonR = ConfigGamepadInputId.RightShoulder,
ButtonZr = ConfigGamepadInputId.RightTrigger,
ButtonSl = ConfigGamepadInputId.Unbound,
ButtonSr = ConfigGamepadInputId.Unbound,
},
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
{
Joystick = ConfigStickInputId.Right,
StickButton = ConfigGamepadInputId.RightStick,
InvertStickX = false,
InvertStickY = false,
Rotate90CW = false,
},
Motion = new StandardMotionConfigController
{
MotionBackend = MotionInputBackendType.GamepadDriver,
EnableMotion = true,
Sensitivity = 100,
GyroDeadzone = 1,
},
Rumble = new RumbleConfigController
{
StrongRumble = 1f,
WeakRumble = 1f,
EnableRumble = false
}
};
}
public static void UpdateInput()
{
_npadManager?.Update(GraphicsConfiguration.AspectRatio.ToFloat());
if(!_touchScreenManager!.Update(true, _virtualTouchScreen!.IsButtonPressed(MouseButton.Button1), GraphicsConfiguration.AspectRatio.ToFloat()))
{
SwitchDevice!.EmulationContext?.Hid.Touchscreen.Update();
}
}
// Native Methods
[UnmanagedCallersOnly(EntryPoint = "input_initialize")]
public static void InitializeInputNative(int width, int height)
{
InitializeInput(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_client_size")]
public static void SetClientSizeNative(int width, int height)
{
SetClientSize(width, height);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_touch_point")]
public static void SetTouchPointNative(int x, int y)
{
SetTouchPoint(x, y);
}
[UnmanagedCallersOnly(EntryPoint = "input_release_touch_point")]
public static void ReleaseTouchPointNative()
{
ReleaseTouchPoint();
}
[UnmanagedCallersOnly(EntryPoint = "input_update")]
public static void UpdateInputNative()
{
UpdateInput();
}
[UnmanagedCallersOnly(EntryPoint = "input_set_button_pressed")]
public static void SetButtonPressedNative(GamepadButtonInputId button, int id)
{
SetButtonPressed(button, id);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_button_released")]
public static void SetButtonReleasedNative(GamepadButtonInputId button, int id)
{
SetButtonReleased(button, id);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_accelerometer_data")]
public static void SetAccelerometerDataNative(Vector3 accel, int id)
{
SetAccelerometerData(accel, id);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_gyro_data")]
public static void SetGryoDataNatuve(Vector3 gyro, int id)
{
SetGryoData(gyro, id);
}
[UnmanagedCallersOnly(EntryPoint = "input_set_stick_axis")]
public static void SetStickAxisNative(StickInputId stick, Vector2 axes, int id)
{
SetStickAxis(stick, axes, id);
}
[UnmanagedCallersOnly(EntryPoint = "input_connect_gamepad")]
public static IntPtr ConnectGamepadNative(int index)
{
return ConnectGamepad(index);
}
}
public class VirtualTouchScreen : IMouse
{
public Size ClientSize { get; set; }
public bool[] Buttons { get; }
public VirtualTouchScreen()
{
Buttons = new bool[2];
}
public Vector2 CurrentPosition { get; private set; }
public Vector2 Scroll { get; private set; }
public string Id => "0";
public string Name => "AvaloniaMouse";
public bool IsConnected => true;
public GamepadFeaturesFlag Features => throw new NotImplementedException();
public void Dispose()
{
}
public GamepadStateSnapshot GetMappedStateSnapshot()
{
throw new NotImplementedException();
}
public void SetPosition(int x, int y)
{
CurrentPosition = new Vector2(x, y);
Buttons[0] = true;
}
public void ReleaseTouch()
{
Buttons[0] = false;
}
public Vector3 GetMotionData(MotionInputId inputId)
{
throw new NotImplementedException();
}
public Vector2 GetPosition()
{
return CurrentPosition;
}
public Vector2 GetScroll()
{
return Scroll;
}
public GamepadStateSnapshot GetStateSnapshot()
{
throw new NotImplementedException();
}
public (float, float) GetStick(Ryujinx.Input.StickInputId inputId)
{
throw new NotImplementedException();
}
public bool IsButtonPressed(MouseButton button)
{
return Buttons[0];
}
public bool IsPressed(GamepadButtonInputId inputId)
{
throw new NotImplementedException();
}
public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
throw new NotImplementedException();
}
public void SetConfiguration(InputConfig configuration)
{
throw new NotImplementedException();
}
public void SetTriggerThreshold(float triggerThreshold)
{
throw new NotImplementedException();
}
}
public class VirtualTouchScreenDriver : IGamepadDriver
{
private readonly VirtualTouchScreen _virtualTouchScreen;
public VirtualTouchScreenDriver(VirtualTouchScreen virtualTouchScreen)
{
_virtualTouchScreen = virtualTouchScreen;
}
public string DriverName => "VirtualTouchDriver";
public ReadOnlySpan<string> GamepadsIds => new[] { "0" };
public event Action<string> OnGamepadConnected
{
add { }
remove { }
}
public event Action<string> OnGamepadDisconnected
{
add { }
remove { }
}
public void Dispose()
{
}
public IGamepad GetGamepad(string id)
{
return _virtualTouchScreen;
}
}
public class VirtualGamepadDriver : IGamepadDriver
{
private readonly int _controllerCount;
public ReadOnlySpan<string> GamepadsIds => _gamePads.Keys.Select(x => x.ToString()).ToArray();
public string DriverName => "Virtual";
public event Action<string> OnGamepadConnected;
public event Action<string> OnGamepadDisconnected;
private Dictionary<int, VirtualGamepad> _gamePads;
public VirtualGamepadDriver(int controllerCount)
{
_gamePads = new Dictionary<int, VirtualGamepad>();
for (int joystickIndex = 0; joystickIndex < controllerCount; joystickIndex++)
{
HandleJoyStickConnected(joystickIndex);
}
_controllerCount = controllerCount;
}
private void HandleJoyStickConnected(int joystickDeviceId)
{
_gamePads[joystickDeviceId] = new VirtualGamepad(this, joystickDeviceId);
OnGamepadConnected?.Invoke(joystickDeviceId.ToString());
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Simulate a full disconnect when disposing
var ids = GamepadsIds;
foreach (string id in ids)
{
OnGamepadDisconnected?.Invoke(id);
}
_gamePads.Clear();
}
}
public void Dispose()
{
Dispose(true);
}
public IGamepad GetGamepad(string id)
{
return _gamePads[int.Parse(id)];
}
public IGamepad GetGamepad(int index)
{
return _gamePads[index];
}
public void SetStickAxis(StickInputId stick, Vector2 axes, int deviceId)
{
if(_gamePads.TryGetValue(deviceId, out var gamePad))
{
gamePad.StickInputs[(int)stick] = axes;
}
}
public void SetButtonPressed(GamepadButtonInputId button, int deviceId)
{
if (_gamePads.TryGetValue(deviceId, out var gamePad))
{
gamePad.ButtonInputs[(int)button] = true;
}
}
public void SetButtonReleased(GamepadButtonInputId button, int deviceId)
{
if (_gamePads.TryGetValue(deviceId, out var gamePad))
{
gamePad.ButtonInputs[(int)button] = false;
}
}
public void SetAccelerometerData(Vector3 accel, int deviceId)
{
if (_gamePads.TryGetValue(deviceId, out var gamePad))
{
gamePad.Accelerometer = accel;
}
}
public void SetGryoData(Vector3 gyro, int deviceId)
{
if (_gamePads.TryGetValue(deviceId, out var gamePad))
{
gamePad.Gyro = gyro;
}
}
}
public class VirtualGamepad : IGamepad
{
private readonly VirtualGamepadDriver _driver;
private bool[] _buttonInputs;
private Vector2[] _stickInputs;
public VirtualGamepad(VirtualGamepadDriver driver, int id)
{
_buttonInputs = new bool[(int)GamepadButtonInputId.Count];
_stickInputs = new Vector2[(int)StickInputId.Count];
_driver = driver;
Id = id.ToString();
IdInt = id;
}
public void Dispose() { }
public GamepadFeaturesFlag Features { get; } = GamepadFeaturesFlag.Motion;
public string Id { get; }
internal readonly int IdInt;
public string Name => Id;
public bool IsConnected { get; }
public Vector2[] StickInputs { get => _stickInputs; set => _stickInputs = value; }
public bool[] ButtonInputs { get => _buttonInputs; set => _buttonInputs = value; }
public Vector3 Accelerometer { get; internal set; }
public Vector3 Gyro { get; internal set; }
public bool IsPressed(GamepadButtonInputId inputId)
{
return _buttonInputs[(int)inputId];
}
public (float, float) GetStick(StickInputId inputId)
{
var v = _stickInputs[(int)inputId];
return (v.X, v.Y);
}
public Vector3 GetMotionData(MotionInputId inputId)
{
if (inputId == MotionInputId.Accelerometer)
return Accelerometer;
else if (inputId == MotionInputId.Gyroscope)
return RadToDegree(Gyro);
return new Vector3();
}
private static Vector3 RadToDegree(Vector3 rad)
{
return rad * (180 / MathF.PI);
}
public void SetTriggerThreshold(float triggerThreshold)
{
//throw new System.NotImplementedException();
}
public void SetConfiguration(InputConfig configuration)
{
//throw new System.NotImplementedException();
}
public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
{
//throw new System.NotImplementedException();
}
public GamepadStateSnapshot GetMappedStateSnapshot()
{
GamepadStateSnapshot result = default;
foreach (var button in Enum.GetValues<GamepadButtonInputId>())
{
// Do not touch state of button already pressed
if (button != GamepadButtonInputId.Count && !result.IsPressed(button))
{
result.SetPressed(button, IsPressed(button));
}
}
(float leftStickX, float leftStickY) = GetStick(StickInputId.Left);
(float rightStickX, float rightStickY) = GetStick(StickInputId.Right);
result.SetStick(StickInputId.Left, leftStickX, leftStickY);
result.SetStick(StickInputId.Right, rightStickX, rightStickY);
return result;
}
public GamepadStateSnapshot GetStateSnapshot()
{
return new GamepadStateSnapshot();
}
}
}

View File

@ -0,0 +1,82 @@
using Ryujinx.HLE.HOS.Services.Account.Acc;
using System;
using System.Linq;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
public static string GetOpenedUser()
{
var lastProfile = SwitchDevice?.AccountManager.LastOpenedUser;
return lastProfile?.UserId.ToString() ?? "";
}
public static string GetUserPicture(string userId)
{
var uid = new UserId(userId);
var user = SwitchDevice?.AccountManager.GetAllUsers().FirstOrDefault(x => x.UserId == uid);
if (user == null)
return "";
var pic = user.Image;
return pic != null ? Convert.ToBase64String(pic) : "";
}
public static void SetUserPicture(string userId, string picture)
{
var uid = new UserId(userId);
SwitchDevice?.AccountManager.SetUserImage(uid, Convert.FromBase64String(picture));
}
public static string GetUserName(string userId)
{
var uid = new UserId(userId);
var user = SwitchDevice?.AccountManager.GetAllUsers().FirstOrDefault(x => x.UserId == uid);
return user?.Name ?? "";
}
public static void SetUserName(string userId, string name)
{
var uid = new UserId(userId);
SwitchDevice?.AccountManager.SetUserName(uid, name);
}
public static string[] GetAllUsers()
{
return SwitchDevice?.AccountManager.GetAllUsers().Select(x => x.UserId.ToString()).ToArray() ??
Array.Empty<string>();
}
public static void AddUser(string userName, string picture)
{
SwitchDevice?.AccountManager.AddUser(userName, Convert.FromBase64String(picture));
}
public static void DeleteUser(string userId)
{
var uid = new UserId(userId);
SwitchDevice?.AccountManager.DeleteUser(uid);
}
public static void OpenUser(string userId)
{
var uid = new UserId(userId);
SwitchDevice?.AccountManager.OpenUser(uid);
}
public static void CloseUser(string userId)
{
var uid = new UserId(userId);
SwitchDevice?.AccountManager.CloseUser(uid);
}
}
}

View File

@ -0,0 +1,883 @@
// State class for the library
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS;
using Ryujinx.Input.HLE;
using Ryujinx.HLE;
using System;
using System.Runtime.InteropServices;
using Ryujinx.Common.Configuration;
using LibHac.Tools.FsSystem;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Audio.Integration;
using Ryujinx.Audio.Backends.SDL2;
using System.IO;
using LibHac.Common.Keys;
using LibHac.Common;
using LibHac.Ns;
using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem.NcaUtils;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Fs;
using Path = System.IO.Path;
using LibHac;
using OpenTK.Audio.OpenAL;
using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.HLE.Loaders.Npdm;
using Ryujinx.Common.Utilities;
using System.Globalization;
using Ryujinx.Ui.Common.Configuration.System;
using Ryujinx.Common.Logging.Targets;
using System.Collections.Generic;
using LibHac.Bcat;
using Ryujinx.Ui.App.Common;
using System.Text;
using Ryujinx.HLE.Ui;
using LibRyujinx.Android;
namespace LibRyujinx
{
public static partial class LibRyujinx
{
internal static IHardwareDeviceDriver AudioDriver { get; set; } = new DummyHardwareDeviceDriver();
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public static SwitchDevice? SwitchDevice { get; set; }
[UnmanagedCallersOnly(EntryPoint = "initialize")]
public static bool Initialize(IntPtr basePathPtr)
{
var path = Marshal.PtrToStringAnsi(basePathPtr);
var res = Initialize(path);
InitializeAudio();
return res;
}
public static bool Initialize(string? basePath)
{
if (SwitchDevice != null)
{
return false;
}
try
{
AppDataManager.Initialize(basePath);
ConfigurationState.Initialize();
LoggerModule.Initialize();
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget(AppDataManager.BaseDirPath, "file"),
1000,
AsyncLogTargetOverflowAction.Block
));
Logger.Notice.Print(LogClass.Application, "Initializing...");
Logger.Notice.Print(LogClass.Application, $"Using base path: {AppDataManager.BaseDirPath}");
SwitchDevice = new SwitchDevice();
}
catch (Exception ex)
{
Console.WriteLine(ex);
return false;
}
OpenALLibraryNameContainer.OverridePath = "libopenal.so";
Logger.Notice.Print(LogClass.Application, "RyujinxAndroid is ready!");
return true;
}
public static void InitializeAudio()
{
AudioDriver = new SDL2HardwareDeviceDriver();
}
public static GameStats GetGameStats()
{
if (SwitchDevice?.EmulationContext == null)
return new GameStats();
var context = SwitchDevice.EmulationContext;
return new GameStats
{
Fifo = context.Statistics.GetFifoPercent(),
GameFps = context.Statistics.GetGameFrameRate(),
GameTime = context.Statistics.GetGameFrameTime()
};
}
public static GameInfo? GetGameInfo(string? file)
{
if (string.IsNullOrWhiteSpace(file))
{
return new GameInfo();
}
Logger.Info?.Print(LogClass.Application, $"Getting game info for file: {file}");
using var stream = File.Open(file, FileMode.Open);
return GetGameInfo(stream, new FileInfo(file).Extension.Remove('.'));
}
[UnmanagedCallersOnly(EntryPoint = "get_game_info")]
public static GameInfoNative GetGameInfoNative(int descriptor, IntPtr extensionPtr)
{
var extension = Marshal.PtrToStringAnsi(extensionPtr);
var stream = OpenFile(descriptor);
var gameInfo = GetGameInfo(stream, extension);
return new GameInfoNative(0, gameInfo.TitleName, 0, gameInfo.Developer, 0);
}
public static GameInfo? GetGameInfo(Stream gameStream, string extension)
{
if (SwitchDevice == null)
{
Logger.Error?.Print(LogClass.Application, "SwitchDevice is not initialized.");
return null;
}
var gameInfo = new GameInfo
{
FileSize = gameStream.Length * 0.000000000931,
TitleName = "Unknown",
TitleId = "0000000000000000",
Developer = "Unknown",
Version = "0",
Icon = null
};
const Language TitleLanguage = Language.AmericanEnglish;
BlitStruct<ApplicationControlProperty> controlHolder = new(1);
try
{
try
{
if (extension == "nsp" || extension == "pfs0" || extension == "xci")
{
IFileSystem pfs;
bool isExeFs = false;
if (extension == "xci")
{
Xci xci = new(SwitchDevice.VirtualFileSystem.KeySet, gameStream.AsStorage());
pfs = xci.OpenPartition(XciPartitionType.Secure);
}
else
{
var pfsTemp = new PartitionFileSystem();
pfsTemp.Initialize(gameStream.AsStorage()).ThrowIfFailure();
pfs = pfsTemp;
// If the NSP doesn't have a main NCA, decrement the number of applications found and then continue to the next application.
bool hasMainNca = false;
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*"))
{
if (Path.GetExtension(fileEntry.FullPath).ToLower() == ".nca")
{
using UniqueRef<IFile> ncaFile = new();
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(SwitchDevice.VirtualFileSystem.KeySet, ncaFile.Get.AsStorage());
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
// Some main NCAs don't have a data partition, so check if the partition exists before opening it
if (nca.Header.ContentType == NcaContentType.Program && !(nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection()))
{
hasMainNca = true;
break;
}
}
else if (Path.GetFileNameWithoutExtension(fileEntry.FullPath) == "main")
{
isExeFs = true;
}
}
if (!hasMainNca && !isExeFs)
{
return null;
}
}
if (isExeFs)
{
using UniqueRef<IFile> npdmFile = new();
Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
if (ResultFs.PathNotFound.Includes(result))
{
Npdm npdm = new(npdmFile.Get.AsStream());
gameInfo.TitleName = npdm.TitleName;
gameInfo.TitleId = npdm.Aci0.TitleId.ToString("x16");
}
}
else
{
GetControlFsAndTitleId(pfs, out IFileSystem? controlFs, out string? id);
gameInfo.TitleId = id;
if (controlFs == null)
{
Logger.Error?.Print(LogClass.Application, $"No control FS was returned. Unable to process game any further: {gameInfo.TitleName}");
return null;
}
// Check if there is an update available.
if (IsUpdateApplied(gameInfo.TitleId, out IFileSystem? updatedControlFs))
{
// Replace the original ControlFs by the updated one.
controlFs = updatedControlFs;
}
ReadControlData(controlFs, controlHolder.ByteSpan);
GetGameInformation(ref controlHolder.Value, out gameInfo.TitleName, out _, out gameInfo.Developer, out gameInfo.Version);
// Read the icon from the ControlFS and store it as a byte array
try
{
using UniqueRef<IFile> icon = new();
controlFs?.OpenFile(ref icon.Ref, $"/icon_{TitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();
using MemoryStream stream = new();
icon.Get.AsStream().CopyTo(stream);
gameInfo.Icon = stream.ToArray();
}
catch (HorizonResultException)
{
foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
{
if (entry.Name == "control.nacp")
{
continue;
}
using var icon = new UniqueRef<IFile>();
controlFs?.OpenFile(ref icon.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
using MemoryStream stream = new();
icon.Get.AsStream().CopyTo(stream);
gameInfo.Icon = stream.ToArray();
if (gameInfo.Icon != null)
{
break;
}
}
}
}
}
else if (extension == "nro")
{
BinaryReader reader = new(gameStream);
byte[] Read(long position, int size)
{
gameStream.Seek(position, SeekOrigin.Begin);
return reader.ReadBytes(size);
}
gameStream.Seek(24, SeekOrigin.Begin);
int assetOffset = reader.ReadInt32();
if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
{
byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
ulong nacpOffset = reader.ReadUInt64();
ulong nacpSize = reader.ReadUInt64();
// Reads and stores game icon as byte array
if (iconSize > 0)
{
gameInfo.Icon = Read(assetOffset + iconOffset, (int)iconSize);
}
// Read the NACP data
Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
GetGameInformation(ref controlHolder.Value, out gameInfo.TitleName, out _, out gameInfo.Developer, out gameInfo.Version);
}
}
}
catch (MissingKeyException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
}
catch (InvalidDataException exception)
{
Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. {exception}");
}
catch (Exception exception)
{
Logger.Warning?.Print(LogClass.Application, $"The gameStream encountered was not of a valid type. Error: {exception}");
return null;
}
}
catch (IOException exception)
{
Logger.Warning?.Print(LogClass.Application, exception.Message);
}
void ReadControlData(IFileSystem? controlFs, Span<byte> outProperty)
{
using UniqueRef<IFile> controlFile = new();
controlFs?.OpenFile(ref controlFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
controlFile.Get.Read(out _, 0, outProperty, ReadOption.None).ThrowIfFailure();
}
void GetGameInformation(ref ApplicationControlProperty controlData, out string? titleName, out string titleId, out string? publisher, out string? version)
{
_ = Enum.TryParse(TitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage);
if (controlData.Title.ItemsRo.Length > (int)desiredTitleLanguage)
{
titleName = controlData.Title[(int)desiredTitleLanguage].NameString.ToString();
publisher = controlData.Title[(int)desiredTitleLanguage].PublisherString.ToString();
}
else
{
titleName = null;
publisher = null;
}
if (string.IsNullOrWhiteSpace(titleName))
{
foreach (ref readonly var controlTitle in controlData.Title.ItemsRo)
{
if (!controlTitle.NameString.IsEmpty())
{
titleName = controlTitle.NameString.ToString();
break;
}
}
}
if (string.IsNullOrWhiteSpace(publisher))
{
foreach (ref readonly var controlTitle in controlData.Title.ItemsRo)
{
if (!controlTitle.PublisherString.IsEmpty())
{
publisher = controlTitle.PublisherString.ToString();
break;
}
}
}
if (controlData.PresenceGroupId != 0)
{
titleId = controlData.PresenceGroupId.ToString("x16");
}
else if (controlData.SaveDataOwnerId != 0)
{
titleId = controlData.SaveDataOwnerId.ToString();
}
else if (controlData.AddOnContentBaseId != 0)
{
titleId = (controlData.AddOnContentBaseId - 0x1000).ToString("x16");
}
else
{
titleId = "0000000000000000";
}
version = controlData.DisplayVersionString.ToString();
}
void GetControlFsAndTitleId(IFileSystem pfs, out IFileSystem? controlFs, out string? titleId)
{
if (SwitchDevice == null)
{
Logger.Error?.Print(LogClass.Application, "SwitchDevice is not initialized.");
controlFs = null;
titleId = null;
return;
}
(_, _, Nca? controlNca) = GetGameData(SwitchDevice.VirtualFileSystem, pfs, 0);
if (controlNca == null)
{
Logger.Warning?.Print(LogClass.Application, "Control NCA is null. Unable to load control FS.");
}
// Return the ControlFS
controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
titleId = controlNca?.Header.TitleId.ToString("x16");
}
(Nca? mainNca, Nca? patchNca, Nca? controlNca) GetGameData(VirtualFileSystem fileSystem, IFileSystem pfs, int programIndex)
{
Nca? mainNca = null;
Nca? patchNca = null;
Nca? controlNca = null;
fileSystem.ImportTickets(pfs);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
{
using var ncaFile = new UniqueRef<IFile>();
Logger.Info?.Print(LogClass.Application, $"Loading file from PFS: {fileEntry.FullPath}");
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(fileSystem.KeySet, ncaFile.Release().AsStorage());
int ncaProgramIndex = (int)(nca.Header.TitleId & 0xF);
if (ncaProgramIndex != programIndex)
{
continue;
}
if (nca.Header.ContentType == NcaContentType.Program)
{
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection())
{
patchNca = nca;
}
else
{
mainNca = nca;
}
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
return (mainNca, patchNca, controlNca);
}
bool IsUpdateApplied(string? titleId, out IFileSystem? updatedControlFs)
{
updatedControlFs = null;
string? updatePath = "(unknown)";
if (SwitchDevice?.VirtualFileSystem == null)
{
Logger.Error?.Print(LogClass.Application, "SwitchDevice was not initialized.");
return false;
}
try
{
(Nca? patchNca, Nca? controlNca) = GetGameUpdateData(SwitchDevice.VirtualFileSystem, titleId, 0, out updatePath);
if (patchNca != null && controlNca != null)
{
updatedControlFs = controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None);
return true;
}
}
catch (InvalidDataException)
{
Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {updatePath}");
}
catch (MissingKeyException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {updatePath}");
}
return false;
}
(Nca? patch, Nca? control) GetGameUpdateData(VirtualFileSystem fileSystem, string? titleId, int programIndex, out string? updatePath)
{
updatePath = null;
if (ulong.TryParse(titleId, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdBase))
{
// Clear the program index part.
titleIdBase &= ~0xFUL;
// Load update information if exists.
string titleUpdateMetadataPath = Path.Combine(AppDataManager.GamesDirPath, titleIdBase.ToString("x16"), "updates.json");
if (File.Exists(titleUpdateMetadataPath))
{
updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, _titleSerializerContext.TitleUpdateMetadata).Selected;
if (File.Exists(updatePath))
{
FileStream file = new(updatePath, FileMode.Open, FileAccess.Read);
PartitionFileSystem nsp = new();
nsp.Initialize(file.AsStorage()).ThrowIfFailure();
return GetGameUpdateDataFromPartition(fileSystem, nsp, titleIdBase.ToString("x16"), programIndex);
}
}
}
return (null, null);
}
(Nca? patchNca, Nca? controlNca) GetGameUpdateDataFromPartition(VirtualFileSystem fileSystem, PartitionFileSystem pfs, string titleId, int programIndex)
{
Nca? patchNca = null;
Nca? controlNca = null;
fileSystem.ImportTickets(pfs);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
{
using var ncaFile = new UniqueRef<IFile>();
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(fileSystem.KeySet, ncaFile.Release().AsStorage());
int ncaProgramIndex = (int)(nca.Header.TitleId & 0xF);
if (ncaProgramIndex != programIndex)
{
continue;
}
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != titleId)
{
break;
}
if (nca.Header.ContentType == NcaContentType.Program)
{
patchNca = nca;
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
return (patchNca, controlNca);
}
return gameInfo;
}
public static string GetDlcTitleId(string path, string ncaPath)
{
if (File.Exists(path))
{
using FileStream containerFile = File.OpenRead(path);
PartitionFileSystem partitionFileSystem = new();
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
using UniqueRef<IFile> ncaFile = new();
partitionFileSystem.OpenFile(ref ncaFile.Ref, ncaPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), ncaPath);
if (nca != null)
{
return nca.Header.TitleId.ToString("X16");
}
}
return string.Empty;
}
private static Nca TryOpenNca(IStorage ncaStorage, string containerPath)
{
try
{
return new Nca(SwitchDevice.VirtualFileSystem.KeySet, ncaStorage);
}
catch (Exception ex)
{
}
return null;
}
public static List<string> GetDlcContentList(string path, ulong titleId)
{
if (!File.Exists(path))
return new List<string>();
using FileStream containerFile = File.OpenRead(path);
PartitionFileSystem partitionFileSystem = new();
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
List<string> paths = new List<string>();
foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
{
using var ncaFile = new UniqueRef<IFile>();
partitionFileSystem.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), path);
if (nca == null)
{
continue;
}
if (nca.Header.ContentType == NcaContentType.PublicData)
{
if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != titleId)
{
break;
}
paths.Add(fileEntry.FullPath);
}
}
return paths;
}
public static void SetupUiHandler()
{
if (SwitchDevice is { } switchDevice)
{
switchDevice.HostUiHandler = new AndroidUiHandler();
}
}
public static void WaitUiHandler()
{
if (SwitchDevice?.HostUiHandler is AndroidUiHandler uiHandler)
{
uiHandler.Wait();
}
}
public static void StopUiHandlerWait()
{
if (SwitchDevice?.HostUiHandler is AndroidUiHandler uiHandler)
{
uiHandler.Set();
}
}
public static void SetUiHandlerResponse(bool isOkPressed, long input)
{
if (SwitchDevice?.HostUiHandler is AndroidUiHandler uiHandler)
{
uiHandler.SetResponse(isOkPressed, input);
}
}
}
public class SwitchDevice : IDisposable
{
private readonly SystemVersion _firmwareVersion;
public VirtualFileSystem VirtualFileSystem { get; set; }
public ContentManager ContentManager { get; set; }
public AccountManager AccountManager { get; set; }
public LibHacHorizonManager LibHacHorizonManager { get; set; }
public UserChannelPersistence UserChannelPersistence { get; set; }
public InputManager? InputManager { get; set; }
public Switch? EmulationContext { get; set; }
public IHostUiHandler? HostUiHandler { get; set; }
public void Dispose()
{
GC.SuppressFinalize(this);
VirtualFileSystem.Dispose();
InputManager?.Dispose();
EmulationContext?.Dispose();
}
public SwitchDevice()
{
VirtualFileSystem = VirtualFileSystem.CreateInstance();
LibHacHorizonManager = new LibHacHorizonManager();
LibHacHorizonManager.InitializeFsServer(VirtualFileSystem);
LibHacHorizonManager.InitializeArpServer();
LibHacHorizonManager.InitializeBcatServer();
LibHacHorizonManager.InitializeSystemClients();
ContentManager = new ContentManager(VirtualFileSystem);
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient);
UserChannelPersistence = new UserChannelPersistence();
_firmwareVersion = ContentManager.GetCurrentFirmwareVersion();
if (_firmwareVersion != null)
{
Logger.Notice.Print(LogClass.Application, $"System Firmware Version: {_firmwareVersion.VersionString}");
}
else
{
Logger.Notice.Print(LogClass.Application, $"System Firmware not installed");
}
}
public bool InitializeContext(bool isHostMapped,
bool useNce,
SystemLanguage systemLanguage,
RegionCode regionCode,
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
bool enableInternetAccess,
string? timeZone,
bool ignoreMissingServices)
{
if (LibRyujinx.Renderer == null)
{
return false;
}
var renderer = LibRyujinx.Renderer;
BackendThreading threadingMode = LibRyujinx.GraphicsConfiguration.BackendThreading;
bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
if (threadedGAL)
{
renderer = new ThreadedRenderer(renderer);
}
HLEConfiguration configuration = new HLEConfiguration(VirtualFileSystem,
LibHacHorizonManager,
ContentManager,
AccountManager,
UserChannelPersistence,
renderer,
LibRyujinx.AudioDriver, //Audio
MemoryConfiguration.MemoryConfiguration4GiB,
HostUiHandler,
systemLanguage,
regionCode,
enableVsync,
enableDockedMode,
enablePtc,
enableInternetAccess,
IntegrityCheckLevel.None,
0,
0,
timeZone,
isHostMapped ? MemoryManagerMode.HostMappedUnsafe : MemoryManagerMode.SoftwarePageTable,
ignoreMissingServices,
LibRyujinx.GraphicsConfiguration.AspectRatio,
100,
useNce,
"",
MultiplayerMode.Disabled);
EmulationContext = new Switch(configuration);
return true;
}
internal void ReloadFileSystem()
{
VirtualFileSystem.ReloadKeySet();
ContentManager = new ContentManager(VirtualFileSystem);
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient);
}
internal void DisposeContext()
{
EmulationContext?.Dispose();
EmulationContext?.DisposeGpu();
EmulationContext = null;
LibRyujinx.Renderer = null;
}
}
public class GameInfo
{
public double FileSize;
public string? TitleName;
public string? TitleId;
public string? Developer;
public string? Version;
public byte[]? Icon;
}
public unsafe struct GameInfoNative
{
public ulong FileSize;
public fixed byte TitleName[512];
public ulong TitleId;
public fixed byte Developer[256];
public uint Version;
public GameInfoNative(ulong fileSize, string titleName, ulong titleId, string developer, uint version)
{
FileSize = fileSize;
TitleId = titleId;
Version = version;
fixed (byte* developerPtr = Developer)
fixed (byte* titleNamePtr = TitleName)
{
CopyStringToFixedArray(titleName, titleNamePtr, 512);
CopyStringToFixedArray(developer, developerPtr, 256);
}
}
private void CopyStringToFixedArray(string source, byte* destination, int length)
{
var span = new Span<byte>(destination, length);
Encoding.UTF8.GetBytes(source, span);
}
}
public class GameStats
{
public double Fifo;
public double GameFps;
public double GameTime;
}
}

View File

@ -0,0 +1,81 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>linux-bionic-arm64;ios-arm64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
<LinkerFlavor Condition="'$(RuntimeIdentifier)'=='linux-bionic-arm64'">lld</LinkerFlavor>
<DefineConstants>$(DefineConstants);FORCE_EXTERNAL_BASE_DIR</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<PublishAot>true</PublishAot>
<PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
<!-- Not sure why, but on iOS this results in an error. Result is still a .dylib. -->
<NativeLib Condition="'$(RuntimeIdentifier)'=='linux-bionic-arm64'">Shared</NativeLib>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<InvariantGlobalization>true</InvariantGlobalization>
<IlcInstructionSet>armv8.2-a</IlcInstructionSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<Optimize>true</Optimize>
<OptimizationPreference>Speed</OptimizationPreference>
</PropertyGroup>
<!-- iOS Linking Fixes -->
<Target Condition="'$(RuntimeIdentifier)'=='ios-arm64'" Name="PrepareBeforeIlcCompile" BeforeTargets="IlcCompile">
<Exec Command="xcrun xcode-select -p" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="XcodeSelect" />
</Exec>
<PropertyGroup>
<XcodePath>$(XcodeSelect)</XcodePath>
<XcodePath>$([MSBuild]::EnsureTrailingSlash('$(XCodePath)'))</XcodePath>
</PropertyGroup>
<Message Importance="normal" Text="Found Xcode at $(XcodeSelect)" />
<ItemGroup>
<LinkerArg Include="-Wl,-ld_classic" />
<LinkerArg Include="-isysroot %22$(XcodePath)Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk%22"
Condition=" $(RuntimeIdentifier.Contains('simulator')) "/>
<LinkerArg Include="-isysroot %22$(XcodePath)Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk%22"
Condition=" !$(RuntimeIdentifier.Contains('simulator')) "/>
</ItemGroup>
</Target>
<Target Condition="'$(RuntimeIdentifier)'=='ios-arm64'" Name="FixDylib" AfterTargets="Publish">
<Exec Command="install_name_tool -id @rpath/$(TargetName).dylib $(NativeBinary)" ConsoleToMSBuild="true" />
</Target>
<Target Condition="'$(RuntimeIdentifier)'=='ios-arm64'" Name="FixSymbols" AfterTargets="Publish">
<RemoveDir Directories="$(PublishDir)$(TargetName).framework.dSYM"/>
<!-- create-xcframework (called from the export plugin wants the symbol files in a directory
with a slightly different name from the one created by dotnet publish, so we copy them over
to the correctly-named directory -->
<ItemGroup>
<SymbolFiles Include="$(NativeBinary).dsym\**\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(SymbolFiles)" DestinationFolder="$(PublishDir)$(TargetName).framework.dSYM"/>
</Target>
<!-- End iOS Linking Fixes -->
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Audio.Backends.OpenAL\Ryujinx.Audio.Backends.OpenAL.csproj" />
<ProjectReference Include="..\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj" />
<ProjectReference Include="..\Ryujinx.Input\Ryujinx.Input.csproj" />
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.HLE\Ryujinx.HLE.csproj" />
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
<ProjectReference Include="..\Ryujinx.Ui.Common\Ryujinx.Ui.Common.csproj" />
</ItemGroup>
<ItemGroup>
<RdXmlFile Include="rd.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Rxmxnx.PInvoke.Extensions" />
<PackageReference Include="Silk.NET.Vulkan" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" />
<LinkerArg Condition="'$(RuntimeIdentifier)'=='linux-bionic-arm64'" Include="-llog" />
</ItemGroup>
<ItemGroup>
<Folder Include="Jni\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,20 @@
using OpenTK;
using System;
namespace LibRyujinx.Shared
{
public class OpenTKBindingsContext : IBindingsContext
{
private readonly Func<string, IntPtr> _getProcAddress;
public OpenTKBindingsContext(Func<string, IntPtr> getProcAddress)
{
_getProcAddress = getProcAddress;
}
public IntPtr GetProcAddress(string procName)
{
return _getProcAddress(procName);
}
}
}

View File

@ -0,0 +1,99 @@
using Ryujinx.Common.Logging;
using Silk.NET.Core.Contexts;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace LibRyujinx
{
public class VulkanLoader : IDisposable
{
private delegate IntPtr GetInstanceProcAddress(IntPtr instance, IntPtr name);
private delegate IntPtr GetDeviceProcAddress(IntPtr device, IntPtr name);
private IntPtr _loadedLibrary = IntPtr.Zero;
private GetInstanceProcAddress _getInstanceProcAddr;
private GetDeviceProcAddress _getDeviceProcAddr;
public void Dispose()
{
if (_loadedLibrary != IntPtr.Zero)
{
NativeLibrary.Free(_loadedLibrary);
_loadedLibrary = IntPtr.Zero;
}
}
public VulkanLoader(IntPtr driver)
{
_loadedLibrary = driver;
if (_loadedLibrary != IntPtr.Zero)
{
var instanceGetProc = NativeLibrary.GetExport(_loadedLibrary, "vkGetInstanceProcAddr");
var deviceProc = NativeLibrary.GetExport(_loadedLibrary, "vkGetDeviceProcAddr");
_getInstanceProcAddr = Marshal.GetDelegateForFunctionPointer<GetInstanceProcAddress>(instanceGetProc);
_getDeviceProcAddr = Marshal.GetDelegateForFunctionPointer<GetDeviceProcAddress>(deviceProc);
}
}
public unsafe Vk GetApi()
{
if (_loadedLibrary == IntPtr.Zero)
{
return Vk.GetApi();
}
var ctx = new MultiNativeContext(new INativeContext[1]);
var ret = new Vk(ctx);
ctx.Contexts[0] = new LamdaNativeContext
(
x =>
{
var xPtr = Marshal.StringToHGlobalAnsi(x);
byte* xp = (byte*)xPtr;
LibRyujinx.debug_break(0);
try
{
nint ptr = default;
ptr = _getInstanceProcAddr(ret.CurrentInstance.GetValueOrDefault().Handle, xPtr);
if (ptr == default)
{
ptr = _getInstanceProcAddr(IntPtr.Zero, xPtr);
if (ptr == default)
{
var currentDevice = ret.CurrentDevice.GetValueOrDefault().Handle;
if (currentDevice != IntPtr.Zero)
{
ptr = _getDeviceProcAddr(currentDevice, xPtr);
}
if (ptr == default)
{
Logger.Warning?.Print(LogClass.Gpu, $"Failed to get function pointer: {x}");
}
}
}
return ptr;
}
finally
{
Marshal.FreeHGlobal(xPtr);
}
}
);
return ret;
}
}
}

610
src/LibRyujinx/rd.xml Normal file
View File

@ -0,0 +1,610 @@
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="Silk.NET.Vulkan.Extensions.EXT">
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtDebugUtils"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtExternalMemoryHost"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtConditionalRendering"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtExtendedDynamicState"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.EXT.ExtTransformFeedback"
Dynamic="Required All"/>
</Assembly>
<Assembly Name="Silk.NET.Vulkan.Extensions.KHR">
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrSurface"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrAndroidSurface"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrPushDescriptor"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrDrawIndirectCount"
Dynamic="Required All"/>
<Type Name="Silk.NET.Vulkan.Extensions.KHR.KhrSwapchain"
Dynamic="Required All"/>
</Assembly>
<Assembly Name="Ryujinx.HLE">
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.NvHostGpuDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IFileSystemProxyForLoader"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IInformationInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ngct.IService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IFactorySettingsServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Grc.IRemoteVideoTransfer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IProfileEditor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostDbgGpu.NvHostDbgGpuDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy.ILibraryAppletSelfAccessor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IProfile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IManagerForSystemService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.SslManagedSocketConnection"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.INetworkInstallManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager.Decoder"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.SessionServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Ethc.IEthInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.IAmManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Types.NvQueryEventNotImplementedException"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap.NvMapDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Idle.IPolicyManagerSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForSystemService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.ManagerServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bluetooth.IBluetoothUser"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.Irs.IIrSensorSystemServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.EphemeralNetworkSystemClockContextWriter"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.ProfilesJsonSerializerContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.IManagerPrivileged"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.MouseDevice"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Bpc.IRtcManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bgct.IStateControlService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IStaticServiceForPsc"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fatal.IService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.ConsumerBase"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ISteadyClock"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IStorage"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.HidServer.IAppletResource"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.StaticService.IGeneralService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IServiceGetterInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IMultiCommitManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IAudioController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IHardwareOpusDecoderManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.AmiiboJsonSerializerContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager.MultiSampleDecoder"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardLocalSystemClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.IWriter"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.NfcManager.INfc"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fgm.IDebugger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Eupld.IRequest"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.TickBasedSteadyClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferItem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.IDaemonSuspendSessionService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Erpt.IContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.IShopServiceAccessor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IFileSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.ISystemDisplayService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenshotService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IGlobalStateController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.IFirmwareDebugSettingsServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioRendererManagerForApplet"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.IReader"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardNetworkSystemClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager.IHardwareOpusDecoder"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Olsc.IOlscServiceForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IApplicationManagerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IProgramRegistry"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.Lp2p.IServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidDebugServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.IAmManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pdm.INotifyService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IPowerStateRequestHandler"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IDeviceOperator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioOutManagerForApplet"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.ISystemAppletProxy"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRendererManagerServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumAccessorService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pl.ISharedFontManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Cec.ICecManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.IUserManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.ServiceAttribute"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.News.IServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.Irs.IIrSensorServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pctl.IParentalControlServiceFactory"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bgct.ITaskService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Omm.IOperationModeManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.KeyboardDevice"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fatal.IPrivateService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmDebug"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRenderer.AudioDeviceServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletProxy.IProcessWindingController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IDirectory"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.ShopServiceAccessServer.ShopServiceAccessor.IShopServiceAsync"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.TouchDevice"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.NetworkSystemClockContextWriter"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.StaticService.IRequest"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.ISystemSettingsServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ISelfController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ICommonStateGetter"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.Ntc.StaticService.IEnsureNetworkClockAvailabilityService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IWindowController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.DebugPadDevice"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioOut.AudioOut"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager.ILocationResolver"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.IStaticService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidbusServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.IClkrstManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IDevelopInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.StaticService.DatabaseServiceImpl"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.IHidSystemServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForAdministrator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IWriterForSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.NpadDevices"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.IManagerRootService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvDrvServices"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.AccountService.IManagerForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.HidServer.IActiveApplicationDeviceList"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IDebugFunctions"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IAvmService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtmUser"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcie.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioIn.AudioIn"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IStorageAccessor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator.ILibraryAppletAccessor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAccountServiceForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioRendererManagerForDebugger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenShotApplicationService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IBaasAccessTokenAccessor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioSnoopManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.IUserManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceAccessSystemInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.IApplicationProxy"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.IBtm"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fgm.ISession"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Host1xContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.LibHacIReader"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Arp.LibHacArpServiceObject"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IAlarmService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ngct.IServiceWithManagementApi"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Npns.INpnsSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Ts.IMeasurementServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostProfGpu.NvHostProfGpuDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.INotificationService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AppletFifo`1"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Bpc.IBoardPowerControlManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.IUserServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Spl.IRandomInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sdb.Pdm.IQueryService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Pcm.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioInManagerForApplet"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.HOSBinderDriverServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.IContentManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.ISystemRootService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Fan.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.IApplicationFunctions"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioInManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.INfp"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IVulnerabilityManagerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumApplicationService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Tcap.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Friend.ServiceCreator.IFriendService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferQueueProducer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.EphemeralNetworkSystemClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.ServerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.ShopServiceAccessServerInterface.IShopServiceAccessServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IPurchaseEventManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ro.IRoInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mig.IService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.Ntc.IStaticService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ITimeZoneServiceForPsc"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.Types.NvIoctlNotImplementedException"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioOutManagerForDebugger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.ISystemServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.ServerBase"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Nsd.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.LocalSystemClockContextWriter"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcie.ILogManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Dauth.IService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvGemControl"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Spl.IGeneralInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.IArbitrationManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.EventFileDescriptorPollManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Ethc.IEthInterfaceGroup"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Settings.ISettingsServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvDrvDebugFSServices"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.ISystemUpdateInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.ISystemManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.IPcvService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRenderer.AudioRendererServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.IApplicationProxyService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IFinalOutputRecorderManagerForApplet"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IShellInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.ISslConnection"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.BufferItemConsumer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrl.NvHostCtrlDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory.IParentalControlService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.IAllSystemAppletProxiesService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.IReadOnlyApplicationControlDataInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Erpt.ISession"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Friend.IServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Psm.IPsmServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nim.IShopServiceAccessServerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IScreenShotControlService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardSteadyClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IAudioInManagerForDebugger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Hid.ISystemServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Mifare.IUserManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Clkrst.ClkrstManager.IClkrstSession"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ISystemClock"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IDebugMonitorInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.IMonitorServiceCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Grc.IGrcService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IDisplayController"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.IClient"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IApplicationCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IAddOnContentManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.ITimeServiceManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Bluetooth.IBluetoothDriver"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ns.Aoc.IContentsServiceManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.ILibraryAppletCreator"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IFinalOutputRecorderManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel.NvHostChannelDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy.IStorage"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sm.IUserInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostCtrlGpu.NvHostCtrlGpuDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.CommandTipcAttribute"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Eupld.IControl"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioIn.AudioInServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.IApplicationDisplayService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IDebugMonitorInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioOutManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nfc.Nfp.ISystemManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAsyncNetworkServiceLicenseKindContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IWriterForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ncm.Lr.ILocationResolverManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.StaticService.ITimeZoneServiceForGlue"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Notification.INotificationServicesForSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.Spsm.IPowerStateInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.DummyService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IHomeMenuFunctions"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.NvHostAsGpuDeviceFile"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Apm.SystemManagerServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioOutManagerServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.IFinalOutputRecorderManagerForDebugger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sm.IManagerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.SurfaceFlinger.SurfaceFlinger"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.IResolver"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRenderer.AudioKernelEvent"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Psm.IPsmSession"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Account.Acc.IAsyncContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.IAppletCommonFunctions"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.ManagedSocket"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IBootModeInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Npns.INpnsUser"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Olsc.IOlscServiceForSystemService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRenderer.AudioRenderer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService.IManagerDisplayService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ptm.Tc.IManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ectx.IReaderForSystem"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Loader.IProcessManagerInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Notification.INotificationServicesForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pm.IShellInterface"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.ILibraryAppletProxy"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioInManagerServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.ISslService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mii.IImageDatabaseService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.Clock.StandardUserSystemClockCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Vi.IApplicationRootService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioOut.AudioOutServer"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.BluetoothManager.BtmUser.IBtmUserCore"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.ISaveDataInfoReader"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ssl.SslService.ISslContext"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nv.INvGemCoreDump"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.EventFileDescriptor"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Mnpp.IServiceForApplication"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Fs.IFileSystemProxy"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Caps.IAlbumControlService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.IUserLocalCommunicationService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Nifm.IStaticService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl.ManagedSocketPollManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Audio.AudioRenderer.AudioDevice"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Time.IStaticServiceForGlue"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.CommandCmifAttribute"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Rtc.IRtcManager"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Es.IETicketService"
Dynamic="Required All" />
<Type Name="Ryujinx.HLE.HOS.Services.Pcv.Rgltr.IRegulatorManager"
Dynamic="Required All" />
</Assembly>
</Application>
</Directives>

View File

@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One);
private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One);
private static readonly int[] _defaultSurroundToStereoCoefficients = new int[4]
private static readonly long[] _defaultSurroundToStereoCoefficients = new long[4]
{
RawQ15One,
Minus3dBInQ15,
@ -39,7 +39,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
Minus3dBInQ15,
};
private static readonly int[] _defaultStereoToMonoCoefficients = new int[2]
private static readonly long[] _defaultStereoToMonoCoefficients = new long[2]
{
Minus6dBInQ15,
Minus6dBInQ15,
@ -62,19 +62,23 @@ namespace Ryujinx.Audio.Backends.CompatLayer
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short DownMixStereoToMono(ReadOnlySpan<int> coefficients, short left, short right)
private static short DownMixStereoToMono(ReadOnlySpan<long> coefficients, short left, short right)
{
return (short)((left * coefficients[0] + right * coefficients[1]) >> Q15Bits);
return (short)Math.Clamp((left * coefficients[0] + right * coefficients[1]) >> Q15Bits, short.MinValue, short.MaxValue);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short DownMixSurroundToStereo(ReadOnlySpan<int> coefficients, short back, short lfe, short center, short front)
private static short DownMixSurroundToStereo(ReadOnlySpan<long> coefficients, short back, short lfe, short center, short front)
{
return (short)((coefficients[3] * back + coefficients[2] * lfe + coefficients[1] * center + coefficients[0] * front + RawQ15HalfOne) >> Q15Bits);
return (short)Math.Clamp(
(coefficients[3] * back +
coefficients[2] * lfe +
coefficients[1] * center +
coefficients[0] * front + RawQ15HalfOne) >> Q15Bits, short.MinValue, short.MaxValue);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short[] DownMixSurroundToStereo(ReadOnlySpan<int> coefficients, ReadOnlySpan<short> data)
private static short[] DownMixSurroundToStereo(ReadOnlySpan<long> coefficients, ReadOnlySpan<short> data)
{
int samplePerChannelCount = data.Length / SurroundChannelCount;
@ -94,7 +98,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static short[] DownMixStereoToMono(ReadOnlySpan<int> coefficients, ReadOnlySpan<short> data)
private static short[] DownMixStereoToMono(ReadOnlySpan<long> coefficients, ReadOnlySpan<short> data)
{
int samplePerChannelCount = data.Length / StereoChannelCount;

View File

@ -1,4 +1,3 @@
using ARMeilleure.Translation;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
@ -916,7 +915,6 @@ namespace Ryujinx.Ava
{
Device.Gpu.SetGpuThread();
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
Translator.IsReadyForTranslation.Set();
_renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.9.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 355.6" style="enable-background:new 0 0 1000 355.6;" xml:space="preserve">
<style type="text/css">
.st0{fill:#00BBDB;stroke:#000000;}
.st1{fill:#333333;stroke:#000000;stroke-width:0.93;}
.st2{fill:#333333;stroke:#000000;stroke-width:0.96;}
.st3{fill:#333333;stroke:#000000;stroke-width:0.85;}
.st4{fill:#1A1A1A;stroke:#000000;}
.st5{fill:#333333;stroke:#000000;}
.st6{fill:#1A1A1A;stroke:#1A1A1A;}
.st7{fill:#1A1A1A;stroke:#4D4D4D;}
.st8{stroke:#4D4D4D;}
.st9{stroke:#000000;}
</style>
<g id="g344">
<path id="path66-7" d="M906.6,6.5v7.9c0,3.6-2.9,6.4-6.5,6.5H71.2c-3.6,0-6.4-2.9-6.5-6.5V6.5c0-3.6,2.9-6.4,6.5-6.5L207,0
c4.9,0,9.6,1.2,14,3.4l13,6.7h79.2l13-6.7c4.3-2.2,9.1-3.4,13.9-3.4l269.7,0c4.9,0,9.6,1.2,14,3.4l13,6.7H716l13-6.7
c4.3-2.2,9.1-3.4,13.9-3.4l157.2,0C903.7,0,906.6,2.9,906.6,6.5L906.6,6.5L906.6,6.5z M65.7,14.4c0,3,2.4,5.5,5.5,5.5h828.9
c3,0,5.5-2.4,5.5-5.5V6.5c0-3-2.4-5.5-5.5-5.5H742.9c-4.7,0-9.3,1.1-13.5,3.3l-13.1,6.8c-0.1,0-0.2,0.1-0.2,0.1h-79.5
c-0.1,0-0.2,0-0.2-0.1l-13.1-6.8c-4.2-2.2-8.8-3.3-13.5-3.3H340.1c-4.7,0-9.3,1.1-13.5,3.3l-13.1,6.8c-0.1,0-0.2,0.1-0.2,0.1h-79.5
c-0.1,0-0.2,0-0.2-0.1l-13.1-6.8C216.3,2.1,211.7,1,207,1L71.2,1c-3,0-5.5,2.4-5.5,5.5L65.7,14.4L65.7,14.4z"/>
<path id="path68-5" d="M858.9,20.3v11.2c0,0.3-0.2,0.5-0.5,0.5H72c-0.3,0-0.5-0.2-0.5-0.5V20.3c0-0.3,0.2-0.5,0.5-0.5h786.4
C858.7,19.8,858.9,20,858.9,20.3z M857.9,31V20.8H72.5V31H857.9z"/>
<path id="path70-3" d="M1000,37.5v106.2c0,117-94.8,211.9-211.9,211.9l0,0H220.9c-116.8,0-211.8-95.1-211.8-211.9V37.5
c0-3.6,2.9-6.5,6.5-6.5h978C997.1,31,1000,33.9,1000,37.5L1000,37.5L1000,37.5z M10.1,143.7c0,116.3,94.6,210.9,210.8,210.9h567.2
C904.4,354.6,999,260,999,143.7V37.5c0-3-2.4-5.5-5.5-5.5h-978c-3,0-5.5,2.4-5.5,5.5v106.2L10.1,143.7L10.1,143.7z"/>
<path id="path98" d="M717.1,6.5v4.2c0,0.6-0.4,1-1,1l0,0h-79.5c-0.6,0-1-0.4-1-1V6.5c0-3.8,3.1-6.9,7-7h67.6
C714-0.5,717.1,2.6,717.1,6.5z M715.1,9.7V6.5c0-2.7-2.2-5-5-5h-67.6c-2.7,0-5,2.2-5,5v3.2H715.1z"/>
<path id="path100" d="M314.3,6.5v4.2c0,0.6-0.4,1-1,1h-79.5c-0.6,0-1-0.4-1-1V6.5c0-3.8,3.1-6.9,7-7h67.6
C311.2-0.5,314.3,2.6,314.3,6.5z M312.3,9.7V6.5c0-2.7-2.2-5-5-5h-67.6c-2.7,0-5,2.2-5,5v3.2H312.3z"/>
<path id="path1144" class="st0" d="M997.9,162.4c-3,26.2-8.5,49.9-21,75.1c-10.9,21.9-25.7,41.1-42.5,57.5
c-33.2,32.3-77.8,53.7-126.7,59c-3.4,0.4-30.5,0.1-72.2,0.3c-158.5,1.1-520.6,0.9-534.4-0.5c-17.7-1.8-36.5-6.1-52.4-12
c-7.5-2.8-15.8-7.1-23.1-10.7C61.8,299.6,21.2,238.8,12,168.6C9.6,150.4,8.7,35.5,11,33.1c0.1-0.1,2.3-0.9,7-1
c11.1-0.4,36-0.4,79.4-1.3c32.7-0.7,76.3,0,132.5-0.1c70.3-0.2,160.2,1.6,274.8,1.6c484.5,0,491.2-1.4,492.4,0.9
c0.2,0.3,1.7,2.5,1.8,5.3c1.1,21.9-0.5,119.2-0.7,120.6L997.9,162.4L997.9,162.4z"/>
<polygon id="polygon80" class="st1" points="470.2,195 470.2,168.3 448.1,181.7 "/>
<polygon id="polygon82" class="st2" points="627.3,181.3 605.6,194.1 605.6,168.5 "/>
<polygon id="polygon84" class="st1" points="538.1,271.6 551.5,249.7 524.7,249.7 "/>
<polygon id="polygon86" class="st3" points="551.6,114.8 524.1,114.8 537.9,89.2 "/>
<path id="path102" d="M139.3,338.3c0,0.3-0.1,0.5-0.3,0.7l-3.4,3.4c-2,2-5.1,2.6-7.8,1.5C50.1,309.1,0.1,231.9,0,146.7l0-51.2
c0-3.8,3.1-6.9,7-7h2.6c0.6,0,1,0.4,1,1v54.2C10.5,228.2,61,304.5,138.7,337.4c0.3,0.1,0.5,0.4,0.6,0.7L139.3,338.3L139.3,338.3z
M2,146.7c0.1,84.4,49.7,160.9,126.7,195.4c1.9,0.8,4.1,0.4,5.5-1.1l2.4-2.4C58.8,305,8.5,228.3,8.6,143.6V90.4H7c-2.7,0-5,2.2-5,5
L2,146.7L2,146.7z"/>
<path id="path104" d="M116.1,60v46.9c0,2.2-1.8,4-4,4h-11.7c-2.2,0-4-1.8-4-4V60c0-2.2,1.8-4,4-4h11.7
C114.3,56,116.1,57.8,116.1,60z M98.5,106.9c0,1.1,0.9,2,2,2h11.7c1.1,0,2-0.9,2-2V60c0-1.1-0.9-2-2-2h-11.7c-1.1,0-2,0.9-2,2
V106.9z"/>
<path id="path106" d="M502.9,181.7c0,21.2-17.2,38.5-38.5,38.5s-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5S502.9,160.4,502.9,181.7
L502.9,181.7z M428,181.7c0,20.1,16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5s-16.3-36.5-36.5-36.5S428,161.5,428,181.7L428,181.7z"/>
<path id="path108" d="M649.8,181.7c0,21.2-17.2,38.5-38.5,38.5s-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5S649.8,160.4,649.8,181.7
L649.8,181.7z M574.9,181.7c0,20.1,16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5s-16.3-36.5-36.5-36.5l0,0
C591.2,145.2,574.9,161.5,574.9,181.7L574.9,181.7z"/>
<path id="path110" d="M576.3,108.2c0,21.2-17.2,38.5-38.5,38.5s-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5l0,0
C559.1,69.8,576.3,87,576.3,108.2z M501.4,108.2c0,20.1,16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5s-16.3-36.5-36.5-36.5l0,0
C517.7,71.8,501.4,88.1,501.4,108.2L501.4,108.2L501.4,108.2z"/>
<path id="path112" d="M576.3,255.1c0,21.2-17.2,38.5-38.5,38.5s-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5l0,0
C559.1,216.7,576.3,233.9,576.3,255.1z M501.4,255.1c0,20.1,16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5s-16.3-36.5-36.5-36.5l0,0
C517.7,218.7,501.4,235,501.4,255.1L501.4,255.1L501.4,255.1z"/>
<path id="path114" d="M753.7,105.5v45c0,5.5-4.4,9.9-9.9,9.9h-45c-5.5,0-9.9-4.4-9.9-9.9v-45c0-5.5,4.4-9.9,9.9-9.9h45
C749.3,95.6,753.7,100.1,753.7,105.5z M690.9,150.5c0,4.4,3.6,7.9,7.9,7.9h45c4.4,0,7.9-3.6,7.9-7.9v-45c0-4.4-3.6-7.9-7.9-7.9h-45
c-4.4,0-7.9,3.6-7.9,7.9V150.5z"/>
<path id="path116" d="M741.7,128c0,11.3-9.2,20.4-20.4,20.4s-20.4-9.2-20.4-20.4s9.2-20.4,20.4-20.4l0,0
C732.6,107.6,741.7,116.7,741.7,128z M702.8,128c0,10.2,8.3,18.4,18.4,18.4s18.4-8.3,18.4-18.4s-8.3-18.4-18.4-18.4
S702.9,117.8,702.8,128z"/>
<path id="path118" d="M260.2,244.8v12.3c0,0.6-0.4,1-1,1l0,0c-39.6-1.7-71.3-33.4-73-73c0-0.3,0.1-0.5,0.3-0.7s0.4-0.3,0.7-0.3
h12.3c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9C257.6,238.4,260.2,241.3,260.2,244.8L260.2,244.8z M258.2,256v-11.2
c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-11.2C190.3,223.4,220.8,253.9,258.2,256L258.2,256z
"/>
<path id="path120" d="M338.9,185L338.9,185c-1.7,39.6-33.4,71.3-73,73c-0.6,0-1-0.4-1-1v-12.3c0-3.5,2.6-6.4,6-6.9
c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6H338C338.5,184,338.9,184.5,338.9,185L338.9,185z M266.9,256
c37.4-2.2,67.8-32.6,70-70h-11.2c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9V256L266.9,256z"/>
<path id="path122" d="M338.9,178.3c0,0.6-0.4,1-1,1h-12.3c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9
c-3.4-0.5-6-3.4-6-6.9v-12.3c0-0.6,0.4-1,1-1l0,0C305.5,107,337.2,138.7,338.9,178.3L338.9,178.3L338.9,178.3z M266.9,118.6
c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h11.2c-2.2-37.4-32.6-67.8-70-70V118.6z"/>
<path id="path124" d="M260.2,106.3v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-12.3
c-0.3,0-0.5-0.1-0.7-0.3s-0.3-0.5-0.3-0.7c1.7-39.6,33.4-71.3,73-73C259.7,105.3,260.2,105.7,260.2,106.3L260.2,106.3L260.2,106.3z
M188.2,177.3h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2
C220.8,109.5,190.3,140,188.2,177.3L188.2,177.3L188.2,177.3z"/>
<path id="path126" d="M339,181.7c0,1.2,0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9h-12.3c-2.5,0-4.6,1.8-4.9,4.3
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1c-1.1,0.1-2.2,0.1-3.4,0.1s-2.3,0-3.4-0.1
c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3
c-0.5,0-1-0.4-1-0.9c-0.1-2.3-0.1-4.5,0-6.8c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6
c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1c1.1-0.1,2.2-0.1,3.4-0.1s2.3,0,3.4,0.1c0.5,0,0.9,0.5,0.9,1v12.3
c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3c0.5,0,1,0.4,1,0.9C339,179.4,339,180.5,339,181.7
L339,181.7z M337,184c0.1-1.5,0.1-3.1,0-4.7h-11.3c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3
h-4.6v11.4c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3c-0.1,1.5-0.1,3.1,0,4.7h11.3
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v11.3h4.6v-11.3c0-3.5,2.6-6.4,6-6.9
c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6L337,184L337,184z"/>
<path id="path179" class="st4" d="M574.3,261.6c-3.2,14.7-12.7,24.9-27.1,29c-3.4,1-6.3,1.2-11.7,0.9c-6.5-0.3-7.8-0.7-13.5-3.5
c-22.9-11.4-27.9-40.7-10-58.6c19.4-19.4,51.9-12,60.8,13.9C574.5,248.5,575.3,257.1,574.3,261.6L574.3,261.6L574.3,261.6z
M538,249c-7.3,0-13.4,0.2-13.4,0.4c0,0.9,13.2,23.3,13.5,23c0.7-0.7,13.1-22.2,13.2-22.8C551.3,249.2,545.4,249,538,249L538,249
L538,249z"/>
<path id="path181" class="st4" d="M500.6,187.1c-0.9,6.9-5,15-10.4,20.5c-14.5,14.6-36.9,14.6-51.4-0.1c-22.9-23-7-62.3,25.4-62.3
c10.4,0,18.8,3.5,26,10.7C498.4,164.3,502.1,175.2,500.6,187.1L500.6,187.1L500.6,187.1z M469.9,168.5
c-2.4,0.9-22.4,12.8-22.4,13.3c0,0.4,9,5.9,19.9,12l3.6,2v-13.9C471,169.7,470.9,168.1,469.9,168.5L469.9,168.5L469.9,168.5z"/>
<path id="path185" class="st4" d="M647,190.4c-3.5,12.9-13.7,23.1-26.6,26.5c-22.7,5.9-45.2-11.6-45.3-35.2
c0-7.4,0.9-11.3,4.5-18.1c8.8-16.9,30.4-23.9,47.9-15.4C643,155.8,651.4,173.9,647,190.4L647,190.4L647,190.4z M616.9,174.2
c-6.3-3.6-11.6-6.5-11.8-6.3s-0.3,6.4-0.1,13.8l0.2,13.5l11.6-6.7c6.4-3.7,11.6-6.9,11.6-7.2C628.4,181.1,623.2,177.8,616.9,174.2
L616.9,174.2z"/>
<path id="path187" class="st4" d="M574.2,111.7c0,0.3-0.3,1.6-0.5,2.9c-2.2,11.2-9.7,20.9-20.1,26.2c-5.6,2.8-12.2,4.2-17.9,3.8
c-14.8-1.1-27.7-11.3-32.5-25.6c-2.9-8.8-2.2-18,2.2-26.7s12.1-15.5,21.3-18.6c15.3-5.3,32.2,0.7,41.6,14.7c4,6,6.3,13.4,6.2,20.2
C574.3,109.9,574.3,111.4,574.2,111.7L574.2,111.7L574.2,111.7z M551.1,112.4c-0.4-0.7-1.6-3-2.8-5.1c-4.8-8.7-9.2-15.6-10-16.2
c-0.4-0.3-0.5-0.3-0.9,0c-1.3,0.9-13.5,21.5-13.5,22.9c0,0.3,0.1,0.6,0.2,0.7c0.5,0.4,4.8,0.6,13.9,0.6c9.1,0,13-0.2,13.5-0.6
C551.9,114.3,551.8,113.8,551.1,112.4L551.1,112.4L551.1,112.4z"/>
<path id="path189" class="st5" d="M739.1,131.6c-0.2,1-1,3-1.6,4.4c-1,2.1-1.6,2.9-3.5,4.8c-1.9,1.9-2.7,2.5-4.8,3.5
c-5.5,2.7-10.6,2.7-16.1,0c-2.1-1-2.8-1.6-4.8-3.5c-3.6-3.6-5.3-7.7-5.3-12.7c0-8.4,5.7-15.7,13.9-17.8c2-0.5,6.2-0.5,8.3,0
c6.3,1.5,11.5,6.3,13.4,12.7C739.4,125.4,739.6,129.2,739.1,131.6L739.1,131.6L739.1,131.6z"/>
<path id="path191" class="st4" d="M751.3,152.4c-0.4,1.6-1.3,3-2.6,4.1c-2.1,1.8-0.9,1.7-27.4,1.7s-25.3,0.1-27.5-1.9
c-0.7-0.6-1.5-1.7-1.9-2.5l-0.7-1.5v-48.3l0.9-1.8c0.6-1.3,1.2-2,2.1-2.7c2.3-1.8,1.3-1.7,27.8-1.6c23.8,0.1,23.9,0.1,25.1,0.6
c1.6,0.7,3.1,2.3,3.9,3.9l0.7,1.3l0,23.8C751.6,145.6,751.5,151.4,751.3,152.4L751.3,152.4L751.3,152.4z M741.6,125.1
c-1.5-10.6-10.7-18.1-21.4-17.5c-3.4,0.2-5.3,0.7-8.1,2c-9.3,4.6-13.7,15.5-10.2,25.3c1,2.8,2.2,4.7,4.3,7c2.8,3,6.3,5.1,10.3,6
c2.2,0.5,7.2,0.5,9.4,0c3.9-0.9,7.4-3,10.2-6c2.1-2.2,3.3-4.2,4.3-6.7C741.7,131.9,742.1,128.5,741.6,125.1L741.6,125.1
L741.6,125.1z"/>
<path id="path1082" class="st6" d="M330.4,183.8c-6,0-6.5,0.1-7.9,0.7c-2.1,1.1-3.4,2.9-3.9,5.6c-2.7,15.1-10.1,27.5-21.9,36.5
c-6.5,5-15.1,8.8-23.2,10.4c-4.3,0.8-5.7,1.4-7,3c-1.5,1.8-1.8,3.3-1.8,10v5.9h-4.2v-6.3c0-6.1,0-6.3-0.9-8
c-1.2-2.4-2.7-3.3-7.3-4.2c-23.2-4.6-41-22.4-45.4-45.6c-0.8-4.2-1.6-5.6-3.8-6.9c-1.5-0.9-1.6-0.9-8.1-1l-6.6-0.1v-4.2h6.3
c6.2,0,6.3,0,8-0.9c2.6-1.3,3.4-2.6,4.4-7.6c3.8-19.4,17-35.1,35.4-42.3c2.7-1,5.9-1.9,12-3.3c2.6-0.6,4.2-1.7,5.2-3.6
c0.6-1.1,0.7-2,0.8-7.9l0.1-6.6h4.2v6.3c0,6.1,0,6.3,0.9,8c1.1,2.2,2.9,3.4,5.9,3.9c23.8,4.1,42.3,22.2,46.8,46
c0.8,4.2,1.7,5.7,4.1,7c1.5,0.8,1.9,0.8,8,0.9l6.4,0.1v4.2L330.4,183.8L330.4,183.8z"/>
<path id="path1084" class="st7" d="M257.3,255.8c-0.5-0.1-1.9-0.3-3.2-0.4c-3.9-0.4-10.1-1.7-14.8-3.3c-24.1-8-42.7-28.1-48.9-52.7
c-0.8-3.1-1.6-7.6-1.9-11.3l-0.2-2h5.9c8.5,0,9.1,0.4,10.4,6.5c3.7,18.4,15.2,33.7,31.9,41.9c5.1,2.6,10.1,4.1,17,5.5
c2.4,0.5,4,1.8,4.4,3.7c0.2,0.7,0.3,3.8,0.3,6.8v5.5L257.3,255.8L257.3,255.8z"/>
<path id="path1086" class="st7" d="M336.4,189.8c-3,27-21.4,50.8-46.9,60.9c-6,2.4-13.4,4.2-18.7,4.7c-1.3,0.1-2.7,0.3-3.1,0.4
l-0.8,0.2l0.1-6.3c0.1-5.8,0.2-6.4,0.8-7.2c1.2-1.6,2.2-2,6.2-2.9c5.8-1.2,9.4-2.4,14.8-5.2c5.7-2.9,9.8-5.7,14.2-9.9
c9.1-8.6,15.2-19.7,17.5-31.7c0.7-3.6,1.2-4.6,2.7-5.8c0.8-0.6,1.4-0.7,7.2-0.8c5.9-0.1,6.3-0.1,6.3,0.5
C336.7,187,336.6,188.4,336.4,189.8L336.4,189.8L336.4,189.8z"/>
<path id="path1088" class="st7" d="M257.7,119.9c-0.9,2.4-1.6,2.8-6.5,3.8c-18.2,3.7-33.5,15.4-41.6,32c-2.4,4.8-3.7,8.6-4.7,13.5
c-1,4.7-1.6,6.2-2.9,7.1c-1.1,0.7-1.4,0.7-7.4,0.7c-3.5,0-6.3-0.1-6.3-0.3s0.2-1.9,0.5-4c1.5-12,5.6-22.9,12.4-32.8
c3-4.4,5.6-7.4,9.9-11.6c9.6-9.3,20.7-15.5,33.5-18.8c3.6-0.9,10.9-2.1,12.9-2.1c0.6,0,0.6,0.3,0.6,5.6
C258.1,116.9,258,119.1,257.7,119.9L257.7,119.9L257.7,119.9z"/>
<path id="path1090" class="st7" d="M330.5,177.3c-5.8-0.1-6.4-0.2-7.2-0.8c-1.6-1.2-2-2.2-2.9-6.3c-4.7-23.5-23.3-41.9-47-46.4
c-3.5-0.7-4.5-1.1-5.6-2.7c-0.6-0.8-0.7-1.4-0.8-7.2l-0.1-6.3l1.7,0.2c10.5,1.2,18,3.3,26.4,7.5c22.6,11.2,38.1,32.9,41.3,58
c0.3,2.1,0.5,3.9,0.5,4S333.9,177.3,330.5,177.3L330.5,177.3L330.5,177.3z"/>
<path id="path1092" class="st4" d="M113.5,108c-0.6,0.5-1.8,0.7-7.2,0.7c-4.5,0-6.7-0.2-7-0.5c-0.4-0.4-0.5-6.4-0.5-24.6
c0-21.3,0.1-24.2,0.7-24.8c0.6-0.5,1.8-0.7,7-0.7c6.1,0,6.4,0,7,1c0.6,0.8,0.7,3.9,0.7,24.6S114,107.4,113.5,108z"/>
<path id="path1094" class="st8" d="M134.2,340.6c-2.8,2.4-3.7,2.2-12.6-2.3c-21.7-10.8-39.6-23.6-56.5-40.5
c-31.4-31.4-52.2-71.6-59.8-115.3c-2.6-15.1-2.7-16.5-2.9-54L2.3,93.7l1.2-1.4c0.9-1,1.7-1.4,3-1.6l1.8-0.2l0.2,33.8
c0.2,36.2,0.3,38.8,2.7,53.3c6.2,38.4,22,72.9,47.3,103.3c5.7,6.8,18.3,19.5,25.2,25.2c10,8.4,21.7,16.5,32.4,22.5
c5.4,3.1,18.7,9.6,19.5,9.6C136.4,338.3,136,339.1,134.2,340.6L134.2,340.6L134.2,340.6z"/>
<path id="path1150" class="st9" d="M616,21.1c-216,0-634,0-526-0.1c108-0.1,614.3-0.3,722.4-0.1c29.2,0,43.2,0.1,45,0.1
C862.4,21.1,773.6,21.1,616,21.1L616,21.1L616,21.1z"/>
<path id="path1152" class="st4" d="M903.2,19c-2.1,1.5-44.2,0.8-417.6,0.8S70.3,20.6,68.2,19.1c-2-1.4-2.2-3.4-2.2-8.5
c0-1.8-0.1-3.8,0.2-5.4c0.3-1.4,2-3.2,2.4-3.5c0.5-0.5,4.3-0.3,16.4-0.4c11.3-0.1,29,0.2,55.3,0.2c44.7,0,61.8-0.6,69.8-0.1
c4.4,0.3,6.1,1.2,8.1,1.9c3.1,1.2,8.2,3.9,10.9,5.6l5,3.2l40.4-0.4c37.6-0.4,39,0.2,41.7-1.6c1.5-1.1,6.1-3,9.3-4.6l5.8-3l7.9-1.3
l19.8,0.1l15.8,0.1l97.9,0.2c93.1,0.2,126.7-1.2,141.1,0.3c4.2,0.4,6.5,1.6,8.5,2.3c2.7,0.9,4.9,2.1,7.8,3.9l6.1,3.7l15.6-0.4
l25.1-0.1c26.5-0.1,40.4-0.6,40.9-1.3c0.4-0.6,4-2.7,8.5-4.3l9-3.3l9-1.1l15.9,0.2l57.9,0.2c61.9,0.2,84.5-0.4,85.5,0.5
c0.9,0.8,2.4,4.5,2.4,8.4C905.8,15.4,905.1,17.6,903.2,19L903.2,19L903.2,19z"/>
<path id="path1154" class="st4" d="M464.9,30.8l-5.2,0l-387-0.4v-8.5h392.2l393-1.1l0.2,5.3l-0.2,4.9L464.9,30.8L464.9,30.8z"/>
<path id="path1156" class="st0" d="M273.3,9.7h-38.6v-3c0-1.7,0.9-3.6,2.1-4.3c2.8-1.7,70.3-1.7,73.1,0c1.2,0.7,2.1,2.6,2.1,4.3v3
H273.3L273.3,9.7z"/>
<path id="path1158" class="st0" d="M676.2,9.7h-38.7v-3c0-1.8,0.9-3.6,2.1-4.3c2.8-1.7,70.3-1.7,73.2,0c1.2,0.7,2.1,2.6,2.1,4.3v3
H676.2L676.2,9.7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,341 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.9.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 1000.2" style="enable-background:new 0 0 1000 1000.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#00BBDB;stroke:#000000;}
.st1{fill:#333333;stroke:#000000;stroke-width:0.93;}
.st2{fill:#333333;stroke:#000000;stroke-width:0.96;}
.st3{fill:#333333;stroke:#000000;stroke-width:0.85;}
.st4{fill:#1A1A1A;stroke:#000000;}
.st5{fill:#333333;stroke:#000000;}
.st6{fill:#1A1A1A;stroke:#1A1A1A;}
.st7{fill:#1A1A1A;stroke:#4D4D4D;}
.st8{stroke:#4D4D4D;}
.st9{stroke:#000000;}
.st10{opacity:0.1;}
.st11{fill:#FF5F55;}
.st12{fill:#FF5F53;}
.st13{fill:#FFFFFF;}
.st14{fill:#999595;stroke:#000000;stroke-width:2.39;stroke-linecap:round;stroke-linejoin:round;}
.st15{fill:#3A3D40;stroke:#000000;stroke-width:2.73;stroke-linecap:round;stroke-linejoin:round;}
</style>
<g id="layer1">
<g id="g344">
<path id="path66-7" d="M349.1,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V71.2c0-3.6,2.9-6.4,6.5-6.5h7.9c3.6,0,6.4,2.9,6.5,6.5V207
c0,4.9-1.2,9.6-3.4,14l-6.7,13v79.2l6.7,13c2.2,4.3,3.4,9.1,3.4,13.9v269.7c0,4.9-1.2,9.6-3.4,14l-6.7,13V716l6.7,13
c2.2,4.3,3.4,9.1,3.4,13.9v157.2C355.6,903.7,352.7,906.6,349.1,906.6L349.1,906.6L349.1,906.6z M341.2,65.7c-3,0-5.5,2.4-5.5,5.5
v828.9c0,3,2.4,5.5,5.5,5.5h7.9c3,0,5.5-2.4,5.5-5.5V742.9c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5
c0-0.1,0-0.2,0.1-0.2l6.8-13.1c2.2-4.2,3.3-8.8,3.3-13.5V340.1c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5
c0-0.1,0-0.2,0.1-0.2l6.8-13.1c2.2-4.2,3.3-8.8,3.3-13.5V71.2c0-3-2.4-5.5-5.5-5.5L341.2,65.7L341.2,65.7z"/>
<path id="path68-5" d="M335.3,858.9h-11.2c-0.3,0-0.5-0.2-0.5-0.5V72c0-0.3,0.2-0.5,0.5-0.5h11.2c0.3,0,0.5,0.2,0.5,0.5v786.4
C335.8,858.7,335.6,858.9,335.3,858.9z M324.6,857.9h10.2V72.5h-10.2V857.9z"/>
<path id="path70-3" d="M318.1,1000H211.9C94.9,1000,0,905.2,0,788.1l0,0V220.9C0,104.1,95.1,9.1,211.9,9.1h106.2
c3.6,0,6.5,2.9,6.5,6.5v978C324.6,997.1,321.7,1000,318.1,1000L318.1,1000L318.1,1000z M211.9,10.1C95.6,10.1,1,104.7,1,220.9
v567.2C1,904.4,95.6,999,211.9,999h106.2c3,0,5.5-2.4,5.5-5.5v-978c0-3-2.4-5.5-5.5-5.5H211.9L211.9,10.1L211.9,10.1z"/>
<path id="path98" d="M349.1,717.1h-4.2c-0.6,0-1-0.4-1-1l0,0v-79.5c0-0.6,0.4-1,1-1h4.2c3.8,0,6.9,3.1,7,7v67.6
C356.1,714,353,717.1,349.1,717.1z M345.9,715.1h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V715.1z"/>
<path id="path100" d="M349.1,314.3h-4.2c-0.6,0-1-0.4-1-1v-79.5c0-0.6,0.4-1,1-1h4.2c3.8,0,6.9,3.1,7,7v67.6
C356.1,311.2,353,314.3,349.1,314.3z M345.9,312.3h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V312.3z"/>
<path id="path1144" class="st0" d="M193.2,997.9c-26.2-3-49.9-8.5-75.1-21C96.2,966,77,951.2,60.7,934.4
C28.4,901.1,7,856.6,1.7,807.7c-0.4-3.4-0.1-30.5-0.3-72.2C0.3,576.9,0.4,214.9,1.8,201c1.8-17.7,6.1-36.5,12-52.4
c2.8-7.5,7.1-15.8,10.7-23.1C55.9,61.8,116.8,21.2,187,12c18.2-2.4,133.1-3.3,135.5-0.9c0.1,0.1,0.9,2.3,1,7
c0.4,11.1,0.4,36,1.3,79.4c0.7,32.7,0,76.3,0.1,132.5c0.2,70.3-1.6,160.2-1.6,274.8c0,484.5,1.4,491.2-0.9,492.4
c-0.3,0.2-2.5,1.7-5.3,1.8c-21.9,1.1-119.2-0.5-120.6-0.7L193.2,997.9L193.2,997.9z"/>
<polygon id="polygon80" class="st1" points="173.9,448.1 160.6,470.2 187.3,470.2 "/>
<polygon id="polygon82" class="st2" points="187.1,605.6 174.3,627.3 161.5,605.6 "/>
<polygon id="polygon84" class="st1" points="105.9,524.7 84,538.1 105.9,551.5 "/>
<polygon id="polygon86" class="st3" points="266.4,537.9 240.8,551.6 240.8,524.1 "/>
<path id="path102" d="M17.3,139.3c-0.3,0-0.5-0.1-0.7-0.3l-3.4-3.4c-2-2-2.6-5.1-1.5-7.8C46.5,50.1,123.7,0.1,208.9,0h51.2
c3.8,0,6.9,3.1,7,7v2.6c0,0.6-0.4,1-1,1h-54.2C127.4,10.5,51.1,61,18.2,138.7c-0.1,0.3-0.4,0.5-0.7,0.6L17.3,139.3L17.3,139.3z
M208.9,2C124.5,2.1,48,51.7,13.5,128.7c-0.8,1.9-0.4,4.1,1.1,5.5l2.4,2.4C50.6,58.8,127.3,8.5,212,8.6h53.2V7c0-2.7-2.2-5-5-5
L208.9,2L208.9,2z"/>
<path id="path104" d="M295.6,116.1h-46.9c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4h46.9c2.2,0,4,1.8,4,4v11.7
C299.6,114.3,297.8,116.1,295.6,116.1z M248.7,98.5c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h46.9c1.1,0,2-0.9,2-2v-11.7
c0-1.1-0.9-2-2-2H248.7z"/>
<path id="path106" d="M173.9,502.9c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5S195.2,502.9,173.9,502.9
L173.9,502.9z M173.9,428c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5S194.1,428,173.9,428L173.9,428z"
/>
<path id="path108" d="M173.9,649.8c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5S195.2,649.8,173.9,649.8
L173.9,649.8z M173.9,574.9c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5l0,0
C210.4,591.2,194.1,574.9,173.9,574.9L173.9,574.9z"/>
<path id="path110" d="M247.4,576.3c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
C285.8,559.1,268.6,576.3,247.4,576.3z M247.4,501.4c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5l0,0
C283.8,517.7,267.5,501.4,247.4,501.4L247.4,501.4L247.4,501.4z"/>
<path id="path112" d="M100.5,576.3c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
C138.9,559.1,121.7,576.3,100.5,576.3z M100.5,501.4c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5l0,0
C136.9,517.7,120.6,501.4,100.5,501.4L100.5,501.4L100.5,501.4z"/>
<path id="path114" d="M250.1,753.7h-45c-5.5,0-9.9-4.4-9.9-9.9v-45c0-5.5,4.4-9.9,9.9-9.9h45c5.5,0,9.9,4.4,9.9,9.9v45
C260,749.3,255.5,753.7,250.1,753.7z M205.1,690.9c-4.4,0-7.9,3.6-7.9,7.9v45c0,4.4,3.6,7.9,7.9,7.9h45c4.4,0,7.9-3.6,7.9-7.9v-45
c0-4.4-3.6-7.9-7.9-7.9H205.1z"/>
<path id="path116" d="M227.6,741.7c-11.3,0-20.4-9.2-20.4-20.4s9.2-20.4,20.4-20.4s20.4,9.2,20.4,20.4l0,0
C248,732.6,238.9,741.7,227.6,741.7z M227.6,702.8c-10.2,0-18.4,8.3-18.4,18.4s8.3,18.4,18.4,18.4s18.4-8.3,18.4-18.4
S237.8,702.9,227.6,702.8z"/>
<path id="path118" d="M110.8,260.2H98.5c-0.6,0-1-0.4-1-1l0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3s0.3,0.4,0.3,0.7
v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C117.2,257.6,114.3,260.2,110.8,260.2L110.8,260.2z M99.6,258.2h11.2
c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2C132.2,190.3,101.7,220.8,99.6,258.2L99.6,258.2
z"/>
<path id="path120" d="M170.6,338.9L170.6,338.9c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1h12.3c3.5,0,6.4,2.6,6.9,6
c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9V338C171.6,338.5,171.1,338.9,170.6,338.9L170.6,338.9z M99.6,266.9
c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3H99.6L99.6,266.9z"
/>
<path id="path122" d="M177.3,338.9c-0.6,0-1-0.4-1-1v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6
h12.3c0.6,0,1,0.4,1,1l0,0C248.6,305.5,216.9,337.2,177.3,338.9L177.3,338.9L177.3,338.9z M237,266.9c-2.5,0-4.6,1.8-4.9,4.3
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v11.2c37.4-2.2,67.8-32.6,70-70H237z"/>
<path id="path124" d="M249.3,260.2H237c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
c0-0.3,0.1-0.5,0.3-0.7s0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C250.3,259.7,249.9,260.2,249.3,260.2L249.3,260.2L249.3,260.2z
M178.3,188.2v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h11.2
C246.1,220.8,215.6,190.3,178.3,188.2L178.3,188.2L178.3,188.2z"/>
<path id="path126" d="M173.9,339c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3H98.5c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9H237c-2.5,0-4.6,1.8-4.9,4.3
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C176.2,339,175.1,339,173.9,339L173.9,339z
M171.6,337c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3v-4.6H237
c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6H99.4v4.6h11.3c3.5,0,6.4,2.6,6.9,6
c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9L171.6,337L171.6,337z"/>
<path id="path179" class="st4" d="M94,574.3c-14.7-3.2-24.9-12.7-29-27.1c-1-3.4-1.2-6.3-0.9-11.7c0.3-6.5,0.7-7.8,3.5-13.5
c11.4-22.9,40.7-27.9,58.6-10c19.4,19.4,12,51.9-13.9,60.8C107.1,574.5,98.5,575.3,94,574.3L94,574.3L94,574.3z M106.6,538
c0-7.3-0.2-13.4-0.4-13.4c-0.9,0-23.3,13.2-23,13.5c0.7,0.7,22.2,13.1,22.8,13.2C106.4,551.3,106.6,545.4,106.6,538L106.6,538
L106.6,538z"/>
<path id="path181" class="st4" d="M168.5,500.6c-6.9-0.9-15-5-20.5-10.4c-14.6-14.5-14.6-36.9,0.1-51.4c23-22.9,62.3-7,62.3,25.4
c0,10.4-3.5,18.8-10.7,26C191.3,498.4,180.4,502.1,168.5,500.6L168.5,500.6L168.5,500.6z M187.1,469.9
c-0.9-2.4-12.8-22.4-13.3-22.4c-0.4,0-5.9,9-12,19.9l-2,3.6h13.9C185.9,471,187.5,470.9,187.1,469.9L187.1,469.9L187.1,469.9z"/>
<path id="path185" class="st4" d="M165.2,647c-12.9-3.5-23.1-13.7-26.5-26.6c-5.9-22.7,11.6-45.2,35.2-45.3
c7.4,0,11.3,0.9,18.1,4.5c16.9,8.8,23.9,30.4,15.4,47.9C199.8,643,181.7,651.4,165.2,647L165.2,647L165.2,647z M181.4,616.9
c3.6-6.3,6.5-11.6,6.3-11.8s-6.4-0.3-13.8-0.1l-13.5,0.2l6.7,11.6c3.7,6.4,6.9,11.6,7.2,11.6C174.5,628.4,177.8,623.2,181.4,616.9
L181.4,616.9z"/>
<path id="path187" class="st4" d="M243.9,574.2c-0.3,0-1.6-0.3-2.9-0.5c-11.2-2.2-20.9-9.7-26.2-20.1c-2.8-5.6-4.2-12.2-3.8-17.9
c1.1-14.8,11.3-27.7,25.6-32.5c8.8-2.9,18-2.2,26.7,2.2s15.5,12.1,18.6,21.3c5.3,15.3-0.7,32.2-14.7,41.6c-6,4-13.4,6.3-20.2,6.2
C245.7,574.3,244.2,574.3,243.9,574.2L243.9,574.2L243.9,574.2z M243.2,551.1c0.7-0.4,3-1.6,5.1-2.8c8.7-4.8,15.6-9.2,16.2-10
c0.3-0.4,0.3-0.5,0-0.9c-0.9-1.3-21.5-13.5-22.9-13.5c-0.3,0-0.6,0.1-0.7,0.2c-0.4,0.5-0.6,4.8-0.6,13.9c0,9.1,0.2,13,0.6,13.5
C241.3,551.9,241.8,551.8,243.2,551.1L243.2,551.1L243.2,551.1z"/>
<path id="path189" class="st5" d="M224,739.1c-1-0.2-3-1-4.4-1.6c-2.1-1-2.9-1.6-4.8-3.5c-1.9-1.9-2.5-2.7-3.5-4.8
c-2.7-5.5-2.7-10.6,0-16.1c1-2.1,1.6-2.8,3.5-4.8c3.6-3.6,7.7-5.3,12.7-5.3c8.4,0,15.7,5.7,17.8,13.9c0.5,2,0.5,6.2,0,8.3
c-1.5,6.3-6.3,11.5-12.7,13.4C230.2,739.4,226.4,739.6,224,739.1L224,739.1L224,739.1z"/>
<path id="path191" class="st4" d="M203.2,751.3c-1.6-0.4-3-1.3-4.1-2.6c-1.8-2.1-1.7-0.9-1.7-27.4s-0.1-25.3,1.9-27.5
c0.6-0.7,1.7-1.5,2.5-1.9l1.5-0.7h48.3l1.8,0.9c1.3,0.6,2,1.2,2.7,2.1c1.8,2.3,1.7,1.3,1.6,27.8c-0.1,23.8-0.1,23.9-0.6,25.1
c-0.7,1.6-2.3,3.1-3.9,3.9l-1.3,0.7l-23.8,0C210,751.6,204.2,751.5,203.2,751.3L203.2,751.3L203.2,751.3z M230.5,741.6
c10.6-1.5,18.1-10.7,17.5-21.4c-0.2-3.4-0.7-5.3-2-8.1c-4.6-9.3-15.5-13.7-25.3-10.2c-2.8,1-4.7,2.2-7,4.3c-3,2.8-5.1,6.3-6,10.3
c-0.5,2.2-0.5,7.2,0,9.4c0.9,3.9,3,7.4,6,10.2c2.2,2.1,4.2,3.3,6.7,4.3C223.7,741.7,227.1,742.1,230.5,741.6L230.5,741.6
L230.5,741.6z"/>
<path id="path1082" class="st6" d="M171.8,330.4c0-6-0.1-6.5-0.7-7.9c-1.1-2.1-2.9-3.4-5.6-3.9c-15.1-2.7-27.5-10.1-36.5-21.9
c-5-6.5-8.8-15.1-10.4-23.2c-0.8-4.3-1.4-5.7-3-7c-1.8-1.5-3.3-1.8-10-1.8h-5.9v-4.2h6.3c6.1,0,6.3,0,8-0.9
c2.4-1.2,3.3-2.7,4.2-7.3c4.6-23.2,22.4-41,45.6-45.4c4.2-0.8,5.6-1.6,6.9-3.8c0.9-1.5,0.9-1.6,1-8.1l0.1-6.6h4.2v6.3
c0,6.2,0,6.3,0.9,8c1.3,2.6,2.6,3.4,7.6,4.4c19.4,3.8,35.1,17,42.3,35.4c1,2.7,1.9,5.9,3.3,12c0.6,2.6,1.7,4.2,3.6,5.2
c1.1,0.6,2,0.7,7.9,0.8l6.6,0.1v4.2h-6.3c-6.1,0-6.3,0-8,0.9c-2.2,1.1-3.4,2.9-3.9,5.9c-4.1,23.8-22.2,42.3-46,46.8
c-4.2,0.8-5.7,1.7-7,4.1c-0.8,1.5-0.8,1.9-0.9,8l-0.1,6.4h-4.2L171.8,330.4L171.8,330.4z"/>
<path id="path1084" class="st7" d="M99.8,257.3c0.1-0.5,0.3-1.9,0.4-3.2c0.4-3.9,1.7-10.1,3.3-14.8c8-24.1,28.1-42.7,52.7-48.9
c3.1-0.8,7.6-1.6,11.3-1.9l2-0.2v5.9c0,8.5-0.4,9.1-6.5,10.4c-18.4,3.7-33.7,15.2-41.9,31.9c-2.6,5.1-4.1,10.1-5.5,17
c-0.5,2.4-1.8,4-3.7,4.4c-0.7,0.2-3.8,0.3-6.8,0.3h-5.5L99.8,257.3L99.8,257.3z"/>
<path id="path1086" class="st7" d="M165.8,336.4c-27-3-50.8-21.4-60.9-46.9c-2.4-6-4.2-13.4-4.7-18.7c-0.1-1.3-0.3-2.7-0.4-3.1
l-0.2-0.8l6.3,0.1c5.8,0.1,6.4,0.2,7.2,0.8c1.6,1.2,2,2.2,2.9,6.2c1.2,5.8,2.4,9.4,5.2,14.8c2.9,5.7,5.7,9.8,9.9,14.2
c8.6,9.1,19.7,15.2,31.7,17.5c3.6,0.7,4.6,1.2,5.8,2.7c0.6,0.8,0.7,1.4,0.8,7.2c0.1,5.9,0.1,6.3-0.5,6.3
C168.6,336.7,167.2,336.6,165.8,336.4L165.8,336.4L165.8,336.4z"/>
<path id="path1088" class="st7" d="M235.7,257.7c-2.4-0.9-2.8-1.6-3.8-6.5c-3.7-18.2-15.4-33.5-32-41.6c-4.8-2.4-8.6-3.7-13.5-4.7
c-4.7-1-6.2-1.6-7.1-2.9c-0.7-1.1-0.7-1.4-0.7-7.4c0-3.5,0.1-6.3,0.3-6.3s1.9,0.2,4,0.5c12,1.5,22.9,5.6,32.8,12.4
c4.4,3,7.4,5.6,11.6,9.9c9.3,9.6,15.5,20.7,18.8,33.5c0.9,3.6,2.1,10.9,2.1,12.9c0,0.6-0.3,0.6-5.6,0.6
C238.7,258.1,236.5,258,235.7,257.7L235.7,257.7L235.7,257.7z"/>
<path id="path1090" class="st7" d="M178.3,330.5c0.1-5.8,0.2-6.4,0.8-7.2c1.2-1.6,2.2-2,6.3-2.9c23.5-4.7,41.9-23.3,46.4-47
c0.7-3.5,1.1-4.5,2.7-5.6c0.8-0.6,1.4-0.7,7.2-0.8l6.3-0.1l-0.2,1.7c-1.2,10.5-3.3,18-7.5,26.4c-11.2,22.6-32.9,38.1-58,41.3
c-2.1,0.3-3.9,0.5-4,0.5S178.3,333.9,178.3,330.5L178.3,330.5L178.3,330.5z"/>
<path id="path1092" class="st4" d="M247.6,113.5c-0.5-0.6-0.7-1.8-0.7-7.2c0-4.5,0.2-6.7,0.5-7c0.4-0.4,6.4-0.5,24.6-0.5
c21.3,0,24.2,0.1,24.8,0.7c0.5,0.6,0.7,1.8,0.7,7c0,6.1,0,6.4-1,7c-0.8,0.6-3.9,0.7-24.6,0.7S248.2,114,247.6,113.5z"/>
<path id="path1094" class="st8" d="M15,134.2c-2.3-2.8-2.2-3.7,2.3-12.6C28,99.9,40.9,82,57.8,65.1C89.1,33.7,129.4,12.8,173,5.3
c15.1-2.6,16.5-2.7,54-2.9l34.8-0.2l1.4,1.2c1,0.9,1.4,1.7,1.6,3l0.2,1.8l-33.8,0.2C195,8.6,192.5,8.8,178,11.1
c-38.4,6.2-72.9,22-103.3,47.3c-6.8,5.7-19.5,18.3-25.2,25.2c-8.4,10-16.5,21.7-22.5,32.4c-3.1,5.4-9.6,18.7-9.6,19.5
C17.3,136.4,16.5,136,15,134.2L15,134.2L15,134.2z"/>
<path id="path1150" class="st9" d="M334.4,616c0-216,0-634,0.1-526c0.1,108,0.3,614.3,0.1,722.4c0,29.2-0.1,43.2-0.1,45
C334.5,862.4,334.5,773.6,334.4,616L334.4,616L334.4,616z"/>
<path id="path1152" class="st4" d="M336.6,903.2c-1.5-2.1-0.8-44.2-0.8-417.6S335,70.3,336.5,68.2c1.4-2,3.4-2.2,8.5-2.2
c1.8,0,3.8-0.1,5.4,0.2c1.4,0.3,3.2,2,3.5,2.4c0.5,0.5,0.3,4.3,0.4,16.4c0.1,11.3-0.2,29-0.2,55.3c0,44.7,0.6,61.8,0.1,69.8
c-0.3,4.4-1.2,6.1-1.9,8.1c-1.2,3.1-3.9,8.2-5.6,10.9l-3.2,5l0.4,40.4c0.4,37.6-0.2,39,1.6,41.7c1.1,1.5,3,6.1,4.6,9.3l3,5.8
l1.3,7.9l-0.1,19.8l-0.1,15.8l-0.2,97.9c-0.2,93.1,1.2,126.7-0.3,141.1c-0.4,4.2-1.6,6.5-2.3,8.5c-0.9,2.7-2.1,4.9-3.9,7.8
l-3.7,6.1l0.4,15.6l0.1,25.1c0.1,26.5,0.6,40.4,1.3,40.9c0.6,0.4,2.7,4,4.3,8.5l3.3,9l1.1,9l-0.2,15.9l-0.2,57.9
c-0.2,61.9,0.4,84.5-0.5,85.5c-0.8,0.9-4.5,2.4-8.4,2.4C340.2,905.8,338,905.1,336.6,903.2L336.6,903.2L336.6,903.2z"/>
<path id="path1154" class="st4" d="M325.2,464.9V72.7h8.5v392.2l1.1,393l-5.3,0.2l-4.9-0.2L325.2,464.9L325.2,464.9z"/>
<path id="path1156" class="st0" d="M345.9,273.3v-38.6h3c1.7,0,3.6,0.9,4.3,2.1c1.7,2.8,1.7,70.3,0,73.1c-0.7,1.2-2.6,2.1-4.3,2.1
h-3V273.3L345.9,273.3z"/>
<path id="path1158" class="st0" d="M345.9,676.2v-38.7h3c1.8,0,3.6,0.9,4.3,2.1c1.7,2.8,1.7,70.3,0,73.2c-0.7,1.2-2.6,2.1-4.3,2.1
h-3V676.2L345.9,676.2z"/>
</g>
<g id="g315">
<g id="g64" class="st10">
<path id="path36" class="st11" d="M654.6,233.9v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6h4.2V233.9z"/>
<path id="path38" class="st11" d="M654.6,636.6v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6L654.6,636.6L654.6,636.6z"/>
<path id="path40" class="st11" d="M985.7,134.9l-3.4,3.4C949.1,60.3,872.5,9.6,787.6,9.6h-54.2V7c0-3.3,2.7-6,6-6h51.2
C875.4,1,952.3,50.8,987,128.2C988,130.5,987.5,133.1,985.7,134.9L985.7,134.9L985.7,134.9z"/>
<path id="path42" class="st11" d="M736.2,94.5V82.8c0-1.6-1.3-3-3-3h-11.7c-1.6,0-3,1.3-3,3l0,0v11.7c0,1.6-1.3,3-3,3h-11.7
c-1.6,0-3,1.3-3,3l0,0v11.7c0,1.6,1.3,3,3,3h11.7c1.6,0,3,1.3,3,3l0,0v11.7c0,1.6,1.3,3,3,3h11.7c1.6,0,3-1.3,3-3l0,0v-11.7
c0-1.6,1.3-3,3-3h11.7c1.6,0,3-1.3,3-3l0,0v-11.7c0-1.6-1.3-3-3-3h-11.7C737.5,97.5,736.2,96.1,736.2,94.5L736.2,94.5z"/>
<circle id="circle44" class="st11" cx="825.6" cy="333.9" r="37.5"/>
<circle id="circle46" class="st11" cx="825.6" cy="187.1" r="37.5"/>
<circle id="circle48" class="st11" cx="899" cy="260.5" r="37.5"/>
<circle id="circle50" class="st11" cx="752.2" cy="260.5" r="37.5"/>
<circle id="circle52" class="st11" cx="771.7" cy="721.3" r="27.9"/>
<path id="path54" class="st11" d="M822.3,460.3v12.3c0,3-2.2,5.5-5.2,5.9c-25.2,3.7-45,23.5-48.7,48.7c-0.4,2.9-2.9,5.1-5.9,5.2
h-12.3C751.9,493.3,783.2,462,822.3,460.3L822.3,460.3L822.3,460.3z"/>
<path id="path56" class="st11" d="M822.3,598.8v12.3c-39.1-1.7-70.3-33-72.1-72h12.3c3,0,5.5,2.2,5.9,5.2
c3.7,25.2,23.5,45,48.7,48.7C820.1,593.3,822.3,595.8,822.3,598.8L822.3,598.8L822.3,598.8z"/>
<path id="path58" class="st11" d="M901,539c-1.7,39.1-33,70.3-72.1,72v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7
c0.4-2.9,2.9-5.1,5.9-5.2L901,539L901,539z"/>
<path id="path60" class="st11" d="M901,532.4h-12.3c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9
v-12.3C868,462,899.3,493.3,901,532.4L901,532.4L901,532.4z"/>
<path id="path62" class="st11" d="M901.1,535.7c0,1.1,0,2.2-0.1,3.3h-12.3c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3c-1.1,0.1-2.2,0.1-3.3,0.1s-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
c0.4,2.9,2.9,5.1,5.9,5.2H901C901,533.5,901.1,534.6,901.1,535.7L901.1,535.7z"/>
</g>
<path id="path72" d="M658.3,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V742.9c0-4.9,1.2-9.6,3.4-13.9l6.7-13v-79.2l-6.7-13
c-2.2-4.3-3.4-9.1-3.4-14V340.1c0-4.9,1.2-9.6,3.4-13.9l6.7-13V234l-6.7-13c-2.2-4.3-3.4-9.1-3.4-14V71.2c0-3.6,2.9-6.4,6.5-6.5
h7.9c3.6,0,6.4,2.9,6.5,6.5c1.1,276.3,1.2,552.6,0,828.9C664.7,903.7,661.8,906.6,658.3,906.6L658.3,906.6L658.3,906.6z
M650.4,65.7c-3,0-5.5,2.4-5.5,5.5V207c0,4.7,1.1,9.3,3.3,13.5l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2
l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v269.7c0,4.7,1.1,9.3,3.3,13.5l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2
l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v157.2c0,3,2.4,5.5,5.5,5.5h7.9c3,0,5.5-2.4,5.5-5.5V71.2c0-3-2.4-5.5-5.5-5.5L650.4,65.7
L650.4,65.7z"/>
<path id="path74" d="M675.5,858.9h-11.3c-0.3,0-0.5-0.2-0.5-0.5l0,0L664.5,72c0-0.3,0.2-0.5,0.5-0.5h11.3c0.3,0-0.3,0.2-0.3,0.5
v786.4C676,858.7,675.8,858.9,675.5,858.9z M665.6,857.9h9.4l0.8-785.4h-10.3l1,8.8c-0.6,256.1,4.5,511.8-1.1,768.3
C665.3,852.3,665.6,855.1,665.6,857.9L665.6,857.9z"/>
<path id="path76" d="M787.4,1000.2H681.2c-3.6,0-6.5-2.9-6.5-6.5v-978c0-3.6,2.9-6.5,6.5-6.5h106.2
c116.8,0,211.9,95.1,211.9,211.9v567.2C999.3,905.3,904.5,1000.2,787.4,1000.2L787.4,1000.2z M681.2,10.4c-3,0-5.5,2.4-5.5,5.5
v978c0,3,2.4,5.5,5.5,5.5h106.2c116.3,0,210.9-94.6,210.9-210.9V221.1c0-116.3-94.6-210.9-210.9-210.9L681.2,10.4z"/>
<path id="path128" d="M654.6,314.3h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1l0,0v79.5
C655.6,313.9,655.1,314.3,654.6,314.3L654.6,314.3z M650.4,234.8c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5h3.2v-77.5h-3.2V234.8z"/>
<path id="path130" d="M654.6,717.1h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1l0,0V716
C655.6,716.6,655.1,717.1,654.6,717.1L654.6,717.1z M650.4,637.6c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5h3.2v-77.5L650.4,637.6
L650.4,637.6z"/>
<path id="path1240" class="st12" d="M805.5,998.7c26.6-2.4,50.5-9.2,75.9-21.8c5.1-2.5,10-5.2,14.9-8
c19.1-11.3,36.3-27.1,49.6-41.7c25.5-28,45.5-70.1,51.4-116.5c0.1-0.7,0.4-4.3,0.4-6.8c-0.1-6.9,0.7-20,0.8-38.3
c0.7-77.5,1.1-244,1.1-376.4c0-101.2-0.3-182.5-1-188.9c-2.7-26.1-9.3-49.1-20.8-72.1c-31.8-63.9-93-107.4-164-116.7
c-11.4-1.5-60.7-1.6-96.6-1.3c-7.7,0.1-14.1-0.1-20.1,0.1c-7.5,0.2-12.9-0.1-16.2,0.2c-1.7,0.2-3,0.8-3.2,1
c-0.1,0.1-1.4,1.4-1.5,3.3c-0.3,5.2-0.3,17.1-0.4,38c0,4.2-0.1,8.8-0.1,13.8c0,4.9,0.1,10.1,0.1,15.8c-0.1,8.8,0.1,18.6,0.1,29.2
c0,9.8-0.2,20.5,0,32c0.2,9,0.2,18.4,0.2,28.4c-0.1,15.1,0.6,31.1,0.3,49c-0.2,15,0.1,30,0,46.9c-0.1,11.1,0.1,22.6,0,34.6
c-0.1,7.2,0,14.5-0.1,22.1c-0.5,52.1,0,112.2,0,180.3c0,254.3-0.3,376.1,0,435.2c0,7.7-0.2,14.5-0.1,20.2c0,2.2,0,4.3,0,6.2
c0,3.3,0,6.6,0,9.3c0,2.9-0.1,5.8,0,8c0.1,5,0.1,8.1,0.3,10c0.3,2.8,1.3,3.6,1.6,3.8c0.2,0.2,1.3,0.9,3.1,1.1
c4.5,0.4,14.6,0.3,27.1,0.2c9.9-0.1,21.3-0.2,32.8-0.2C772.7,998.8,805.8,999,805.5,998.7L805.5,998.7L805.5,998.7z"/>
<path id="path78" d="M771.7,763.2c-23.1,0-41.9-18.7-41.9-41.9s18.7-41.9,41.9-41.9c23.2,0,41.9,18.7,41.9,41.9l0,0
C813.5,744.4,794.8,763.1,771.7,763.2z M771.7,680.4c-22.6,0-40.9,18.3-40.9,40.9s18.3,40.9,40.9,40.9c22.6,0,40.9-18.3,40.9-40.9
l0,0C812.5,698.7,794.3,680.4,771.7,680.4z"/>
<path id="path88" class="st13" d="M838.9,203.2h-5.5l-7.6-10.9l-8,10.9h-5.4l10.6-16.3l-9.8-15.6h5.2l7.4,10.6l7.3-10.6h5
l-9.8,15.4L838.9,203.2L838.9,203.2z"/>
<path id="path90" class="st13" d="M765.9,244.5l-11.6,20.6v11.4h-4.4V265l-11.6-20.5h5.3l6.4,11.7l2.1,3l2.4-2.6l6.4-12.1H765.9
L765.9,244.5z"/>
<path id="path92" class="st13" d="M912.6,276.5h-4.7l-2.2-7l-12.4,0.3l-3.2,6.7h-4.5l9.9-35.2l6.7,3.2L912.6,276.5z M903.9,265.2
l-4.9-14.6l-4.6,14.8L903.9,265.2L903.9,265.2z"/>
<path id="path132" d="M982.3,139.3h-0.2c-0.3-0.1-0.6-0.3-0.7-0.6C948.4,61,872.1,10.5,787.6,10.6h-54.2c-0.6,0-1-0.4-1-1l0,0V7
c0-3.8,3.1-6.9,7-7h51.2C875.8,0.1,953,50.1,987.9,127.8c1.2,2.6,0.6,5.7-1.5,7.8L983,139C982.8,139.2,982.5,139.3,982.3,139.3
L982.3,139.3z M734.4,8.6h53.2c84.7-0.1,161.3,50.2,195,128l2.4-2.4l0,0c1.5-1.4,1.9-3.6,1.1-5.5C951.5,51.7,875,2.1,790.6,2
h-51.2c-2.7,0-5,2.2-5,5V8.6z"/>
<path id="path134" d="M733.2,133.7h-11.7c-2.2,0-4-1.8-4-4V118c0-1.1-0.9-2-2-2h-11.7c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4
h11.7c1.1,0,2-0.9,2-2V82.8c0-2.2,1.8-4,4-4h11.7c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c2.2,0,4,1.8,4,4v11.7
c0,2.2-1.8,4-4,4h-11.7c-1.1,0-2,0.9-2,2v11.7C737.2,131.9,735.4,133.7,733.2,133.7z M703.9,98.5c-1.1,0-2,0.9-2,2v11.7
c0,1.1,0.9,2,2,2h11.7c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c1.1,0,2-0.9,2-2v-11.7c0-2.2,1.8-4,4-4H751c1.1,0,2-0.9,2-2
v-11.7c0-1.1-0.9-2-2-2h-11.7c-2.2,0-4-1.8-4-4V82.8c0-1.1-0.9-2-2-2h-11.7c-1.1,0-2,0.9-2,2v11.7c0,2.2-1.8,4-4,4H703.9z"/>
<path id="path136" d="M825.6,372.4c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5c21.3,0,38.5,17.2,38.5,38.5
C864,355.2,846.8,372.4,825.6,372.4z M825.6,297.5c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5c20.2,0,36.5-16.3,36.5-36.5
C862,313.8,845.7,297.5,825.6,297.5z"/>
<path id="path138" d="M825.6,225.5c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5c21.3,0,38.5,17.2,38.5,38.5
C864,208.3,846.8,225.5,825.6,225.5z M825.6,150.6c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5c20.2,0,36.5-16.3,36.5-36.5
C862,166.9,845.7,150.6,825.6,150.6z"/>
<path id="path140" d="M899,299c-21.2,0-38.5-17.2-38.5-38.5S877.7,222,899,222c21.3,0,38.5,17.2,38.5,38.5S920.3,298.9,899,299z
M899,224c-20.1,0-36.5,16.3-36.5,36.5S878.8,297,899,297c20.2,0,36.5-16.3,36.5-36.5S919.2,224,899,224z"/>
<path id="path142" d="M752.2,299c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5c21.3,0,38.5,17.2,38.5,38.5
C790.6,281.7,773.4,298.9,752.2,299z M752.2,224c-20.1,0-36.5,16.3-36.5,36.5s16.2,36.2,36.4,36.2s36.6-16,36.6-36.2
C788.6,240.4,772.3,224,752.2,224z"/>
<path id="path144" d="M771.7,750.2c-16,0-28.9-13-28.9-28.9s13-28.9,28.9-28.9s28.9,13,28.9,28.9l0,0
C800.6,737.3,787.7,750.2,771.7,750.2z M771.7,694.3c-14.9,0-26.9,12.1-26.9,26.9s12.1,26.9,26.9,26.9s26.9-12.1,26.9-26.9
S786.6,694.4,771.7,694.3z"/>
<path id="path146" d="M762.5,533.4h-12.3c-0.6,0-1-0.4-1-1l0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3
c0.2,0.2,0.3,0.4,0.3,0.7v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C768.9,530.8,766,533.4,762.5,533.4z
M751.3,531.4h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2
C783.9,463.5,753.4,494,751.3,531.4z"/>
<path id="path148" d="M822.3,612.1C822.3,612.1,822.2,612.1,822.3,612.1c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1h12.3
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v12.3C823.3,611.6,822.8,612.1,822.3,612.1L822.3,612.1
L822.3,612.1z M751.3,540c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6
c-0.3-2.5-2.4-4.3-4.9-4.3H751.3z"/>
<path id="path150" d="M828.9,612.1c-0.6,0-1-0.4-1-1l0,0v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9
c0.5-3.4,3.4-6,6.9-6H901c0.6,0,1,0.4,1,1l0,0C900.2,578.7,868.6,610.3,828.9,612.1C829,612.1,829,612.1,828.9,612.1L828.9,612.1
L828.9,612.1z M888.7,540c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9V610
c37.4-2.2,67.8-32.6,70-70H888.7z"/>
<path id="path152" d="M901,533.4h-12.3c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
c0-0.3,0.1-0.5,0.3-0.7c0.2-0.2,0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C902,532.9,901.6,533.3,901,533.4L901,533.4L901,533.4z
M829.9,461.4v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h11.2
C897.8,494,867.3,463.5,829.9,461.4z"/>
<path id="path154" d="M825.6,612.2c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3H901
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9h-12.3c-2.5,0-4.6,1.8-4.9,4.3
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C827.9,612.1,826.8,612.2,825.6,612.2L825.6,612.2
L825.6,612.2z M823.3,610.1c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6
h11.3v-4.6h-11.4c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3v4.6h11.3c3.5,0,6.4,2.6,6.9,6
c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9L823.3,610.1L823.3,610.1L823.3,610.1z"/>
<path id="path1462" class="st4" d="M743,295.5c-6.3-1.7-11.3-3.9-16.5-9.1c-7.7-7.7-11.3-17-10.8-27.7c0.6-13.5,8-25,20-31
c10.5-5.2,22.6-5.3,32.7-0.3c7.9,3.9,12.8,10,16.6,18c5.2,10.8,4.2,24.4-2.4,34.6c-5,7.6-13.5,13.7-22,15.7
C755.7,296.8,747.8,296.7,743,295.5L743,295.5L743,295.5z"/>
<path id="path1464" class="st4" d="M819.4,222.9c0-0.3-3.7-0.9-5.7-1.6c-3-1.1-5.9-2.6-8-4c-6.9-4.6-11.7-10.9-14.5-18.9
c-1.3-3.8-2.1-5.2-2.1-11.4s0.7-7.2,2.1-11c3.9-11.1,11.8-19.1,22.8-23c4.2-1.5,5.2-2.3,11.6-2.3c6.4,0,7.3,0.8,11.6,2.3
c14.5,5.2,24,17.6,24.7,32.9c0.5,10.6-2.7,19.5-10.2,26.9c-7.6,7.5-14.4,10.7-24.6,11C823.6,223.7,820.2,223,819.4,222.9
L819.4,222.9L819.4,222.9z"/>
<path id="path1466" class="st4" d="M891.7,296.5c-6.7-1-15.6-5.8-20.8-12.9c-3-4.1-6.2-10.7-7.3-15.7
c-2.8-13.2,2.6-27.9,13.3-35.9c20-15.1,48.1-6.7,56.4,17c1.9,5.3,3,13.3,1.7,19.2c-1.5,6.8-4.9,12.9-10.2,18.2
c-5.3,5.2-9.9,8-16.4,9.6C903.5,297.2,896.3,297.2,891.7,296.5L891.7,296.5L891.7,296.5z"/>
<path id="path1468" class="st4" d="M820.4,369.9c-8.1-1.3-14.2-4-20.6-10.3c-3.8-3.7-5.4-6.2-7.2-10c-7.6-15.8-3-33.1,10.8-44.1
c6.4-5.1,13.6-7.6,22.1-7.6c29.9,0,46.7,33.8,28.7,58c-2.8,3.8-6.3,7.5-10.5,9.8C836.7,369.8,828.1,371.1,820.4,369.9L820.4,369.9
L820.4,369.9z"/>
<path id="path1500" class="st6" d="M823.6,602.7c-0.3-8.9-0.8-9.7-10.1-11.9c-21.1-4.8-37.2-20.1-42.6-41.3
c-0.6-2.2-1.1-5.2-1.1-5.9s-1-2.2-2.2-3.5l-2.3-2l-6.9-0.3h-7v-4h5.9c6.6,0,9.9-1,11.2-3.4c0.4-0.8,1.5-3.9,2-7
c2.7-16.3,14.9-30.7,29.5-38c4.7-2.4,11.4-4.6,15.5-5.4c6.6-1.1,8.2-3.6,8.2-12.8v-5.9h4v6.9c0,6.6,0.1,7,1.8,8.8
c1.5,1.6,3.9,1.7,9.5,3.1c20.4,5,35.3,20.5,40.7,40.1c0.8,2.9,1.8,6.4,2.2,7.8c1.2,4.3,3.8,5.6,11.7,5.6h6.5v4h-6.6
c-7,0-9.9,0.8-10.8,3.1c-0.3,0.7-1.3,4.6-2.1,8c-5.4,21.4-21.3,36.7-42.1,41.5c-9.9,2.3-10.7,3.2-10.7,12.8v6.3h-3.8L823.6,602.7
L823.6,602.7z"/>
<path id="path1504" class="st7" d="M752.2,526.5c1.8-15.3,8.9-31.2,20.4-43c11.9-12.2,27.5-19.2,45.7-21.6l2.8-0.4v6.2
c0,7.9-0.1,8.9-6.8,10.2c-22.3,4.6-41.8,22.1-46.1,44.2c-1.8,9.1-2.4,9.1-11.1,9.1h-5.4L752.2,526.5L752.2,526.5z"/>
<path id="path1506" class="st7" d="M811.2,608.2c-32.2-6.9-55.7-32.9-59.4-65.6l-0.2-2.1h6.4c6.9,0,6.8,0,7.8,1
c1.3,1.4,1.5,3.8,2.4,7.9c4.8,21.2,24.2,39.1,46.6,44c6.9,1.5,6.4,2.7,6.4,10.3v5.9l-2.1,0C817.8,609.5,814.3,608.9,811.2,608.2
L811.2,608.2L811.2,608.2z"/>
<path id="path1508" class="st7" d="M830,603c-0.3-7.3,1-8.2,5.3-9c4.8-0.8,11.1-2.9,16.3-5.5c15.8-7.7,27.1-22,31.6-39.9
c1-4,1.6-7.2,2.2-7.7c0.7-0.5,3.9-0.5,7.8-0.5h6.2l-0.4,3.8c-3.8,33.2-31.8,61.3-64.8,65l-4,0.5L830,603L830,603z"/>
<path id="path1510" class="st7" d="M885.4,529.8c-1.2-1.1-1.3-3-2.1-6.7c-4.4-20.5-19-36.6-39.3-43.5c-2.4-0.8-5.8-1.7-7.5-2
c-1.9-0.3-3.9-0.6-4.8-1.5c-1.4-1.4-1.3-2.6-1.3-8.2v-6.2l2.5,0.3c19,2.5,32.7,9.2,45.4,22.1c10.4,10.5,17.4,23.8,20.2,38.1
c0.6,2.9,1,6.1,1,7.1v1.9h-5.9C888.3,531.3,886.8,531.1,885.4,529.8L885.4,529.8L885.4,529.8z"/>
<path id="path1512" class="st4" d="M720.3,131c-0.5-0.6-0.6-1.7-0.6-7.6v-6.9l-1.1-1.2l-1.1-1.2l-7.1-0.1
c-4.1-0.1-6.5,0.5-7.6-0.2c-1.3-0.8-0.9-3.1-0.9-7.6s0.1-6.3,0.5-6.8c0.5-0.7,1.1-0.7,7.3-0.8c3.7-0.1,7.1-0.2,7.6-0.3
c0.5-0.1,1.2-0.7,1.6-1.4c0.7-1.1,0.7-1.9,0.7-7.8c0-3.8,0.2-6.8,0.4-7.3c0.4-0.7,0.9-0.7,7.3-0.7s7,0.1,7.3,0.7
c0.2,0.4,0.4,3.5,0.4,7.3c0,5.8,0.1,6.7,0.7,7.8c0.4,0.7,1.1,1.3,1.6,1.4s3.9,0.2,7.6,0.3c6.2,0.1,6.8,0.2,7.3,0.8
c0.4,0.6,0.5,2.2,0.5,6.8s0.7,7.2-0.9,7.9c-1.2,0.5-3.8-0.1-7.6-0.1l-7.1,0.1l-1.1,1.2l-1.1,1.2v6.9c0,6.2-0.1,7-0.7,7.6
c-0.6,0.5-1.7,0.6-7.1,0.6C721.7,131.7,720.9,131.6,720.3,131L720.3,131L720.3,131z"/>
<path id="path1514" class="st7" d="M766.6,726.4v-5.3h10.5v10.5h-10.5V726.4L766.6,726.4z"/>
<path id="path1518" class="st7" d="M766,761.6c-14.8-2.3-27.2-12.3-32.4-26.2c-7.5-20,2.3-43,22-51.4c6.1-2.6,8-3.5,15.7-3.5
c6.5,0,7.9,0.6,11.3,1.6c14.4,4.4,24.6,14.9,28.6,29.4c0.8,2.9,1.1,5.2,1.1,10.7c0,5.5-0.3,6.2-1.1,9c-4.8,17.7-20,30-38.1,30.5
C770.5,761.9,767.4,761.8,766,761.6L766,761.6L766,761.6z M778.1,749.7c11.9-2.6,21.3-13,22.5-25.1c2.2-21.5-18.1-37.7-38.5-30.7
c-4.2,1.4-7,3.3-10.8,7.1c-2.8,2.8-3.8,4.1-5.3,7.2c-2.6,5.1-3.3,8.7-3,14.6c0.3,6.8,2.2,11.7,6.3,16.9
C755.9,748,767.4,752,778.1,749.7L778.1,749.7L778.1,749.7z"/>
<path id="path1520" class="st9" d="M648.2,714.3c-1.3-0.8-2.3-0.9-2.5-5.3c-0.2-4.3,0.1-13.5,0.1-32.6c0-32.8-0.5-35.2,0.6-36.3
c0.1-0.1,0.1-0.2,0.2-0.2c1.1-1.5,2.7-2.1,4.9-2.1h1.9V715h-2C650.1,715,648.9,714.8,648.2,714.3L648.2,714.3L648.2,714.3z"/>
<path id="path1522" class="st9" d="M649.6,312.1c-0.5-0.1-1.3-0.4-1.8-0.8c-0.8-0.5-1.5-0.8-1.8-2.7c-0.5-3.2-0.2-11.4-0.2-35.1
c0-19.3-0.5-28.4-0.4-32.5c0.1-2.7,0.8-3.2,1-3.6c0.9-1.6,2.4-2.3,4.8-2.3h2.1v77.3l-1.4,0C651.2,312.3,650.1,312.2,649.6,312.1
L649.6,312.1L649.6,312.1z"/>
<path id="path1524" class="st8" d="M978,126.4c-10.1-20.6-21.9-37.2-38.2-53.9c-34.8-35.7-78.7-57-129.6-63.1
c-5.1-0.6-13.1-0.8-40.9-1l-34.6-0.2V6.9c0-1,0-3,1.4-3.7l2.1-1.1l30.4,0.2c16.9,0.1,33.6,0.2,37,0.5
c50.8,3.9,97.1,24.6,133.3,59.5c17.6,16.9,31.5,35.7,42.8,57.9c4.3,8.4,4.9,10.1,4.2,11.8c-0.4,1.1-2.7,4.2-3.2,4.1
C982.6,136.1,980.5,131.5,978,126.4L978,126.4L978,126.4z"/>
<path id="path1530" class="st4" d="M646.8,903.8c-0.6-0.5-1.7-1.2-1.6-5c0.3-6.7-0.2-27.2-0.1-79.1l0.3-82.6l2.6-6.5l7.9-15
l0.1-39.4l-0.4-39.6l-7.1-13.2l-2.9-7.7l-0.4-7.3l0.1-48l-0.1-22.1l0.1-34.1l0.1-10.5V483l-0.1-8.6l0-25.6v-19.4l-0.2-27.5
l0.1-21.6l0-11l0.1-19.6l0-10.2l0.5-5.7l1.9-5.8l3-5.5l5.3-9.8v-39.5l-0.4-39.6l-5.3-9.8l-2.7-5.3l-1.8-5.1l-0.7-7.6l0.2-13.3
l-0.1-12.2v-11.1l-0.1-10.9l0-9.9V142l0-2.9l0.1-17.4l0-21.5V89.4l-0.1-8.4l0-5.1l-0.2-5.9l2.2-3.1l3.2-1.1l3.2,0.1
c1.4,0,2.7,0.1,3.9,0.2c0.9,0.1,1.8,0.1,2.6,0.4c1,0.4,1.7,1,2,1.3c0.2,0.2,1.2,1.7,1.3,4.8c0.1,2.1,0,4.7,0,8.3
c0,4.1,0.1,9.7,0,16.4c-0.1,10,0,23.1-0.1,40.4c0,13.2,0.2,28.7,0.1,47c-0.2,62.8-0.2,158-0.2,301l0,416.2l-1.3,1.8
C660.4,906.2,649.5,906.5,646.8,903.8L646.8,903.8L646.8,903.8z"/>
<path id="path1532" class="st4" d="M665.8,465.1V72.7h8.6v784.7h-8.6V465.1L665.8,465.1z"/>
<ellipse id="path3879" class="st14" cx="771.6" cy="721.1" rx="40.3" ry="40.3"/>
<ellipse id="path3881" class="st15" cx="771.7" cy="721.4" rx="34.1" ry="34.5"/>
<path id="path96" d="M771.7,694.3l-26.8,26.4h7.7v22.5h38.5v-22.5h7.2L771.7,694.3L771.7,694.3z M779.5,735.2h-15.2v-14.5h15.2
V735.2z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.9.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000.4 356.1" style="enable-background:new 0 0 1000.4 356.1;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.1;}
.st1{fill:#FF5F55;}
.st2{fill:#FF5F53;}
.st3{fill:#FFFFFF;}
.st4{fill:#1A1A1A;stroke:#000000;}
.st5{fill:#1A1A1A;stroke:#1A1A1A;}
.st6{fill:#1A1A1A;stroke:#4D4D4D;}
.st7{stroke:#000000;}
.st8{stroke:#4D4D4D;}
.st9{fill:#999595;stroke:#000000;stroke-width:2.39;stroke-linecap:round;stroke-linejoin:round;}
.st10{fill:#3A3D40;stroke:#000000;stroke-width:2.73;stroke-linecap:round;stroke-linejoin:round;}
</style>
<g id="g315">
<g id="g64" class="st0">
<path id="path36" class="st1" d="M766.5,11.2H687V7c0-3.3,2.7-6,6-6h67.6c3.3,0,6,2.7,6,6L766.5,11.2L766.5,11.2z"/>
<path id="path38" class="st1" d="M363.8,11.2h-79.5V7c0-3.3,2.7-6,6-6h67.6c3.3,0,6,2.7,6,6L363.8,11.2L363.8,11.2z"/>
<path id="path40" class="st1" d="M865.5,342.3l-3.4-3.4c78-33.2,128.7-109.8,128.7-194.7V90h2.6c3.3,0,6,2.7,6,6v51.2
c0,84.8-49.8,161.7-127.2,196.4C869.9,344.6,867.3,344.1,865.5,342.3L865.5,342.3L865.5,342.3z"/>
<path id="path42" class="st1" d="M905.9,92.8h11.7c1.6,0,3-1.3,3-3V78.1c0-1.6-1.3-3-3-3l0,0h-11.7c-1.6,0-3-1.3-3-3V60.4
c0-1.6-1.3-3-3-3l0,0h-11.7c-1.6,0-3,1.3-3,3v11.7c0,1.6-1.3,3-3,3l0,0h-11.7c-1.6,0-3,1.3-3,3v11.7c0,1.6,1.3,3,3,3l0,0h11.7
c1.6,0,3,1.3,3,3v11.7c0,1.6,1.3,3,3,3l0,0h11.7c1.6,0,3-1.3,3-3V95.8C902.9,94.1,904.3,92.8,905.9,92.8L905.9,92.8z"/>
<circle id="circle44" class="st1" cx="666.5" cy="182.2" r="37.5"/>
<circle id="circle46" class="st1" cx="813.3" cy="182.2" r="37.5"/>
<circle id="circle48" class="st1" cx="739.9" cy="255.6" r="37.5"/>
<circle id="circle50" class="st1" cx="739.9" cy="108.8" r="37.5"/>
<circle id="circle52" class="st1" cx="279.1" cy="128.3" r="27.9"/>
<path id="path54" class="st1" d="M540.1,178.9h-12.3c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9
v-12.3C507.1,108.5,538.4,139.8,540.1,178.9L540.1,178.9L540.1,178.9z"/>
<path id="path56" class="st1" d="M401.6,178.9h-12.3c1.7-39.1,33-70.3,72-72.1v12.3c0,3-2.2,5.5-5.2,5.9
c-25.2,3.7-45,23.5-48.7,48.7C407.1,176.7,404.6,178.9,401.6,178.9L401.6,178.9L401.6,178.9z"/>
<path id="path58" class="st1" d="M461.4,257.6c-39.1-1.7-70.3-33-72-72.1h12.3c3,0,5.5,2.2,5.9,5.2c3.7,25.2,23.5,45,48.7,48.7
c2.9,0.4,5.1,2.9,5.2,5.9L461.4,257.6L461.4,257.6z"/>
<path id="path60" class="st1" d="M468,257.6v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7c0.4-2.9,2.9-5.1,5.9-5.2h12.3
C538.4,224.6,507.1,255.9,468,257.6L468,257.6L468,257.6z"/>
<path id="path62" class="st1" d="M464.7,257.7c-1.1,0-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
c0.4,2.9,2.9,5.1,5.9,5.2h12.3c0.1,1.1,0.1,2.2,0.1,3.3s0,2.2-0.1,3.3h-12.3c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3C466.9,257.6,465.8,257.7,464.7,257.7L464.7,257.7z"/>
</g>
<path id="path72" d="M93.8,14.9V7c0-3.6,2.9-6.4,6.5-6.5h157.2c4.9,0,9.6,1.2,13.9,3.4l13,6.7h79.2l13-6.7c4.3-2.2,9.1-3.4,14-3.4
h269.7c4.9,0,9.6,1.2,13.9,3.4l13,6.7h79.2l13-6.7c4.3-2.2,9.1-3.4,14-3.4h135.8c3.6,0,6.4,2.9,6.5,6.5v7.9c0,3.6-2.9,6.4-6.5,6.5
c-276.3,1.1-552.6,1.2-828.9,0C96.7,21.3,93.8,18.4,93.8,14.9L93.8,14.9L93.8,14.9z M934.7,7c0-3-2.4-5.5-5.5-5.5H793.4
c-4.7,0-9.3,1.1-13.5,3.3l-13.1,6.8c-0.1,0-0.1,0.1-0.2,0.1h-79.5c-0.1,0-0.2,0-0.2-0.1l-13.1-6.8c-4.2-2.2-8.8-3.3-13.5-3.3H390.6
c-4.7,0-9.3,1.1-13.5,3.3L364,11.6c-0.1,0-0.1,0.1-0.2,0.1h-79.5c-0.1,0-0.2,0-0.2-0.1L271,4.8c-4.2-2.2-8.8-3.3-13.5-3.3H100.3
c-3,0-5.5,2.4-5.5,5.5v7.9c0,3,2.4,5.5,5.5,5.5h828.9c3,0,5.5-2.4,5.5-5.5L934.7,7L934.7,7z"/>
<path id="path74" d="M141.5,32.1V20.8c0-0.3,0.2-0.5,0.5-0.5l0,0l786.4,0.8c0.3,0,0.5,0.2,0.5,0.5v11.3c0,0.3-0.2-0.3-0.5-0.3H142
C141.7,32.6,141.5,32.4,141.5,32.1z M142.5,22.2v9.4L928,32.4V22.1l-8.8,1c-256.1-0.6-511.8,4.5-768.3-1.1
C148.1,21.9,145.3,22.2,142.5,22.2L142.5,22.2z"/>
<path id="path76" d="M0.2,144V37.8c0-3.6,2.9-6.5,6.5-6.5h978c3.6,0,6.5,2.9,6.5,6.5V144c0,116.8-95.1,211.9-211.9,211.9H212.1
C95.1,355.9,0.2,261.1,0.2,144L0.2,144L0.2,144z M990.1,37.8c0-3-2.4-5.5-5.5-5.5H6.6c-3,0-5.5,2.4-5.5,5.5V144
c0,116.3,94.6,210.9,210.9,210.9h567.3c116.3,0,210.9-94.6,210.9-210.9L990.1,37.8L990.1,37.8z"/>
<path id="path128" d="M686.1,11.2V7c0-3.8,3.1-6.9,7-7h67.6c3.8,0,6.9,3.1,7,7v4.2c0,0.6-0.4,1-1,1l0,0h-79.5
C686.5,12.2,686.1,11.7,686.1,11.2L686.1,11.2z M765.6,7c0-2.7-2.2-5-5-5H693c-2.7,0-5,2.2-5,5v3.2h77.5L765.6,7L765.6,7z"/>
<path id="path130" d="M283.3,11.2V7c0-3.8,3.1-6.9,7-7h67.6c3.8,0,6.9,3.1,7,7v4.2c0,0.6-0.4,1-1,1l0,0h-79.5
C283.8,12.2,283.3,11.7,283.3,11.2L283.3,11.2z M362.8,7c0-2.7-2.2-5-5-5h-67.6c-2.7,0-5,2.2-5,5v3.2h77.5L362.8,7L362.8,7z"/>
<path id="path1240" class="st2" d="M1.8,162.1c2.4,26.6,9.2,50.5,21.8,76c2.5,5.1,5.2,10,8,14.9c11.3,19.1,27.1,36.3,41.7,49.6
c28,25.5,70.1,45.5,116.5,51.4c0.7,0.1,4.3,0.4,6.8,0.4c6.9-0.1,20,0.7,38.3,0.8c77.5,0.7,244,1.1,376.4,1.1
c101.2,0,182.5-0.3,188.9-1c26.1-2.7,49.1-9.3,72.1-20.8c63.9-31.8,107.4-93,116.7-164c1.5-11.4,1.6-60.7,1.3-96.6
c-0.1-7.7,0.1-14.1-0.1-20.1c-0.2-7.5,0.1-12.9-0.2-16.2c-0.2-1.7-0.8-3-1-3.2c-0.1-0.1-1.4-1.4-3.3-1.5c-5.2-0.3-17.1-0.3-38-0.4
c-4.2,0-8.8-0.1-13.8-0.1c-4.9,0-10.1,0.1-15.8,0.1c-8.8,0-18.6,0.1-29.2,0.1c-9.8,0-20.5-0.2-32,0c-9,0.2-18.4,0.2-28.4,0.2
c-15.1-0.1-31.1,0.6-49,0.3c-15-0.2-30,0.1-46.9,0c-11.1-0.1-22.6,0.1-34.6,0c-7.2-0.1-14.5,0-22.1-0.1c-52.1-0.5-112.2,0-180.3,0
c-254.3,0-376.1-0.3-435.2,0c-7.7,0-14.5-0.2-20.2-0.1c-2.2,0-4.3,0-6.2,0c-3.3,0-6.6,0-9.3,0c-2.9,0-5.8-0.1-8,0
c-5,0.1-8.1,0.1-10,0.3c-2.8,0.3-3.6,1.3-3.8,1.6c-0.2,0.2-0.9,1.3-1.1,3.1c-0.4,4.5-0.3,14.6-0.2,27.1c0.1,9.9,0.2,21.3,0.2,32.8
C1.7,129.3,1.5,162.4,1.8,162.1L1.8,162.1L1.8,162.1z"/>
<path id="path78" d="M237.2,128.3c0-23.1,18.7-41.9,41.9-41.9s41.9,18.7,41.9,41.9s-18.7,41.9-41.9,41.9l0,0
C256,170.1,237.3,151.4,237.2,128.3z M320,128.3c0-22.6-18.3-40.9-40.9-40.9s-40.9,18.3-40.9,40.9s18.3,40.9,40.9,40.9l0,0
C301.7,169.1,320,150.9,320,128.3z"/>
<path id="path92" class="st3" d="M723.9,269.2v-4.7l7-2.2l-0.3-12.4l-6.7-3.2v-4.5l35.2,9.9l-3.2,6.7L723.9,269.2z M735.2,260.5
l14.6-4.9L735,251L735.2,260.5L735.2,260.5z"/>
<path id="path132" d="M861.1,338.9v-0.2c0.1-0.3,0.3-0.6,0.6-0.7c77.7-33,128.2-109.3,128.1-193.8V90c0-0.6,0.4-1,1-1l0,0h2.6
c3.8,0,6.9,3.1,7,7v51.2c-0.1,85.2-50.1,162.4-127.8,197.3c-2.6,1.2-5.7,0.6-7.8-1.5l-3.4-3.4C861.2,339.4,861.1,339.1,861.1,338.9
L861.1,338.9z M991.8,91v53.2c0.1,84.7-50.2,161.3-128,195l2.4,2.4l0,0c1.4,1.5,3.6,1.9,5.5,1.1c77-34.6,126.6-111.1,126.7-195.5
V96c0-2.7-2.2-5-5-5H991.8z"/>
<path id="path134" d="M866.7,89.8V78.1c0-2.2,1.8-4,4-4h11.7c1.1,0,2-0.9,2-2V60.4c0-2.2,1.8-4,4-4h11.7c2.2,0,4,1.8,4,4v11.7
c0,1.1,0.9,2,2,2h11.5c2.2,0,4,1.8,4,4v11.7c0,2.2-1.8,4-4,4h-11.7c-1.1,0-2,0.9-2,2v11.7c0,2.2-1.8,4-4,4h-11.7c-2.2,0-4-1.8-4-4
V95.8c0-1.1-0.9-2-2-2h-11.7C868.5,93.8,866.7,92,866.7,89.8z M901.9,60.5c0-1.1-0.9-2-2-2h-11.7c-1.1,0-2,0.9-2,2v11.7
c0,2.2-1.8,4-4,4h-11.7c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h11.7c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c1.1,0,2-0.9,2-2
V95.9c0-2.2,1.8-4,4-4h11.7c1.1,0,2-0.9,2-2V78.2c0-1.1-0.9-2-2-2h-11.7c-2.2,0-4-1.8-4-4V60.5z"/>
<path id="path136" d="M628,182.2c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5s-17.2,38.5-38.5,38.5
C645.2,220.6,628,203.4,628,182.2z M702.9,182.2c0-20.1-16.3-36.5-36.5-36.5s-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5
C686.6,218.6,702.9,202.3,702.9,182.2z"/>
<path id="path138" d="M774.9,182.2c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5s-17.2,38.5-38.5,38.5
C792.1,220.6,774.9,203.4,774.9,182.2z M849.8,182.2c0-20.1-16.3-36.5-36.5-36.5c-20.2,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5
C833.5,218.6,849.8,202.3,849.8,182.2z"/>
<path id="path140" d="M701.4,255.6c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5s-17.2,38.5-38.5,38.5S701.5,276.9,701.4,255.6z
M776.4,255.6c0-20.1-16.3-36.5-36.5-36.5s-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5S776.4,275.8,776.4,255.6z"/>
<path id="path142" d="M701.4,108.8c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5s-17.2,38.5-38.5,38.5
C718.7,147.2,701.5,130,701.4,108.8z M776.4,108.8c0-20.1-16.3-36.5-36.5-36.5s-36.2,16.2-36.2,36.4s16,36.6,36.2,36.6
C760,145.2,776.4,128.9,776.4,108.8z"/>
<path id="path144" d="M250.2,128.3c0-16,13-28.9,28.9-28.9s28.9,13,28.9,28.9s-13,28.9-28.9,28.9l0,0
C263.1,157.2,250.2,144.3,250.2,128.3z M306.1,128.3c0-14.9-12.1-26.9-26.9-26.9s-26.9,12.1-26.9,26.9s12.1,26.9,26.9,26.9
S306,143.2,306.1,128.3z"/>
<path id="path146" d="M467,119.1v-12.3c0-0.6,0.4-1,1-1l0,0c39.6,1.7,71.3,33.4,73,73c0,0.3-0.1,0.5-0.3,0.7s-0.4,0.3-0.7,0.3
h-12.3c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9C469.6,125.5,467,122.6,467,119.1z M469,107.9v11.2
c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3H539C536.9,140.5,506.4,110,469,107.9z"/>
<path id="path148" d="M388.3,178.9C388.3,178.9,388.3,178.8,388.3,178.9c1.7-39.6,33.4-71.3,73-73c0.6,0,1,0.4,1,1v12.3
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-12.3C388.8,179.9,388.3,179.4,388.3,178.9L388.3,178.9
L388.3,178.9z M460.4,107.9c-37.4,2.2-67.8,32.6-70,70h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6
c2.5-0.3,4.3-2.4,4.3-4.9V107.9z"/>
<path id="path150" d="M388.3,185.5c0-0.6,0.4-1,1-1l0,0h12.3c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9
c3.4,0.5,6,3.4,6,6.9v12.3c0,0.6-0.4,1-1,1l0,0C421.7,256.8,390.1,225.2,388.3,185.5C388.3,185.6,388.3,185.6,388.3,185.5
L388.3,185.5L388.3,185.5z M460.4,245.3c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-11.2
c2.2,37.4,32.6,67.8,70,70V245.3z"/>
<path id="path152" d="M467,257.6v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h12.3
c0.3,0,0.5,0.1,0.7,0.3s0.3,0.5,0.3,0.7c-1.7,39.6-33.4,71.3-73,73C467.5,258.6,467.1,258.2,467,257.6L467,257.6L467,257.6z
M539,186.5h-11.2c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v11.2
C506.4,254.4,536.9,223.9,539,186.5z"/>
<path id="path154" d="M388.2,182.2c0-1.2,0-2.3,0.1-3.4c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3
c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1c1.1-0.1,2.2-0.1,3.4-0.1s2.3,0,3.4,0.1
c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3c0.5,0,1,0.4,1,0.9
c0.1,2.3,0.1,4.5,0,6.8c0,0.5-0.5,0.9-1,0.9h-12.3c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9
v12.3c0,0.5-0.4,1-0.9,1c-1.1,0.1-2.2,0.1-3.4,0.1s-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9C388.3,184.5,388.2,183.4,388.2,182.2L388.2,182.2
L388.2,182.2z M390.3,179.9c-0.1,1.5-0.1,3.1,0,4.7h11.3c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9
v11.3h4.6v-11.4c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3c0.1-1.5,0.1-3.1,0-4.7h-11.3
c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3h-4.6V119c0,3.5-2.6,6.4-6,6.9
c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3V179.9L390.3,179.9z"/>
<path id="path1462" class="st4" d="M705,99.6c1.7-6.3,3.9-11.3,9.1-16.5c7.7-7.7,17-11.3,27.7-10.8c13.5,0.6,25,8,31,20
c5.2,10.5,5.3,22.5,0.3,32.7c-4,7.9-10,12.8-18,16.6c-10.8,5.2-24.4,4.2-34.6-2.4c-7.7-5-13.7-13.5-15.7-22
C703.6,112.3,703.7,104.4,705,99.6L705,99.6L705,99.6z"/>
<path id="path1464" class="st4" d="M777.6,176c0.3,0,0.9-3.7,1.6-5.7c1.1-3,2.6-5.9,4-8c4.6-6.9,10.9-11.7,18.9-14.5
c3.8-1.3,5.2-2.1,11.5-2.1s7.2,0.7,11,2.1c11.1,3.9,19.1,11.8,23,22.8c1.5,4.2,2.3,5.2,2.3,11.6s-0.8,7.3-2.3,11.6
c-5.2,14.5-17.6,24-32.9,24.7c-10.6,0.5-19.5-2.7-26.9-10.2c-7.5-7.6-10.7-14.4-11-24.6C776.7,180.2,777.4,176.7,777.6,176
L777.6,176L777.6,176z"/>
<path id="path1466" class="st4" d="M704,248.2c1-6.7,5.8-15.6,12.9-20.8c4.1-3,10.7-6.2,15.7-7.3c13.2-2.8,27.9,2.6,35.9,13.3
c15.2,20,6.7,48.1-17,56.4c-5.3,1.9-13.3,3-19.2,1.7c-6.8-1.5-12.9-4.9-18.2-10.2c-5.2-5.3-8-9.9-9.6-16.4
C703.3,260.1,703.3,252.9,704,248.2L704,248.2L704,248.2z"/>
<path id="path1468" class="st4" d="M630.6,177c1.3-8.1,4-14.2,10.3-20.6c3.7-3.8,6.2-5.4,10-7.2c15.8-7.6,33.1-3,44.1,10.8
c5.1,6.4,7.6,13.6,7.6,22.1c0,29.9-33.8,46.7-58,28.7c-3.8-2.8-7.5-6.3-9.8-10.5C630.7,193.3,629.4,184.7,630.6,177L630.6,177
L630.6,177z"/>
<path id="path1500" class="st5" d="M397.8,180.2c8.9-0.3,9.7-0.8,11.9-10.1c4.8-21.1,20.1-37.2,41.3-42.6c2.2-0.5,5.2-1.1,5.9-1.1
s2.2-1,3.5-2.2l2-2.3l0.3-6.9v-7h4v5.9c0,6.6,1,9.9,3.4,11.2c0.8,0.4,3.9,1.5,7,2c16.3,2.7,30.7,14.9,38,29.5
c2.4,4.7,4.6,11.4,5.4,15.5c1.1,6.6,3.6,8.2,12.8,8.2h5.9v4H532c-6.6,0-7,0.1-8.8,1.8c-1.6,1.5-1.7,3.9-3.1,9.5
c-5,20.4-20.5,35.3-40.2,40.7c-2.9,0.8-6.4,1.8-7.8,2.2c-4.3,1.2-5.6,3.8-5.6,11.7v6.5h-4V250c0-7-0.8-9.9-3.1-10.8
c-0.7-0.3-4.6-1.3-8-2.1c-21.4-5.4-36.7-21.3-41.5-42.1c-2.3-10-3.2-10.7-12.8-10.7h-6.3v-3.8L397.8,180.2L397.8,180.2z"/>
<path id="path1504" class="st6" d="M473.9,108.8c15.3,1.8,31.2,8.9,43,20.4c12.2,12,19.2,27.5,21.6,45.7l0.4,2.8h-6.2
c-7.9,0-8.9-0.1-10.2-6.8c-4.6-22.3-22.1-41.8-44.2-46.1c-9.1-1.8-9.1-2.4-9.1-11.1v-5.4L473.9,108.8L473.9,108.8z"/>
<path id="path1506" class="st6" d="M392.2,167.8c6.9-32.2,32.9-55.7,65.6-59.4l2.1-0.2v6.4c0,6.9,0,6.8-1,7.8
c-1.4,1.3-3.8,1.5-7.9,2.4c-21.2,4.8-39.1,24.2-44,46.6c-1.5,6.9-2.7,6.4-10.3,6.4h-5.9l0-2.1C391,174.4,391.5,170.9,392.2,167.8
L392.2,167.8L392.2,167.8z"/>
<path id="path1508" class="st6" d="M397.4,186.6c7.3-0.3,8.2,1,9,5.3c0.8,4.8,2.9,11.1,5.5,16.3c7.7,15.8,22,27.1,39.9,31.6
c4,1,7.2,1.6,7.7,2.2c0.5,0.7,0.5,3.9,0.5,7.8v6.2l-3.8-0.4c-33.2-3.8-61.3-31.8-65-64.8l-0.5-4L397.4,186.6L397.4,186.6z"/>
<path id="path1510" class="st6" d="M470.6,242c1.1-1.2,3-1.3,6.7-2.1c20.5-4.4,36.6-19,43.5-39.3c0.8-2.4,1.7-5.8,2-7.5
c0.3-1.9,0.6-3.9,1.5-4.8c1.4-1.4,2.6-1.3,8.2-1.3h6.2l-0.3,2.5c-2.5,19-9.2,32.7-22.1,45.4c-10.6,10.4-23.8,17.4-38.2,20.2
c-2.9,0.5-6.1,1-7.1,1h-1.9v-5.9C469.2,244.9,469.3,243.4,470.6,242L470.6,242L470.6,242z"/>
<path id="path1512" class="st4" d="M869.4,76.9c0.6-0.5,1.7-0.6,7.5-0.6h6.9l1.2-1.1l1.2-1.1l0.1-7.1c0.1-4.1-0.5-6.5,0.2-7.6
c0.8-1.3,3.1-0.9,7.6-0.9s6.3,0.1,6.8,0.5c0.7,0.5,0.7,1.1,0.8,7.3c0,3.7,0.2,7.1,0.3,7.6c0.1,0.5,0.7,1.2,1.4,1.6
c1.1,0.7,1.9,0.7,7.8,0.7c3.8,0,6.9,0.2,7.3,0.4c0.7,0.4,0.7,0.9,0.7,7.3s0,7-0.7,7.3c-0.4,0.2-3.5,0.4-7.3,0.4
c-5.8,0-6.7,0.1-7.8,0.7c-0.7,0.4-1.3,1.1-1.4,1.6s-0.2,3.9-0.3,7.6c-0.1,6.2-0.2,6.8-0.8,7.3c-0.6,0.4-2.2,0.5-6.8,0.5
c-4.7,0-7.2,0.7-7.9-0.9c-0.5-1.2,0.1-3.8,0.1-7.5l-0.1-7.1l-1.2-1.1l-1.2-1.1h-6.9c-6.2,0-7-0.1-7.5-0.7c-0.5-0.6-0.6-1.7-0.6-7.1
C868.7,78.2,868.8,77.5,869.4,76.9L869.4,76.9L869.4,76.9z"/>
<path id="path1514" class="st6" d="M274,123.2h5.3v10.5h-10.5v-10.5H274L274,123.2z"/>
<path id="path1518" class="st6" d="M238.8,122.6c2.3-14.8,12.3-27.2,26.2-32.4c20-7.5,43,2.3,51.4,22c2.6,6.1,3.5,8,3.5,15.7
c0,6.5-0.6,7.9-1.6,11.3c-4.4,14.4-14.9,24.6-29.4,28.6c-2.9,0.8-5.2,1.1-10.7,1.1c-5.5,0-6.2-0.3-9-1.1
c-17.7-4.8-29.9-20-30.5-38.1C238.5,127.1,238.6,124,238.8,122.6L238.8,122.6L238.8,122.6z M250.8,134.7
c2.6,11.9,13,21.3,25.1,22.5c21.5,2.2,37.7-18.1,30.7-38.5c-1.4-4.2-3.3-7-7.1-10.8c-2.8-2.8-4.1-3.8-7.2-5.3
c-5.1-2.6-8.7-3.3-14.6-3c-6.8,0.3-11.7,2.2-16.9,6.3C252.4,112.5,248.4,124,250.8,134.7L250.8,134.7L250.8,134.7z"/>
<path id="path1520" class="st7" d="M286.1,4.8c0.8-1.3,0.9-2.3,5.3-2.5c4.3-0.2,13.5,0.1,32.6,0.1c32.8,0,35.2-0.5,36.3,0.6
c0.1,0.1,0.2,0.1,0.2,0.2c1.5,1.1,2.1,2.7,2.1,4.9v1.9h-77.3v-2C285.4,6.6,285.7,5.5,286.1,4.8L286.1,4.8L286.1,4.8z"/>
<path id="path1522" class="st7" d="M688.3,6.2c0.1-0.5,0.4-1.3,0.8-1.8c0.5-0.8,0.8-1.5,2.7-1.8c3.2-0.5,11.4-0.2,35.1-0.2
c19.3,0,28.3-0.5,32.5-0.4c2.7,0.1,3.2,0.8,3.6,1c1.6,0.9,2.3,2.4,2.3,4.8v2.1h-77.3l0-1.4C688.1,7.7,688.2,6.7,688.3,6.2
L688.3,6.2L688.3,6.2z"/>
<path id="path1524" class="st8" d="M874,334.6c20.6-10.1,37.2-21.9,53.9-38.2c35.7-34.8,57-78.7,63.1-129.7
c0.6-5.1,0.8-13.1,1-40.9l0.2-34.6h1.4c1,0,3,0,3.7,1.4l1.1,2.1l-0.2,30.4c-0.1,16.9-0.2,33.5-0.5,37
c-3.9,50.8-24.6,97.1-59.5,133.3c-16.9,17.6-35.7,31.5-57.9,42.8c-8.4,4.3-10.1,4.9-11.8,4.2c-1.1-0.4-4.2-2.7-4.1-3.2
C864.4,339.2,869,337.1,874,334.6L874,334.6L874,334.6z"/>
<path id="path1530" class="st4" d="M96.7,3.4c0.5-0.6,1.2-1.7,5-1.6c6.7,0.3,27.2-0.2,79.1-0.1L263.4,2l6.5,2.6l15,7.9l39.4,0.1
l39.6-0.4l13.2-7.1l7.7-2.9l7.3-0.4l48,0.1l22.1-0.1l34.1,0.1l10.5,0.1h10.5l8.6-0.1l25.6,0h19.4l27.5-0.2L620,1.8l11,0l19.6,0.1
l10.2,0l5.7,0.5l5.8,1.9l5.5,3l9.8,5.3h39.5l39.6-0.4l9.8-5.3l5.3-2.7l5.1-1.8l7.6-0.7l13.3,0.2l12.2-0.1h11.1l10.9,0l9.9,0h6.5
l2.9,0l17.4,0.1l21.5,0h10.8l8.4-0.1l5.1,0l5.9-0.2l3.1,2.2l1.1,3.2l-0.1,3.2c0,1.4-0.1,2.7-0.2,3.9c-0.1,0.9-0.1,1.8-0.4,2.6
c-0.4,1-1,1.7-1.3,2c-0.2,0.2-1.7,1.2-4.8,1.3c-2.1,0.1-4.7,0-8.3,0c-4.1,0-9.7,0.1-16.4,0c-10-0.1-23.1,0-40.4-0.1
c-13.2,0-28.7,0.2-47,0.1c-62.8-0.2-158-0.2-301-0.2L98.7,20l-1.8-1.3C94.3,16.9,94,6.1,96.7,3.4L96.7,3.4L96.7,3.4z"/>
<path id="path1532" class="st4" d="M535.4,22.4h392.4V31H143v-8.6H535.4L535.4,22.4z"/>
<ellipse id="path3879" class="st9" cx="279.4" cy="128.2" rx="40.3" ry="40.3"/>
<ellipse id="path3881" class="st10" cx="279.1" cy="128.2" rx="34.5" ry="34.1"/>
<path id="path96" d="M306.1,128.3l-26.4-26.8v7.7h-22.5v38.5h22.5v7.2L306.1,128.3L306.1,128.3z M265.2,136.1v-15.2h14.5v15.2
H265.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 996.25 690.92">
<defs>
<style>
.cls-1 {
stroke: #fff;
stroke-miterlimit: 10;
stroke-width: 2px;
}
.cls-1, .cls-2 {
fill: #444542;
}
.cls-3 {
fill: #3b3b3b;
}
.cls-3, .cls-4, .cls-2, .cls-5, .cls-6, .cls-7 {
stroke-width: 0px;
}
.cls-4 {
fill: #3b3c3a;
}
.cls-5 {
fill: #454644;
}
.cls-6 {
fill: #20221f;
}
.cls-7 {
fill: #121212;
}
</style>
</defs>
<g id="Front">
<path id="Right_Grip" data-name="Right Grip" class="cls-6" d="m739.17,492.09c34,28.2,27.6,35.9,68.5,108.5,36.7,74.7,64.4,104.4,125.1,84.1h0c95.3-57.9,59.3-145.3,43.6-275.2-10-60.6-35.6-190.3-35.6-190.3l-201.6,272.9Z"/>
<path id="Left_Grip" data-name="Left Grip" class="cls-6" d="m55.47,219.19s-25.6,129.7-35.6,190.3c-15.7,129.9-51.7,217.2,43.6,275.1h0c60.8,20.3,88.4-9.4,125.1-84.1,40.9-72.7,34.5-80.3,68.5-108.5L55.47,219.19Z"/>
<path id="Right_Bumper" data-name="Right Bumper" class="cls-3" d="m649.47,19.99c10.1-4.3,39.7-22.5,58.7-19.7,59.5.9,166.7,17.7,172.6,81.2"/>
<path id="Left_Bumper" data-name="Left Bumper" class="cls-3" d="m115.57,81.49C121.47,18.09,228.57,1.29,288.17.29c19-2.8,48.6,15.4,58.7,19.7"/>
<path id="Background" class="cls-7" d="m739.17,492.09c35.5-30.8,68.5-74.7,96-113.5,26.9-36.3,94.7-136.7,105.6-159.3,0-2.4-6.3-30.1-12.8-56.2C892.27,3.49,675.37,19.69,498.17,19.69S104.07,3.49,68.27,162.99c-6.5,26-12.8,53.8-12.8,56.2,10.9,22.6,78.8,123,105.6,159.3,27.5,38.8,60.5,82.8,96,113.5"/>
<g id="Directional_Pad" data-name="Directional Pad">
<path id="Background-2" data-name="Background" class="cls-2" d="m439.37,325.09h-40c-2.8,0-5-2.2-5-5v-40c0-2.8-2.2-5-5-5h-30c-2.8,0-5,2.2-5,5v40c0,2.8-2.2,5-5,5h-40c-2.8,0-5,2.2-5,5v30c0,2.8,2.2,5,5,5h40c2.8,0,5,2.2,5,5v40c0,2.8,2.2,5,5,5h30c2.8,0,5-2.2,5-5v-40c0-2.8,2.2-5,5-5h40c2.8,0,5-2.2,5-5v-30c0-2.7-2.2-5-5-5Z"/>
</g>
<g id="R_Thumbstick" data-name="R Thumbstick">
<circle id="Background-3" data-name="Background" class="cls-6" cx="623.77" cy="345.09" r="55"/>
<circle id="Stick" class="cls-1" cx="623.77" cy="345.09" r="45"/>
</g>
<g id="L_Thumbstick" data-name="L Thumbstick">
<circle id="Background-4" data-name="Background" class="cls-6" cx="213.37" cy="206.39" r="55"/>
<circle id="Stick-2" data-name="Stick" class="cls-1" cx="213.37" cy="206.39" r="45" transform="translate(-24.53 383.95) rotate(-80.78)"/>
</g>
<g id="Minus_Button" data-name="Minus Button">
<circle id="_Background" data-name=" Background" class="cls-5" cx="374.17" cy="130.89" r="22.5"/>
</g>
<g id="Plus_Button" data-name="Plus Button">
<circle id="_Background-2" data-name=" Background" class="cls-5" cx="623.57" cy="131.19" r="22.5"/>
</g>
<g id="Home_Button" data-name="Home Button">
<circle id="_Background-3" data-name=" Background" class="cls-5" cx="578.57" cy="206.39" r="22.5"/>
</g>
<g id="Capture_Button" data-name="Capture Button">
<path class="cls-5" d="m441.77,228.09h-30c-2.8,0-5-2.2-5-5v-29.5c0-2.8,2.2-5,5-5h30c2.8,0,5,2.2,5,5v29.5c0,2.7-2.2,5-5,5Z"/>
</g>
<g id="Buttons">
<g id="A_Button" data-name="A Button">
<circle id="Background-5" data-name="Background" class="cls-4" cx="837.07" cy="206.39" r="35"/>
</g>
<g id="X_Button" data-name="X Button">
<circle id="Background-6" data-name="Background" class="cls-4" cx="767.07" cy="136.39" r="35"/>
</g>
<g id="Y_Button" data-name="Y Button">
<circle id="Background-7" data-name="Background" class="cls-4" cx="697.07" cy="206.39" r="35"/>
</g>
<g id="B_Button" data-name="B Button">
<circle id="Background-8" data-name="Background" class="cls-4" cx="767.07" cy="276.39" r="35"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -549,9 +549,10 @@
"SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only",
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
"SoftwareKeyboardModeASCII": "Must be ASCII text only",
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
"DialogControllerAppletDockModeSet": "Docked mode set. Handheld is also invalid.\n\n",
"ControllerAppletControllers": "Supported Controllers:",
"ControllerAppletPlayers": "Players:",
"ControllerAppletDescription": "Your current configuration is invalid. Open settings and reconfigure your inputs.",
"ControllerAppletDocked": "Docked mode set. Handheld control should be disabled.",
"UpdaterRenaming": "Renaming Old Files...",
"UpdaterRenameFailed": "Updater was unable to rename file: {0}",
"UpdaterAddingFiles": "Adding New Files...",

View File

@ -16,8 +16,10 @@ namespace Ryujinx.Ava.Common.Locale
private readonly Dictionary<LocaleKeys, string> _localeStrings;
private Dictionary<LocaleKeys, string> _localeDefaultStrings;
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
private string _localeLanguageCode;
public static LocaleManager Instance { get; } = new();
public event Action LocaleChanged;
public LocaleManager()
{
@ -104,6 +106,15 @@ namespace Ryujinx.Ava.Common.Locale
}
}
public bool IsRTL()
{
return _localeLanguageCode switch
{
"he_IL" => true,
_ => false
};
}
public string UpdateAndGetDynamicValue(LocaleKeys key, params object[] values)
{
_dynamicValues[key] = values;
@ -124,6 +135,9 @@ namespace Ryujinx.Ava.Common.Locale
{
this[item.Key] = item.Value;
}
_localeLanguageCode = languageCode;
LocaleChanged?.Invoke();
}
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode = DefaultLanguageCode)

View File

@ -119,6 +119,7 @@
<None Remove="Assets\Locales\en_US.json" />
<None Remove="Assets\Locales\es_ES.json" />
<None Remove="Assets\Locales\fr_FR.json" />
<None Remove="Assets\Locales\he_IL.json" />
<None Remove="Assets\Locales\de_DE.json" />
<None Remove="Assets\Locales\it_IT.json" />
<None Remove="Assets\Locales\ja_JP.json" />
@ -132,6 +133,10 @@
<None Remove="Assets\Locales\zh_TW.json" />
<None Remove="Assets\Styles\Styles.xaml" />
<None Remove="Assets\Styles\Themes.xaml" />
<None Remove="Assets\Icons\Controller_JoyConLeft.svg" />
<None Remove="Assets\Icons\Controller_JoyConPair.svg" />
<None Remove="Assets\Icons\Controller_JoyConRight.svg" />
<None Remove="Assets\Icons\Controller_ProCon.svg" />
</ItemGroup>
<ItemGroup>
@ -139,6 +144,7 @@
<EmbeddedResource Include="Assets\Locales\en_US.json" />
<EmbeddedResource Include="Assets\Locales\es_ES.json" />
<EmbeddedResource Include="Assets\Locales\fr_FR.json" />
<EmbeddedResource Include="Assets\Locales\he_IL.json" />
<EmbeddedResource Include="Assets\Locales\de_DE.json" />
<EmbeddedResource Include="Assets\Locales\it_IT.json" />
<EmbeddedResource Include="Assets\Locales\ja_JP.json" />
@ -151,6 +157,10 @@
<EmbeddedResource Include="Assets\Locales\zh_CN.json" />
<EmbeddedResource Include="Assets\Locales\zh_TW.json" />
<EmbeddedResource Include="Assets\Styles\Styles.xaml" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConLeft.svg" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
<EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="Assets\Locales\en_US.json" />

View File

@ -29,14 +29,24 @@ namespace Ryujinx.Ava.UI.Applet
public bool DisplayMessageDialog(ControllerAppletUiArgs args)
{
string message = LocaleManager.Instance.UpdateAndGetDynamicValue(
args.PlayerCountMin == args.PlayerCountMax ? LocaleKeys.DialogControllerAppletMessage : LocaleKeys.DialogControllerAppletMessagePlayerRange,
args.PlayerCountMin == args.PlayerCountMax ? args.PlayerCountMin.ToString() : $"{args.PlayerCountMin}-{args.PlayerCountMax}",
args.SupportedStyles,
string.Join(", ", args.SupportedPlayers),
args.IsDocked ? LocaleManager.Instance[LocaleKeys.DialogControllerAppletDockModeSet] : "");
ManualResetEvent dialogCloseEvent = new(false);
return DisplayMessageDialog(LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle], message);
bool okPressed = false;
Dispatcher.UIThread.InvokeAsync(async () =>
{
var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args);
if (response == UserResult.Ok)
{
okPressed = true;
}
dialogCloseEvent.Set();
});
dialogCloseEvent.WaitOne();
return okPressed;
}
public bool DisplayMessageDialog(string title, string message)
@ -75,6 +85,8 @@ namespace Ryujinx.Ava.UI.Applet
await _parent.SettingsWindow.ShowDialog(window);
_parent.SettingsWindow = null;
opened = false;
});

View File

@ -0,0 +1,145 @@
<UserControl
x:Class="Ryujinx.Ava.UI.Applet.ControllerAppletDialog"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:applet="using:Ryujinx.Ava.UI.Applet"
mc:Ignorable="d"
Width="400"
Focusable="True"
x:DataType="applet:ControllerAppletDialog">
<Grid
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="2"
Margin="0 0 0 10"
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5">
<StackPanel
Spacing="10"
Margin="10">
<TextBlock
Text="{locale:Locale ControllerAppletDescription}" />
<TextBlock
IsVisible="{Binding IsDocked}"
FontWeight="Bold"
Text="{locale:Locale ControllerAppletDocked}" />
</StackPanel>
</Border>
<Border
Grid.Column="0"
Grid.Row="1"
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5"
Margin="0 0 10 0">
<StackPanel
Margin="10"
Spacing="10"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
FontWeight="Bold"
Text="{locale:Locale ControllerAppletControllers}" />
<StackPanel
Spacing="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<Image
Height="50"
Width="50"
Stretch="Uniform"
Source="{Binding ProControllerImage}"
IsVisible="{Binding SupportsProController}" />
<Image
Height="50"
Width="50"
Stretch="Uniform"
Source="{Binding JoyconPairImage}"
IsVisible="{Binding SupportsJoyconPair}" />
<Image
Height="50"
Width="50"
Stretch="Uniform"
Source="{Binding JoyconLeftImage}"
IsVisible="{Binding SupportsLeftJoycon}" />
<Image
Height="50"
Width="50"
Stretch="Uniform"
Source="{Binding JoyconRightImage}"
IsVisible="{Binding SupportsRightJoycon}" />
</StackPanel>
</StackPanel>
</Border>
<Border
Grid.Column="1"
Grid.Row="1"
BorderBrush="{DynamicResource ThemeControlBorderColor}"
BorderThickness="1"
CornerRadius="5">
<StackPanel
Margin="10"
Spacing="10"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
FontWeight="Bold"
Text="{locale:Locale ControllerAppletPlayers}" />
<Border Height="50">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
FontSize="40"
FontWeight="Thin"
Text="{Binding PlayerCount}" />
</Border>
</StackPanel>
</Border>
<Panel
Margin="0 24 0 0"
Grid.Column="0"
Grid.Row="2"
Grid.ColumnSpan="2">
<StackPanel
Orientation="Horizontal"
Spacing="10"
HorizontalAlignment="Right">
<Button
Name="SaveButton"
MinWidth="90"
Command="{Binding OpenSettingsWindow}">
<TextBlock Text="{locale:Locale DialogOpenSettingsWindowLabel}" />
</Button>
<Button
Name="CancelButton"
MinWidth="90"
Command="{Binding Close}">
<TextBlock Text="{locale:Locale SettingsButtonClose}" />
</Button>
</StackPanel>
</Panel>
</Grid>
</UserControl>

View File

@ -0,0 +1,139 @@
using Avalonia.Controls;
using Avalonia.Styling;
using Avalonia.Svg.Skia;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Services.Hid;
using System.Linq;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Applet
{
internal partial class ControllerAppletDialog : UserControl
{
private const string ProControllerResource = "Ryujinx.Ava/Assets/Icons/Controller_ProCon.svg";
private const string JoyConPairResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConPair.svg";
private const string JoyConLeftResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConLeft.svg";
private const string JoyConRightResource = "Ryujinx.Ava/Assets/Icons/Controller_JoyConRight.svg";
public static SvgImage ProControllerImage => GetResource(ProControllerResource);
public static SvgImage JoyconPairImage => GetResource(JoyConPairResource);
public static SvgImage JoyconLeftImage => GetResource(JoyConLeftResource);
public static SvgImage JoyconRightImage => GetResource(JoyConRightResource);
public string PlayerCount { get; set; } = "";
public bool SupportsProController { get; set; }
public bool SupportsLeftJoycon { get; set; }
public bool SupportsRightJoycon { get; set; }
public bool SupportsJoyconPair { get; set; }
public bool IsDocked { get; set; }
private readonly MainWindow _mainWindow;
public ControllerAppletDialog(MainWindow mainWindow, ControllerAppletUiArgs args)
{
if (args.PlayerCountMin == args.PlayerCountMax)
{
PlayerCount = args.PlayerCountMin.ToString();
}
else
{
PlayerCount = $"{args.PlayerCountMin} - {args.PlayerCountMax}";
}
SupportsProController = (args.SupportedStyles & ControllerType.ProController) != 0;
SupportsLeftJoycon = (args.SupportedStyles & ControllerType.JoyconLeft) != 0;
SupportsRightJoycon = (args.SupportedStyles & ControllerType.JoyconRight) != 0;
SupportsJoyconPair = (args.SupportedStyles & ControllerType.JoyconPair) != 0;
IsDocked = args.IsDocked;
_mainWindow = mainWindow;
DataContext = this;
InitializeComponent();
}
public ControllerAppletDialog(MainWindow mainWindow)
{
_mainWindow = mainWindow;
DataContext = this;
InitializeComponent();
}
public static async Task<UserResult> ShowControllerAppletDialog(MainWindow window, ControllerAppletUiArgs args)
{
ContentDialog contentDialog = new();
UserResult result = UserResult.Cancel;
ControllerAppletDialog content = new(window, args);
contentDialog.Title = LocaleManager.Instance[LocaleKeys.DialogControllerAppletTitle];
contentDialog.Content = content;
void Handler(ContentDialog sender, ContentDialogClosedEventArgs eventArgs)
{
if (eventArgs.Result == ContentDialogResult.Primary)
{
result = UserResult.Ok;
}
}
contentDialog.Closed += Handler;
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
contentDialog.Styles.Add(bottomBorder);
await ContentDialogHelper.ShowAsync(contentDialog);
return result;
}
private static SvgImage GetResource(string path)
{
SvgImage image = new();
if (!string.IsNullOrWhiteSpace(path))
{
SvgSource source = new();
source.Load(EmbeddedResources.GetStream(path));
image.Source = source;
}
return image;
}
public void OpenSettingsWindow()
{
if (_mainWindow.SettingsWindow == null)
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
_mainWindow.SettingsWindow = new SettingsWindow(_mainWindow.VirtualFileSystem, _mainWindow.ContentManager);
_mainWindow.SettingsWindow.NavPanel.Content = _mainWindow.SettingsWindow.InputPage;
_mainWindow.SettingsWindow.NavPanel.SelectedItem = _mainWindow.SettingsWindow.NavPanel.MenuItems.ElementAt(1);
await ContentDialogHelper.ShowWindowAsync(_mainWindow.SettingsWindow, _mainWindow);
_mainWindow.SettingsWindow = null;
this.Close();
});
}
}
public void Close()
{
((ContentDialog)Parent)?.Hide();
}
}
}

View File

@ -86,17 +86,17 @@
HorizontalAlignment="Stretch"
FontWeight="Bold"
Text="{Binding TitleName}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding Developer}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding Version}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
</StackPanel>
</Border>
@ -110,12 +110,12 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding TitleId}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding FileExtension}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
</StackPanel>
<StackPanel
@ -127,17 +127,17 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding TimePlayedString}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding LastPlayedString, Converter={helpers:LocalizedNeverConverter}}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding FileSizeString}"
TextAlignment="Right"
TextAlignment="End"
TextWrapping="Wrap" />
</StackPanel>
<ui:SymbolIcon

View File

@ -18,6 +18,7 @@ namespace Ryujinx.Ava.UI.Helpers
public static class ContentDialogHelper
{
private static bool _isChoiceDialogOpen;
private static ContentDialogOverlayWindow _contentDialogOverlayWindow;
private async static Task<UserResult> ShowContentDialog(
string title,
@ -310,16 +311,20 @@ namespace Ryujinx.Ava.UI.Helpers
public static async Task<ContentDialogResult> ShowAsync(ContentDialog contentDialog)
{
ContentDialogResult result;
ContentDialogOverlayWindow contentDialogOverlayWindow = null;
bool isTopDialog = true;
Window parent = GetMainWindow();
if (_contentDialogOverlayWindow != null)
{
isTopDialog = false;
}
if (parent is MainWindow window)
{
parent.Activate();
contentDialogOverlayWindow = new()
_contentDialogOverlayWindow = new ContentDialogOverlayWindow
{
Height = parent.Bounds.Height,
Width = parent.Bounds.Width,
@ -331,14 +336,14 @@ namespace Ryujinx.Ava.UI.Helpers
void OverlayOnPositionChanged(object sender, PixelPointEventArgs e)
{
contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
_contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
}
contentDialogOverlayWindow.ContentDialog = contentDialog;
_contentDialogOverlayWindow.ContentDialog = contentDialog;
bool opened = false;
contentDialogOverlayWindow.Opened += OverlayOnActivated;
_contentDialogOverlayWindow.Opened += OverlayOnActivated;
async void OverlayOnActivated(object sender, EventArgs e)
{
@ -349,12 +354,12 @@ namespace Ryujinx.Ava.UI.Helpers
opened = true;
contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
_contentDialogOverlayWindow.Position = parent.PointToScreen(new Point());
result = await ShowDialog();
}
result = await contentDialogOverlayWindow.ShowDialog<ContentDialogResult>(parent);
result = await _contentDialogOverlayWindow.ShowDialog<ContentDialogResult>(parent);
}
else
{
@ -363,11 +368,11 @@ namespace Ryujinx.Ava.UI.Helpers
async Task<ContentDialogResult> ShowDialog()
{
if (contentDialogOverlayWindow is not null)
if (_contentDialogOverlayWindow is not null)
{
result = await contentDialog.ShowAsync(contentDialogOverlayWindow);
result = await contentDialog.ShowAsync(_contentDialogOverlayWindow);
contentDialogOverlayWindow!.Close();
_contentDialogOverlayWindow!.Close();
}
else
{
@ -379,15 +384,22 @@ namespace Ryujinx.Ava.UI.Helpers
return result;
}
if (contentDialogOverlayWindow is not null)
if (isTopDialog && _contentDialogOverlayWindow is not null)
{
contentDialogOverlayWindow.Content = null;
contentDialogOverlayWindow.Close();
_contentDialogOverlayWindow.Content = null;
_contentDialogOverlayWindow.Close();
}
return result;
}
public static Task ShowWindowAsync(Window dialogWindow, Window mainWindow = null)
{
mainWindow ??= GetMainWindow();
return dialogWindow.ShowDialog(_contentDialogOverlayWindow ?? mainWindow);
}
private static Window GetMainWindow()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime al)

View File

@ -1,11 +1,12 @@
<UserControl
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="800"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Renderer.RendererHost"
FlowDirection="LeftToRight"
Focusable="True">
</UserControl>
</UserControl>

View File

@ -17,6 +17,7 @@ using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.ViewModels
@ -188,17 +189,25 @@ namespace Ryujinx.Ava.UI.ViewModels
_httpClient.Dispose();
}
private bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
{
if (string.IsNullOrEmpty(json))
{
amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
return false;
}
try
{
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(json, _serializerContext.AmiiboJson);
amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson);
return true;
}
catch
catch (JsonException exception)
{
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}");
amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
return false;
}
@ -208,27 +217,41 @@ namespace Ryujinx.Ava.UI.ViewModels
{
bool localIsValid = false;
bool remoteIsValid = false;
AmiiboJson amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
AmiiboJson amiiboJson = new();
try
{
localIsValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
try
{
if (File.Exists(_amiiboJsonPath))
{
localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson);
}
}
catch (Exception exception)
{
Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
}
if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
{
remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
}
}
catch
catch (Exception exception)
{
if (!(localIsValid || remoteIsValid))
{
Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
// Neither local or remote files are valid JSON, close window.
ShowInfoDialog();
Close();
}
else if (!remoteIsValid)
{
Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}");
// Only the local file is valid, the local one should be used
// but the user should be warned.
ShowInfoDialog();
@ -388,11 +411,18 @@ namespace Ryujinx.Ava.UI.ViewModels
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
{
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
if (response.IsSuccessStatusCode)
try
{
return response.Content.Headers.LastModified != oldLastModified;
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
if (response.IsSuccessStatusCode)
{
return response.Content.Headers.LastModified != oldLastModified;
}
}
catch (HttpRequestException exception)
{
Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}");
}
return false;
@ -400,21 +430,33 @@ namespace Ryujinx.Ava.UI.ViewModels
private async Task<string> DownloadAmiiboJson()
{
HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
if (response.IsSuccessStatusCode)
try
{
string amiiboJsonString = await response.Content.ReadAsStringAsync();
HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
using (FileStream amiiboJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough))
if (response.IsSuccessStatusCode)
{
amiiboJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
string amiiboJsonString = await response.Content.ReadAsStringAsync();
try
{
using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough);
dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
}
catch (Exception exception)
{
Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'");
}
return amiiboJsonString;
}
return amiiboJsonString;
Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
}
catch (HttpRequestException exception)
{
Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}");
}
Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
LocaleManager.Instance[LocaleKeys.DialogAmiiboApiFailFetchMessage],
@ -422,9 +464,7 @@ namespace Ryujinx.Ava.UI.ViewModels
"",
LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
Close();
return DefaultJson;
return null;
}
private void Close()

View File

@ -115,7 +115,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS();
public bool IsHypervisorAvailable => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
public bool IsHypervisorAvailable => RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
public bool DirectoryChanged
{

View File

@ -101,7 +101,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
SelectedIndex="0"
ItemsSource="{Binding ProfilesList}"
ItemsSource="{Binding ProfilesList}"
Text="{Binding ProfileName, Mode=TwoWay}" />
<Button
Grid.Column="2"
@ -218,6 +218,7 @@
<Grid
Name="SettingButtons"
MinHeight="450"
FlowDirection="LeftToRight"
IsVisible="{Binding ShowSettings}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />

View File

@ -122,6 +122,8 @@ namespace Ryujinx.Ava.UI.Views.Main
await Window.SettingsWindow.ShowDialog(Window);
Window.SettingsWindow = null;
ViewModel.LoadConfigurableHotKeys();
}

View File

@ -88,7 +88,7 @@
IsVisible="{Binding !ShowLoadProgress}"
PointerReleased="VsyncStatus_PointerReleased"
Text="VSync"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@ -105,7 +105,7 @@
IsVisible="{Binding !ShowLoadProgress}"
PointerReleased="DockedStatus_PointerReleased"
Text="{Binding DockedStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@ -225,7 +225,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GameStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@ -240,7 +240,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding FifoStatusText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@ -255,7 +255,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding BackendText}"
TextAlignment="Left" />
TextAlignment="Start" />
<Border
Width="2"
Height="12"
@ -270,7 +270,7 @@
VerticalAlignment="Center"
IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GpuNameText}"
TextAlignment="Left" />
TextAlignment="Start" />
</StackPanel>
<StackPanel
Grid.Column="3"

View File

@ -27,7 +27,7 @@
Grid.Row="0"
TextWrapping="Wrap"
HorizontalAlignment="Left"
TextAlignment="Left"
TextAlignment="Start"
Text="{locale:Locale ProfileImageSelectionNote}" />
<StackPanel
Grid.Row="2"
@ -59,4 +59,4 @@
</Button>
</StackPanel>
</Grid>
</UserControl>
</UserControl>

View File

@ -49,7 +49,7 @@
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding UserId}"
TextAlignment="Left"
TextAlignment="Start"
TextWrapping="Wrap" />
<Button Grid.Column="1"
HorizontalAlignment="Right"
@ -79,4 +79,4 @@
</Button>
</StackPanel>
</Grid>
</UserControl>
</UserControl>

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