Feature: Auto-Assign Controllers #706

Open
uncavo-hdmi wants to merge 31 commits from uncavo-hdmi/auto-assign-controller into master
796 changed files with 25653 additions and 13344 deletions
Showing only changes of commit da268ebbee - Show all commits

View File

@ -29,7 +29,7 @@ env:
jobs:
tag:
name: Create tag
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
@ -202,7 +202,7 @@ jobs:
macos_release:
name: Release MacOS universal
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

View File

@ -18,7 +18,7 @@ env:
jobs:
tag:
name: Create tag
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- name: Get version info
id: version_info
@ -183,7 +183,7 @@ jobs:
macos_release:
name: Release MacOS universal
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

View File

@ -10,7 +10,7 @@ Make sure your SDK version is higher or equal to the required version specified
### 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

View File

@ -14,13 +14,13 @@ We always welcome bug reports, feature proposals and overall feedback. Here are
### 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.
### 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
@ -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.
* 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
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
@ -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`).
- 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.
- [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.
6. Build the repository with your changes.
- Make sure that the builds are clean.
- 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.
- 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
- 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.
@ -90,7 +90,7 @@ We use and recommend the following workflow:
### 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
@ -113,7 +113,7 @@ Also do your best to factor commits appropriately, not too large with unrelated
### 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:
* `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 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

@ -7,11 +7,11 @@
# Ryujinx
[![Release workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml)
[![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/GreemDev/Ryujinx/releases/latest)
[![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/Ryubing/Ryujinx/releases/latest)
<br>
[![Canary workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/GreemDev/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)
[![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/Ryubing/Canary-Releases?label=canary)](https://github.com/Ryubing/Canary-Releases/releases/latest)
</td>
</tr>
</table>
@ -20,7 +20,7 @@
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.
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 />
</p>
<p align="center">
@ -30,7 +30,7 @@
<br>
This is not a Ryujinx revival project. This is not a Phoenix project.
<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 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>.
@ -39,12 +39,12 @@
<p align="center">
Click below to join the Discord:
<br>
<a href="https://discord.gg/dHPrkBkkyA">
<a href="https://discord.gg/PEuzjrFXUA">
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
</a>
<br>
<br>
<img src="https://raw.githubusercontent.com/GreemDev/Ryujinx/refs/heads/master/docs/shell.png">
<img src="https://raw.githubusercontent.com/Ryubing/Ryujinx/refs/heads/master/docs/shell.png">
</p>
## Usage
@ -58,13 +58,13 @@ Stable builds are made every so often, based on the `master` branch, that then g
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
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.
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.
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

File diff suppressed because it is too large Load Diff

View File

@ -332,6 +332,7 @@
0100E680149DC000,"Arcaea",,playable,2023-03-16 19:31:21
01003C2010C78000,"Archaica: The Path Of Light",crash,nothing,2020-10-16 13:22:26
01004DA012976000,"Area 86",,playable,2020-12-16 16:45:52
01008d8006a6a000,"Arena of Valor",crash,boots,2025-02-03 22:19:34
0100691013C46000,"ARIA CHRONICLE",,playable,2022-11-16 13:50:55
0100D4A00B284000,"ARK: Survival Evolved",gpu;nvdec;online-broken;UE4;ldn-untested,ingame,2024-04-16 00:53:56
0100C56012C96000,"Arkanoid vs. Space Invaders",services,ingame,2021-01-21 12:50:30
@ -426,6 +427,7 @@
0100E48013A34000,"Balan Wonderworld Demo",gpu;services;UE4;demo,ingame,2023-02-16 20:05:07
0100CD801CE5E000,"Balatro",,ingame,2024-04-21 02:01:53
010010A00DA48000,"Baldur's Gate and Baldur's Gate II: Enhanced Editions",32-bit,playable,2022-09-12 23:52:15
0100fd1014726000,"Baldur's Gate: Dark Alliance",ldn-untested,ingame,2025-02-03 22:21:00
0100BC400FB64000,"Balthazar's Dream",,playable,2022-09-13 00:13:22
01008D30128E0000,"Bamerang",,playable,2022-10-26 00:29:39
010013C010C5C000,"Banner of the Maid",,playable,2021-06-14 15:23:37
@ -528,6 +530,7 @@
01005950022EC000,"Blade Strangers",nvdec,playable,2022-07-17 19:02:43
0100DF0011A6A000,"Bladed Fury",,playable,2022-10-26 11:36:26
0100CFA00CC74000,"Blades of Time",deadlock;online,boots,2022-07-17 19:19:58
01003d700dd8a000,"Blades",,boots,2025-02-03 22:22:00
01006CC01182C000,"Blair Witch",nvdec;UE4,playable,2022-10-01 14:06:16
010039501405E000,"Blanc",gpu;slow,ingame,2023-02-22 14:00:13
0100698009C6E000,"Blasphemous",nvdec,playable,2021-03-01 12:15:31
@ -955,7 +958,7 @@
010012800EBAE000,"Disney TSUM TSUM FESTIVAL",crash,menus,2020-07-14 14:05:28
01009740120FE000,"DISTRAINT 2",,playable,2020-09-03 16:08:12
010075B004DD2000,"DISTRAINT: Deluxe Edition",,playable,2020-06-15 23:42:24
010027400CDC6000,"Divinity: Original Sin 2 - Definitive Edition",services;crash;online-broken;regression,menus,2023-08-13 17:20:03
010027400CDC6000,"Divinity: Original Sin 2 - Definitive Edition",services;crash;online-broken;regression,ingame,2025-02-03 22:12:30
01001770115C8000,"Dodo Peak",nvdec;UE4,playable,2022-10-04 16:13:05
010077B0100DA000,"Dogurai",,playable,2020-10-04 02:40:16
010048100D51A000,"Dokapon Up! Mugen no Roulette",gpu;Needs Update,menus,2022-12-08 19:39:10
@ -966,6 +969,7 @@
0100751007ADA000,"Don't Starve: Nintendo Switch Edition",nvdec,playable,2022-02-05 20:43:34
010088B010DD2000,"Dongo Adventure",,playable,2022-10-04 16:22:26
0100C1F0051B6000,"Donkey Kong Country™: Tropical Freeze",,playable,2024-08-05 16:46:10
01009D901BC56000,"Donkey Kong Country™: Returns HD",gpu,ingame,2025-02-16 13:44:12
0100F2C00F060000,"Doodle Derby",,boots,2020-12-04 22:51:48
0100416004C00000,"DOOM",gpu;slow;nvdec;online-broken,ingame,2024-09-23 15:40:07
010018900DD00000,"DOOM (1993)",nvdec;online-broken,menus,2022-09-06 13:32:19
@ -1155,7 +1159,7 @@
010095600AA36000,"Fill-a-Pix: Phil's Epic Adventure",,playable,2020-12-22 13:48:22
0100C3A00BB76000,"Fimbul",nvdec,playable,2022-07-26 13:31:47
0100C8200E942000,"Fin and the Ancient Mystery",nvdec,playable,2020-12-17 16:40:39
01000EA014150000,"FINAL FANTASY",crash,nothing,2024-09-05 20:55:30
01000EA014150000,"FINAL FANTASY",,playable,2025-02-16 21:27:30
01006B7014156000,"FINAL FANTASY II",crash,nothing,2024-04-13 19:18:04
01006F000B056000,"FINAL FANTASY IX",audout;nvdec,playable,2021-06-05 11:35:00
0100AA201415C000,"FINAL FANTASY V",,playable,2023-04-26 01:11:55
@ -1246,7 +1250,7 @@
0100A6B00D4EC000,"Furwind",,playable,2021-02-19 19:44:08
0100ECE00C0C4000,"Fury Unleashed",crash;services,ingame,2020-10-18 11:52:40
010070000ED9E000,"Fury Unleashed Demo",,playable,2020-10-08 20:09:21
0100E1F013674000,"FUSER™",nvdec;UE4,playable,2022-10-17 20:58:32
0100E1F013674000,"FUSER™",nvdec;UE4;slow;gpu,ingame,2025-02-12 16:03:00
0100A7A015E4C000,"Fushigi no Gensokyo Lotus Labyrinth",Needs Update;audio;gpu;nvdec,ingame,2021-01-20 15:30:02
01003C300B274000,"Futari de! Nyanko Daisensou",,playable,2024-01-05 22:26:52
010055801134E000,"FUZE Player",online-broken;vulkan-backend-bug,ingame,2022-10-18 12:23:53
@ -1654,7 +1658,7 @@
0100A73006E74000,"Legendary Eleven",,playable,2021-06-08 12:09:03
0100A7700B46C000,"Legendary Fishing",online,playable,2021-04-14 15:08:46
0100739018020000,"LEGO® 2K Drive",gpu;ldn-works,ingame,2024-04-09 02:05:12
01003A30012C0000,"LEGO® CITY Undercover",nvdec,playable,2024-09-30 08:44:27
010085500130a000,"LEGO® CITY Undercover",nvdec,playable,2024-09-30 08:44:27
010070D009FEC000,"LEGO® DC Super-Villains",,playable,2021-05-27 18:10:37
010052A00B5D2000,"LEGO® Harry Potter™ Collection",crash,ingame,2024-01-31 10:28:07
010073C01AF34000,"LEGO® Horizon Adventures™",vulkan-backend-bug;opengl-backend-bug;UE4,ingame,2025-01-07 04:24:56
@ -1913,6 +1917,7 @@
010073E008E6E000,"Mugsters",,playable,2021-01-28 17:57:17
0100A8400471A000,"MUJO",,playable,2020-05-08 16:31:04
0100211005E94000,"Mulaka",,playable,2021-01-28 18:07:20
01008e2013fb4000,"Multi Quiz",ldn-untested,ingame,2025-02-03 22:26:00
010038B00B9AE000,"Mummy Pinball",,playable,2022-08-05 16:08:11
01008E200C5C2000,"Muse Dash",,playable,2020-06-06 14:41:29
010035901046C000,"Mushroom Quest",,playable,2020-05-17 13:07:08
@ -2028,6 +2033,7 @@
010003C00B868000,"Ninjin: Clash of Carrots",online-broken,playable,2024-07-10 05:12:26
0100746010E4C000,"NinNinDays",,playable,2022-11-20 15:17:29
0100C9A00ECE6000,"Nintendo 64™ Nintendo Switch Online",gpu;vulkan,ingame,2024-04-23 20:21:07
0100e0601c632000,"Nintendo 64™ Nintendo Switch Online: MATURE 17+",,ingame,2025-02-03 22:27:00
0100D870045B6000,"Nintendo Entertainment System™ - Nintendo Switch Online",online,playable,2022-07-01 15:45:06
0100C4B0034B2000,"Nintendo Labo Toy-Con 01 Variety Kit",gpu,ingame,2022-08-07 12:56:07
01001E9003502000,"Nintendo Labo Toy-Con 03 Vehicle Kit",services;crash,menus,2022-08-03 17:20:11
@ -2058,7 +2064,7 @@
010002700C34C000,"Numbala",,playable,2020-05-11 12:01:07
010020500C8C8000,"Number Place 10000",gpu,menus,2021-11-24 09:14:23
010003701002C000,"Nurse Love Syndrome",,playable,2022-10-13 10:05:22
0000000000000000,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
,"nx-hbmenu",Needs Update;homebrew,boots,2024-04-06 22:05:32
,"nxquake2",services;crash;homebrew,nothing,2022-08-04 23:14:04
010049F00EC30000,"Nyan Cat: Lost in Space",online,playable,2021-06-12 13:22:03
01002E6014FC4000,"O---O",,playable,2022-10-29 12:12:14
@ -2466,7 +2472,7 @@
0100AFE00DDAC000,"Royal Roads",,playable,2020-11-17 12:54:38
0100E2C00B414000,"RPG Maker MV",nvdec,playable,2021-01-05 20:12:01
01005CD015986000,"rRootage Reloaded",,playable,2022-08-05 23:20:18
0000000000000000,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
,"RSDKv5u",homebrew,ingame,2024-04-01 16:25:34
010009B00D33C000,"Rugby Challenge 4",slow;online-broken;UE4,playable,2022-10-06 12:45:53
01006EC00F2CC000,"RUINER",UE4,playable,2022-10-03 14:11:33
010074F00DE4A000,"Run the Fan",,playable,2021-02-27 13:36:28
@ -2475,6 +2481,7 @@
010081C0191D8000,"Rune Factory 3 Special",,playable,2023-10-15 08:32:49
010051D00E3A4000,"Rune Factory 4 Special",32-bit;crash;nvdec,ingame,2023-05-06 08:49:17
010014D01216E000,"Rune Factory 5 (JP)",gpu,ingame,2021-06-01 12:00:36
010071E0145F8000,"Rustler",,playable,2025-02-10 20:17:12
0100E21013908000,"RWBY: Grimm Eclipse - Definitive Edition",online-broken,playable,2022-11-03 10:44:01
010012C0060F0000,"RXN -Raijin-",nvdec,playable,2021-01-10 16:05:43
0100B8B012ECA000,"S.N.I.P.E.R. - Hunter Scope",,playable,2021-04-19 15:58:09
@ -2483,7 +2490,7 @@
0100A5200C2E0000,"Safety First!",,playable,2021-01-06 09:05:23
0100A51013530000,"SaGa Frontier Remastered",nvdec,playable,2022-11-03 13:54:56
010003A00D0B4000,"SaGa SCARLET GRACE: AMBITIONS™",,playable,2022-10-06 13:20:31
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN,playable,2023-12-04 18:33:37
01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN;deadlock,ingame,2025-02-02 16:57:53
0100DE600BEEE000,"SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE",slow;LAN,playable,2023-08-24 02:40:58
01007F000EB36000,"Sakai and...",nvdec,playable,2022-12-15 13:53:19
0100B1400E8FE000,"Sakuna: Of Rice and Ruin",,playable,2023-07-24 13:47:13
@ -2532,7 +2539,7 @@
0100C3E00B700000,"SEGA AGES Space Harrier",,playable,2021-01-11 12:57:40
010054400D2E6000,"SEGA AGES Virtua Racing",online-broken,playable,2023-01-29 17:08:39
01001E700AC60000,"SEGA AGES Wonder Boy: Monster Land",online,playable,2021-05-05 16:28:25
0100B3C014BDA000,"SEGA Genesis™ Nintendo Switch Online",crash;regression,nothing,2022-04-11 07:27:21
0100B3C014BDA000,"SEGA Genesis™ Nintendo Switch Online",crash;regression,ingame,2025-02-03 22:13:30
0100F7300B24E000,"SEGA Mega Drive Classics",online,playable,2021-01-05 11:08:00
01009840046BC000,"Semispheres",,playable,2021-01-06 23:08:31
0100D1800D902000,"SENRAN KAGURA Peach Ball",,playable,2021-06-03 15:12:10
@ -2668,10 +2675,10 @@
01004F401BEBE000,"Song of Nunu: A League of Legends Story",,ingame,2024-07-12 18:53:44
0100E5400BF94000,"Songbird Symphony",,playable,2021-02-27 02:44:04
010031D00A604000,"Songbringer",,playable,2020-06-22 10:42:02
0000000000000000,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
0000000000000000,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
0000000000000000,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
0000000000000000,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
,"Sonic 1 (2013)",crash;homebrew,ingame,2024-04-06 18:31:20
,"Sonic 2 (2013)",crash;homebrew,ingame,2024-04-01 16:25:30
,"Sonic A.I.R",homebrew,ingame,2024-04-01 16:25:32
,"Sonic CD",crash;homebrew,ingame,2024-04-01 16:25:31
010040E0116B8000,"Sonic Colors: Ultimate",,playable,2022-11-12 21:24:26
01001270012B6000,"SONIC FORCES™",,playable,2024-07-28 13:11:21
01004AD014BF0000,"Sonic Frontiers",gpu;deadlock;amd-vendor-bug;intel-vendor-bug,ingame,2024-09-05 09:18:53
@ -2688,7 +2695,7 @@
0100707011722000,"Space Elite Force",,playable,2020-11-27 15:21:05
010047B010260000,"Space Pioneer",,playable,2022-10-20 12:24:37
010010A009830000,"Space Ribbon",,playable,2022-08-15 17:17:10
0000000000000000,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
,"SpaceCadetPinball",homebrew,ingame,2024-04-18 19:30:04
0100D9B0041CE000,"Spacecats with Lasers",,playable,2022-08-15 17:22:44
010034800FB60000,"Spaceland",,playable,2020-11-01 14:31:56
010028D0045CE000,"Sparkle 2",,playable,2020-10-19 11:51:39
@ -2832,8 +2839,9 @@
01009B90006DC000,"Super Mario Maker™ 2",online-broken;ldn-broken,playable,2024-08-25 11:05:19
0100000000010000,"Super Mario Odyssey™",nvdec;intel-vendor-bug;mac-bug,playable,2024-08-25 01:32:34
010036B0034E4000,"Super Mario Party™",gpu;Needs Update;ldn-works,ingame,2024-06-21 05:10:16
0100965017338000,"Super Mario Party Jamboree",mac-bug;gpu,ingame,2025-02-17 02:09:20
0100BC0018138000,"Super Mario RPG™",gpu;audio;nvdec,ingame,2024-06-19 17:43:42
0000000000000000,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
,"Super Mario World",homebrew,boots,2024-06-13 01:40:31
010049900F546000,"Super Mario™ 3D All-Stars",services-horizon;slow;vulkan;amd-vendor-bug,ingame,2024-05-07 02:38:16
010028600EBDA000,"Super Mario™ 3D World + Bowsers Fury",ldn-works,playable,2024-07-31 10:45:37
01004F8006A78000,"Super Meat Boy",services,playable,2020-04-02 23:10:07
@ -2964,6 +2972,7 @@
0100C38004DCC000,"The Flame In The Flood: Complete Edition",gpu;nvdec;UE4,ingame,2022-08-22 16:23:49
010007700D4AC000,"The Forbidden Arts",,playable,2021-01-26 16:26:24
010030700CBBC000,"The friends of Ringo Ishikawa",,playable,2022-08-22 16:33:17
0100b620139d8000,"The Game of Life 2",ldn-untested,ingame,2025-02-03 22:30:00
01006350148DA000,"The Gardener and the Wild Vines",gpu,ingame,2024-04-29 16:32:10
0100B13007A6A000,"The Gardens Between",,playable,2021-01-29 16:16:53
010036E00FB20000,"The Great Ace Attorney Chronicles",,playable,2023-06-22 21:26:29
@ -2981,6 +2990,8 @@
010015D003EE4000,"The Jackbox Party Pack 2",online-working,playable,2022-08-22 18:23:40
0100CC80013D6000,"The Jackbox Party Pack 3",slow;online-working,playable,2022-08-22 18:41:06
0100E1F003EE8000,"The Jackbox Party Pack 4",online-working,playable,2022-08-22 18:56:34
01006fe0096ac000,"The Jackbox Party Pack 5",slow;online-working,ingame,2025-02-14 05:32:00
01005a400db52000,"The Jackbox Party Pack 6",slow;online-working,ingame,2025-02-14 05:26:00
010052C00B184000,"The Journey Down: Chapter One",nvdec,playable,2021-02-24 13:32:41
01006BC00B188000,"The Journey Down: Chapter Three",nvdec,playable,2021-02-24 13:45:27
01009AB00B186000,"The Journey Down: Chapter Two",nvdec,playable,2021-02-24 13:32:13
@ -3159,6 +3170,7 @@
010055E00CA68000,"Trine 4: The Nightmare Prince",gpu,nothing,2025-01-07 05:47:46
0100D9000A930000,"Trine Enchanted Edition",ldn-untested;nvdec,playable,2021-06-03 11:28:15
01002D7010A54000,"Trinity Trigger",crash,ingame,2023-03-03 03:09:09
010020700a5e0000,"TRIVIAL PURSUIT Live!",ldn-untested,ingame,2025-02-03 22:35:00
0100868013FFC000,"TRIVIAL PURSUIT Live! 2",,boots,2022-12-19 00:04:33
0100F78002040000,"Troll and I™",gpu;nvdec,ingame,2021-06-04 16:58:50
0100145011008000,"Trollhunters: Defenders of Arcadia",gpu;nvdec,ingame,2020-11-30 13:27:09
@ -3208,6 +3220,7 @@
0100AB2010B4C000,"Unlock The King",,playable,2020-09-01 13:58:27
0100A3E011CB0000,"Unlock the King 2",,playable,2021-06-15 20:43:55
01005AA00372A000,"UNO® for Nintendo Switch",nvdec;ldn-untested,playable,2022-07-28 14:49:47
0100b6e012ebe000,"UNO",ldn-untested,ingame,2025-02-03 22:40:00
0100E5D00CC0C000,"Unravel Two",nvdec,playable,2024-05-23 15:45:05
010001300CC4A000,"Unruly Heroes",,playable,2021-01-07 18:09:31
0100B410138C0000,"Unspottable",,playable,2022-10-25 19:28:49
@ -3372,6 +3385,7 @@
0100F47016F26000,"Yomawari 3",,playable,2022-05-10 08:26:51
010012F00B6F2000,"Yomawari: The Long Night Collection",,playable,2022-09-03 14:36:59
0100CC600ABB2000,"Yonder: The Cloud Catcher Chronicles (Retail Only)",,playable,2021-01-28 14:06:25
0100534009ff2000,"Yonder: The Cloud Catcher Chronicles",,playable,2025-02-03 22:19:13
0100BE50042F6000,"Yono and the Celestial Elephants",,playable,2021-01-28 18:23:58
0100F110029C8000,"Yooka-Laylee",,playable,2021-01-28 14:21:45
010022F00DA66000,"Yooka-Laylee and the Impossible Lair",,playable,2021-03-05 17:32:21

1 title_id game_name labels status last_updated
332 0100E680149DC000 Arcaea playable 2023-03-16 19:31:21
333 01003C2010C78000 Archaica: The Path Of Light crash nothing 2020-10-16 13:22:26
334 01004DA012976000 Area 86 playable 2020-12-16 16:45:52
335 01008d8006a6a000 Arena of Valor crash boots 2025-02-03 22:19:34
336 01008d8006a6a000 0100691013C46000 Arena of Valor ARIA CHRONICLE crash boots playable 2025-02-03 22:19:34 2022-11-16 13:50:55
337 0100691013C46000 0100D4A00B284000 ARIA CHRONICLE ARK: Survival Evolved gpu;nvdec;online-broken;UE4;ldn-untested playable ingame 2022-11-16 13:50:55 2024-04-16 00:53:56
338 0100D4A00B284000 0100C56012C96000 ARK: Survival Evolved Arkanoid vs. Space Invaders gpu;nvdec;online-broken;UE4;ldn-untested services ingame 2024-04-16 00:53:56 2021-01-21 12:50:30
427 0100438012EC8000 0100E48013A34000 BALAN WONDERWORLD Balan Wonderworld Demo nvdec;UE4 gpu;services;UE4;demo playable ingame 2022-10-22 13:08:43 2023-02-16 20:05:07
428 0100E48013A34000 0100CD801CE5E000 Balan Wonderworld Demo Balatro gpu;services;UE4;demo ingame 2023-02-16 20:05:07 2024-04-21 02:01:53
429 0100CD801CE5E000 010010A00DA48000 Balatro Baldur's Gate and Baldur's Gate II: Enhanced Editions 32-bit ingame playable 2024-04-21 02:01:53 2022-09-12 23:52:15
430 0100fd1014726000 Baldur's Gate: Dark Alliance ldn-untested ingame 2025-02-03 22:21:00
431 010010A00DA48000 0100BC400FB64000 Baldur's Gate and Baldur's Gate II: Enhanced Editions Balthazar's Dream 32-bit playable 2022-09-12 23:52:15 2022-09-13 00:13:22
432 0100fd1014726000 01008D30128E0000 Baldur's Gate: Dark Alliance Bamerang ldn-untested ingame playable 2025-02-03 22:21:00 2022-10-26 00:29:39
433 0100BC400FB64000 010013C010C5C000 Balthazar's Dream Banner of the Maid playable 2022-09-13 00:13:22 2021-06-14 15:23:37
530 0100EA1018A2E000 01005950022EC000 Blade Assault Blade Strangers audio nvdec nothing playable 2024-04-29 14:32:50 2022-07-17 19:02:43
531 01009CC00E224000 0100DF0011A6A000 Blade II - The Return Of Evil Bladed Fury audio;crash;UE4 ingame playable 2021-11-14 02:49:59 2022-10-26 11:36:26
532 01005950022EC000 0100CFA00CC74000 Blade Strangers Blades of Time nvdec deadlock;online playable boots 2022-07-17 19:02:43 2022-07-17 19:19:58
533 01003d700dd8a000 Blades boots 2025-02-03 22:22:00
534 0100DF0011A6A000 01006CC01182C000 Bladed Fury Blair Witch nvdec;UE4 playable 2022-10-26 11:36:26 2022-10-01 14:06:16
535 0100CFA00CC74000 010039501405E000 Blades of Time Blanc deadlock;online gpu;slow boots ingame 2022-07-17 19:19:58 2023-02-22 14:00:13
536 01003d700dd8a000 0100698009C6E000 Blades Blasphemous nvdec boots playable 2025-02-03 22:22:00 2021-03-01 12:15:31
958 0100A2F00EEFC000 010012800EBAE000 Disney Classic Games Collection Disney TSUM TSUM FESTIVAL online-broken crash playable menus 2022-09-13 15:44:17 2020-07-14 14:05:28
959 0100DA201EBF8000 01009740120FE000 Disney Epic Mickey: Rebrushed DISTRAINT 2 crash ingame playable 2024-09-26 22:11:51 2020-09-03 16:08:12
960 0100F0401435E000 010075B004DD2000 Disney Speedstorm DISTRAINT: Deluxe Edition services boots playable 2023-11-27 02:15:32 2020-06-15 23:42:24
961 010012800EBAE000 010027400CDC6000 Disney TSUM TSUM FESTIVAL Divinity: Original Sin 2 - Definitive Edition crash services;crash;online-broken;regression menus ingame 2020-07-14 14:05:28 2025-02-03 22:12:30
962 01009740120FE000 01001770115C8000 DISTRAINT 2 Dodo Peak nvdec;UE4 playable 2020-09-03 16:08:12 2022-10-04 16:13:05
963 010075B004DD2000 010077B0100DA000 DISTRAINT: Deluxe Edition Dogurai playable 2020-06-15 23:42:24 2020-10-04 02:40:16
964 010027400CDC6000 010048100D51A000 Divinity: Original Sin 2 - Definitive Edition Dokapon Up! Mugen no Roulette services;crash;online-broken;regression gpu;Needs Update ingame menus 2025-02-03 22:12:30 2022-12-08 19:39:10
969 010007200AC0E000 0100751007ADA000 Don't Die, Mr Robot! Don't Starve: Nintendo Switch Edition nvdec playable 2022-09-02 18:34:38 2022-02-05 20:43:34
970 0100E470067A8000 010088B010DD2000 Don't Knock Twice Dongo Adventure playable 2024-05-08 22:37:58 2022-10-04 16:22:26
971 0100C4D00B608000 0100C1F0051B6000 Don't Sink Donkey Kong Country™: Tropical Freeze gpu ingame playable 2021-02-26 15:41:11 2024-08-05 16:46:10
972 01009D901BC56000 Donkey Kong Country™: Returns HD gpu ingame 2025-02-16 13:44:12
973 0100751007ADA000 0100F2C00F060000 Don't Starve: Nintendo Switch Edition Doodle Derby nvdec playable boots 2022-02-05 20:43:34 2020-12-04 22:51:48
974 010088B010DD2000 0100416004C00000 Dongo Adventure DOOM gpu;slow;nvdec;online-broken playable ingame 2022-10-04 16:22:26 2024-09-23 15:40:07
975 0100C1F0051B6000 010018900DD00000 Donkey Kong Country™: Tropical Freeze DOOM (1993) nvdec;online-broken playable menus 2024-08-05 16:46:10 2022-09-06 13:32:19
1159 010047E010B3E000 010095600AA36000 Fight of Animals Fill-a-Pix: Phil's Epic Adventure online playable 2020-10-15 15:08:28 2020-12-22 13:48:22
1160 0100C7D00E730000 0100C3A00BB76000 Fight'N Rage Fimbul nvdec playable 2020-06-16 23:35:19 2022-07-26 13:31:47
1161 0100D02014048000 0100C8200E942000 FIGHTING EX LAYER ANOTHER DASH Fin and the Ancient Mystery online-broken;UE4 nvdec playable 2024-04-07 10:22:33 2020-12-17 16:40:39
1162 0100118009C68000 01000EA014150000 Figment FINAL FANTASY nvdec playable 2021-01-27 19:36:05 2025-02-16 21:27:30
1163 010095600AA36000 01006B7014156000 Fill-a-Pix: Phil's Epic Adventure FINAL FANTASY II crash playable nothing 2020-12-22 13:48:22 2024-04-13 19:18:04
1164 0100C3A00BB76000 01006F000B056000 Fimbul FINAL FANTASY IX nvdec audout;nvdec playable 2022-07-26 13:31:47 2021-06-05 11:35:00
1165 0100C8200E942000 0100AA201415C000 Fin and the Ancient Mystery FINAL FANTASY V nvdec playable 2020-12-17 16:40:39 2023-04-26 01:11:55
1250 0100E7B00BF24000 0100A6B00D4EC000 Funghi Explosion Furwind playable 2020-11-23 14:17:41 2021-02-19 19:44:08
1251 01008E10130F8000 0100ECE00C0C4000 Funimation Fury Unleashed gpu crash;services boots ingame 2021-04-08 13:08:17 2020-10-18 11:52:40
1252 0100EA501033C000 010070000ED9E000 Funny Bunny Adventures Fury Unleashed Demo playable 2020-08-05 13:46:56 2020-10-08 20:09:21
1253 01000EC00AF98000 0100E1F013674000 Furi FUSER™ nvdec;UE4;slow;gpu playable ingame 2022-07-27 12:21:20 2025-02-12 16:03:00
1254 0100A6B00D4EC000 0100A7A015E4C000 Furwind Fushigi no Gensokyo Lotus Labyrinth Needs Update;audio;gpu;nvdec playable ingame 2021-02-19 19:44:08 2021-01-20 15:30:02
1255 0100ECE00C0C4000 01003C300B274000 Fury Unleashed Futari de! Nyanko Daisensou crash;services ingame playable 2020-10-18 11:52:40 2024-01-05 22:26:52
1256 010070000ED9E000 010055801134E000 Fury Unleashed Demo FUZE Player online-broken;vulkan-backend-bug playable ingame 2020-10-08 20:09:21 2022-10-18 12:23:53
1658 010079901C898000 0100A73006E74000 Legacy of Kain™ Soul Reaver 1&2 Remastered Legendary Eleven playable 2025-01-07 05:50:01 2021-06-08 12:09:03
1659 01002DB007A96000 0100A7700B46C000 Legend of Kay Anniversary Legendary Fishing nvdec online playable 2021-01-29 18:38:29 2021-04-14 15:08:46
1660 0100ECC00EF3C000 0100739018020000 Legend of the Skyfish LEGO® 2K Drive gpu;ldn-works playable ingame 2020-06-24 13:04:22 2024-04-09 02:05:12
1661 01007E900DFB6000 010085500130a000 Legend of the Tetrarchs LEGO® CITY Undercover deadlock nvdec ingame playable 2020-07-10 07:54:03 2024-09-30 08:44:27
1662 0100A73006E74000 010070D009FEC000 Legendary Eleven LEGO® DC Super-Villains playable 2021-06-08 12:09:03 2021-05-27 18:10:37
1663 0100A7700B46C000 010052A00B5D2000 Legendary Fishing LEGO® Harry Potter™ Collection online crash playable ingame 2021-04-14 15:08:46 2024-01-31 10:28:07
1664 0100739018020000 010073C01AF34000 LEGO® 2K Drive LEGO® Horizon Adventures™ gpu;ldn-works vulkan-backend-bug;opengl-backend-bug;UE4 ingame 2024-04-09 02:05:12 2025-01-07 04:24:56
1917 0100DCA011262000 010073E008E6E000 Mr. DRILLER DrillLand Mugsters nvdec playable 2020-07-24 13:56:48 2021-01-28 17:57:17
1918 010031F002B66000 0100A8400471A000 Mr. Shifty MUJO slow playable 2020-05-08 15:28:16 2020-05-08 16:31:04
1919 01005EF00B4BC000 0100211005E94000 Ms. Splosion Man Mulaka online playable 2020-05-09 20:45:43 2021-01-28 18:07:20
1920 01008e2013fb4000 Multi Quiz ldn-untested ingame 2025-02-03 22:26:00
1921 010087C009246000 010038B00B9AE000 Muddledash Mummy Pinball services ingame playable 2020-05-08 16:46:14 2022-08-05 16:08:11
1922 01009D200952E000 01008E200C5C2000 MudRunner - American Wilds Muse Dash gpu;ldn-untested;vulkan-backend-bug;opengl-backend-bug ingame playable 2022-08-16 11:40:52 2020-06-06 14:41:29
1923 010073E008E6E000 010035901046C000 Mugsters Mushroom Quest playable 2021-01-28 17:57:17 2020-05-17 13:07:08
2033 0100E2F014F46000 010003C00B868000 NINJA GAIDEN Σ Ninjin: Clash of Carrots nvdec online-broken playable 2022-11-13 16:27:02 2024-07-10 05:12:26
2034 0100696014F4A000 0100746010E4C000 NINJA GAIDEN Σ2 NinNinDays nvdec playable 2024-07-31 21:53:48 2022-11-20 15:17:29
2035 01002AF014F4C000 0100C9A00ECE6000 NINJA GAIDEN: Master Collection Nintendo 64™ – Nintendo Switch Online nvdec gpu;vulkan playable ingame 2023-08-11 08:25:31 2024-04-23 20:21:07
2036 0100e0601c632000 Nintendo 64™ – Nintendo Switch Online: MATURE 17+ ingame 2025-02-03 22:27:00
2037 010088E003A76000 0100D870045B6000 Ninja Shodown Nintendo Entertainment System™ - Nintendo Switch Online online playable 2020-05-11 12:31:21 2022-07-01 15:45:06
2038 010081D00A480000 0100C4B0034B2000 Ninja Striker! Nintendo Labo Toy-Con 01 Variety Kit gpu playable ingame 2020-12-08 19:33:29 2022-08-07 12:56:07
2039 0100CCD0073EA000 01001E9003502000 Ninjala Nintendo Labo Toy-Con 03 Vehicle Kit online-broken;UE4 services;crash boots menus 2024-07-03 20:04:49 2022-08-03 17:20:11
2064 0100A9E00D97A000 010002700C34C000 Northgard Numbala crash menus playable 2022-02-06 02:05:35 2020-05-11 12:01:07
2065 01008AE019614000 010020500C8C8000 nOS new Operating System Number Place 10000 gpu playable menus 2023-03-22 16:49:08 2021-11-24 09:14:23
2066 0100CB800B07E000 010003701002C000 NOT A HERO: SUPER SNAZZY EDITION Nurse Love Syndrome playable 2021-01-28 19:31:24 2022-10-13 10:05:22
2067 01004D500D9BE000 Not Not - A Brain Buster nx-hbmenu Needs Update;homebrew playable boots 2020-05-10 02:05:26 2024-04-06 22:05:32
2068 0100DAF00D0E2000 Not Tonight: Take Back Control Edition nxquake2 nvdec services;crash;homebrew playable nothing 2022-10-19 11:48:47 2022-08-04 23:14:04
2069 0100343013248000 010049F00EC30000 Nubarron: The adventure of an unlucky gnome Nyan Cat: Lost in Space online playable 2020-12-17 16:45:17 2021-06-12 13:22:03
2070 01005140089F6000 01002E6014FC4000 Nuclien O---O playable 2020-05-10 05:32:55 2022-10-29 12:12:14
2472 010050400BD38000 0100AFE00DDAC000 Roman Rumble in Las Vegum - Asterix & Obelix XXL 2 Royal Roads deadlock;nvdec ingame playable 2022-07-21 17:54:14 2020-11-17 12:54:38
2473 01001F600829A000 0100E2C00B414000 Romancing SaGa 2 RPG Maker MV nvdec playable 2022-08-12 12:02:24 2021-01-05 20:12:01
2474 0100D0400D27A000 01005CD015986000 Romancing SaGa 3 rRootage Reloaded audio;gpu ingame playable 2020-06-27 20:26:18 2022-08-05 23:20:18
2475 010088100DD42000 Roof Rage RSDKv5u crash;regression homebrew boots ingame 2023-11-12 03:47:18 2024-04-01 16:25:34
2476 0100F3000FA58000 010009B00D33C000 Roombo: First Blood Rugby Challenge 4 nvdec slow;online-broken;UE4 playable 2020-08-05 12:11:37 2022-10-06 12:45:53
2477 0100936011556000 01006EC00F2CC000 Root Double -Before Crime * After Days- Xtend Edition RUINER crash UE4 nothing playable 2022-02-05 02:03:49 2022-10-03 14:11:33
2478 010030A00DA3A000 010074F00DE4A000 Root Letter: Last Answer Run the Fan vulkan-backend-bug playable 2022-09-17 10:25:57 2021-02-27 13:36:28
2481 01005CD015986000 010081C0191D8000 rRootage Reloaded Rune Factory 3 Special playable 2022-08-05 23:20:18 2023-10-15 08:32:49
2482 010051D00E3A4000 RSDKv5u Rune Factory 4 Special homebrew 32-bit;crash;nvdec ingame 2024-04-01 16:25:34 2023-05-06 08:49:17
2483 010009B00D33C000 010014D01216E000 Rugby Challenge 4 Rune Factory 5 (JP) slow;online-broken;UE4 gpu playable ingame 2022-10-06 12:45:53 2021-06-01 12:00:36
2484 010071E0145F8000 Rustler playable 2025-02-10 20:17:12
2485 01006EC00F2CC000 0100E21013908000 RUINER RWBY: Grimm Eclipse - Definitive Edition UE4 online-broken playable 2022-10-03 14:11:33 2022-11-03 10:44:01
2486 010074F00DE4A000 010012C0060F0000 Run the Fan RXN -Raijin- nvdec playable 2021-02-27 13:36:28 2021-01-10 16:05:43
2487 0100ADF00700E000 0100B8B012ECA000 Runbow S.N.I.P.E.R. - Hunter Scope online playable 2021-01-08 22:47:44 2021-04-19 15:58:09
2490 010051D00E3A4000 0100A5200C2E0000 Rune Factory 4 Special Safety First! 32-bit;crash;nvdec ingame playable 2023-05-06 08:49:17 2021-01-06 09:05:23
2491 010014D01216E000 0100A51013530000 Rune Factory 5 (JP) SaGa Frontier Remastered gpu nvdec ingame playable 2021-06-01 12:00:36 2022-11-03 13:54:56
2492 010071E0145F8000 010003A00D0B4000 Rustler SaGa SCARLET GRACE: AMBITIONS™ playable 2025-02-10 20:17:12 2022-10-06 13:20:31
2493 0100E21013908000 01008D100D43E000 RWBY: Grimm Eclipse - Definitive Edition Saints Row IV®: Re-Elected™ online-broken ldn-untested;LAN;deadlock playable ingame 2022-11-03 10:44:01 2025-02-02 16:57:53
2494 010012C0060F0000 0100DE600BEEE000 RXN -Raijin- SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE nvdec slow;LAN playable 2021-01-10 16:05:43 2023-08-24 02:40:58
2495 0100B8B012ECA000 01007F000EB36000 S.N.I.P.E.R. - Hunter Scope Sakai and... nvdec playable 2021-04-19 15:58:09 2022-12-15 13:53:19
2496 010007700CFA2000 0100B1400E8FE000 Saboteur II: Avenging Angel Sakuna: Of Rice and Ruin Needs Update;cpu;crash nothing playable 2021-01-26 14:47:37 2023-07-24 13:47:13
2539 0100394010844000 0100C3E00B700000 Seers Isle SEGA AGES Space Harrier playable 2020-11-17 12:28:50 2021-01-11 12:57:40
2540 0100A8900AF04000 010054400D2E6000 SEGA AGES Alex Kidd in Miracle World SEGA AGES Virtua Racing online online-broken playable 2021-05-05 16:35:47 2023-01-29 17:08:39
2541 01001E600AF08000 01001E700AC60000 SEGA AGES Gain Ground SEGA AGES Wonder Boy: Monster Land online playable 2021-05-05 16:16:27 2021-05-05 16:28:25
2542 0100D4D00AC62000 0100B3C014BDA000 SEGA AGES Out Run SEGA Genesis™ – Nintendo Switch Online crash;regression playable ingame 2021-01-11 13:13:59 2025-02-03 22:13:30
2543 01005A300C9F6000 0100F7300B24E000 SEGA AGES Phantasy Star SEGA Mega Drive Classics online playable 2021-01-11 12:49:48 2021-01-05 11:08:00
2544 01005F600CB0E000 01009840046BC000 SEGA AGES Puyo Puyo Semispheres online playable 2021-05-05 16:09:28 2021-01-06 23:08:31
2545 010051F00AC5E000 0100D1800D902000 SEGA AGES Sonic The Hedgehog SENRAN KAGURA Peach Ball slow playable 2023-03-05 20:16:31 2021-06-03 15:12:10
2675 010017B012AFC000 01004F401BEBE000 Soccer Club Life: Playing Manager Song of Nunu: A League of Legends Story gpu ingame 2022-10-25 11:59:22 2024-07-12 18:53:44
2676 0100B5000E05C000 0100E5400BF94000 Soccer Pinball Songbird Symphony UE4;gpu ingame playable 2021-06-15 20:56:51 2021-02-27 02:44:04
2677 010011A00A9A8000 010031D00A604000 Soccer Slammers Songbringer playable 2020-05-30 07:48:14 2020-06-22 10:42:02
2678 010095C00F9DE000 Soccer, Tactics & Glory Sonic 1 (2013) gpu crash;homebrew ingame 2022-09-26 17:15:58 2024-04-06 18:31:20
2679 0100590009C38000 SOL DIVIDE -SWORD OF DARKNESS- for Nintendo Switch Sonic 2 (2013) 32-bit crash;homebrew playable ingame 2021-06-09 14:13:03 2024-04-01 16:25:30
2680 0100A290048B0000 Soldam: Drop, Connect, Erase Sonic A.I.R homebrew playable ingame 2020-05-30 09:18:54 2024-04-01 16:25:32
2681 010008600D1AC000 Solo: Islands of the Heart Sonic CD gpu;nvdec crash;homebrew ingame 2022-09-11 17:54:43 2024-04-01 16:25:31
2682 01009EE00E91E000 010040E0116B8000 Some Distant Memory Sonic Colors: Ultimate playable 2022-09-15 21:48:19 2022-11-12 21:24:26
2683 01004F401BEBE000 01001270012B6000 Song of Nunu: A League of Legends Story SONIC FORCES™ ingame playable 2024-07-12 18:53:44 2024-07-28 13:11:21
2684 0100E5400BF94000 01004AD014BF0000 Songbird Symphony Sonic Frontiers gpu;deadlock;amd-vendor-bug;intel-vendor-bug playable ingame 2021-02-27 02:44:04 2024-09-05 09:18:53
2695 01008F701C074000 0100707011722000 SONIC SUPERSTARS Space Elite Force gpu;nvdec ingame playable 2023-10-28 17:48:07 2020-11-27 15:21:05
2696 010088801C150000 010047B010260000 Sonic Superstars Digital Art Book with Mini Digital Soundtrack Space Pioneer playable 2024-08-20 13:26:56 2022-10-20 12:24:37
2697 01005EA01C0FC000 010010A009830000 SONIC X SHADOW GENERATIONS Space Ribbon crash ingame playable 2025-01-07 04:20:45 2022-08-15 17:17:10
2698 010064F00C212000 Soul Axiom Rebooted SpaceCadetPinball nvdec;slow homebrew ingame 2020-09-04 12:41:01 2024-04-18 19:30:04
2699 0100F2100F0B2000 0100D9B0041CE000 Soul Searching Spacecats with Lasers playable 2020-07-09 18:39:07 2022-08-15 17:22:44
2700 01008F2005154000 010034800FB60000 South Park™: The Fractured but Whole™ - Standard Edition Spaceland slow;online-broken;vulkan-backend-bug;gpu ingame playable 2025-01-21 17:35:10 2020-11-01 14:31:56
2701 0100B9F00C162000 010028D0045CE000 Space Blaze Sparkle 2 playable 2020-08-30 16:18:05 2020-10-19 11:51:39
2839 010015700D5DC000 01009B90006DC000 Super Jumpy Ball Super Mario Maker™ 2 online-broken;ldn-broken playable 2020-07-04 18:40:36 2024-08-25 11:05:19
2840 0100196009998000 0100000000010000 Super Kickers League Ultimate Super Mario Odyssey™ nvdec;intel-vendor-bug;mac-bug playable 2021-01-26 13:36:48 2024-08-25 01:32:34
2841 01003FB00C5A8000 010036B0034E4000 Super Kirby Clash™ Super Mario Party™ ldn-works gpu;Needs Update;ldn-works playable ingame 2024-07-30 18:21:55 2024-06-21 05:10:16
2842 0100965017338000 Super Mario Party Jamboree mac-bug;gpu ingame 2025-02-17 02:09:20
2843 010000D00F81A000 0100BC0018138000 Super Korotama Super Mario RPG™ gpu;audio;nvdec playable ingame 2021-06-06 19:06:22 2024-06-19 17:43:42
2844 01003E300FCAE000 Super Loop Drive Super Mario World nvdec;UE4 homebrew playable boots 2022-09-22 10:58:05 2024-06-13 01:40:31
2845 054507E0B7552000 010049900F546000 Super Mario 64 Super Mario™ 3D All-Stars homebrew services-horizon;slow;vulkan;amd-vendor-bug ingame 2024-03-20 16:57:27 2024-05-07 02:38:16
2846 0100277011F1A000 010028600EBDA000 Super Mario Bros.™ 35 Super Mario™ 3D World + Bowser’s Fury online-broken ldn-works menus playable 2022-08-07 16:27:25 2024-07-31 10:45:37
2847 010015100B514000 01004F8006A78000 Super Mario Bros.™ Wonder Super Meat Boy amd-vendor-bug services playable 2024-09-06 13:21:21 2020-04-02 23:10:07
2972 0100CA100489C000 0100C38004DCC000 The Escapists 2 The Flame In The Flood: Complete Edition nvdec gpu;nvdec;UE4 playable ingame 2020-09-24 12:31:31 2022-08-22 16:23:49
2973 01001B700BA7C000 010007700D4AC000 The Escapists: Complete Edition The Forbidden Arts playable 2021-02-24 17:50:31 2021-01-26 16:26:24
2974 0100C2E0129A6000 010030700CBBC000 The Executioner The friends of Ringo Ishikawa nvdec playable 2021-01-23 00:31:28 2022-08-22 16:33:17
2975 0100b620139d8000 The Game of Life 2 ldn-untested ingame 2025-02-03 22:30:00
2976 01006050114D4000 01006350148DA000 The Experiment: Escape Room The Gardener and the Wild Vines gpu ingame 2022-09-30 13:20:35 2024-04-29 16:32:10
2977 0100B5900DFB2000 0100B13007A6A000 The Eyes of Ara The Gardens Between playable 2022-09-16 14:44:06 2021-01-29 16:16:53
2978 01002DD00AF9E000 010036E00FB20000 The Fall The Great Ace Attorney Chronicles gpu ingame playable 2020-05-31 23:31:16 2023-06-22 21:26:29
2990 01003B300E4AA000 010015D003EE4000 THE GRISAIA TRILOGY The Jackbox Party Pack 2 online-working playable 2021-01-31 15:53:59 2022-08-22 18:23:40
2991 01001950137D8000 0100CC80013D6000 The Hong Kong Massacre The Jackbox Party Pack 3 crash slow;online-working ingame playable 2021-01-21 12:06:56 2022-08-22 18:41:06
2992 01004AD00E094000 0100E1F003EE8000 The House of Da Vinci The Jackbox Party Pack 4 online-working playable 2021-01-05 14:17:19 2022-08-22 18:56:34
2993 01006fe0096ac000 The Jackbox Party Pack 5 slow;online-working ingame 2025-02-14 05:32:00
2994 01005a400db52000 The Jackbox Party Pack 6 slow;online-working ingame 2025-02-14 05:26:00
2995 01005A80113D2000 010052C00B184000 The House of Da Vinci 2 The Journey Down: Chapter One nvdec playable 2020-10-23 20:47:17 2021-02-24 13:32:41
2996 010088401495E000 01006BC00B188000 The House of the Dead: Remake The Journey Down: Chapter Three nvdec playable 2025-01-11 00:36:01 2021-02-24 13:45:27
2997 0100E24004510000 01009AB00B186000 The Hunt - Championship Edition The Journey Down: Chapter Two 32-bit nvdec menus playable 2022-07-21 20:21:25 2021-02-24 13:32:13
3170 01004C4010C00000 010055E00CA68000 Travel Mosaics 5: Waltzing Vienna Trine 4: The Nightmare Prince gpu playable nothing 2021-05-26 11:49:35 2025-01-07 05:47:46
3171 0100D520119D6000 0100D9000A930000 Travel Mosaics 6: Christmas Around the World Trine Enchanted Edition ldn-untested;nvdec playable 2021-05-26 00:52:47 2021-06-03 11:28:15
3172 01000BD0119DE000 01002D7010A54000 Travel Mosaics 7: Fantastic Berlin Trinity Trigger crash playable ingame 2021-05-22 18:37:34 2023-03-03 03:09:09
3173 010020700a5e0000 TRIVIAL PURSUIT Live! ldn-untested ingame 2025-02-03 22:35:00
3174 01007DB00A226000 0100868013FFC000 Travel Mosaics: A Paris Tour TRIVIAL PURSUIT Live! 2 playable boots 2021-05-26 12:42:26 2022-12-19 00:04:33
3175 010011600C946000 0100F78002040000 Travis Strikes Again: No More Heroes Troll and I™ nvdec;UE4 gpu;nvdec playable ingame 2022-08-25 12:36:38 2021-06-04 16:58:50
3176 01006EB004B0E000 0100145011008000 Treadnauts Trollhunters: Defenders of Arcadia gpu;nvdec playable ingame 2021-01-10 14:57:41 2020-11-30 13:27:09
3220 01007330027EE000 0100AB2010B4C000 Ultra Street Fighter® II: The Final Challengers Unlock The King ldn-untested playable 2021-11-25 07:54:58 2020-09-01 13:58:27
3221 01006A300BA2C000 0100A3E011CB0000 Umineko no Naku Koro ni Saku - うみねこのなく頃に咲 ~猫箱と夢想の交響曲~ Unlock the King 2 audout playable 2023-05-04 17:25:23 2021-06-15 20:43:55
3222 0100592005164000 01005AA00372A000 UNBOX: Newbie's Adventure UNO® for Nintendo Switch UE4 nvdec;ldn-untested playable 2022-08-29 13:12:56 2022-07-28 14:49:47
3223 0100b6e012ebe000 UNO ldn-untested ingame 2025-02-03 22:40:00
3224 01002D900C5E4000 0100E5D00CC0C000 Uncanny Valley Unravel Two nvdec playable 2021-06-04 13:28:45 2024-05-23 15:45:05
3225 010076F011F54000 010001300CC4A000 Undead & Beyond Unruly Heroes nvdec playable 2022-10-04 09:11:18 2021-01-07 18:09:31
3226 01008F3013E4E000 0100B410138C0000 Under Leaves Unspottable playable 2021-05-22 18:13:58 2022-10-25 19:28:49
3385 010074F013262000 0100F47016F26000 Xenoblade Chronicles™ 3 Yomawari 3 gpu;crash;nvdec;vulkan-backend-bug;amd-vendor-bug ingame playable 2024-08-06 19:56:44 2022-05-10 08:26:51
3386 0100FF500E34A000 010012F00B6F2000 Xenoblade Chronicles™ Definitive Edition Yomawari: The Long Night Collection nvdec playable 2024-05-04 20:12:41 2022-09-03 14:36:59
3387 010028600BA16000 0100CC600ABB2000 Xenon Racer Yonder: The Cloud Catcher Chronicles (Retail Only) nvdec;UE4 playable 2022-08-31 22:05:30 2021-01-28 14:06:25
3388 0100534009ff2000 Yonder: The Cloud Catcher Chronicles playable 2025-02-03 22:19:13
3389 010064200C324000 0100BE50042F6000 Xenon Valkyrie+ Yono and the Celestial Elephants playable 2021-06-07 20:25:53 2021-01-28 18:23:58
3390 0100928005BD2000 0100F110029C8000 Xenoraid Yooka-Laylee playable 2022-09-03 13:01:10 2021-01-28 14:21:45
3391 01005B5009364000 010022F00DA66000 Xeodrifter Yooka-Laylee and the Impossible Lair playable 2022-09-03 13:18:39 2021-03-05 17:32:21

View File

@ -18,13 +18,13 @@ To merge pull requests, you must have write permissions in the repository.
## 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).
## 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
@ -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.
* 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.

View File

@ -13,7 +13,7 @@ namespace ARMeilleure.CodeGen.Arm64
public static void RunPass(ControlFlowGraph cfg)
{
Dictionary<ulong, Operand> constants = new Dictionary<ulong, Operand>();
Dictionary<ulong, Operand> constants = new();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{

View File

@ -42,7 +42,7 @@ namespace ARMeilleure.CodeGen.Arm64
{
Offset = offset;
Symbol = symbol;
LdrOffsets = new List<(Operand, int)>();
LdrOffsets = [];
}
}
@ -266,7 +266,7 @@ namespace ARMeilleure.CodeGen.Arm64
}
else
{
relocInfo = new RelocInfo(Array.Empty<RelocEntry>());
relocInfo = new RelocInfo([]);
}
return (code, relocInfo);

View File

@ -1079,7 +1079,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static UnwindInfo WritePrologue(CodeGenContext context)
{
List<UnwindPushEntry> pushEntries = new();
List<UnwindPushEntry> pushEntries = [];
Operand rsp = Register(SpRegister);

View File

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

View File

@ -261,10 +261,10 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination;
List<Operand> sources = new()
{
operation.GetSource(0),
};
List<Operand> sources =
[
operation.GetSource(0)
];
int argsCount = operation.SourcesCount - 1;
@ -365,10 +365,10 @@ namespace ARMeilleure.CodeGen.Arm64
Operation node,
Operation operation)
{
List<Operand> sources = new()
{
operation.GetSource(0),
};
List<Operand> sources =
[
operation.GetSource(0)
];
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.
// 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.SetSources(new[] { address, expectedLow, expectedHigh, desiredLow, desiredHigh });
operation.SetDestinations([actualLow, actualHigh, Local(OperandType.I64), Local(OperandType.I64)]);
operation.SetSources([address, expectedLow, expectedHigh, desiredLow, desiredHigh]);
// 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.
@ -486,7 +486,7 @@ namespace ARMeilleure.CodeGen.Arm64
else
{
// 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,
// so they can't be used as destination operand.

View File

@ -1,7 +1,6 @@
using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Translation.Cache;
using System;
using System.Runtime.InteropServices;
namespace ARMeilleure.CodeGen

View File

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

View File

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

View File

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

View File

@ -75,9 +75,9 @@ namespace ARMeilleure.CodeGen.X86
{
_stream = stream;
_labels = new Dictionary<Operand, long>();
_jumps = new List<Jump>();
_jumps = [];
_relocs = relocatable ? new List<Reloc>() : null;
_relocs = relocatable ? [] : null;
}
public void MarkLabel(Operand label)
@ -1412,14 +1412,14 @@ namespace ARMeilleure.CodeGen.X86
_stream.Seek(0, SeekOrigin.Begin);
using RecyclableMemoryStream codeStream = MemoryStreamManager.Shared.GetStream();
Assembler assembler = new Assembler(codeStream, HasRelocs);
Assembler assembler = new(codeStream, HasRelocs);
bool hasRelocs = HasRelocs;
int relocIndex = 0;
int relocOffset = 0;
RelocEntry[] relocEntries = hasRelocs
? new RelocEntry[relocs.Length]
: Array.Empty<RelocEntry>();
: [];
for (int i = 0; i < jumps.Length; i++)
{
@ -1471,7 +1471,7 @@ namespace ARMeilleure.CodeGen.X86
_stream.CopyTo(codeStream);
byte[] code = codeStream.ToArray();
RelocInfo relocInfo = new RelocInfo(relocEntries);
RelocInfo relocInfo = new(relocEntries);
return (code, relocInfo);
}

View File

@ -1748,7 +1748,7 @@ namespace ARMeilleure.CodeGen.X86
private static UnwindInfo WritePrologue(CodeGenContext context)
{
List<UnwindPushEntry> pushEntries = new();
List<UnwindPushEntry> pushEntries = [];
Operand rsp = Register(X86Register.Rsp);

View File

@ -40,12 +40,12 @@ namespace ARMeilleure.CodeGen.X86
return 0;
}
ReadOnlySpan<byte> asmGetXcr0 = new byte[]
{
ReadOnlySpan<byte> asmGetXcr0 =
[
0x31, 0xc9, // xor ecx, ecx
0xf, 0x01, 0xd0, // xgetbv
0xc3, // ret
};
0xc3 // ret
];
using MemoryBlock memGetXcr0 = new((ulong)asmGetXcr0.Length);

View File

@ -124,13 +124,13 @@ namespace ARMeilleure.CodeGen.X86
{
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)
{
int stackOffset = stackAlloc.Allocate(OperandType.I32);
node.SetSources(new Operand[] { Const(stackOffset) });
node.SetSources([Const(stackOffset)]);
}
break;
}
@ -253,8 +253,8 @@ namespace ARMeilleure.CodeGen.X86
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
operation.SetDestinations(new Operand[] { rdx, rax });
operation.SetSources(new Operand[] { operation.GetSource(0), rdx, rax, rcx, rbx });
operation.SetDestinations([rdx, rax]);
operation.SetSources([operation.GetSource(0), rdx, rax, rcx, rbx]);
}
else
{
@ -274,7 +274,7 @@ namespace ARMeilleure.CodeGen.X86
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));
@ -303,7 +303,7 @@ namespace ARMeilleure.CodeGen.X86
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;
}
@ -348,7 +348,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
node.SetDestinations(new Operand[] { rdx, rax });
node.SetDestinations([rdx, rax]);
break;
}

View File

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

View File

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

View File

@ -13,7 +13,7 @@ namespace ARMeilleure.CodeGen.X86
public static void RunPass(ControlFlowGraph cfg)
{
Dictionary<ulong, Operand> constants = new Dictionary<ulong, Operand>();
Dictionary<ulong, Operand> constants = new();
Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source)
{

View File

@ -3,52 +3,46 @@ namespace ARMeilleure.Common
public static class AddressTablePresets
{
private static readonly AddressTableLevel[] _levels64Bit =
new AddressTableLevel[]
{
[
new(31, 17),
new(23, 8),
new(15, 8),
new( 7, 8),
new( 2, 5),
};
new( 2, 5)
];
private static readonly AddressTableLevel[] _levels32Bit =
new AddressTableLevel[]
{
[
new(31, 17),
new(23, 8),
new(15, 8),
new( 7, 8),
new( 1, 6),
};
new( 1, 6)
];
private static readonly AddressTableLevel[] _levels64BitSparseTiny =
new AddressTableLevel[]
{
[
new( 11, 28),
new( 2, 9),
};
new( 2, 9)
];
private static readonly AddressTableLevel[] _levels32BitSparseTiny =
new AddressTableLevel[]
{
[
new( 10, 22),
new( 1, 9),
};
new( 1, 9)
];
private static readonly AddressTableLevel[] _levels64BitSparseGiant =
new AddressTableLevel[]
{
[
new( 38, 1),
new( 2, 36),
};
new( 2, 36)
];
private static readonly AddressTableLevel[] _levels32BitSparseGiant =
new AddressTableLevel[]
{
[
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
//low power will never run worse than non-sparse, but for most systems it won't be necessary

View File

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

View File

@ -5,7 +5,7 @@ namespace ARMeilleure.Common
{
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)
{

View File

@ -17,7 +17,7 @@ namespace ARMeilleure.Decoders
public Block()
{
OpCodes = new List<OpCode>();
OpCodes = [];
}
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)
{
List<Block> blocks = new();
List<Block> blocks = [];
Queue<Block> workQueue = new();

View File

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

View File

@ -12,7 +12,7 @@ namespace ARMeilleure.Decoders
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 mask = opCode & 0xf;

View File

@ -29,9 +29,9 @@ namespace ARMeilleure.Decoders
}
}
private static readonly List<InstInfo> _allInstA32 = new();
private static readonly List<InstInfo> _allInstT32 = new();
private static readonly List<InstInfo> _allInstA64 = new();
private static readonly List<InstInfo> _allInstA32 = [];
private static readonly List<InstInfo> _allInstT32 = [];
private static readonly List<InstInfo> _allInstA64 = [];
private static readonly InstInfo[][] _instA32FastLookup = 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++)
{
temp[index] = new List<InstInfo>();
temp[index] = [];
}
foreach (InstInfo inst in allInsts)

View File

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

View File

@ -285,7 +285,7 @@ namespace ARMeilleure.Diagnostics
public static string GetDump(ControlFlowGraph cfg)
{
IRDumper dumper = new IRDumper(1);
IRDumper dumper = new(1);
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{

View File

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

View File

@ -9,8 +9,8 @@ namespace ARMeilleure.Instructions
{
#region "LookUp Tables"
#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,
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,
@ -26,11 +26,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -46,11 +46,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -66,11 +66,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -86,11 +86,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -106,11 +106,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -126,11 +126,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -146,11 +146,11 @@ namespace ARMeilleure.Instructions
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,
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,
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,
@ -166,18 +166,18 @@ namespace ARMeilleure.Instructions
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,
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[]
{
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3,
};
private static ReadOnlySpan<byte> _srPerm =>
[
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
];
private static ReadOnlySpan<byte> _isrPerm => new byte[]
{
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11,
};
private static ReadOnlySpan<byte> _isrPerm =>
[
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
];
#pragma warning restore IDE1006
#endregion

View File

@ -245,8 +245,8 @@ namespace ARMeilleure.Instructions
string name = nameof(Math.Round);
MethodInfo info = (op.Size & 1) == 0
? typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(MidpointRounding) })
: typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(MidpointRounding) });
? typeof(MathF).GetMethod(name, [typeof(float), typeof(MidpointRounding)])
: typeof(Math).GetMethod(name, [typeof(double), typeof(MidpointRounding)]);
return context.Call(info, n, Const((int)roundMode));
}

View File

@ -18,19 +18,19 @@ namespace ARMeilleure.Instructions
static class InstEmitSimdHelper
{
#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
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 | 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;
@ -44,118 +44,118 @@ namespace ARMeilleure.Instructions
#endregion
#region "X86 SSE Intrinsics"
public static readonly Intrinsic[] X86PaddInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PaddInstruction =
[
Intrinsic.X86Paddb,
Intrinsic.X86Paddw,
Intrinsic.X86Paddd,
Intrinsic.X86Paddq,
};
Intrinsic.X86Paddq
];
public static readonly Intrinsic[] X86PcmpeqInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PcmpeqInstruction =
[
Intrinsic.X86Pcmpeqb,
Intrinsic.X86Pcmpeqw,
Intrinsic.X86Pcmpeqd,
Intrinsic.X86Pcmpeqq,
};
Intrinsic.X86Pcmpeqq
];
public static readonly Intrinsic[] X86PcmpgtInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PcmpgtInstruction =
[
Intrinsic.X86Pcmpgtb,
Intrinsic.X86Pcmpgtw,
Intrinsic.X86Pcmpgtd,
Intrinsic.X86Pcmpgtq,
};
Intrinsic.X86Pcmpgtq
];
public static readonly Intrinsic[] X86PmaxsInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PmaxsInstruction =
[
Intrinsic.X86Pmaxsb,
Intrinsic.X86Pmaxsw,
Intrinsic.X86Pmaxsd,
};
Intrinsic.X86Pmaxsd
];
public static readonly Intrinsic[] X86PmaxuInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PmaxuInstruction =
[
Intrinsic.X86Pmaxub,
Intrinsic.X86Pmaxuw,
Intrinsic.X86Pmaxud,
};
Intrinsic.X86Pmaxud
];
public static readonly Intrinsic[] X86PminsInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PminsInstruction =
[
Intrinsic.X86Pminsb,
Intrinsic.X86Pminsw,
Intrinsic.X86Pminsd,
};
Intrinsic.X86Pminsd
];
public static readonly Intrinsic[] X86PminuInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PminuInstruction =
[
Intrinsic.X86Pminub,
Intrinsic.X86Pminuw,
Intrinsic.X86Pminud,
};
Intrinsic.X86Pminud
];
public static readonly Intrinsic[] X86PmovsxInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PmovsxInstruction =
[
Intrinsic.X86Pmovsxbw,
Intrinsic.X86Pmovsxwd,
Intrinsic.X86Pmovsxdq,
};
Intrinsic.X86Pmovsxdq
];
public static readonly Intrinsic[] X86PmovzxInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PmovzxInstruction =
[
Intrinsic.X86Pmovzxbw,
Intrinsic.X86Pmovzxwd,
Intrinsic.X86Pmovzxdq,
};
Intrinsic.X86Pmovzxdq
];
public static readonly Intrinsic[] X86PsllInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PsllInstruction =
[
0,
Intrinsic.X86Psllw,
Intrinsic.X86Pslld,
Intrinsic.X86Psllq,
};
Intrinsic.X86Psllq
];
public static readonly Intrinsic[] X86PsraInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PsraInstruction =
[
0,
Intrinsic.X86Psraw,
Intrinsic.X86Psrad,
};
Intrinsic.X86Psrad
];
public static readonly Intrinsic[] X86PsrlInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PsrlInstruction =
[
0,
Intrinsic.X86Psrlw,
Intrinsic.X86Psrld,
Intrinsic.X86Psrlq,
};
Intrinsic.X86Psrlq
];
public static readonly Intrinsic[] X86PsubInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PsubInstruction =
[
Intrinsic.X86Psubb,
Intrinsic.X86Psubw,
Intrinsic.X86Psubd,
Intrinsic.X86Psubq,
};
Intrinsic.X86Psubq
];
public static readonly Intrinsic[] X86PunpckhInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PunpckhInstruction =
[
Intrinsic.X86Punpckhbw,
Intrinsic.X86Punpckhwd,
Intrinsic.X86Punpckhdq,
Intrinsic.X86Punpckhqdq,
};
Intrinsic.X86Punpckhqdq
];
public static readonly Intrinsic[] X86PunpcklInstruction = new Intrinsic[]
{
public static readonly Intrinsic[] X86PunpcklInstruction =
[
Intrinsic.X86Punpcklbw,
Intrinsic.X86Punpcklwd,
Intrinsic.X86Punpckldq,
Intrinsic.X86Punpcklqdq,
};
Intrinsic.X86Punpcklqdq
];
#endregion
public static void EnterArmFpMode(EmitterContext context, Func<FPState, Operand> getFpFlag)
@ -460,8 +460,8 @@ namespace ARMeilleure.Instructions
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
MethodInfo info = (op.Size & 1) == 0
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float) })
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double) });
? typeof(MathHelperF).GetMethod(name, [typeof(float)])
: typeof(MathHelper).GetMethod(name, [typeof(double)]);
return context.Call(info, n);
}
@ -473,8 +473,8 @@ namespace ARMeilleure.Instructions
string name = nameof(MathHelper.Round);
MethodInfo info = (op.Size & 1) == 0
? typeof(MathHelperF).GetMethod(name, new Type[] { typeof(float), typeof(int) })
: typeof(MathHelper).GetMethod(name, new Type[] { typeof(double), typeof(int) });
? typeof(MathHelperF).GetMethod(name, [typeof(float), typeof(int)])
: typeof(MathHelper).GetMethod(name, [typeof(double), typeof(int)]);
return context.Call(info, n, Const((int)roundMode));
}

View File

@ -12,17 +12,17 @@ namespace ARMeilleure.Instructions
static partial class InstEmit
{
#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,
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 | 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
public static void Dup_Gp(ArmEmitterContext context)
@ -601,7 +601,7 @@ namespace ARMeilleure.Instructions
{
Operand d = GetVec(op.Rd);
List<Operand> args = new();
List<Operand> args = [];
if (!isTbl)
{

View File

@ -13,17 +13,17 @@ namespace ARMeilleure.Instructions
{
#region "Masks"
// 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,
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 | 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
public static void Vmov_I(ArmEmitterContext context)

View File

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

View File

@ -211,7 +211,7 @@ namespace ARMeilleure.Instructions
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]
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).

View File

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

View File

@ -1,4 +1,3 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

View File

@ -304,7 +304,7 @@ namespace ARMeilleure.IntermediateRepresentation
ushort newCount = checked((ushort)(count + 1));
ushort newCapacity = (ushort)Math.Min(capacity * 2, ushort.MaxValue);
Span<T> oldSpan = new Span<T>(data, count);
Span<T> oldSpan = new(data, count);
capacity = newCapacity;
data = Allocators.References.Allocate<T>(capacity);
@ -338,7 +338,7 @@ namespace ARMeilleure.IntermediateRepresentation
throw new OverflowException();
}
Span<T> oldSpan = new Span<T>(data, (int)count);
Span<T> oldSpan = new(data, (int)count);
capacity = newCapacity;
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
{
Span<T> span = new Span<T>(data, count);
Span<T> span = new(data, count);
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
{
Span<T> span = new Span<T>(data, (int)count);
Span<T> span = new(data, (int)count);
for (int i = 0; i < span.Length; i++)
{

View File

@ -7,6 +7,7 @@ namespace ARMeilleure.Memory
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.
public IJitMemoryBlock Block { get; }
public IJitMemoryAllocator Allocator { get; }
public nint Pointer => Block.Pointer;
@ -21,6 +22,7 @@ namespace ARMeilleure.Memory
granularity = DefaultGranularity;
}
Allocator = allocator;
Block = allocator.Reserve(maxSize);
_maxSize = maxSize;
_sizeGranularity = granularity;

View File

@ -1,4 +1,3 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

View File

@ -198,7 +198,7 @@ namespace ARMeilleure.Signal
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;
}
@ -252,7 +252,7 @@ namespace ARMeilleure.Signal
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;
}

View File

@ -1,6 +1,5 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using System;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -30,7 +29,7 @@ namespace ARMeilleure.Signal
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>();
}
@ -47,7 +46,7 @@ namespace ARMeilleure.Signal
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>();
}
@ -76,7 +75,7 @@ namespace ARMeilleure.Signal
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>();
}

View File

@ -1,7 +1,6 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using Ryujinx.Common.Memory.PartialUnmaps;
using System;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;

View File

@ -1,5 +1,4 @@
using ARMeilleure.Memory;
using System;
namespace ARMeilleure.State
{

View File

@ -6,7 +6,6 @@ using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Memory;
using ARMeilleure.State;
using System;
using System.Collections.Generic;
using System.Reflection;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -55,7 +54,7 @@ namespace ARMeilleure.Translation
public Aarch32Mode Mode { get; }
private int _ifThenBlockStateIndex = 0;
private Condition[] _ifThenBlockState = Array.Empty<Condition>();
private Condition[] _ifThenBlockState = [];
public bool IsInIfThenBlock => _ifThenBlockStateIndex < _ifThenBlockState.Length;
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)
{

View File

@ -2,6 +2,8 @@ using ARMeilleure.CodeGen;
using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Memory;
using ARMeilleure.Native;
using Humanizer;
using Ryujinx.Common.Logging;
using Ryujinx.Memory;
using System;
using System.Collections.Generic;
@ -18,18 +20,20 @@ namespace ARMeilleure.Translation.Cache
private static readonly int _pageMask = _pageSize - 1;
private const int CodeAlignment = 4; // Bytes.
private const int CacheSize = 2047 * 1024 * 1024;
private const int CacheSize = 256 * 1024 * 1024;
private static ReservedRegion _jitRegion;
private static JitCacheInvalidation _jitCacheInvalidator;
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 bool _initialized;
private static readonly List<ReservedRegion> _jitRegions = [];
private static int _activeRegionIndex = 0;
[SupportedOSPlatform("windows")]
[LibraryImport("kernel32.dll", SetLastError = true)]
public static partial nint FlushInstructionCache(nint hProcess, nint lpAddress, nuint dwSize);
@ -48,7 +52,9 @@ namespace ARMeilleure.Translation.Cache
return;
}
_jitRegion = new ReservedRegion(allocator, CacheSize);
ReservedRegion firstRegion = new(allocator, CacheSize);
_jitRegions.Add(firstRegion);
_activeRegionIndex = 0;
if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
{
@ -59,7 +65,9 @@ namespace ARMeilleure.Translation.Cache
if (OperatingSystem.IsWindows())
{
JitUnwindWindows.InstallFunctionTableHandler(_jitRegion.Pointer, CacheSize, _jitRegion.Pointer + Allocate(_pageSize));
JitUnwindWindows.InstallFunctionTableHandler(
firstRegion.Pointer, CacheSize, firstRegion.Pointer + Allocate(_pageSize)
);
}
_initialized = true;
@ -75,8 +83,8 @@ namespace ARMeilleure.Translation.Cache
Debug.Assert(_initialized);
int funcOffset = Allocate(code.Length);
nint funcPtr = _jitRegion.Pointer + funcOffset;
ReservedRegion targetRegion = _jitRegions[_activeRegionIndex];
nint funcPtr = targetRegion.Pointer + funcOffset;
if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
@ -90,9 +98,9 @@ namespace ARMeilleure.Translation.Cache
}
else
{
ReprotectAsWritable(funcOffset, code.Length);
ReprotectAsWritable(targetRegion, funcOffset, code.Length);
Marshal.Copy(code, 0, funcPtr, code.Length);
ReprotectAsExecutable(funcOffset, code.Length);
ReprotectAsExecutable(targetRegion, funcOffset, code.Length);
if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
@ -116,51 +124,82 @@ namespace ARMeilleure.Translation.Cache
{
Debug.Assert(_initialized);
int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
foreach (ReservedRegion region in _jitRegions)
{
if (pointer.ToInt64() < region.Pointer.ToInt64() ||
pointer.ToInt64() >= (region.Pointer + CacheSize).ToInt64())
{
continue;
}
int funcOffset = (int)(pointer.ToInt64() - region.Pointer.ToInt64());
if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
{
_cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
_cacheEntries.RemoveAt(entryIndex);
}
return;
}
}
}
private static void ReprotectAsWritable(int offset, int size)
private static void ReprotectAsWritable(ReservedRegion region, int offset, int size)
{
int endOffs = offset + size;
int regionStart = offset & ~_pageMask;
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
_jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
region.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
}
private static void ReprotectAsExecutable(int offset, int size)
private static void ReprotectAsExecutable(ReservedRegion region, int offset, int size)
{
int endOffs = offset + size;
int regionStart = offset & ~_pageMask;
int regionEnd = (endOffs + _pageMask) & ~_pageMask;
_jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
region.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
}
private static int Allocate(int codeSize)
{
codeSize = AlignCodeSize(codeSize);
for (int i = _activeRegionIndex; i < _jitRegions.Count; i++)
{
int allocOffset = _cacheAllocator.Allocate(codeSize);
if (allocOffset < 0)
if (allocOffset >= 0)
{
throw new OutOfMemoryException("JIT Cache exhausted.");
}
_jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
_jitRegions[i].ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
_activeRegionIndex = i;
return allocOffset;
}
}
int exhaustedRegion = _activeRegionIndex;
ReservedRegion newRegion = new(_jitRegions[0].Allocator, CacheSize);
_jitRegions.Add(newRegion);
_activeRegionIndex = _jitRegions.Count - 1;
int newRegionNumber = _activeRegionIndex;
Logger.Warning?.Print(LogClass.Cpu, $"JIT Cache Region {exhaustedRegion} exhausted, creating new Cache Region {newRegionNumber} ({((long)(newRegionNumber + 1) * CacheSize).Bytes()} Total Allocation).");
_cacheAllocator = new CacheMemoryAllocator(CacheSize);
int allocOffsetNew = _cacheAllocator.Allocate(codeSize);
if (allocOffsetNew < 0)
{
throw new OutOfMemoryException("Failed to allocate in new Cache Region!");
}
newRegion.ExpandIfNeeded((ulong)allocOffsetNew + (ulong)codeSize);
return allocOffsetNew;
}
private static int AlignCodeSize(int codeSize)
{
@ -184,6 +223,8 @@ namespace ARMeilleure.Translation.Cache
public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
{
lock (_lock)
{
foreach (ReservedRegion _ in _jitRegions)
{
int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0, default));
@ -199,6 +240,7 @@ namespace ARMeilleure.Translation.Cache
return true;
}
}
}
entry = default;
entryIndex = 0;

View File

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

View File

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

View File

@ -1,5 +1,3 @@
using System;
namespace ARMeilleure.Translation
{
class DelegateInfo

View File

@ -1,5 +1,3 @@
using System;
namespace ARMeilleure.Translation
{
delegate void DispatcherFunction(nint nativeContext, ulong startAddress);

View File

@ -1,5 +1,3 @@
using System;
namespace ARMeilleure.Translation
{
delegate ulong GuestFunction(nint nativeContextPtr);

View File

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

View File

@ -3,6 +3,8 @@ using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Common;
using ARMeilleure.Memory;
using ARMeilleure.State;
using Humanizer;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
@ -31,7 +33,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\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 BackupDir = "1";
@ -154,7 +156,7 @@ namespace ARMeilleure.Translation.PTC
private void InitializeCarriers()
{
_infosStream = MemoryStreamManager.Shared.GetStream();
_codesList = new List<byte[]>();
_codesList = [];
_relocsStream = MemoryStreamManager.Shared.GetStream();
_unwindInfosStream = MemoryStreamManager.Shared.GetStream();
}
@ -184,6 +186,36 @@ namespace ARMeilleure.Translation.PTC
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()
{
string fileNameActual = $"{CachePathActual}.cache";
@ -532,7 +564,7 @@ namespace ARMeilleure.Translation.PTC
public void LoadTranslations(Translator translator)
{
if (AreCarriersEmpty())
if (AreCarriersEmpty() || ContainsBlacklistedFunctions())
{
return;
}
@ -750,7 +782,7 @@ namespace ARMeilleure.Translation.PTC
UnwindInfo unwindInfo,
bool highCq)
{
CompiledFunction cFunc = new CompiledFunction(code, unwindInfo, RelocInfo.Empty);
CompiledFunction cFunc = new(code, unwindInfo, RelocInfo.Empty);
GuestFunction gFunc = cFunc.MapWithPointer<GuestFunction>(out nint gFuncPointer);
return new TranslatedFunction(gFunc, gFuncPointer, callCounter, guestSize, highCq);
@ -765,7 +797,7 @@ namespace ARMeilleure.Translation.PTC
private void StubCode(int index)
{
_codesList[index] = Array.Empty<byte>();
_codesList[index] = [];
}
private void StubReloc(int relocEntriesCount)
@ -835,10 +867,18 @@ namespace ARMeilleure.Translation.PTC
while (profiledFuncsToTranslate.TryDequeue(out (ulong address, PtcProfiler.FuncProfile funcProfile) item))
{
ulong address = item.address;
ExecutionMode executionMode = item.funcProfile.Mode;
bool highCq = item.funcProfile.HighCq;
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);
@ -885,7 +925,10 @@ namespace ARMeilleure.Translation.PTC
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)
{
@ -945,7 +988,7 @@ namespace ARMeilleure.Translation.PTC
WriteCode(code.AsSpan());
// WriteReloc.
using BinaryWriter relocInfoWriter = new BinaryWriter(_relocsStream, EncodingCache.UTF8NoBOM, true);
using BinaryWriter relocInfoWriter = new(_relocsStream, EncodingCache.UTF8NoBOM, true);
foreach (RelocEntry entry in relocInfo.Entries)
{
@ -955,7 +998,7 @@ namespace ARMeilleure.Translation.PTC
}
// WriteUnwindInfo.
using BinaryWriter unwindInfoWriter = new BinaryWriter(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
using BinaryWriter unwindInfoWriter = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true);
unwindInfoWriter.Write(unwindInfo.PushEntries.Length);

View File

@ -50,7 +50,7 @@ namespace ARMeilleure.Translation.PTC
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static List<T> DeserializeList<T>(Stream stream) where T : struct
{
List<T> list = new();
List<T> list = [];
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 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,
};
5518,
];
private const int SaveInterval = 30; // Seconds.
@ -76,20 +78,30 @@ namespace ARMeilleure.Translation.PTC
private void TimerElapsed(object _, ElapsedEventArgs __)
=> 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))
{
Debug.Assert(!highCq);
if (blacklist)
{
lock (_lock)
{
ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false));
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))
{
@ -99,7 +111,7 @@ namespace ARMeilleure.Translation.PTC
{
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)
{
ConcurrentQueue<(ulong address, FuncProfile funcProfile)> profiledFuncsToTranslate = new ConcurrentQueue<(ulong address, FuncProfile funcProfile)>();
ConcurrentQueue<(ulong address, FuncProfile funcProfile)> profiledFuncsToTranslate = new();
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));
}
@ -130,6 +142,22 @@ namespace ARMeilleure.Translation.PTC
ProfiledFuncs.TrimExcess();
}
public List<ulong> GetBlacklistedFunctions()
{
List<ulong> funcs = [];
foreach ((ulong ptr, FuncProfile funcProfile) in ProfiledFuncs)
{
if (!funcProfile.Blacklist)
continue;
if (!funcs.Contains(ptr))
funcs.Add(ptr);
}
return funcs;
}
public void PreLoad()
{
_lastHash = default;
@ -220,13 +248,18 @@ namespace ARMeilleure.Translation.PTC
return false;
}
Func<ulong, FuncProfile, (ulong, FuncProfile)> migrateEntryFunc = null;
switch (outerHeader.InfoFileVersion)
{
case InternalVersion:
ProfiledFuncs = Deserialize(stream);
break;
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;
default:
Logger.Error?.Print(LogClass.Ptc, $"No migration path for {nameof(outerHeader.InfoFileVersion)} '{outerHeader.InfoFileVersion}'. Discarding cache.");
@ -256,6 +289,16 @@ namespace ARMeilleure.Translation.PTC
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)
{
return new(memoryStream.GetBuffer(), (int)memoryStream.Position, (int)memoryStream.Length - (int)memoryStream.Position);
@ -387,13 +430,35 @@ namespace ARMeilleure.Translation.PTC
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 6*/)]
public struct FuncProfile
{
public ExecutionMode Mode;
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;
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,
// 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.
BasicBlock newEntry = new BasicBlock(cfg.Blocks.Count);
BasicBlock newEntry = new(cfg.Blocks.Count);
cfg.UpdateEntry(newEntry);
}

View File

@ -47,7 +47,7 @@ namespace ARMeilleure.Translation
DefMap[] globalDefs = new DefMap[cfg.Blocks.Count];
Operand[] localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
Queue<BasicBlock> dfPhiBlocks = new Queue<BasicBlock>();
Queue<BasicBlock> dfPhiBlocks = new();
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{

View File

@ -1,5 +1,4 @@
using ARMeilleure.Common;
using System;
namespace ARMeilleure.Translation
{

View File

@ -5,7 +5,6 @@ using ARMeilleure.Diagnostics;
using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Memory;
using ARMeilleure.Signal;
using ARMeilleure.State;
using ARMeilleure.Translation.Cache;
using ARMeilleure.Translation.PTC;
@ -222,7 +221,7 @@ namespace ARMeilleure.Translation
internal TranslatedFunction Translate(ulong address, ExecutionMode mode, bool highCq, bool singleStep = false)
{
ArmEmitterContext context = new ArmEmitterContext(
ArmEmitterContext context = new(
Memory,
CountTable,
FunctionTable,
@ -249,6 +248,11 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter);
if (cfg == null)
{
return null;
}
ulong funcSize = funcRange.End - funcRange.Start;
Logger.EndPass(PassName.Translation, cfg);
@ -260,7 +264,7 @@ namespace ARMeilleure.Translation
Logger.EndPass(PassName.RegisterUsage);
OperandType retType = OperandType.I64;
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
OperandType[] argTypes = [OperandType.I64];
CompilerOptions options = highCq ? CompilerOptions.HighCq : CompilerOptions.None;
@ -407,6 +411,11 @@ namespace ARMeilleure.Translation
if (opCode.Instruction.Emitter != null)
{
opCode.Instruction.Emitter(context);
if (opCode.Instruction.Name == InstName.Und && blkIndex == 0)
{
range = new Range(rangeStart, rangeEnd);
return null;
}
}
else
{
@ -478,7 +487,7 @@ namespace ARMeilleure.Translation
public void InvalidateJitCacheRegion(ulong address, ulong size)
{
ulong[] overlapAddresses = Array.Empty<ulong>();
ulong[] overlapAddresses = [];
int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses);

View File

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

View File

@ -4,7 +4,6 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
using ARMeilleure.Translation.Cache;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
@ -142,7 +141,7 @@ namespace ARMeilleure.Translation
/// <returns>Generated <see cref="DispatchStub"/></returns>
private nint GenerateDispatchStub()
{
EmitterContext context = new EmitterContext();
EmitterContext context = new();
Operand lblFallback = Label();
Operand lblEnd = Label();
@ -187,7 +186,7 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64 };
OperandType[] argTypes = [OperandType.I64];
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
@ -200,7 +199,7 @@ namespace ARMeilleure.Translation
/// <returns>Generated <see cref="SlowDispatchStub"/></returns>
private nint GenerateSlowDispatchStub()
{
EmitterContext context = new EmitterContext();
EmitterContext context = new();
// Load the target guest address from the native context.
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
@ -212,7 +211,7 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64 };
OperandType[] argTypes = [OperandType.I64];
GuestFunction func = Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<GuestFunction>();
@ -251,7 +250,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="DispatchLoop"/> function</returns>
private DispatcherFunction GenerateDispatchLoop()
{
EmitterContext context = new EmitterContext();
EmitterContext context = new();
Operand beginLbl = Label();
Operand endLbl = Label();
@ -281,7 +280,7 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.None;
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 };
OperandType[] argTypes = [OperandType.I64, OperandType.I64];
return Compiler.Compile(cfg, argTypes, retType, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DispatcherFunction>();
}
@ -292,7 +291,7 @@ namespace ARMeilleure.Translation
/// <returns><see cref="ContextWrapper"/> function</returns>
private WrapperFunction GenerateContextWrapper()
{
EmitterContext context = new EmitterContext();
EmitterContext context = new();
Operand nativeContext = context.LoadArgument(OperandType.I64, 0);
Operand guestMethod = context.LoadArgument(OperandType.I64, 1);
@ -305,7 +304,7 @@ namespace ARMeilleure.Translation
ControlFlowGraph cfg = context.GetControlFlowGraph();
OperandType retType = OperandType.I64;
OperandType[] argTypes = new[] { OperandType.I64, OperandType.I64 };
OperandType[] argTypes = [OperandType.I64, OperandType.I64];
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();
OperandType[] argTypes = new OperandType[] { OperandType.I64 };
OperandType[] argTypes = [OperandType.I64];
return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<FpFlagsPInvokeTest>();
}

View File

@ -4,7 +4,6 @@ using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
using Ryujinx.Memory;
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Threading;

View File

@ -1,5 +1,4 @@
using Ryujinx.Common.Memory;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

View File

@ -1,4 +1,3 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;

View File

@ -4,7 +4,6 @@ using Ryujinx.Audio.Common;
using Ryujinx.Common.Memory;
using Ryujinx.Memory;
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;

View File

@ -1,7 +1,6 @@
using Ryujinx.Common;
using Ryujinx.Common.Memory;
using System;
using System.Buffers;
using System.Threading;
namespace Ryujinx.Audio.Backends.Common

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,21 +9,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
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[] _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[] _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 = [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[] _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[] _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 = [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[] _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[] _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 = [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[] _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[] _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 = [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; }

View File

@ -9,25 +9,27 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
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[] _targetEarlyDelayLineIndicesTableMono = new int[10] { 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[] _targetOutputFeedbackIndicesTableMono = new int[4] { 0, 1, 2, 3 };
private static readonly int[] _outputEarlyIndicesTableMono = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
private static readonly int[] _targetEarlyDelayLineIndicesTableMono = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableMono = [0, 0, 0, 0];
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[] _targetEarlyDelayLineIndicesTableStereo = new int[10] { 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[] _targetOutputFeedbackIndicesTableStereo = new int[4] { 2, 0, 3, 1 };
private static readonly int[] _outputEarlyIndicesTableStereo = [0, 0, 1, 1, 0, 1, 0, 0, 1, 1];
private static readonly int[] _targetEarlyDelayLineIndicesTableStereo = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableStereo = [0, 0, 1, 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[] _targetEarlyDelayLineIndicesTableQuadraphonic = new int[10] { 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[] _targetOutputFeedbackIndicesTableQuadraphonic = new int[4] { 0, 1, 2, 3 };
private static readonly int[] _outputEarlyIndicesTableQuadraphonic = [0, 0, 1, 1, 0, 1, 2, 2, 3, 3];
private static readonly int[] _targetEarlyDelayLineIndicesTableQuadraphonic = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
private static readonly int[] _outputIndicesTableQuadraphonic = [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[] _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[] _targetOutputFeedbackIndicesTableSurround = new int[Constants.ChannelCountMax] { 0, 1, 2, 3, -1, 3 };
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 = [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 = [0, 1, 2, 3, 4, 5];
private static readonly int[] _targetOutputFeedbackIndicesTableSurround = [0, 1, 2, 3, -1, 3];
public bool Enabled { get; set; }

View File

@ -10,7 +10,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
public static class ResamplerHelper
{
#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,
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,
@ -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,
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,
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,
-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,
@ -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,
-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,
-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,
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,
@ -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,
-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,
-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
#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,
-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,
@ -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,
-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,
-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,
-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,
@ -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,
-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,
-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,
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,
@ -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,
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,
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
private static readonly float[] _normalCurveLut0F;

View File

@ -6,12 +6,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
{
public struct Reverb3dState
{
private readonly float[] _fdnDelayMinTimes = new float[4] { 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[] _decayDelayMaxTimes1 = new float[4] { 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[] _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 };
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 };
private readonly float[] _fdnDelayMinTimes = [5.0f, 6.0f, 13.0f, 14.0f];
private readonly float[] _fdnDelayMaxTimes = [45.704f, 82.782f, 149.94f, 271.58f];
private readonly float[] _decayDelayMaxTimes1 = [17.0f, 13.0f, 9.0f, 7.0f];
private readonly float[] _decayDelayMaxTimes2 = [19.0f, 11.0f, 10.0f, 6.0f];
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 = [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 DecayDelay[] DecayDelays1 { get; }

View File

@ -7,8 +7,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
{
public struct ReverbState
{
private static readonly float[] _fdnDelayTimes = new float[20]
{
private static readonly float[] _fdnDelayTimes =
[
// Room
53.953247f, 79.192566f, 116.238770f, 130.615295f,
// Hall
@ -18,11 +18,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral
47.03f, 71f, 103f, 170f,
// 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
7f, 9f, 13f, 17f,
// Hall
@ -32,11 +32,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral
7f, 7f, 13f, 9f,
// 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
0.0f, 3.5f, 2.8f, 3.9f, 2.7f, 13.4f, 7.9f, 8.4f, 9.9f, 12.0f,
// Chamber
@ -46,11 +46,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral
33.1f, 43.3f, 22.8f, 37.9f, 14.9f, 35.3f, 17.9f, 34.2f, 0.0f, 43.3f,
// 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
0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.70f, 0.68f, 0.68f, 0.68f,
// Chamber
@ -60,11 +60,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral
0.93f, 0.92f, 0.87f, 0.86f, 0.94f, 0.81f, 0.80f, 0.77f, 0.76f, 0.65f,
// 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
12.5f,
// Chamber
@ -74,8 +74,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
// Cathedral
50.0f,
// Disabled
0.0f,
};
0.0f
];
public DelayLine[] FdnDelayLines { get; }
public DecayDelay[] DecayDelays { get; }

View File

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

View File

@ -1,4 +1,3 @@
using System;
using System.Runtime.InteropServices;
using CpuAddress = System.UInt64;
using DspAddress = System.UInt64;

View File

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

View File

@ -106,7 +106,7 @@ namespace Ryujinx.Common.Collections
/// <returns>A list of all RangeNodes sorted by Key Order</returns>
public List<RangeNode<TKey, TValue>> AsList()
{
List<RangeNode<TKey, TValue>> list = new();
List<RangeNode<TKey, TValue>> list = [];
AddToList(Root, list);

View File

@ -139,7 +139,7 @@ namespace Ryujinx.Common.Collections
/// <param name="list">List to add the tree pairs into</param>
public List<KeyValuePair<TKey, TValue>> AsLevelOrderList()
{
List<KeyValuePair<TKey, TValue>> list = new();
List<KeyValuePair<TKey, TValue>> list = [];
Queue<Node<TKey, TValue>> nodes = new();
@ -168,7 +168,7 @@ namespace Ryujinx.Common.Collections
/// <returns>A list of all KeyValuePairs sorted by Key Order</returns>
public List<KeyValuePair<TKey, TValue>> AsList()
{
List<KeyValuePair<TKey, TValue>> list = new();
List<KeyValuePair<TKey, TValue>> list = [];
AddToList(Root, list);

View File

@ -8,7 +8,7 @@ namespace Ryujinx.Common.Configuration
public ModMetadata()
{
Mods = new List<Mod>();
Mods = [];
}
}
}

View File

@ -6,4 +6,16 @@ namespace Ryujinx.Common.Configuration
Unbounded,
Custom
}
public static class VSyncModeExtensions
{
public static VSyncMode Next(this VSyncMode vsync, bool customEnabled = false) =>
vsync switch
{
VSyncMode.Switch => customEnabled ? VSyncMode.Custom : VSyncMode.Unbounded,
VSyncMode.Unbounded => VSyncMode.Switch,
VSyncMode.Custom => VSyncMode.Unbounded,
_ => VSyncMode.Switch
};
}
}

View File

@ -164,7 +164,7 @@ namespace Ryujinx.Common.Extensions
// Not enough data in the current segment, try to peek for the data we need.
T buffer = default;
Span<byte> tempSpan = new Span<byte>(&buffer, sizeof(T));
Span<byte> tempSpan = new(&buffer, sizeof(T));
if (!reader.TryCopyTo(tempSpan))
{

View File

@ -1,5 +1,4 @@
using Microsoft.Win32;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Diagnostics;

View File

@ -1,4 +1,3 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;

View File

@ -0,0 +1,118 @@
using System.Text.RegularExpressions;
namespace Ryujinx.Common.Helper
{
public static partial class Patterns
{
#region Accessors
public static readonly Regex Numeric = NumericRegex();
public static readonly Regex AmdGcn = AmdGcnRegex();
public static readonly Regex NvidiaConsumerClass = NvidiaConsumerClassRegex();
public static readonly Regex DomainLp1Ns = DomainLp1NsRegex();
public static readonly Regex DomainLp1Lp1Npln = DomainLp1Lp1NplnRegex();
public static readonly Regex DomainLp1Znc = DomainLp1ZncRegex();
public static readonly Regex DomainSbApi = DomainSbApiRegex();
public static readonly Regex DomainSbAccounts = DomainSbAccountsRegex();
public static readonly Regex DomainAccounts = DomainAccountsRegex();
public static readonly Regex Module = ModuleRegex();
public static readonly Regex FsSdk = FsSdkRegex();
public static readonly Regex SdkMw = SdkMwRegex();
// ReSharper disable once InconsistentNaming
public static readonly Regex CJK = CJKRegex();
public static readonly Regex LdnPassphrase = LdnPassphraseRegex();
public static readonly Regex CleanText = CleanTextRegex();
#endregion
#region Generated pattern stubs
#region Numeric validation
[GeneratedRegex("[0-9]|.")]
internal static partial Regex NumericRegex();
#endregion
#region GPU names
[GeneratedRegex(
"Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
internal static partial Regex AmdGcnRegex();
[GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")]
internal static partial Regex NvidiaConsumerClassRegex();
#endregion
#region DNS blocking
public static readonly Regex[] BlockedHosts =
[
DomainLp1Ns,
DomainLp1Lp1Npln,
DomainLp1Znc,
DomainSbApi,
DomainSbAccounts,
DomainAccounts
];
const RegexOptions DnsRegexOpts =
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
[GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", DnsRegexOpts)]
internal static partial Regex DomainLp1NsRegex();
[GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", DnsRegexOpts)]
internal static partial Regex DomainLp1Lp1NplnRegex();
[GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", DnsRegexOpts)]
internal static partial Regex DomainLp1ZncRegex();
[GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", DnsRegexOpts)]
internal static partial Regex DomainSbApiRegex();
[GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", DnsRegexOpts)]
internal static partial Regex DomainSbAccountsRegex();
[GeneratedRegex(@"^accounts\.nintendo\.com$", DnsRegexOpts)]
internal static partial Regex DomainAccountsRegex();
#endregion
#region Executable information
[GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
internal static partial Regex ModuleRegex();
[GeneratedRegex(@"sdk_version: ([0-9.]*)")]
internal static partial Regex FsSdkRegex();
[GeneratedRegex(@"SDK MW[ -~]*")]
internal static partial Regex SdkMwRegex();
#endregion
#region CJK
[GeneratedRegex(
"\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
private static partial Regex CJKRegex();
#endregion
[GeneratedRegex("Ryujinx-[0-9a-f]{8}")]
private static partial Regex LdnPassphraseRegex();
[GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
private static partial Regex CleanTextRegex();
#endregion
}
}

View File

@ -0,0 +1,58 @@
using Gommon;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.Common.Helper
{
public class RefEvent<T>
{
public delegate void Handler(ref T arg);
private readonly Lock _subLock = new();
private readonly List<Handler> _subscriptions = [];
public bool HasSubscribers
{
get
{
lock (_subLock)
return _subscriptions.Count != 0;
}
}
public IReadOnlyList<Handler> Subscriptions
{
get
{
lock (_subLock)
return _subscriptions;
}
}
public void Add(Handler subscriber)
{
Guard.Require(subscriber, nameof(subscriber));
lock (_subLock)
_subscriptions.Add(subscriber);
}
public void Remove(Handler subscriber)
{
Guard.Require(subscriber, nameof(subscriber));
lock (_subLock)
_subscriptions.Remove(subscriber);
}
public void Clear()
{
lock (_subLock)
_subscriptions.Clear();
}
public void Call(ref T arg)
{
foreach (Handler subscription in Subscriptions)
subscription(ref arg);
}
}
}

View File

@ -11,13 +11,17 @@ namespace Ryujinx.Common.Helper
public static bool IsWindows => OperatingSystem.IsWindows();
public static bool IsLinux => OperatingSystem.IsLinux();
public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64;
public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64;
public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64;
public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64);
public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64;
public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64);
public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64);
public static bool IsIntelMac => IsMacOS && IsX64;
public static bool IsArmMac => IsMacOS && IsArm;
public static bool IsX64Windows => IsWindows && IsX64;
public static bool IsArmWindows => IsWindows && IsArm;
public static bool IsX64Linux => IsLinux && IsX64;
public static bool IsArmLinux => IsLinux && IsArmMac;
}
}

View File

@ -132,7 +132,7 @@ namespace Ryujinx.Common.Logging
_enabledClasses[index] = true;
}
_logTargets = new List<ILogTarget>();
_logTargets = [];
_time = Stopwatch.StartNew();
@ -203,7 +203,7 @@ namespace Ryujinx.Common.Logging
public static IReadOnlyCollection<LogLevel> GetEnabledLevels()
{
Log?[] logs = new[] { Debug, Info, Warning, Error, Guest, AccessLog, Stub, Trace };
Log?[] logs = [Debug, Info, Warning, Error, Guest, AccessLog, Stub, Trace];
List<LogLevel> levels = new(logs.Length);
foreach (Log? log in logs)
{

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