Compare commits

...

180 Commits

Author SHA1 Message Date
Vladimir Sokolov
e02ef52069 Added --backend-threading arg for CommandLineState (#599)
Added the `--backend-threading` arg so that you can launch games via
a shortcut with modifications to this setting.
2025-01-29 12:49:36 -06:00
Evan Husted
707c9ef748 misc: chore: slightly improve PTC init log line 2025-01-28 22:25:01 -06:00
Evan Husted
2acc43e968 misc: chore: Use string.Empty in more places where it's snuck back 2025-01-28 22:17:11 -06:00
Evan Husted
191e158289 misc: chore: Use static instances of converters instead of using control resources 2025-01-28 22:11:48 -06:00
Evan Husted
a469f3d710 UI: Remove empty StackPanel in UserSelectorDialog 2025-01-28 21:47:29 -06:00
shinyoyo
1b3656bca9 LED Color & LED settings header (zh_CN) (#590) 2025-01-28 21:29:06 -06:00
Evan Husted
502ce98b3a UI: [ci skip] Make cheat window larger by default 2025-01-28 21:27:51 -06:00
LotP1
7085bafa60 PPTC Profiles (#370)
Added functionality that allows ExeFS mods to compile to their own PPTC
Profile and therefore store PTC data between sessions.
The feature calculates the hash of the currently loaded ExeFS mods and
stores the PPTC data in a profile that matches said hash, so you can
have multiple ExeFS loadouts without causing issues. This includes
different versions of the same mod as their hashes will be different.
Using this PR should be seamless as the JIT Sparse PR already laid the
groundwork for PPTC Profiles and this PR just allows ExeFS mods to load
and store their own profiles besides the `default` profile.

 **WARNING!** 
**This will update your PPTC profile version, which means the
PPTC profile will be invalidated if you try to run a PR/Build/Branch
that does not include this change!**
**This is only relevant for the default PPTC Profile, as any other profiles do not exist to older versions!**
2025-01-28 20:36:58 -06:00
Evan Husted
9d28af935d headless: Enable Rainbow cycling if any input configs have UseRainbow enabled 2025-01-28 20:16:41 -06:00
Evan Husted
cdf4016c25 Update README.md 2025-01-27 15:04:57 -06:00
Evan Husted
082c718f5d fix canary URL 2025-01-27 15:04:14 -06:00
Josh
31de0bf8c6 Increase NAT discovery timeout to 5000ms (#589)
1000ms was too fast on some slower networks. It would lead to an early
cancellation before device could be found.
2025-01-26 19:40:10 -06:00
Evan Husted
f3942968f9 UI: Convert the various options for LED into a popup window similar to motion & rumble config. 2025-01-26 17:18:27 -06:00
Evan Husted
ac838aa81d misc: chore: Use collection expressions everywhere else (except VP9) 2025-01-26 15:59:11 -06:00
Evan Husted
0f857400b6 misc: chore: Use collection expressions in Common project 2025-01-26 15:53:31 -06:00
Evan Husted
95f9e548ca misc: chore: Use collection expressions in Shader project 2025-01-26 15:50:50 -06:00
Evan Husted
a5dbcb75d0 misc: chore: Use collection expressions in OpenGL project 2025-01-26 15:50:22 -06:00
Evan Husted
aa0cb50c5d misc: chore: Use collection expressions in Gpu project 2025-01-26 15:49:22 -06:00
Evan Husted
ae90db2040 misc: chore: Use collection expressions in Avalonia project 2025-01-26 15:47:11 -06:00
Evan Husted
46a5cafaa8 misc: chore: Use collection expressions in Memory project 2025-01-26 15:46:58 -06:00
Evan Husted
2853f5b426 misc: chore: Use collection expressions in Generator projects 2025-01-26 15:45:43 -06:00
Evan Husted
45125c16cf misc: chore: Use collection expressions in Input projects 2025-01-26 15:43:58 -06:00
Evan Husted
9f3eac7f26 misc: chore: Use collection expressions in Horizon project 2025-01-26 15:43:27 -06:00
Evan Husted
70b767ef60 misc: chore: Use collection expressions in HLE project 2025-01-26 15:43:02 -06:00
Evan Husted
3c2f283ec7 misc: chore: Use collection expressions in Audio project 2025-01-26 15:41:47 -06:00
Evan Husted
3e12865f51 misc: chore: Use collection expressions in Cpu 2025-01-26 15:41:05 -06:00
Evan Husted
ed2590a8ac misc: chore: Use collection expressions in Vulkan project 2025-01-26 15:32:25 -06:00
Evan Husted
9cb3b40ffc misc: chore: Use collection expressions in ARMeilleure 2025-01-26 15:31:44 -06:00
Evan Husted
c7db948fb3 misc: chore: Fix object creation everywhere else 2025-01-26 15:28:18 -06:00
Evan Husted
9e1a13b2ee misc: chore: Fix object creation in Audio project 2025-01-26 15:26:51 -06:00
Evan Husted
d95f724d17 misc: chore: Fix object creation in Metal 2025-01-26 15:26:11 -06:00
Evan Husted
e859bd5aa2 misc: chore: Fix object creation in Horizon generators 2025-01-26 15:26:01 -06:00
Evan Husted
ccef0b49eb misc: chore: Fix object creation in Shader project 2025-01-26 15:22:30 -06:00
Evan Husted
7f5a356c3d misc: chore: Fix object creation in Common project 2025-01-26 15:21:47 -06:00
Evan Husted
ae92fbf539 misc: chore: Fix object creation in Memory project 2025-01-26 15:20:28 -06:00
Evan Husted
56d373a011 misc: chore: Fix object creation in SPIRV generator 2025-01-26 15:19:53 -06:00
Evan Husted
742083ae3d misc: chore: Fix object creation in Horizon 2025-01-26 15:19:33 -06:00
Evan Husted
5fad450027 misc: chore: Fix object creation in Tests project 2025-01-26 15:19:01 -06:00
Evan Husted
929a16dd26 misc: chore: Fix object creation in Gpu project 2025-01-26 15:18:04 -06:00
Evan Husted
4e47c86f90 misc: chore: Fix object creation in GAL 2025-01-26 15:17:37 -06:00
Evan Husted
15d1528774 misc: chore: Fix object creation in ARMeilleure 2025-01-26 15:17:12 -06:00
Evan Husted
3cdaaa0b69 misc: chore: Fix object creation in Avalonia project 2025-01-26 15:16:50 -06:00
Evan Husted
5f023ca49b misc: chore: Fix object creation in Vulkan project 2025-01-26 15:16:32 -06:00
Evan Husted
eae6dba610 misc: chore: Fix object creation in OpenGL project 2025-01-26 15:16:12 -06:00
Evan Husted
94b65aec02 misc: chore: Fix object creation in Cpu project 2025-01-26 15:15:48 -06:00
Evan Husted
beab133c8d misc: chore: Fix object creation in HLE project 2025-01-26 15:15:26 -06:00
Evan Husted
f1fd5c9366 misc: chore: Link to Ryubing/Ryujinx in markdown docs 2025-01-26 14:28:55 -06:00
Evan Husted
5396327ac1 misc: chore: Replace GreemDev/Ryujinx with Ryubing/Ryujinx in Amiibo.json 2025-01-26 14:22:59 -06:00
Evan Husted
3f12727ef8 input: LED rainbow now updates the LED with the normal gamepad update loop instead of subscribing to an updated event for the rainbow color in SetConfiguration. 2025-01-25 23:13:51 -06:00
Evan Husted
8bfcebebf1 Merge remote-tracking branch 'origin/master' 2025-01-25 22:44:26 -06:00
Evan Husted
e3f20abd23 UI: RPC: Maintain game started timestamp for the duration of the AppHost 2025-01-25 22:44:16 -06:00
Daenorth
0c36bcd7d4 Added more titles to RPC (#569)
Added some more titles to the RPC environment

-Brawlhalla
-Minecraft
-Risk
-Stardew Vallet
-Valkyria Chronicles 4
-Super bomberman R
-Arcade archives Super mario bros
-Divinity Original sin 2 DE
-Monopoly
-titan Quest
2025-01-25 22:02:24 -06:00
shinyoyo
050b9a0da4 Updated Zh_CN Simplified Chinese (#578) 2025-01-25 21:59:20 -06:00
Dehunc
a1291f1061 Improved Simplified Chinese translation (#568)
Co-authored-by: Cwood <Cwood@DoVirt.org>
2025-01-25 21:59:06 -06:00
Otozinclus
f15aa8fba0 Fix LED turning on in input settings, despite TurnOffLed being set to true (#583)
The ColorPicker auotmatically sets the LED to the selected Color
whenever the Input Settings are opened. Therefore it now checks if the
setting is turned off before changing the color.
2025-01-25 17:15:17 -06:00
Evan Husted
250acab7a7 misc: chore: Use explicit types in Tests projects 2025-01-25 14:15:47 -06:00
Evan Husted
93539e7d45 misc: chore: Use explicit types in GAL 2025-01-25 14:14:40 -06:00
Evan Husted
69e0b79bd9 misc: chore: Use explicit types in Horizon project 2025-01-25 14:14:13 -06:00
Evan Husted
5eba42fa06 misc: chore: Use explicit types in HLE project 2025-01-25 14:13:18 -06:00
Evan Husted
58c1ab7989 misc: chore: Use explicit types in OpenGL project 2025-01-25 14:12:37 -06:00
Evan Husted
2d1a4c3ce5 misc: chore: Use explicit types in Vulkan project 2025-01-25 14:12:17 -06:00
Evan Husted
e6b393e420 misc: chore: Use explicit types in Generator projects 2025-01-25 14:11:46 -06:00
Evan Husted
fe661dc750 misc: chore: Use explicit types in Memory project 2025-01-25 14:09:36 -06:00
Evan Husted
ac401034d7 misc: chore: Use explicit types in input projects 2025-01-25 14:09:05 -06:00
Evan Husted
1712d69dcd misc: chore: Use explicit types in Texture & Vic 2025-01-25 14:08:35 -06:00
Evan Husted
f2aa6b3a5b misc: chore: Use explicit types in Shader project 2025-01-25 14:07:59 -06:00
Evan Husted
68bbb29be6 misc: chore: Use explicit types in NVDEC projects (except VP9 because there's an open PR and I don't want to cause conflicts) 2025-01-25 14:07:20 -06:00
Evan Husted
76ec047eb7 misc: chore: Use explicit types in Metal project 2025-01-25 14:06:26 -06:00
Evan Husted
1ae349efb1 misc: chore: Use explicit types in GPU, Device, and Host1x projects 2025-01-25 14:05:44 -06:00
Evan Husted
5099548856 misc: chore: Use explicit types in CPU project 2025-01-25 14:04:43 -06:00
Evan Husted
a97fd4beb1 misc: chore: Use explicit types in common project 2025-01-25 14:04:12 -06:00
Evan Husted
97188556d8 misc: chore: Use explicit types in audio projects 2025-01-25 14:03:38 -06:00
Evan Husted
e0567c5ce9 misc: chore: Use explicit types in ARMeilleure project 2025-01-25 14:01:13 -06:00
Evan Husted
be3bd0bcb5 misc: chore: Use explicit types in the Avalonia project 2025-01-25 14:00:23 -06:00
Evan Husted
3b5f6170d1 misc: chore: move Rainbow updating to a separate task started/stopped as needed
update gommon & use the Event class from it to allow easily clearing all handlers when the apphost exits to avoid leftover invalid event handlers in the rainbow event handler list.
More robust config application logic to ensure what needs to happen only happens once
2025-01-24 23:06:59 -06:00
Evan Husted
9b6afa0ea2 misc: chore: Add log line to the other parts of the Updater that represent "up to date" 2025-01-24 17:00:50 -06:00
Evan Husted
3541e282ea Fully disconnect gamepad handler for rainbow color if configuration is set with UseRainbowLed false
Also check if its even enabled before setting the rainbow color
Fixes strobing
2025-01-24 16:52:20 -06:00
Otozinclus
1ce37ec317 Add option to change controller LED color (#572)
This allows the user to change the controller LED while using Ryujinx.
Useful for PS4 and PS5 controllers as an example.

You can also use a spectrum-cycling Rainbow color option, or turn the LED off for DualSense controllers.

---------

Co-authored-by: Evan Husted <greem@greemdev.net>
2025-01-24 14:47:36 -06:00
Evan Husted
c06f16c5e6 infra: chore: Raise minimum required Windows 10 version
Inspired by the breakages covered in #409
2025-01-23 17:39:34 -06:00
Evan Husted
7829fd8ee7 misc: chore: OS + CPU arch helpers 2025-01-23 16:58:48 -06:00
Evan Husted
33079422fe misc: chore: code cleanups 2025-01-23 16:47:11 -06:00
Evan Husted
f81cb093fc misc: chore: Change references of GreemDev/Ryujinx to Ryubing/Ryujinx 2025-01-23 16:27:49 -06:00
Evan Husted
dc0c7a2912 infra: clarify how stable builds are made now 2025-01-23 16:27:25 -06:00
Evan Husted
1fbee5a584 infra: Metal label 2025-01-23 14:39:36 -06:00
Evan Husted
c140e9b23c UI: Localize LED color & hide it until it's functional
Also moved IgnoreApplet to the System config section object.
2025-01-23 00:48:42 -06:00
Evan Husted
9c8055440e HLE: TryAdd firmware NCAs 2025-01-22 23:58:11 -06:00
Evan Husted
c03cd50fa3 UI: Add the ability to change a DualSense/DualShock 4's LED color.
Not functional yet. This is the UI & persistence side of #572.
2025-01-22 19:53:39 -06:00
Evan Husted
069f630776 docs: compat: boots: ENDER MAGNOLIA: Bloom in the Mist 2025-01-22 18:00:14 -06:00
Evan Husted
13d411e4de misc: chore: also ToLower the titleID for the OpenShaderDirectory button 2025-01-22 08:54:39 -06:00
Evan Husted
9f53b07491 misc: chore: Fix shader cache & CPU cache being in different folders on non-Windows
fixes #565
2025-01-22 08:52:21 -06:00
Evan Husted
cd8113dadf misc: chore: Collapse adding a game/autoload dir into a single reusable method. 2025-01-21 18:59:56 -06:00
Evan Husted
9089c4ffe5 misc: chore: Multi/Single file/folder picker extensions (for convenience)
The result of these extensions is an empty Optional when the user hits Cancel on the shown file picker.
2025-01-21 18:59:19 -06:00
Evan Husted
fe9d8d05bd UI: Fixed the Amiibo keybind only working when the UI had been updated. 2025-01-21 18:00:51 -06:00
Evan Husted
880a8ae748 misc: chore: Remove duplicated styling blocks in MainMenuBarView in favor of a reusable Avalonia Style. 2025-01-21 17:50:55 -06:00
asfasagag
11531dacb6 UI: Option to automatically Hide UI when game launches (#462)
Quality of life feature
Similar in function to the "Start Games in Fullscreen" toggle
For users who want to run games in windowed/non-fullscreen mode with
menu UI hidden, this eliminates the need to always click "Hide UI"
2025-01-21 17:36:51 -06:00
Evan Husted
3974739ed3 More descriptive classification 2025-01-21 17:35:22 -06:00
Evan Husted
440a3447fb docs: compat: Update South Park: The Fractured but Whole: playable -> boots 2025-01-21 17:10:54 -06:00
Evan Husted
65374ed6cb UI: [ci skip] clarify dirty hacks subtext 2025-01-21 16:57:05 -06:00
Evan Husted
789d6ab959 misc: chore: Improve autoloading DLC/updates logging, deliberately switch to Vulkan if Metal was somehow chosen on a non-mac system, add logger lines in the updater, cleanup enabled logs printing 2025-01-21 14:59:08 -06:00
Evan Husted
182db31343 metal: Added Persona 4 Arena Ultimax to Auto 2025-01-21 14:07:05 -06:00
Evan Husted
ea296b134d Use specific Ubuntu version in build script 2025-01-21 14:05:49 -06:00
Evan Husted
bf584442b2 misc: chore: remove needless call to string.Format 2025-01-21 14:05:49 -06:00
Otozinclus
cb7c294dbf Add more games to metal game list (#558)
Link's awakening I have played through most of the game with 0 issues.

In LEGO City undercover I have played multiple missions and explored the
map, I was unable to spot any issue. Except shadows flickering
sometimes, but that seems to happen on Vulkan and the PC version as well
and is propably normal.

Bayonetta seems to work flawless so far.

In Fast RMX, some tracks have flickering issues, like the second track
of the first cup. This happens on Vulkan as well.

-

Mario Bros. Wonder has following issues:

Overall issues:
- Sometimes there is short white flickering/artifacts, but they happen
on Vulkan as well.

Metal specific issue:
- In 2 underwater levels, a specific location causes a FPS drop not
present on Vulkan. But this is very minor and on all current M chips you
get on average better FPS with Metal (On my M3, there are occasional
drops that are worse with Vulkan), reducing stutter quite noticeably,
which is why I think it should get added to auto regardless.

- Isaac mentioned there is a issue in level 2, where the flowers singing
desync somehow. However, I was after lot of testing unable to replicate
this issue at all. More testing could be useful.

Fix: Fixed 2 typos in the comments
2025-01-21 14:05:41 -06:00
Daenorth
eaf1e7efd2 Cleanup in TitleIDs.cs (#546)
Just a little cleanup in TitleID.cs, adding a franchise title to most
franchises + sorting in alphabetical on all games.
2025-01-21 11:20:43 -06:00
Judas Drekonym
471e7ed2e4 Add TitleID sort method (#553)
Adds an additional application list sorting method for the TitleID. A
bit of a niche choice for sorting but I think the TID is a relevant
enough piece of metadata that it should be there. (And I personally
would be using it)

- Using existing TitleId constant in ApplicationSort, implying this was
meant to be in the sorting options at some point?
- Reuses the "DlcManagerTableHeadingTitleIdLabel" locale for fulfilling
the need already, might be better to make a unique one for this in the
long run but this codebase is new to me so I wanted to make the changes
as unobtrusive as possible
- Using app.Id for the comparer seems to work fine, not sure if using
something else like IdString would be better?
2025-01-21 11:06:40 -06:00
Matt Zinkevicius
ad3e80b383 Log .NET runtime version (#552)
I was looking into a crash, and found out it was an issue that was fixed
in .NET 9.0.1. Since Ryujinx embeds the runtime into the executable, it
not obvious which runtime a build uses. This logs the .NET runtime
version immediately after the build version.
2025-01-20 19:19:19 -06:00
Evan Husted
ed64a63094 UI: Visually merge "Actions" and "Tools" menu bar items into Actions
The contents of the menu item are dependent on whether you're in a game.
No functionality has been removed.
2025-01-20 16:56:05 -06:00
Evan Husted
8df7ba2d56 i18n: Norwegian DLC RomFS dumping translation 2025-01-20 15:55:37 -06:00
LotP1
e743d78115 Add/fix service reported info (#551)
fixes the GetConfig service call, which now returns success correctly
adds support for getting the device serial number (which is fake and
reports as "RYU00000000000")
2025-01-20 14:59:54 -06:00
Evan Husted
04ba762710 UI: Move DLC RomFS dumping under normal RomFS dumping.
Also removed it from DLC manager.
2025-01-20 14:30:28 -06:00
Evan Husted
f42b2ed59d misc: chore: more correct last used user checking 2025-01-20 13:33:59 -06:00
Evan Husted
d135385cab Leftovers, oops 2025-01-20 09:32:38 -06:00
Evan Husted
b360f4e721 UI: Dump DLC RomFS.
You can access this in the Manage DLC screen, it's the new button on each DLC line.

Closes #548
2025-01-20 09:28:58 -06:00
Daenorth
a1c0c70ec2 Added missing TitleIDs (#545)
Added the remaining missing TitleIDs in the compat.csv list.
Excluding Homebrew apps.
2025-01-19 21:15:46 -06:00
Daenorth
290ac405ac Updated Ukrainian translation by Rondo (#543)
Co-authored-by: rrondo <46533574+rrondo@users.noreply.github.com>
2025-01-19 21:00:40 -06:00
Evan Husted
bbd64fd5f0 misc: chore: Cleanup AppletMetadata usage 2025-01-19 19:40:49 -06:00
Evan Husted
09446fd80e [ci skip] infra: Update copyright year in shortcut plist 2025-01-19 18:57:05 -06:00
Evan Husted
4f014a89cf docs: compat: Donkey Kong Country Returns HD 2025-01-19 18:28:43 -06:00
Evan Husted
6482e566ab UI: Compat: Unload compatibility entries when the window closes. 2025-01-19 17:41:50 -06:00
Evan Husted
7fcd9b792e UI: Compat: Update owned game title IDs when ApplicationLibrary app count updates 2025-01-19 17:41:31 -06:00
Evan Husted
e676fd8b17 UI: misc: simplify Intel Mac warning logic 2025-01-19 14:42:15 -06:00
Evan Husted
dd16e3cee1 misc: chore: very small cleanup in AvaHostUIHandler 2025-01-19 13:18:40 -06:00
Evan Husted
31e5f74e05 UI: misc: Replace spaces in Title with newlines when using custom title bar (since the Title is in an Avalonia tooltip) 2025-01-19 13:05:20 -06:00
Evan Husted
f2f099bddb remove Async suffixes; they're factory methods not actual async methods. 2025-01-19 12:46:32 -06:00
Evan Husted
2616dc57fb misc: chore: RelayCommand helper 2025-01-19 12:44:07 -06:00
Evan Husted
0cdf7cfe21 UI: Open cheat manager in catch-all try 2025-01-18 22:48:06 -06:00
Evan Husted
2ecf999569 misc: chore: change ThemeManager ThemeChanged to a basic Action since both arguments are unused 2025-01-18 22:48:06 -06:00
Daenorth
b612fc5155 Updated TitleIDs (#541)
Added more games to the RPC list. Now alphabetical.
2025-01-18 22:19:28 -06:00
Evan Husted
25eb545409 Update bug_report.yml 2025-01-18 20:55:28 -06:00
Jacob
52269964b6 Add the player select applet. (#537)
This introduces the somewhat completed version of the Player Select
Applet, allowing users to select either a user or a guest from the UI.
Note: Selecting the guest more then once currently does not work.

closes https://github.com/Ryubing/Ryujinx/issues/532
2025-01-18 20:40:33 -06:00
Evan Husted
ccdddac8fc Fix compile warnings 2025-01-18 19:34:31 -06:00
Daenorth
1bc30bf3ba Update locales.json (#538)
Added a missing translation line
2025-01-18 18:40:51 -06:00
Evan Husted
4868fface8 UI: Intel Mac warning
Upon launch, shows a warning about using an Intel Mac. This will only show once every boot. You can only turn it off by getting a better system.
2025-01-18 15:33:05 -06:00
Evan Husted
6fca4492d0 misc: chore: Remove status update event stuff in Headless 2025-01-18 15:15:08 -06:00
Evan Husted
ade2f256e0 misc: chore: remove duplicate graphics debug levels in headless windows 2025-01-18 11:19:38 -06:00
Evan Husted
580b150c9a Revert "infra: Conditionally compile Metal & OpenGL depending on if the target RuntimeIdentifier is mac"
This reverts commit 2f93a0f706.
2025-01-18 10:57:02 -06:00
Evan Husted
e6bad52945 Revert "Only selectively compile Metal & fix some compilation issues"
This reverts commit beda3206e0.
2025-01-18 10:56:58 -06:00
Evan Husted
beda3206e0 Only selectively compile Metal & fix some compilation issues 2025-01-18 10:52:32 -06:00
Evan Husted
2f93a0f706 infra: Conditionally compile Metal & OpenGL depending on if the target RuntimeIdentifier is mac 2025-01-18 10:38:29 -06:00
Evan Husted
80f44d9547 misc: chore: small cleanup 2025-01-18 10:33:57 -06:00
Evan Husted
b08e5db6d8 Headless: Dispose of inputmanager in a catch-all try 2025-01-18 10:30:19 -06:00
Evan Husted
6a291d4116 Headless: Use main UI logo for window icon instead of separate bmp 2025-01-18 10:26:12 -06:00
Evan Husted
6fc827fe67 headless: collapse headless window definition into a "Windows" folder, change GetWindowFlags to an abstract property. 2025-01-18 10:15:24 -06:00
Daniel Nylander
6cd4866d76 Updated sv_SE in locales.json (#513) 2025-01-17 18:04:18 -06:00
WilliamWsyHK
4d7ca5c0f0 Update Chinese translations (#375) 2025-01-17 17:35:34 -06:00
GabCoolGuy
a375faecc1 UI: Fix UpdateWaitWindow.axaml windows being too big on windows (#314) 2025-01-17 14:14:19 -06:00
Evan Husted
1728b0f20c WWE 2K18 is not playable. 2025-01-17 11:37:08 -06:00
LotP1
5aa071c59b remove notice for unusual core counts (#531) 2025-01-17 05:50:42 -06:00
Daenorth
1018c9db8b Update Norwegian Translation (#503)
Norwegian translation updated with the Compatibility list addition
2025-01-16 10:02:33 -06:00
Evan Husted
01ccd18726 UI: Meant to use that method in another place [ci-skip] 2025-01-16 09:52:35 -06:00
Evan Husted
abfbc6f4bc UI: Prevent desynced RPC when toggling it off/on while in-game 2025-01-16 09:52:01 -06:00
Francesco Saltori
6a4bc02d7a Update Italian translation (#489) 2025-01-16 06:38:36 -06:00
Hack茶ん
814c0526d2 Korean translations for compat list (#502) 2025-01-16 04:57:32 -06:00
Evan Husted
a5a4ef38e6 HLE: Stub IHidServer SetGestureOutputRanges (#524)
Lets "Donkey Kong Country Returns HD" get into main gameplay.
2025-01-16 02:39:39 -06:00
Evan Husted
c17e3bfcdf genuinely dont know how that was still there, i thought i got rid of UI.Common 2025-01-15 03:01:17 -06:00
Evan Husted
017f46f318 HLE: misc: throw a more descriptive error when the loaded processes doesn't contain _latestPid (likely missing FW) 2025-01-15 03:01:17 -06:00
Keaton
fd4d801bfd Various NuGet package updates (#203)
Updates the following packages:

**nuget: bump the avalonia group with 7 updates**

* Bump Avalonia, Avalonia.Controls.DataGrid, Avalonia.Desktop,
Avalonia.Diagnostics, and Avalonia.Markup.Xaml.Loader from 11.0.10 to
11.0.13
* Bump Avalonia.Svg and Avalonia.Svg.Skia from 11.0.0.18 to 11.0.0.19

**nuget: bump non-avalonia packages**

* Bump Concentus from 2.2.0 to 2.2.2
* Bump Microsoft.IdentityModel.JsonWebTokens from 8.1.2 to 8.3.0
* Bump Silk.NET.Vulkan group with 3 updates (2.21.0 to 2.22.0)
* Bump SkiaSharp group with 2 updates (2.88.7 to 2.88.9)
2025-01-13 11:15:05 -06:00
GabCoolGuy
f1dee50275 infra: Update to LLVM 17 (#519)
This fixes macos builds not building correctly because of a missing
LLVM 14 package.
2025-01-12 14:57:57 -06:00
shinyoyo
c2ae49eb47 Add some missing Simplified Chinese translations (#515) 2025-01-12 12:33:27 -06:00
WilliamWsyHK
47c71966d0 Add compat of Xenoblade 2 JP edition same as global edition (#517) 2025-01-12 12:31:58 -06:00
Evan Husted
f9e8f4bc29 docs: compat: Ori and the Will of the Wisps is now ingame, not playable 2025-01-11 06:10:58 -06:00
Evan Husted
7694c8c046 Do not auto release stable 2025-01-11 04:08:11 -06:00
Evan Husted
0dd789e8a5 misc: chore: remove redundant trimming on CompatibilityEntry.GameName init 2025-01-11 01:26:34 -06:00
Evan Husted
4e0aafd005 docs: compat: Trim redundant/duplicate information to save space 2025-01-11 01:18:10 -06:00
Evan Husted
c5091f499e docs: compat: The House of the Dead: Remake Playable 2025-01-11 00:38:32 -06:00
Evan Husted
41c8fd8194 misc: chore: lol this field was misspelled 2025-01-10 23:23:53 -06:00
Evan Husted
d4a7ee25ea misc: chore: use ObservableProperty on input view models 2025-01-10 23:23:05 -06:00
Evan Husted
3141c560fb misc: chore: remove sender parameter from LdnGameData receieved event 2025-01-10 23:15:55 -06:00
Evan Husted
de341b285b misc: use ObservableProperty on HotkeyConfig fields 2025-01-10 23:15:37 -06:00
Evan Husted
cc95e80ee9 misc: chore: Move converters into a directory in Helpers. Namespace unchanged 2025-01-10 20:24:53 -06:00
Evan Husted
d75ce52bd4 UI: Show play time in one time unit, maxing out at hours. 2025-01-10 20:23:47 -06:00
Evan Husted
4a4ea557de UI: compat: show last updated date on entry hover 2025-01-10 01:43:34 -06:00
Evan Husted
33f42adb11 Merge remote-tracking branch 'origin/master' 2025-01-09 22:09:01 -06:00
LotP1
918ec1bde3 cores rework (#505)
This PR changes the core count to be defined in the device instead of
being a const value.
This is mostly a change for future features I want to implement and
should not impact any functionality.
The console will now log the range of cores requested from the
application, and for now, if the requested range is not 0 to 2 (the 3
cores used for application emulation), it will give an error message
which tells the user to contact me on discord. I'm doing this because
I'm interested in finding applications/games that don't use 3 cores and
the error will be removed in the future once I've gotten enough data.
2025-01-09 21:43:18 -06:00
Evan Husted
cca429d46a misc: chore: restore not enable 2025-01-09 21:42:54 -06:00
Evan Husted
845c86f545 misc: chore: cleanup AppletMetadata.CanStart 2025-01-09 21:14:35 -06:00
Evan Husted
27993b789f misc: chore: fix some compile warnings 2025-01-09 20:23:26 -06:00
Evan Husted
bdd890cf6f UI: logger function name 2025-01-09 19:48:11 -06:00
Evan Husted
c5574b41a1 UI: collapse LoadFromStream into static ctor
pass the index get delegate to the struct instead of the entire header
2025-01-09 19:44:24 -06:00
Evan Husted
292e27f0da UI: dispose CSV reader when done + use explicit types 2025-01-09 19:24:48 -06:00
838 changed files with 17291 additions and 14544 deletions

View File

@@ -22,7 +22,7 @@ body:
id: log id: log
attributes: attributes:
label: Log file label: Log file
description: A log file will help our developers to better diagnose and fix the issue. description: "A log file will help our developers to better diagnose and fix the issue. UPLOAD THE FILE. DO NOT COPY AND PASTE THE FILE'S CONTENT."
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste). placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
validations: validations:
required: true required: true

4
.github/labeler.yml vendored
View File

@@ -18,6 +18,10 @@ gpu:
- changed-files: - changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**'] - any-glob-to-any-file: ['src/Ryujinx.Graphics.Vulkan/**', 'src/Spv.Generator/**']
'graphics-backend:metal':
- changed-files:
- any-glob-to-any-file: ['src/Ryujinx.Graphics.Metal/**', 'src/Ryujinx.Graphics.Metal.SharpMetalExtensions/**']
gui: gui:
- changed-files: - changed-files:
- any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**'] - any-glob-to-any-file: ['src/Ryujinx/**', 'src/Ryujinx.UI.Common/**', 'src/Ryujinx.UI.LocaleGenerator/**']

View File

@@ -129,11 +129,11 @@ jobs:
with: with:
global-json-file: global.json global-json-file: global.json
- name: Setup LLVM 14 - name: Setup LLVM 17
run: | run: |
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 14 sudo ./llvm.sh 17
- name: Install rcodesign - name: Install rcodesign
run: | run: |

View File

@@ -202,7 +202,7 @@ jobs:
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -210,11 +210,11 @@ jobs:
with: with:
global-json-file: global.json global-json-file: global.json
- name: Setup LLVM 15 - name: Setup LLVM 17
run: | run: |
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 15 sudo ./llvm.sh 17
- name: Install rcodesign - name: Install rcodesign
run: | run: |

View File

@@ -3,16 +3,6 @@ name: Release job
on: on:
workflow_dispatch: workflow_dispatch:
inputs: {} inputs: {}
push:
branches: [ release ]
paths-ignore:
- '.github/**'
- 'docs/**'
- 'assets/**'
- '*.yml'
- '*.json'
- '*.config'
- '*.md'
concurrency: release concurrency: release
@@ -193,7 +183,7 @@ jobs:
macos_release: macos_release:
name: Release MacOS universal name: Release MacOS universal
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -201,11 +191,11 @@ jobs:
with: with:
global-json-file: global.json global-json-file: global.json
- name: Setup LLVM 15 - name: Setup LLVM 17
run: | run: |
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 15 sudo ./llvm.sh 17
- name: Install rcodesign - name: Install rcodesign
run: | run: |

View File

@@ -10,7 +10,7 @@ Make sure your SDK version is higher or equal to the required version specified
### Step 2 ### Step 2
Either use `git clone https://github.com/GreemDev/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files. Either use `git clone https://github.com/Ryubing/Ryujinx` on the command line to clone the repository or use Code --> Download zip button to get the files.
### Step 3 ### Step 3

View File

@@ -14,13 +14,13 @@ We always welcome bug reports, feature proposals and overall feedback. Here are
### Finding Existing Issues ### Finding Existing Issues
Before filing a new issue, please search our [open issues](https://github.com/GreemDev/Ryujinx/issues) to check if it already exists. Before filing a new issue, please search our [open issues](https://github.com/Ryubing/Ryujinx/issues) to check if it already exists.
If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog. If you do find an existing issue, please include your own feedback in the discussion. Do consider upvoting (👍 reaction) the original post, as this helps us prioritize popular issues in our backlog.
### Writing a Good Feature Request ### Writing a Good Feature Request
Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/GreemDev/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D). Please review any feature requests already opened to both check it has not already been suggested, and to familiarize yourself with the format. When ready to submit a proposal, please use the [Feature Request issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=%5BFeature+Request%5D).
### Writing a Good Bug Report ### Writing a Good Bug Report
@@ -34,13 +34,13 @@ Ideally, a bug report should contain the following information:
* A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically. * A Ryujinx log file of the run instance where the issue occurred. Log files can be found in `[Executable Folder]/Logs` and are named chronologically.
* Additional information, e.g. is it a regression from previous versions? Are there any known workarounds? * Additional information, e.g. is it a regression from previous versions? Are there any known workarounds?
When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/GreemDev/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D). When ready to submit a bug report, please use the [Bug Report issue template](https://github.com/Ryubing/Ryujinx/issues/new?assignees=&labels=bug&projects=&template=bug_report.yml&title=%5BBug%5D).
## Contributing Changes ## Contributing Changes
Project maintainers will merge changes that both improve the project and meet our standards for code quality. Project maintainers will merge changes that both improve the project and meet our standards for code quality.
The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance. The [Pull Request Guide](docs/workflow/pr-guide.md) and [License](https://github.com/Ryubing/Ryujinx/blob/master/LICENSE.txt) docs define additional guidance.
### DOs and DON'Ts ### DOs and DON'Ts
@@ -74,14 +74,14 @@ We use and recommend the following workflow:
3. In your fork, create a branch off of main (`git checkout -b mybranch`). 3. In your fork, create a branch off of main (`git checkout -b mybranch`).
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork. - Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
4. Make and commit your changes to your branch. 4. Make and commit your changes to your branch.
- [Build Instructions](https://github.com/GreemDev/Ryujinx/blob/master/COMPILING.md) explains how to build and test. - [Build Instructions](https://github.com/Ryubing/Ryujinx/blob/master/COMPILING.md) explains how to build and test.
- Commit messages should be clear statements of action and intent. - Commit messages should be clear statements of action and intent.
6. Build the repository with your changes. 6. Build the repository with your changes.
- Make sure that the builds are clean. - Make sure that the builds are clean.
- Make sure that `dotnet format` has been run and any corrections tested and committed. - Make sure that `dotnet format` has been run and any corrections tested and committed.
7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch. 7. Create a pull request (PR) against the Ryujinx/Ryujinx repository's **main** branch.
- State in the description what issue or improvement your change is addressing. - State in the description what issue or improvement your change is addressing.
- Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/GreemDev/Ryujinx/actions) to check for outstanding errors. - Check if all the Continuous Integration checks are passing. Refer to [Actions](https://github.com/Ryubing/Ryujinx/actions) to check for outstanding errors.
8. Wait for feedback or approval of your changes from the core development team 8. Wait for feedback or approval of your changes from the core development team
- Details about the pull request [review procedure](docs/workflow/pr-guide.md). - Details about the pull request [review procedure](docs/workflow/pr-guide.md).
9. When the team members have signed off, and all checks are green, your PR will be merged. 9. When the team members have signed off, and all checks are green, your PR will be merged.
@@ -90,7 +90,7 @@ We use and recommend the following workflow:
### Good First Issues ### Good First Issues
The team marks the most straightforward issues as [good first issues](https://github.com/GreemDev/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase. The team marks the most straightforward issues as [good first issues](https://github.com/Ryubing/Ryujinx/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). This set of issues is the place to start if you are interested in contributing but new to the codebase.
### Commit Messages ### Commit Messages
@@ -113,7 +113,7 @@ Also do your best to factor commits appropriately, not too large with unrelated
### PR - CI Process ### PR - CI Process
The [Ryujinx continuous integration](https://github.com/GreemDev/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change. The [Ryujinx continuous integration](https://github.com/Ryubing/Ryujinx/actions) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.
If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure: If the CI build fails for any reason, the PR actions tab should be consulted for further information on the failure. There are a few usual suspects for such a failure:
* `dotnet format` has not been run on the PR and has outstanding stylistic issues. * `dotnet format` has not been run on the PR and has outstanding stylistic issues.
@@ -134,5 +134,5 @@ Ryujinx uses some implementations and frameworks from other projects. The follow
- The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence). - The license of the file is [permissive](https://en.wikipedia.org/wiki/Permissive_free_software_licence).
- The license of the file is left in-tact. - The license of the file is left in-tact.
- The contribution is correctly attributed in the [3rd party notices](https://github.com/GreemDev/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed. - The contribution is correctly attributed in the [3rd party notices](https://github.com/Ryubing/Ryujinx/blob/master/distribution/legal/THIRDPARTY.md) file in the repository, as needed.

View File

@@ -3,13 +3,13 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageVersion Include="Avalonia" Version="11.0.10" /> <PackageVersion Include="Avalonia" Version="11.0.13" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" /> <PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" /> <PackageVersion Include="Avalonia.Desktop" Version="11.0.13" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.0.10" /> <PackageVersion Include="Avalonia.Diagnostics" Version="11.0.13" />
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.10" /> <PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.13" />
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.18" /> <PackageVersion Include="Avalonia.Svg" Version="11.0.0.19" />
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.18" /> <PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.19" />
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" /> <PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" /> <PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
@@ -18,7 +18,7 @@
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/> <PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
<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.0" /> <PackageVersion Include="Concentus" Version="2.2.2" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageVersion Include="DynamicData" Version="9.0.4" /> <PackageVersion Include="DynamicData" Version="9.0.4" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
@@ -26,7 +26,7 @@
<PackageVersion Include="LibHac" Version="0.19.0" /> <PackageVersion Include="LibHac" Version="0.19.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.1.2" /> <PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.3.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" /> <PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" /> <PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
@@ -42,17 +42,17 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
<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.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.0.1" /> <PackageVersion Include="Gommon" Version="2.7.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.6.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" /> <PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.22.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.21.0" /> <PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.22.0" />
<PackageVersion Include="SkiaSharp" Version="2.88.7" /> <PackageVersion Include="SkiaSharp" Version="2.88.9" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" /> <PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.9" />
<PackageVersion Include="SPB" Version="0.0.4-build32" /> <PackageVersion Include="SPB" Version="0.0.4-build32" />
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" /> <PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
<PackageVersion Include="System.Management" Version="9.0.0" /> <PackageVersion Include="System.Management" Version="9.0.0" />

View File

@@ -7,11 +7,11 @@
# Ryujinx # Ryujinx
[![Release workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml) [![Release workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/release.yml)
[![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/GreemDev/Ryujinx/releases/latest) [![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/Ryubing/Ryujinx/releases/latest)
<br> <br>
[![Canary workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml) [![Canary workflow](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/Ryubing/Ryujinx/actions/workflows/canary.yml)
[![Latest canary release](https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary)](https://github.com/GreemDev/Ryujinx-Canary/releases/latest) [![Latest canary release](https://img.shields.io/github/v/release/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest)
</td> </td>
</tr> </tr>
</table> </table>
@@ -20,7 +20,7 @@
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#. Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds. This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
It was written from scratch and development on the project began in September 2017. It was written from scratch and development on the project began in September 2017.
Ryujinx is available on GitHub under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>. Ryujinx is available on GitHub under the <a href="https://github.com/Ryubing/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
<br /> <br />
</p> </p>
<p align="center"> <p align="center">
@@ -30,7 +30,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://github.com/GreemDev/Ryujinx/wiki">Wiki tab</a>. Guides and documentation can be found on the <a href="https://github.com/Ryubing/Ryujinx/wiki">Wiki tab</a>.
</p> </p>
<p align="center"> <p align="center">
If you would like a more preservative fork of Ryujinx, check out <a href="https://github.com/ryujinx-mirror/ryujinx">ryujinx-mirror</a>. If you would like a more preservative fork of Ryujinx, check out <a href="https://github.com/ryujinx-mirror/ryujinx">ryujinx-mirror</a>.
@@ -54,16 +54,17 @@ failing to meet this requirement may result in a poor gameplay experience or une
## Latest build ## Latest build
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love. Stable builds are made every so often, based on the `master` branch, that then gets put into the releases you know and love.
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.
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest). You can find the latest stable release [here](https://github.com/Ryubing/Ryujinx/releases/latest).
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/GreemDev/Ryujinx-Canary/releases/latest). You can find the latest canary release [here](https://github.com/Ryubing/Canary-Releases/releases/latest).
## Documentation ## Documentation
@@ -109,7 +110,7 @@ If you are planning to contribute or just want to learn more about this project
- **Configuration** - **Configuration**
The emulator has settings for enabling or disabling some logging, remapping controllers, and more. The emulator has settings for enabling or disabling some logging, remapping controllers, and more.
You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the user folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI. You can configure all of them through the graphical interface or manually through the config file, `Config.json`, found in the Ryujinx data folder which can be accessed by clicking `Open Ryujinx Folder` under the File menu in the GUI.
## License ## License

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@ if platform.system() == "Darwin":
else: else:
OTOOL = shutil.which("llvm-otool") OTOOL = shutil.which("llvm-otool")
if OTOOL is None: if OTOOL is None:
for llvm_ver in [15, 14, 13]: for llvm_ver in [17, 16, 15, 14, 13]:
otool_path = shutil.which(f"llvm-otool-{llvm_ver}") otool_path = shutil.which(f"llvm-otool-{llvm_ver}")
if otool_path is not None: if otool_path is not None:
OTOOL = otool_path OTOOL = otool_path

View File

@@ -26,7 +26,7 @@ else:
LIPO = shutil.which("llvm-lipo") LIPO = shutil.which("llvm-lipo")
if LIPO is None: if LIPO is None:
for llvm_ver in [15, 14, 13]: for llvm_ver in [17, 16, 15, 14, 13]:
lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}") lipo_path = shutil.which(f"llvm-lipo-{llvm_ver}")
if lipo_path is not None: if lipo_path is not None:
LIPO = lipo_path LIPO = lipo_path

View File

@@ -67,11 +67,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_APP_
if ! [ -x "$(command -v lipo)" ]; if ! [ -x "$(command -v lipo)" ];
then then
if ! [ -x "$(command -v llvm-lipo-14)" ]; if ! [ -x "$(command -v llvm-lipo-17)" ];
then then
LIPO=llvm-lipo LIPO=llvm-lipo
else else
LIPO=llvm-lipo-14 LIPO=llvm-lipo-17
fi fi
else else
LIPO=lipo LIPO=lipo

View File

@@ -62,11 +62,11 @@ python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTP
if ! [ -x "$(command -v lipo)" ]; if ! [ -x "$(command -v lipo)" ];
then then
if ! [ -x "$(command -v llvm-lipo-14)" ]; if ! [ -x "$(command -v llvm-lipo-17)" ];
then then
LIPO=llvm-lipo LIPO=llvm-lipo
else else
LIPO=llvm-lipo-14 LIPO=llvm-lipo-17
fi fi
else else
LIPO=lipo LIPO=lipo

View File

@@ -19,7 +19,7 @@
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 - 2023 Ryujinx Team and Contributors.</string> <string>Copyright © 2018 - 2025 Ryujinx Team and Contributors.</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

File diff suppressed because it is too large Load Diff

View File

@@ -18,13 +18,13 @@ To merge pull requests, you must have write permissions in the repository.
## Pull Request Ownership ## Pull Request Ownership
Every pull request will have automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned. Every pull request will automatically have labels and reviewers assigned. The label not only indicates the code segment which the change touches but also the area reviewers to be assigned.
If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github). If during the code review process a merge conflict occurs, the PR author is responsible for its resolution. Help will be provided if necessary although GitHub makes this easier by allowing simple conflict resolution using the [conflict-editor](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github).
## Pull Request Builds ## Pull Request Builds
When submitting a PR to the `GreemDev/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/GreemDev/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion. When submitting a PR to the `Ryubing/Ryujinx` repository, various builds will run validating many areas to ensure we keep developer productivity and product quality high. These various workflows can be tracked in the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of the repository. If the job continues to completion, the build artifacts will be uploaded and posted as a comment in the PR discussion.
## Review Turnaround Times ## Review Turnaround Times
@@ -42,7 +42,7 @@ Anyone with write access can merge a pull request manually when the following co
* The PR has been approved by two reviewers and any other objections are addressed. * The PR has been approved by two reviewers and any other objections are addressed.
* You can request follow up reviews from the original reviewers if they requested changes. * You can request follow up reviews from the original reviewers if they requested changes.
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/GreemDev/Ryujinx/actions) tab of your PR. * The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [Actions](https://github.com/Ryubing/Ryujinx/actions) tab of your PR.
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them. Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to dissect them.

View File

@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.Arm64
public static void RunPass(ControlFlowGraph cfg) public static void RunPass(ControlFlowGraph cfg)
{ {
var constants = new Dictionary<ulong, Operand>(); Dictionary<ulong, Operand> constants = new();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{ {
// If the constant has many uses, we also force a new constant mov to be added, in order // If the constant has many uses, we also force a new constant mov to be added, in order
// to avoid overflow of the counts field (that is limited to 16 bits). // to avoid overflow of the counts field (that is limited to 16 bits).
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses) if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
{ {
constant = Local(source.Type); constant = Local(source.Type);

View File

@@ -123,7 +123,7 @@ namespace ARMeilleure.CodeGen.Arm64
public void Cset(Operand rd, ArmCondition condition) public void Cset(Operand rd, ArmCondition condition)
{ {
var zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type); Operand zr = Factory.Register(ZrRegister, RegisterType.Integer, rd.Type);
Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1)); Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
} }

View File

@@ -42,7 +42,7 @@ namespace ARMeilleure.CodeGen.Arm64
{ {
Offset = offset; Offset = offset;
Symbol = symbol; Symbol = symbol;
LdrOffsets = new List<(Operand, int)>(); LdrOffsets = [];
} }
} }
@@ -91,7 +91,7 @@ namespace ARMeilleure.CodeGen.Arm64
long target = _stream.Position; long target = _stream.Position;
if (_pendingBranches.TryGetValue(block, out var list)) if (_pendingBranches.TryGetValue(block, out List<(ArmCondition Condition, long BranchPos)> list))
{ {
foreach ((ArmCondition condition, long branchPos) in list) foreach ((ArmCondition condition, long branchPos) in list)
{ {
@@ -119,7 +119,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
else else
{ {
if (!_pendingBranches.TryGetValue(target, out var list)) if (!_pendingBranches.TryGetValue(target, out List<(ArmCondition Condition, long BranchPos)> list))
{ {
list = new List<(ArmCondition, long)>(); list = new List<(ArmCondition, long)>();
_pendingBranches.Add(target, list); _pendingBranches.Add(target, list);
@@ -266,7 +266,7 @@ namespace ARMeilleure.CodeGen.Arm64
} }
else else
{ {
relocInfo = new RelocInfo(Array.Empty<RelocEntry>()); relocInfo = new RelocInfo([]);
} }
return (code, relocInfo); return (code, relocInfo);

View File

@@ -322,7 +322,7 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var cond = ((Comparison)comp.AsInt32()).ToArmCondition(); ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -354,7 +354,7 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(dest.Type == OperandType.I32); Debug.Assert(dest.Type == OperandType.I32);
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var cond = ((Comparison)comp.AsInt32()).ToArmCondition(); ArmCondition cond = ((Comparison)comp.AsInt32()).ToArmCondition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -1079,7 +1079,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new(); List<UnwindPushEntry> pushEntries = [];
Operand rsp = Register(SpRegister); Operand rsp = Register(SpRegister);

View File

@@ -140,8 +140,8 @@ namespace ARMeilleure.CodeGen.Arm64
return false; return false;
} }
private static readonly string[] _sysctlNames = new string[] private static readonly string[] _sysctlNames =
{ [
"hw.optional.floatingpoint", "hw.optional.floatingpoint",
"hw.optional.AdvSIMD", "hw.optional.AdvSIMD",
"hw.optional.arm.FEAT_FP16", "hw.optional.arm.FEAT_FP16",
@@ -150,8 +150,8 @@ namespace ARMeilleure.CodeGen.Arm64
"hw.optional.arm.FEAT_LSE", "hw.optional.arm.FEAT_LSE",
"hw.optional.armv8_crc32", "hw.optional.armv8_crc32",
"hw.optional.arm.FEAT_SHA1", "hw.optional.arm.FEAT_SHA1",
"hw.optional.arm.FEAT_SHA256", "hw.optional.arm.FEAT_SHA256"
}; ];
[Flags] [Flags]
public enum MacOsFeatureFlags public enum MacOsFeatureFlags

View File

@@ -261,10 +261,10 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination; Operand dest = operation.Destination;
List<Operand> sources = new() List<Operand> sources =
{ [
operation.GetSource(0), operation.GetSource(0)
}; ];
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@@ -365,10 +365,10 @@ namespace ARMeilleure.CodeGen.Arm64
Operation node, Operation node,
Operation operation) Operation operation)
{ {
List<Operand> sources = new() List<Operand> sources =
{ [
operation.GetSource(0), operation.GetSource(0)
}; ];
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@@ -468,8 +468,8 @@ namespace ARMeilleure.CodeGen.Arm64
// Update the sources and destinations with split 64-bit halfs of the whole 128-bit values. // Update the sources and destinations with split 64-bit halfs of the whole 128-bit values.
// We also need a additional registers that will be used to store temporary information. // We also need a additional registers that will be used to store temporary information.
operation.SetDestinations(new[] { actualLow, actualHigh, Local(OperandType.I64), Local(OperandType.I64) }); operation.SetDestinations([actualLow, actualHigh, Local(OperandType.I64), Local(OperandType.I64)]);
operation.SetSources(new[] { address, expectedLow, expectedHigh, desiredLow, desiredHigh }); operation.SetSources([address, expectedLow, expectedHigh, desiredLow, desiredHigh]);
// Add some dummy uses of the input operands, as the CAS operation will be a loop, // Add some dummy uses of the input operands, as the CAS operation will be a loop,
// so they can't be used as destination operand. // so they can't be used as destination operand.
@@ -486,7 +486,7 @@ namespace ARMeilleure.CodeGen.Arm64
else else
{ {
// We need a additional register where the store result will be written to. // We need a additional register where the store result will be written to.
node.SetDestinations(new[] { node.Destination, Local(OperandType.I32) }); node.SetDestinations([node.Destination, Local(OperandType.I32)]);
// Add some dummy uses of the input operands, as the CAS operation will be a loop, // Add some dummy uses of the input operands, as the CAS operation will be a loop,
// so they can't be used as destination operand. // so they can't be used as destination operand.
@@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.Arm64
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType == Comparison.Equal || compType == Comparison.NotEqual;
} }

View File

@@ -10,7 +10,7 @@ namespace ARMeilleure.CodeGen.Linking
/// <summary> /// <summary>
/// Gets an empty <see cref="RelocInfo"/>. /// Gets an empty <see cref="RelocInfo"/>.
/// </summary> /// </summary>
public static RelocInfo Empty { get; } = new RelocInfo(null); public static RelocInfo Empty { get; } = new(null);
private readonly RelocEntry[] _entries; private readonly RelocEntry[] _entries;

View File

@@ -31,7 +31,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public ParallelCopy() public ParallelCopy()
{ {
_copies = new List<Copy>(); _copies = [];
} }
public void AddCopy(Register dest, Register source, OperandType type) public void AddCopy(Register dest, Register source, OperandType type)
@@ -218,7 +218,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public Operation[] Sequence() public Operation[] Sequence()
{ {
List<Operation> sequence = new(); List<Operation> sequence = [];
if (_spillQueue != null) if (_spillQueue != null)
{ {

View File

@@ -115,7 +115,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
NumberLocals(cfg, regMasks.RegistersCount); NumberLocals(cfg, regMasks.RegistersCount);
var context = new AllocationContext(stackAlloc, regMasks, _intervals.Count); AllocationContext context = new(stackAlloc, regMasks, _intervals.Count);
BuildIntervals(cfg, context); BuildIntervals(cfg, context);
@@ -799,8 +799,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private void NumberLocals(ControlFlowGraph cfg, int registersCount) private void NumberLocals(ControlFlowGraph cfg, int registersCount)
{ {
_operationNodes = new List<(IntrusiveList<Operation>, Operation)>(); _operationNodes = [];
_intervals = new List<LiveInterval>(); _intervals = [];
for (int index = 0; index < registersCount; index++) for (int index = 0; index < registersCount; index++)
{ {
@@ -839,7 +839,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
dest.NumberLocal(_intervals.Count); dest.NumberLocal(_intervals.Count);
LiveInterval interval = new LiveInterval(dest); LiveInterval interval = new(dest);
_intervals.Add(interval); _intervals.Add(interval);
SetVisited(dest); SetVisited(dest);
@@ -980,7 +980,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
_blockLiveIn = blkLiveIn; _blockLiveIn = blkLiveIn;
_blockEdges = new HashSet<int>(); _blockEdges = [];
// Compute lifetime intervals. // Compute lifetime intervals.
int operationPos = _operationsCount; int operationPos = _operationsCount;

View File

@@ -15,12 +15,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
if (_count + 1 > _capacity) if (_count + 1 > _capacity)
{ {
var oldSpan = Span; Span<LiveInterval> oldSpan = Span;
_capacity = Math.Max(4, _capacity * 2); _capacity = Math.Max(4, _capacity * 2);
_items = Allocators.References.Allocate<LiveInterval>((uint)_capacity); _items = Allocators.References.Allocate<LiveInterval>((uint)_capacity);
var newSpan = Span; Span<LiveInterval> newSpan = Span;
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
} }

View File

@@ -16,12 +16,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{ {
if (Count + 1 > _capacity) if (Count + 1 > _capacity)
{ {
var oldSpan = Span; Span<int> oldSpan = Span;
_capacity = Math.Max(4, _capacity * 2); _capacity = Math.Max(4, _capacity * 2);
_items = Allocators.Default.Allocate<int>((uint)_capacity); _items = Allocators.Default.Allocate<int>((uint)_capacity);
var newSpan = Span; Span<int> newSpan = Span;
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
} }

View File

@@ -1,5 +1,6 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
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;
@@ -74,9 +75,9 @@ namespace ARMeilleure.CodeGen.X86
{ {
_stream = stream; _stream = stream;
_labels = new Dictionary<Operand, long>(); _labels = new Dictionary<Operand, long>();
_jumps = new List<Jump>(); _jumps = [];
_relocs = relocatable ? new List<Reloc>() : null; _relocs = relocatable ? [] : null;
} }
public void MarkLabel(Operand label) public void MarkLabel(Operand label)
@@ -1324,8 +1325,8 @@ namespace ARMeilleure.CodeGen.X86
public (byte[], RelocInfo) GetCode() public (byte[], RelocInfo) GetCode()
{ {
var jumps = CollectionsMarshal.AsSpan(_jumps); Span<Jump> jumps = CollectionsMarshal.AsSpan(_jumps);
var relocs = CollectionsMarshal.AsSpan(_relocs); Span<Reloc> relocs = CollectionsMarshal.AsSpan(_relocs);
// Write jump relative offsets. // Write jump relative offsets.
bool modified; bool modified;
@@ -1410,15 +1411,15 @@ namespace ARMeilleure.CodeGen.X86
// Write the code, ignoring the dummy bytes after jumps, into a new stream. // Write the code, ignoring the dummy bytes after jumps, into a new stream.
_stream.Seek(0, SeekOrigin.Begin); _stream.Seek(0, SeekOrigin.Begin);
using var codeStream = MemoryStreamManager.Shared.GetStream(); using RecyclableMemoryStream codeStream = MemoryStreamManager.Shared.GetStream();
var assembler = new Assembler(codeStream, HasRelocs); Assembler assembler = new(codeStream, HasRelocs);
bool hasRelocs = HasRelocs; bool hasRelocs = HasRelocs;
int relocIndex = 0; int relocIndex = 0;
int relocOffset = 0; int relocOffset = 0;
var relocEntries = hasRelocs RelocEntry[] relocEntries = hasRelocs
? new RelocEntry[relocs.Length] ? new RelocEntry[relocs.Length]
: Array.Empty<RelocEntry>(); : [];
for (int i = 0; i < jumps.Length; i++) for (int i = 0; i < jumps.Length; i++)
{ {
@@ -1469,8 +1470,8 @@ namespace ARMeilleure.CodeGen.X86
_stream.CopyTo(codeStream); _stream.CopyTo(codeStream);
var code = codeStream.ToArray(); byte[] code = codeStream.ToArray();
var relocInfo = new RelocInfo(relocEntries); RelocInfo relocInfo = new(relocEntries);
return (code, relocInfo); return (code, relocInfo);
} }

View File

@@ -623,7 +623,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var cond = ((Comparison)comp.AsInt32()).ToX86Condition(); X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -661,7 +661,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(dest.Type == OperandType.I32); Debug.Assert(dest.Type == OperandType.I32);
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var cond = ((Comparison)comp.AsInt32()).ToX86Condition(); X86Condition cond = ((Comparison)comp.AsInt32()).ToX86Condition();
GenerateCompareCommon(context, operation); GenerateCompareCommon(context, operation);
@@ -1748,7 +1748,7 @@ namespace ARMeilleure.CodeGen.X86
private static UnwindInfo WritePrologue(CodeGenContext context) private static UnwindInfo WritePrologue(CodeGenContext context)
{ {
List<UnwindPushEntry> pushEntries = new(); List<UnwindPushEntry> pushEntries = [];
Operand rsp = Register(X86Register.Rsp); Operand rsp = Register(X86Register.Rsp);

View File

@@ -40,12 +40,12 @@ namespace ARMeilleure.CodeGen.X86
return 0; return 0;
} }
ReadOnlySpan<byte> asmGetXcr0 = new byte[] ReadOnlySpan<byte> asmGetXcr0 =
{ [
0x31, 0xc9, // xor ecx, ecx 0x31, 0xc9, // xor ecx, ecx
0xf, 0x01, 0xd0, // xgetbv 0xf, 0x01, 0xd0, // xgetbv
0xc3, // ret 0xc3 // ret
}; ];
using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length); using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);
@@ -53,7 +53,7 @@ namespace ARMeilleure.CodeGen.X86
memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute); memGetXcr0.Reprotect(0, (ulong)asmGetXcr0.Length, MemoryPermission.ReadAndExecute);
var fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer); GetXcr0 fGetXcr0 = Marshal.GetDelegateForFunctionPointer<GetXcr0>(memGetXcr0.Pointer);
return fGetXcr0(); return fGetXcr0();
} }

View File

@@ -124,13 +124,13 @@ namespace ARMeilleure.CodeGen.X86
{ {
int stackOffset = stackAlloc.Allocate(OperandType.I32); int stackOffset = stackAlloc.Allocate(OperandType.I32);
node.SetSources(new Operand[] { Const(stackOffset), node.GetSource(0) }); node.SetSources([Const(stackOffset), node.GetSource(0)]);
} }
else if (node.Intrinsic == Intrinsic.X86Stmxcsr) else if (node.Intrinsic == Intrinsic.X86Stmxcsr)
{ {
int stackOffset = stackAlloc.Allocate(OperandType.I32); int stackOffset = stackAlloc.Allocate(OperandType.I32);
node.SetSources(new Operand[] { Const(stackOffset) }); node.SetSources([Const(stackOffset)]);
} }
break; break;
} }
@@ -253,8 +253,8 @@ namespace ARMeilleure.CodeGen.X86
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
operation.SetDestinations(new Operand[] { rdx, rax }); operation.SetDestinations([rdx, rax]);
operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx }); operation.SetSources([operation.GetSource(0), rdx, rax, rcx, rbx]);
} }
else else
{ {
@@ -274,7 +274,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue)); nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
node.SetSources(new Operand[] { node.GetSource(0), rax, temp }); node.SetSources([node.GetSource(0), rax, temp]);
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
@@ -303,7 +303,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
node.SetSources(new Operand[] { rdx, rax, node.GetSource(1) }); node.SetSources([rdx, rax, node.GetSource(1)]);
node.Destination = rax; node.Destination = rax;
} }
@@ -348,7 +348,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
node.SetDestinations(new Operand[] { rdx, rax }); node.SetDestinations([rdx, rax]);
break; break;
} }
@@ -759,7 +759,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(comp.Kind == OperandKind.Constant); Debug.Assert(comp.Kind == OperandKind.Constant);
var compType = (Comparison)comp.AsInt32(); Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual; return compType == Comparison.Equal || compType == Comparison.NotEqual;
} }

View File

@@ -14,10 +14,10 @@ namespace ARMeilleure.CodeGen.X86
{ {
Operand dest = node.Destination; Operand dest = node.Destination;
List<Operand> sources = new() List<Operand> sources =
{ [
node.GetSource(0), node.GetSource(0)
}; ];
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;
@@ -117,10 +117,10 @@ namespace ARMeilleure.CodeGen.X86
public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node) public static void InsertTailcallCopies(IntrusiveList<Operation> nodes, Operation node)
{ {
List<Operand> sources = new() List<Operand> sources =
{ [
node.GetSource(0), node.GetSource(0)
}; ];
int argsCount = node.SourcesCount - 1; int argsCount = node.SourcesCount - 1;

View File

@@ -321,7 +321,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddBefore(node, retCopyOp); nodes.AddBefore(node, retCopyOp);
} }
node.SetSources(Array.Empty<Operand>()); node.SetSources([]);
} }
} }
} }

View File

@@ -13,13 +13,13 @@ namespace ARMeilleure.CodeGen.X86
public static void RunPass(ControlFlowGraph cfg) public static void RunPass(ControlFlowGraph cfg)
{ {
var constants = new Dictionary<ulong, Operand>(); Dictionary<ulong, Operand> constants = new();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{ {
// If the constant has many uses, we also force a new constant mov to be added, in order // If the constant has many uses, we also force a new constant mov to be added, in order
// to avoid overflow of the counts field (that is limited to 16 bits). // to avoid overflow of the counts field (that is limited to 16 bits).
if (!constants.TryGetValue(source.Value, out var constant) || constant.UsesCount > MaxConstantUses) if (!constants.TryGetValue(source.Value, out Operand constant) || constant.UsesCount > MaxConstantUses)
{ {
constant = Local(source.Type); constant = Local(source.Type);

View File

@@ -3,52 +3,46 @@ namespace ARMeilleure.Common
public static class AddressTablePresets public static class AddressTablePresets
{ {
private static readonly AddressTableLevel[] _levels64Bit = private static readonly AddressTableLevel[] _levels64Bit =
new AddressTableLevel[] [
{ new(31, 17),
new(31, 17),
new(23, 8), new(23, 8),
new(15, 8), new(15, 8),
new( 7, 8), new( 7, 8),
new( 2, 5), new( 2, 5)
}; ];
private static readonly AddressTableLevel[] _levels32Bit = private static readonly AddressTableLevel[] _levels32Bit =
new AddressTableLevel[] [
{ new(31, 17),
new(31, 17),
new(23, 8), new(23, 8),
new(15, 8), new(15, 8),
new( 7, 8), new( 7, 8),
new( 1, 6), new( 1, 6)
}; ];
private static readonly AddressTableLevel[] _levels64BitSparseTiny = private static readonly AddressTableLevel[] _levels64BitSparseTiny =
new AddressTableLevel[] [
{ new( 11, 28),
new( 11, 28), new( 2, 9)
new( 2, 9), ];
};
private static readonly AddressTableLevel[] _levels32BitSparseTiny = private static readonly AddressTableLevel[] _levels32BitSparseTiny =
new AddressTableLevel[] [
{ new( 10, 22),
new( 10, 22), new( 1, 9)
new( 1, 9), ];
};
private static readonly AddressTableLevel[] _levels64BitSparseGiant = private static readonly AddressTableLevel[] _levels64BitSparseGiant =
new AddressTableLevel[] [
{ new( 38, 1),
new( 38, 1), new( 2, 36)
new( 2, 36), ];
};
private static readonly AddressTableLevel[] _levels32BitSparseGiant = private static readonly AddressTableLevel[] _levels32BitSparseGiant =
new AddressTableLevel[] [
{ new( 31, 1),
new( 31, 1), new( 1, 30)
new( 1, 30), ];
};
//high power will run worse on DDR3 systems and some DDR4 systems due to the higher ram utilization //high power will run worse on DDR3 systems and some DDR4 systems due to the higher ram utilization
//low power will never run worse than non-sparse, but for most systems it won't be necessary //low power will never run worse than non-sparse, but for most systems it won't be necessary

View File

@@ -129,13 +129,13 @@ namespace ARMeilleure.Common
if (count > _count) if (count > _count)
{ {
var oldMask = _masks; long* oldMask = _masks;
var oldSpan = new Span<long>(_masks, _count); Span<long> oldSpan = new(_masks, _count);
_masks = _allocator.Allocate<long>((uint)count); _masks = _allocator.Allocate<long>((uint)count);
_count = count; _count = count;
var newSpan = new Span<long>(_masks, _count); Span<long> newSpan = new(_masks, _count);
oldSpan.CopyTo(newSpan); oldSpan.CopyTo(newSpan);
newSpan[oldSpan.Length..].Clear(); newSpan[oldSpan.Length..].Clear();

View File

@@ -5,7 +5,7 @@ namespace ARMeilleure.Common
{ {
static class BitUtils static class BitUtils
{ {
private static ReadOnlySpan<sbyte> HbsNibbleLut => new sbyte[] { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 }; private static ReadOnlySpan<sbyte> HbsNibbleLut => [-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3];
public static long FillWithOnes(int bits) public static long FillWithOnes(int bits)
{ {

View File

@@ -63,7 +63,7 @@ namespace ARMeilleure.Common
} }
int index = _freeHint++; int index = _freeHint++;
var page = GetPage(index); Span<TEntry> page = GetPage(index);
_allocated.Set(index); _allocated.Set(index);
@@ -111,7 +111,7 @@ namespace ARMeilleure.Common
throw new ArgumentException("Entry at the specified index was not allocated", nameof(index)); throw new ArgumentException("Entry at the specified index was not allocated", nameof(index));
} }
var page = GetPage(index); Span<TEntry> page = GetPage(index);
return ref GetValue(page, index); return ref GetValue(page, index);
} }
@@ -136,7 +136,7 @@ namespace ARMeilleure.Common
/// <returns>Page for the specified <see cref="index"/></returns> /// <returns>Page for the specified <see cref="index"/></returns>
private unsafe Span<TEntry> GetPage(int index) private unsafe Span<TEntry> GetPage(int index)
{ {
var pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity); int pageIndex = (int)((uint)(index & ~(_pageCapacity - 1)) >> _pageLogCapacity);
if (!_pages.TryGetValue(pageIndex, out nint page)) if (!_pages.TryGetValue(pageIndex, out nint page))
{ {
@@ -168,7 +168,7 @@ namespace ARMeilleure.Common
{ {
_allocated.Dispose(); _allocated.Dispose();
foreach (var page in _pages.Values) foreach (IntPtr page in _pages.Values)
{ {
NativeAllocator.Instance.Free((void*)page); NativeAllocator.Instance.Free((void*)page);
} }

View File

@@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders
public Block() public Block()
{ {
OpCodes = new List<OpCode>(); OpCodes = [];
} }
public Block(ulong address) : this() public Block(ulong address) : this()

View File

@@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode) public static Block[] Decode(IMemoryManager memory, ulong address, ExecutionMode mode, bool highCq, DecoderMode dMode)
{ {
List<Block> blocks = new(); List<Block> blocks = [];
Queue<Block> workQueue = new(); Queue<Block> workQueue = new();

View File

@@ -9,7 +9,7 @@ namespace ARMeilleure.Decoders
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb) public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
{ {
var opc = (opCode >> 16) & 0xf; int opc = (opCode >> 16) & 0xf;
if ((opc & 0b1) == 1) if ((opc & 0b1) == 1)
{ {

View File

@@ -5,12 +5,12 @@ namespace ARMeilleure.Decoders
class OpCode32SimdMemPair : OpCode32, IOpCode32Simd class OpCode32SimdMemPair : OpCode32, IOpCode32Simd
{ {
private static readonly int[] _regsMap = private static readonly int[] _regsMap =
{ [
1, 1, 4, 2, 1, 1, 4, 2,
1, 1, 3, 1, 1, 1, 3, 1,
1, 1, 2, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1
}; ];
public int Vd { get; } public int Vd { get; }
public int Rn { get; } public int Rn { get; }

View File

@@ -21,7 +21,7 @@ namespace ARMeilleure.Decoders
Op = (opCode >> 20) & 0x1; Op = (opCode >> 20) & 0x1;
U = ((opCode >> 23) & 1) != 0; U = ((opCode >> 23) & 1) != 0;
var opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3); int opc = (((opCode >> 23) & 1) << 4) | (((opCode >> 21) & 0x3) << 2) | ((opCode >> 5) & 0x3);
if ((opc & 0b01000) == 0b01000) if ((opc & 0b01000) == 0b01000)
{ {

View File

@@ -20,7 +20,7 @@ namespace ARMeilleure.Decoders
} }
else if (DataOp == DataOp.Logical) else if (DataOp == DataOp.Logical)
{ {
var bm = DecoderHelper.DecodeBitMask(opCode, true); DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, true);
if (bm.IsUndefined) if (bm.IsUndefined)
{ {

View File

@@ -11,7 +11,7 @@ namespace ARMeilleure.Decoders
public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCodeBfm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
var bm = DecoderHelper.DecodeBitMask(opCode, false); DecoderHelper.BitMask bm = DecoderHelper.DecodeBitMask(opCode, false);
if (bm.IsUndefined) if (bm.IsUndefined)
{ {

View File

@@ -12,7 +12,7 @@ namespace ARMeilleure.Decoders
public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
List<Condition> conds = new(); List<Condition> conds = [];
int cond = (opCode >> 4) & 0xf; int cond = (opCode >> 4) & 0xf;
int mask = opCode & 0xf; int mask = opCode & 0xf;

View File

@@ -29,9 +29,9 @@ namespace ARMeilleure.Decoders
} }
} }
private static readonly List<InstInfo> _allInstA32 = new(); private static readonly List<InstInfo> _allInstA32 = [];
private static readonly List<InstInfo> _allInstT32 = new(); private static readonly List<InstInfo> _allInstT32 = [];
private static readonly List<InstInfo> _allInstA64 = new(); private static readonly List<InstInfo> _allInstA64 = [];
private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][]; private static readonly InstInfo[][] _instA32FastLookup = new InstInfo[FastLookupSize][];
private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][]; private static readonly InstInfo[][] _instT32FastLookup = new InstInfo[FastLookupSize][];
@@ -1330,7 +1330,7 @@ namespace ARMeilleure.Decoders
for (int index = 0; index < temp.Length; index++) for (int index = 0; index < temp.Length; index++)
{ {
temp[index] = new List<InstInfo>(); temp[index] = [];
} }
foreach (InstInfo inst in allInsts) foreach (InstInfo inst in allInsts)

View File

@@ -69,7 +69,7 @@ namespace ARMeilleure.Decoders.Optimizations
} }
} }
var newBlocks = new List<Block>(blocks.Count); List<Block> newBlocks = new(blocks.Count);
// Finally, rebuild decoded block list, ignoring blocks outside the contiguous range. // Finally, rebuild decoded block list, ignoring blocks outside the contiguous range.
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < blocks.Count; i++)

View File

@@ -141,7 +141,7 @@ namespace ARMeilleure.Diagnostics
break; break;
case OperandKind.Memory: case OperandKind.Memory:
var memOp = operand.GetMemory(); MemoryOperand memOp = operand.GetMemory();
_builder.Append('['); _builder.Append('[');
@@ -285,7 +285,7 @@ namespace ARMeilleure.Diagnostics
public static string GetDump(ControlFlowGraph cfg) public static string GetDump(ControlFlowGraph cfg)
{ {
var dumper = new IRDumper(1); IRDumper dumper = new(1);
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {

View File

@@ -29,7 +29,7 @@ namespace ARMeilleure.Diagnostics
static Symbols() static Symbols()
{ {
_symbols = new ConcurrentDictionary<ulong, string>(); _symbols = new ConcurrentDictionary<ulong, string>();
_rangedSymbols = new List<RangedSymbol>(); _rangedSymbols = [];
} }
public static string Get(ulong address) public static string Get(ulong address)

View File

@@ -9,8 +9,8 @@ namespace ARMeilleure.Instructions
{ {
#region "LookUp Tables" #region "LookUp Tables"
#pragma warning disable IDE1006 // Naming rule violation #pragma warning disable IDE1006 // Naming rule violation
private static ReadOnlySpan<byte> _sBox => new byte[] private static ReadOnlySpan<byte> _sBox =>
{ [
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
@@ -26,11 +26,11 @@ namespace ARMeilleure.Instructions
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
}; ];
private static ReadOnlySpan<byte> _invSBox => new byte[] private static ReadOnlySpan<byte> _invSBox =>
{ [
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
@@ -46,11 +46,11 @@ namespace ARMeilleure.Instructions
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
}; ];
private static ReadOnlySpan<byte> _gfMul02 => new byte[] private static ReadOnlySpan<byte> _gfMul02 =>
{ [
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
@@ -66,11 +66,11 @@ namespace ARMeilleure.Instructions
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
}; ];
private static ReadOnlySpan<byte> _gfMul03 => new byte[] private static ReadOnlySpan<byte> _gfMul03 =>
{ [
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
@@ -86,11 +86,11 @@ namespace ARMeilleure.Instructions
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
}; ];
private static ReadOnlySpan<byte> _gfMul09 => new byte[] private static ReadOnlySpan<byte> _gfMul09 =>
{ [
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
@@ -106,11 +106,11 @@ namespace ARMeilleure.Instructions
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
}; ];
private static ReadOnlySpan<byte> _gfMul0B => new byte[] private static ReadOnlySpan<byte> _gfMul0B =>
{ [
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
@@ -126,11 +126,11 @@ namespace ARMeilleure.Instructions
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
}; ];
private static ReadOnlySpan<byte> _gfMul0D => new byte[] private static ReadOnlySpan<byte> _gfMul0D =>
{ [
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
@@ -146,11 +146,11 @@ namespace ARMeilleure.Instructions
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
}; ];
private static ReadOnlySpan<byte> _gfMul0E => new byte[] private static ReadOnlySpan<byte> _gfMul0E =>
{ [
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
@@ -166,18 +166,18 @@ namespace ARMeilleure.Instructions
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
}; ];
private static ReadOnlySpan<byte> _srPerm => new byte[] private static ReadOnlySpan<byte> _srPerm =>
{ [
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
}; ];
private static ReadOnlySpan<byte> _isrPerm => new byte[] private static ReadOnlySpan<byte> _isrPerm =>
{ [
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
}; ];
#pragma warning restore IDE1006 #pragma warning restore IDE1006
#endregion #endregion

View File

@@ -415,7 +415,7 @@ namespace ARMeilleure.Instructions
{ {
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
Operand n = GetIntA32(context, op.Rn); Operand n = GetIntA32(context, op.Rn);
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
@@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions
{ {
IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp;
var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. int msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width.
Operand n = GetIntA32(context, op.Rn); Operand n = GetIntA32(context, op.Rn);
Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));

View File

@@ -1,4 +1,5 @@
using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Linking;
using ARMeilleure.Common;
using ARMeilleure.Decoders; using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation; using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State; using ARMeilleure.State;
@@ -193,7 +194,7 @@ namespace ARMeilleure.Instructions
Operand hostAddress; Operand hostAddress;
var table = context.FunctionTable; IAddressTable<ulong> table = context.FunctionTable;
// If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback // If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback
// onto the dispatch stub. // onto the dispatch stub.
@@ -218,7 +219,7 @@ namespace ARMeilleure.Instructions
for (int i = 0; i < table.Levels.Length; i++) for (int i = 0; i < table.Levels.Length; i++)
{ {
var level = table.Levels[i]; AddressTableLevel level = table.Levels[i];
int clearBits = 64 - (level.Index + level.Length); int clearBits = 64 - (level.Index + level.Length);
Operand index = context.ShiftLeft( Operand index = context.ShiftLeft(

View File

@@ -143,8 +143,8 @@ namespace ARMeilleure.Instructions
Operand address = context.Copy(GetIntA32(context, op.Rn)); Operand address = context.Copy(GetIntA32(context, op.Rn));
var exclusive = (accType & AccessType.Exclusive) != 0; bool exclusive = (accType & AccessType.Exclusive) != 0;
var ordered = (accType & AccessType.Ordered) != 0; bool ordered = (accType & AccessType.Ordered) != 0;
if ((accType & AccessType.Load) != 0) if ((accType & AccessType.Load) != 0)
{ {

View File

@@ -229,7 +229,7 @@ namespace ARMeilleure.Instructions
private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType) private static Operand ZerosOrOnes(ArmEmitterContext context, Operand fromBool, OperandType baseType)
{ {
var ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1); Operand ones = (baseType == OperandType.I64) ? Const(-1L) : Const(-1);
return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L)); return context.ConditionalSelect(fromBool, ones, Const(baseType, 0L));
} }

View File

@@ -118,15 +118,15 @@ namespace ARMeilleure.Instructions
{ {
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp; OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
var toFixed = op.Opc == 1; bool toFixed = op.Opc == 1;
int fracBits = op.Fbits; int fracBits = op.Fbits;
var unsigned = op.U; bool unsigned = op.U;
if (toFixed) // F32 to S32 or U32 (fixed) if (toFixed) // F32 to S32 or U32 (fixed)
{ {
EmitVectorUnaryOpF32(context, (op1) => EmitVectorUnaryOpF32(context, (op1) =>
{ {
var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits))); Operand scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)); MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
return context.Call(info, scaledValue); return context.Call(info, scaledValue);
@@ -136,7 +136,7 @@ namespace ARMeilleure.Instructions
{ {
EmitVectorUnaryOpI32(context, (op1) => EmitVectorUnaryOpI32(context, (op1) =>
{ {
var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1); Operand floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits))); return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
}, !unsigned); }, !unsigned);
@@ -245,8 +245,8 @@ namespace ARMeilleure.Instructions
string name = nameof(Math.Round); string name = nameof(Math.Round);
MethodInfo info = (op.Size & 1) == 0 MethodInfo info = (op.Size & 1) == 0
? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) }) ? typeof(MathF).GetMethod(name, [typeof(float), typeof(MidpointRounding)])
: typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) }); : typeof(Math).GetMethod(name, [typeof(double), typeof(MidpointRounding)]);
return context.Call(info, n, Const((int)roundMode)); return context.Call(info, n, Const((int)roundMode));
} }

View File

@@ -18,19 +18,19 @@ namespace ARMeilleure.Instructions
static class InstEmitSimdHelper static class InstEmitSimdHelper
{ {
#region "Masks" #region "Masks"
public static readonly long[] EvenMasks = new long[] public static readonly long[] EvenMasks =
{ [
14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0, // B 14L << 56 | 12L << 48 | 10L << 40 | 08L << 32 | 06L << 24 | 04L << 16 | 02L << 8 | 00L << 0, // B
13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, // H 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, // H
11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0, // S 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0 // S
}; ];
public static readonly long[] OddMasks = new long[] public static readonly long[] OddMasks =
{ [
15L << 56 | 13L << 48 | 11L << 40 | 09L << 32 | 07L << 24 | 05L << 16 | 03L << 8 | 01L << 0, // B 15L << 56 | 13L << 48 | 11L << 40 | 09L << 32 | 07L << 24 | 05L << 16 | 03L << 8 | 01L << 0, // B
15L << 56 | 14L << 48 | 11L << 40 | 10L << 32 | 07L << 24 | 06L << 16 | 03L << 8 | 02L << 0, // H 15L << 56 | 14L << 48 | 11L << 40 | 10L << 32 | 07L << 24 | 06L << 16 | 03L << 8 | 02L << 0, // H
15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0, // S 15L << 56 | 14L << 48 | 13L << 40 | 12L << 32 | 07L << 24 | 06L << 16 | 05L << 8 | 04L << 0 // S
}; ];
public const long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0; public const long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0;
@@ -44,118 +44,118 @@ namespace ARMeilleure.Instructions
#endregion #endregion
#region "X86 SSE Intrinsics" #region "X86 SSE Intrinsics"
public static readonly Intrinsic[] X86PaddInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PaddInstruction =
{ [
Intrinsic.X86Paddb, Intrinsic.X86Paddb,
Intrinsic.X86Paddw, Intrinsic.X86Paddw,
Intrinsic.X86Paddd, Intrinsic.X86Paddd,
Intrinsic.X86Paddq, Intrinsic.X86Paddq
}; ];
public static readonly Intrinsic[] X86PcmpeqInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PcmpeqInstruction =
{ [
Intrinsic.X86Pcmpeqb, Intrinsic.X86Pcmpeqb,
Intrinsic.X86Pcmpeqw, Intrinsic.X86Pcmpeqw,
Intrinsic.X86Pcmpeqd, Intrinsic.X86Pcmpeqd,
Intrinsic.X86Pcmpeqq, Intrinsic.X86Pcmpeqq
}; ];
public static readonly Intrinsic[] X86PcmpgtInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PcmpgtInstruction =
{ [
Intrinsic.X86Pcmpgtb, Intrinsic.X86Pcmpgtb,
Intrinsic.X86Pcmpgtw, Intrinsic.X86Pcmpgtw,
Intrinsic.X86Pcmpgtd, Intrinsic.X86Pcmpgtd,
Intrinsic.X86Pcmpgtq, Intrinsic.X86Pcmpgtq
}; ];
public static readonly Intrinsic[] X86PmaxsInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PmaxsInstruction =
{ [
Intrinsic.X86Pmaxsb, Intrinsic.X86Pmaxsb,
Intrinsic.X86Pmaxsw, Intrinsic.X86Pmaxsw,
Intrinsic.X86Pmaxsd, Intrinsic.X86Pmaxsd
}; ];
public static readonly Intrinsic[] X86PmaxuInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PmaxuInstruction =
{ [
Intrinsic.X86Pmaxub, Intrinsic.X86Pmaxub,
Intrinsic.X86Pmaxuw, Intrinsic.X86Pmaxuw,
Intrinsic.X86Pmaxud, Intrinsic.X86Pmaxud
}; ];
public static readonly Intrinsic[] X86PminsInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PminsInstruction =
{ [
Intrinsic.X86Pminsb, Intrinsic.X86Pminsb,
Intrinsic.X86Pminsw, Intrinsic.X86Pminsw,
Intrinsic.X86Pminsd, Intrinsic.X86Pminsd
}; ];
public static readonly Intrinsic[] X86PminuInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PminuInstruction =
{ [
Intrinsic.X86Pminub, Intrinsic.X86Pminub,
Intrinsic.X86Pminuw, Intrinsic.X86Pminuw,
Intrinsic.X86Pminud, Intrinsic.X86Pminud
}; ];
public static readonly Intrinsic[] X86PmovsxInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PmovsxInstruction =
{ [
Intrinsic.X86Pmovsxbw, Intrinsic.X86Pmovsxbw,
Intrinsic.X86Pmovsxwd, Intrinsic.X86Pmovsxwd,
Intrinsic.X86Pmovsxdq, Intrinsic.X86Pmovsxdq
}; ];
public static readonly Intrinsic[] X86PmovzxInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PmovzxInstruction =
{ [
Intrinsic.X86Pmovzxbw, Intrinsic.X86Pmovzxbw,
Intrinsic.X86Pmovzxwd, Intrinsic.X86Pmovzxwd,
Intrinsic.X86Pmovzxdq, Intrinsic.X86Pmovzxdq
}; ];
public static readonly Intrinsic[] X86PsllInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PsllInstruction =
{ [
0, 0,
Intrinsic.X86Psllw, Intrinsic.X86Psllw,
Intrinsic.X86Pslld, Intrinsic.X86Pslld,
Intrinsic.X86Psllq, Intrinsic.X86Psllq
}; ];
public static readonly Intrinsic[] X86PsraInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PsraInstruction =
{ [
0, 0,
Intrinsic.X86Psraw, Intrinsic.X86Psraw,
Intrinsic.X86Psrad, Intrinsic.X86Psrad
}; ];
public static readonly Intrinsic[] X86PsrlInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PsrlInstruction =
{ [
0, 0,
Intrinsic.X86Psrlw, Intrinsic.X86Psrlw,
Intrinsic.X86Psrld, Intrinsic.X86Psrld,
Intrinsic.X86Psrlq, Intrinsic.X86Psrlq
}; ];
public static readonly Intrinsic[] X86PsubInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PsubInstruction =
{ [
Intrinsic.X86Psubb, Intrinsic.X86Psubb,
Intrinsic.X86Psubw, Intrinsic.X86Psubw,
Intrinsic.X86Psubd, Intrinsic.X86Psubd,
Intrinsic.X86Psubq, Intrinsic.X86Psubq
}; ];
public static readonly Intrinsic[] X86PunpckhInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PunpckhInstruction =
{ [
Intrinsic.X86Punpckhbw, Intrinsic.X86Punpckhbw,
Intrinsic.X86Punpckhwd, Intrinsic.X86Punpckhwd,
Intrinsic.X86Punpckhdq, Intrinsic.X86Punpckhdq,
Intrinsic.X86Punpckhqdq, Intrinsic.X86Punpckhqdq
}; ];
public static readonly Intrinsic[] X86PunpcklInstruction = new Intrinsic[] public static readonly Intrinsic[] X86PunpcklInstruction =
{ [
Intrinsic.X86Punpcklbw, Intrinsic.X86Punpcklbw,
Intrinsic.X86Punpcklwd, Intrinsic.X86Punpcklwd,
Intrinsic.X86Punpckldq, Intrinsic.X86Punpckldq,
Intrinsic.X86Punpcklqdq, Intrinsic.X86Punpcklqdq
}; ];
#endregion #endregion
public static void EnterArmFpMode(EmitterContext context, Func<FPState, Operand> getFpFlag) public static void EnterArmFpMode(EmitterContext context, Func<FPState, Operand> getFpFlag)
@@ -460,8 +460,8 @@ namespace ARMeilleure.Instructions
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
MethodInfo info = (op.Size & 1) == 0 MethodInfo info = (op.Size & 1) == 0
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float) }) ? typeof(MathHelperF).GetMethod(name, [typeof(float)])
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double) }); : typeof(MathHelper).GetMethod(name, [typeof(double)]);
return context.Call(info, n); return context.Call(info, n);
} }
@@ -473,8 +473,8 @@ namespace ARMeilleure.Instructions
string name = nameof(MathHelper.Round); string name = nameof(MathHelper.Round);
MethodInfo info = (op.Size & 1) == 0 MethodInfo info = (op.Size & 1) == 0
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float), typeof(int) }) ? typeof(MathHelperF).GetMethod(name, [typeof(float), typeof(int)])
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double), typeof(int) }); : typeof(MathHelper).GetMethod(name, [typeof(double), typeof(int)]);
return context.Call(info, n, Const((int)roundMode)); return context.Call(info, n, Const((int)roundMode));
} }

View File

@@ -87,7 +87,7 @@ namespace ARMeilleure.Instructions
{ {
if (op.Replicate) if (op.Replicate)
{ {
var regs = (count > 1) ? 1 : op.Increment; int regs = (count > 1) ? 1 : op.Increment;
for (int reg = 0; reg < regs; reg++) for (int reg = 0; reg < regs; reg++)
{ {
int dreg = reg + d; int dreg = reg + d;

View File

@@ -12,17 +12,17 @@ namespace ARMeilleure.Instructions
static partial class InstEmit static partial class InstEmit
{ {
#region "Masks" #region "Masks"
private static readonly long[] _masksE0_Uzp = new long[] private static readonly long[] _masksE0_Uzp =
{ [
13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0, 13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0,
11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0, 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0
}; ];
private static readonly long[] _masksE1_Uzp = new long[] private static readonly long[] _masksE1_Uzp =
{ [
15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0, 15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0,
15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0, 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0
}; ];
#endregion #endregion
public static void Dup_Gp(ArmEmitterContext context) public static void Dup_Gp(ArmEmitterContext context)
@@ -601,7 +601,7 @@ namespace ARMeilleure.Instructions
{ {
Operand d = GetVec(op.Rd); Operand d = GetVec(op.Rd);
List<Operand> args = new(); List<Operand> args = [];
if (!isTbl) if (!isTbl)
{ {

View File

@@ -13,17 +13,17 @@ namespace ARMeilleure.Instructions
{ {
#region "Masks" #region "Masks"
// Same as InstEmitSimdMove, as the instructions do the same thing. // Same as InstEmitSimdMove, as the instructions do the same thing.
private static readonly long[] _masksE0_Uzp = new long[] private static readonly long[] _masksE0_Uzp =
{ [
13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0, 13L << 56 | 09L << 48 | 05L << 40 | 01L << 32 | 12L << 24 | 08L << 16 | 04L << 8 | 00L << 0,
11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0, 11L << 56 | 10L << 48 | 03L << 40 | 02L << 32 | 09L << 24 | 08L << 16 | 01L << 8 | 00L << 0
}; ];
private static readonly long[] _masksE1_Uzp = new long[] private static readonly long[] _masksE1_Uzp =
{ [
15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0, 15L << 56 | 11L << 48 | 07L << 40 | 03L << 32 | 14L << 24 | 10L << 16 | 06L << 8 | 02L << 0,
15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0, 15L << 56 | 14L << 48 | 07L << 40 | 06L << 32 | 13L << 24 | 12L << 16 | 05L << 8 | 04L << 0
}; ];
#endregion #endregion
public static void Vmov_I(ArmEmitterContext context) public static void Vmov_I(ArmEmitterContext context)

View File

@@ -17,10 +17,10 @@ namespace ARMeilleure.Instructions
static partial class InstEmit static partial class InstEmit
{ {
#region "Masks" #region "Masks"
private static readonly long[] _masks_SliSri = new long[] // Replication masks. private static readonly long[] _masks_SliSri =
{ [
0x0101010101010101L, 0x0001000100010001L, 0x0000000100000001L, 0x0000000000000001L, 0x0101010101010101L, 0x0001000100010001L, 0x0000000100000001L, 0x0000000000000001L
}; ];
#endregion #endregion
public static void Rshrn_V(ArmEmitterContext context) public static void Rshrn_V(ArmEmitterContext context)

View File

@@ -211,7 +211,7 @@ namespace ARMeilleure.Instructions
return (ulong)(size - 1); return (ulong)(size - 1);
} }
private static ReadOnlySpan<byte> ClzNibbleTbl => new byte[] { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; private static ReadOnlySpan<byte> ClzNibbleTbl => [4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0];
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.). public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).

View File

@@ -1538,7 +1538,7 @@ namespace ARMeilleure.Instructions
} }
else if (MathF.Abs(value) < MathF.Pow(2f, -128)) else if (MathF.Abs(value) < MathF.Pow(2f, -128))
{ {
var overflowToInf = fpcr.GetRoundingMode() switch bool overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true, FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,
@@ -3073,7 +3073,7 @@ namespace ARMeilleure.Instructions
} }
else if (Math.Abs(value) < Math.Pow(2d, -1024)) else if (Math.Abs(value) < Math.Pow(2d, -1024))
{ {
var overflowToInf = fpcr.GetRoundingMode() switch bool overflowToInf = fpcr.GetRoundingMode() switch
{ {
FPRoundingMode.ToNearest => true, FPRoundingMode.ToNearest => true,
FPRoundingMode.TowardsPlusInfinity => !sign, FPRoundingMode.TowardsPlusInfinity => !sign,

View File

@@ -27,7 +27,7 @@ namespace ARMeilleure.IntermediateRepresentation
{ {
get get
{ {
_domFrontiers ??= new HashSet<BasicBlock>(); _domFrontiers ??= [];
return _domFrontiers; return _domFrontiers;
} }
@@ -38,7 +38,7 @@ namespace ARMeilleure.IntermediateRepresentation
public BasicBlock(int index) public BasicBlock(int index)
{ {
Operations = new IntrusiveList<Operation>(); Operations = new IntrusiveList<Operation>();
Predecessors = new List<BasicBlock>(); Predecessors = [];
Index = index; Index = index;
} }

View File

@@ -304,7 +304,7 @@ namespace ARMeilleure.IntermediateRepresentation
ushort newCount = checked((ushort)(count + 1)); ushort newCount = checked((ushort)(count + 1));
ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue); ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue);
var oldSpan = new Span<T>(data, count); Span<T> oldSpan = new(data, count);
capacity = newCapacity; capacity = newCapacity;
data = Allocators.References.Allocate<T>(capacity); data = Allocators.References.Allocate<T>(capacity);
@@ -338,7 +338,7 @@ namespace ARMeilleure.IntermediateRepresentation
throw new OverflowException(); throw new OverflowException();
} }
var oldSpan = new Span<T>(data, (int)count); Span<T> oldSpan = new(data, (int)count);
capacity = newCapacity; capacity = newCapacity;
data = Allocators.References.Allocate<T>(capacity); data = Allocators.References.Allocate<T>(capacity);
@@ -352,7 +352,7 @@ namespace ARMeilleure.IntermediateRepresentation
private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged
{ {
var span = new Span<T>(data, count); Span<T> span = new(data, count);
for (int i = 0; i < span.Length; i++) for (int i = 0; i < span.Length; i++)
{ {
@@ -372,7 +372,7 @@ namespace ARMeilleure.IntermediateRepresentation
private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged
{ {
var span = new Span<T>(data, (int)count); Span<T> span = new(data, (int)count);
for (int i = 0; i < span.Length; i++) for (int i = 0; i < span.Length; i++)
{ {

View File

@@ -198,7 +198,7 @@ namespace ARMeilleure.Signal
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I32, OperandType.I64, OperandType.I64 }; OperandType[] argTypes = [OperandType.I32, OperandType.I64, OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code;
} }
@@ -252,7 +252,7 @@ namespace ARMeilleure.Signal
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code; return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Code;
} }

View File

@@ -22,7 +22,7 @@ namespace ARMeilleure.Signal
{ {
EmitterContext context = new(); EmitterContext context = new();
var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context); Operand result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
context.Return(result); context.Return(result);
@@ -30,7 +30,7 @@ namespace ARMeilleure.Signal
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugPartialUnmap>(); return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugPartialUnmap>();
} }
@@ -39,7 +39,7 @@ namespace ARMeilleure.Signal
{ {
EmitterContext context = new(); EmitterContext context = new();
var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1)); Operand result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
context.Return(result); context.Return(result);
@@ -47,7 +47,7 @@ namespace ARMeilleure.Signal
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugThreadLocalMapGetOrReserve>(); return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugThreadLocalMapGetOrReserve>();
} }
@@ -76,7 +76,7 @@ namespace ARMeilleure.Signal
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugNativeWriteLoop>(); return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugNativeWriteLoop>();
} }

View File

@@ -55,7 +55,7 @@ namespace ARMeilleure.Translation
public Aarch32Mode Mode { get; } public Aarch32Mode Mode { get; }
private int _ifThenBlockStateIndex = 0; private int _ifThenBlockStateIndex = 0;
private Condition[] _ifThenBlockState = Array.Empty<Condition>(); private Condition[] _ifThenBlockState = [];
public bool IsInIfThenBlock => _ifThenBlockStateIndex < _ifThenBlockState.Length; public bool IsInIfThenBlock => _ifThenBlockStateIndex < _ifThenBlockState.Length;
public Condition CurrentIfThenBlockCond => _ifThenBlockState[_ifThenBlockStateIndex]; public Condition CurrentIfThenBlockCond => _ifThenBlockState[_ifThenBlockStateIndex];

View File

@@ -23,7 +23,7 @@ namespace ARMeilleure.Translation.Cache
} }
} }
private readonly List<MemoryBlock> _blocks = new(); private readonly List<MemoryBlock> _blocks = [];
public CacheMemoryAllocator(int capacity) public CacheMemoryAllocator(int capacity)
{ {

View File

@@ -25,7 +25,7 @@ namespace ARMeilleure.Translation.Cache
private static CacheMemoryAllocator _cacheAllocator; private static CacheMemoryAllocator _cacheAllocator;
private static readonly List<CacheEntry> _cacheEntries = new(); private static readonly List<CacheEntry> _cacheEntries = [];
private static readonly Lock _lock = new(); private static readonly Lock _lock = new();
private static bool _initialized; private static bool _initialized;

View File

@@ -6,8 +6,8 @@ namespace ARMeilleure.Translation.Cache
{ {
class JitCacheInvalidation class JitCacheInvalidation
{ {
private static readonly int[] _invalidationCode = new int[] private static readonly int[] _invalidationCode =
{ [
unchecked((int)0xd53b0022), // mrs x2, ctr_el0 unchecked((int)0xd53b0022), // mrs x2, ctr_el0
unchecked((int)0xd3504c44), // ubfx x4, x2, #16, #4 unchecked((int)0xd3504c44), // ubfx x4, x2, #16, #4
unchecked((int)0x52800083), // mov w3, #0x4 unchecked((int)0x52800083), // mov w3, #0x4
@@ -35,8 +35,8 @@ namespace ARMeilleure.Translation.Cache
unchecked((int)0x54ffffa8), // b.hi 54 <ic_clear_loop> unchecked((int)0x54ffffa8), // b.hi 54 <ic_clear_loop>
unchecked((int)0xd5033b9f), // dsb ish unchecked((int)0xd5033b9f), // dsb ish
unchecked((int)0xd5033fdf), // isb unchecked((int)0xd5033fdf), // isb
unchecked((int)0xd65f03c0), // ret unchecked((int)0xd65f03c0) // ret
}; ];
private delegate void InvalidateCache(ulong start, ulong end); private delegate void InvalidateCache(ulong start, ulong end);

View File

@@ -100,13 +100,13 @@ namespace ARMeilleure.Translation.Cache
return null; // Not found. return null; // Not found.
} }
var unwindInfo = funcEntry.UnwindInfo; CodeGen.Unwinding.UnwindInfo unwindInfo = funcEntry.UnwindInfo;
int codeIndex = 0; int codeIndex = 0;
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--) for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
{ {
var entry = unwindInfo.PushEntries[index]; UnwindPushEntry entry = unwindInfo.PushEntries[index];
switch (entry.PseudoOp) switch (entry.PseudoOp)
{ {

View File

@@ -47,8 +47,8 @@ namespace ARMeilleure.Translation
{ {
RemoveUnreachableBlocks(Blocks); RemoveUnreachableBlocks(Blocks);
var visited = new HashSet<BasicBlock>(); HashSet<BasicBlock> visited = [];
var blockStack = new Stack<BasicBlock>(); Stack<BasicBlock> blockStack = new();
Array.Resize(ref _postOrderBlocks, Blocks.Count); Array.Resize(ref _postOrderBlocks, Blocks.Count);
Array.Resize(ref _postOrderMap, Blocks.Count); Array.Resize(ref _postOrderMap, Blocks.Count);
@@ -88,8 +88,8 @@ namespace ARMeilleure.Translation
private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks) private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks)
{ {
var visited = new HashSet<BasicBlock>(); HashSet<BasicBlock> visited = [];
var workQueue = new Queue<BasicBlock>(); Queue<BasicBlock> workQueue = new();
visited.Add(Entry); visited.Add(Entry);
workQueue.Enqueue(Entry); workQueue.Enqueue(Entry);

View File

@@ -108,7 +108,7 @@ namespace ARMeilleure.Translation
/// <returns>A list of all values sorted by Key Order</returns> /// <returns>A list of all values sorted by Key Order</returns>
public List<TV> AsList() public List<TV> AsList()
{ {
List<TV> list = new(); List<TV> list = [];
AddToList(_root, list); AddToList(_root, list);

View File

@@ -3,12 +3,15 @@ using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Common; using ARMeilleure.Common;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using ARMeilleure.State;
using Humanizer;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@@ -29,8 +32,8 @@ 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 = 6998; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 7007; //! 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";
@@ -153,7 +156,7 @@ namespace ARMeilleure.Translation.PTC
private void InitializeCarriers() private void InitializeCarriers()
{ {
_infosStream = MemoryStreamManager.Shared.GetStream(); _infosStream = MemoryStreamManager.Shared.GetStream();
_codesList = new List<byte[]>(); _codesList = [];
_relocsStream = MemoryStreamManager.Shared.GetStream(); _relocsStream = MemoryStreamManager.Shared.GetStream();
_unwindInfosStream = MemoryStreamManager.Shared.GetStream(); _unwindInfosStream = MemoryStreamManager.Shared.GetStream();
} }
@@ -183,6 +186,36 @@ namespace ARMeilleure.Translation.PTC
InitializeCarriers(); InitializeCarriers();
} }
private bool ContainsBlacklistedFunctions()
{
List<ulong> blacklist = Profiler.GetBlacklistedFunctions();
bool containsBlacklistedFunctions = false;
_infosStream.Seek(0L, SeekOrigin.Begin);
bool foundBadFunction = false;
for (int index = 0; index < GetEntriesCount(); index++)
{
InfoEntry infoEntry = DeserializeStructure<InfoEntry>(_infosStream);
foreach (ulong address in blacklist)
{
if (infoEntry.Address == address)
{
containsBlacklistedFunctions = true;
Logger.Warning?.Print(LogClass.Ptc, "PPTC cache invalidated: Found blacklisted functions in PPTC cache");
foundBadFunction = true;
break;
}
}
if (foundBadFunction)
{
break;
}
}
return containsBlacklistedFunctions;
}
private void PreLoad() private void PreLoad()
{ {
string fileNameActual = $"{CachePathActual}.cache"; string fileNameActual = $"{CachePathActual}.cache";
@@ -531,7 +564,7 @@ namespace ARMeilleure.Translation.PTC
public void LoadTranslations(Translator translator) public void LoadTranslations(Translator translator)
{ {
if (AreCarriersEmpty()) if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
{ {
return; return;
} }
@@ -562,7 +595,7 @@ namespace ARMeilleure.Translation.PTC
bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize); bool isEntryChanged = infoEntry.Hash != ComputeHash(translator.Memory, infoEntry.Address, infoEntry.GuestSize);
if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) && value.HighCq)) if (isEntryChanged || (!infoEntry.HighCq && Profiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out PtcProfiler.FuncProfile value) && value.HighCq))
{ {
infoEntry.Stubbed = true; infoEntry.Stubbed = true;
infoEntry.CodeLength = 0; infoEntry.CodeLength = 0;
@@ -749,8 +782,8 @@ namespace ARMeilleure.Translation.PTC
UnwindInfo unwindInfo, UnwindInfo unwindInfo,
bool highCq) bool highCq)
{ {
var cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty); CompiledFunction cFunc = new(code, unwindInfo, RelocInfo.Empty);
var gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer); GuestFunction gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer);
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq); return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
} }
@@ -764,7 +797,7 @@ namespace ARMeilleure.Translation.PTC
private void StubCode(int index) private void StubCode(int index)
{ {
_codesList[index] = Array.Empty<byte>(); _codesList[index] = [];
} }
private void StubReloc(int relocEntriesCount) private void StubReloc(int relocEntriesCount)
@@ -787,7 +820,7 @@ namespace ARMeilleure.Translation.PTC
public void MakeAndSaveTranslations(Translator translator) public void MakeAndSaveTranslations(Translator translator)
{ {
var profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions); ConcurrentQueue<(ulong address, PtcProfiler.FuncProfile funcProfile)> profiledFuncsToTranslate = Profiler.GetProfiledFuncsToTranslate(translator.Functions);
_translateCount = 0; _translateCount = 0;
_translateTotalCount = profiledFuncsToTranslate.Count; _translateTotalCount = profiledFuncsToTranslate.Count;
@@ -831,13 +864,21 @@ namespace ARMeilleure.Translation.PTC
void TranslateFuncs() void TranslateFuncs()
{ {
while (profiledFuncsToTranslate.TryDequeue(out var item)) while (profiledFuncsToTranslate.TryDequeue(out (ulong address, PtcProfiler.FuncProfile funcProfile) item))
{ {
ulong address = item.address; ulong address = item.address;
ExecutionMode executionMode = item.funcProfile.Mode;
bool highCq = item.funcProfile.HighCq;
Debug.Assert(Profiler.IsAddressInStaticCodeRange(address)); Debug.Assert(Profiler.IsAddressInStaticCodeRange(address));
TranslatedFunction func = translator.Translate(address, item.funcProfile.Mode, item.funcProfile.HighCq); TranslatedFunction func = translator.Translate(address, executionMode, highCq);
if (func == null)
{
Profiler.UpdateEntry(address, executionMode, true, true);
continue;
}
bool isAddressUnique = translator.Functions.TryAdd(address, func.GuestSize, func); bool isAddressUnique = translator.Functions.TryAdd(address, func.GuestSize, func);
@@ -866,11 +907,11 @@ namespace ARMeilleure.Translation.PTC
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
foreach (var thread in threads) foreach (Thread thread in threads)
{ {
thread.Start(); thread.Start();
} }
foreach (var thread in threads) foreach (Thread thread in threads)
{ {
thread.Join(); thread.Join();
} }
@@ -883,8 +924,11 @@ 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, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism} in {sw.Elapsed.TotalSeconds} s"); Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}");
Thread preSaveThread = new(PreSave) Thread preSaveThread = new(PreSave)
{ {
@@ -944,7 +988,7 @@ namespace ARMeilleure.Translation.PTC
WriteCode(code.AsSpan()); WriteCode(code.AsSpan());
// WriteReloc. // WriteReloc.
using var relocInfoWriter = new BinaryWriter(_relocsStream, EncodingCache.UTF8NoBOM, true); using BinaryWriter relocInfoWriter = new(_relocsStream, EncodingCache.UTF8NoBOM, true);
foreach (RelocEntry entry in relocInfo.Entries) foreach (RelocEntry entry in relocInfo.Entries)
{ {
@@ -954,7 +998,7 @@ namespace ARMeilleure.Translation.PTC
} }
// WriteUnwindInfo. // WriteUnwindInfo.
using var unwindInfoWriter = new BinaryWriter(_unwindInfosStream, EncodingCache.UTF8NoBOM, true); using BinaryWriter unwindInfoWriter = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
unwindInfoWriter.Write(unwindInfo.PushEntries.Length); unwindInfoWriter.Write(unwindInfo.PushEntries.Length);

View File

@@ -50,7 +50,7 @@ namespace ARMeilleure.Translation.PTC
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static List<T> DeserializeList<T>(Stream stream) where T : struct public static List<T> DeserializeList<T>(Stream stream) where T : struct
{ {
List<T> list = new(); List<T> list = [];
int count = DeserializeStructure<int>(stream); int count = DeserializeStructure<int>(stream);

View File

@@ -24,11 +24,13 @@ namespace ARMeilleure.Translation.PTC
{ {
private const string OuterHeaderMagicString = "Pohd\0\0\0\0"; private const string OuterHeaderMagicString = "Pohd\0\0\0\0";
private const uint InternalVersion = 5518; //! 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,
];
private const int SaveInterval = 30; // Seconds. private const int SaveInterval = 30; // Seconds.
@@ -76,20 +78,30 @@ namespace ARMeilleure.Translation.PTC
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) public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
{ {
if (IsAddressInStaticCodeRange(address)) if (IsAddressInStaticCodeRange(address))
{ {
Debug.Assert(!highCq); Debug.Assert(!highCq);
lock (_lock) if (blacklist)
{ {
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false)); lock (_lock)
{
ProfiledFuncs[address] = new FuncProfile(mode, highCq: false, true);
}
}
else
{
lock (_lock)
{
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false, false));
}
} }
} }
} }
public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq) public void UpdateEntry(ulong address, ExecutionMode mode, bool highCq, bool? blacklist = null)
{ {
if (IsAddressInStaticCodeRange(address)) if (IsAddressInStaticCodeRange(address))
{ {
@@ -99,7 +111,7 @@ namespace ARMeilleure.Translation.PTC
{ {
Debug.Assert(ProfiledFuncs.ContainsKey(address)); Debug.Assert(ProfiledFuncs.ContainsKey(address));
ProfiledFuncs[address] = new FuncProfile(mode, highCq: true); ProfiledFuncs[address] = new FuncProfile(mode, highCq: true, blacklist ?? ProfiledFuncs[address].Blacklist);
} }
} }
} }
@@ -111,11 +123,11 @@ namespace ARMeilleure.Translation.PTC
public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs) public ConcurrentQueue<(ulong address, FuncProfile funcProfile)> GetProfiledFuncsToTranslate(TranslatorCache<TranslatedFunction> funcs)
{ {
var profiledFuncsToTranslate = new ConcurrentQueue<(ulong address, FuncProfile funcProfile)>(); ConcurrentQueue<(ulong address, FuncProfile funcProfile)> profiledFuncsToTranslate = new();
foreach (var profiledFunc in ProfiledFuncs) foreach (KeyValuePair<ulong, FuncProfile> profiledFunc in ProfiledFuncs)
{ {
if (!funcs.ContainsKey(profiledFunc.Key)) if (!funcs.ContainsKey(profiledFunc.Key) && !profiledFunc.Value.Blacklist)
{ {
profiledFuncsToTranslate.Enqueue((profiledFunc.Key, profiledFunc.Value)); profiledFuncsToTranslate.Enqueue((profiledFunc.Key, profiledFunc.Value));
} }
@@ -130,6 +142,24 @@ namespace ARMeilleure.Translation.PTC
ProfiledFuncs.TrimExcess(); ProfiledFuncs.TrimExcess();
} }
public List<ulong> GetBlacklistedFunctions()
{
List<ulong> funcs = new List<ulong>();
foreach (var profiledFunc in ProfiledFuncs)
{
if (profiledFunc.Value.Blacklist)
{
if (!funcs.Contains(profiledFunc.Key))
{
funcs.Add(profiledFunc.Key);
}
}
}
return funcs;
}
public void PreLoad() public void PreLoad()
{ {
_lastHash = default; _lastHash = default;
@@ -220,13 +250,18 @@ namespace ARMeilleure.Translation.PTC
return false; return false;
} }
Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null;
switch (outerHeader.InfoFileVersion) switch (outerHeader.InfoFileVersion)
{ {
case InternalVersion: case InternalVersion:
ProfiledFuncs = Deserialize(stream); ProfiledFuncs = Deserialize(stream);
break; break;
case 1866: case 1866:
ProfiledFuncs = Deserialize(stream, (address, profile) => (address + 0x500000UL, profile)); migrateEntryFunc = (address, profile) => (address + 0x500000UL, profile);
goto case 5518;
case 5518:
ProfiledFuncs = DeserializeAddBlacklist(stream, migrateEntryFunc);
break; break;
default: default:
Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache."); Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache.");
@@ -256,6 +291,16 @@ namespace ARMeilleure.Translation.PTC
return DeserializeDictionary<ulong, FuncProfile>(stream, DeserializeStructure<FuncProfile>); return DeserializeDictionary<ulong, FuncProfile>(stream, DeserializeStructure<FuncProfile>);
} }
private static Dictionary<ulong, FuncProfile> DeserializeAddBlacklist(Stream stream, Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null)
{
if (migrateEntryFunc != null)
{
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
}
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
}
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream) private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
{ {
return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position); return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position);
@@ -387,13 +432,35 @@ namespace ARMeilleure.Translation.PTC
} }
} }
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)] [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 6*/)]
public struct FuncProfile public struct FuncProfile
{ {
public ExecutionMode Mode; public ExecutionMode Mode;
public bool HighCq; public bool HighCq;
public bool Blacklist;
public FuncProfile(ExecutionMode mode, bool highCq) public FuncProfile(ExecutionMode mode, bool highCq, bool blacklist)
{
Mode = mode;
HighCq = highCq;
Blacklist = blacklist;
}
public FuncProfile(FuncProfilePreBlacklist fp)
{
Mode = fp.Mode;
HighCq = fp.HighCq;
Blacklist = false;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
public struct FuncProfilePreBlacklist
{
public ExecutionMode Mode;
public bool HighCq;
public FuncProfilePreBlacklist(ExecutionMode mode, bool highCq)
{ {
Mode = mode; Mode = mode;
HighCq = highCq; HighCq = highCq;

View File

@@ -95,7 +95,7 @@ namespace ARMeilleure.Translation
// This is required because we have a implicit context load at the start of the function, // This is required because we have a implicit context load at the start of the function,
// but if there is a jump to the start of the function, the context load would trash the modified values. // but if there is a jump to the start of the function, the context load would trash the modified values.
// Here we insert a new entry block that will jump to the existing entry block. // Here we insert a new entry block that will jump to the existing entry block.
BasicBlock newEntry = new BasicBlock(cfg.Blocks.Count); BasicBlock newEntry = new(cfg.Blocks.Count);
cfg.UpdateEntry(newEntry); cfg.UpdateEntry(newEntry);
} }

View File

@@ -44,10 +44,10 @@ namespace ARMeilleure.Translation
public static void Construct(ControlFlowGraph cfg) public static void Construct(ControlFlowGraph cfg)
{ {
var globalDefs = new DefMap[cfg.Blocks.Count]; DefMap[] globalDefs = new DefMap[cfg.Blocks.Count];
var localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount]; Operand[] localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
var dfPhiBlocks = new Queue<BasicBlock>(); Queue<BasicBlock> dfPhiBlocks = new();
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{ {

View File

@@ -222,7 +222,7 @@ namespace ARMeilleure.Translation
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false) internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
{ {
var context = new ArmEmitterContext( ArmEmitterContext context = new(
Memory, Memory,
CountTable, CountTable,
FunctionTable, FunctionTable,
@@ -249,6 +249,11 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter); ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter);
if (cfg == null)
{
return null;
}
ulong funcSize = funcRange.End - funcRange.Start; ulong funcSize = funcRange.End - funcRange.Start;
Logger.EndPass(PassName.Translation, cfg); Logger.EndPass(PassName.Translation, cfg);
@@ -259,10 +264,10 @@ namespace ARMeilleure.Translation
Logger.EndPass(PassName.RegisterUsage); Logger.EndPass(PassName.RegisterUsage);
var retType = OperandType.I64; OperandType retType = OperandType.I64;
var argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
var options = highCq ? CompilerOptions.HighCq : CompilerOptions.None; CompilerOptions options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
if (context.HasPtc && !singleStep) if (context.HasPtc && !singleStep)
{ {
@@ -407,6 +412,11 @@ namespace ARMeilleure.Translation
if (opCode.Instruction.Emitter != null) if (opCode.Instruction.Emitter != null)
{ {
opCode.Instruction.Emitter(context); opCode.Instruction.Emitter(context);
if (opCode.Instruction.Name == InstName.Und && blkIndex == 0)
{
range = new Range(rangeStart, rangeEnd);
return null;
}
} }
else else
{ {
@@ -478,7 +488,7 @@ namespace ARMeilleure.Translation
public void InvalidateJitCacheRegion(ulong address, ulong size) public void InvalidateJitCacheRegion(ulong address, ulong size)
{ {
ulong[] overlapAddresses = Array.Empty<ulong>(); ulong[] overlapAddresses = [];
int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses); int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses);
@@ -521,7 +531,7 @@ namespace ARMeilleure.Translation
List<TranslatedFunction> functions = Functions.AsList(); List<TranslatedFunction> functions = Functions.AsList();
foreach (var func in functions) foreach (TranslatedFunction func in functions)
{ {
JitCache.Unmap(func.FuncPointer); JitCache.Unmap(func.FuncPointer);
@@ -530,7 +540,7 @@ namespace ARMeilleure.Translation
Functions.Clear(); Functions.Clear();
while (_oldFuncs.TryDequeue(out var kv)) while (_oldFuncs.TryDequeue(out KeyValuePair<ulong, TranslatedFunction> kv))
{ {
JitCache.Unmap(kv.Value.FuncPointer); JitCache.Unmap(kv.Value.FuncPointer);
@@ -551,7 +561,7 @@ namespace ARMeilleure.Translation
{ {
while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request)) while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
{ {
if (Functions.TryGetValue(request.Address, out var func) && func.CallCounter != null) if (Functions.TryGetValue(request.Address, out TranslatedFunction func) && func.CallCounter != null)
{ {
Volatile.Write(ref func.CallCounter.Value, 0); Volatile.Write(ref func.CallCounter.Value, 0);
} }

View File

@@ -36,7 +36,7 @@ namespace ARMeilleure.Translation
Sync = new object(); Sync = new object();
_requests = new Stack<RejitRequest>(); _requests = new Stack<RejitRequest>();
_requestAddresses = new HashSet<ulong>(); _requestAddresses = [];
} }
/// <summary> /// <summary>

View File

@@ -142,7 +142,7 @@ namespace ARMeilleure.Translation
/// <returns>Generated <see cref="DispatchStub"/></returns> /// <returns>Generated <see cref="DispatchStub"/></returns>
private nint GenerateDispatchStub() private nint GenerateDispatchStub()
{ {
var context = new EmitterContext(); EmitterContext context = new();
Operand lblFallback = Label(); Operand lblFallback = Label();
Operand lblEnd = Label(); Operand lblEnd = Label();
@@ -161,7 +161,7 @@ namespace ARMeilleure.Translation
for (int i = 0; i < _functionTable.Levels.Length; i++) for (int i = 0; i < _functionTable.Levels.Length; i++)
{ {
ref var level = ref _functionTable.Levels[i]; ref AddressTableLevel level = ref _functionTable.Levels[i];
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not // level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
// be encoded as an immediate on x86's bitwise and operation. // be encoded as an immediate on x86's bitwise and operation.
@@ -185,11 +185,11 @@ namespace ARMeilleure.Translation
hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext); context.Tailcall(hostAddress, nativeContext);
var cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
var retType = OperandType.I64; OperandType retType = OperandType.I64;
var argTypes = new[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>(); GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
return Marshal.GetFunctionPointerForDelegate(func); return Marshal.GetFunctionPointerForDelegate(func);
} }
@@ -200,7 +200,7 @@ namespace ARMeilleure.Translation
/// <returns>Generated <see cref="SlowDispatchStub"/></returns> /// <returns>Generated <see cref="SlowDispatchStub"/></returns>
private nint GenerateSlowDispatchStub() private nint GenerateSlowDispatchStub()
{ {
var context = new EmitterContext(); EmitterContext context = new();
// Load the target guest address from the native context. // Load the target guest address from the native context.
Operand nativeContext = context.LoadArgument(OperandType.I64, 0); Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
@@ -210,11 +210,11 @@ namespace ARMeilleure.Translation
Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext); context.Tailcall(hostAddress, nativeContext);
var cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
var retType = OperandType.I64; OperandType retType = OperandType.I64;
var argTypes = new[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
var func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>(); GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
return Marshal.GetFunctionPointerForDelegate(func); return Marshal.GetFunctionPointerForDelegate(func);
} }
@@ -251,7 +251,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="DispatchLoop"/> function</returns> /// <returns><see cref="DispatchLoop"/> function</returns>
private DispatcherFunction GenerateDispatchLoop() private DispatcherFunction GenerateDispatchLoop()
{ {
var context = new EmitterContext(); EmitterContext context = new();
Operand beginLbl = Label(); Operand beginLbl = Label();
Operand endLbl = Label(); Operand endLbl = Label();
@@ -279,9 +279,9 @@ namespace ARMeilleure.Translation
context.Return(); context.Return();
var cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
var retType = OperandType.None; OperandType retType = OperandType.None;
var argTypes = new[] { OperandType.I64, OperandType.I64 }; OperandType[] argTypes = [OperandType.I64, OperandType.I64];
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>(); return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>();
} }
@@ -292,7 +292,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="ContextWrapper"/> function</returns> /// <returns><see cref="ContextWrapper"/> function</returns>
private WrapperFunction GenerateContextWrapper() private WrapperFunction GenerateContextWrapper()
{ {
var context = new EmitterContext(); EmitterContext context = new();
Operand nativeContext = context.LoadArgument(OperandType.I64, 0); Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
Operand guestMethod = context.LoadArgument(OperandType.I64, 1); Operand guestMethod = context.LoadArgument(OperandType.I64, 1);
@@ -303,9 +303,9 @@ namespace ARMeilleure.Translation
context.Return(returnValue); context.Return(returnValue);
var cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
var retType = OperandType.I64; OperandType retType = OperandType.I64;
var argTypes = new[] { OperandType.I64, OperandType.I64 }; OperandType[] argTypes = [OperandType.I64, OperandType.I64];
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>(); return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<WrapperFunction>();
} }

View File

@@ -139,7 +139,7 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = context.GetControlFlowGraph(); ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType[] argTypes = new OperandType[] { OperandType.I64 }; OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<FpFlagsPInvokeTest>(); return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<FpFlagsPInvokeTest>();
} }

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Audio.Backends.SDL2
SDL2Driver.Instance.Initialize(); SDL2Driver.Instance.Initialize();
int res = SDL_GetDefaultAudioInfo(nint.Zero, out var spec, 0); int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
if (res != 0) if (res != 0)
{ {

View File

@@ -38,7 +38,7 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
get => Marshal.PtrToStringAnsi(GetOutContext().Name); get => Marshal.PtrToStringAnsi(GetOutContext().Name);
set set
{ {
var context = GetOutContext(); SoundIoOutStream context = GetOutContext();
if (_nameStored != nint.Zero && context.Name == _nameStored) if (_nameStored != nint.Zero && context.Name == _nameStored)
{ {
@@ -129,8 +129,8 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
unsafe unsafe
{ {
var frameCountPtr = &nativeFrameCount; int* frameCountPtr = &nativeFrameCount;
var arenasPtr = &arenas; IntPtr* arenasPtr = &arenas;
CheckError(soundio_outstream_begin_write(_context, (nint)arenasPtr, (nint)frameCountPtr)); CheckError(soundio_outstream_begin_write(_context, (nint)arenasPtr, (nint)frameCountPtr));
frameCount = *frameCountPtr; frameCount = *frameCountPtr;

View File

@@ -31,19 +31,19 @@ namespace Ryujinx.Audio.Backends.CompatLayer
private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One); private const int Minus6dBInQ15 = (int)(0.501f * RawQ15One);
private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One); private const int Minus12dBInQ15 = (int)(0.251f * RawQ15One);
private static readonly long[] _defaultSurroundToStereoCoefficients = new long[4] private static readonly long[] _defaultSurroundToStereoCoefficients =
{ [
RawQ15One, RawQ15One,
Minus3dBInQ15, Minus3dBInQ15,
Minus12dBInQ15, Minus12dBInQ15,
Minus3dBInQ15, Minus3dBInQ15
}; ];
private static readonly long[] _defaultStereoToMonoCoefficients = new long[2] private static readonly long[] _defaultStereoToMonoCoefficients =
{ [
Minus6dBInQ15, Minus6dBInQ15,
Minus6dBInQ15, Minus6dBInQ15
}; ];
private const int SurroundChannelCount = 6; private const int SurroundChannelCount = 6;
private const int StereoChannelCount = 2; private const int StereoChannelCount = 2;

View File

@@ -164,12 +164,12 @@ namespace Ryujinx.Audio
/// <summary> /// <summary>
/// The default coefficients used for standard 5.1 surround to stereo downmixing. /// The default coefficients used for standard 5.1 surround to stereo downmixing.
/// </summary> /// </summary>
public static readonly float[] DefaultSurroundToStereoCoefficients = new float[4] public static readonly float[] DefaultSurroundToStereoCoefficients =
{ [
1.0f, 1.0f,
0.707f, 0.707f,
0.251f, 0.251f,
0.707f, 0.707f
}; ];
} }
} }

View File

@@ -173,7 +173,7 @@ namespace Ryujinx.Audio.Input
// TODO: Detect if the driver supports audio input // TODO: Detect if the driver supports audio input
} }
return new[] { Constants.DefaultDeviceInputName }; return [Constants.DefaultDeviceInputName];
} }
/// <summary> /// <summary>

View File

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

View File

@@ -10,14 +10,14 @@ namespace Ryujinx.Audio.Renderer.Device
/// <summary> /// <summary>
/// All the defined virtual devices. /// All the defined virtual devices.
/// </summary> /// </summary>
public static readonly VirtualDevice[] Devices = new VirtualDevice[5] public static readonly VirtualDevice[] Devices =
{ [
new("AudioStereoJackOutput", 2, true), new("AudioStereoJackOutput", 2, true),
new("AudioBuiltInSpeakerOutput", 2, false), new("AudioBuiltInSpeakerOutput", 2, false),
new("AudioTvOutput", 6, false), new("AudioTvOutput", 6, false),
new("AudioUsbDeviceOutput", 2, true), new("AudioUsbDeviceOutput", 2, true),
new("AudioExternalOutput", 6, true), new("AudioExternalOutput", 6, true)
}; ];
/// <summary> /// <summary>
/// The name of the <see cref="VirtualDevice"/>. /// The name of the <see cref="VirtualDevice"/>.

View File

@@ -46,7 +46,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
SampleRate = sampleRate; SampleRate = sampleRate;
BufferCount = mixBufferCount + voiceChannelCountMax; BufferCount = mixBufferCount + voiceChannelCountMax;
Buffers = mixBuffer; Buffers = mixBuffer;
Commands = new List<ICommand>(); Commands = [];
MemoryManager = memoryManager; MemoryManager = memoryManager;
_buffersEntryCount = Buffers.Length; _buffersEntryCount = Buffers.Length;

View File

@@ -9,21 +9,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{ {
public class Reverb3dCommand : ICommand public class Reverb3dCommand : ICommand
{ {
private static readonly int[] _outputEarlyIndicesTableMono = new int[20] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; private static readonly int[] _outputEarlyIndicesTableMono = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
private static readonly int[] _targetEarlyDelayLineIndicesTableMono = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; ];
private static readonly int[] _targetOutputFeedbackIndicesTableMono = new int[1] { 0 }; private static readonly int[] _targetEarlyDelayLineIndicesTableMono = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
];
private static readonly int[] _targetOutputFeedbackIndicesTableMono = [0];
private static readonly int[] _outputEarlyIndicesTableStereo = new int[20] { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }; private static readonly int[] _outputEarlyIndicesTableStereo = [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1
private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; ];
private static readonly int[] _targetOutputFeedbackIndicesTableStereo = new int[2] { 0, 1 }; private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
];
private static readonly int[] _targetOutputFeedbackIndicesTableStereo = [0, 1];
private static readonly int[] _outputEarlyIndicesTableQuadraphonic = new int[20] { 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3 }; private static readonly int[] _outputEarlyIndicesTableQuadraphonic = [0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3
private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = new int[20] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; ];
private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
];
private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = [0, 1, 2, 3];
private static readonly int[] _outputEarlyIndicesTableSurround = new int[40] { 4, 5, 0, 5, 0, 5, 1, 5, 1, 5, 1, 5, 1, 5, 2, 5, 2, 5, 2, 5, 1, 5, 1, 5, 1, 5, 0, 5, 0, 5, 0, 5, 0, 5, 3, 5, 3, 5, 3, 5 }; private static readonly int[] _outputEarlyIndicesTableSurround = [4, 5, 0, 5, 0, 5, 1, 5, 1, 5, 1, 5, 1, 5, 2, 5, 2, 5, 2, 5, 1, 5, 1, 5, 1, 5, 0, 5, 0, 5, 0, 5, 0, 5, 3, 5, 3, 5, 3, 5
private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = new int[40] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19 }; ];
private static readonly int[] _targetOutputFeedbackIndicesTableSurround = new int[6] { 0, 1, 2, 3, -1, 3 }; private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19
];
private static readonly int[] _targetOutputFeedbackIndicesTableSurround = [0, 1, 2, 3, -1, 3];
public bool Enabled { get; set; } public bool Enabled { get; set; }

View File

@@ -9,25 +9,27 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{ {
public class ReverbCommand : ICommand public class ReverbCommand : ICommand
{ {
private static readonly int[] _outputEarlyIndicesTableMono = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; private static readonly int[] _outputEarlyIndicesTableMono = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
private static readonly int[] _targetEarlyDelayLineIndicesTableMono = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; private static readonly int[] _targetEarlyDelayLineIndicesTableMono = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableMono = new int[4] { 0, 0, 0, 0 }; private static readonly int[] _outputIndicesTableMono = [0, 0, 0, 0];
private static readonly int[] _targetOutputFeedbackIndicesTableMono = new int[4] { 0, 1, 2, 3 }; private static readonly int[] _targetOutputFeedbackIndicesTableMono = [0, 1, 2, 3];
private static readonly int[] _outputEarlyIndicesTableStereo = new int[10] { 0, 0, 1, 1, 0, 1, 0, 0, 1, 1 }; private static readonly int[] _outputEarlyIndicesTableStereo = [0, 0, 1, 1, 0, 1, 0, 0, 1, 1];
private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableStereo = new int[4] { 0, 0, 1, 1 }; private static readonly int[] _outputIndicesTableStereo = [0, 0, 1, 1];
private static readonly int[] _targetOutputFeedbackIndicesTableStereo = new int[4] { 2, 0, 3, 1 }; private static readonly int[] _targetOutputFeedbackIndicesTableStereo = [2, 0, 3, 1];
private static readonly int[] _outputEarlyIndicesTableQuadraphonic = new int[10] { 0, 0, 1, 1, 0, 1, 2, 2, 3, 3 }; private static readonly int[] _outputEarlyIndicesTableQuadraphonic = [0, 0, 1, 1, 0, 1, 2, 2, 3, 3];
private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; private static readonly int[] _outputIndicesTableQuadraphonic = [0, 1, 2, 3];
private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 }; private static readonly int[] _targetOutputFeedbackIndicesTableQuadraphonic = [0, 1, 2, 3];
private static readonly int[] _outputEarlyIndicesTableSurround = new int[20] { 0, 5, 0, 5, 1, 5, 1, 5, 4, 5, 4, 5, 2, 5, 2, 5, 3, 5, 3, 5 }; private static readonly int[] _outputEarlyIndicesTableSurround = [0, 5, 0, 5, 1, 5, 1, 5, 4, 5, 4, 5, 2, 5, 2, 5, 3, 5, 3, 5
private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = new int[20] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9 }; ];
private static readonly int[] _outputIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, 4, 5 }; private static readonly int[] _targetEarlyDelayLineIndicesTableSurround = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9
private static readonly int[] _targetOutputFeedbackIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, -1, 3 }; ];
private static readonly int[] _outputIndicesTableSurround = [0, 1, 2, 3, 4, 5];
private static readonly int[] _targetOutputFeedbackIndicesTableSurround = [0, 1, 2, 3, -1, 3];
public bool Enabled { get; set; } public bool Enabled { get; set; }

View File

@@ -10,7 +10,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
public static class ResamplerHelper public static class ResamplerHelper
{ {
#region "Default Quality Lookup Tables" #region "Default Quality Lookup Tables"
private static readonly short[] _normalCurveLut0 = { private static readonly short[] _normalCurveLut0 =
[
6600, 19426, 6722, 3, 6479, 19424, 6845, 9, 6359, 19419, 6968, 15, 6239, 19412, 7093, 22, 6600, 19426, 6722, 3, 6479, 19424, 6845, 9, 6359, 19419, 6968, 15, 6239, 19412, 7093, 22,
6121, 19403, 7219, 28, 6004, 19391, 7345, 34, 5888, 19377, 7472, 41, 5773, 19361, 7600, 48, 6121, 19403, 7219, 28, 6004, 19391, 7345, 34, 5888, 19377, 7472, 41, 5773, 19361, 7600, 48,
5659, 19342, 7728, 55, 5546, 19321, 7857, 62, 5434, 19298, 7987, 69, 5323, 19273, 8118, 77, 5659, 19342, 7728, 55, 5546, 19321, 7857, 62, 5434, 19298, 7987, 69, 5323, 19273, 8118, 77,
@@ -42,10 +43,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
109, 8646, 19148, 4890, 101, 8513, 19183, 4997, 92, 8381, 19215, 5104, 84, 8249, 19245, 5213, 109, 8646, 19148, 4890, 101, 8513, 19183, 4997, 92, 8381, 19215, 5104, 84, 8249, 19245, 5213,
77, 8118, 19273, 5323, 69, 7987, 19298, 5434, 62, 7857, 19321, 5546, 55, 7728, 19342, 5659, 77, 8118, 19273, 5323, 69, 7987, 19298, 5434, 62, 7857, 19321, 5546, 55, 7728, 19342, 5659,
48, 7600, 19361, 5773, 41, 7472, 19377, 5888, 34, 7345, 19391, 6004, 28, 7219, 19403, 6121, 48, 7600, 19361, 5773, 41, 7472, 19377, 5888, 34, 7345, 19391, 6004, 28, 7219, 19403, 6121,
22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600, 22, 7093, 19412, 6239, 15, 6968, 19419, 6359, 9, 6845, 19424, 6479, 3, 6722, 19426, 6600
}; ];
private static readonly short[] _normalCurveLut1 = { private static readonly short[] _normalCurveLut1 =
[
-68, 32639, 69, -5, -200, 32630, 212, -15, -328, 32613, 359, -26, -450, 32586, 512, -36, -68, 32639, 69, -5, -200, 32630, 212, -15, -328, 32613, 359, -26, -450, 32586, 512, -36,
-568, 32551, 669, -47, -680, 32507, 832, -58, -788, 32454, 1000, -69, -891, 32393, 1174, -80, -568, 32551, 669, -47, -680, 32507, 832, -58, -788, 32454, 1000, -69, -891, 32393, 1174, -80,
-990, 32323, 1352, -92, -1084, 32244, 1536, -103, -1173, 32157, 1724, -115, -1258, 32061, 1919, -128, -990, 32323, 1352, -92, -1084, 32244, 1536, -103, -1173, 32157, 1724, -115, -1258, 32061, 1919, -128,
@@ -77,10 +79,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
-180, 2747, 31593, -1554, -167, 2532, 31723, -1486, -153, 2322, 31844, -1414, -140, 2118, 31956, -1338, -180, 2747, 31593, -1554, -167, 2532, 31723, -1486, -153, 2322, 31844, -1414, -140, 2118, 31956, -1338,
-128, 1919, 32061, -1258, -115, 1724, 32157, -1173, -103, 1536, 32244, -1084, -92, 1352, 32323, -990, -128, 1919, 32061, -1258, -115, 1724, 32157, -1173, -103, 1536, 32244, -1084, -92, 1352, 32323, -990,
-80, 1174, 32393, -891, -69, 1000, 32454, -788, -58, 832, 32507, -680, -47, 669, 32551, -568, -80, 1174, 32393, -891, -69, 1000, 32454, -788, -58, 832, 32507, -680, -47, 669, 32551, -568,
-36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68, -36, 512, 32586, -450, -26, 359, 32613, -328, -15, 212, 32630, -200, -5, 69, 32639, -68
}; ];
private static readonly short[] _normalCurveLut2 = { private static readonly short[] _normalCurveLut2 =
[
3195, 26287, 3329, -32, 3064, 26281, 3467, -34, 2936, 26270, 3608, -38, 2811, 26253, 3751, -42, 3195, 26287, 3329, -32, 3064, 26281, 3467, -34, 2936, 26270, 3608, -38, 2811, 26253, 3751, -42,
2688, 26230, 3897, -46, 2568, 26202, 4046, -50, 2451, 26169, 4199, -54, 2338, 26130, 4354, -58, 2688, 26230, 3897, -46, 2568, 26202, 4046, -50, 2451, 26169, 4199, -54, 2338, 26130, 4354, -58,
2227, 26085, 4512, -63, 2120, 26035, 4673, -67, 2015, 25980, 4837, -72, 1912, 25919, 5004, -76, 2227, 26085, 4512, -63, 2120, 26035, 4673, -67, 2015, 25980, 4837, -72, 1912, 25919, 5004, -76,
@@ -112,12 +115,13 @@ namespace Ryujinx.Audio.Renderer.Dsp
-98, 5701, 25621, 1531, -92, 5522, 25704, 1622, -87, 5347, 25780, 1716, -81, 5174, 25852, 1813, -98, 5701, 25621, 1531, -92, 5522, 25704, 1622, -87, 5347, 25780, 1716, -81, 5174, 25852, 1813,
-76, 5004, 25919, 1912, -72, 4837, 25980, 2015, -67, 4673, 26035, 2120, -63, 4512, 26085, 2227, -76, 5004, 25919, 1912, -72, 4837, 25980, 2015, -67, 4673, 26035, 2120, -63, 4512, 26085, 2227,
-58, 4354, 26130, 2338, -54, 4199, 26169, 2451, -50, 4046, 26202, 2568, -46, 3897, 26230, 2688, -58, 4354, 26130, 2338, -54, 4199, 26169, 2451, -50, 4046, 26202, 2568, -46, 3897, 26230, 2688,
-42, 3751, 26253, 2811, -38, 3608, 26270, 2936, -34, 3467, 26281, 3064, -32, 3329, 26287, 3195, -42, 3751, 26253, 2811, -38, 3608, 26270, 2936, -34, 3467, 26281, 3064, -32, 3329, 26287, 3195
}; ];
#endregion #endregion
#region "High Quality Lookup Tables" #region "High Quality Lookup Tables"
private static readonly short[] _highCurveLut0 = { private static readonly short[] _highCurveLut0 =
[
-582, -23, 8740, 16386, 8833, 8, -590, 0, -573, -54, 8647, 16385, 8925, 40, -598, -1, -582, -23, 8740, 16386, 8833, 8, -590, 0, -573, -54, 8647, 16385, 8925, 40, -598, -1,
-565, -84, 8555, 16383, 9018, 72, -606, -1, -557, -113, 8462, 16379, 9110, 105, -614, -2, -565, -84, 8555, 16383, 9018, 72, -606, -1, -557, -113, 8462, 16379, 9110, 105, -614, -2,
-549, -142, 8370, 16375, 9203, 139, -622, -2, -541, -170, 8277, 16369, 9295, 173, -630, -3, -549, -142, 8370, 16375, 9203, 139, -622, -2, -541, -170, 8277, 16369, 9295, 173, -630, -3,
@@ -181,10 +185,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
-5, -646, 244, 9480, 16354, 8093, -225, -525, -4, -638, 208, 9387, 16362, 8185, -198, -533, -5, -646, 244, 9480, 16354, 8093, -225, -525, -4, -638, 208, 9387, 16362, 8185, -198, -533,
-3, -630, 173, 9295, 16369, 8277, -170, -541, -2, -622, 139, 9203, 16375, 8370, -142, -549, -3, -630, 173, 9295, 16369, 8277, -170, -541, -2, -622, 139, 9203, 16375, 8370, -142, -549,
-2, -614, 105, 9110, 16379, 8462, -113, -557, -1, -606, 72, 9018, 16383, 8555, -84, -565, -2, -614, 105, 9110, 16379, 8462, -113, -557, -1, -606, 72, 9018, 16383, 8555, -84, -565,
-1, -598, 40, 8925, 16385, 8647, -54, -573, 0, -590, 8, 8833, 16386, 8740, -23, -582, -1, -598, 40, 8925, 16385, 8647, -54, -573, 0, -590, 8, 8833, 16386, 8740, -23, -582
}; ];
private static readonly short[] _highCurveLut1 = { private static readonly short[] _highCurveLut1 =
[
-12, 47, -134, 32767, 81, -16, 2, 0, -26, 108, -345, 32760, 301, -79, 17, -1, -12, 47, -134, 32767, 81, -16, 2, 0, -26, 108, -345, 32760, 301, -79, 17, -1,
-40, 168, -552, 32745, 526, -144, 32, -2, -53, 226, -753, 32723, 755, -210, 47, -3, -40, 168, -552, 32745, 526, -144, 32, -2, -53, 226, -753, 32723, 755, -210, 47, -3,
-66, 284, -950, 32694, 989, -277, 63, -5, -78, 340, -1143, 32658, 1226, -346, 79, -6, -66, 284, -950, 32694, 989, -277, 63, -5, -78, 340, -1143, 32658, 1226, -346, 79, -6,
@@ -248,10 +253,11 @@ namespace Ryujinx.Audio.Renderer.Dsp
-9, 113, -486, 1715, 32564, -1514, 447, -101, -8, 96, -415, 1469, 32615, -1331, 394, -90, -9, 113, -486, 1715, 32564, -1514, 447, -101, -8, 96, -415, 1469, 32615, -1331, 394, -90,
-6, 79, -346, 1226, 32658, -1143, 340, -78, -5, 63, -277, 989, 32694, -950, 284, -66, -6, 79, -346, 1226, 32658, -1143, 340, -78, -5, 63, -277, 989, 32694, -950, 284, -66,
-3, 47, -210, 755, 32723, -753, 226, -53, -2, 32, -144, 526, 32745, -552, 168, -40, -3, 47, -210, 755, 32723, -753, 226, -53, -2, 32, -144, 526, 32745, -552, 168, -40,
-1, 17, -79, 301, 32760, -345, 108, -26, 0, 2, -16, 81, 32767, -134, 47, -12, -1, 17, -79, 301, 32760, -345, 108, -26, 0, 2, -16, 81, 32767, -134, 47, -12
}; ];
private static readonly short[] _highCurveLut2 = { private static readonly short[] _highCurveLut2 =
[
418, -2538, 6118, 24615, 6298, -2563, 417, 0, 420, -2512, 5939, 24611, 6479, -2588, 415, 1, 418, -2538, 6118, 24615, 6298, -2563, 417, 0, 420, -2512, 5939, 24611, 6479, -2588, 415, 1,
421, -2485, 5761, 24605, 6662, -2612, 412, 2, 422, -2458, 5585, 24595, 6846, -2635, 409, 3, 421, -2485, 5761, 24605, 6662, -2612, 412, 2, 422, -2458, 5585, 24595, 6846, -2635, 409, 3,
423, -2430, 5410, 24582, 7030, -2658, 406, 4, 423, -2402, 5236, 24565, 7216, -2680, 403, 5, 423, -2430, 5410, 24582, 7030, -2658, 406, 4, 423, -2402, 5236, 24565, 7216, -2680, 403, 5,
@@ -315,8 +321,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
7, 395, -2721, 7591, 24523, 4893, -2343, 423, 6, 399, -2701, 7403, 24546, 5064, -2373, 423, 7, 395, -2721, 7591, 24523, 4893, -2343, 423, 6, 399, -2701, 7403, 24546, 5064, -2373, 423,
5, 403, -2680, 7216, 24565, 5236, -2402, 423, 4, 406, -2658, 7030, 24582, 5410, -2430, 423, 5, 403, -2680, 7216, 24565, 5236, -2402, 423, 4, 406, -2658, 7030, 24582, 5410, -2430, 423,
3, 409, -2635, 6846, 24595, 5585, -2458, 422, 2, 412, -2612, 6662, 24605, 5761, -2485, 421, 3, 409, -2635, 6846, 24595, 5585, -2458, 422, 2, 412, -2612, 6662, 24605, 5761, -2485, 421,
1, 415, -2588, 6479, 24611, 5939, -2512, 420, 0, 417, -2563, 6298, 24615, 6118, -2538, 418, 1, 415, -2588, 6479, 24611, 5939, -2512, 420, 0, 417, -2563, 6298, 24615, 6118, -2538, 418
}; ];
#endregion #endregion
private static readonly float[] _normalCurveLut0F; private static readonly float[] _normalCurveLut0F;

View File

@@ -6,12 +6,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
{ {
public struct Reverb3dState public struct Reverb3dState
{ {
private readonly float[] _fdnDelayMinTimes = new float[4] { 5.0f, 6.0f, 13.0f, 14.0f }; private readonly float[] _fdnDelayMinTimes = [5.0f, 6.0f, 13.0f, 14.0f];
private readonly float[] _fdnDelayMaxTimes = new float[4] { 45.704f, 82.782f, 149.94f, 271.58f }; private readonly float[] _fdnDelayMaxTimes = [45.704f, 82.782f, 149.94f, 271.58f];
private readonly float[] _decayDelayMaxTimes1 = new float[4] { 17.0f, 13.0f, 9.0f, 7.0f }; private readonly float[] _decayDelayMaxTimes1 = [17.0f, 13.0f, 9.0f, 7.0f];
private readonly float[] _decayDelayMaxTimes2 = new float[4] { 19.0f, 11.0f, 10.0f, 6.0f }; private readonly float[] _decayDelayMaxTimes2 = [19.0f, 11.0f, 10.0f, 6.0f];
private readonly float[] _earlyDelayTimes = new float[20] { 0.017136f, 0.059154f, 0.16173f, 0.39019f, 0.42526f, 0.45541f, 0.68974f, 0.74591f, 0.83384f, 0.8595f, 0.0f, 0.075024f, 0.16879f, 0.2999f, 0.33744f, 0.3719f, 0.59901f, 0.71674f, 0.81786f, 0.85166f }; private readonly float[] _earlyDelayTimes = [0.017136f, 0.059154f, 0.16173f, 0.39019f, 0.42526f, 0.45541f, 0.68974f, 0.74591f, 0.83384f, 0.8595f, 0.0f, 0.075024f, 0.16879f, 0.2999f, 0.33744f, 0.3719f, 0.59901f, 0.71674f, 0.81786f, 0.85166f
public readonly float[] EarlyGain = new float[20] { 0.67096f, 0.61027f, 1.0f, 0.35680f, 0.68361f, 0.65978f, 0.51939f, 0.24712f, 0.45945f, 0.45021f, 0.64196f, 0.54879f, 0.92925f, 0.38270f, 0.72867f, 0.69794f, 0.5464f, 0.24563f, 0.45214f, 0.44042f }; ];
public readonly float[] EarlyGain = [0.67096f, 0.61027f, 1.0f, 0.35680f, 0.68361f, 0.65978f, 0.51939f, 0.24712f, 0.45945f, 0.45021f, 0.64196f, 0.54879f, 0.92925f, 0.38270f, 0.72867f, 0.69794f, 0.5464f, 0.24563f, 0.45214f, 0.44042f
];
public IDelayLine[] FdnDelayLines { get; } public IDelayLine[] FdnDelayLines { get; }
public DecayDelay[] DecayDelays1 { get; } public DecayDelay[] DecayDelays1 { get; }

View File

@@ -7,8 +7,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
{ {
public struct ReverbState public struct ReverbState
{ {
private static readonly float[] _fdnDelayTimes = new float[20] private static readonly float[] _fdnDelayTimes =
{ [
// Room // Room
53.953247f, 79.192566f, 116.238770f, 130.615295f, 53.953247f, 79.192566f, 116.238770f, 130.615295f,
// Hall // Hall
@@ -18,11 +18,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral // Cathedral
47.03f, 71f, 103f, 170f, 47.03f, 71f, 103f, 170f,
// Max delay (Hall is the one with the highest values so identical to Hall) // Max delay (Hall is the one with the highest values so identical to Hall)
53.953247f, 79.192566f, 116.238770f, 170.615295f, 53.953247f, 79.192566f, 116.238770f, 170.615295f
}; ];
private static readonly float[] _decayDelayTimes = new float[20] private static readonly float[] _decayDelayTimes =
{ [
// Room // Room
7f, 9f, 13f, 17f, 7f, 9f, 13f, 17f,
// Hall // Hall
@@ -32,11 +32,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral // Cathedral
7f, 7f, 13f, 9f, 7f, 7f, 13f, 9f,
// Max delay (Hall is the one with the highest values so identical to Hall) // Max delay (Hall is the one with the highest values so identical to Hall)
7f, 9f, 13f, 17f, 7f, 9f, 13f, 17f
}; ];
private static readonly float[] _earlyDelayTimes = new float[50] private static readonly float[] _earlyDelayTimes =
{ [
// Room // Room
0.0f, 3.5f, 2.8f, 3.9f, 2.7f, 13.4f, 7.9f, 8.4f, 9.9f, 12.0f, 0.0f, 3.5f, 2.8f, 3.9f, 2.7f, 13.4f, 7.9f, 8.4f, 9.9f, 12.0f,
// Chamber // Chamber
@@ -46,11 +46,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral // Cathedral
33.1f, 43.3f, 22.8f, 37.9f, 14.9f, 35.3f, 17.9f, 34.2f, 0.0f, 43.3f, 33.1f, 43.3f, 22.8f, 37.9f, 14.9f, 35.3f, 17.9f, 34.2f, 0.0f, 43.3f,
// Disabled // Disabled
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
}; ];
private static readonly float[] _earlyGainBase = new float[50] private static readonly float[] _earlyGainBase =
{ [
// Room // Room
0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.68f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.68f, 0.68f,
// Chamber // Chamber
@@ -60,11 +60,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral // Cathedral
0.93f, 0.92f, 0.87f, 0.86f, 0.94f, 0.81f, 0.80f, 0.77f, 0.76f, 0.65f, 0.93f, 0.92f, 0.87f, 0.86f, 0.94f, 0.81f, 0.80f, 0.77f, 0.76f, 0.65f,
// Disabled // Disabled
0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f
}; ];
private static readonly float[] _preDelayTimes = new float[5] private static readonly float[] _preDelayTimes =
{ [
// Room // Room
12.5f, 12.5f,
// Chamber // Chamber
@@ -74,8 +74,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral // Cathedral
50.0f, 50.0f,
// Disabled // Disabled
0.0f, 0.0f
}; ];
public DelayLine[] FdnDelayLines { get; } public DelayLine[] FdnDelayLines { get; }
public DecayDelay[] DecayDelays { get; } public DecayDelay[] DecayDelays { get; }

View File

@@ -436,7 +436,7 @@ namespace Ryujinx.Audio.Renderer.Server
return result; return result;
} }
PoolMapper poolMapper = new PoolMapper(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled()); PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
result = stateUpdater.UpdateVoices(_voiceContext, poolMapper); result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);

View File

@@ -27,7 +27,7 @@ namespace Ryujinx.Audio.Renderer.Utils
private void UpdateHeader() private void UpdateHeader()
{ {
var writer = new BinaryWriter(_stream); BinaryWriter writer = new(_stream);
long currentPos = writer.Seek(0, SeekOrigin.Current); long currentPos = writer.Seek(0, SeekOrigin.Current);

View File

@@ -83,7 +83,7 @@ namespace Ryujinx.BuildValidationTasks
if (isGitRunner && encounteredIssue) if (isGitRunner && encounteredIssue)
throw new JsonException("1 or more locales are invalid!"); throw new JsonException("1 or more locales are invalid!");
JsonSerializerOptions jsonOptions = new JsonSerializerOptions() JsonSerializerOptions jsonOptions = new()
{ {
WriteIndented = true, WriteIndented = true,
NewLine = "\n", NewLine = "\n",

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