Compare commits

...

164 Commits

Author SHA1 Message Date
LotP
a60b2a0ba3 Memory changes 2.2 (ryubing/ryujinx!143)
See merge request ryubing/ryujinx!143
2025-09-06 11:10:55 -05:00
Hack茶ん
4c9b48b754 Update Korean translation (ryubing/ryujinx!141)
See merge request ryubing/ryujinx!141
2025-09-05 13:06:59 -05:00
Neo
3bd7d5904e Compat: New Entries + Minor Adjustments (ryubing/ryujinx!140)
See merge request ryubing/ryujinx!140
2025-09-05 03:50:49 -05:00
GreemDev
23eb9a3043 improvement: Make the updater log a special error message in some cases
specifically about potentially not being connected to the internet on a connection error or name resolution error
2025-09-05 03:12:15 -05:00
GreemDev
931ec44406 [ci skip] fix: <Reset> text in Pokemon Scarlet/Violet play report rich presence 2025-09-05 03:02:16 -05:00
GreemDev
d68efa98ba [ci skip] Update NuGet packages 2025-09-05 02:25:05 -05:00
GreemDev
ded76801d1 removal: Installing keys from a zip
Also cleaned up a bit
2025-09-04 19:04:50 -05:00
GreemDev
6084df7473 Silksong compatibility entry and RPC image 2025-09-04 16:23:38 -05:00
LotP1
f3953c6039 Fix a crash when no controller is connected 2025-09-04 16:18:07 -05:00
LotP1
91f5247e7f add missing field 2025-09-04 16:17:59 -05:00
LotP1
5658402c6b fix spelling 2025-09-04 16:17:53 -05:00
LotP1
1b2c93e188 Add version comment 2025-09-04 16:14:38 -05:00
LotP1
9e599ff325 remove stub 2025-09-04 16:14:18 -05:00
LotP1
7a5f430b59 hle: Basic event handle implementation for IApplicationFunctions 210
Lets Hollow Knight: Silksong boot.
2025-09-04 16:14:03 -05:00
shinyoyo
1e340ce2f3 Update Simplified Chinese translation. (ryubing/ryujinx!139)
See merge request ryubing/ryujinx!139
2025-09-03 15:49:14 -05:00
WilliamWsyHK
dbb4e63e1e Update zh-TW translation (ryubing/ryujinx!130)
See merge request ryubing/ryujinx!130
2025-09-03 03:28:37 -05:00
Hack茶ん
d00ab52fa2 Update Korean translation (ryubing/ryujinx!138)
See merge request ryubing/ryujinx!138
2025-09-03 03:26:33 -05:00
VewDev
959af3613d doc: update documentation for Shared property in Switch class (ryubing/ryujinx!137)
See merge request ryubing/ryujinx!137
2025-09-03 03:25:43 -05:00
GreemDev
3309fb2351 chore: Replace dead URLs in the changelog with archive.org links (that I could find) 2025-09-03 00:49:30 -05:00
GreemDev
e1e8628a6f chore: remove BuildAndPushLibraries.sh 2025-09-03 00:25:08 -05:00
Neo
3969191605 UI: Menubar & Game Context Menu Updates (ryubing/ryujinx!134)
See merge request ryubing/ryujinx!134
2025-09-02 03:32:06 -05:00
Hack茶ん
07c7b39053 Update Korean translation (ryubing/ryujinx!136)
See merge request ryubing/ryujinx!136
2025-09-01 17:57:44 -05:00
Hack茶ん
053efaa414 Update Korean translation (ryubing/ryujinx!135)
See merge request ryubing/ryujinx!135
2025-09-01 01:36:27 -05:00
GreemDev
56e6339553 hle: cheats: Prevent NullRef and throw a TamperCompilationException instead
for null base instruction byte arrays on the current block in EndConditionalBlock
2025-08-31 23:06:42 -05:00
shinyoyo
042362ee2b Update Simplified Chinese translation. (ryubing/ryujinx!133)
See merge request ryubing/ryujinx!133
2025-08-30 22:40:05 -05:00
GreemDev
7347ee2212 [ci skip] chore: UI: Add localization key for LDN Game Viewer filters dropdown button heading 2025-08-30 22:13:38 -05:00
LotP
01a9b636af Memory changes 2.1 (ryubing/ryujinx!132)
See merge request ryubing/ryujinx!132
2025-08-30 20:30:17 -05:00
GreemDev
6e47d8548c feature: UI: LDN Games Viewer
This window can be accessed via "Help" menu in the title bar.
This menu's data is synced with the in-app-list LDN game data, and that has been modified to hide unjoinable games (in-progress and/or private (needing a passphrase)). You can still see these games in the list.
2025-08-30 19:54:00 -05:00
GreemDev
da340f5615 chore: remove redundant CloseWindow helper 2025-08-30 00:40:39 -05:00
GreemDev
be249f7bdc chore: move NFC tags URL to SharedConstants.cs 2025-08-30 00:35:16 -05:00
GreemDev
462c93e1ff fix key number 5 locale 2025-08-28 20:32:48 -05:00
Babib3l
573a6f32fe nullify + update spanish and french translations (ryubing/ryujinx!125)
See merge request ryubing/ryujinx!125
2025-08-28 13:28:24 -05:00
GreemDev
7846f58cad [ci skip] chore: Change LDN server URL (it's the same server, just a more official URL) 2025-08-27 22:49:51 -05:00
GreemDev
0203065fed ui: fix: Missing "Loading" text when shader cache is disabled and PPTC doesn't trigger 2025-08-27 22:35:09 -05:00
shinyoyo
7319a2dafc Nullify & update Simplified Chinese translation. (ryubing/ryujinx!124)
See merge request ryubing/ryujinx!124
2025-08-27 00:41:47 -05:00
Hack茶ん
f992735656 Nullify & Update Korean translation (ryubing/ryujinx!122)
See merge request ryubing/ryujinx!122
2025-08-27 00:40:11 -05:00
GreemDev
48b9f2ab93 docs: compat: High on Life: Menus 2025-08-26 20:12:36 -05:00
LotP
50ab108ee1 Memory Changes part 2 (ryubing/ryujinx!123)
See merge request ryubing/ryujinx!123
2025-08-25 17:44:15 -05:00
VewDev
d499449f57 feat(ui): improve Amiibo selection UX (ryubing/ryujinx!121)
See merge request ryubing/ryujinx!121
2025-08-25 05:14:06 -05:00
GreemDev
cd3c614021 fix: part 2: Resolve AppImage CI failures in Stable and Canary
This was done by adding the -n flag when running appimagetool.
Fix suggested by `settyness` on Discord.
2025-08-24 15:44:38 -05:00
GreemDev
5fa82bb1f5 fix: attempt at resolving AppImage CI failures 2025-08-24 15:35:11 -05:00
GreemDev
234cb99325 [ci skip] chore: minor nitpick: Use passed dlc IDs array instead of the field 2025-08-23 23:50:23 -05:00
GreemDev
ab7914f235 input: ava: Rename timer interval constant
Also cut the delay after which scrolling is considered ended in half
2025-08-19 19:39:18 -05:00
MaxLastBreath
3df6b7c0f5 Fix Avalonia Native MouseWheel-Support (ryubing/ryujinx!116)
See merge request ryubing/ryujinx!116
2025-08-19 18:46:20 -05:00
ProIcons
37e81481c4 Fix nn::ec::detail::PurchasedProductInfo to return No purchase information... (ryubing/ryujinx!114)
See merge request ryubing/ryujinx!114
2025-08-17 04:52:20 -05:00
shinyoyo
4d8b799763 Updated Simplified Chinese translation. (ryubing/ryujinx!104)
See merge request ryubing/ryujinx!104
2025-08-16 19:18:39 -05:00
WilliamWsyHK
cb786b7147 Update zh-TW translation after nullify locales to signify intention of using default en-US values (ryubing/ryujinx!85)
See merge request ryubing/ryujinx!85
2025-08-16 19:17:51 -05:00
Gab
2a308f50c0 Nullify french locales + updated translation (ryubing/ryujinx!87)
See merge request ryubing/ryujinx!87
2025-08-16 16:59:20 -05:00
Neo
b51c5cead6 Nullify + Update Russian Locales (ryubing/ryujinx!103)
See merge request ryubing/ryujinx!103
2025-08-13 05:00:22 -05:00
GreemDev
461c1f5342 UI: compat list: fix squished search box 2025-08-13 04:08:28 -05:00
Neo
cfea61b3a0 QUICK FIX: Compatibility Window Checkbox Spacing (ryubing/ryujinx!112)
See merge request ryubing/ryujinx!112
2025-08-13 03:53:58 -05:00
Neo
ae2e9a73ab UI Updates Batch 2 (ryubing/ryujinx!105)
See merge request ryubing/ryujinx!105
2025-08-12 17:45:24 -05:00
GreemDev
c6f22318a7 add an ASCII header at startup in the log 2025-08-11 18:06:53 -05:00
GreemDev
dd5e1b99b1 remove localization entries for auto graphics backend 2025-08-11 18:00:10 -05:00
Hack茶ん
c863ffd353 Update Korean translation (ryubing/ryujinx!107)
See merge request ryubing/ryujinx!107
2025-08-10 16:37:14 -05:00
LotP
d6d089b81b Revert "Fix crash caused by VirtualRange mismatch (ryubing/ryujinx!109)" (ryubing/ryujinx!110)
See merge request ryubing/ryujinx!110
2025-08-09 18:41:36 -05:00
LotP
c482b7a1c0 Fix crash caused by VirtualRange mismatch (ryubing/ryujinx!109)
See merge request ryubing/ryujinx!109
2025-08-09 17:46:29 -05:00
在中国的泰国青年_
01e1cd4d5a update thai language in locales.json (ryubing/ryujinx!102)
See merge request ryubing/ryujinx!102
2025-08-08 04:34:56 -05:00
GreemDev
bb06eb751b Revert "fix: Super Mario Party Jamboree audio renderer crashing"
This reverts commit c0c021c7a9.

This commit was useless, and submitted by a GDKchan-obsessed chronically online lunatic who has disrespected the maintainers of this fork due to petty disagreements of how we run our Discord server. This is my parting gift to you: Stay gone. I'd prefer this code the way it was, because then you didn't touch it.

For the record, this commit is literally useless. The behavioral outcome is functionally identical to before the commit.
2025-08-06 18:43:31 -05:00
LotP
5613d3f35d Memory Changes (ryubing/ryujinx!46)
See merge request ryubing/ryujinx!46
2025-08-06 15:57:08 -05:00
Coxxs
54d4d184f4 gdb: Improve stepping (ryubing/ryujinx!106)
See merge request ryubing/ryujinx!106
2025-08-05 14:51:51 -05:00
Coxxs
d22756f1bd Add GDB Stub (ryubing/ryujinx!71)
See merge request ryubing/ryujinx!71
2025-08-04 20:45:15 -05:00
Neo
324f18aa5f Tooltip Fix Pt.4 (ryubing/ryujinx!101)
See merge request ryubing/ryujinx!101
2025-08-03 04:39:56 -05:00
Neo
31870707cf Tooltip Fix Pt.3 (ryubing/ryujinx!96)
See merge request ryubing/ryujinx!96
2025-08-02 20:30:54 -05:00
Hack茶ん
fd6648e30a Update Korean translation (ryubing/ryujinx!100)
See merge request ryubing/ryujinx!100
2025-08-02 20:29:50 -05:00
Neo
bc6be4e088 Other Tooltips Pt.2 (ryubing/ryujinx!95)
See merge request ryubing/ryujinx!95
2025-08-02 05:01:59 -05:00
Neo
64a6494d90 GameListContext Menu Tooltips (ryubing/ryujinx!94)
See merge request ryubing/ryujinx!94
2025-08-02 04:51:32 -05:00
Neo
ddb8afa6f4 Edit compatibility.csv (ryubing/ryujinx!88)
See merge request ryubing/ryujinx!88
2025-08-02 04:33:29 -05:00
Neo
c2f4118b1f Minor locales.json Adjustments (ryubing/ryujinx!91)
See merge request ryubing/ryujinx!91
2025-08-02 04:21:52 -05:00
GreemDev
47aa2c1513 Comment AppImage builds
It randomly started erroring in GitHub actions with exit code 8 but only sometimes, and I don't have the patience to debug it. I don't even use linux lol
2025-07-28 19:34:21 -05:00
LotP
f3a2f59683 Nullify Locales (ryubing/ryujinx!83)
See merge request ryubing/ryujinx!83
2025-07-28 18:24:35 -05:00
Rondo
51bcb9e128 Changes to uk_UA (ryubing/ryujinx!84)
See merge request ryubing/ryujinx!84
2025-07-28 15:55:48 -05:00
Daenorth
dce5f0eb55 Edit TileIDs.cs (ryubing/ryujinx!81)
See merge request ryubing/ryujinx!81
2025-07-24 13:04:22 -05:00
Daenorth
f2eb3749f9 Edit compatibility.csv (ryubing/ryujinx!80)
See merge request ryubing/ryujinx!80
2025-07-24 06:48:56 -05:00
GreemDev
45b2e613cf Update Ryujinx.LibHac
This should fix crashes with mods that worked on Ryubing 1.3.1.

Thanks @cyphix!

e39169ab50
2025-07-20 03:29:01 -05:00
Babib3l
932c480325 small translation update (ryubing/ryujinx!79)
See merge request ryubing/ryujinx!79
2025-07-16 14:02:26 -05:00
Godzilaa4
0e24435414 Updated Brazilian Portuguese translation. (ryubing/ryujinx!77)
See merge request ryubing/ryujinx!77
2025-06-30 20:21:14 -05:00
Babib3l
a5cf0482b4 Update to the french translation (ryubing/ryujinx!76)
See merge request ryubing/ryujinx!76
2025-06-30 13:45:29 -05:00
Neo
14e794af84 Update UI Icons (ryubing/ryujinx!75)
See merge request ryubing/ryujinx!75
2025-06-30 03:15:14 -05:00
GreemDev
29a02f4787 docs: compat: Risk of Rain Returns: Playable 2025-06-28 04:24:20 -05:00
GreemDev
e2f9d84b64 docs: Latest update redirect URL
GitLab does not offer a web-page view of the latest release like GitHub does, this is only available on the REST API.
As such, I added this functionality to the update server since it keeps track of what the latest version is for both release channels anyways.
2025-06-28 04:21:04 -05:00
Neo
0cc94fdf37 Update French Translation (ryubing/ryujinx!67)
See merge request ryubing/ryujinx!67
2025-06-23 14:50:47 -05:00
GreemDev
74a9b94227 UI: Properly space total play time separator when loading bar is shown. 2025-06-20 23:06:16 -05:00
GreemDev
d3208a4c44 UI: Don't show total play time if there is none. 2025-06-20 23:02:39 -05:00
Coxxs
5d136980a3 fix: UI deadlock when launching a game with "Trace Logs" enabled (ryubing/ryujinx!70)
See merge request ryubing/ryujinx!70
2025-06-19 20:51:11 -05:00
mqudsi
572ad1eac5 Exclude time spent with emulator paused from play time (ryubing/ryujinx!55)
See merge request ryubing/ryujinx!55
2025-06-19 16:33:10 -05:00
Coxxs
6bb2af0091 Implement CreateLibraryAppletEx in ILibraryAppletCreator (ryubing/ryujinx!69)
See merge request ryubing/ryujinx!69
2025-06-19 15:48:06 -05:00
WilliamWsyHK
534a194ed9 Correct typo on part of the character for word "server" (ryubing/ryujinx!68)
See merge request ryubing/ryujinx!68
2025-06-19 15:25:40 -05:00
GreemDev
331805791e infra: [ci skip] fix inconsistent namespaces from update library 2025-06-19 04:26:22 -05:00
GreemDev
6773406bb6 infra: Use Ryujinx.UpdateClient NuGet package for checking for updates.
Main benefit to this is sharing the C# model definitions from what the server returns and Ryujinx uses in-app without differences.
Additionally removed the GitHub API JSON models.
2025-06-19 04:18:33 -05:00
GreemDev
6226eadf55 docs: compat: The Legend of Nayuta: Boundless Trails: ingame (ryubing/ryujinx!59) 2025-06-18 14:31:08 -05:00
yeager
b1cde5fd97 Updated Swedish translation (ryubing/ryujinx!66)
See merge request ryubing/ryujinx!66
2025-06-17 13:05:39 -05:00
Hack茶ん
39944b2063 Update Korean translation (ryubing/ryujinx!64)
See merge request ryubing/ryujinx!64
2025-06-17 03:21:30 -05:00
GreemDev
973c6ba5df UI: RPC: Squeakross: Home Squeak Home image
docs: compat: Squeakross: Home Squeak Home: Playable
2025-06-16 02:06:45 -05:00
GreemDev
6803c91da8 infra: Add package source mappings for Ryujinx.UpdateClient to silence compile warnings 2025-06-16 02:05:11 -05:00
GreemDev
557c2a50b2 infra: Add NuGet config to solution items 2025-06-16 02:04:48 -05:00
GreemDev
77a797f154 Revert "Structural and Memory Safety Improvements, Analyzer Cleanup (ryubing/ryujinx!47)"
This reverts merge request !47
2025-06-15 20:45:26 -05:00
Emiyl
faf9e3cdd7 macOS: Fix MoltenVK config packing (ryubing/ryujinx!65)
See merge request ryubing/ryujinx!65
2025-06-15 18:24:45 -05:00
Godzilaa4
7bc80ed4fe Updated Brazilian Portuguese translation (ryubing/ryujinx!62)
See merge request ryubing/ryujinx!62
2025-06-15 10:28:41 -05:00
WilliamWsyHK
a1d44ec496 Update translation for Traditional Chinese (ryubing/ryujinx!61)
See merge request ryubing/ryujinx!61
2025-06-14 20:06:12 -05:00
GreemDev
bab3beb0ac [ci skip] Forgot closing / lol 2025-06-13 15:51:23 -05:00
GreemDev
aa9e74339b Add support for notifying the update server when a new update has been pushed instead of relying on periodic refreshes 2025-06-13 01:57:54 -05:00
GreemDev
908273d848 [ci skip] UpdateClient package source
https://git.ryujinx.app/ryubing/update-server/-/packages
2025-06-13 01:57:54 -05:00
shinyoyo
b51ad11574 Updated Simplified Chinese translation (ryubing/ryujinx!58)
See merge request ryubing/ryujinx!58
2025-06-11 19:43:50 -05:00
MrKev
ea027d65a7 Structural and Memory Safety Improvements, Analyzer Cleanup (ryubing/ryujinx!47)
See merge request ryubing/ryujinx!47
2025-06-11 17:58:27 -05:00
Coxxs
d03ae9c164 fix: socket blocking flag is inverted when setting it (ryubing/ryujinx!57)
See merge request ryubing/ryujinx!57
2025-06-11 16:44:07 -05:00
Hack茶ん
90e9492f6c Update Korean translation (ryubing/ryujinx!56)
See merge request ryubing/ryujinx!56
2025-06-11 15:37:48 -05:00
mqudsi
512120db04 Work around Escape hotkey race with exit confirmation dialog
See merge request ryubing/ryujinx!54
2025-06-10 22:52:08 -05:00
rockingdice
90582e9e93 fix: crash caused by cursor overflow
See merge request ryubing/ryujinx!53
2025-06-10 16:34:12 -05:00
rockingdice
b97fae08b5 fix: use the correct font family for CJK characters
See merge request ryubing/ryujinx!52
2025-06-10 15:41:39 -05:00
GreemDev
eed6ef632d infra: [ci skip] update CHANGELOG.md 2025-06-09 19:57:31 -05:00
GreemDev
0409c15903 Remove GitHub updater support. 2025-06-09 19:51:53 -05:00
GreemDev
c58272ac20 infra: CI: Remove GitHub release uploading from Stable workflow. 2025-06-09 18:56:28 -05:00
GreemDev
9d83dfd19c misc: [ci skip] Missed the property part of _chosenProfile 2025-06-09 17:59:40 -05:00
GreemDev
ce31a47934 misc: Code styling changes & cleanups 2025-06-09 17:57:26 -05:00
Goodfeat
d31d1f91cf Added the ability to switch between local and global input in the user configuration
See merge request ryubing/ryujinx!8
2025-06-09 17:24:24 -05:00
Goodfeat
ef02194a77 Update: Compatibility list
See merge request ryubing/ryujinx!29
2025-06-09 02:54:45 -05:00
Goodfeat
a16764d191 Moved "Graphics Backend Multitreading" item to Graphics API & Optimization section
See merge request ryubing/ryujinx!13
2025-06-09 02:37:49 -05:00
GreemDev
5108ab790f UI: RPC: [ci skip] Add BL2, BLTPS, and Minecraft Dungeons RPC images 2025-06-09 01:47:57 -05:00
GreemDev
71dc71fee8 infra: [ci skip] Remove duplicate GLI install in canary CI 2025-06-08 22:37:21 -05:00
GreemDev
c95bf748b2 infra: Update to Ryujinx.LibHac 0.20.0
This is identical to the previous version, it's just on NuGet.org so we can comment out the LibHacAlpha source in nuget.config.
2025-06-08 22:31:32 -05:00
GreemDev
b5e9acc50b misc: [ci skip] Cause GitHub fallback properly 2025-06-08 21:06:34 -05:00
GreemDev
e3fba4e32f docs: compat: further clarify the issue with 'FANTASY LIFE i: The Girl Who Steals Time' with 'crash' and 'vulkan-backend-bug' labels. 2025-06-08 20:44:01 -05:00
GreemDev
efa25d471e docs: compat: ingame: FANTASY LIFE i: The Girl Who Steals Time 2025-06-08 20:41:51 -05:00
GreemDev
b37aa61e47 infra: Remove GitHub uploading from Canary CI workflows 2025-06-08 17:55:36 -05:00
GreemDev
8feeb977b7 infra: [ci skip] fix canary changelog generation 2025-06-08 17:47:45 -05:00
GreemDev
b761a2c86d infra: Custom Update server instead of direct GitLab API calls
This reduces the amount of requests for an update from 3 if an update is needed, or 2 if not; to 1 if an update is needed, and none if an update is not. The difference comes from using this update server to check if an update is needed, and not GETing a snippet content for the release channels.
2025-06-08 17:37:34 -05:00
GreemDev
693837dca7 infra: [ci skip] make the canary release notes look nicer 2025-06-05 23:07:02 -05:00
GreemDev
70abff072b canary CI: checkout code before trying to get current revision 2025-06-05 20:56:17 -05:00
GreemDev
1e861b99a9 misc: Update LibHac
See merge request ryubing/libhac!3
2025-06-05 20:45:35 -05:00
GreemDev
13e404bde0 infra: [ci skip] Move tag creation to the end of the build process in CI 2025-06-05 01:57:21 -05:00
KeatonTheBot
04561a0cd3 Vulkan: Use compute shader for non-indirect unsupported topology index buffer conversions
See merge request ryubing/ryujinx!5
2025-06-05 01:19:44 -05:00
GreemDev
0652d7e740 misc: readme: stable and canary release channels from gitlab 2025-06-04 23:18:44 -05:00
GreemDev
f2aea4fb22 misc: [ci skip] fix typo in comment & rename CheckForUpdateAsync 2025-06-04 21:05:54 -05:00
GreemDev
3950e8adff infra: Embed milestone description in stable release description in CI 2025-06-04 21:05:35 -05:00
GreemDev
0e84f2b1f0 infra: Send a Discord webhook message when a new build is available 2025-06-04 04:31:58 -05:00
TheToid
051c794cc4 Use rcodesign for dylib signing where avaiilable and clear out all "._" files...
See merge request ryubing/ryujinx!14
2025-06-03 23:26:49 -05:00
LotP
053a9cb549 fix: use accurate length for enumerating
See merge request ryubing/ryujinx!49
2025-06-03 23:20:55 -05:00
GreemDev
d688fed7d2 missed the projects/ API endpoint part 2025-06-03 18:38:22 -05:00
GreemDev
8f5102aa2a infra: Add functionality to the CI to upload artifacts to this GitLab and make releases based on all files uploaded.
See merge request ryubing/ryujinx!48
2025-06-03 18:28:59 -05:00
GreemDev
379e9ab622 stable release test workflow for gitlab releases 2025-06-03 04:04:41 -05:00
LotP
af2575b40e Update LibHac
See merge request ryubing/ryujinx!45
2025-06-01 01:28:21 -05:00
MrKev
361d0c5632 Fix ~3500 analyser issues
See merge request ryubing/ryujinx!44
2025-05-30 17:08:34 -05:00
Hack茶ん
417df486b1 Update Korean translation
See merge request ryubing/ryujinx!43
2025-05-29 19:09:03 -05:00
GreemDev
813d05bdf7 misc: Remove internal release channel constants 2025-05-29 17:36:24 -05:00
GreemDev
3429361a5d UI: RPC: Remove release channel from RPC logo hover 2025-05-29 17:35:43 -05:00
GreemDev
92b2947f04 fix invalid link in canary release message & change stable too 2025-05-29 16:14:51 -05:00
GreemDev
4c281062ba test new canary release channel repo 2025-05-29 15:53:01 -05:00
GreemDev
84686d50cd Revert "PPTC: fix rare EndOfStreamException in ContainsBlacklistedFunctions"
This reverts commit 1156307ef9
2025-05-29 02:37:52 -05:00
GreemDev
81412c7dd5 misc: fix duplicated code (oops), reorder the commands in-code to match the UI 2025-05-29 02:09:21 -05:00
GreemDev
960421a7c1 misc: Swap the context menu actions to Commands 2025-05-29 01:58:05 -05:00
GreemDev
9233fe86b0 [ci skip] infra: After a quick test, ARMeilleure didn't even use anything from Ryujinx.Common. 2025-05-28 23:52:06 -05:00
GreemDev
1156307ef9 PPTC: fix rare EndOfStreamException in ContainsBlacklistedFunctions 2025-05-28 23:35:52 -05:00
KeatonTheBot
a32a87e0c9 Workaround undefined behavior in bad dual source blend states
See merge request ryubing/ryujinx!4
2025-05-28 05:59:16 -05:00
GreemDev
7157565665 UI: RPC: link to release channels on logo in RPC 2025-05-28 00:13:27 -05:00
GreemDev
6873303864 UI: Show "Paused" in place of FPS and FIFO when emulation is paused. 2025-05-28 00:12:55 -05:00
GreemDev
cd72ba0075 headless: Load global input configs by default. Added an option --disable-main-input-config to disable this behavior. 2025-05-27 23:46:43 -05:00
GreemDev
be6919d931 cpu: turbo: Increase Turbo cap to 1000% and remove the discrepancy between the slider and number box max values. 2025-05-27 23:36:53 -05:00
GreemDev
cf0185da17 Add LotP to About window 2025-05-27 23:36:53 -05:00
MrKev
1d923ba7b0 Fix JWT Claims and Socket Flag Handling to Improve Just Dance® Server Connection
See merge request ryubing/ryujinx!38
2025-05-27 16:46:54 -05:00
GreemDev
f14d65b543 update changelog 2025-05-26 17:00:54 -05:00
Hack茶ん
fd9f161476 Update Korean translation
See merge request ryubing/ryujinx!42
2025-05-26 15:10:50 -05:00
KeatonTheBot
ae070c76d7 ffmpeg: Fix green screen issues on Linux
See merge request ryubing/ryujinx!40
2025-05-25 22:34:56 -05:00
GreemDev
2aa072fbfa fix: Super Mario Party Jamboree audio renderer crashing
See merge request ryubing/ryujinx!34
2025-05-24 17:00:30 -05:00
785 changed files with 16994 additions and 9770 deletions

View File

@@ -16,6 +16,17 @@ tab_width = 4
# New line preferences # New line preferences
end_of_line = lf end_of_line = lf
insert_final_newline = true insert_final_newline = true
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_explicit_tuple_names = true:suggestion
# Markdown, JSON, YAML, props and csproj files # Markdown, JSON, YAML, props and csproj files
[*.{md,json,yml,props,csproj}] [*.{md,json,yml,props,csproj}]
@@ -106,7 +117,7 @@ csharp_style_conditional_delegate_call = true:suggestion
csharp_prefer_static_local_function = true:suggestion csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
csharp_style_prefer_readonly_struct = true csharp_style_prefer_readonly_struct = true
csharp_style_prefer_method_group_conversion = true csharp_style_prefer_method_group_conversion = true:silent
# Code-block preferences # Code-block preferences
csharp_prefer_braces = true:silent csharp_prefer_braces = true:silent
@@ -177,9 +188,9 @@ csharp_preserve_single_line_statements = false
# Naming rules # Naming rules
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.severity = suggestion dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = suggestion
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface dotnet_naming_rule.interfaces_should_be_prefixed_with_I.symbols = interface
dotnet_naming_rule.interfaces_should_be_prefixed_with_I.style = IPascalCase dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = IPascalCase
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types dotnet_naming_rule.types_should_be_pascal_case.symbols = types
@@ -236,28 +247,22 @@ dotnet_naming_style.IPascalCase.required_suffix =
dotnet_naming_style.IPascalCase.word_separator = dotnet_naming_style.IPascalCase.word_separator =
dotnet_naming_style.IPascalCase.capitalization = pascal_case dotnet_naming_style.IPascalCase.capitalization = pascal_case
# TODO: # Other settings
# .NET 8 migration (new warnings are caused by the NET 8 C# compiler and analyzer) csharp_style_prefer_top_level_statements = true:suggestion
# The following info messages might need to be fixed in the source code instead of hiding the actual message csharp_style_prefer_primary_constructors = false:suggestion
# Without the following lines, dotnet format would fail csharp_prefer_system_threading_lock = true:suggestion
# Disable "Collection initialization can be simplified"
# Analyzers
dotnet_diagnostic.CA1069.severity = none # CA1069: Enums values should not be duplicated
# Disable Collection initialization can be simplified
dotnet_diagnostic.IDE0028.severity = none dotnet_diagnostic.IDE0028.severity = none
dotnet_diagnostic.IDE0300.severity = none dotnet_diagnostic.IDE0300.severity = none
dotnet_diagnostic.IDE0301.severity = none dotnet_diagnostic.IDE0301.severity = none
dotnet_diagnostic.IDE0302.severity = none dotnet_diagnostic.IDE0302.severity = none
dotnet_diagnostic.IDE0305.severity = none dotnet_diagnostic.IDE0305.severity = none
# Disable "'new' expression can be simplified" dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
dotnet_diagnostic.IDE0090.severity = none dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
# Disable "Use primary constructor"
dotnet_diagnostic.IDE0290.severity = none
# Disable "Member '' does not access instance data and can be marked as static"
dotnet_diagnostic.CA1822.severity = none
# Disable "Change type of field '' from '' to '' for improved performance"
dotnet_diagnostic.CA1859.severity = none
# Disable "Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array"
dotnet_diagnostic.CA1861.severity = none
# Disable "Prefer using 'string.Equals(string, StringComparison)' to perform a case-insensitive comparison, but keep in mind that this might cause subtle changes in behavior, so make sure to conduct thorough testing after applying the suggestion, or if culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'"
dotnet_diagnostic.CA1862.severity = none
[src/Ryujinx/UI/ViewModels/**.cs] [src/Ryujinx/UI/ViewModels/**.cs]
# Disable "mark members as static" rule for ViewModels # Disable "mark members as static" rule for ViewModels

View File

@@ -21,60 +21,9 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3" RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
RELEASE: 1 RELEASE: 1
jobs: jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/Stable-Releases/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release: release:
name: Release for ${{ matrix.platform.name }} name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }} runs-on: ${{ matrix.platform.os }}
@@ -82,7 +31,7 @@ jobs:
matrix: matrix:
platform: platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 } - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 } #- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 } - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 } - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps: steps:
@@ -108,11 +57,8 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop sed -r --in-place '/^Name=Ryujinx$/s/Name=Ryujinx/Name=Ryujinx-Canary/' distribution/linux/Ryujinx.desktop
shell: bash shell: bash
- name: Create output dir - name: Create output dir
@@ -129,7 +75,24 @@ jobs:
rm libarmeilleure-jitsupport.dylib rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish 7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds - name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@@ -139,8 +102,10 @@ jobs:
chmod +x Ryujinx.sh Ryujinx chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash shell: bash
- name: Build AppImage (Linux) - name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
run: | run: |
@@ -169,41 +134,17 @@ jobs:
exit 1 exit 1
fi fi
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|Canary-Releases|latest|*-$ARCH_NAME.AppImage.zsync" export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage mv Ryujinx.AppImage ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync mv Ryujinx.AppImage.zsync ../release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd popd
shell: bash
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
- name: Pushing new release gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
uses: ncipollo/release-action@v1 shell: bash
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Canary Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
@@ -220,6 +161,16 @@ jobs:
wget https://apt.llvm.org/llvm.sh wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh chmod +x llvm.sh
sudo ./llvm.sh 17 sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign - name: Install rcodesign
run: | run: |
@@ -246,24 +197,53 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash
- name: Publish macOS Ryujinx - name: Publish macOS Ryujinx
run: | run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1 ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|publish_ava/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
- name: Pushing new release create_gitlab_release:
uses: ncipollo/release-action@v1 name: Create GitLab Release
with: runs-on: ubuntu-24.04
name: "Canary ${{ steps.version_info.outputs.build_version }}" needs:
artifacts: "publish_ava/*.tar.gz" - macos_release
tag: ${{ steps.version_info.outputs.build_version }} - release
body: "" steps:
omitBodyDuringUpdate: true - uses: actions/checkout@v4
allowUpdates: true
replacesArtifacts: true - name: Get version info
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} id: version_info
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} run: |
token: ${{ secrets.RELEASE_TOKEN }} echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create tag
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "Canary-${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}"
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=CreateReleaseFromGenericPackageFiles "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|main|Canary ${{ steps.version_info.outputs.build_version }}|**Full Changelog:** [${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}](https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }})"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'

224
.github/workflows/debug_release.yml vendored Normal file
View File

@@ -0,0 +1,224 @@
name: Release job (Debug)
on:
workflow_dispatch:
inputs: {}
concurrency: release
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RELEASE: 1
jobs:
release:
name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }}
strategy:
matrix:
platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
#- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Overwrite csc problem matcher
run: echo "::add-matcher::.github/csc.json"
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Create output dir
run: "mkdir release_output"
- name: Publish
run: |
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
- name: Packing Windows builds
if: matrix.platform.os == 'windows-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest'
run: |
pushd publish
rm libarmeilleure-jitsupport.dylib
chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash
- name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest'
run: |
BUILD_VERSION="${{ steps.version_info.outputs.build_version }}"
PLATFORM_NAME="${{ matrix.platform.name }}"
sudo apt install -y zsync desktop-file-utils appstream
mkdir -p tools
export PATH="$PATH:$(readlink -f tools)"
# Setup appimagetool
wget -q -O tools/appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x tools/appimagetool
chmod +x distribution/linux/appimage/build-appimage.sh
# Explicitly set $ARCH for appimagetool ($ARCH_NAME is for the file name)
if [ "$PLATFORM_NAME" = "linux-x64" ]; then
ARCH_NAME=x64
export ARCH=x86_64
elif [ "$PLATFORM_NAME" = "linux-arm64" ]; then
ARCH_NAME=arm64
export ARCH=aarch64
else
echo "Unexpected PLATFORM_NAME "$PLATFORM_NAME""
exit 1
fi
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
pushd publish_appimage
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash
macos_release:
name: Release MacOS universal
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
- name: Setup LLVM 17
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign
run: |
mkdir -p $HOME/.bin
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
rm apple-codesign.tar.gz
mv rcodesign $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Configure for release
run: |
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash
- name: Publish macOS Ryujinx
run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} + 10))" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|test|THIS IS NOT INTENDED FOR END USER USAGE"

View File

@@ -11,57 +11,9 @@ env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.3" RYUJINX_BASE_VERSION: "1.3"
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release" RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Stable-Releases"
RELEASE: 1 RELEASE: 1
jobs: jobs:
tag:
name: Create tag
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
shell: bash
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitLab tag
run: gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateTag "${{ steps.version_info.outputs.build_version }}|master"
- name: Create release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
release: release:
name: Release for ${{ matrix.platform.name }} name: Release for ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.os }} runs-on: ${{ matrix.platform.os }}
@@ -69,7 +21,7 @@ jobs:
matrix: matrix:
platform: platform:
- { name: win-x64, os: windows-latest, zip_os_name: win_x64 } - { name: win-x64, os: windows-latest, zip_os_name: win_x64 }
- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 } #- { name: win-arm64, os: windows-latest, zip_os_name: win_arm64 }
- { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 } - { name: linux-x64, os: ubuntu-latest, zip_os_name: linux_x64 }
- { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 } - { name: linux-arm64, os: ubuntu-latest, zip_os_name: linux_arm64 }
steps: steps:
@@ -95,9 +47,6 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash
@@ -115,7 +64,24 @@ jobs:
rm libarmeilleure-jitsupport.dylib rm libarmeilleure-jitsupport.dylib
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish 7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
popd popd
gh release download -R GreemDev/GLI -O gli.exe -p 'GitLabCli-win_x64.exe'
./gli.exe --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install GitLabCli
if: matrix.platform.os == 'ubuntu-latest'
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Packing Linux builds - name: Packing Linux builds
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
@@ -125,8 +91,12 @@ jobs:
chmod +x Ryujinx.sh Ryujinx chmod +x Ryujinx.sh Ryujinx
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
shell: bash shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build AppImage (Linux) - name: Build AppImage (Linux)
if: matrix.platform.os == 'ubuntu-latest' if: matrix.platform.os == 'ubuntu-latest'
run: | run: |
@@ -162,32 +132,11 @@ jobs:
mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage mv Ryujinx.AppImage ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage
mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync mv Ryujinx.AppImage.zsync ../release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync
popd popd
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
shell: bash shell: bash
- name: Pushing new release
uses: ncipollo/release-action@v1
with:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: |
# Stable builds:
| Platform | Artifact |
|--|--|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Windows ARM 64-bit | [Stable Windows ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_arm64.zip) |
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**[Full Changelog](https://git.ryujinx.app/ryubing/ryujinx/-/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }})**
omitBodyDuringUpdate: true
allowUpdates: true
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
token: ${{ secrets.RELEASE_TOKEN }}
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
@@ -203,6 +152,16 @@ jobs:
wget https://apt.llvm.org/llvm.sh wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh chmod +x llvm.sh
sudo ./llvm.sh 17 sudo ./llvm.sh 17
- name: Install GitLabCli
run: |
mkdir -p $HOME/.bin
gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
chmod +x gli
mv gli $HOME/.bin/
echo "$HOME/.bin" >> $GITHUB_PATH
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install rcodesign - name: Install rcodesign
run: | run: |
@@ -227,26 +186,49 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_CONFIG_FILE_NAME\%\%/Config\.json/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash
- name: Publish macOS Ryujinx - name: Publish macOS Ryujinx
run: | run: |
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0 ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|publish/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz"
create_gitlab_release:
name: Create GitLab Release
runs-on: ubuntu-24.04
needs:
- macos_release
- release
steps:
- uses: actions/checkout@v4
- name: Get version info
id: version_info
run: |
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "prev_build_version=${{ env.RYUJINX_BASE_VERSION }}.$((${{ github.run_number }} - 1))" >> $GITHUB_OUTPUT
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Pushing new release - name: Install GitLabCli
uses: ncipollo/release-action@v1 run: |
with: mkdir -p $HOME/.bin
name: ${{ steps.version_info.outputs.build_version }} gh release download -R GreemDev/GLI -O gli -p 'GitLabCli-linux_x64'
artifacts: "publish/*.tar.gz" chmod +x gli
tag: ${{ steps.version_info.outputs.build_version }} mv gli $HOME/.bin/
body: "" echo "$HOME/.bin" >> $GITHUB_PATH
omitBodyDuringUpdate: true env:
allowUpdates: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
replacesArtifacts: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }} - name: Create release
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }} run: |
token: ${{ secrets.RELEASE_TOKEN }} gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=CreateReleaseFromGenericPackageFiles "Ryubing|${{ steps.version_info.outputs.build_version }}|${{ steps.version_info.outputs.git_short_hash }}|${{ steps.version_info.outputs.build_version }}|msd:${{ steps.version_info.outputs.build_version }}"
- name: Send notification webhook
run: |
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
- name: Notify update server of new builds
run: |
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'

View File

@@ -1,19 +0,0 @@
function pub {
dotnet publish -c release
}
function package {
cd src/$1
pub
mv bin/Release/$1.1.0.0.nupkg ../../pkgs/$1.1.0.0.nupkg
cd ../../
}
rm -rf pkgs
mkdir pkgs
package ARMeilleure
package Ryujinx.Common
package Ryujinx.Memory
dotnet nuget push pkgs/*.nupkg --source RyubingPkgs

View File

@@ -2,18 +2,17 @@
All updates to this Ryujinx branch will be documented in this file. All updates to this Ryujinx branch will be documented in this file.
## [1.3.2](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.2>) - 2025-06-09
## [1.2.86](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.2.86>) - 2025-03-13 ## [1.3.1](<https://git.ryujinx.app/ryubing/ryujinx/-/releases/1.3.1>) - 2025-04-23
A list of notable changes can be found on the release linked in the version number above.
## [1.2.86](<https://github.com/Ryubing/Stable-Releases/releases/tag/1.2.86>) - 2025-03-13
## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16 ## [1.2.82](<https://web.archive.org/web/20250312010534/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.82>) - 2025-02-16
A list of notable changes can be found on the release linked in the version number above.
## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22 ## [1.2.80-81](<https://web.archive.org/web/20250302064257/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.81>) - 2025-01-22
A list of notable changes can be found on the release linked in the version number above.
## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19 ## [1.2.78](<https://web.archive.org/web/20250301174537/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.78>) - 2024-12-19
A list of notable changes can be found on the release linked in the version number above.
## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19 ## [1.2.73-1.2.76](<https://web.archive.org/web/20250209202612/https://github.com/Ryubing/Ryujinx/releases/tag/1.2.76>) - 2024-11-19
A list of notable changes can be found on the release linked in the version number above. A list of notable changes can be found on the release linked in the version number above.
@@ -22,8 +21,8 @@ Additionally, 1.2.74 & 75 were fixes for uploading Windows build artifacts.
1.2.76 fixes a rare crash on startup. 1.2.76 fixes a rare crash on startup.
## [1.2.72](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.72>) - 2024-11-03 ## [1.2.72](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.72>) - 2024-11-03
PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://github.com/GreemDev/Ryujinx/pull/164>), [#139](<https://github.com/GreemDev/Ryujinx/pull/139>) PRs [#163](<https://web.archive.org/web/20241123015123/https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://web.archive.org/web/20250307192526/https://github.com/Ryubing/Ryujinx/pull/164>), [#139](<https://web.archive.org/web/20250306123457/https://github.com/Ryubing/Ryujinx/pull/139>)
### HLE: ### HLE:
- Add DebugMouse HID device. - Add DebugMouse HID device.
- Fixes "Clock Tower Rewind" crashing while loading. - Fixes "Clock Tower Rewind" crashing while loading.
@@ -33,7 +32,7 @@ PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://gith
### misc: ### misc:
- Update macOS distribution .icns. - Update macOS distribution .icns.
## [1.2.69](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.69>) - 2024-11-01 ## [1.2.69](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.69>) - 2024-11-01
### Infra: ### Infra:
- Compile the native libraries into the Ryujinx executable. - Compile the native libraries into the Ryujinx executable.
- Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only) - Remove `libarmeilleure-jitsupport.dylib` from Windows & Linux releases (dylibs are macOS-only)
@@ -43,8 +42,8 @@ PRs [#163](<https://github.com/GreemDev/Ryujinx/pull/163>), [#164](<https://gith
- Replace "" with `string.Empty`. - Replace "" with `string.Empty`.
- Code cleanups & simplifications. - Code cleanups & simplifications.
## [1.2.67](<https://github.com/GreemDev/Ryujinx/releases/tag/1.2.67>) - 2024-11-01 ## [1.2.67](<https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.67>) - 2024-11-01
PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github.com/GreemDev/Ryujinx/pull/135>) PRs [#36](<https://web.archive.org/web/20250306215917/https://github.com/Ryubing/Ryujinx/pull/36>), [#135](<https://web.archive.org/web/20241122135125/https://github.com/GreemDev/Ryujinx/pull/135>)
### GUI: ### GUI:
- Set UseFloatingWatermark to false when watermark is empty - Set UseFloatingWatermark to false when watermark is empty
@@ -55,8 +54,8 @@ PRs [#36](<https://github.com/GreemDev/Ryujinx/pull/36>), [#135](<https://github
- Fix homebrew loading. - Fix homebrew loading.
## [1.2.64](https://github.com/GreemDev/Ryujinx/releases/tag/1.2.64) - 2024-10-30 ## [1.2.64](https://git.ryujinx.app/ryubing/ryujinx/-/tags/1.2.64) - 2024-10-30
PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com/GreemDev/Ryujinx/pull/96), [#97](https://github.com/GreemDev/Ryujinx/pull/97), [#101](https://github.com/GreemDev/Ryujinx/pull/101), [#103](https://github.com/GreemDev/Ryujinx/pull/103) PRs [#92](https://web.archive.org/web/20241118052724/https://github.com/GreemDev/Ryujinx/pull/92), ~~[#96](https://github.com/GreemDev/Ryujinx/pull/96)~~, ~~[#97](https://github.com/GreemDev/Ryujinx/pull/97)~~, [#101](https://web.archive.org/web/20250306223605/https://github.com/Ryubing/Ryujinx/pull/101), ~~[#103](https://github.com/GreemDev/Ryujinx/pull/103)~~
### GUI: ### GUI:
- Option to show classic-style title bar. Requires restart of emulator to take effect. - Option to show classic-style title bar. Requires restart of emulator to take effect.
- This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place. - This is only relevant on Windows. Other Operating Systems default to this being on and not being changeable, because the custom (current) title bar only works on Windows in the first place.
@@ -72,14 +71,14 @@ PRs [#92](https://github.com/GreemDev/Ryujinx/pull/92), [#96](https://github.com
## 1.2.59 - 2024-10-27 ## 1.2.59 - 2024-10-27
PRs [#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87) PRs ~~[#88](https://github.com/GreemDev/Ryujinx/pull/88), [#87](https://github.com/GreemDev/Ryujinx/pull/87)~~
### i18n: ### i18n:
- fr_FR: - fr_FR:
- Add missing translations for new features & fix a couple wrong ones. - Add missing translations for new features & fix a couple wrong ones.
- Fix Ignore Missing Services / Ignore Applet tooltip. - Fix Ignore Missing Services / Ignore Applet tooltip.
## 1.2.57 - 2024-10-27 ## 1.2.57 - 2024-10-27
PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com/GreemDev/Ryujinx/pull/42) PRs ~~[#60](https://github.com/GreemDev/Ryujinx/pull/60)~~, [#42](https://web.archive.org/web/20241126203614/https://github.com/GreemDev/Ryujinx/pull/42)
### GUI: ### GUI:
- Automatically remove invalid DLC & updates as part of autoload. - Automatically remove invalid DLC & updates as part of autoload.
- Added Thai translation for Ignore Applet hover tooltip. - Added Thai translation for Ignore Applet hover tooltip.
@@ -105,7 +104,7 @@ PRs [#60](https://github.com/GreemDev/Ryujinx/pull/60), [#42](https://github.com
- Code cleanup. - Code cleanup.
## 1.2.44 - 2024-10-25 ## 1.2.44 - 2024-10-25
PR [#59](https://github.com/GreemDev/Ryujinx/pull/59) PR [#59](https://web.archive.org/web/20241125060420/https://github.com/GreemDev/Ryujinx/pull/59)
### GUI: ### GUI:
- Add descriptions for "ignoring applet" translated into other languages. - Add descriptions for "ignoring applet" translated into other languages.
@@ -118,9 +117,9 @@ NOTE: The translation isn't referenced in the code yet, it will be in the next u
## 1.2.42 - 2024-10-24 ## 1.2.42 - 2024-10-24
Sources: Sources:
Init function: https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9 Init function: [archive of github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9](https://web.archive.org/web/20241122193401/https://github.com/MutantAura/Ryujinx/commit/9cef4ceba40d66492ff775af793ff70e6e7551a9)
Shader counter: https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357 Shader counter: ~~https://github.com/MutantAura/Ryujinx/commit/67b873645fd593e83d042a77bf7ab12e5ec97357~~ Original commit has been lost
Thanks MutantAura :D Thanks MutantAura :D
### GUI: ### GUI:
@@ -128,14 +127,14 @@ Thanks MutantAura :D
- Remove graphics backend / GPU name event logic in favor of a single init function. - Remove graphics backend / GPU name event logic in favor of a single init function.
## 1.2.41 - 2024-10-24 ## 1.2.41 - 2024-10-24
PR [#54](https://github.com/GreemDev/Ryujinx/pull/54) PR ~~[#54](https://github.com/GreemDev/Ryujinx/pull/54)~~
Thanks Whitescatz! Thanks Whitescatz!
### i18n: ### i18n:
- th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar. - th_TH (Thai): Added missing translations, reduce transliterated words, fix grammar.
## 1.2.40 - 2024-10-23 ## 1.2.40 - 2024-10-23
PR [#40](https://github.com/GreemDev/Ryujinx/pull/40) PR ~~[#40](https://github.com/GreemDev/Ryujinx/pull/40)~~
Thanks Вова С! Thanks Вова С!
### GUI: ### GUI:
@@ -149,30 +148,30 @@ Thanks Вова С!
- Should prevent crashing on config loads in some circumstances. - Should prevent crashing on config loads in some circumstances.
## 1.2.38 - 2024-10-23 ## 1.2.38 - 2024-10-23
PR [#51](https://github.com/GreemDev/Ryujinx/pull/51) PR [#51](https://web.archive.org/web/20241127022413/https://github.com/GreemDev/Ryujinx/pull/51)
### i18n: ### i18n:
- zh_CH (Simplified Chinese): Add some missing translations. - zh_CH (Simplified Chinese): Add some missing translations.
## 1.2.37 - 2024-10-23 ## 1.2.37 - 2024-10-23
PR [#37](https://github.com/GreemDev/Ryujinx/pull/37) PR [#37](https://web.archive.org/web/20241123010103/https://github.com/GreemDev/Ryujinx/pull/37)
Thanks Last Breath! Thanks Last Breath!
### GUI: ### GUI:
- Set the default controller to the Pro Controller. - Set the default controller to the Pro Controller.
## 1.2.36 - 2024-10-21 ## 1.2.36 - 2024-10-21
PR [#30](https://github.com/GreemDev/Ryujinx/pull/30) PR ~~[#30](https://github.com/GreemDev/Ryujinx/pull/30)~~
### GUI: ### GUI:
- Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file. - Fix repeated dialog popup notifying you of new updates when there aren't any, while having a bundled update inside an XCI and an external update file.
## 1.2.35 - 2024-10-21 ## 1.2.35 - 2024-10-21
PR [#32](https://github.com/GreemDev/Ryujinx/pull/32) PR [#32](https://web.archive.org/web/20241127010942/https://github.com/GreemDev/Ryujinx/pull/32)
### GUI: ### GUI:
- Replace "expand DRAM" option with a DRAM size dropdown. - Replace "expand DRAM" option with a DRAM size dropdown.
- Allows for using mods which require a ridiculous amount of memory to allocate from. - Allows for using mods which require a ridiculous amount of memory to allocate from.
## 1.2.34 - 2024-10-21 ## 1.2.34 - 2024-10-21
PR [#29](https://github.com/GreemDev/Ryujinx/pull/29) PR [#29](https://web.archive.org/web/20241125093029/https://github.com/GreemDev/Ryujinx/pull/29)
### GUI: ### GUI:
- Fix duplicate controller names when 2 controllers of the same type are connected. - Fix duplicate controller names when 2 controllers of the same type are connected.
### INPUT: ### INPUT:
@@ -249,7 +248,7 @@ Added Low-power PPTC mode strings to the translation files.
## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11 ## 1.2.1-1.2.19 - 2024-10-08 - 2024-10-11
### GUI/INFRA/MISC: ### GUI/INFRA/MISC:
- Remove GTK UI. - Remove GTK UI.
- Autoload DLC/Updates from dir ([#12](https://github.com/GreemDev/Ryujinx/pull/12)). - Autoload DLC/Updates from dir ([#12](https://web.archive.org/web/20241127004005/https://github.com/GreemDev/Ryujinx/pull/12)).
- Changed executable icon to rainbow logo. - Changed executable icon to rainbow logo.
- Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI. - Extract Data > Logo now also extracts the square thumbnail you see for the game in the UI.
- The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session. - The "use random UUID hack" checkbox in the Amiibo screen now remembers its last state when you reopen the window in a given session.

View File

@@ -19,8 +19,8 @@
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/> <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
<PackageVersion Include="Concentus" Version="2.2.2" /> <PackageVersion Include="Concentus" Version="2.2.2" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageVersion Include="DynamicData" Version="9.0.4" /> <PackageVersion Include="DynamicData" Version="9.4.1" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
<PackageVersion Include="Humanizer" Version="2.14.1" /> <PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
@@ -40,11 +40,13 @@
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" /> <PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0-alpha.103" /> <PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.1.1" /> <PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
<PackageVersion Include="Gommon" Version="2.7.2.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.6.0" /> <PackageVersion Include="Sep" Version="0.11.1" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />

View File

@@ -7,8 +7,8 @@
# Ryujinx # Ryujinx
[![Latest release](https://img.shields.io/github/v/release/Ryubing/Stable-Releases?label=stable)](https://github.com/Ryubing/Stable-Releases/releases/latest) [![Latest release](https://img.shields.io/gitlab/v/release/ryubing%2Fryujinx?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=stable&color=32cd32)](https://update.ryujinx.app/latest/stable)
[![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest) [![Latest canary release](https://img.shields.io/gitlab/v/release/ryubing%2Fcanary?gitlab_url=https%3A%2F%2Fgit.ryujinx.app&label=canary&color=FF4500)](https://update.ryujinx.app/latest/canary)
<br> <br>
<a href="https://discord.gg/PEuzjrFXUA"> <a href="https://discord.gg/PEuzjrFXUA">
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord"> <img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
@@ -31,7 +31,7 @@
<br> <br>
This is not a Ryujinx revival project. This is not a Phoenix project. This is not a Ryujinx revival project. This is not a Phoenix project.
<br> <br>
Guides and documentation can be found on the <a href="https://git.ryujinx.app/ryubing/ryujinx/-/wikis/home">Wiki tab</a>. Guides and documentation can be found on the <a href="https://git.ryujinx.app/groups/ryubing/-/wikis/home">Wiki tab</a>.
</p> </p>
<p align="center"> <p align="center">
@@ -49,13 +49,13 @@ Stable builds are made every so often, based on the `master` branch, that then g
These stable builds exist so that the end user can get a more **enjoyable and stable experience**. These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month. They are released every month or so, to ensure consistent updates, while not being an annoying amount of individual updates to download over the course of that month.
You can find the latest stable release [here](https://github.com/Ryubing/Stable-Releases/releases/latest). You can find the stable releases [here](https://git.ryujinx.app/ryubing/ryujinx/-/releases).
Canary builds are compiled automatically for each commit on the `master` branch. Canary builds are compiled automatically for each commit on the `master` branch.
While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**. While we strive to ensure optimal stability and performance prior to pushing an update, these builds **may be unstable or completely broken**.
These canary builds are only recommended for experienced users. These canary builds are only recommended for experienced users.
You can find the latest canary release [here](https://github.com/Ryubing/Canary-Releases/releases/latest). You can find the canary releases [here](https://git.ryujinx.app/ryubing/canary/-/releases).
## Documentation ## Documentation
@@ -111,7 +111,7 @@ See [LICENSE.txt](LICENSE.txt) and [THIRDPARTY.md](distribution/legal/THIRDPARTY
## Credits ## Credits
- [LibHac](https://github.com/Thealexbarney/LibHac) is used for our file-system. - [LibHac](https://git.ryujinx.app/ryubing/libhac) is used for our file-system.
- [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation. - [AmiiboAPI](https://www.amiiboapi.com) is used in our Amiibo emulation.
- [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes. - [ldn_mitm](https://github.com/spacemeowx2/ldn_mitm) is used for one of our available multiplayer modes.
- [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation. - [ShellLink](https://github.com/securifybv/ShellLink) is used for Windows shortcut generation.

View File

@@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
@@ -84,10 +86,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.github\workflows\canary.yml = .github\workflows\canary.yml .github\workflows\canary.yml = .github\workflows\canary.yml
Directory.Packages.props = Directory.Packages.props Directory.Packages.props = Directory.Packages.props
.github\workflows\release.yml = .github\workflows\release.yml .github\workflows\release.yml = .github\workflows\release.yml
nuget.config = nuget.config
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@ chmod +x AppDir/AppRun AppDir/usr/bin/Ryujinx*
mkdir -p "$OUTDIR" mkdir -p "$OUTDIR"
appimagetool --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \ appimagetool -n --comp zstd --mksquashfs-opt -Xcompression-level --mksquashfs-opt 21 \
-u "$UFLAG" \ -u "$UFLAG" \
AppDir "$OUTDIR"/Ryujinx.AppImage AppDir "$OUTDIR"/Ryujinx.AppImage

View File

@@ -33,23 +33,29 @@ echo -n "APPL????" > "$APP_BUNDLE_DIRECTORY/Contents/PkgInfo"
echo "Running bundle fix up python script" echo "Running bundle fix up python script"
python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx python3 bundle_fix_up.py "$APP_BUNDLE_DIRECTORY" MacOS/Ryujinx
# Resign all dyplib files as ad-hoc after changing them
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
# Now sign it # Now sign it
echo "Starting signing process" echo "Starting signing process"
if ! [ -x "$(command -v codesign)" ]; if ! [ -x "$(command -v codesign)" ];
then then
if ! [ -x "$(command -v rcodesign)" ]; if ! [ -x "$(command -v rcodesign)" ];
then then
echo "Cannot find rcodesign on your system, please install rcodesign." echo "Cannot find rcodesign on your system, please install rcodesign and ensure it is in your search path."
exit 1 exit 1
fi fi
# cargo install apple-codesign
echo "Using rcodesign for ad-hoc signing" echo "Using rcodesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec rcodesign sign {} \;
echo "Signing app bundle as ad-hoc"
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY" rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$APP_BUNDLE_DIRECTORY"
else else
echo "Using codesign for ad-hoc signing" echo "Using codesign for ad-hoc signing"
echo "Resigning all frameworks dylib files as ad-hoc"
find "$APP_BUNDLE_DIRECTORY/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
echo "Signing app bundle as ad-hoc"
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY" codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f -s - "$APP_BUNDLE_DIRECTORY"
fi fi

View File

@@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7 CONFIGURATION=$7
CANARY=$8 CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar RELEASE_TAR_FILE_NAME=ryujinx-canary-$VERSION-macos_universal.app.tar
elif [ "$VERSION" == "1.1.0" ]; then elif [ "$VERSION" == "1.1.0" ]; then

View File

@@ -20,6 +20,18 @@ SOURCE_REVISION_ID=$6
CONFIGURATION=$7 CONFIGURATION=$7
CANARY=$8 CANARY=$8
if [[ "$(uname)" == "Darwin" ]]; then
echo "Clearing xattr on all dot undercsore files"
find "$BASE_DIR" -type f -name "._*" -exec sh -c '
for f; do
dir=$(dirname "$f")
base=$(basename "$f")
orig="$dir/${base#._}"
[ -f "$orig" ] && xattr -c "$orig" || true
done
' sh {} +
fi
if [ "$CANARY" == "1" ]; then if [ "$CANARY" == "1" ]; then
RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar RELEASE_TAR_FILE_NAME=nogui-ryujinx-canary-$VERSION-macos_universal.tar
elif [ "$VERSION" == "1.1.0" ]; then elif [ "$VERSION" == "1.1.0" ]; then

View File

@@ -188,6 +188,8 @@
01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27 01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27
01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18 01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18
01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12 01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12
01009E8012976000,"AKIBA'S TRIP: Hellbound & Debriefed",,playable,2025-07-30 23:22:47
0100D74019A0E000,"AKIBA'S TRIP: Undead & Undressed Director's Cut",,playable,2025-07-31 13:58:42
010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35 010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35
0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36 0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36
010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27 010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27
@@ -976,7 +978,7 @@
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07 0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19 010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
01008CB01E52E000,"DOOM + DOOM II",opengl;ldn-untested;LAN,playable,2024-09-12 07:06:01 01008CB01E52E000,"DOOM + DOOM II",opengl;ldn-untested;LAN,playable,2024-09-12 07:06:01
010029D00E740000,"DOOM 3",crash,menus,2024-08-03 05:25:47 010029D00E740000,"DOOM 3",crash;slow,menus,2024-08-03 05:25:47
01005D700E742000,"DOOM 64",nvdec;vulkan,playable,2020-10-13 23:47:28 01005D700E742000,"DOOM 64",nvdec;vulkan,playable,2020-10-13 23:47:28
0100D4F00DD02000,"DOOM II (Classic)",nvdec;online,playable,2021-06-03 20:10:01 0100D4F00DD02000,"DOOM II (Classic)",nvdec;online,playable,2021-06-03 20:10:01
0100B1A00D8CE000,"DOOM® Eternal",gpu;slow;nvdec;online-broken,ingame,2024-08-28 15:57:17 0100B1A00D8CE000,"DOOM® Eternal",gpu;slow;nvdec;online-broken,ingame,2024-08-28 15:57:17
@@ -1095,6 +1097,7 @@
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08 0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14 010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58 01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
010018F01E0A0000,"Eternights",,playable,2025-07-30 12:10:24
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32 0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12 010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30 01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
@@ -1125,6 +1128,7 @@
0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06 0100034012606000,"Family Mysteries: Poisonous Promises",audio;crash,menus,2021-11-26 12:35:06
010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39 010017C012726000,"Fantasy Friends",,playable,2022-10-17 19:42:39
0100767008502000,"FANTASY HERO unsigned legacy",,playable,2022-07-26 12:28:52 0100767008502000,"FANTASY HERO unsigned legacy",,playable,2022-07-26 12:28:52
0100755017EE0000,"FANTASY LIFE i: The Girl Who Steals Time",gpu;crash;vulkan-backend-bug,ingame,2025-06-08 20:41:00
0100944003820000,"Fantasy Strike",online,playable,2021-02-27 01:59:18 0100944003820000,"Fantasy Strike",online,playable,2021-02-27 01:59:18
01000E2012F6E000,"Fantasy Tavern Sextet -Vol.1 New World Days-",gpu;crash;Needs Update,ingame,2022-12-05 16:48:00 01000E2012F6E000,"Fantasy Tavern Sextet -Vol.1 New World Days-",gpu;crash;Needs Update,ingame,2022-12-05 16:48:00
01005C10136CA000,"Fantasy Tavern Sextet -Vol.2 Adventurer's Days-",gpu;slow;crash,ingame,2021-11-06 02:57:29 01005C10136CA000,"Fantasy Tavern Sextet -Vol.2 Adventurer's Days-",gpu;slow;crash,ingame,2021-11-06 02:57:29
@@ -1239,6 +1243,8 @@
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38 010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27 010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24 0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
0100C4E018A24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
01007E6019872000,"FRONT MISSION 3: Remake",,playable,2025-07-30 12:12:02
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59 0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36 0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33 010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33
@@ -1434,6 +1440,7 @@
0100C2700E338000,"Heroland",,playable,2020-08-05 15:35:39 0100C2700E338000,"Heroland",,playable,2020-08-05 15:35:39
01007AC00E012000,"HexaGravity",,playable,2021-05-28 13:47:48 01007AC00E012000,"HexaGravity",,playable,2021-05-28 13:47:48
01004E800F03C000,"Hidden",slow,ingame,2022-10-05 10:56:53 01004E800F03C000,"Hidden",slow,ingame,2022-10-05 10:56:53
0100C1101EE5A000,"High on Life",,menus,2025-08-26 19:11:00
0100F6A00A684000,"Higurashi no Naku Koro ni Hō",audio,ingame,2021-09-18 14:40:28 0100F6A00A684000,"Higurashi no Naku Koro ni Hō",audio,ingame,2021-09-18 14:40:28
0100F8D0129F4000,"Himehibi 1 gakki - Princess Days",crash,nothing,2021-11-03 08:34:19 0100F8D0129F4000,"Himehibi 1 gakki - Princess Days",crash,nothing,2021-11-03 08:34:19
0100F3D008436000,"Hiragana Pixel Party",,playable,2021-01-14 08:36:50 0100F3D008436000,"Hiragana Pixel Party",,playable,2021-01-14 08:36:50
@@ -1443,6 +1450,7 @@
0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35 0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35
0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58 0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58
0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56 0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56
010013C00E930000,"Hollow Knight: Silksong",,playable,2025-09-04 17:23:22
0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56 0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56
0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56 0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56
010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38 010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38
@@ -1517,6 +1525,7 @@
010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53 010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53
0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15 0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15
0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22 0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22
010059801B736000,"IronFall: Invasion",,playable,2025-07-30 11:42:30
01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57 01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57
01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29 01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29
0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37 0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37
@@ -1880,7 +1889,7 @@
010097800EA20000,"Monster Energy Supercross - The Official Videogame 3",UE4;audout;nvdec;online,playable,2021-06-14 12:37:54 010097800EA20000,"Monster Energy Supercross - The Official Videogame 3",UE4;audout;nvdec;online,playable,2021-06-14 12:37:54
0100E9900ED74000,"Monster Farm",32-bit;nvdec,playable,2021-05-05 19:29:13 0100E9900ED74000,"Monster Farm",32-bit;nvdec,playable,2021-05-05 19:29:13
0100770008DD8000,"Monster Hunter Generations Ultimate™",32-bit;online-broken;ldn-works,playable,2024-03-18 14:35:36 0100770008DD8000,"Monster Hunter Generations Ultimate™",32-bit;online-broken;ldn-works,playable,2024-03-18 14:35:36
0100B04011742000,"Monster Hunter Rise",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59 0100B04011742000,"MONSTER HUNTER RISE",gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works,ingame,2024-08-24 11:04:59
010093A01305C000,"Monster Hunter Rise Demo",online-broken;ldn-works;demo,playable,2022-10-18 23:04:17 010093A01305C000,"Monster Hunter Rise Demo",online-broken;ldn-works;demo,playable,2022-10-18 23:04:17
0100E21011446000,"Monster Hunter Stories 2: Wings of Ruin",services,ingame,2022-07-10 19:27:30 0100E21011446000,"Monster Hunter Stories 2: Wings of Ruin",services,ingame,2022-07-10 19:27:30
010042501329E000,"MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version",demo,playable,2022-11-13 22:20:26 010042501329E000,"MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version",demo,playable,2022-11-13 22:20:26
@@ -2256,6 +2265,7 @@
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00 010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54 0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04 010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32 01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22 01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37 0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
@@ -2304,6 +2314,7 @@
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19 010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45 010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33 0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
0100C3A017834000,"Prodeus",,playable,2025-07-30 12:07:52
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12 0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43 0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27 01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
@@ -2435,6 +2446,7 @@
0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14 0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14
01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06 01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06
010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02 010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02
0100D1801A0F4000,"Risk of Rain Returns",,playable,2025-06-28 04:24:04
010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05 010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05
0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28 0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28
010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47 010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47
@@ -2568,6 +2580,7 @@
0100C610154CA000,"Shadowrun: Hong Kong - Extended Edition",gpu;Needs Update,ingame,2022-10-04 20:53:09 0100C610154CA000,"Shadowrun: Hong Kong - Extended Edition",gpu;Needs Update,ingame,2022-10-04 20:53:09
010000000EEF0000,"Shadows 2: Perfidia",,playable,2020-08-07 12:43:46 010000000EEF0000,"Shadows 2: Perfidia",,playable,2020-08-07 12:43:46
0100AD700CBBE000,"Shadows of Adam",,playable,2021-01-11 13:35:58 0100AD700CBBE000,"Shadows of Adam",,playable,2021-01-11 13:35:58
010037A01F96C000,"Shadows of the Damned: Hella Remastered",,playable,2025-09-05 11:34:32
01002A800C064000,"Shadowverse Champions Battle",,playable,2022-10-02 22:59:29 01002A800C064000,"Shadowverse Champions Battle",,playable,2022-10-02 22:59:29
01003B90136DA000,"Shadowverse: Champion's Battle",crash,nothing,2023-03-06 00:31:50 01003B90136DA000,"Shadowverse: Champion's Battle",crash,nothing,2023-03-06 00:31:50
0100820013612000,"Shady Part of Me",,playable,2022-10-20 11:31:55 0100820013612000,"Shady Part of Me",,playable,2022-10-20 11:31:55
@@ -2745,6 +2758,7 @@
01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51 01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51
010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33 010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33
0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05 0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05
0100E1D01EB2E000,"Squeakross: Home Squeak Home",,playable,2025-06-16 02:02:00
010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08 010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08
0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32 0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32
0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16 0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16
@@ -2764,7 +2778,7 @@
0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51 0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51
01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19 01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19
0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19 0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",services-horizon;crash;Needs Update,nothing,2024-05-05 17:25:11 01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",,playable,2025-07-30 12:09:37
010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43 010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43
01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55 01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55
010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05 010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05
@@ -2965,6 +2979,7 @@
0100EBA01548E000,"The Cruel King and the Great Hero",gpu;services,ingame,2022-12-02 07:02:08 0100EBA01548E000,"The Cruel King and the Great Hero",gpu;services,ingame,2022-12-02 07:02:08
010051800E922000,"The Dark Crystal: Age of Resistance Tactics",,playable,2020-08-11 13:43:41 010051800E922000,"The Dark Crystal: Age of Resistance Tactics",,playable,2020-08-11 13:43:41
01003DE00918E000,"The Darkside Detective",,playable,2020-06-03 22:16:18 01003DE00918E000,"The Darkside Detective",,playable,2020-06-03 22:16:18
010032B015D66000,"The DioField Chronicle",,playable,2025-09-05 11:35:50
01000A10041EA000,"The Elder Scrolls V: Skyrim",gpu;crash,ingame,2024-07-14 03:21:31 01000A10041EA000,"The Elder Scrolls V: Skyrim",gpu;crash,ingame,2024-07-14 03:21:31
01004A9006B84000,"The End Is Nigh",,playable,2020-06-01 11:26:45 01004A9006B84000,"The End Is Nigh",,playable,2020-06-01 11:26:45
0100CA100489C000,"The Escapists 2",nvdec,playable,2020-09-24 12:31:31 0100CA100489C000,"The Escapists 2",nvdec,playable,2020-09-24 12:31:31
@@ -2972,6 +2987,7 @@
0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28 0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28
01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35 01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35
0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06 0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06
0100BA5013E52000,"The Falconeer: Warrior Edition",,playable,2025-07-30 12:04:50
01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16 01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16
01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08 01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08
0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39 0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39
@@ -3015,6 +3031,7 @@
01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32 01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32
0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05 0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05
01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07 01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07
01009C901ACEE000,"The Legend of Nayuta: Boundless Trails",,ingame,2025-06-12 15:47
01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01 01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01
0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58 0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58
01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46 01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46
@@ -3193,6 +3210,7 @@
010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05 010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05
0100752011628000,"TTV2",,playable,2020-11-27 13:21:36 0100752011628000,"TTV2",,playable,2020-11-27 13:21:36
0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20 0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20
0100D1A01D7BA000,"Turbo Overkill",,playable,2025-07-30 12:08:57
010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24 010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24
0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05 0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05
010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56 010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56
@@ -3216,6 +3234,8 @@
0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56 0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56
01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45 01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45
010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18 010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18
01009B700D0B8000,"Undead Horde",,playable,2025-07-30 12:05:05
0100FC301A878000,"Undead Horde 2: Necropolis",,playable,2025-07-30 12:06:07
01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58 01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58
010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46 010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46
01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00 01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00
1 title_id game_name labels status last_updated
188 01003DD00BFEE000 Airheart - Tales of broken Wings playable 2021-02-26 15:20:27
189 01007F100DE52000 Akane nvdec playable 2022-07-21 00:12:18
190 01009A800F0C8000 Akash: Path of the Five gpu;nvdec ingame 2020-12-14 22:33:12
191 01009E8012976000 AKIBA'S TRIP: Hellbound & Debriefed playable 2025-07-30 23:22:47
192 0100D74019A0E000 AKIBA'S TRIP: Undead & Undressed Director's Cut playable 2025-07-31 13:58:42
193 010053100B0EA000 Akihabara - Feel the Rhythm Remixed playable 2021-02-22 14:39:35
194 0100D4C00EE0C000 Akuarium slow playable 2020-12-12 23:43:36
195 010026E00FEBE000 Akuto: Showdown playable 2020-08-04 19:43:27
978 0100416004C00000 DOOM gpu;slow;nvdec;online-broken ingame 2024-09-23 15:40:07
979 010018900DD00000 DOOM (1993) nvdec;online-broken menus 2022-09-06 13:32:19
980 01008CB01E52E000 DOOM + DOOM II opengl;ldn-untested;LAN playable 2024-09-12 07:06:01
981 010029D00E740000 DOOM 3 crash crash;slow menus 2024-08-03 05:25:47
982 01005D700E742000 DOOM 64 nvdec;vulkan playable 2020-10-13 23:47:28
983 0100D4F00DD02000 DOOM II (Classic) nvdec;online playable 2021-06-03 20:10:01
984 0100B1A00D8CE000 DOOM® Eternal gpu;slow;nvdec;online-broken ingame 2024-08-28 15:57:17
1097 0100F9600E746000 ESP Ra.De. Psi audio;slow ingame 2024-03-07 15:05:08
1098 010073000FE18000 Esports powerful pro yakyuu 2020 gpu;crash;Needs More Attention ingame 2024-04-29 05:34:14
1099 01004F9012FD8000 Estranged: The Departure nvdec;UE4 playable 2022-10-24 10:37:58
1100 010018F01E0A0000 Eternights playable 2025-07-30 12:10:24
1101 0100CB900B498000 Eternum Ex playable 2021-01-13 20:28:32
1102 010092501EB2C000 Europa (Demo) gpu;crash;UE4 ingame 2024-04-23 10:47:12
1103 01007BE0160D6000 EVE ghost enemies gpu ingame 2023-01-14 03:13:30
1128 0100034012606000 Family Mysteries: Poisonous Promises audio;crash menus 2021-11-26 12:35:06
1129 010017C012726000 Fantasy Friends playable 2022-10-17 19:42:39
1130 0100767008502000 FANTASY HERO ~unsigned legacy~ playable 2022-07-26 12:28:52
1131 0100755017EE0000 FANTASY LIFE i: The Girl Who Steals Time gpu;crash;vulkan-backend-bug ingame 2025-06-08 20:41:00
1132 0100944003820000 Fantasy Strike online playable 2021-02-27 01:59:18
1133 01000E2012F6E000 Fantasy Tavern Sextet -Vol.1 New World Days- gpu;crash;Needs Update ingame 2022-12-05 16:48:00
1134 01005C10136CA000 Fantasy Tavern Sextet -Vol.2 Adventurer's Days- gpu;slow;crash ingame 2021-11-06 02:57:29
1243 010003F00BD48000 Friday the 13th: Killer Puzzle playable 2021-01-28 01:33:38
1244 010092A00C4B6000 Friday the 13th: The Game Ultimate Slasher Edition nvdec;online-broken;UE4 playable 2022-09-06 17:33:27
1245 0100F200178F4000 FRONT MISSION 1st: Remake playable 2023-06-09 07:44:24
1246 0100C4E018A24000 FRONT MISSION 2: Remake playable 2025-07-30 12:11:23
1247 01007E6019872000 FRONT MISSION 3: Remake playable 2025-07-30 12:12:02
1248 0100861012474000 Frontline Zed playable 2020-10-03 12:55:59
1249 0100B5300B49A000 Frost playable 2022-07-27 12:00:36
1250 010038A007AA4000 FruitFall Crush playable 2020-10-20 11:33:33
1440 0100C2700E338000 Heroland playable 2020-08-05 15:35:39
1441 01007AC00E012000 HexaGravity playable 2021-05-28 13:47:48
1442 01004E800F03C000 Hidden slow ingame 2022-10-05 10:56:53
1443 0100C1101EE5A000 High on Life menus 2025-08-26 19:11:00
1444 0100F6A00A684000 Higurashi no Naku Koro ni Hō audio ingame 2021-09-18 14:40:28
1445 0100F8D0129F4000 Himehibi 1 gakki - Princess Days crash nothing 2021-11-03 08:34:19
1446 0100F3D008436000 Hiragana Pixel Party playable 2021-01-14 08:36:50
1450 0100F7300ED2C000 Hoggy2 playable 2022-10-10 13:53:35
1451 0100F7E00C70E000 Hogwarts Legacy UE4;slow ingame 2024-09-03 19:53:58
1452 0100633007D48000 Hollow Knight nvdec playable 2023-01-16 15:44:56
1453 010013C00E930000 Hollow Knight: Silksong playable 2025-09-04 17:23:22
1454 0100F2100061E800 Hollow0 UE4;gpu ingame 2021-03-03 23:42:56
1455 0100342009E16000 Holy Potatoes! What The Hell?! playable 2020-07-03 10:48:56
1456 010071B00C904000 HoPiKo playable 2021-01-13 20:12:38
1525 010095C016C14000 Iridium playable 2022-08-05 23:19:53
1526 0100AD300B786000 Iris School of Wizardry -Vinculum Hearts- playable 2022-12-05 13:11:15
1527 0100945012168000 Iris.Fall nvdec playable 2022-10-18 13:40:22
1528 010059801B736000 IronFall: Invasion playable 2025-07-30 11:42:30
1529 01005270118D6000 Iron Wings slow ingame 2022-08-07 08:32:57
1530 01004DB003E6A000 IRONCAST playable 2021-01-13 13:54:29
1531 0100E5700CD56000 Irony Curtain: From Matryoshka with Love playable 2021-06-04 20:12:37
1889 010097800EA20000 Monster Energy Supercross - The Official Videogame 3 UE4;audout;nvdec;online playable 2021-06-14 12:37:54
1890 0100E9900ED74000 Monster Farm 32-bit;nvdec playable 2021-05-05 19:29:13
1891 0100770008DD8000 Monster Hunter Generations Ultimate™ 32-bit;online-broken;ldn-works playable 2024-03-18 14:35:36
1892 0100B04011742000 Monster Hunter Rise MONSTER HUNTER RISE gpu;slow;crash;nvdec;online-broken;Needs Update;ldn-works ingame 2024-08-24 11:04:59
1893 010093A01305C000 Monster Hunter Rise Demo online-broken;ldn-works;demo playable 2022-10-18 23:04:17
1894 0100E21011446000 Monster Hunter Stories 2: Wings of Ruin services ingame 2022-07-10 19:27:30
1895 010042501329E000 MONSTER HUNTER STORIES 2: WINGS OF RUIN Trial Version demo playable 2022-11-13 22:20:26
2265 010086F0064CE000 Poi: Explorer Edition nvdec playable 2021-01-21 19:32:00
2266 0100EB6012FD2000 Poison Control playable 2021-05-16 14:01:54
2267 010072400E04A000 Pokémon Café ReMix playable 2021-08-17 20:00:04
2268 010008c01e742000 Pokémon Friends crash;services menus 2025-07-24 13:32:00
2269 01003D200BAA2000 Pokémon Mystery Dungeon™: Rescue Team DX mac-bug playable 2024-01-21 00:16:32
2270 01008DB008C2C000 Pokémon Shield + Pokémon Shield Expansion Pass deadlock;crash;online-broken;ldn-works;LAN ingame 2024-08-12 07:20:22
2271 0100ABF008968000 Pokémon Sword + Pokémon Sword Expansion Pass deadlock;crash;online-broken;ldn-works;LAN ingame 2024-08-26 15:40:37
2314 010077B00BDD8000 Professional Farmer: Nintendo Switch™ Edition slow playable 2020-12-16 13:38:19
2315 010018300C83A000 Professor Lupo and his Horrible Pets playable 2020-06-12 00:08:45
2316 0100D1F0132F6000 Professor Lupo: Ocean playable 2021-04-14 16:33:33
2317 0100C3A017834000 Prodeus playable 2025-07-30 12:07:52
2318 0100BBD00976C000 Project Highrise: Architect's Edition playable 2022-08-10 17:19:12
2319 0100ACE00DAB6000 Project Nimbus: Complete Edition nvdec;UE4;vulkan-backend-bug playable 2022-08-10 17:35:43
2320 01002980140F6000 Project TRIANGLE STRATEGY™ Debut Demo UE4;demo playable 2022-10-24 21:40:27
2446 0100E9C010EA8000 Rise of Insanity playable 2020-08-30 15:42:14
2447 01006BA00E652000 Rise: Race The Future playable 2021-02-27 13:29:06
2448 010020C012F48000 Rising Hell playable 2022-10-31 13:54:02
2449 0100D1801A0F4000 Risk of Rain Returns playable 2025-06-28 04:24:04
2450 010076D00E4BA000 Risk of Rain 2 online-broken playable 2024-03-04 17:01:05
2451 0100E8300A67A000 RISK® Global Domination nvdec;online-broken playable 2022-08-01 18:53:28
2452 010042500FABA000 Ritual: Crown of Horns playable 2021-01-26 16:01:47
2580 0100C610154CA000 Shadowrun: Hong Kong - Extended Edition gpu;Needs Update ingame 2022-10-04 20:53:09
2581 010000000EEF0000 Shadows 2: Perfidia playable 2020-08-07 12:43:46
2582 0100AD700CBBE000 Shadows of Adam playable 2021-01-11 13:35:58
2583 010037A01F96C000 Shadows of the Damned: Hella Remastered playable 2025-09-05 11:34:32
2584 01002A800C064000 Shadowverse Champions Battle playable 2022-10-02 22:59:29
2585 01003B90136DA000 Shadowverse: Champion's Battle crash nothing 2023-03-06 00:31:50
2586 0100820013612000 Shady Part of Me playable 2022-10-20 11:31:55
2758 01005D701264A000 SpyHack playable 2021-04-15 10:53:51
2759 010077B00E046000 Spyro™ Reignited Trilogy nvdec;UE4 playable 2022-09-11 18:38:33
2760 0100085012A0E000 Squeakers playable 2020-12-13 12:13:05
2761 0100E1D01EB2E000 Squeakross: Home Squeak Home playable 2025-06-16 02:02:00
2762 010009300D31C000 Squidgies Takeover playable 2020-07-20 22:28:08
2763 0100FCD0102EC000 Squidlit playable 2020-08-06 12:38:32
2764 0100EBF00E702000 STAR OCEAN First Departure R nvdec playable 2021-07-05 19:29:16
2778 0100E6B0115FC000 Star99 online menus 2021-11-26 14:18:51
2779 01002100137BA000 Stardash playable 2021-01-21 16:31:19
2780 0100E65002BB8000 Stardew Valley online-broken;ldn-untested playable 2024-02-14 03:11:19
2781 01002CC003FE6000 Starlink: Battle for Atlas™ Digital Edition services-horizon;crash;Needs Update nothing playable 2024-05-05 17:25:11 2025-07-30 12:09:37
2782 010098E010FDA000 Starlit Adventures Golden Stars playable 2020-11-21 12:14:43
2783 01001BB00AC26000 STARSHIP AVENGER Operation: Take Back Earth playable 2021-01-12 15:52:55
2784 010000700A572000 State of Anarchy: Master of Mayhem nvdec playable 2021-01-12 19:00:05
2979 0100EBA01548E000 The Cruel King and the Great Hero gpu;services ingame 2022-12-02 07:02:08
2980 010051800E922000 The Dark Crystal: Age of Resistance Tactics playable 2020-08-11 13:43:41
2981 01003DE00918E000 The Darkside Detective playable 2020-06-03 22:16:18
2982 010032B015D66000 The DioField Chronicle playable 2025-09-05 11:35:50
2983 01000A10041EA000 The Elder Scrolls V: Skyrim gpu;crash ingame 2024-07-14 03:21:31
2984 01004A9006B84000 The End Is Nigh playable 2020-06-01 11:26:45
2985 0100CA100489C000 The Escapists 2 nvdec playable 2020-09-24 12:31:31
2987 0100C2E0129A6000 The Executioner nvdec playable 2021-01-23 00:31:28
2988 01006050114D4000 The Experiment: Escape Room gpu ingame 2022-09-30 13:20:35
2989 0100B5900DFB2000 The Eyes of Ara playable 2022-09-16 14:44:06
2990 0100BA5013E52000 The Falconeer: Warrior Edition playable 2025-07-30 12:04:50
2991 01002DD00AF9E000 The Fall gpu ingame 2020-05-31 23:31:16
2992 01003E5002320000 The Fall Part 2: Unbound playable 2021-11-06 02:18:08
2993 0100CDC00789E000 The Final Station nvdec playable 2022-08-22 15:54:39
3031 01009B101044C000 The Legend of Heroes: Trails of Cold Steel III Demo demo;nvdec playable 2021-04-23 01:07:32
3032 0100D3C010DE8000 The Legend of Heroes: Trails of Cold Steel IV nvdec playable 2021-04-23 14:01:05
3033 01005E5013862000 THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改] crash nothing 2021-09-30 14:41:07
3034 01009C901ACEE000 The Legend of Nayuta: Boundless Trails ingame 2025-06-12 15:47
3035 01008CF01BAAC000 The Legend of Zelda Echoes of Wisdom nvdec;ASTC;intel-vendor-bug playable 2024-10-01 14:11:01
3036 0100509005AF2000 The Legend of Zelda: Breath of the Wild Demo demo ingame 2022-12-24 05:02:58
3037 01007EF00011E000 The Legend of Zelda™: Breath of the Wild gpu;amd-vendor-bug;mac-bug ingame 2024-09-23 19:35:46
3210 010000400F582000 TT Isle of Man Ride on the Edge 2 gpu;nvdec;online-broken ingame 2022-09-30 22:13:05
3211 0100752011628000 TTV2 playable 2020-11-27 13:21:36
3212 0100AFE00452E000 Tumblestone playable 2021-01-07 17:49:20
3213 0100D1A01D7BA000 Turbo Overkill playable 2025-07-30 12:08:57
3214 010085500D5F6000 Turok gpu ingame 2021-06-04 13:16:24
3215 0100CDC00D8D6000 Turok 2: Seeds of Evil gpu;vulkan ingame 2022-09-12 17:50:05
3216 010004B0130C8000 Turrican Flashback audout playable 2021-08-30 10:07:56
3234 0100592005164000 UNBOX: Newbie's Adventure UE4 playable 2022-08-29 13:12:56
3235 01002D900C5E4000 Uncanny Valley nvdec playable 2021-06-04 13:28:45
3236 010076F011F54000 Undead & Beyond nvdec playable 2022-10-04 09:11:18
3237 01009B700D0B8000 Undead Horde playable 2025-07-30 12:05:05
3238 0100FC301A878000 Undead Horde 2: Necropolis playable 2025-07-30 12:06:07
3239 01008F3013E4E000 Under Leaves playable 2021-05-22 18:13:58
3240 010080B00AD66000 Undertale playable 2022-08-31 17:31:46
3241 01008F80049C6000 Unepic playable 2024-01-15 17:03:00

View File

@@ -4,18 +4,20 @@
<packageSources> <packageSources>
<clear /> <clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" /> <add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />
<add key="RyubingPkgs" value="https://git.ryujinx.app/api/v4/projects/1/packages/nuget/index.json" /> <add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
</packageSources> </packageSources>
<!-- Define mappings by adding package patterns beneath the target source. -->
<!-- Ryujinx.LibHac packages will be restored from LibHacAlpha,
everything else from nuget.org. -->
<packageSourceMapping> <packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element --> <!-- key value for <packageSource> should match key values from <packageSources> element -->
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
<packageSource key="nuget.org"> <packageSource key="nuget.org">
<package pattern="*" /> <package pattern="*" />
</packageSource> </packageSource>
<packageSource key="Ryujinx.UpdateClient">
<package pattern="Ryujinx.UpdateClient" />
<package pattern="Ryujinx.Systems.Update.Common" />
</packageSource>
<packageSource key="LibHacAlpha"> <packageSource key="LibHacAlpha">
<package pattern="Ryujinx.LibHac" /> <package pattern="Ryujinx.LibHac" />
</packageSource> </packageSource>

View File

@@ -7,7 +7,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" /> <ProjectReference Include="..\Ryujinx.Memory\Ryujinx.Memory.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsMemoryLoadOrStore(Instruction inst) private static bool IsMemoryLoadOrStore(Instruction inst)
{ {
return inst == Instruction.Load || inst == Instruction.Store; return inst is Instruction.Load or Instruction.Store;
} }
private static bool ConstTooLong(Operand constOp, OperandType accessType) private static bool ConstTooLong(Operand constOp, OperandType accessType)

View File

@@ -774,6 +774,7 @@ namespace ARMeilleure.CodeGen.Arm64
instI |= 1 << 22; // sh flag instI |= 1 << 22; // sh flag
imm >>= 12; imm >>= 12;
} }
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn); WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
} }
else else

View File

@@ -52,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
// Any value AND all ones will be equal itself, so it's effectively a no-op. // Any value AND all ones will be equal itself, so it's effectively a no-op.
// Any value OR all ones will be equal all ones, so one can just use MOV. // Any value OR all ones will be equal all ones, so one can just use MOV.
// Any value XOR all ones will be equal its inverse, so one can just use MVN. // Any value XOR all ones will be equal its inverse, so one can just use MVN.
if (value == 0 || value == ulong.MaxValue) if (value is 0 or ulong.MaxValue)
{ {
immN = 0; immN = 0;
immS = 0; immS = 0;

View File

@@ -1,6 +1,7 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -14,7 +15,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4; private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4; private const int LdrLitInstLength = 4;
private readonly Stream _stream; private readonly RecyclableMemoryStream _stream;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;

View File

@@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
// The only blocks which can have 0 successors are exit blocks. // The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last; Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall || Debug.Assert(last.Instruction is Instruction.Tailcall or
last.Instruction == Instruction.Return); Instruction.Return);
} }
else else
{ {
@@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type); Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type != OperandType.V128); Debug.Assert(source.Type != OperandType.V128);
@@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type); Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type.IsInteger()); Debug.Assert(source.Type.IsInteger());
@@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsLoadOrStore(Operation operation) private static bool IsLoadOrStore(Operation operation)
{ {
return operation.Instruction == Instruction.Load || operation.Instruction == Instruction.Store; return operation.Instruction is Instruction.Load or Instruction.Store;
} }
private static OperandType GetMemOpValueType(Operation operation) private static OperandType GetMemOpValueType(Operation operation)
@@ -1499,6 +1499,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
} }
if (memOp.Index != default) if (memOp.Index != default)
{ {
return false; return false;
@@ -1553,7 +1554,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void EnsureSameReg(Operand op1, Operand op2) private static void EnsureSameReg(Operand op1, Operand op2)
{ {
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory); Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind); Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value); Debug.Assert(op1.Value == op2.Value);
} }

View File

@@ -509,7 +509,6 @@ namespace ARMeilleure.CodeGen.Arm64
context.Assembler.WriteInstruction(instruction, rd, rn); context.Assembler.WriteInstruction(instruction, rd, rn);
} }
} }
private static void GenerateScalarTernary( private static void GenerateScalarTernary(

View File

@@ -137,6 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
return val != 0; return val != 0;
} }
return false; return false;
} }

View File

@@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask)); IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
return info.Type == IntrinsicType.ScalarBinaryRd || return info.Type is IntrinsicType.ScalarBinaryRd or
info.Type == IntrinsicType.ScalarTernaryFPRdByElem || IntrinsicType.ScalarTernaryFPRdByElem or
info.Type == IntrinsicType.ScalarTernaryShlRd || IntrinsicType.ScalarTernaryShlRd or
info.Type == IntrinsicType.ScalarTernaryShrRd || IntrinsicType.ScalarTernaryShrRd or
info.Type == IntrinsicType.Vector128BinaryRd || IntrinsicType.Vector128BinaryRd or
info.Type == IntrinsicType.VectorBinaryRd || IntrinsicType.VectorBinaryRd or
info.Type == IntrinsicType.VectorInsertByElem || IntrinsicType.VectorInsertByElem or
info.Type == IntrinsicType.VectorTernaryRd || IntrinsicType.VectorTernaryRd or
info.Type == IntrinsicType.VectorTernaryRdBitwise || IntrinsicType.VectorTernaryRdBitwise or
info.Type == IntrinsicType.VectorTernaryFPRdByElem || IntrinsicType.VectorTernaryFPRdByElem or
info.Type == IntrinsicType.VectorTernaryRdByElem || IntrinsicType.VectorTernaryRdByElem or
info.Type == IntrinsicType.VectorTernaryShlRd || IntrinsicType.VectorTernaryShlRd or
info.Type == IntrinsicType.VectorTernaryShrRd; IntrinsicType.VectorTernaryShrRd;
} }
private static bool HasConstSrc1(Operation node, ulong value) private static bool HasConstSrc1(Operation node, ulong value)
@@ -849,7 +849,7 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
} }
@@ -871,9 +871,9 @@ namespace ARMeilleure.CodeGen.Arm64
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask)); IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
// Those have integer inputs that don't support consts. // Those have integer inputs that don't support consts.
return info.Type != IntrinsicType.ScalarFPConvGpr && return info.Type is not IntrinsicType.ScalarFPConvGpr and
info.Type != IntrinsicType.ScalarFPConvFixedGpr && not IntrinsicType.ScalarFPConvFixedGpr and
info.Type != IntrinsicType.SetRegister; not IntrinsicType.SetRegister;
} }
return false; return false;

View File

@@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x + y); EvaluateBinaryI64(operation, (x, y) => x + y);
} }
break; break;
case Instruction.BitwiseAnd: case Instruction.BitwiseAnd:
@@ -48,6 +49,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x & y); EvaluateBinaryI64(operation, (x, y) => x & y);
} }
break; break;
case Instruction.BitwiseExclusiveOr: case Instruction.BitwiseExclusiveOr:
@@ -59,6 +61,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x ^ y); EvaluateBinaryI64(operation, (x, y) => x ^ y);
} }
break; break;
case Instruction.BitwiseNot: case Instruction.BitwiseNot:
@@ -70,6 +73,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => ~x); EvaluateUnaryI64(operation, (x) => ~x);
} }
break; break;
case Instruction.BitwiseOr: case Instruction.BitwiseOr:
@@ -81,6 +85,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x | y); EvaluateBinaryI64(operation, (x, y) => x | y);
} }
break; break;
case Instruction.ConvertI64ToI32: case Instruction.ConvertI64ToI32:
@@ -88,6 +93,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI32(operation, (x) => x); EvaluateUnaryI32(operation, (x) => x);
} }
break; break;
case Instruction.Compare: case Instruction.Compare:
@@ -129,6 +135,7 @@ namespace ARMeilleure.CodeGen.Optimizations
break; break;
} }
} }
break; break;
case Instruction.Copy: case Instruction.Copy:
@@ -140,6 +147,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => x); EvaluateUnaryI64(operation, (x) => x);
} }
break; break;
case Instruction.Divide: case Instruction.Divide:
@@ -151,6 +159,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0); EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
} }
break; break;
case Instruction.DivideUI: case Instruction.DivideUI:
@@ -162,6 +171,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0); EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
} }
break; break;
case Instruction.Multiply: case Instruction.Multiply:
@@ -173,6 +183,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x * y); EvaluateBinaryI64(operation, (x, y) => x * y);
} }
break; break;
case Instruction.Negate: case Instruction.Negate:
@@ -184,6 +195,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => -x); EvaluateUnaryI64(operation, (x) => -x);
} }
break; break;
case Instruction.ShiftLeft: case Instruction.ShiftLeft:
@@ -195,6 +207,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x << (int)y); EvaluateBinaryI64(operation, (x, y) => x << (int)y);
} }
break; break;
case Instruction.ShiftRightSI: case Instruction.ShiftRightSI:
@@ -206,6 +219,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x >> (int)y); EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
} }
break; break;
case Instruction.ShiftRightUI: case Instruction.ShiftRightUI:
@@ -217,6 +231,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y)); EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
} }
break; break;
case Instruction.SignExtend16: case Instruction.SignExtend16:
@@ -228,6 +243,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (short)x); EvaluateUnaryI64(operation, (x) => (short)x);
} }
break; break;
case Instruction.SignExtend32: case Instruction.SignExtend32:
@@ -239,6 +255,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (int)x); EvaluateUnaryI64(operation, (x) => (int)x);
} }
break; break;
case Instruction.SignExtend8: case Instruction.SignExtend8:
@@ -250,6 +267,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (sbyte)x); EvaluateUnaryI64(operation, (x) => (sbyte)x);
} }
break; break;
case Instruction.ZeroExtend16: case Instruction.ZeroExtend16:
@@ -261,6 +279,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (ushort)x); EvaluateUnaryI64(operation, (x) => (ushort)x);
} }
break; break;
case Instruction.ZeroExtend32: case Instruction.ZeroExtend32:
@@ -272,6 +291,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (uint)x); EvaluateUnaryI64(operation, (x) => (uint)x);
} }
break; break;
case Instruction.ZeroExtend8: case Instruction.ZeroExtend8:
@@ -283,6 +303,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateUnaryI64(operation, (x) => (byte)x); EvaluateUnaryI64(operation, (x) => (byte)x);
} }
break; break;
case Instruction.Subtract: case Instruction.Subtract:
@@ -294,6 +315,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{ {
EvaluateBinaryI64(operation, (x, y) => x - y); EvaluateBinaryI64(operation, (x, y) => x - y);
} }
break; break;
} }
} }

View File

@@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
private static bool HasSideEffects(Operation node) private static bool HasSideEffects(Operation node)
{ {
return node.Instruction == Instruction.Call return node.Instruction is Instruction.Call
|| node.Instruction == Instruction.Tailcall or Instruction.Tailcall
|| node.Instruction == Instruction.CompareAndSwap or Instruction.CompareAndSwap
|| node.Instruction == Instruction.CompareAndSwap16 or Instruction.CompareAndSwap16
|| node.Instruction == Instruction.CompareAndSwap8; or Instruction.CompareAndSwap8;
} }
private static bool IsPropagableCompare(Operation operation) private static bool IsPropagableCompare(Operation operation)

View File

@@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// If this is a copy (or copy-like operation), set the copy source interval as well. // If this is a copy (or copy-like operation), set the copy source interval as well.
// This is used for register preferencing later on, which allows the copy to be eliminated // This is used for register preferencing later on, which allows the copy to be eliminated
// in some cases. // in some cases.
if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32) if (node.Instruction is Instruction.Copy or Instruction.ZeroExtend32)
{ {
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
@@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static bool IsLocalOrRegister(OperandKind kind) private static bool IsLocalOrRegister(OperandKind kind)
{ {
return kind == OperandKind.LocalVariable || return kind is OperandKind.LocalVariable or
kind == OperandKind.Register; OperandKind.Register;
} }
} }
} }

View File

@@ -1478,7 +1478,7 @@ namespace ARMeilleure.CodeGen.X86
private static bool Is64Bits(OperandType type) private static bool Is64Bits(OperandType type)
{ {
return type == OperandType.I64 || type == OperandType.FP64; return type is OperandType.I64 or OperandType.FP64;
} }
private static bool IsImm8(ulong immediate, OperandType type) private static bool IsImm8(ulong immediate, OperandType type)

View File

@@ -13,7 +13,6 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0; private const int BadOp = 0;
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags private enum InstructionFlags
{ {
None = 0, None = 0,

View File

@@ -1,5 +1,6 @@
using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System.IO; using System.IO;
using System.Numerics; using System.Numerics;
@@ -8,7 +9,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
class CodeGenContext class CodeGenContext
{ {
private readonly Stream _stream; private readonly RecyclableMemoryStream _stream;
private readonly Operand[] _blockLabels; private readonly Operand[] _blockLabels;
public int StreamOffset => (int)_stream.Length; public int StreamOffset => (int)_stream.Length;

View File

@@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
// The only blocks which can have 0 successors are exit blocks. // The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last; Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall || Debug.Assert(last.Instruction is Instruction.Tailcall or
last.Instruction == Instruction.Return); Instruction.Return);
} }
else else
{ {
@@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(HardwareCapabilities.SupportsVexEncoding); Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register); Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory); Debug.Assert(src3.Kind is OperandKind.Register or OperandKind.Memory);
EnsureSameType(dest, src1, src2, src3); EnsureSameType(dest, src1, src2, src3);
Debug.Assert(dest.Type == OperandType.V128); Debug.Assert(dest.Type == OperandType.V128);
@@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = operation.Destination; Operand dest = operation.Destination;
Operand source = operation.GetSource(0); Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64); Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
if (dest.Type == OperandType.FP32) if (dest.Type == OperandType.FP32)
{ {
@@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
return; return;
} }
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory); Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind); Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value); Debug.Assert(op1.Value == op2.Value);
} }

View File

@@ -66,6 +66,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertCallCopies(block.Operations, node); PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
} }
break; break;
case Instruction.ConvertToFPUI: case Instruction.ConvertToFPUI:
@@ -81,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node); nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
} }
break; break;
case Instruction.Negate: case Instruction.Negate:
@@ -88,6 +90,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
GenerateNegate(block.Operations, node); GenerateNegate(block.Operations, node);
} }
break; break;
case Instruction.Return: case Instruction.Return:
@@ -99,6 +102,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node); PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
} }
break; break;
case Instruction.Tailcall: case Instruction.Tailcall:
@@ -110,6 +114,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node); PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
} }
break; break;
case Instruction.VectorInsert8: case Instruction.VectorInsert8:
@@ -117,6 +122,7 @@ namespace ARMeilleure.CodeGen.X86
{ {
GenerateVectorInsert8(block.Operations, node); GenerateVectorInsert8(block.Operations, node);
} }
break; break;
case Instruction.Extended: case Instruction.Extended:
@@ -132,6 +138,7 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources([Const(stackOffset)]); node.SetSources([Const(stackOffset)]);
} }
break; break;
} }
} }
@@ -312,9 +319,9 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Extended: case Instruction.Extended:
{ {
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd || bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
node.Intrinsic == Intrinsic.X86Blendvps || Intrinsic.X86Blendvps or
node.Intrinsic == Intrinsic.X86Pblendvb; Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported. // BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
// SHA256RNDS2 always has an implied XMM0 as a last operand. // SHA256RNDS2 always has an implied XMM0 as a last operand.
@@ -513,8 +520,8 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = node.Destination; Operand dest = node.Destination;
Operand source = node.GetSource(0); Operand source = node.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || Debug.Assert(dest.Type is OperandType.FP32 or
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\"."); OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Operation currentNode = node; Operation currentNode = node;
@@ -761,7 +768,7 @@ namespace ARMeilleure.CodeGen.X86
Comparison compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType is Comparison.Equal or Comparison.NotEqual;
} }
} }

View File

@@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
private static bool IsMemoryLoadOrStore(Instruction inst) private static bool IsMemoryLoadOrStore(Instruction inst)
{ {
return inst == Instruction.Load || return inst is Instruction.Load or
inst == Instruction.Load16 || Instruction.Load16 or
inst == Instruction.Load8 || Instruction.Load8 or
inst == Instruction.Store || Instruction.Store or
inst == Instruction.Store16 || Instruction.Store16 or
inst == Instruction.Store8; Instruction.Store8;
} }
} }
} }

View File

@@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86 namespace ARMeilleure.CodeGen.X86
{ {
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum X86Register enum X86Register
{ {
Invalid = -1, Invalid = -1,

View File

@@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
} }
// Compare and branch instructions are always conditional. // Compare and branch instructions are always conditional.
if (opCode.Instruction.Name == InstName.Cbz || if (opCode.Instruction.Name is InstName.Cbz or
opCode.Instruction.Name == InstName.Cbnz) InstName.Cbnz)
{ {
return false; return false;
} }
@@ -274,9 +274,10 @@ namespace ARMeilleure.Decoders
{ {
if (opCode is OpCodeT32) if (opCode is OpCodeT32)
{ {
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq && return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn; not InstName.Cmp and not InstName.Cmn;
} }
return true; return true;
} }
@@ -284,7 +285,7 @@ namespace ARMeilleure.Decoders
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is // register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
// a write back to PC (wback == true && Rn == 15), however the later may // a write back to PC (wback == true && Rn == 15), however the later may
// be "undefined" depending on the CPU, so compilers should not produce that. // be "undefined" depending on the CPU, so compilers should not produce that.
if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult) if (opCode is IOpCode32Mem or IOpCode32MemMult)
{ {
int rt, rn; int rt, rn;
@@ -326,15 +327,15 @@ namespace ARMeilleure.Decoders
} }
// Explicit branch instructions. // Explicit branch instructions.
return opCode is IOpCode32BImm || return opCode is IOpCode32BImm or
opCode is IOpCode32BReg; IOpCode32BReg;
} }
private static bool IsCall(OpCode opCode) private static bool IsCall(OpCode opCode)
{ {
return opCode.Instruction.Name == InstName.Bl || return opCode.Instruction.Name is InstName.Bl or
opCode.Instruction.Name == InstName.Blr || InstName.Blr or
opCode.Instruction.Name == InstName.Blx; InstName.Blx;
} }
private static bool IsException(OpCode opCode) private static bool IsException(OpCode opCode)
@@ -344,9 +345,9 @@ namespace ARMeilleure.Decoders
private static bool IsTrap(OpCode opCode) private static bool IsTrap(OpCode opCode)
{ {
return opCode.Instruction.Name == InstName.Brk || return opCode.Instruction.Name is InstName.Brk or
opCode.Instruction.Name == InstName.Trap || InstName.Trap or
opCode.Instruction.Name == InstName.Und; InstName.Und;
} }
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode) public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)

View File

@@ -162,6 +162,7 @@ namespace ARMeilleure.Decoders
} }
} }
} }
return false; return false;
} }
} }

View File

@@ -20,6 +20,7 @@ namespace ARMeilleure.Decoders
Instruction = InstDescriptor.Undefined; Instruction = InstDescriptor.Undefined;
return; return;
} }
Q = ((opCode >> 21) & 0x1) != 0; Q = ((opCode >> 21) & 0x1) != 0;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;

View File

@@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf; Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc; WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp; RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
Regs = _regsMap[(opCode >> 8) & 0xf]; Regs = _regsMap[(opCode >> 8) & 0xf];

View File

@@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf; Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc; WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp; RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
} }
} }
} }

View File

@@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned; MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
PostIdx = type == MemOp.PostIndexed; PostIdx = type == MemOp.PostIndexed;
Unscaled = type == MemOp.Unscaled || Unscaled = type is MemOp.Unscaled or
type == MemOp.Unprivileged; MemOp.Unprivileged;
// Unscaled and Unprivileged doesn't write back, // Unscaled and Unprivileged doesn't write back,
// but they do use the 9-bits Signed Immediate. // but they do use the 9-bits Signed Immediate.

View File

@@ -1381,6 +1381,7 @@ namespace ARMeilleure.Decoders
{ {
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}"; thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
} }
SetT32(thumbEncoding, name, emitter, makeOpT32); SetT32(thumbEncoding, name, emitter, makeOpT32);
} }
@@ -1409,6 +1410,7 @@ namespace ARMeilleure.Decoders
{ {
throw new ArgumentException("Invalid ASIMD instruction encoding"); throw new ArgumentException("Invalid ASIMD instruction encoding");
} }
SetT32(thumbEncoding, name, emitter, makeOpT32); SetT32(thumbEncoding, name, emitter, makeOpT32);
} }

View File

@@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
{ {
class IRDumper class IRDumper
{ {
private const string Indentation = " "; private const char Indentation = ' ';
private int _indentLevel; private int _indentLevel;
@@ -30,14 +30,11 @@ namespace ARMeilleure.Diagnostics
private void Indent() private void Indent()
{ {
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length); if (_indentLevel == 0)
return;
for (int index = 0; index < _indentLevel; index++) _builder.EnsureCapacity(_builder.Capacity + _indentLevel);
{ _builder.Append(Indentation, _indentLevel);
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
_builder.Append(Indentation);
#pragma warning restore CA1834
}
} }
private void IncreaseIndentation() private void IncreaseIndentation()
@@ -235,8 +232,8 @@ namespace ARMeilleure.Diagnostics
{ {
_builder.Append('.').Append(operation.Intrinsic); _builder.Append('.').Append(operation.Intrinsic);
} }
else if (operation.Instruction == Instruction.BranchIf || else if (operation.Instruction is Instruction.BranchIf or
operation.Instruction == Instruction.Compare) Instruction.Compare)
{ {
comparison = true; comparison = true;
} }
@@ -262,6 +259,7 @@ namespace ARMeilleure.Diagnostics
DumpOperand(source); DumpOperand(source);
} }
} }
break; break;
} }

View File

@@ -899,6 +899,7 @@ namespace ARMeilleure.Instructions
{ {
n = context.ShiftLeft(n, Const(shift)); n = context.ShiftLeft(n, Const(shift));
} }
break; break;
case ShiftType.Asr: case ShiftType.Asr:
if (shift == 32) if (shift == 32)
@@ -909,6 +910,7 @@ namespace ARMeilleure.Instructions
{ {
n = context.ShiftRightSI(n, Const(shift)); n = context.ShiftRightSI(n, Const(shift));
} }
break; break;
} }

View File

@@ -266,7 +266,7 @@ namespace ARMeilleure.Instructions
} }
} }
private static Exception InvalidOpCodeType(OpCode opCode) private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{ {
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\"."); return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
} }
@@ -318,6 +318,7 @@ namespace ARMeilleure.Instructions
{ {
m = GetRrxC(context, m, setCarry); m = GetRrxC(context, m, setCarry);
} }
break; break;
} }
} }

View File

@@ -143,6 +143,12 @@ namespace ARMeilleure.Instructions
public static void EmitCall(ArmEmitterContext context, ulong immediate) public static void EmitCall(ArmEmitterContext context, ulong immediate)
{ {
if (context.IsSingleStep)
{
context.Return(Const(immediate));
return;
}
bool isRecursive = immediate == context.EntryAddress; bool isRecursive = immediate == context.EntryAddress;
if (isRecursive) if (isRecursive)
@@ -157,12 +163,24 @@ namespace ARMeilleure.Instructions
public static void EmitVirtualCall(ArmEmitterContext context, Operand target) public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
{ {
EmitTableBranch(context, target, isJump: false); if (context.IsSingleStep)
{
if (target.Type == OperandType.I32)
{
target = context.ZeroExtend32(OperandType.I64, target);
}
context.Return(target);
}
else
{
EmitTableBranch(context, target, isJump: false);
}
} }
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn) public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
{ {
if (isReturn) if (isReturn || context.IsSingleStep)
{ {
if (target.Type == OperandType.I32) if (target.Type == OperandType.I32)
{ {

View File

@@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli) public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
{ {
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger()); Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
Debug.Assert(size >= 0 && size < 4); Debug.Assert(size is >= 0 and < 4);
Debug.Assert((size < 3) || (value.Type == OperandType.I64)); Debug.Assert((size < 3) || (value.Type == OperandType.I64));
if (castagnoli && Optimizations.UseSse42) if (castagnoli && Optimizations.UseSse42)

View File

@@ -90,6 +90,7 @@ namespace ARMeilleure.Instructions
{ {
value = context.ConvertI64ToI32(value); value = context.ConvertI64ToI32(value);
} }
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32); Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
context.Copy(reg, value); context.Copy(reg, value);

View File

@@ -140,7 +140,7 @@ namespace ARMeilleure.Instructions
if (pair) if (pair)
{ {
Debug.Assert(op.Size == 2 || op.Size == 3, "Invalid size for pairwise store."); Debug.Assert(op.Size is 2 or 3, "Invalid size for pairwise store.");
Operand t2 = GetIntOrZR(context, op.Rt2); Operand t2 = GetIntOrZR(context, op.Rt2);

View File

@@ -42,6 +42,7 @@ namespace ARMeilleure.Instructions
{ {
context.Store(exValuePtr, Const(0UL)); context.Store(exValuePtr, Const(0UL));
} }
if (size < 4) if (size < 4)
{ {
context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL)); context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL));

View File

@@ -59,7 +59,7 @@ namespace ARMeilleure.Instructions
{ {
Operand value = GetInt(context, rt); Operand value = GetInt(context, rt);
if (ext == Extension.Sx32 || ext == Extension.Sx64) if (ext is Extension.Sx32 or Extension.Sx64)
{ {
OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32; OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32;
@@ -123,9 +123,9 @@ namespace ARMeilleure.Instructions
private static bool IsSimd(ArmEmitterContext context) private static bool IsSimd(ArmEmitterContext context)
{ {
return context.CurrOp is IOpCodeSimd && return context.CurrOp is IOpCodeSimd and
!(context.CurrOp is OpCodeSimdMemMs || not (OpCodeSimdMemMs or
context.CurrOp is OpCodeSimdMemSs); OpCodeSimdMemSs);
} }
public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size) public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size)
@@ -717,7 +717,7 @@ namespace ARMeilleure.Instructions
}; };
} }
private static Exception InvalidOpCodeType(OpCode opCode) private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{ {
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\"."); return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
} }
@@ -768,6 +768,7 @@ namespace ARMeilleure.Instructions
{ {
m = InstEmitAluHelper.GetRrxC(context, m, setCarry); m = InstEmitAluHelper.GetRrxC(context, m, setCarry);
} }
break; break;
} }
} }

View File

@@ -33,7 +33,6 @@ namespace ARMeilleure.Instructions
public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract); public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum MullFlags private enum MullFlags
{ {
Subtract = 0, Subtract = 0,

View File

@@ -5266,7 +5266,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift) private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift)
{ {
// The upper part of op is assumed to be zero. // The upper part of op is assumed to be zero.
Debug.Assert(shift >= 0 && shift < 64); Debug.Assert(shift is >= 0 and < 64);
if (shift == 0) if (shift == 0)
{ {

View File

@@ -231,10 +231,12 @@ namespace ARMeilleure.Instructions
{ {
result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8); result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8);
} }
for (int i = 8; i < 16; i++) for (int i = 8; i < 16; i++)
{ {
result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8); result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8);
} }
return (result2, result); return (result2, result);
} }
@@ -261,6 +263,7 @@ namespace ARMeilleure.Instructions
nMaskHigh = nMaskLow + 0x0808080808080808L; nMaskHigh = nMaskLow + 0x0808080808080808L;
mMaskHigh = mMaskLow + 0x0808080808080808L; mMaskHigh = mMaskLow + 0x0808080808080808L;
} }
nMask = X86GetElements(context, nMaskHigh, nMaskLow); nMask = X86GetElements(context, nMaskHigh, nMaskLow);
mMask = X86GetElements(context, mMaskHigh, mMaskLow); mMask = X86GetElements(context, mMaskHigh, mMaskLow);
Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask); Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask);
@@ -285,6 +288,7 @@ namespace ARMeilleure.Instructions
{ {
extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size); extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size);
} }
byteOff++; byteOff++;
res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size); res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size);
@@ -1304,6 +1308,7 @@ namespace ARMeilleure.Instructions
case 2: case 2:
return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6))); return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6)));
} }
break; break;
case 2: case 2:
// Rev32 // Rev32
@@ -1316,6 +1321,7 @@ namespace ARMeilleure.Instructions
mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L); mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L);
return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask); return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask);
} }
break; break;
case 1: case 1:
// Rev16 // Rev16
@@ -1341,6 +1347,7 @@ namespace ARMeilleure.Instructions
case 3: case 3:
return context.ByteSwap(op1); return context.ByteSwap(op1);
} }
break; break;
case 1: case 1:
switch (op.Size) switch (op.Size)
@@ -1355,6 +1362,7 @@ namespace ARMeilleure.Instructions
context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)), context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)),
context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16)))); context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16))));
} }
break; break;
case 2: case 2:
// Swap upper and lower halves. // Swap upper and lower halves.

View File

@@ -1119,7 +1119,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed) private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed)
{ {
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
Debug.Assert((uint)size < 2); Debug.Assert((uint)size < 2);
OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64; OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64;
@@ -1136,7 +1136,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits); value = EmitF2iFBitsMul(context, value, fBits);
@@ -1160,7 +1160,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits); value = EmitF2iFBitsMul(context, value, fBits);
@@ -1184,7 +1184,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0) if (fBits == 0)
{ {
@@ -1203,7 +1203,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits) private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64); Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0) if (fBits == 0)
{ {

View File

@@ -385,6 +385,7 @@ namespace ARMeilleure.Instructions
{ {
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res); res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
} }
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
res = context.VectorExtract16(res, 0); res = context.VectorExtract16(res, 0);
InsertScalar16(context, op.Vd, op.T, res); InsertScalar16(context, op.Vd, op.T, res);
@@ -397,6 +398,7 @@ namespace ARMeilleure.Instructions
{ {
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res); res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
} }
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0); res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
InsertScalar(context, op.Vd, res); InsertScalar(context, op.Vd, res);
} }
@@ -635,7 +637,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed) private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed)
{ {
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
if (signed) if (signed)
{ {

View File

@@ -363,7 +363,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.). public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
{ {
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64); Debug.Assert(op.Type is OperandType.I32 or OperandType.I64);
Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L))); Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L)));
@@ -489,7 +489,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op) public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op)
{ {
Debug.Assert(op.Type == OperandType.FP32 || op.Type == OperandType.FP64); Debug.Assert(op.Type is OperandType.FP32 or OperandType.FP64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lbl2 = Label(); Operand lbl2 = Label();
@@ -1676,7 +1676,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -1709,7 +1709,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -1735,7 +1735,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst; int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32); Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -1768,7 +1768,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst; int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32); Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lblEnd = Label(); Operand lblEnd = Label();

View File

@@ -31,7 +31,7 @@ namespace ARMeilleure.Instructions
{ {
Debug.Assert(type != OperandType.V128); Debug.Assert(type != OperandType.V128);
if (type == OperandType.FP64 || type == OperandType.I64) if (type is OperandType.FP64 or OperandType.I64)
{ {
// From dreg. // From dreg.
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1); return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
@@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(value.Type != OperandType.V128); Debug.Assert(value.Type != OperandType.V128);
Operand vec, insert; Operand vec, insert;
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64) if (value.Type is OperandType.FP64 or OperandType.I64)
{ {
// From dreg. // From dreg.
vec = GetVecA32(reg >> 1); vec = GetVecA32(reg >> 1);
@@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions
public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value) public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value)
{ {
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.I32); Debug.Assert(value.Type is OperandType.FP32 or OperandType.I32);
Operand vec, insert; Operand vec, insert;
vec = GetVecA32(reg >> 2); vec = GetVecA32(reg >> 2);
@@ -880,6 +880,7 @@ namespace ARMeilleure.Instructions
{ {
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd); res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
} }
res = EmitDoubleWordInsert(context, d, res, op.Vd); res = EmitDoubleWordInsert(context, d, res, op.Vd);
} }

View File

@@ -146,6 +146,7 @@ namespace ARMeilleure.Instructions
{ {
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd); res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
} }
res = EmitDoubleWordInsert(context, d, res, op.Vd); res = EmitDoubleWordInsert(context, d, res, op.Vd);
} }

View File

@@ -268,6 +268,7 @@ namespace ARMeilleure.Instructions
{ {
m = context.BitwiseNot(m); m = context.BitwiseNot(m);
} }
return context.BitwiseExclusiveOr( return context.BitwiseExclusiveOr(
context.BitwiseAnd(m, context.BitwiseAnd(m,
context.BitwiseExclusiveOr(d, n)), d); context.BitwiseExclusiveOr(d, n)), d);

View File

@@ -110,6 +110,7 @@ namespace ARMeilleure.Instructions
EmitStoreSimd(context, address, d >> 1, index, op.Size); EmitStoreSimd(context, address, d >> 1, index, op.Size);
} }
} }
offset += eBytes; offset += eBytes;
d += op.Increment; d += op.Increment;
} }

View File

@@ -1634,7 +1634,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand res = context.AllocateLocal(OperandType.I64); Operand res = context.AllocateLocal(OperandType.I64);
@@ -1657,7 +1657,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size; int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -1732,7 +1732,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32); Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -1769,7 +1769,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64); Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32); Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64); Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label(); Operand lbl1 = Label();
Operand lbl2 = Label(); Operand lbl2 = Label();
@@ -1813,6 +1813,7 @@ namespace ARMeilleure.Instructions
? EmitSignedSrcSatQ(context, shl, size, signedDst: true) ? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false)); : EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
@@ -1850,6 +1851,7 @@ namespace ARMeilleure.Instructions
{ {
context.Copy(res, sar); context.Copy(res, sar);
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
@@ -1906,6 +1908,7 @@ namespace ARMeilleure.Instructions
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one))); Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right)); context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
} }
context.Branch(lblEnd); context.Branch(lblEnd);
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);

View File

@@ -3,6 +3,7 @@ using ARMeilleure.State;
using ARMeilleure.Translation; using ARMeilleure.Translation;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ExecutionContext = ARMeilleure.State.ExecutionContext;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
{ {
@@ -69,13 +70,13 @@ namespace ARMeilleure.Instructions
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
public static ulong GetCtrEl0() public static ulong GetCtrEl0()
{ {
return GetContext().CtrEl0; return ExecutionContext.CtrEl0;
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
public static ulong GetDczidEl0() public static ulong GetDczidEl0()
{ {
return GetContext().DczidEl0; return ExecutionContext.DczidEl0;
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
@@ -200,7 +201,11 @@ namespace ARMeilleure.Instructions
ExecutionContext context = GetContext(); ExecutionContext context = GetContext();
context.CheckInterrupt(); // If debugging, we'll handle interrupts outside
if (!Optimizations.EnableDebugging)
{
context.CheckInterrupt();
}
Statistics.ResumeTimer(); Statistics.ResumeTimer();

View File

@@ -24,7 +24,7 @@ namespace ARMeilleure.Instructions
{ {
uint src = (uint)idx + 256u; uint src = (uint)idx + 256u;
Debug.Assert(256u <= src && src < 512u); Debug.Assert(src is >= 256u and < 512u);
src = (src << 1) + 1u; src = (src << 1) + 1u;
@@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1; uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u); Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u); tbl[idx] = (byte)(dst - 256u);
} }
@@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
{ {
uint src = (uint)idx + 128u; uint src = (uint)idx + 128u;
Debug.Assert(128u <= src && src < 512u); Debug.Assert(src is >= 128u and < 512u);
if (src < 256u) if (src < 256u)
{ {
@@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1; uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u); Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u); tbl[idx] = (byte)(dst - 256u);
} }
@@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if ((context.Fpcr & FPCR.Dn) != 0) if ((context.Fpcr & FPCR.Dn) != 0)
{ {
@@ -498,7 +498,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if ((context.Fpcr & FPCR.Dn) != 0) if ((context.Fpcr & FPCR.Dn) != 0)
{ {
@@ -676,7 +676,7 @@ namespace ARMeilleure.Instructions
ushort resultBits; ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if (altHp) if (altHp)
{ {
@@ -1086,7 +1086,7 @@ namespace ARMeilleure.Instructions
{ {
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1); return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
} }
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr) private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
{ {
ExecutionContext context = NativeInterface.GetContext(); ExecutionContext context = NativeInterface.GetContext();
@@ -1522,7 +1522,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -1689,7 +1689,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -1726,7 +1726,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -1920,7 +1920,7 @@ namespace ARMeilleure.Instructions
float result; float result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -2211,7 +2211,7 @@ namespace ARMeilleure.Instructions
ushort resultBits; ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
if (altHp) if (altHp)
{ {
@@ -3057,7 +3057,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -3224,7 +3224,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -3261,7 +3261,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }
@@ -3455,7 +3455,7 @@ namespace ARMeilleure.Instructions
double result; double result;
if (type == FPType.SNaN || type == FPType.QNaN) if (type is FPType.SNaN or FPType.QNaN)
{ {
result = FPProcessNaN(type, op, context, fpcr); result = FPProcessNaN(type, op, context, fpcr);
} }

View File

@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.IntermediateRepresentation namespace ARMeilleure.IntermediateRepresentation
{ {
[Flags] [Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum Intrinsic : ushort enum Intrinsic : ushort
{ {
// X86 (SSE and AVX) // X86 (SSE and AVX)

View File

@@ -446,7 +446,7 @@ namespace ARMeilleure.IntermediateRepresentation
Data* data = null; Data* data = null;
// If constant or register, then try to look up in the intern table before allocating. // If constant or register, then try to look up in the intern table before allocating.
if (kind == OperandKind.Constant || kind == OperandKind.Register) if (kind is OperandKind.Constant or OperandKind.Register)
{ {
uint hash = (uint)HashCode.Combine(kind, type, value); uint hash = (uint)HashCode.Combine(kind, type, value);

View File

@@ -16,8 +16,8 @@ namespace ARMeilleure.IntermediateRepresentation
{ {
public static bool IsInteger(this OperandType type) public static bool IsInteger(this OperandType type)
{ {
return type == OperandType.I32 || return type is OperandType.I32 or
type == OperandType.I64; OperandType.I64;
} }
public static RegisterType ToRegisterType(this OperandType type) public static RegisterType ToRegisterType(this OperandType type)

View File

@@ -47,12 +47,12 @@ namespace ARMeilleure.Memory
{ {
public static bool IsHostMapped(this MemoryManagerType type) public static bool IsHostMapped(this MemoryManagerType type)
{ {
return type == MemoryManagerType.HostMapped || type == MemoryManagerType.HostMappedUnsafe; return type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
} }
public static bool IsHostTracked(this MemoryManagerType type) public static bool IsHostTracked(this MemoryManagerType type)
{ {
return type == MemoryManagerType.HostTracked || type == MemoryManagerType.HostTrackedUnsafe; return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
} }
public static bool IsHostMappedOrTracked(this MemoryManagerType type) public static bool IsHostMappedOrTracked(this MemoryManagerType type)

View File

@@ -12,6 +12,7 @@ namespace ARMeilleure
public static bool AllowLcqInFunctionTable { get; set; } = true; public static bool AllowLcqInFunctionTable { get; set; } = true;
public static bool UseUnmanagedDispatchLoop { get; set; } = true; public static bool UseUnmanagedDispatchLoop { get; set; } = true;
public static bool EnableDebugging { get; set; } = false;
public static bool UseAdvSimdIfAvailable { get; set; } = true; public static bool UseAdvSimdIfAvailable { get; set; } = true;
public static bool UseArm64AesIfAvailable { get; set; } = true; public static bool UseArm64AesIfAvailable { get; set; } = true;

View File

@@ -1,4 +1,5 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using System.Threading;
namespace ARMeilleure.State namespace ARMeilleure.State
{ {
@@ -10,16 +11,14 @@ namespace ARMeilleure.State
internal nint NativeContextPtr => _nativeContext.BasePtr; internal nint NativeContextPtr => _nativeContext.BasePtr;
private bool _interrupted; internal bool Interrupted { get; private set; }
private readonly ICounter _counter; private readonly ICounter _counter;
public ulong Pc => _nativeContext.GetPc(); public ulong Pc => _nativeContext.GetPc();
#pragma warning disable CA1822 // Mark member as static public static uint CtrEl0 => 0x8444c004;
public uint CtrEl0 => 0x8444c004; public static uint DczidEl0 => 0x00000004;
public uint DczidEl0 => 0x00000004;
#pragma warning restore CA1822
public ulong CntfrqEl0 => _counter.Frequency; public ulong CntfrqEl0 => _counter.Frequency;
public ulong CntpctEl0 => _counter.Counter; public ulong CntpctEl0 => _counter.Counter;
@@ -67,6 +66,8 @@ namespace ARMeilleure.State
public bool IsAarch32 { get; set; } public bool IsAarch32 { get; set; }
public ulong ThreadUid { get; set; }
internal ExecutionMode ExecutionMode internal ExecutionMode ExecutionMode
{ {
get get
@@ -92,14 +93,19 @@ namespace ARMeilleure.State
private readonly ExceptionCallbackNoArgs _interruptCallback; private readonly ExceptionCallbackNoArgs _interruptCallback;
private readonly ExceptionCallback _breakCallback; private readonly ExceptionCallback _breakCallback;
private readonly ExceptionCallbackNoArgs _stepCallback;
private readonly ExceptionCallback _supervisorCallback; private readonly ExceptionCallback _supervisorCallback;
private readonly ExceptionCallback _undefinedCallback; private readonly ExceptionCallback _undefinedCallback;
internal int ShouldStep;
public ulong DebugPc { get; set; }
public ExecutionContext( public ExecutionContext(
IJitMemoryAllocator allocator, IJitMemoryAllocator allocator,
ICounter counter, ICounter counter,
ExceptionCallbackNoArgs interruptCallback = null, ExceptionCallbackNoArgs interruptCallback = null,
ExceptionCallback breakCallback = null, ExceptionCallback breakCallback = null,
ExceptionCallbackNoArgs stepCallback = null,
ExceptionCallback supervisorCallback = null, ExceptionCallback supervisorCallback = null,
ExceptionCallback undefinedCallback = null) ExceptionCallback undefinedCallback = null)
{ {
@@ -107,6 +113,7 @@ namespace ARMeilleure.State
_counter = counter; _counter = counter;
_interruptCallback = interruptCallback; _interruptCallback = interruptCallback;
_breakCallback = breakCallback; _breakCallback = breakCallback;
_stepCallback = stepCallback;
_supervisorCallback = supervisorCallback; _supervisorCallback = supervisorCallback;
_undefinedCallback = undefinedCallback; _undefinedCallback = undefinedCallback;
@@ -129,9 +136,9 @@ namespace ARMeilleure.State
internal void CheckInterrupt() internal void CheckInterrupt()
{ {
if (_interrupted) if (Interrupted)
{ {
_interrupted = false; Interrupted = false;
_interruptCallback?.Invoke(this); _interruptCallback?.Invoke(this);
} }
@@ -141,16 +148,37 @@ namespace ARMeilleure.State
public void RequestInterrupt() public void RequestInterrupt()
{ {
_interrupted = true; Interrupted = true;
}
public void StepHandler()
{
_stepCallback?.Invoke(this);
}
public void RequestDebugStep()
{
Interlocked.Exchange(ref ShouldStep, 1);
RequestInterrupt();
} }
internal void OnBreak(ulong address, int imm) internal void OnBreak(ulong address, int imm)
{ {
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_breakCallback?.Invoke(this, address, imm); _breakCallback?.Invoke(this, address, imm);
} }
internal void OnSupervisorCall(ulong address, int imm) internal void OnSupervisorCall(ulong address, int imm)
{ {
if (Optimizations.EnableDebugging)
{
DebugPc = Pc;
}
_supervisorCallback?.Invoke(this, address, imm); _supervisorCallback?.Invoke(this, address, imm);
} }

View File

@@ -22,6 +22,12 @@ namespace ARMeilleure.State
public ulong ExclusiveValueHigh; public ulong ExclusiveValueHigh;
public int Running; public int Running;
public long Tpidr2El0; public long Tpidr2El0;
/// <summary>
/// Precise PC value used for debugging.
/// This will only be set when Optimizations.EnableDebugging is true.
/// </summary>
public ulong DebugPrecisePc;
} }
private static NativeCtxStorage _dummyStorage = new(); private static NativeCtxStorage _dummyStorage = new();
@@ -39,6 +45,11 @@ namespace ARMeilleure.State
public ulong GetPc() public ulong GetPc()
{ {
if (Optimizations.EnableDebugging)
{
return GetStorage().DebugPrecisePc;
}
// TODO: More precise tracking of PC value. // TODO: More precise tracking of PC value.
return GetStorage().DispatchAddress; return GetStorage().DispatchAddress;
} }
@@ -111,6 +122,7 @@ namespace ARMeilleure.State
{ {
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u; value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
} }
return value; return value;
} }
@@ -155,6 +167,7 @@ namespace ARMeilleure.State
value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u; value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
} }
} }
return value; return value;
} }
@@ -266,6 +279,11 @@ namespace ARMeilleure.State
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running); return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
} }
public static int GetDebugPrecisePcOffset()
{
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
}
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target) private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
{ {
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target); return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);

View File

@@ -52,6 +52,7 @@ namespace ARMeilleure.Translation
public bool HighCq { get; } public bool HighCq { get; }
public bool HasPtc { get; } public bool HasPtc { get; }
public Aarch32Mode Mode { get; } public Aarch32Mode Mode { get; }
public bool IsSingleStep { get; }
private int _ifThenBlockStateIndex = 0; private int _ifThenBlockStateIndex = 0;
private Condition[] _ifThenBlockState = []; private Condition[] _ifThenBlockState = [];
@@ -66,7 +67,8 @@ namespace ARMeilleure.Translation
ulong entryAddress, ulong entryAddress,
bool highCq, bool highCq,
bool hasPtc, bool hasPtc,
Aarch32Mode mode) Aarch32Mode mode,
bool isSingleStep)
{ {
Memory = memory; Memory = memory;
CountTable = countTable; CountTable = countTable;
@@ -76,6 +78,7 @@ namespace ARMeilleure.Translation
HighCq = highCq; HighCq = highCq;
HasPtc = hasPtc; HasPtc = hasPtc;
Mode = mode; Mode = mode;
IsSingleStep = isSingleStep;
_labels = new Dictionary<ulong, Operand>(); _labels = new Dictionary<ulong, Operand>();
} }

View File

@@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
private static JitCacheInvalidation _jitCacheInvalidator; private static JitCacheInvalidation _jitCacheInvalidator;
private static List<CacheMemoryAllocator> _cacheAllocators = []; private static readonly List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheEntry> _cacheEntries = []; private static readonly List<CacheEntry> _cacheEntries = [];
@@ -205,7 +205,6 @@ namespace ARMeilleure.Translation.Cache
return allocOffsetNew; return allocOffsetNew;
} }
private static int AlignCodeSize(int codeSize) private static int AlignCodeSize(int codeSize)
{ {
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1); return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);

View File

@@ -32,7 +32,7 @@ namespace ARMeilleure.Translation
return _delegates.Values[index].FuncPtr; // O(1). return _delegates.Values[index].FuncPtr; // O(1).
} }
public static int GetDelegateIndex(MethodInfo info) public static int GetDelegateIndex(MethodInfo info)
{ {
ArgumentNullException.ThrowIfNull(info); ArgumentNullException.ThrowIfNull(info);
@@ -48,7 +48,7 @@ namespace ARMeilleure.Translation
return index; return index;
} }
private static void SetDelegateInfo(MethodInfo method) private static void SetDelegateInfo(MethodInfo method)
{ {
string key = GetKey(method); string key = GetKey(method);

View File

@@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
{ {
continue; continue;
} }
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++) for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
{ {
BasicBlock current = block.Predecessors[pBlkIndex]; BasicBlock current = block.Predecessors[pBlkIndex];

View File

@@ -124,7 +124,7 @@ namespace ARMeilleure.Translation
/// </summary> /// </summary>
/// <param name="node">The node to search for values within</param> /// <param name="node">The node to search for values within</param>
/// <param name="list">The list to add values to</param> /// <param name="list">The list to add values to</param>
private void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list) private static void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
{ {
if (node == null) if (node == null)
{ {
@@ -165,6 +165,7 @@ namespace ARMeilleure.Translation
return node; return node;
} }
} }
return null; return null;
} }
@@ -175,7 +176,7 @@ namespace ARMeilleure.Translation
/// <param name="end">End of the range</param> /// <param name="end">End of the range</param>
/// <param name="overlaps">Overlaps array to place results in</param> /// <param name="overlaps">Overlaps array to place results in</param>
/// <param name="overlapCount">Overlaps count to update</param> /// <param name="overlapCount">Overlaps count to update</param>
private void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount) private static void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
{ {
if (node == null || start.CompareTo(node.Max) >= 0) if (node == null || start.CompareTo(node.Max) >= 0)
{ {
@@ -311,6 +312,7 @@ namespace ARMeilleure.Translation
return false; return false;
} }
} }
IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent); IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent);
if (newNode.Parent == null) if (newNode.Parent == null)
{ {
@@ -422,12 +424,14 @@ namespace ARMeilleure.Translation
{ {
return Maximum(node.Left); return Maximum(node.Left);
} }
IntervalTreeNode<TK, TV> parent = node.Parent; IntervalTreeNode<TK, TV> parent = node.Parent;
while (parent != null && node == parent.Left) while (parent != null && node == parent.Left)
{ {
node = parent; node = parent;
parent = parent.Parent; parent = parent.Parent;
} }
return parent; return parent;
} }
@@ -452,6 +456,7 @@ namespace ARMeilleure.Translation
RotateLeft(ParentOf(ptr)); RotateLeft(ParentOf(ptr));
sibling = RightOf(ParentOf(ptr)); sibling = RightOf(ParentOf(ptr));
} }
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black) if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
{ {
SetColor(sibling, Red); SetColor(sibling, Red);
@@ -466,6 +471,7 @@ namespace ARMeilleure.Translation
RotateRight(sibling); RotateRight(sibling);
sibling = RightOf(ParentOf(ptr)); sibling = RightOf(ParentOf(ptr));
} }
SetColor(sibling, ColorOf(ParentOf(ptr))); SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black); SetColor(ParentOf(ptr), Black);
SetColor(RightOf(sibling), Black); SetColor(RightOf(sibling), Black);
@@ -484,6 +490,7 @@ namespace ARMeilleure.Translation
RotateRight(ParentOf(ptr)); RotateRight(ParentOf(ptr));
sibling = LeftOf(ParentOf(ptr)); sibling = LeftOf(ParentOf(ptr));
} }
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black) if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
{ {
SetColor(sibling, Red); SetColor(sibling, Red);
@@ -498,6 +505,7 @@ namespace ARMeilleure.Translation
RotateLeft(sibling); RotateLeft(sibling);
sibling = LeftOf(ParentOf(ptr)); sibling = LeftOf(ParentOf(ptr));
} }
SetColor(sibling, ColorOf(ParentOf(ptr))); SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black); SetColor(ParentOf(ptr), Black);
SetColor(LeftOf(sibling), Black); SetColor(LeftOf(sibling), Black);
@@ -506,6 +514,7 @@ namespace ARMeilleure.Translation
} }
} }
} }
SetColor(ptr, Black); SetColor(ptr, Black);
} }
@@ -532,6 +541,7 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode); balanceNode = ParentOf(balanceNode);
RotateLeft(balanceNode); RotateLeft(balanceNode);
} }
SetColor(ParentOf(balanceNode), Black); SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red); SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateRight(ParentOf(ParentOf(balanceNode))); RotateRight(ParentOf(ParentOf(balanceNode)));
@@ -555,12 +565,14 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode); balanceNode = ParentOf(balanceNode);
RotateRight(balanceNode); RotateRight(balanceNode);
} }
SetColor(ParentOf(balanceNode), Black); SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red); SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateLeft(ParentOf(ParentOf(balanceNode))); RotateLeft(ParentOf(ParentOf(balanceNode)));
} }
} }
} }
SetColor(_root, Black); SetColor(_root, Black);
} }
@@ -574,6 +586,7 @@ namespace ARMeilleure.Translation
{ {
node.Right.Parent = node; node.Right.Parent = node;
} }
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node); IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
right.Parent = nodeParent; right.Parent = nodeParent;
if (nodeParent == null) if (nodeParent == null)
@@ -588,6 +601,7 @@ namespace ARMeilleure.Translation
{ {
nodeParent.Right = right; nodeParent.Right = right;
} }
right.Left = node; right.Left = node;
node.Parent = right; node.Parent = right;
@@ -605,6 +619,7 @@ namespace ARMeilleure.Translation
{ {
node.Left.Parent = node; node.Left.Parent = node;
} }
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node); IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
left.Parent = nodeParent; left.Parent = nodeParent;
if (nodeParent == null) if (nodeParent == null)
@@ -619,6 +634,7 @@ namespace ARMeilleure.Translation
{ {
nodeParent.Left = left; nodeParent.Left = left;
} }
left.Right = node; left.Right = node;
node.Parent = left; node.Parent = left;

View File

@@ -33,7 +33,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 7008; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 7009; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";
@@ -193,7 +193,7 @@ namespace ARMeilleure.Translation.PTC
_infosStream.Seek(0L, SeekOrigin.Begin); _infosStream.Seek(0L, SeekOrigin.Begin);
bool foundBadFunction = false; bool foundBadFunction = false;
for (int index = 0; index < GetEntriesCount(); index++) for (int index = 0; index < _infosStream.Length / Unsafe.SizeOf<InfoEntry>(); index++)
{ {
InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream); InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream);
foreach (ulong address in blacklist) foreach (ulong address in blacklist)
@@ -303,6 +303,13 @@ namespace ARMeilleure.Translation.PTC
return false; return false;
} }
if (outerHeader.DebuggerMode != Optimizations.EnableDebugging)
{
InvalidateCompressedStream(compressedStream);
return false;
}
nint intPtr = nint.Zero; nint intPtr = nint.Zero;
try try
@@ -479,6 +486,7 @@ namespace ARMeilleure.Translation.PTC
MemoryManagerMode = GetMemoryManagerMode(), MemoryManagerMode = GetMemoryManagerMode(),
OSPlatform = GetOSPlatform(), OSPlatform = GetOSPlatform(),
Architecture = (uint)RuntimeInformation.ProcessArchitecture, Architecture = (uint)RuntimeInformation.ProcessArchitecture,
DebuggerMode = Optimizations.EnableDebugging,
UncompressedStreamSize = UncompressedStreamSize =
(long)Unsafe.SizeOf<InnerHeader>() + (long)Unsafe.SizeOf<InnerHeader>() +
@@ -835,8 +843,6 @@ namespace ARMeilleure.Translation.PTC
return; return;
} }
int degreeOfParallelism = Environment.ProcessorCount; int degreeOfParallelism = Environment.ProcessorCount;
if (Optimizations.LowPower) if (Optimizations.LowPower)
@@ -896,13 +902,12 @@ namespace ARMeilleure.Translation.PTC
} }
} }
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism) List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
.Select(idx => .Select(idx =>
new Thread(TranslateFuncs) new Thread(TranslateFuncs)
{ {
IsBackground = true, IsBackground = true,
Name = "Ptc.TranslateThread." + idx Name = "Ptc.TranslateThread." + idx
} }
).ToList(); ).ToList();
@@ -912,6 +917,7 @@ namespace ARMeilleure.Translation.PTC
{ {
thread.Start(); thread.Start();
} }
foreach (Thread thread in threads) foreach (Thread thread in threads)
{ {
thread.Join(); thread.Join();
@@ -925,8 +931,8 @@ namespace ARMeilleure.Translation.PTC
sw.Stop(); sw.Stop();
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount); PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
Logger.Info?.Print(LogClass.Ptc, Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " + $"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " + $"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}"); $"| Thread count: {degreeOfParallelism}");
@@ -1070,7 +1076,7 @@ namespace ARMeilleure.Translation.PTC
return osPlatform; return osPlatform;
} }
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 86*/)] [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 87*/)]
private struct OuterHeader private struct OuterHeader
{ {
public ulong Magic; public ulong Magic;
@@ -1082,6 +1088,7 @@ namespace ARMeilleure.Translation.PTC
public byte MemoryManagerMode; public byte MemoryManagerMode;
public uint OSPlatform; public uint OSPlatform;
public uint Architecture; public uint Architecture;
public bool DebuggerMode;
public long UncompressedStreamSize; public long UncompressedStreamSize;
@@ -1164,8 +1171,8 @@ namespace ARMeilleure.Translation.PTC
public void Close() public void Close()
{ {
if (State == PtcState.Enabled || if (State is PtcState.Enabled or
State == PtcState.Continuing) PtcState.Continuing)
{ {
State = PtcState.Closing; State = PtcState.Closing;
} }

View File

@@ -1,5 +1,6 @@
using ARMeilleure.State; using ARMeilleure.State;
using Humanizer; using Humanizer;
using Microsoft.IO;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
@@ -26,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions = private static readonly uint[] _migrateInternalVersions =
[ [
1866, 1866,
5518, 5518,
@@ -75,7 +76,7 @@ namespace ARMeilleure.Translation.PTC
Enabled = false; Enabled = false;
} }
private void TimerElapsed(object _, ElapsedEventArgs __) private void TimerElapsed(object _, ElapsedEventArgs __)
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start(); => new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false) public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
@@ -151,7 +152,7 @@ namespace ARMeilleure.Translation.PTC
if (!funcProfile.Blacklist) if (!funcProfile.Blacklist)
continue; continue;
if (!funcs.Contains(ptr)) if (!funcs.Contains(ptr))
funcs.Add(ptr); funcs.Add(ptr);
} }
@@ -219,7 +220,7 @@ namespace ARMeilleure.Translation.PTC
return false; return false;
} }
using MemoryStream stream = MemoryStreamManager.Shared.GetStream(); using RecyclableMemoryStream stream = MemoryStreamManager.Shared.GetStream();
Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L);
try try
@@ -293,10 +294,10 @@ namespace ARMeilleure.Translation.PTC
{ {
if (migrateEntryFunc != null) if (migrateEntryFunc != null)
{ {
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc); return DeserializeAndUpdateDictionary(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
} }
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }); return DeserializeDictionary<ulong, FuncProfile>(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
} }
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream) private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
@@ -467,8 +468,8 @@ namespace ARMeilleure.Translation.PTC
public void Start() public void Start()
{ {
if (_ptc.State == PtcState.Enabled || if (_ptc.State is PtcState.Enabled or
_ptc.State == PtcState.Continuing) PtcState.Continuing)
{ {
Enabled = true; Enabled = true;

View File

@@ -119,7 +119,25 @@ namespace ARMeilleure.Translation
NativeInterface.RegisterThread(context, Memory, this); NativeInterface.RegisterThread(context, Memory, this);
if (Optimizations.UseUnmanagedDispatchLoop) if (Optimizations.EnableDebugging)
{
context.DebugPc = address;
do
{
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
{
context.DebugPc = Step(context, context.DebugPc);
context.StepHandler();
}
else
{
context.DebugPc = ExecuteSingle(context, context.DebugPc);
}
context.CheckInterrupt();
}
while (context.Running && context.DebugPc != 0);
}
else if (Optimizations.UseUnmanagedDispatchLoop)
{ {
Stubs.DispatchLoop(context.NativeContextPtr, address); Stubs.DispatchLoop(context.NativeContextPtr, address);
} }
@@ -175,7 +193,7 @@ namespace ARMeilleure.Translation
return nextAddr; return nextAddr;
} }
public ulong Step(State.ExecutionContext context, ulong address) private ulong Step(State.ExecutionContext context, ulong address)
{ {
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true); TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
@@ -186,6 +204,8 @@ namespace ARMeilleure.Translation
return address; return address;
} }
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode) internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
{ {
if (!Functions.TryGetValue(address, out TranslatedFunction func)) if (!Functions.TryGetValue(address, out TranslatedFunction func))
@@ -229,7 +249,8 @@ namespace ARMeilleure.Translation
address, address,
highCq, highCq,
_ptc.State != PtcState.Disabled, _ptc.State != PtcState.Disabled,
mode: Aarch32Mode.User); mode: Aarch32Mode.User,
isSingleStep: singleStep);
Logger.StartPass(PassName.Decoding); Logger.StartPass(PassName.Decoding);
@@ -367,9 +388,13 @@ namespace ARMeilleure.Translation
if (block.Exit) if (block.Exit)
{ {
// Left option here as it may be useful if we need to return to managed rather than tail call in // Return to managed rather than tail call.
// future. (eg. for debug) bool useReturns = Optimizations.EnableDebugging;
bool useReturns = false;
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, block.Address);
}
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns); InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
} }
@@ -393,6 +418,11 @@ namespace ARMeilleure.Translation
} }
} }
if (Optimizations.EnableDebugging)
{
EmitDebugPrecisePcUpdate(context, opCode.Address);
}
Operand lblPredicateSkip = default; Operand lblPredicateSkip = default;
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al) if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
@@ -489,6 +519,14 @@ namespace ARMeilleure.Translation
context.MarkLabel(lblExit); context.MarkLabel(lblExit);
} }
internal static void EmitDebugPrecisePcUpdate(EmitterContext context, ulong address)
{
long debugPrecisePcOffs = NativeContext.GetDebugPrecisePcOffset();
Operand debugPrecisePcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(debugPrecisePcOffs));
context.Store(debugPrecisePcAddr, Const(address));
}
public void InvalidateJitCacheRegion(ulong address, ulong size) public void InvalidateJitCacheRegion(ulong address, ulong size)
{ {
ulong[] overlapAddresses = []; ulong[] overlapAddresses = [];

View File

@@ -178,7 +178,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)

View File

@@ -24,10 +24,8 @@ namespace Ryujinx.Audio.Backends.SDL2
// TODO: Add this to SDL2-CS // TODO: Add this to SDL2-CS
// NOTE: We use a DllImport here because of marshaling issue for spec. // NOTE: We use a DllImport here because of marshaling issue for spec.
#pragma warning disable SYSLIB1054
[DllImport("SDL2")] [DllImport("SDL2")]
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture); private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture);
#pragma warning restore SYSLIB1054
public SDL2HardwareDeviceDriver() public SDL2HardwareDeviceDriver()
{ {

View File

@@ -162,7 +162,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
public bool SupportsSampleFormat(SampleFormat sampleFormat) public bool SupportsSampleFormat(SampleFormat sampleFormat)
@@ -184,7 +184,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)
{ {
return direction == Direction.Input || direction == Direction.Output; return direction is Direction.Input or Direction.Output;
} }
} }
} }

View File

@@ -73,12 +73,12 @@ namespace Ryujinx.Audio.Backends.Dummy
public bool SupportsDirection(Direction direction) public bool SupportsDirection(Direction direction)
{ {
return direction == Direction.Output || direction == Direction.Input; return direction is Direction.Output or Direction.Input;
} }
public bool SupportsChannelCount(uint channelCount) public bool SupportsChannelCount(uint channelCount)
{ {
return channelCount == 1 || channelCount == 2 || channelCount == 6; return channelCount is 1 or 2 or 6;
} }
} }
} }

View File

@@ -109,7 +109,7 @@ namespace Ryujinx.Audio.Common
/// <returns>The state of the session</returns> /// <returns>The state of the session</returns>
public AudioDeviceState GetState() public AudioDeviceState GetState()
{ {
Debug.Assert(_state == AudioDeviceState.Started || _state == AudioDeviceState.Stopped); Debug.Assert(_state is AudioDeviceState.Started or AudioDeviceState.Stopped);
return _state; return _state;
} }

View File

@@ -166,7 +166,7 @@ namespace Ryujinx.Audio.Input
/// </summary> /// </summary>
/// <param name="filtered">If true, filter disconnected devices</param> /// <param name="filtered">If true, filter disconnected devices</param>
/// <returns>The list of all audio inputs name</returns> /// <returns>The list of all audio inputs name</returns>
public string[] ListAudioIns(bool filtered) public static string[] ListAudioIns(bool filtered)
{ {
if (filtered) if (filtered)
{ {

View File

@@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Input
return ResultCode.DeviceNotFound; return ResultCode.DeviceNotFound;
} }
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
{ {
return ResultCode.UnsupportedSampleRate; return ResultCode.UnsupportedSampleRate;
} }
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
{ {
return ResultCode.UnsupportedChannelConfiguration; return ResultCode.UnsupportedChannelConfiguration;
} }

View File

@@ -47,7 +47,7 @@ namespace Ryujinx.Audio.Integration
{ {
uint channelCount = GetChannelCount(); uint channelCount = GetChannelCount();
Debug.Assert(channelCount > 0 && channelCount <= Constants.ChannelCountMax); Debug.Assert(channelCount is > 0 and <= Constants.ChannelCountMax);
return channelCount != Constants.ChannelCountMax; return channelCount != Constants.ChannelCountMax;
} }

View File

@@ -165,7 +165,7 @@ namespace Ryujinx.Audio.Output
/// Get the list of all audio outputs name. /// Get the list of all audio outputs name.
/// </summary> /// </summary>
/// <returns>The list of all audio outputs name</returns> /// <returns>The list of all audio outputs name</returns>
public string[] ListAudioOuts() public static string[] ListAudioOuts()
{ {
return [Constants.DefaultDeviceOutputName]; return [Constants.DefaultDeviceOutputName];
} }

View File

@@ -91,12 +91,12 @@ namespace Ryujinx.Audio.Output
return ResultCode.DeviceNotFound; return ResultCode.DeviceNotFound;
} }
if (configuration.SampleRate != 0 && configuration.SampleRate != Constants.TargetSampleRate) if (configuration.SampleRate is not 0 and not Constants.TargetSampleRate)
{ {
return ResultCode.UnsupportedSampleRate; return ResultCode.UnsupportedSampleRate;
} }
if (configuration.ChannelCount != 0 && configuration.ChannelCount != 1 && configuration.ChannelCount != 2 && configuration.ChannelCount != 6) if (configuration.ChannelCount is not 0 and not 1 and not 2 and not 6)
{ {
return ResultCode.UnsupportedChannelConfiguration; return ResultCode.UnsupportedChannelConfiguration;
} }

View File

@@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// <param name="volume">The new master volume.</param> /// <param name="volume">The new master volume.</param>
public void UpdateMasterVolume(float volume) public void UpdateMasterVolume(float volume)
{ {
Debug.Assert(volume >= 0.0f && volume <= 1.0f); Debug.Assert(volume is >= 0.0f and <= 1.0f);
MasterVolume = volume; MasterVolume = volume;
} }

View File

@@ -17,9 +17,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// The default <see cref="VirtualDevice"/>. /// The default <see cref="VirtualDevice"/>.
/// </summary> /// </summary>
/// <remarks>This is used when the USB device is the default one on older revision.</remarks> /// <remarks>This is used when the USB device is the default one on older revision.</remarks>
#pragma warning disable CA1822 // Mark member as static public static VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
public VirtualDevice DefaultDevice => VirtualDevice.Devices[0];
#pragma warning restore CA1822
/// <summary> /// <summary>
/// The current active <see cref="VirtualDevice"/>. /// The current active <see cref="VirtualDevice"/>.

View File

@@ -26,12 +26,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
ReadOnlySpan<float> inputBuffer, ReadOnlySpan<float> inputBuffer,
uint sampleCount) uint sampleCount)
{ {
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter); Span<short> numeratorSpan = parameter.Numerator.AsSpan();
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter); Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter); float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter); float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
@@ -64,12 +67,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount, uint sampleCount,
float volume) float volume)
{ {
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter); Span<short> numeratorSpan = parameter.Numerator.AsSpan();
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter); Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter); float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter); float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
@@ -107,12 +113,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume, float volume,
float ramp) float ramp)
{ {
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter); Span<short> numeratorSpan = parameter.Numerator.AsSpan();
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter); Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter); float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter); float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float mixState = 0f; float mixState = 0f;
@@ -157,13 +166,16 @@ namespace Ryujinx.Audio.Renderer.Dsp
BiquadFilterParameter parameter = parameters[stageIndex]; BiquadFilterParameter parameter = parameters[stageIndex];
ref BiquadFilterState state = ref states[stageIndex]; ref BiquadFilterState state = ref states[stageIndex];
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter); float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter); float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter); float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter); float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter); float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
@@ -201,19 +213,25 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount, uint sampleCount,
float volume) float volume)
{ {
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter); Span<short> numerator0Span = parameter0.Numerator.AsSpan();
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter); Span<short> numerator1Span = parameter1.Numerator.AsSpan();
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter); Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter); float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter); float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter); float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter); float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter); float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter); float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter); float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
@@ -261,19 +279,24 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume, float volume,
float ramp) float ramp)
{ {
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter); Span<short> numerator0Span = parameter0.Numerator.AsSpan();
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter); Span<short> numerator1Span = parameter1.Numerator.AsSpan();
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter); Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter); float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter); float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter); float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter); float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter); float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter); float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter); float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
float mixState = 0f; float mixState = 0f;

View File

@@ -39,12 +39,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = outputBufferIndex; OutputBufferIndex = outputBufferIndex;
SampleRate = serverState.SampleRate; SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch; Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++) for (int i = 0; i < WaveBuffers.Length; i++)
{ {
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i]; ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1); WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
} }

View File

@@ -1,5 +1,6 @@
using Ryujinx.Audio.Renderer.Parameter.Sink; using Ryujinx.Audio.Renderer.Parameter.Sink;
using Ryujinx.Audio.Renderer.Server.MemoryPool; using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System;
using System.Diagnostics; using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Dsp.Command namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -28,10 +29,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Input = new ushort[Constants.ChannelCountMax]; Input = new ushort[Constants.ChannelCountMax];
InputCount = parameter.InputCount; InputCount = parameter.InputCount;
Span<byte> inputSpan = parameter.Input.AsSpan();
for (int i = 0; i < InputCount; i++) for (int i = 0; i < InputCount; i++)
{ {
Input[i] = (ushort)(bufferOffset + parameter.Input[i]); Input[i] = (ushort)(bufferOffset + inputSpan[i]);
} }
CircularBuffer = circularBufferAddressInfo.GetReference(true); CircularBuffer = circularBufferAddressInfo.GetReference(true);

View File

@@ -42,11 +42,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++) for (int i = 0; i < _parameter.ChannelCount; i++)
{ {
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]); InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
} }
} }
@@ -171,10 +174,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain); statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain);
statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean); statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean);
Span<float> lastSamplesSpan = statistics.LastSamples.AsSpan();
for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++) for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++)
{ {
statistics.LastSamples[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f)); lastSamplesSpan[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
} }
} }
} }

View File

@@ -52,12 +52,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex); OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
SampleRate = serverState.SampleRate; SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch; Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++) for (int i = 0; i < WaveBuffers.Length; i++)
{ {
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i]; ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(2); WaveBuffers[i] = voiceWaveBuffer.ToCommon(2);
} }

View File

@@ -42,11 +42,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = Parameter.Input.AsSpan();
Span<byte> outputSpan = Parameter.Output.AsSpan();
for (int i = 0; i < Parameter.ChannelCount; i++) for (int i = 0; i < Parameter.ChannelCount; i++)
{ {
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]); InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
} }
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount); DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);
@@ -129,7 +132,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain, delayFeedbackCrossGain, 0.0f, delayFeedbackBaseGain, delayFeedbackCrossGain,
0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain); 0.0f, delayFeedbackCrossGain, delayFeedbackCrossGain, delayFeedbackBaseGain);
for (int i = 0; i < sampleCount; i++) for (int i = 0; i < sampleCount; i++)
{ {
Vector4 channelInput = new() Vector4 channelInput = new()

View File

@@ -42,14 +42,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
ref VoiceUpdateState state = ref State.Span[0]; ref VoiceUpdateState state = ref State.Span[0];
Span<float> depopBuffer = DepopBuffer.Span; Span<float> depopBuffer = DepopBuffer.Span;
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
for (int i = 0; i < MixBufferCount; i++) for (int i = 0; i < MixBufferCount; i++)
{ {
if (state.LastSamples[i] != 0) if (lastSamplesSpan[i] != 0)
{ {
depopBuffer[OutputBufferIndices[i]] += state.LastSamples[i]; depopBuffer[OutputBufferIndices[i]] += lastSamplesSpan[i];
state.LastSamples[i] = 0; lastSamplesSpan[i] = 0;
} }
} }
} }

View File

@@ -34,10 +34,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
SessionId = sessionId; SessionId = sessionId;
InputCount = sink.Parameter.InputCount; InputCount = sink.Parameter.InputCount;
InputBufferIndices = new ushort[InputCount]; InputBufferIndices = new ushort[InputCount];
Span<byte> inputSpan = sink.Parameter.Input.AsSpan();
for (int i = 0; i < Math.Min(InputCount, Constants.ChannelCountMax); i++) for (int i = 0; i < Math.Min(InputCount, Constants.ChannelCountMax); i++)
{ {
InputBufferIndices[i] = (ushort)(bufferOffset + sink.Parameter.Input[i]); InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
} }
if (sink.UpsamplerState != null) if (sink.UpsamplerState != null)

View File

@@ -37,11 +37,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++) for (int i = 0; i < _parameter.ChannelCount; i++)
{ {
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]); InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
} }
} }

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