Compare commits
405 Commits
Author | SHA1 | Date | |
---|---|---|---|
2457cfc911 | |||
515fc32b21 | |||
0684b00b3c | |||
02b5c7ea89 | |||
801b71a128 | |||
12c5f6ee89 | |||
79a1314ee4 | |||
e9848339dd | |||
6e28a4dd13 | |||
7c989f88bd | |||
16fa983704 | |||
40daca5684 | |||
981e0c082d | |||
cebfa54467 | |||
fc20d9b925 | |||
0a75b73fa4 | |||
46b7c905f5 | |||
40f2bd37e3 | |||
9288ffd26d | |||
2cdc82cb91 | |||
6aa8d71588 | |||
9becbd7d72 | |||
e055217292 | |||
fbaf62c230 | |||
b186ec9fc5 | |||
0191e2396a | |||
e96299eef5 | |||
ff53dcf560 | |||
2de78a2d55 | |||
b29ded1d60 | |||
9860bfb2cd | |||
f6ada8d169 | |||
42d31f646d | |||
07fc3ded68 | |||
fd01259d2b | |||
7ffe7f8442 | |||
2b2ce68f07 | |||
bc53d00463 | |||
bddb2a1483 | |||
e3bacfa774 | |||
7c2f07d124 | |||
ede5b3c324 | |||
df5be5812f | |||
bc392e55df | |||
fffc3ed193 | |||
7d160e98fd | |||
bf96bc84a8 | |||
91e4caaa69 | |||
efbd29463d | |||
7608cb37ab | |||
d604e98227 | |||
58907e2c29 | |||
649d372f7d | |||
f9a538bb0f | |||
f92921a6d1 | |||
32d21ddf17 | |||
82f90704a0 | |||
f978d3726a | |||
6f28c4abad | |||
105c9712c1 | |||
4d804ed45e | |||
4a27d29412 | |||
5bd2c58ad6 | |||
cf4c78b9c8 | |||
52aa4b6c22 | |||
5a02433080 | |||
915a0f7173 | |||
0cc266ff19 | |||
9a1b74799d | |||
638f3761f3 | |||
193ca3c9a2 | |||
eb0bb36bbf | |||
0e95a8271a | |||
76b474e97b | |||
27ee86f33b | |||
f7ec310231 | |||
e94d24f508 | |||
2bf4555591 | |||
86de288142 | |||
f35aa8e9d6 | |||
0e8e735a6d | |||
0003a7c118 | |||
2cdcfe46d8 | |||
fe30c03cac | |||
5813b2e354 | |||
af1906ea04 | |||
68848000f7 | |||
d98da47a0f | |||
306f7e93a0 | |||
8954ff3af2 | |||
d2f3adbf69 | |||
d511c845b7 | |||
21c9ac6240 | |||
81c9052847 | |||
9367e3c35d | |||
52cf141874 | |||
8a352df3c6 | |||
c545c59851 | |||
96ea4e8c8e | |||
b8f48bcf64 | |||
6966211e07 | |||
57524a4c8a | |||
f4539c49d8 | |||
12c62fdbc2 | |||
e3c6be5e29 | |||
4741a05df9 | |||
c6676007bf | |||
92b0b7d753 | |||
232237bf28 | |||
c27e453fd3 | |||
0e037d0213 | |||
0dca1fbe12 | |||
35d91a0e58 | |||
a73a5d7e85 | |||
832a5e8852 | |||
96d1f0da2d | |||
597388ecda | |||
1cf6d7b7bb | |||
7bc9d0cdad | |||
dc0dbc50ab | |||
994f4dc77d | |||
c9e297b74c | |||
dd514a115c | |||
7e0b4bd538 | |||
378080eb87 | |||
e8f5e97fa4 | |||
f3873620a3 | |||
986ac9ff83 | |||
42b9c1e8fe | |||
3b375525fb | |||
e6658c133c | |||
5b42a4d2c4 | |||
8f0c89ffd6 | |||
2c9715acf6 | |||
274af65f69 | |||
4ca78eded5 | |||
6cb6b15612 | |||
2725e40838 | |||
c2e4c8f98e | |||
b53e7ffd46 | |||
ac66643346 | |||
21e88f17f6 | |||
5626f2ca1c | |||
402f05b8ef | |||
fb27042e01 | |||
69a9de33d3 | |||
bba51c2eeb | |||
fc26189fe1 | |||
a40c90e7dd | |||
f864a49014 | |||
ecbf303266 | |||
b3bf05356b | |||
cb4b58052f | |||
f8cdd5f484 | |||
22202be394 | |||
17ba217940 | |||
aae4595bdb | |||
880fd3cfcb | |||
f679f25e08 | |||
c2709b3bdd | |||
2b6e81deea | |||
7271f1b18e | |||
5fda543f84 | |||
95c06de4c1 | |||
49c63ea077 | |||
531da8a1c0 | |||
5cbdfbc7a4 | |||
e0544dd9c7 | |||
aa784c3e5e | |||
9205077590 | |||
0ed40c7175 | |||
40d47b7aa2 | |||
ec0bb74968 | |||
42f7f98666 | |||
95bad6995c | |||
3d42995822 | |||
9095941fd1 | |||
ba71141bdc | |||
0a0675a7f6 | |||
a7c6e6a8cf | |||
0bc8151c7e | |||
40c17673f5 | |||
a8950d6ac4 | |||
162798b026 | |||
1b28ecd63e | |||
895d9b53bc | |||
0e06aace45 | |||
adf4ebcd60 | |||
470a8031a4 | |||
5440d4ad5c | |||
dde208b480 | |||
4c3d2d5d75 | |||
fab11ba3f1 | |||
332891b5ff | |||
7df4fcada7 | |||
d6698680be | |||
e5c9838b0b | |||
f8ec878796 | |||
9ff21f9ab6 | |||
aa021085cf | |||
1f5d881860 | |||
1f664100bd | |||
1f5e1ffa80 | |||
264438ff19 | |||
3b8ac1641a | |||
4250732353 | |||
4d1579acbf | |||
6279f5e430 | |||
b7d2bff6aa | |||
7c327fecb3 | |||
cc1a933a2f | |||
dd574146fb | |||
2c94ac455e | |||
e18d258fa0 | |||
36f10df775 | |||
680e548022 | |||
21c4176157 | |||
3b4ff2d6d9 | |||
12504f280c | |||
250fc51374 | |||
206e0882c2 | |||
609abc8b9b | |||
cee7121058 | |||
cd124bda58 | |||
9f12e50a54 | |||
097562bc6c | |||
db4242c5dc | |||
4dd77316f7 | |||
3f98369a17 | |||
c26aeefe03 | |||
666e05f5cb | |||
8d9d508dc7 | |||
e27f5522e2 | |||
add2a9d151 | |||
9e50dd99d7 | |||
0dec91bb42 | |||
d9b63353b0 | |||
eabd0ec93f | |||
138d5dc64a | |||
3e68a87d63 | |||
69b6ef7a4a | |||
40e87c634e | |||
79d1c190db | |||
2bc88467eb | |||
baf8752e74 | |||
d5e4378aea | |||
6dbcdfea47 | |||
c5258cf082 | |||
5c89e22bb9 | |||
11ecff2ff0 | |||
4c3f09644a | |||
e187a8870a | |||
a64fee29dc | |||
9ef94c8292 | |||
915d6d044c | |||
a4780ab33b | |||
a947a45d81 | |||
9db73f74cf | |||
a1efd87c45 | |||
49be977588 | |||
c95be55091 | |||
63dedbda86 | |||
c532118d94 | |||
52d6f2e656 | |||
c9bc4eaf58 | |||
3249f8ff41 | |||
1b41b285ac | |||
f5a6f45b27 | |||
210557951b | |||
4c2d9ff3ff | |||
8198b99935 | |||
460f96967d | |||
7ca779a26d | |||
b5032b3c91 | |||
f0a3dff136 | |||
f659dcb9d8 | |||
a34fb0e939 | |||
21ce8a9b80 | |||
9ecbee8032 | |||
80519af67d | |||
26e30faff3 | |||
0992310b76 | |||
009c1101d2 | |||
ba95ee54ab | |||
4ce4299ca2 | |||
17620d18db | |||
9f1cf6458c | |||
67b4e63cff | |||
c05c688ee8 | |||
b2623dc27d | |||
5131b71437 | |||
7870423671 | |||
b72916fbc1 | |||
da073fce61 | |||
1fc90e57d2 | |||
eafcc314a9 | |||
6e9bd4de13 | |||
05a41b31bc | |||
eed17f963e | |||
c09c0c002d | |||
d56d335c0b | |||
23c844b2aa | |||
81691b9e37 | |||
2dc422bc14 | |||
a80fa5e33f | |||
954e995321 | |||
dad9ab6bb6 | |||
f0562b9c75 | |||
b8556530f2 | |||
4f3af839be | |||
155736c986 | |||
dba908dc78 | |||
ecee34a50c | |||
9b5a0c3889 | |||
80b4972139 | |||
5d85468302 | |||
9b1cc2cec6 | |||
e691622f0a | |||
f663a5cd38 | |||
f7c2e867f4 | |||
cedd200745 | |||
58207685c0 | |||
095ad923ad | |||
f07ae7d53f | |||
c308f09722 | |||
f1eef29409 | |||
1f8d66db7c | |||
c3a5716a95 | |||
1f1e2a7f03 | |||
e54f9dc4b4 | |||
edfd4d70c0 | |||
fc43aecbbd | |||
58d7a1fe97 | |||
7aa430f1a5 | |||
6bf460e104 | |||
efb135b74c | |||
a707842e14 | |||
a5a9b9bc8b | |||
17078ad929 | |||
32450d45de | |||
ed7a0474c6 | |||
fe9c49949a | |||
052b23c83c | |||
e4f68592c3 | |||
1dcd44b94f | |||
61b1ce252f | |||
5f38086f94 | |||
7bae440d3a | |||
f1943fd0b6 | |||
ec8d4f3af5 | |||
b3f0978869 | |||
f614d2c435 | |||
40c9416097 | |||
618c8edc79 | |||
99fc4fa61b | |||
f6d5499a16 | |||
26bf13a65d | |||
96cf242bcf | |||
59755818ef | |||
f8beeeb7d3 | |||
cb250162cb | |||
7528f94536 | |||
43081c16c4 | |||
780627e7b0 | |||
9044cb38d1 | |||
a53cfdab78 | |||
c7f9962dde | |||
296c4a3d01 | |||
e7cf4e6eaf | |||
a1a4771ac1 | |||
2fd819613f | |||
ad6ff6ce99 | |||
dc30d94852 | |||
4f293f8cbe | |||
32a1cd83fd | |||
e3d0ccf8d5 | |||
c14844d12c | |||
7fea26e97e | |||
7b7f62c776 | |||
423dbc8888 | |||
6adf15e479 | |||
2747f12591 | |||
a47824f961 | |||
8474d52778 | |||
dd7a924596 | |||
a76eaf9a9a | |||
009e6bcd1b | |||
eb2cc159fa | |||
bb89e36fd8 | |||
de3134adbe | |||
36d53819a4 | |||
ae4324032a | |||
f449895e6d | |||
410be95ab6 | |||
cff9046fc7 | |||
86fd0643c2 | |||
43a83a401e | |||
f0e27a23a5 | |||
e68650237d | |||
1faff14e73 | |||
784cf9d594 | |||
64263c5218 | |||
065c4e520d | |||
139a930407 | |||
719dc97bbd |
@ -63,6 +63,10 @@ dotnet_code_quality_unused_parameters = all:suggestion
|
|||||||
|
|
||||||
#### C# Coding Conventions ####
|
#### C# Coding Conventions ####
|
||||||
|
|
||||||
|
# Namespace preferences
|
||||||
|
csharp_style_namespace_declarations = block_scoped:warning
|
||||||
|
resharper_csharp_namespace_body = block_scoped
|
||||||
|
|
||||||
# var preferences
|
# var preferences
|
||||||
csharp_style_var_elsewhere = false:silent
|
csharp_style_var_elsewhere = false:silent
|
||||||
csharp_style_var_for_built_in_types = false:silent
|
csharp_style_var_for_built_in_types = false:silent
|
||||||
|
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,43 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug Report
|
|
||||||
about: Something doesn't work correctly in Ryujinx. Game-specific issues should be posted at https://github.com/Ryujinx/Ryujinx-Games-List instead, unless it is a provable regression.
|
|
||||||
#assignees:
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bug Report
|
|
||||||
|
|
||||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
|
||||||
[ Lines between [ ] (square brackets) should be removed before posting. ]
|
|
||||||
|
|
||||||
### What's the issue you encountered?
|
|
||||||
|
|
||||||
[ Describe the issue in detail and what you were doing beforehand. ]</br>
|
|
||||||
[ Did you make any changes related to Ryujinx itself? ]</br>
|
|
||||||
[ If so, make sure to include details relating to what exactly you changed. ]
|
|
||||||
|
|
||||||
### How can the issue be reproduced?
|
|
||||||
|
|
||||||
[ Include a detailed step by step process for recreating your issue. ]
|
|
||||||
|
|
||||||
### Log file
|
|
||||||
|
|
||||||
[ Logs files can be found under ``Logs`` folder in Ryujinx program folder. ]</br>
|
|
||||||
[ If you don't include a crash report in instances of crash related issues, we will ask you one to provide one. ]
|
|
||||||
|
|
||||||
### Environment?
|
|
||||||
|
|
||||||
- Ryujinx version: 1.0.X</br>
|
|
||||||
[ Replace X's with the Ryujinx version at time of crash. ]
|
|
||||||
- Game version: X.X.X</br>
|
|
||||||
[ Replace X's with the game version at time of crash. ]
|
|
||||||
- System Specs:
|
|
||||||
- OS: *(e.g. Windows 10)*
|
|
||||||
- CPU: *(e.g. i7-6700)*
|
|
||||||
- GPU: *(e.g. NVIDIA RTX 2070)*
|
|
||||||
- RAM: *(e.g. 16GiB)*
|
|
||||||
- Applied Mods : [ Yes (Which ones) / No ]
|
|
||||||
|
|
||||||
### Additional context?
|
|
||||||
|
|
||||||
Additional info about your environment:</br>
|
|
||||||
[ Any other information relevant to your issue. ]
|
|
86
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
86
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: File a bug report
|
||||||
|
title: "[Bug]"
|
||||||
|
labels: bug
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: issue
|
||||||
|
attributes:
|
||||||
|
label: Description of the issue
|
||||||
|
description: What's the issue you encountered?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: repro
|
||||||
|
attributes:
|
||||||
|
label: Reproduction steps
|
||||||
|
description: How can the issue be reproduced?
|
||||||
|
placeholder: Describe each step as precisely as possible
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: log
|
||||||
|
attributes:
|
||||||
|
label: Log file
|
||||||
|
description: A log file will help our developers to better diagnose and fix the issue.
|
||||||
|
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: os
|
||||||
|
attributes:
|
||||||
|
label: OS
|
||||||
|
placeholder: "e.g. Windows 10"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: ryujinx-version
|
||||||
|
attributes:
|
||||||
|
label: Ryujinx version
|
||||||
|
placeholder: "e.g. 1.0.470"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: game-version
|
||||||
|
attributes:
|
||||||
|
label: Game version
|
||||||
|
placeholder: "e.g. 1.1.1"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: cpu
|
||||||
|
attributes:
|
||||||
|
label: CPU
|
||||||
|
placeholder: "e.g. i7-6700"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: gpu
|
||||||
|
attributes:
|
||||||
|
label: GPU
|
||||||
|
placeholder: "e.g. NVIDIA RTX 2070"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: ram
|
||||||
|
attributes:
|
||||||
|
label: RAM
|
||||||
|
placeholder: "e.g. 16GB"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: mods
|
||||||
|
attributes:
|
||||||
|
label: List of applied mods
|
||||||
|
placeholder: You can list applied mods here.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: additional-context
|
||||||
|
attributes:
|
||||||
|
label: Additional context?
|
||||||
|
description: |
|
||||||
|
- Additional info about your environment:
|
||||||
|
- Any other information relevant to your issue.
|
||||||
|
validations:
|
||||||
|
required: false
|
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
34
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature Request
|
|
||||||
about: Suggest a new feature for Ryujinx.
|
|
||||||
#assignees:
|
|
||||||
---
|
|
||||||
|
|
||||||
## Feature Request
|
|
||||||
|
|
||||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
|
||||||
[ If you do not have the information needed for a section, replace its contents with "Unknown". ]</br>
|
|
||||||
[ Lines between [ ] (square brackets) are to be removed before posting. ]</br>
|
|
||||||
|
|
||||||
[ Please search for existing [feature requests](https://github.com/Ryujinx/Ryujinx/issues) before you make your own request. ]</br>
|
|
||||||
[ Duplicate requests will be marked as such and you will be referred to the original request. ]
|
|
||||||
|
|
||||||
### What feature are you suggesting?
|
|
||||||
#### Overview:
|
|
||||||
- [ Include the basic, high-level concepts for this feature here. ]
|
|
||||||
|
|
||||||
#### Smaller Details:
|
|
||||||
- [ These may include specific methods of implementation etc. ]
|
|
||||||
|
|
||||||
#### Nature of Request:
|
|
||||||
[ Remove all that do not apply to your request. ]
|
|
||||||
- Addition
|
|
||||||
- [ Ex: Addition of certain original features or features from other community projects. ]
|
|
||||||
- [ If you are suggesting porting features or including features from other projects, include what license they are distributed under and what, if any libraries those project use. ]
|
|
||||||
- Change
|
|
||||||
- Removal
|
|
||||||
- [Ex: Removal of certain features or implementation due to a specific issue/bug or because of low quality code, etc.]
|
|
||||||
|
|
||||||
### Why would this feature be useful?
|
|
||||||
[ If this is a feature for an end-user, how does it benefit the end-user? ]</br>
|
|
||||||
[ If this feature is for developers, what does it add to Ryujinx that did not already exist? ]
|
|
30
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
30
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: Suggest a new feature for Ryujinx.
|
||||||
|
title: "[Feature Request]"
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: overview
|
||||||
|
attributes:
|
||||||
|
label: Overview
|
||||||
|
description: Include the basic, high-level concepts for this feature here.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: details
|
||||||
|
attributes:
|
||||||
|
label: Smaller details
|
||||||
|
description: These may include specific methods of implementation etc.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: request
|
||||||
|
attributes:
|
||||||
|
label: Nature of request
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: feature
|
||||||
|
attributes:
|
||||||
|
label: Why would this feature be useful?
|
||||||
|
validations:
|
||||||
|
required: true
|
@ -1,34 +0,0 @@
|
|||||||
---
|
|
||||||
name: Missing CPU Instruction
|
|
||||||
about: CPU Instruction is missing in Ryujinx.
|
|
||||||
#assignees:
|
|
||||||
---
|
|
||||||
|
|
||||||
## Missing CPU Instruction
|
|
||||||
|
|
||||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
|
||||||
[ If you do not have the information needed for a section, replace its contents with "Unknown". ]</br>
|
|
||||||
[ Lines between [ ] (square brackets) are to be removed before posting. ]
|
|
||||||
|
|
||||||
[ Please search for existing [missing CPU instruction](https://github.com/Ryujinx/Ryujinx/issues) before you make your own issue. ]</br>
|
|
||||||
[ See the following [issue](https://github.com/Ryujinx/Ryujinx/issues/1405) as an example ]</br>
|
|
||||||
[ Duplicate issue will be marked as such and you will be referred to the original request. ]
|
|
||||||
|
|
||||||
### What CPU instruction is missing?
|
|
||||||
|
|
||||||
Requires the *INSTRUCTION* instruction.</br>
|
|
||||||
[ Replace *INSTRUCTION* by the instruction name, e.g. VADDL.U16 ]
|
|
||||||
|
|
||||||
```
|
|
||||||
*
|
|
||||||
```
|
|
||||||
[ Add the undefined instruction error message in the above code block ]
|
|
||||||
|
|
||||||
### Instruction name
|
|
||||||
```
|
|
||||||
*
|
|
||||||
```
|
|
||||||
[ Include the name from [armconverter.com](https://armconverter.com/?disasm) or [shell-storm.org](http://shell-storm.org/online/Online-Assembler-and-Disassembler/?arch=arm64&endianness=big&dis_with_raw=True&dis_with_ins=True) in the above code block ]
|
|
||||||
|
|
||||||
### Required by:
|
|
||||||
[ Add our (games list database)[https://github.com/Ryujinx/Ryujinx-Games-List/issues] links of games who require this instruction ]
|
|
26
.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
name: Missing CPU Instruction
|
||||||
|
description: CPU Instruction is missing in Ryujinx.
|
||||||
|
title: "[CPU]"
|
||||||
|
labels: [cpu, not-implemented]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: instruction
|
||||||
|
attributes:
|
||||||
|
label: CPU instruction
|
||||||
|
description: What CPU instruction is missing?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: name
|
||||||
|
attributes:
|
||||||
|
label: Instruction name
|
||||||
|
description: Include the name from [armconverter.com](https://armconverter.com/?disasm) or [shell-storm.org](http://shell-storm.org/online/Online-Assembler-and-Disassembler/?arch=arm64&endianness=big&dis_with_raw=True&dis_with_ins=True) in the above code block
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: required
|
||||||
|
attributes:
|
||||||
|
label: Required by
|
||||||
|
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
|
||||||
|
validations:
|
||||||
|
required: true
|
35
.github/ISSUE_TEMPLATE/missing_service_call.md
vendored
35
.github/ISSUE_TEMPLATE/missing_service_call.md
vendored
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
name: Missing Service Call
|
|
||||||
about: Service call is missing in Ryujinx.
|
|
||||||
#assignees:
|
|
||||||
---
|
|
||||||
|
|
||||||
## Missing Service Call
|
|
||||||
|
|
||||||
[ If any section does not apply, replace its contents with "N/A". ]</br>
|
|
||||||
[ If you do not have the information needed for a section, replace its contents with "Unknown". ]</br>
|
|
||||||
[ Lines between [ ] (square brackets) are to be removed before posting. ]
|
|
||||||
|
|
||||||
[ Please search for existing [missing service call](https://github.com/Ryujinx/Ryujinx/issues) before you make your own issue. ]</br>
|
|
||||||
[ See the following [issue](https://github.com/Ryujinx/Ryujinx/issues/1431) as an example ]</br>
|
|
||||||
[ Duplicate issue will be marked as such and you will be referred to the original request. ]
|
|
||||||
|
|
||||||
### What service call is missing?
|
|
||||||
|
|
||||||
*SERVICE* *INTERFACE*: *NUMBER* (*NAME*) is not implemented.</br>
|
|
||||||
[ Replace *SERVICE* by the service name, e.g. appletAE ]</br>
|
|
||||||
[ Replace *INTERFACE* by the interface name, e.g. IAllSystemAppletProxiesService ]</br>
|
|
||||||
[ Replace *NUMBER* by the call number, e.g. 100 ]</br>
|
|
||||||
[ Replace *NAME* by the call name, e.g. OpenSystemAppletProxy ]</br>
|
|
||||||
[ e.g. appletAE IAllSystemAppletProxiesService: 100 (OpenSystemAppletProxy) ]
|
|
||||||
|
|
||||||
[ Add related links to the specific call from [Switchbrew](https://switchbrew.org/w/index.php?title=Services_API) and/or [SwIPC](https://reswitched.github.io/SwIPC/) ]
|
|
||||||
|
|
||||||
### Service description
|
|
||||||
```
|
|
||||||
*
|
|
||||||
```
|
|
||||||
[ Include the description/explanation from [Switchbrew](https://switchbrew.org/w/index.php?title=Services_API) and/or [SwIPC](https://reswitched.github.io/SwIPC/) in the above code block ]
|
|
||||||
|
|
||||||
### Required by:
|
|
||||||
[ Add our (games list database)[https://github.com/Ryujinx/Ryujinx-Games-List/issues] links of games who require this call ]
|
|
25
.github/ISSUE_TEMPLATE/missing_service_call.yml
vendored
Normal file
25
.github/ISSUE_TEMPLATE/missing_service_call.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: Missing Service Call
|
||||||
|
description: Service call is missing in Ryujinx.
|
||||||
|
labels: not-implemented
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: instruction
|
||||||
|
attributes:
|
||||||
|
label: Service call
|
||||||
|
description: What service call is missing?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: name
|
||||||
|
attributes:
|
||||||
|
label: Service description
|
||||||
|
description: Include the description/explanation from [Switchbrew](https://switchbrew.org/w/index.php?title=Services_API) and/or [SwIPC](https://reswitched.github.io/SwIPC/) in the above code block
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: required
|
||||||
|
attributes:
|
||||||
|
label: Required by
|
||||||
|
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this service.
|
||||||
|
validations:
|
||||||
|
required: true
|
19
.github/ISSUE_TEMPLATE/missing_shader_instruction.yml
vendored
Normal file
19
.github/ISSUE_TEMPLATE/missing_shader_instruction.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
name: Missing Shader Instruction
|
||||||
|
description: Shader Instruction is missing in Ryujinx.
|
||||||
|
title: "[GPU]"
|
||||||
|
labels: [gpu, not-implemented]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: instruction
|
||||||
|
attributes:
|
||||||
|
label: Shader instruction
|
||||||
|
description: What shader instruction is missing?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: required
|
||||||
|
attributes:
|
||||||
|
label: Required by
|
||||||
|
description: Add links to the [compatibility list page(s)](https://github.com/Ryujinx/Ryujinx-Games-List/issues) of the game(s) that require this instruction.
|
||||||
|
validations:
|
||||||
|
required: true
|
8
.github/assign/audio.yml
vendored
Normal file
8
.github/assign/audio.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- audio
|
11
.github/assign/cpu.yml
vendored
Normal file
11
.github/assign/cpu.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
- LDj3SNuD
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- cpu
|
4
.github/assign/global.yml
vendored
Normal file
4
.github/assign/global.yml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- Ryujinx/developers
|
10
.github/assign/gpu.yml
vendored
Normal file
10
.github/assign/gpu.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- riperiperi
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- gpu
|
11
.github/assign/gui.yml
vendored
Normal file
11
.github/assign/gui.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- Ack77
|
||||||
|
- emmauss
|
||||||
|
- TSRBerry
|
||||||
|
- marysaka
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- gui
|
11
.github/assign/horizon.yml
vendored
Normal file
11
.github/assign/horizon.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- gdkchan
|
||||||
|
- Ack77
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- horizon
|
9
.github/assign/infra.yml
vendored
Normal file
9
.github/assign/infra.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
addReviewers: true
|
||||||
|
|
||||||
|
reviewers:
|
||||||
|
- marysaka
|
||||||
|
- TSRBerry
|
||||||
|
|
||||||
|
filterLabels:
|
||||||
|
include:
|
||||||
|
- infra
|
33
.github/labeler.yml
vendored
Normal file
33
.github/labeler.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
audio: 'src/Ryujinx.Audio*/**'
|
||||||
|
|
||||||
|
cpu:
|
||||||
|
- 'src/ARMeilleure/**'
|
||||||
|
- 'src/Ryujinx.Cpu/**'
|
||||||
|
- 'src/Ryujinx.Memory/**'
|
||||||
|
|
||||||
|
gpu:
|
||||||
|
- 'src/Ryujinx.Graphics.*/**'
|
||||||
|
- 'src/Spv.Generator/**'
|
||||||
|
- 'src/Ryujinx.ShaderTools/**'
|
||||||
|
|
||||||
|
'graphics-backend:opengl': 'src/Ryujinx.Graphics.OpenGL/**'
|
||||||
|
'graphics-backend:vulkan':
|
||||||
|
- 'src/Ryujinx.Graphics.Vulkan/**'
|
||||||
|
- 'src/Spv.Generator/**'
|
||||||
|
|
||||||
|
gui:
|
||||||
|
- 'src/Ryujinx/**'
|
||||||
|
- 'src/Ryujinx.Ui.Common/**'
|
||||||
|
- 'src/Ryujinx.Ui.LocaleGenerator/**'
|
||||||
|
- 'src/Ryujinx.Ava/**'
|
||||||
|
|
||||||
|
horizon:
|
||||||
|
- 'src/Ryujinx.HLE/**'
|
||||||
|
- 'src/Ryujinx.Horizon*/**'
|
||||||
|
|
||||||
|
kernel: 'src/Ryujinx.HLE/HOS/Kernel/**'
|
||||||
|
|
||||||
|
infra:
|
||||||
|
- '.github/**'
|
||||||
|
- 'distribution/**'
|
||||||
|
- 'Directory.Packages.props'
|
112
.github/workflows/build.yml
vendored
112
.github/workflows/build.yml
vendored
@ -3,25 +3,29 @@ name: Build job
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs: {}
|
inputs: {}
|
||||||
#push:
|
|
||||||
# branches: [ master ]
|
|
||||||
# paths-ignore:
|
|
||||||
# - '.github/*'
|
|
||||||
# - '.github/ISSUE_TEMPLATE/**'
|
|
||||||
# - '*.yml'
|
|
||||||
# - 'README.md'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/*'
|
- '.github/**'
|
||||||
- '.github/ISSUE_TEMPLATE/**'
|
|
||||||
- '*.yml'
|
- '*.yml'
|
||||||
|
- '*.json'
|
||||||
|
- '*.config'
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: pr-checks-${{ github.event.number }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
RYUJINX_BASE_VERSION: "1.1.0"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: ${{ matrix.os }} (${{ matrix.configuration }})
|
name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }})
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 45
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
@ -33,7 +37,7 @@ jobs:
|
|||||||
RELEASE_ZIP_OS_NAME: linux_x64
|
RELEASE_ZIP_OS_NAME: linux_x64
|
||||||
|
|
||||||
- os: macOS-latest
|
- os: macOS-latest
|
||||||
OS_NAME: MacOS x64
|
OS_NAME: macOS x64
|
||||||
DOTNET_RUNTIME_IDENTIFIER: osx-x64
|
DOTNET_RUNTIME_IDENTIFIER: osx-x64
|
||||||
RELEASE_ZIP_OS_NAME: osx_x64
|
RELEASE_ZIP_OS_NAME: osx_x64
|
||||||
|
|
||||||
@ -43,47 +47,107 @@ jobs:
|
|||||||
RELEASE_ZIP_OS_NAME: win_x64
|
RELEASE_ZIP_OS_NAME: win_x64
|
||||||
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
env:
|
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
||||||
RYUJINX_BASE_VERSION: "1.1.0"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 7.0.x
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Get git short hash
|
- name: Get git short hash
|
||||||
id: git_short_hash
|
id: git_short_hash
|
||||||
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
run: dotnet build -c "${{ matrix.configuration }}" -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: dotnet test --no-build -c "${{ matrix.configuration }}"
|
run: dotnet test --no-build -c "${{ matrix.configuration }}"
|
||||||
|
|
||||||
- name: Publish Ryujinx
|
- name: Publish Ryujinx
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained true
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Headless.SDL2
|
- name: Publish Ryujinx.Headless.SDL2
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Headless.SDL2 --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained true
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Ava
|
- name: Publish Ryujinx.Ava
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava --self-contained true
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Ava --self-contained true
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
|
- name: Set executable bit
|
||||||
|
run: |
|
||||||
|
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||||
|
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
||||||
|
chmod +x ./publish_ava/Ryujinx.Ava ./publish_ava/Ryujinx.sh
|
||||||
|
if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish
|
path: publish
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
- name: Upload Ryujinx.Headless.SDL2 artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish_sdl2_headless
|
path: publish_sdl2_headless
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Ava artifact
|
- name: Upload Ryujinx.Ava artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
|
||||||
path: publish_ava
|
path: publish_ava
|
||||||
|
if: github.event_name == 'pull_request' && matrix.os != 'macOS-latest'
|
||||||
|
|
||||||
|
build_macos:
|
||||||
|
name: macOS Universal (${{ matrix.configuration }})
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
configuration: [ Debug, Release ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Setup LLVM 14
|
||||||
|
run: |
|
||||||
|
wget https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x llvm.sh
|
||||||
|
sudo ./llvm.sh 14
|
||||||
|
|
||||||
|
- name: Install rcodesign
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
|
||||||
|
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
|
||||||
|
rm apple-codesign.tar.gz
|
||||||
|
mv rcodesign $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get git short hash
|
||||||
|
id: git_short_hash
|
||||||
|
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Publish macOS
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
|
- name: Upload Ryujinx.Ava artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
|
path: "publish_ava/*.tar.gz"
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
172
.github/workflows/flatpak.yml
vendored
Normal file
172
.github/workflows/flatpak.yml
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
name: Flatpak release job
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
ryujinx_version:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
|
||||||
|
concurrency: flatpak-release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||||
|
GIT_COMMITTER_NAME: "RyujinxBot"
|
||||||
|
GIT_COMMITTER_EMAIL: "61127645+RyujinxBot@users.noreply.github.com"
|
||||||
|
RYUJINX_PROJECT_FILE: "src/Ryujinx/Ryujinx.csproj"
|
||||||
|
NUGET_SOURCES_DESTDIR: "nuget-sources"
|
||||||
|
RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: Ryujinx
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
global-json-file: Ryujinx/global.json
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
working-directory: Ryujinx
|
||||||
|
run: |
|
||||||
|
echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: flathub/org.ryujinx.Ryujinx
|
||||||
|
token: ${{ secrets.RYUJINX_BOT_PAT }}
|
||||||
|
submodules: recursive
|
||||||
|
path: flathub
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: python -m pip install PyYAML lxml
|
||||||
|
|
||||||
|
- name: Restore Nuget packages
|
||||||
|
run: dotnet restore Ryujinx/${{ env.RYUJINX_PROJECT_FILE }}
|
||||||
|
|
||||||
|
- name: Generate nuget_sources.json
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
from pathlib import Path
|
||||||
|
import base64
|
||||||
|
import binascii
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
sources = []
|
||||||
|
|
||||||
|
for path in Path(os.environ['NUGET_PACKAGES']).glob('**/*.nupkg.sha512'):
|
||||||
|
name = path.parent.parent.name
|
||||||
|
version = path.parent.name
|
||||||
|
filename = '{}.{}.nupkg'.format(name, version)
|
||||||
|
url = 'https://api.nuget.org/v3-flatcontainer/{}/{}/{}'.format(name, version, filename)
|
||||||
|
|
||||||
|
with path.open() as fp:
|
||||||
|
sha512 = binascii.hexlify(base64.b64decode(fp.read())).decode('ascii')
|
||||||
|
|
||||||
|
sources.append({
|
||||||
|
'type': 'file',
|
||||||
|
'url': url,
|
||||||
|
'sha512': sha512,
|
||||||
|
'dest': os.environ['NUGET_SOURCES_DESTDIR'],
|
||||||
|
'dest-filename': filename,
|
||||||
|
})
|
||||||
|
|
||||||
|
with open('flathub/nuget_sources.json', 'w') as fp:
|
||||||
|
json.dump(sources, fp, indent=4)
|
||||||
|
|
||||||
|
- name: Update flatpak metadata
|
||||||
|
id: metadata
|
||||||
|
env:
|
||||||
|
RYUJINX_GIT_HASH: ${{ steps.version_info.outputs.git_hash }}
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
from datetime import datetime
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
|
||||||
|
# Ensure we don't destroy multiline strings
|
||||||
|
def str_presenter(dumper, data):
|
||||||
|
if len(data.splitlines()) > 1:
|
||||||
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
|
||||||
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
|
||||||
|
|
||||||
|
|
||||||
|
yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
|
||||||
|
|
||||||
|
yaml_file = "flathub/org.ryujinx.Ryujinx.yml"
|
||||||
|
xml_file = "flathub/org.ryujinx.Ryujinx.appdata.xml"
|
||||||
|
|
||||||
|
with open(yaml_file, "r") as f:
|
||||||
|
data = yaml.safe_load(f)
|
||||||
|
|
||||||
|
for source in data["modules"][0]["sources"]:
|
||||||
|
if type(source) is str:
|
||||||
|
continue
|
||||||
|
if (
|
||||||
|
source["type"] == "git"
|
||||||
|
and source["url"] == "https://github.com/Ryujinx/Ryujinx.git"
|
||||||
|
):
|
||||||
|
source["commit"] = os.environ['RYUJINX_GIT_HASH']
|
||||||
|
|
||||||
|
is_same_version = data["modules"][0]["build-options"]["env"]["RYUJINX_VERSION"] == os.environ['RYUJINX_VERSION']
|
||||||
|
|
||||||
|
with open(os.environ['GITHUB_OUTPUT'], "a") as gh_out:
|
||||||
|
if is_same_version:
|
||||||
|
gh_out.write(f"commit_message=Retry update to {os.environ['RYUJINX_VERSION']}")
|
||||||
|
else:
|
||||||
|
gh_out.write(f"commit_message=Update to {os.environ['RYUJINX_VERSION']}")
|
||||||
|
|
||||||
|
if not is_same_version:
|
||||||
|
data["modules"][0]["build-options"]["env"]["RYUJINX_VERSION"] = os.environ['RYUJINX_VERSION']
|
||||||
|
|
||||||
|
with open(yaml_file, "w") as f:
|
||||||
|
yaml.safe_dump(data, f, sort_keys=False)
|
||||||
|
|
||||||
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
|
tree = etree.parse(xml_file, parser)
|
||||||
|
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
releases = root.find("releases")
|
||||||
|
|
||||||
|
element = etree.Element("release")
|
||||||
|
element.set("version", os.environ['RYUJINX_VERSION'])
|
||||||
|
element.set("date", datetime.now().date().isoformat())
|
||||||
|
releases.insert(0, element)
|
||||||
|
|
||||||
|
# Ensure 4 spaces
|
||||||
|
etree.indent(root, space=" ")
|
||||||
|
|
||||||
|
with open(xml_file, "wb") as f:
|
||||||
|
f.write(
|
||||||
|
etree.tostring(
|
||||||
|
tree,
|
||||||
|
pretty_print=True,
|
||||||
|
encoding="UTF-8",
|
||||||
|
doctype='<?xml version="1.0" encoding="UTF-8"?>',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
- name: Push flatpak update
|
||||||
|
working-directory: flathub
|
||||||
|
env:
|
||||||
|
COMMIT_MESSAGE: ${{ steps.metadata.outputs.commit_message }}
|
||||||
|
run: |
|
||||||
|
git config user.name "${{ env.GIT_COMMITTER_NAME }}"
|
||||||
|
git config user.email "${{ env.GIT_COMMITTER_EMAIL }}"
|
||||||
|
git add .
|
||||||
|
git commit -m "$COMMIT_MESSAGE"
|
||||||
|
git push origin master
|
1
.github/workflows/nightly_pr_comment.yml
vendored
1
.github/workflows/nightly_pr_comment.yml
vendored
@ -7,6 +7,7 @@ jobs:
|
|||||||
pr_comment:
|
pr_comment:
|
||||||
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@v6
|
- uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
|
54
.github/workflows/pr_triage.yml
vendored
Normal file
54
.github/workflows/pr_triage.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
name: "Pull Request Triage"
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, ready_for_review]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Update labels based on changes
|
||||||
|
uses: actions/labeler@v4
|
||||||
|
with:
|
||||||
|
sync-labels: true
|
||||||
|
dot: true
|
||||||
|
|
||||||
|
- name: Auto Assign [Audio]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/audio.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [CPU]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/cpu.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [GPU]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gpu.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [GUI]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/gui.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Horizon]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/horizon.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Infra]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/infra.yml'
|
||||||
|
|
||||||
|
- name: Auto Assign [Global]
|
||||||
|
uses: kentaro-m/auto-assign-action@v1.2.5
|
||||||
|
with:
|
||||||
|
configuration-path: '.github/assign/global.yml'
|
187
.github/workflows/release.yml
vendored
187
.github/workflows/release.yml
vendored
@ -6,17 +6,14 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/*'
|
- '.github/**'
|
||||||
- '.github/ISSUE_TEMPLATE/**'
|
|
||||||
- '*.yml'
|
- '*.yml'
|
||||||
|
- '*.json'
|
||||||
|
- '*.config'
|
||||||
- 'README.md'
|
- 'README.md'
|
||||||
|
|
||||||
concurrency: release
|
concurrency: release
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: windows-latest
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
@ -25,77 +22,109 @@ jobs:
|
|||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryujinx"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tag:
|
||||||
|
name: Create tag
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Create tag
|
||||||
|
uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
github.rest.git.createRef({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||||
|
sha: context.sha
|
||||||
|
})
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Release ${{ matrix.OS_NAME }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ ubuntu-latest, windows-latest ]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
OS_NAME: Linux x64
|
||||||
|
DOTNET_RUNTIME_IDENTIFIER: linux-x64
|
||||||
|
RELEASE_ZIP_OS_NAME: linux_x64
|
||||||
|
|
||||||
|
- os: windows-latest
|
||||||
|
OS_NAME: Windows x64
|
||||||
|
DOTNET_RUNTIME_IDENTIFIER: win10-x64
|
||||||
|
RELEASE_ZIP_OS_NAME: win_x64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 7.0.x
|
global-json-file: global.json
|
||||||
|
|
||||||
- name: Get version info
|
- name: Get version info
|
||||||
id: version_info
|
id: version_info
|
||||||
run: |
|
run: |
|
||||||
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Configure for release
|
- name: Configure for release
|
||||||
run: |
|
run: |
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' Ryujinx.Common/ReleaseInformation.cs
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Create output dir
|
- name: Create output dir
|
||||||
run: "mkdir release_output"
|
run: "mkdir release_output"
|
||||||
- name: Publish Windows
|
|
||||||
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r win10-x64 -o ./publish_windows/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx --self-contained true
|
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_gtk/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained true
|
||||||
dotnet publish -c Release -r win10-x64 -o ./publish_windows_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Headless.SDL2 --self-contained true
|
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained true
|
||||||
dotnet publish -c Release -r win10-x64 -o ./publish_windows_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Ava --self-contained true
|
dotnet publish -c Release -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Ava --self-contained true
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_windows
|
pushd publish_gtk
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_windows_sdl2_headless
|
pushd publish_sdl2_headless
|
||||||
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_windows_ava
|
pushd publish_ava
|
||||||
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
7z a ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip publish
|
||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Publish Linux
|
|
||||||
run: |
|
|
||||||
dotnet publish -c Release -r linux-x64 -o ./publish_linux/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx --self-contained true
|
|
||||||
dotnet publish -c Release -r linux-x64 -o ./publish_linux_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Headless.SDL2 --self-contained true
|
|
||||||
dotnet publish -c Release -r linux-x64 -o ./publish_linux_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded Ryujinx.Ava --self-contained true
|
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pushd publish_linux
|
pushd publish_gtk
|
||||||
tar --exclude "publish/Ryujinx" --exclude "publish/Ryujinx.sh" -cvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
|
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx" "publish/Ryujinx"
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
|
|
||||||
gzip -9 < ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
|
|
||||||
rm ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_linux_sdl2_headless
|
pushd publish_sdl2_headless
|
||||||
tar --exclude "publish/Ryujinx.Headless.SDL2" --exclude "publish/Ryujinx.sh" -cvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
|
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
|
tar -czvf ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
|
|
||||||
gzip -9 < ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
|
|
||||||
rm ../release_output/sdl2-ryujinx-headless-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_linux_ava
|
pushd publish_ava
|
||||||
tar --exclude "publish/Ryujinx.Ava" --exclude "publish/Ryujinx.sh" -cvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar publish
|
chmod +x publish/Ryujinx.sh publish/Ryujinx.Ava
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.Ava" "publish/Ryujinx.Ava"
|
tar -czvf ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz publish
|
||||||
python3 ../distribution/misc/add_tar_exec.py ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar "publish/Ryujinx.sh" "publish/Ryujinx.sh"
|
|
||||||
gzip -9 < ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar > ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz
|
|
||||||
rm ../release_output/test-ava-ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar
|
|
||||||
popd
|
popd
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
@ -105,10 +134,78 @@ jobs:
|
|||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "For more informations about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
|
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
|
||||||
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
removeArtifacts: true
|
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
token: ${{ secrets.RELEASE_TOKEN }}
|
token: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
|
||||||
|
macos_release:
|
||||||
|
name: Release MacOS universal
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
global-json-file: global.json
|
||||||
|
|
||||||
|
- name: Setup LLVM 14
|
||||||
|
run: |
|
||||||
|
wget https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x llvm.sh
|
||||||
|
sudo ./llvm.sh 14
|
||||||
|
|
||||||
|
- name: Install rcodesign
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.bin
|
||||||
|
gh release download -R indygreg/apple-platform-rs -O apple-codesign.tar.gz -p 'apple-codesign-*-x86_64-unknown-linux-musl.tar.gz'
|
||||||
|
tar -xzvf apple-codesign.tar.gz --wildcards '*/rcodesign' --strip-components=1
|
||||||
|
rm apple-codesign.tar.gz
|
||||||
|
mv rcodesign $HOME/.bin/
|
||||||
|
echo "$HOME/.bin" >> $GITHUB_PATH
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get version info
|
||||||
|
id: version_info
|
||||||
|
run: |
|
||||||
|
echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Configure for release
|
||||||
|
run: |
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_VERSION\%\%/${{ steps.version_info.outputs.build_version }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_BUILD_GIT_HASH\%\%/${{ steps.version_info.outputs.git_short_hash }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_NAME\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_NAME }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_OWNER\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Publish macOS
|
||||||
|
run: |
|
||||||
|
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
|
||||||
|
|
||||||
|
- name: Pushing new release
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
|
artifacts: "publish_ava/*.tar.gz"
|
||||||
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
|
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
|
||||||
|
omitBodyDuringUpdate: true
|
||||||
|
allowUpdates: true
|
||||||
|
replacesArtifacts: true
|
||||||
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
|
token: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
|
||||||
|
flatpak_release:
|
||||||
|
uses: ./.github/workflows/flatpak.yml
|
||||||
|
needs: release
|
||||||
|
with:
|
||||||
|
ryujinx_version: "1.1.${{ github.run_number }}"
|
||||||
|
secrets: inherit
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -170,3 +170,6 @@ launchSettings.json
|
|||||||
|
|
||||||
# NetCore Publishing Profiles
|
# NetCore Publishing Profiles
|
||||||
PublishProfiles/
|
PublishProfiles/
|
||||||
|
|
||||||
|
# Glade backup files
|
||||||
|
*.glade~
|
||||||
|
@ -1,173 +0,0 @@
|
|||||||
using ARMeilleure.IntermediateRepresentation;
|
|
||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace ARMeilleure.CodeGen.Arm64
|
|
||||||
{
|
|
||||||
static class CodeGenCommon
|
|
||||||
{
|
|
||||||
public const int TcAddressRegister = 8;
|
|
||||||
public const int ReservedRegister = 17;
|
|
||||||
|
|
||||||
public static bool ConstFitsOnSImm7(int value, int scale)
|
|
||||||
{
|
|
||||||
return (((value >> scale) << 25) >> (25 - scale)) == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ConstFitsOnSImm9(int value)
|
|
||||||
{
|
|
||||||
return ((value << 23) >> 23) == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ConstFitsOnUImm12(int value)
|
|
||||||
{
|
|
||||||
return (value & 0xfff) == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool ConstFitsOnUImm12(int value, OperandType type)
|
|
||||||
{
|
|
||||||
int scale = Assembler.GetScaleForType(type);
|
|
||||||
return (((value >> scale) & 0xfff) << scale) == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR)
|
|
||||||
{
|
|
||||||
ulong value = operand.Value;
|
|
||||||
|
|
||||||
if (operand.Type == OperandType.I32)
|
|
||||||
{
|
|
||||||
value |= value << 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TryEncodeBitMask(value, out immN, out immS, out immR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryEncodeBitMask(ulong value, out int immN, out int immS, out int immR)
|
|
||||||
{
|
|
||||||
// Some special values also can't be encoded:
|
|
||||||
// 0 can't be encoded because we need to subtract 1 from onesCount (which would became negative if 0).
|
|
||||||
// A value with all bits set can't be encoded because it is reserved according to the spec, because:
|
|
||||||
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
|
||||||
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
|
||||||
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
|
||||||
if (value == ulong.MaxValue)
|
|
||||||
{
|
|
||||||
immN = 0;
|
|
||||||
immS = 0;
|
|
||||||
immR = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bitLength = CountSequence(value);
|
|
||||||
|
|
||||||
if ((value >> bitLength) != 0)
|
|
||||||
{
|
|
||||||
bitLength += CountSequence(value >> bitLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bitLengthLog2 = BitOperations.Log2((uint)bitLength);
|
|
||||||
int bitLengthPow2 = 1 << bitLengthLog2;
|
|
||||||
|
|
||||||
if (bitLengthPow2 < bitLength)
|
|
||||||
{
|
|
||||||
bitLengthLog2++;
|
|
||||||
bitLengthPow2 <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int selectedESize = 64;
|
|
||||||
int repetitions = 1;
|
|
||||||
int onesCount = BitOperations.PopCount(value);
|
|
||||||
|
|
||||||
if (bitLengthPow2 < 64 && (value >> bitLengthPow2) != 0)
|
|
||||||
{
|
|
||||||
for (int eSizeLog2 = bitLengthLog2; eSizeLog2 < 6; eSizeLog2++)
|
|
||||||
{
|
|
||||||
bool match = true;
|
|
||||||
int eSize = 1 << eSizeLog2;
|
|
||||||
ulong mask = (1UL << eSize) - 1;
|
|
||||||
ulong eValue = value & mask;
|
|
||||||
|
|
||||||
for (int e = 1; e < 64 / eSize; e++)
|
|
||||||
{
|
|
||||||
if (((value >> (e * eSize)) & mask) != eValue)
|
|
||||||
{
|
|
||||||
match = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
|
||||||
{
|
|
||||||
selectedESize = eSize;
|
|
||||||
repetitions = 64 / eSize;
|
|
||||||
onesCount = BitOperations.PopCount(eValue);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find rotation. We have two cases, one where the highest bit is 0
|
|
||||||
// and one where it is 1.
|
|
||||||
// If it's 1, we just need to count the number of 1 bits on the MSB to find the right rotation.
|
|
||||||
// If it's 0, we just need to count the number of 0 bits on the LSB to find the left rotation,
|
|
||||||
// then we can convert it to the right rotation shift by subtracting the value from the element size.
|
|
||||||
int rotation;
|
|
||||||
long vHigh = (long)(value << (64 - selectedESize));
|
|
||||||
if (vHigh < 0)
|
|
||||||
{
|
|
||||||
rotation = BitOperations.LeadingZeroCount(~(ulong)vHigh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rotation = (selectedESize - BitOperations.TrailingZeroCount(value)) & (selectedESize - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconstruct value and see if it matches. If not, we can't encode.
|
|
||||||
ulong reconstructed = onesCount == 64 ? ulong.MaxValue : RotateRight((1UL << onesCount) - 1, rotation, selectedESize);
|
|
||||||
|
|
||||||
for (int bit = 32; bit >= selectedESize; bit >>= 1)
|
|
||||||
{
|
|
||||||
reconstructed |= reconstructed << bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reconstructed != value || onesCount == 0)
|
|
||||||
{
|
|
||||||
immN = 0;
|
|
||||||
immS = 0;
|
|
||||||
immR = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
immR = rotation;
|
|
||||||
|
|
||||||
// immN indicates that there are no repetitions.
|
|
||||||
// The MSB of immS indicates the amount of repetitions, and the LSB the number of bits set.
|
|
||||||
if (repetitions == 1)
|
|
||||||
{
|
|
||||||
immN = 1;
|
|
||||||
immS = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
immN = 0;
|
|
||||||
immS = (0xf80 >> BitOperations.Log2((uint)repetitions)) & 0x3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
immS |= onesCount - 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int CountSequence(ulong value)
|
|
||||||
{
|
|
||||||
return BitOperations.TrailingZeroCount(value) + BitOperations.TrailingZeroCount(~value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ulong RotateRight(ulong bits, int shift, int size)
|
|
||||||
{
|
|
||||||
return (bits >> shift) | ((bits << (size - shift)) & (size == 64 ? ulong.MaxValue : (1UL << size) - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
|||||||
namespace ARMeilleure.Decoders;
|
|
||||||
|
|
||||||
interface IOpCode32Exception
|
|
||||||
{
|
|
||||||
int Id { get; }
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
namespace ARMeilleure.Decoders
|
|
||||||
{
|
|
||||||
interface IOpCodeLit : IOpCode
|
|
||||||
{
|
|
||||||
int Rt { get; }
|
|
||||||
long Immediate { get; }
|
|
||||||
int Size { get; }
|
|
||||||
bool Signed { get; }
|
|
||||||
bool Prefetch { get; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
namespace ARMeilleure.Decoders
|
|
||||||
{
|
|
||||||
class OpCodeMemLit : OpCode, IOpCodeLit
|
|
||||||
{
|
|
||||||
public int Rt { get; }
|
|
||||||
public long Immediate { get; }
|
|
||||||
public int Size { get; }
|
|
||||||
public bool Signed { get; }
|
|
||||||
public bool Prefetch { get; }
|
|
||||||
|
|
||||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeMemLit(inst, address, opCode);
|
|
||||||
|
|
||||||
public OpCodeMemLit(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
|
||||||
{
|
|
||||||
Rt = opCode & 0x1f;
|
|
||||||
|
|
||||||
Immediate = (long)address + DecoderHelper.DecodeImmS19_2(opCode);
|
|
||||||
|
|
||||||
switch ((opCode >> 30) & 3)
|
|
||||||
{
|
|
||||||
case 0: Size = 2; Signed = false; Prefetch = false; break;
|
|
||||||
case 1: Size = 3; Signed = false; Prefetch = false; break;
|
|
||||||
case 2: Size = 2; Signed = true; Prefetch = false; break;
|
|
||||||
case 3: Size = 0; Signed = false; Prefetch = true; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
namespace ARMeilleure.Decoders
|
|
||||||
{
|
|
||||||
class OpCodeSimdMemMs : OpCodeMemReg, IOpCodeSimd
|
|
||||||
{
|
|
||||||
public int Reps { get; }
|
|
||||||
public int SElems { get; }
|
|
||||||
public int Elems { get; }
|
|
||||||
public bool WBack { get; }
|
|
||||||
|
|
||||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemMs(inst, address, opCode);
|
|
||||||
|
|
||||||
public OpCodeSimdMemMs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
|
||||||
{
|
|
||||||
switch ((opCode >> 12) & 0xf)
|
|
||||||
{
|
|
||||||
case 0b0000: Reps = 1; SElems = 4; break;
|
|
||||||
case 0b0010: Reps = 4; SElems = 1; break;
|
|
||||||
case 0b0100: Reps = 1; SElems = 3; break;
|
|
||||||
case 0b0110: Reps = 3; SElems = 1; break;
|
|
||||||
case 0b0111: Reps = 1; SElems = 1; break;
|
|
||||||
case 0b1000: Reps = 1; SElems = 2; break;
|
|
||||||
case 0b1010: Reps = 2; SElems = 1; break;
|
|
||||||
|
|
||||||
default: Instruction = InstDescriptor.Undefined; return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size = (opCode >> 10) & 3;
|
|
||||||
WBack = ((opCode >> 23) & 1) != 0;
|
|
||||||
|
|
||||||
bool q = ((opCode >> 30) & 1) != 0;
|
|
||||||
|
|
||||||
if (!q && Size == 3 && SElems != 1)
|
|
||||||
{
|
|
||||||
Instruction = InstDescriptor.Undefined;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Extend64 = false;
|
|
||||||
|
|
||||||
RegisterSize = q
|
|
||||||
? RegisterSize.Simd128
|
|
||||||
: RegisterSize.Simd64;
|
|
||||||
|
|
||||||
Elems = (GetBitsCount() >> 3) >> Size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
namespace ARMeilleure.Decoders
|
|
||||||
{
|
|
||||||
class OpCodeSimdMemSs : OpCodeMemReg, IOpCodeSimd
|
|
||||||
{
|
|
||||||
public int SElems { get; }
|
|
||||||
public int Index { get; }
|
|
||||||
public bool Replicate { get; }
|
|
||||||
public bool WBack { get; }
|
|
||||||
|
|
||||||
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeSimdMemSs(inst, address, opCode);
|
|
||||||
|
|
||||||
public OpCodeSimdMemSs(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
|
||||||
{
|
|
||||||
int size = (opCode >> 10) & 3;
|
|
||||||
int s = (opCode >> 12) & 1;
|
|
||||||
int sElems = (opCode >> 12) & 2;
|
|
||||||
int scale = (opCode >> 14) & 3;
|
|
||||||
int l = (opCode >> 22) & 1;
|
|
||||||
int q = (opCode >> 30) & 1;
|
|
||||||
|
|
||||||
sElems |= (opCode >> 21) & 1;
|
|
||||||
|
|
||||||
sElems++;
|
|
||||||
|
|
||||||
int index = (q << 3) | (s << 2) | size;
|
|
||||||
|
|
||||||
switch (scale)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
if ((size & 1) != 0)
|
|
||||||
{
|
|
||||||
Instruction = InstDescriptor.Undefined;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
index >>= 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
if ((size & 2) != 0 ||
|
|
||||||
((size & 1) != 0 && s != 0))
|
|
||||||
{
|
|
||||||
Instruction = InstDescriptor.Undefined;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size & 1) != 0)
|
|
||||||
{
|
|
||||||
index >>= 3;
|
|
||||||
|
|
||||||
scale = 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index >>= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
if (l == 0 || s != 0)
|
|
||||||
{
|
|
||||||
Instruction = InstDescriptor.Undefined;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
scale = size;
|
|
||||||
|
|
||||||
Replicate = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Index = index;
|
|
||||||
SElems = sElems;
|
|
||||||
Size = scale;
|
|
||||||
|
|
||||||
Extend64 = false;
|
|
||||||
|
|
||||||
WBack = ((opCode >> 23) & 1) != 0;
|
|
||||||
|
|
||||||
RegisterSize = q != 0
|
|
||||||
? RegisterSize.Simd128
|
|
||||||
: RegisterSize.Simd64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
namespace ARMeilleure.IntermediateRepresentation
|
|
||||||
{
|
|
||||||
enum Comparison
|
|
||||||
{
|
|
||||||
Equal = 0,
|
|
||||||
NotEqual = 1,
|
|
||||||
Greater = 2,
|
|
||||||
LessOrEqual = 3,
|
|
||||||
GreaterUI = 4,
|
|
||||||
LessOrEqualUI = 5,
|
|
||||||
GreaterOrEqual = 6,
|
|
||||||
Less = 7,
|
|
||||||
GreaterOrEqualUI = 8,
|
|
||||||
LessUI = 9
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ComparisonExtensions
|
|
||||||
{
|
|
||||||
public static Comparison Invert(this Comparison comp)
|
|
||||||
{
|
|
||||||
return (Comparison)((int)comp ^ 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ARMeilleure.IntermediateRepresentation
|
|
||||||
{
|
|
||||||
enum OperandType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
I32,
|
|
||||||
I64,
|
|
||||||
FP32,
|
|
||||||
FP64,
|
|
||||||
V128
|
|
||||||
}
|
|
||||||
|
|
||||||
static class OperandTypeExtensions
|
|
||||||
{
|
|
||||||
public static bool IsInteger(this OperandType type)
|
|
||||||
{
|
|
||||||
return type == OperandType.I32 ||
|
|
||||||
type == OperandType.I64;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RegisterType ToRegisterType(this OperandType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case OperandType.FP32: return RegisterType.Vector;
|
|
||||||
case OperandType.FP64: return RegisterType.Vector;
|
|
||||||
case OperandType.I32: return RegisterType.Integer;
|
|
||||||
case OperandType.I64: return RegisterType.Integer;
|
|
||||||
case OperandType.V128: return RegisterType.Vector;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetSizeInBytes(this OperandType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case OperandType.FP32: return 4;
|
|
||||||
case OperandType.FP64: return 8;
|
|
||||||
case OperandType.I32: return 4;
|
|
||||||
case OperandType.I64: return 8;
|
|
||||||
case OperandType.V128: return 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetSizeInBytesLog2(this OperandType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case OperandType.FP32: return 2;
|
|
||||||
case OperandType.FP64: return 3;
|
|
||||||
case OperandType.I32: return 2;
|
|
||||||
case OperandType.I64: return 3;
|
|
||||||
case OperandType.V128: return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException($"Invalid operand type \"{type}\".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace ARMeilleure.State
|
|
||||||
{
|
|
||||||
enum Aarch32Mode
|
|
||||||
{
|
|
||||||
User = 0b10000,
|
|
||||||
Fiq = 0b10001,
|
|
||||||
Irq = 0b10010,
|
|
||||||
Supervisor = 0b10011,
|
|
||||||
Monitor = 0b10110,
|
|
||||||
Abort = 0b10111,
|
|
||||||
Hypervisor = 0b11010,
|
|
||||||
Undefined = 0b11011,
|
|
||||||
System = 0b11111
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace ARMeilleure.State
|
|
||||||
{
|
|
||||||
enum FPException
|
|
||||||
{
|
|
||||||
InvalidOp = 0,
|
|
||||||
DivideByZero = 1,
|
|
||||||
Overflow = 2,
|
|
||||||
Underflow = 3,
|
|
||||||
Inexact = 4,
|
|
||||||
InputDenorm = 7
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
namespace ARMeilleure.State
|
|
||||||
{
|
|
||||||
public enum FPRoundingMode
|
|
||||||
{
|
|
||||||
ToNearest = 0, // With ties to even.
|
|
||||||
TowardsPlusInfinity = 1,
|
|
||||||
TowardsMinusInfinity = 2,
|
|
||||||
TowardsZero = 3,
|
|
||||||
ToNearestAway = 4 // With ties to away.
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace ARMeilleure.State
|
|
||||||
{
|
|
||||||
static class RegisterConsts
|
|
||||||
{
|
|
||||||
public const int IntRegsCount = 32;
|
|
||||||
public const int VecRegsCount = 32;
|
|
||||||
public const int FlagsCount = 32;
|
|
||||||
public const int FpFlagsCount = 32;
|
|
||||||
public const int IntAndVecRegsCount = IntRegsCount + VecRegsCount;
|
|
||||||
public const int FpFlagsOffset = IntRegsCount + VecRegsCount + FlagsCount;
|
|
||||||
public const int TotalCount = IntRegsCount + VecRegsCount + FlagsCount + FpFlagsCount;
|
|
||||||
|
|
||||||
public const int ZeroIndex = 31;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Reflection.Emit;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
|
||||||
{
|
|
||||||
static class DelegateHelper
|
|
||||||
{
|
|
||||||
private const string DelegateTypesAssemblyName = "JitDelegateTypes";
|
|
||||||
|
|
||||||
private static readonly ModuleBuilder _modBuilder;
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, Type> _delegateTypesCache;
|
|
||||||
|
|
||||||
static DelegateHelper()
|
|
||||||
{
|
|
||||||
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(DelegateTypesAssemblyName), AssemblyBuilderAccess.Run);
|
|
||||||
|
|
||||||
_modBuilder = asmBuilder.DefineDynamicModule(DelegateTypesAssemblyName);
|
|
||||||
|
|
||||||
_delegateTypesCache = new Dictionary<string, Type>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Delegate GetDelegate(MethodInfo info)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
|
||||||
|
|
||||||
Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray();
|
|
||||||
Type returnType = info.ReturnType;
|
|
||||||
|
|
||||||
Type delegateType = GetDelegateType(parameters, returnType);
|
|
||||||
|
|
||||||
return Delegate.CreateDelegate(delegateType, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Type GetDelegateType(Type[] parameters, Type returnType)
|
|
||||||
{
|
|
||||||
string key = GetFunctionSignatureKey(parameters, returnType);
|
|
||||||
|
|
||||||
if (!_delegateTypesCache.TryGetValue(key, out Type delegateType))
|
|
||||||
{
|
|
||||||
delegateType = MakeDelegateType(parameters, returnType, key);
|
|
||||||
|
|
||||||
_delegateTypesCache.TryAdd(key, delegateType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return delegateType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetFunctionSignatureKey(Type[] parameters, Type returnType)
|
|
||||||
{
|
|
||||||
string sig = GetTypeName(returnType);
|
|
||||||
|
|
||||||
foreach (Type type in parameters)
|
|
||||||
{
|
|
||||||
sig += '_' + GetTypeName(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTypeName(Type type)
|
|
||||||
{
|
|
||||||
return type.FullName.Replace(".", string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
private const MethodAttributes CtorAttributes =
|
|
||||||
MethodAttributes.RTSpecialName |
|
|
||||||
MethodAttributes.HideBySig |
|
|
||||||
MethodAttributes.Public;
|
|
||||||
|
|
||||||
private const TypeAttributes DelegateTypeAttributes =
|
|
||||||
TypeAttributes.Class |
|
|
||||||
TypeAttributes.Public |
|
|
||||||
TypeAttributes.Sealed |
|
|
||||||
TypeAttributes.AnsiClass |
|
|
||||||
TypeAttributes.AutoClass;
|
|
||||||
|
|
||||||
private const MethodImplAttributes ImplAttributes =
|
|
||||||
MethodImplAttributes.Runtime |
|
|
||||||
MethodImplAttributes.Managed;
|
|
||||||
|
|
||||||
private const MethodAttributes InvokeAttributes =
|
|
||||||
MethodAttributes.Public |
|
|
||||||
MethodAttributes.HideBySig |
|
|
||||||
MethodAttributes.NewSlot |
|
|
||||||
MethodAttributes.Virtual;
|
|
||||||
|
|
||||||
private static readonly Type[] _delegateCtorSignature = { typeof(object), typeof(IntPtr) };
|
|
||||||
|
|
||||||
private static Type MakeDelegateType(Type[] parameters, Type returnType, string name)
|
|
||||||
{
|
|
||||||
TypeBuilder builder = _modBuilder.DefineType(name, DelegateTypeAttributes, typeof(MulticastDelegate));
|
|
||||||
|
|
||||||
builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _delegateCtorSignature).SetImplementationFlags(ImplAttributes);
|
|
||||||
|
|
||||||
builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes);
|
|
||||||
|
|
||||||
return builder.CreateTypeInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,267 +0,0 @@
|
|||||||
using ARMeilleure.Instructions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace ARMeilleure.Translation
|
|
||||||
{
|
|
||||||
static class Delegates
|
|
||||||
{
|
|
||||||
public static bool TryGetDelegateFuncPtrByIndex(int index, out IntPtr funcPtr)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < _delegates.Count)
|
|
||||||
{
|
|
||||||
funcPtr = _delegates.Values[index].FuncPtr; // O(1).
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
funcPtr = default;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IntPtr GetDelegateFuncPtrByIndex(int index)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= _delegates.Count)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException($"({nameof(index)} = {index})");
|
|
||||||
}
|
|
||||||
|
|
||||||
return _delegates.Values[index].FuncPtr; // O(1).
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IntPtr GetDelegateFuncPtr(MethodInfo info)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
|
||||||
|
|
||||||
string key = GetKey(info);
|
|
||||||
|
|
||||||
if (!_delegates.TryGetValue(key, out DelegateInfo dlgInfo)) // O(log(n)).
|
|
||||||
{
|
|
||||||
throw new KeyNotFoundException($"({nameof(key)} = {key})");
|
|
||||||
}
|
|
||||||
|
|
||||||
return dlgInfo.FuncPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetDelegateIndex(MethodInfo info)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(info);
|
|
||||||
|
|
||||||
string key = GetKey(info);
|
|
||||||
|
|
||||||
int index = _delegates.IndexOfKey(key); // O(log(n)).
|
|
||||||
|
|
||||||
if (index == -1)
|
|
||||||
{
|
|
||||||
throw new KeyNotFoundException($"({nameof(key)} = {key})");
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetDelegateInfo(MethodInfo info)
|
|
||||||
{
|
|
||||||
string key = GetKey(info);
|
|
||||||
|
|
||||||
Delegate dlg = DelegateHelper.GetDelegate(info);
|
|
||||||
|
|
||||||
_delegates.Add(key, new DelegateInfo(dlg)); // ArgumentException (key).
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetKey(MethodInfo info)
|
|
||||||
{
|
|
||||||
return $"{info.DeclaringType.Name}.{info.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly SortedList<string, DelegateInfo> _delegates;
|
|
||||||
|
|
||||||
static Delegates()
|
|
||||||
{
|
|
||||||
_delegates = new SortedList<string, DelegateInfo>();
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Abs), new Type[] { typeof(double) }));
|
|
||||||
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Ceiling), new Type[] { typeof(double) }));
|
|
||||||
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Floor), new Type[] { typeof(double) }));
|
|
||||||
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Round), new Type[] { typeof(double), typeof(MidpointRounding) }));
|
|
||||||
SetDelegateInfo(typeof(Math).GetMethod(nameof(Math.Truncate), new Type[] { typeof(double) }));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Abs), new Type[] { typeof(float) }));
|
|
||||||
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Ceiling), new Type[] { typeof(float) }));
|
|
||||||
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Floor), new Type[] { typeof(float) }));
|
|
||||||
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Round), new Type[] { typeof(float), typeof(MidpointRounding) }));
|
|
||||||
SetDelegateInfo(typeof(MathF).GetMethod(nameof(MathF.Truncate), new Type[] { typeof(float) }));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrroEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cb)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32ch)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cw)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32cx)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32h)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU64)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS32)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToS64)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU32)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF64ToU64)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl4)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx1)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPAddFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareEQFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGE)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGEFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGT)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareGTFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLE)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLEFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLT)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompareLTFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPDiv)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNumFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNumFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMul)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulAddFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulSubFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMulX)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPNegMulSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimate)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipEstimateFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStep))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecipStepFused)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRecpX)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimate)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtEstimateFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStep))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPRSqrtStepFused)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSqrt)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPSub)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPAddFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareEQFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGE)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGEFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGT)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareGTFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLE)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLEFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLT)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompareLTFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPDiv)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMax)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNum)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMaxNumFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMin)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNum)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMinNumFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMul)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulAddFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulSubFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPMulX)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPNegMulSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimate)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipEstimateFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStep))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecipStepFused)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRecpX)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimate)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtEstimateFpscr))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStep))); // A32 only.
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPRSqrtStepFused)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSqrt)));
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPSub)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,40 +3,40 @@
|
|||||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="0.10.18" />
|
<PackageVersion Include="Avalonia" Version="0.10.21" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="0.10.21" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Desktop" Version="0.10.21" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="0.10.21" />
|
||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="0.10.21" />
|
||||||
<PackageVersion Include="Avalonia.Svg" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Svg" Version="0.10.18" />
|
||||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="0.10.18" />
|
<PackageVersion Include="Avalonia.Svg.Skia" Version="0.10.18" />
|
||||||
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
|
||||||
<PackageVersion Include="Concentus" Version="1.1.7" />
|
<PackageVersion Include="Concentus" Version="1.1.7" />
|
||||||
<PackageVersion Include="Crc32.NET" Version="1.2.0" />
|
|
||||||
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
|
<PackageVersion Include="DiscordRichPresence" Version="1.1.3.18" />
|
||||||
<PackageVersion Include="DynamicData" Version="7.12.11" />
|
<PackageVersion Include="DynamicData" Version="7.14.2" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="1.4.5" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
||||||
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
||||||
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
|
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.2.0" />
|
||||||
<PackageVersion Include="LibHac" Version="0.17.0" />
|
<PackageVersion Include="LibHac" Version="0.18.0" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
|
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" />
|
||||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
|
||||||
|
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
|
||||||
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
<PackageVersion Include="MsgPack.Cli" Version="1.0.1" />
|
||||||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||||
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
|
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||||
<PackageVersion Include="OpenTK.Core" Version="4.7.5" />
|
<PackageVersion Include="OpenTK.Core" Version="4.7.7" />
|
||||||
<PackageVersion Include="OpenTK.Graphics" Version="4.7.5" />
|
<PackageVersion Include="OpenTK.Graphics" Version="4.7.7" />
|
||||||
<PackageVersion Include="OpenTK.OpenAL" Version="4.7.5" />
|
<PackageVersion Include="OpenTK.OpenAL" Version="4.7.7" />
|
||||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.5" />
|
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.7.7" />
|
||||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.1-build23" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.1" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />
|
||||||
@ -44,11 +44,10 @@
|
|||||||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
<PackageVersion Include="SPB" Version="0.0.4-build28" />
|
||||||
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.25.1" />
|
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
|
||||||
<PackageVersion Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
|
||||||
<PackageVersion Include="System.Management" Version="7.0.0" />
|
<PackageVersion Include="System.Management" Version="7.0.2" />
|
||||||
<PackageVersion Include="System.Net.NameResolution" Version="4.3.0" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
<PackageVersion Include="System.Threading.ThreadPool" Version="4.3.0" />
|
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
|
||||||
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.5.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
As of November 2022, Ryujinx has been tested on approximately 3,800 titles; over 3,600 boot past menus and into gameplay, with roughly 3,200 of those being considered playable.
|
As of April 2023, Ryujinx has been tested on approximately 4,050 titles; over 4,000 boot past menus and into gameplay, with roughly 3,400 of those being considered playable.
|
||||||
You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -96,7 +96,7 @@ Ryujinx system files are stored in the `Ryujinx` folder. This folder is located
|
|||||||
|
|
||||||
- **GPU**
|
- **GPU**
|
||||||
|
|
||||||
The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. There are currently four graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Aspect Ratio Adjustment, and Anisotropic Filtering. These enhancements can be adjusted or toggled as desired in the GUI.
|
The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. There are currently six graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Anti-Aliasing, Scaling Filters (including FSR), Anisotropic Filtering and Aspect Ratio Adjustment. These enhancements can be adjusted or toggled as desired in the GUI.
|
||||||
|
|
||||||
- **Input**
|
- **Input**
|
||||||
|
|
||||||
|
@ -1,756 +0,0 @@
|
|||||||
using Ryujinx.Audio.Common;
|
|
||||||
using Ryujinx.Audio.Renderer.Dsp.Command;
|
|
||||||
using Ryujinx.Audio.Renderer.Parameter.Effect;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Server
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="ICommandProcessingTimeEstimator"/> version 3. (added with REV8)
|
|
||||||
/// </summary>
|
|
||||||
public class CommandProcessingTimeEstimatorVersion3 : ICommandProcessingTimeEstimator
|
|
||||||
{
|
|
||||||
protected uint _sampleCount;
|
|
||||||
protected uint _bufferCount;
|
|
||||||
|
|
||||||
public CommandProcessingTimeEstimatorVersion3(uint sampleCount, uint bufferCount)
|
|
||||||
{
|
|
||||||
_sampleCount = sampleCount;
|
|
||||||
_bufferCount = bufferCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(PerformanceCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)498.17f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)489.42f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(ClearMixBufferCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
float costPerBuffer = 440.68f;
|
|
||||||
float baseCost = 0;
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerBuffer = 266.65f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(baseCost + costPerBuffer * _bufferCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(BiquadFilterCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)4173.2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)5585.1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(MixRampGroupedCommand command)
|
|
||||||
{
|
|
||||||
float costPerSample = 6.4434f;
|
|
||||||
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerSample = 6.708f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int volumeCount = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < command.MixBufferCount; i++)
|
|
||||||
{
|
|
||||||
if (command.Volume0[i] != 0.0f || command.Volume1[i] != 0.0f)
|
|
||||||
{
|
|
||||||
volumeCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(_sampleCount * costPerSample * volumeCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(MixRampCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)1968.7f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)2459.4f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(DepopPrepareCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(VolumeRampCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)1425.3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)1700.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(PcmInt16DataSourceCommandVersion1 command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
float costPerSample = 710.143f;
|
|
||||||
float baseCost = 7853.286f;
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerSample = 427.52f;
|
|
||||||
baseCost = 6329.442f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(AdpcmDataSourceCommandVersion1 command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
float costPerSample = 3564.1f;
|
|
||||||
float baseCost = 9736.702f;
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerSample = 2125.6f;
|
|
||||||
baseCost = 7913.808f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(DepopForMixBuffersCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)739.64f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)910.97f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(CopyMixBufferCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)842.59f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)986.72f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(MixCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)1402.8f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)1853.2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(DelayCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)8929.04f;
|
|
||||||
case 2:
|
|
||||||
return (uint)25500.75f;
|
|
||||||
case 4:
|
|
||||||
return (uint)47759.62f;
|
|
||||||
case 6:
|
|
||||||
return (uint)82203.07f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)1295.20f;
|
|
||||||
case 2:
|
|
||||||
return (uint)1213.60f;
|
|
||||||
case 4:
|
|
||||||
return (uint)942.03f;
|
|
||||||
case 6:
|
|
||||||
return (uint)1001.55f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)11941.05f;
|
|
||||||
case 2:
|
|
||||||
return (uint)37197.37f;
|
|
||||||
case 4:
|
|
||||||
return (uint)69749.84f;
|
|
||||||
case 6:
|
|
||||||
return (uint)120042.40f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)997.67f;
|
|
||||||
case 2:
|
|
||||||
return (uint)977.63f;
|
|
||||||
case 4:
|
|
||||||
return (uint)792.30f;
|
|
||||||
case 6:
|
|
||||||
return (uint)875.43f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(ReverbCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)81475.05f;
|
|
||||||
case 2:
|
|
||||||
return (uint)84975.0f;
|
|
||||||
case 4:
|
|
||||||
return (uint)91625.15f;
|
|
||||||
case 6:
|
|
||||||
return (uint)95332.27f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)536.30f;
|
|
||||||
case 2:
|
|
||||||
return (uint)588.70f;
|
|
||||||
case 4:
|
|
||||||
return (uint)643.70f;
|
|
||||||
case 6:
|
|
||||||
return (uint)706.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)120174.47f;
|
|
||||||
case 2:
|
|
||||||
return (uint)25262.22f;
|
|
||||||
case 4:
|
|
||||||
return (uint)135751.23f;
|
|
||||||
case 6:
|
|
||||||
return (uint)141129.23f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)617.64f;
|
|
||||||
case 2:
|
|
||||||
return (uint)659.54f;
|
|
||||||
case 4:
|
|
||||||
return (uint)711.43f;
|
|
||||||
case 6:
|
|
||||||
return (uint)778.07f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(Reverb3dCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)116754.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)125912.05f;
|
|
||||||
case 4:
|
|
||||||
return (uint)146336.03f;
|
|
||||||
case 6:
|
|
||||||
return (uint)165812.66f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)734.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)766.62f;
|
|
||||||
case 4:
|
|
||||||
return (uint)797.46f;
|
|
||||||
case 6:
|
|
||||||
return (uint)867.43f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)170292.34f;
|
|
||||||
case 2:
|
|
||||||
return (uint)183875.63f;
|
|
||||||
case 4:
|
|
||||||
return (uint)214696.19f;
|
|
||||||
case 6:
|
|
||||||
return (uint)243846.77f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)508.47f;
|
|
||||||
case 2:
|
|
||||||
return (uint)582.45f;
|
|
||||||
case 4:
|
|
||||||
return (uint)626.42f;
|
|
||||||
case 6:
|
|
||||||
return (uint)682.47f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(AuxiliaryBufferCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
return (uint)7182.14f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)472.11f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
return (uint)9435.96f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)462.62f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(VolumeCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)1311.1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)1713.6f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(CircularBufferSinkCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
float costPerBuffer = 770.26f;
|
|
||||||
float baseCost = 0f;
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerBuffer = 531.07f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(baseCost + costPerBuffer * command.InputCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(DownMixSurroundToStereoCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)9949.7f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)14679.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(UpsampleCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)312990.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(DeviceSinkCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
Debug.Assert(command.InputCount == 2 || command.InputCount == 6);
|
|
||||||
|
|
||||||
if (command.InputCount == 2)
|
|
||||||
{
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)8980.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)9221.9f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (uint)9177.9f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)9725.9f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(PcmFloatDataSourceCommandVersion1 command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
float costPerSample = 3490.9f;
|
|
||||||
float baseCost = 10090.9f;
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
costPerSample = 2310.4f;
|
|
||||||
baseCost = 7845.25f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(DataSourceVersion2Command command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
(float baseCost, float costPerSample) = GetCostByFormat(_sampleCount, command.SampleFormat, command.SrcQuality);
|
|
||||||
|
|
||||||
return (uint)(baseCost + (costPerSample * (((command.SampleRate / 200.0f) / _sampleCount) * (command.Pitch * 0.000030518f) - 1.0f)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static (float, float) GetCostByFormat(uint sampleCount, SampleFormat format, SampleRateConversionQuality quality)
|
|
||||||
{
|
|
||||||
Debug.Assert(sampleCount == 160 || sampleCount == 240);
|
|
||||||
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
case SampleFormat.PcmInt16:
|
|
||||||
switch (quality)
|
|
||||||
{
|
|
||||||
case SampleRateConversionQuality.Default:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (6329.44f, 427.52f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (7853.28f, 710.14f);
|
|
||||||
case SampleRateConversionQuality.High:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (8049.42f, 371.88f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (10138.84f, 610.49f);
|
|
||||||
case SampleRateConversionQuality.Low:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (5062.66f, 423.43f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (5810.96f, 676.72f);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{format} {quality}");
|
|
||||||
}
|
|
||||||
case SampleFormat.PcmFloat:
|
|
||||||
switch (quality)
|
|
||||||
{
|
|
||||||
case SampleRateConversionQuality.Default:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (7845.25f, 2310.4f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (10090.9f, 3490.9f);
|
|
||||||
case SampleRateConversionQuality.High:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (9446.36f, 2308.91f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (12520.85f, 3480.61f);
|
|
||||||
case SampleRateConversionQuality.Low:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (9446.36f, 2308.91f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (12520.85f, 3480.61f);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{format} {quality}");
|
|
||||||
}
|
|
||||||
case SampleFormat.Adpcm:
|
|
||||||
switch (quality)
|
|
||||||
{
|
|
||||||
case SampleRateConversionQuality.Default:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (7913.81f, 1827.66f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (9736.70f, 2756.37f);
|
|
||||||
case SampleRateConversionQuality.High:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (9607.81f, 1829.29f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (12154.38f, 2731.31f);
|
|
||||||
case SampleRateConversionQuality.Low:
|
|
||||||
if (sampleCount == 160)
|
|
||||||
{
|
|
||||||
return (6517.48f, 1824.61f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (7929.44f, 2732.15f);
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{format} {quality}");
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{format}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint EstimateLimiterCommandCommon(LimiterParameter parameter, bool enabled)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
switch (parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)21392.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)26829.0f;
|
|
||||||
case 4:
|
|
||||||
return (uint)32405.0f;
|
|
||||||
case 6:
|
|
||||||
return (uint)52219.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)897.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)931.55f;
|
|
||||||
case 4:
|
|
||||||
return (uint)975.39f;
|
|
||||||
case 6:
|
|
||||||
return (uint)1016.8f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
switch (parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)30556.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)39011.0f;
|
|
||||||
case 4:
|
|
||||||
return (uint)48270.0f;
|
|
||||||
case 6:
|
|
||||||
return (uint)76712.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)874.43f;
|
|
||||||
case 2:
|
|
||||||
return (uint)921.55f;
|
|
||||||
case 4:
|
|
||||||
return (uint)945.26f;
|
|
||||||
case 6:
|
|
||||||
return (uint)992.26f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(LimiterCommandVersion1 command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Estimate(LimiterCommandVersion2 command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (!command.Parameter.StatisticsEnabled || !command.IsEffectEnabled)
|
|
||||||
{
|
|
||||||
return EstimateLimiterCommandCommon(command.Parameter, command.IsEffectEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)23309.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)29954.0f;
|
|
||||||
case 4:
|
|
||||||
return (uint)35807.0f;
|
|
||||||
case 6:
|
|
||||||
return (uint)58340.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)33526.0f;
|
|
||||||
case 2:
|
|
||||||
return (uint)43549.0f;
|
|
||||||
case 4:
|
|
||||||
return (uint)52190.0f;
|
|
||||||
case 6:
|
|
||||||
return (uint)85527.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(GroupedBiquadFilterCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(CaptureBufferCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual uint Estimate(CompressorCommand command)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,310 +0,0 @@
|
|||||||
using Ryujinx.Audio.Renderer.Dsp.Command;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Server
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="ICommandProcessingTimeEstimator"/> version 5. (added with REV11)
|
|
||||||
/// </summary>
|
|
||||||
public class CommandProcessingTimeEstimatorVersion5 : CommandProcessingTimeEstimatorVersion4
|
|
||||||
{
|
|
||||||
public CommandProcessingTimeEstimatorVersion5(uint sampleCount, uint bufferCount) : base(sampleCount, bufferCount) { }
|
|
||||||
|
|
||||||
public override uint Estimate(DelayCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 8929;
|
|
||||||
case 2:
|
|
||||||
return 25501;
|
|
||||||
case 4:
|
|
||||||
return 47760;
|
|
||||||
case 6:
|
|
||||||
return 82203;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)1295.20f;
|
|
||||||
case 2:
|
|
||||||
return (uint)1213.60f;
|
|
||||||
case 4:
|
|
||||||
return (uint)942.03f;
|
|
||||||
case 6:
|
|
||||||
return (uint)1001.6f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 11941;
|
|
||||||
case 2:
|
|
||||||
return 37197;
|
|
||||||
case 4:
|
|
||||||
return 69750;
|
|
||||||
case 6:
|
|
||||||
return 12004;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)997.67f;
|
|
||||||
case 2:
|
|
||||||
return (uint)977.63f;
|
|
||||||
case 4:
|
|
||||||
return (uint)792.31f;
|
|
||||||
case 6:
|
|
||||||
return (uint)875.43f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint Estimate(ReverbCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 81475;
|
|
||||||
case 2:
|
|
||||||
return 84975;
|
|
||||||
case 4:
|
|
||||||
return 91625;
|
|
||||||
case 6:
|
|
||||||
return 95332;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)536.30f;
|
|
||||||
case 2:
|
|
||||||
return (uint)588.80f;
|
|
||||||
case 4:
|
|
||||||
return (uint)643.70f;
|
|
||||||
case 6:
|
|
||||||
return (uint)706.0f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 120170;
|
|
||||||
case 2:
|
|
||||||
return 125260;
|
|
||||||
case 4:
|
|
||||||
return 135750;
|
|
||||||
case 6:
|
|
||||||
return 141130;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)617.64f;
|
|
||||||
case 2:
|
|
||||||
return (uint)659.54f;
|
|
||||||
case 4:
|
|
||||||
return (uint)711.44f;
|
|
||||||
case 6:
|
|
||||||
return (uint)778.07f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint Estimate(Reverb3dCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 116750;
|
|
||||||
case 2:
|
|
||||||
return 125910;
|
|
||||||
case 4:
|
|
||||||
return 146340;
|
|
||||||
case 6:
|
|
||||||
return 165810;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 735;
|
|
||||||
case 2:
|
|
||||||
return (uint)766.62f;
|
|
||||||
case 4:
|
|
||||||
return (uint)834.07f;
|
|
||||||
case 6:
|
|
||||||
return (uint)875.44f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 170290;
|
|
||||||
case 2:
|
|
||||||
return 183880;
|
|
||||||
case 4:
|
|
||||||
return 214700;
|
|
||||||
case 6:
|
|
||||||
return 243850;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)508.47f;
|
|
||||||
case 2:
|
|
||||||
return (uint)582.45f;
|
|
||||||
case 4:
|
|
||||||
return (uint)626.42f;
|
|
||||||
case 6:
|
|
||||||
return (uint)682.47f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint Estimate(CompressorCommand command)
|
|
||||||
{
|
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
|
||||||
|
|
||||||
if (_sampleCount == 160)
|
|
||||||
{
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 34431;
|
|
||||||
case 2:
|
|
||||||
return 44253;
|
|
||||||
case 4:
|
|
||||||
return 63827;
|
|
||||||
case 6:
|
|
||||||
return 83361;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)630.12f;
|
|
||||||
case 2:
|
|
||||||
return (uint)638.27f;
|
|
||||||
case 4:
|
|
||||||
return (uint)705.86f;
|
|
||||||
case 6:
|
|
||||||
return (uint)782.02f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.Enabled)
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return 51095;
|
|
||||||
case 2:
|
|
||||||
return 65693;
|
|
||||||
case 4:
|
|
||||||
return 95383;
|
|
||||||
case 6:
|
|
||||||
return 124510;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (command.Parameter.ChannelCount)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return (uint)840.14f;
|
|
||||||
case 2:
|
|
||||||
return (uint)826.1f;
|
|
||||||
case 4:
|
|
||||||
return (uint)901.88f;
|
|
||||||
case 6:
|
|
||||||
return (uint)965.29f;
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException($"{command.Parameter.ChannelCount}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using Ryujinx.Ui.Common.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Locale
|
|
||||||
{
|
|
||||||
class LocaleManager : BaseModel
|
|
||||||
{
|
|
||||||
private const string DefaultLanguageCode = "en_US";
|
|
||||||
|
|
||||||
private Dictionary<LocaleKeys, string> _localeStrings;
|
|
||||||
private ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
|
|
||||||
|
|
||||||
public static LocaleManager Instance { get; } = new LocaleManager();
|
|
||||||
public Dictionary<LocaleKeys, string> LocaleStrings { get => _localeStrings; set => _localeStrings = value; }
|
|
||||||
|
|
||||||
|
|
||||||
public LocaleManager()
|
|
||||||
{
|
|
||||||
_localeStrings = new Dictionary<LocaleKeys, string>();
|
|
||||||
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
|
|
||||||
|
|
||||||
Load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Load()
|
|
||||||
{
|
|
||||||
string localeLanguageCode = CultureInfo.CurrentCulture.Name.Replace('-', '_');
|
|
||||||
|
|
||||||
if (Program.PreviewerDetached)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(ConfigurationState.Instance.Ui.LanguageCode.Value))
|
|
||||||
{
|
|
||||||
localeLanguageCode = ConfigurationState.Instance.Ui.LanguageCode.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load english first, if the target language translation is incomplete, we default to english.
|
|
||||||
LoadDefaultLanguage();
|
|
||||||
|
|
||||||
if (localeLanguageCode != DefaultLanguageCode)
|
|
||||||
{
|
|
||||||
LoadLanguage(localeLanguageCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string this[LocaleKeys key]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_localeStrings.TryGetValue(key, out string value))
|
|
||||||
{
|
|
||||||
if (_dynamicValues.TryGetValue(key, out var dynamicValue))
|
|
||||||
{
|
|
||||||
return string.Format(value, dynamicValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return key.ToString();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_localeStrings[key] = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateDynamicValue(LocaleKeys key, params object[] values)
|
|
||||||
{
|
|
||||||
_dynamicValues[key] = values;
|
|
||||||
|
|
||||||
OnPropertyChanged("Item");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadDefaultLanguage()
|
|
||||||
{
|
|
||||||
LoadLanguage(DefaultLanguageCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadLanguage(string languageCode)
|
|
||||||
{
|
|
||||||
string languageJson = EmbeddedResources.ReadAllText($"Ryujinx.Ava/Assets/Locales/{languageCode}.json");
|
|
||||||
|
|
||||||
if (languageJson == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var strings = JsonHelper.Deserialize<Dictionary<string, string>>(languageJson);
|
|
||||||
|
|
||||||
foreach (var item in strings)
|
|
||||||
{
|
|
||||||
if (Enum.TryParse<LocaleKeys>(item.Key, out var key))
|
|
||||||
{
|
|
||||||
this[key] = item.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Program.PreviewerDetached)
|
|
||||||
{
|
|
||||||
ConfigurationState.Instance.Ui.LanguageCode.Value = languageCode;
|
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,714 +0,0 @@
|
|||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Threading;
|
|
||||||
using FluentAvalonia.UI.Controls;
|
|
||||||
using ICSharpCode.SharpZipLib.GZip;
|
|
||||||
using ICSharpCode.SharpZipLib.Tar;
|
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Ryujinx.Ava;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
using Ryujinx.Ava.UI.Controls;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
|
||||||
using Ryujinx.Ava.UI.Windows;
|
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.Common.Logging;
|
|
||||||
using Ryujinx.Ui.Common.Helper;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.NetworkInformation;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Modules
|
|
||||||
{
|
|
||||||
internal static class Updater
|
|
||||||
{
|
|
||||||
private const string GitHubApiURL = "https://api.github.com";
|
|
||||||
internal static bool Running;
|
|
||||||
|
|
||||||
private static readonly string HomeDir = AppDomain.CurrentDomain.BaseDirectory;
|
|
||||||
private static readonly string UpdateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
|
||||||
private static readonly string UpdatePublishDir = Path.Combine(UpdateDir, "publish");
|
|
||||||
private static readonly int ConnectionCount = 4;
|
|
||||||
|
|
||||||
private static string _buildVer;
|
|
||||||
private static string _platformExt;
|
|
||||||
private static string _buildUrl;
|
|
||||||
private static long _buildSize;
|
|
||||||
|
|
||||||
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
|
|
||||||
|
|
||||||
public static bool UpdateSuccessful { get; private set; }
|
|
||||||
|
|
||||||
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
|
|
||||||
{
|
|
||||||
if (Running)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Running = true;
|
|
||||||
mainWindow.ViewModel.CanUpdate = false;
|
|
||||||
|
|
||||||
// Detect current platform
|
|
||||||
if (OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
_platformExt = "osx_x64.zip";
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
_platformExt = "win_x64.zip";
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
_platformExt = "linux_x64.tar.gz";
|
|
||||||
}
|
|
||||||
|
|
||||||
Version newVersion;
|
|
||||||
Version currentVersion;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
currentVersion = Version.Parse(Program.Version);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage], LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get latest version number from GitHub API
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (HttpClient jsonClient = ConstructHttpClient())
|
|
||||||
{
|
|
||||||
string buildInfoURL = $"{GitHubApiURL}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
|
|
||||||
|
|
||||||
string fetchedJson = await jsonClient.GetStringAsync(buildInfoURL);
|
|
||||||
JObject jsonRoot = JObject.Parse(fetchedJson);
|
|
||||||
JToken assets = jsonRoot["assets"];
|
|
||||||
|
|
||||||
_buildVer = (string)jsonRoot["name"];
|
|
||||||
|
|
||||||
foreach (JToken asset in assets)
|
|
||||||
{
|
|
||||||
string assetName = (string)asset["name"];
|
|
||||||
string assetState = (string)asset["state"];
|
|
||||||
string downloadURL = (string)asset["browser_download_url"];
|
|
||||||
|
|
||||||
if (assetName.StartsWith("test-ava-ryujinx") && assetName.EndsWith(_platformExt))
|
|
||||||
{
|
|
||||||
_buildUrl = downloadURL;
|
|
||||||
|
|
||||||
if (assetState != "uploaded")
|
|
||||||
{
|
|
||||||
if (showVersionUpToDate)
|
|
||||||
{
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage], "");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If build not done, assume no new update are availaible.
|
|
||||||
if (_buildUrl == null)
|
|
||||||
{
|
|
||||||
if (showVersionUpToDate)
|
|
||||||
{
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage], "");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, exception.Message);
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterFailedToGetVersionMessage]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
newVersion = Version.Parse(_buildVer);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage], LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newVersion <= currentVersion)
|
|
||||||
{
|
|
||||||
if (showVersionUpToDate)
|
|
||||||
{
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage], "");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Running = false;
|
|
||||||
mainWindow.ViewModel.CanUpdate = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch build size information to learn chunk sizes.
|
|
||||||
using (HttpClient buildSizeClient = ConstructHttpClient())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0");
|
|
||||||
|
|
||||||
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
|
|
||||||
|
|
||||||
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.Application, ex.Message);
|
|
||||||
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
|
|
||||||
|
|
||||||
_buildSize = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(async () =>
|
|
||||||
{
|
|
||||||
// Show a message asking the user if they want to update
|
|
||||||
var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
|
|
||||||
$"{Program.Version} -> {newVersion}");
|
|
||||||
|
|
||||||
if (shouldUpdate)
|
|
||||||
{
|
|
||||||
UpdateRyujinx(mainWindow, _buildUrl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpClient ConstructHttpClient()
|
|
||||||
{
|
|
||||||
HttpClient result = new HttpClient();
|
|
||||||
|
|
||||||
// Required by GitHub to interract with APIs.
|
|
||||||
result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async void UpdateRyujinx(Window parent, string downloadUrl)
|
|
||||||
{
|
|
||||||
UpdateSuccessful = false;
|
|
||||||
|
|
||||||
// Empty update dir, although it shouldn't ever have anything inside it
|
|
||||||
if (Directory.Exists(UpdateDir))
|
|
||||||
{
|
|
||||||
Directory.Delete(UpdateDir, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Directory.CreateDirectory(UpdateDir);
|
|
||||||
|
|
||||||
string updateFile = Path.Combine(UpdateDir, "update.bin");
|
|
||||||
|
|
||||||
var taskDialog = new TaskDialog()
|
|
||||||
{
|
|
||||||
Header = LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
|
||||||
SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading],
|
|
||||||
IconSource = new SymbolIconSource { Symbol = Symbol.Download },
|
|
||||||
Buttons = { },
|
|
||||||
ShowProgressBar = true
|
|
||||||
};
|
|
||||||
|
|
||||||
taskDialog.XamlRoot = parent;
|
|
||||||
|
|
||||||
taskDialog.Opened += (s, e) =>
|
|
||||||
{
|
|
||||||
if (_buildSize >= 0)
|
|
||||||
{
|
|
||||||
DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await taskDialog.ShowAsync(true);
|
|
||||||
|
|
||||||
if (UpdateSuccessful)
|
|
||||||
{
|
|
||||||
var shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
|
|
||||||
|
|
||||||
if (shouldRestart)
|
|
||||||
{
|
|
||||||
string ryuName = Path.GetFileName(Environment.ProcessPath);
|
|
||||||
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
|
||||||
|
|
||||||
if (!Path.Exists(ryuExe))
|
|
||||||
{
|
|
||||||
ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx");
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFileExecutable(ryuExe);
|
|
||||||
|
|
||||||
Process.Start(ryuExe, CommandLineState.Arguments);
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
|
||||||
{
|
|
||||||
// Multi-Threaded Updater
|
|
||||||
long chunkSize = _buildSize / ConnectionCount;
|
|
||||||
long remainderChunk = _buildSize % ConnectionCount;
|
|
||||||
|
|
||||||
int completedRequests = 0;
|
|
||||||
int totalProgressPercentage = 0;
|
|
||||||
int[] progressPercentage = new int[ConnectionCount];
|
|
||||||
|
|
||||||
List<byte[]> list = new List<byte[]>(ConnectionCount);
|
|
||||||
List<WebClient> webClients = new List<WebClient>(ConnectionCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < ConnectionCount; i++)
|
|
||||||
{
|
|
||||||
list.Add(Array.Empty<byte>());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < ConnectionCount; i++)
|
|
||||||
{
|
|
||||||
#pragma warning disable SYSLIB0014
|
|
||||||
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
|
|
||||||
using (WebClient client = new WebClient())
|
|
||||||
#pragma warning restore SYSLIB0014
|
|
||||||
{
|
|
||||||
webClients.Add(client);
|
|
||||||
|
|
||||||
if (i == ConnectionCount - 1)
|
|
||||||
{
|
|
||||||
client.Headers.Add("Range", $"bytes={chunkSize * i}-{(chunkSize * (i + 1) - 1) + remainderChunk}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client.Headers.Add("Range", $"bytes={chunkSize * i}-{chunkSize * (i + 1) - 1}");
|
|
||||||
}
|
|
||||||
|
|
||||||
client.DownloadProgressChanged += (_, args) =>
|
|
||||||
{
|
|
||||||
int index = (int)args.UserState;
|
|
||||||
|
|
||||||
Interlocked.Add(ref totalProgressPercentage, -1 * progressPercentage[index]);
|
|
||||||
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
|
|
||||||
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
|
|
||||||
|
|
||||||
taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
|
|
||||||
};
|
|
||||||
|
|
||||||
client.DownloadDataCompleted += (_, args) =>
|
|
||||||
{
|
|
||||||
int index = (int)args.UserState;
|
|
||||||
|
|
||||||
if (args.Cancelled)
|
|
||||||
{
|
|
||||||
webClients[index].Dispose();
|
|
||||||
|
|
||||||
taskDialog.Hide();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
list[index] = args.Result;
|
|
||||||
Interlocked.Increment(ref completedRequests);
|
|
||||||
|
|
||||||
if (Equals(completedRequests, ConnectionCount))
|
|
||||||
{
|
|
||||||
byte[] mergedFileBytes = new byte[_buildSize];
|
|
||||||
for (int connectionIndex = 0, destinationOffset = 0; connectionIndex < ConnectionCount; connectionIndex++)
|
|
||||||
{
|
|
||||||
Array.Copy(list[connectionIndex], 0, mergedFileBytes, destinationOffset, list[connectionIndex].Length);
|
|
||||||
destinationOffset += list[connectionIndex].Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllBytes(updateFile, mergedFileBytes);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InstallUpdate(taskDialog, updateFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.Application, e.Message);
|
|
||||||
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
|
|
||||||
|
|
||||||
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
client.DownloadDataAsync(new Uri(downloadUrl), i);
|
|
||||||
}
|
|
||||||
catch (WebException ex)
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.Application, ex.Message);
|
|
||||||
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
|
|
||||||
|
|
||||||
for (int j = 0; j < webClients.Count; j++)
|
|
||||||
{
|
|
||||||
webClients[j].CancelAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
|
||||||
{
|
|
||||||
using (HttpClient client = new HttpClient())
|
|
||||||
{
|
|
||||||
// We do not want to timeout while downloading
|
|
||||||
client.Timeout = TimeSpan.FromDays(1);
|
|
||||||
|
|
||||||
using (HttpResponseMessage response = client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead).Result)
|
|
||||||
using (Stream remoteFileStream = response.Content.ReadAsStreamAsync().Result)
|
|
||||||
{
|
|
||||||
using (Stream updateFileStream = File.Open(updateFile, FileMode.Create))
|
|
||||||
{
|
|
||||||
long totalBytes = response.Content.Headers.ContentLength.Value;
|
|
||||||
long byteWritten = 0;
|
|
||||||
|
|
||||||
byte[] buffer = new byte[32 * 1024];
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
int readSize = remoteFileStream.Read(buffer);
|
|
||||||
|
|
||||||
if (readSize == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
byteWritten += readSize;
|
|
||||||
|
|
||||||
taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
|
|
||||||
|
|
||||||
updateFileStream.Write(buffer, 0, readSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InstallUpdate(taskDialog, updateFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static double GetPercentage(double value, double max)
|
|
||||||
{
|
|
||||||
return max == 0 ? 0 : value / max * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
|
||||||
{
|
|
||||||
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile));
|
|
||||||
worker.Name = "Updater.SingleThreadWorker";
|
|
||||||
worker.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetFileExecutable(string path)
|
|
||||||
{
|
|
||||||
const UnixFileMode ExecutableFileMode = UnixFileMode.UserExecute |
|
|
||||||
UnixFileMode.UserWrite |
|
|
||||||
UnixFileMode.UserRead |
|
|
||||||
UnixFileMode.GroupRead |
|
|
||||||
UnixFileMode.GroupWrite |
|
|
||||||
UnixFileMode.OtherRead |
|
|
||||||
UnixFileMode.OtherWrite;
|
|
||||||
|
|
||||||
if (!OperatingSystem.IsWindows() && File.Exists(path))
|
|
||||||
{
|
|
||||||
File.SetUnixFileMode(path, ExecutableFileMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async void InstallUpdate(TaskDialog taskDialog, string updateFile)
|
|
||||||
{
|
|
||||||
// Extract Update
|
|
||||||
taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterExtracting];
|
|
||||||
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
|
||||||
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
using (Stream inStream = File.OpenRead(updateFile))
|
|
||||||
using (Stream gzipStream = new GZipInputStream(inStream))
|
|
||||||
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
|
|
||||||
{
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
|
||||||
TarEntry tarEntry;
|
|
||||||
while ((tarEntry = tarStream.GetNextEntry()) != null)
|
|
||||||
{
|
|
||||||
if (tarEntry.IsDirectory) continue;
|
|
||||||
|
|
||||||
string outPath = Path.Combine(UpdateDir, tarEntry.Name);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
|
|
||||||
|
|
||||||
using (FileStream outStream = File.OpenWrite(outPath))
|
|
||||||
{
|
|
||||||
tarStream.CopyEntryContents(outStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
|
|
||||||
|
|
||||||
TarEntry entry = tarEntry;
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
{
|
|
||||||
taskDialog.SetProgressBarState(GetPercentage(entry.Size, inStream.Length), TaskDialogProgressState.Normal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using (Stream inStream = File.OpenRead(updateFile))
|
|
||||||
using (ZipFile zipFile = new ZipFile(inStream))
|
|
||||||
{
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
|
||||||
double count = 0;
|
|
||||||
foreach (ZipEntry zipEntry in zipFile)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
if (zipEntry.IsDirectory) continue;
|
|
||||||
|
|
||||||
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(outPath));
|
|
||||||
|
|
||||||
using (Stream zipStream = zipFile.GetInputStream(zipEntry))
|
|
||||||
using (FileStream outStream = File.OpenWrite(outPath))
|
|
||||||
{
|
|
||||||
zipStream.CopyTo(outStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
{
|
|
||||||
taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete downloaded zip
|
|
||||||
File.Delete(updateFile);
|
|
||||||
|
|
||||||
List<string> allFiles = EnumerateFilesToDelete().ToList();
|
|
||||||
|
|
||||||
taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterRenaming];
|
|
||||||
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
|
||||||
|
|
||||||
// Replace old files
|
|
||||||
await Task.Run(() =>
|
|
||||||
{
|
|
||||||
double count = 0;
|
|
||||||
foreach (string file in allFiles)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Move(file, file + ".ryuold");
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
{
|
|
||||||
taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.Application, string.Format(LocaleManager.Instance[LocaleKeys.UpdaterRenameFailed], file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
{
|
|
||||||
taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterAddingFiles];
|
|
||||||
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
|
|
||||||
});
|
|
||||||
|
|
||||||
MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
|
|
||||||
});
|
|
||||||
|
|
||||||
Directory.Delete(UpdateDir, true);
|
|
||||||
|
|
||||||
SetFileExecutable(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"));
|
|
||||||
|
|
||||||
UpdateSuccessful = true;
|
|
||||||
|
|
||||||
taskDialog.Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
|
||||||
public static bool CanUpdate(bool showWarnings, StyleableWindow parent)
|
|
||||||
{
|
|
||||||
#if !DISABLE_UPDATER
|
|
||||||
if (RuntimeInformation.OSArchitecture != Architecture.X64)
|
|
||||||
{
|
|
||||||
if (showWarnings)
|
|
||||||
{
|
|
||||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterArchNotSupportedMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterArchNotSupportedSubMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NetworkInterface.GetIsNetworkAvailable())
|
|
||||||
{
|
|
||||||
if (showWarnings)
|
|
||||||
{
|
|
||||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterNoInternetSubMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Program.Version.Contains("dirty") || !ReleaseInformation.IsValid())
|
|
||||||
{
|
|
||||||
if (showWarnings)
|
|
||||||
{
|
|
||||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if (showWarnings)
|
|
||||||
{
|
|
||||||
if (ReleaseInformation.IsFlatHubBuild())
|
|
||||||
{
|
|
||||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle], LocaleManager.Instance[LocaleKeys.DialogUpdaterFlatpakNotSupportedMessage]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.UpdaterDisabledWarningTitle], LocaleManager.Instance[LocaleKeys.DialogUpdaterDirtyBuildSubMessage]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
|
||||||
|
|
||||||
// NOTE: This method should always reflect the latest build layout.s
|
|
||||||
private static IEnumerable<string> EnumerateFilesToDelete()
|
|
||||||
{
|
|
||||||
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
|
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
foreach (string dir in WindowsDependencyDirs)
|
|
||||||
{
|
|
||||||
string dirPath = Path.Combine(HomeDir, dir);
|
|
||||||
if (Directory.Exists(dirPath))
|
|
||||||
{
|
|
||||||
files = files.Concat(Directory.EnumerateFiles(dirPath, "*", SearchOption.AllDirectories));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
|
|
||||||
{
|
|
||||||
var total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
|
|
||||||
foreach (string directory in Directory.GetDirectories(root))
|
|
||||||
{
|
|
||||||
string dirName = Path.GetFileName(directory);
|
|
||||||
|
|
||||||
if (!Directory.Exists(Path.Combine(dest, dirName)))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.Combine(dest, dirName));
|
|
||||||
}
|
|
||||||
|
|
||||||
MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
double count = 0;
|
|
||||||
foreach (string file in Directory.GetFiles(root))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
|
|
||||||
|
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CleanupUpdate()
|
|
||||||
{
|
|
||||||
foreach (string file in Directory.GetFiles(HomeDir, "*.ryuold", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
File.Delete(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
x:Class="Ryujinx.Ava.UI.Controls.GameGridView"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
|
||||||
d:DesignHeight="450"
|
|
||||||
d:DesignWidth="800"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Focusable="True">
|
|
||||||
<UserControl.Resources>
|
|
||||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
|
||||||
<MenuFlyout x:Key="GameContextMenu" Opened="MenuBase_OnMenuOpened">
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding ToggleFavorite}"
|
|
||||||
Header="{locale:Locale GameListContextMenuToggleFavorite}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
|
|
||||||
<Separator />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenUserSaveDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenDeviceSaveDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuOpenDeviceSaveDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuOpenDeviceSaveDirectoryToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenBcatSaveDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuOpenBcatSaveDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuOpenBcatSaveDirectoryToolTip}" />
|
|
||||||
<Separator />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenTitleUpdateManager}"
|
|
||||||
Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenDownloadableContentManager}"
|
|
||||||
Header="{locale:Locale GameListContextMenuManageDlc}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenCheatManager}"
|
|
||||||
Header="{locale:Locale GameListContextMenuManageCheat}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenModsDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenSdModsDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
|
|
||||||
<Separator />
|
|
||||||
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding PurgePtcCache}"
|
|
||||||
Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding PurgeShaderCache}"
|
|
||||||
Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenPtcDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding OpenShaderCacheDirectory}"
|
|
||||||
Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding ExtractExeFs}"
|
|
||||||
Header="{locale:Locale GameListContextMenuExtractDataExeFS}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataExeFSToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding ExtractRomFs}"
|
|
||||||
Header="{locale:Locale GameListContextMenuExtractDataRomFS}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataRomFSToolTip}" />
|
|
||||||
<MenuItem
|
|
||||||
Command="{Binding ExtractLogo}"
|
|
||||||
Header="{locale:Locale GameListContextMenuExtractDataLogo}"
|
|
||||||
ToolTip.Tip="{locale:Locale GameListContextMenuExtractDataLogoToolTip}" />
|
|
||||||
</MenuItem>
|
|
||||||
</MenuFlyout>
|
|
||||||
</UserControl.Resources>
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="*" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<ListBox
|
|
||||||
Grid.Row="0"
|
|
||||||
Padding="8"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
ContextFlyout="{StaticResource GameContextMenu}"
|
|
||||||
DoubleTapped="GameList_DoubleTapped"
|
|
||||||
Items="{Binding AppsObservableList}"
|
|
||||||
SelectionChanged="GameList_SelectionChanged">
|
|
||||||
<ListBox.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<flex:FlexPanel
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
AlignContent="FlexStart"
|
|
||||||
JustifyContent="Center" />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ListBox.ItemsPanel>
|
|
||||||
<ListBox.Styles>
|
|
||||||
<Style Selector="ListBoxItem">
|
|
||||||
<Setter Property="Margin" Value="5" />
|
|
||||||
<Setter Property="CornerRadius" Value="4" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
|
|
||||||
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
|
|
||||||
</Style>
|
|
||||||
</ListBox.Styles>
|
|
||||||
<ListBox.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<Grid>
|
|
||||||
<Border
|
|
||||||
Margin="10"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Classes.huge="{Binding $parent[UserControl].DataContext.IsGridHuge}"
|
|
||||||
Classes.large="{Binding $parent[UserControl].DataContext.IsGridLarge}"
|
|
||||||
Classes.normal="{Binding $parent[UserControl].DataContext.IsGridMedium}"
|
|
||||||
Classes.small="{Binding $parent[UserControl].DataContext.IsGridSmall}"
|
|
||||||
ClipToBounds="True"
|
|
||||||
CornerRadius="4">
|
|
||||||
<Grid>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Image
|
|
||||||
Grid.Row="0"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Top"
|
|
||||||
Source="{Binding Icon, Converter={StaticResource ByteImage}}" />
|
|
||||||
<Panel
|
|
||||||
Grid.Row="1"
|
|
||||||
Height="50"
|
|
||||||
Margin="0 10 0 0"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
IsVisible="{Binding $parent[UserControl].DataContext.ShowNames}">
|
|
||||||
<TextBlock
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{Binding TitleName}"
|
|
||||||
TextAlignment="Center"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
</Panel>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
<ui:SymbolIcon
|
|
||||||
Margin="5,5,0,0"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Top"
|
|
||||||
FontSize="16"
|
|
||||||
Foreground="{DynamicResource SystemAccentColor}"
|
|
||||||
IsVisible="{Binding Favorite}"
|
|
||||||
Symbol="StarFilled" />
|
|
||||||
</Grid>
|
|
||||||
</DataTemplate>
|
|
||||||
</ListBox.ItemTemplate>
|
|
||||||
</ListBox>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
@ -1,83 +0,0 @@
|
|||||||
using Avalonia.Collections;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Input;
|
|
||||||
using Avalonia.Interactivity;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using LibHac.Common;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Ui.App.Common;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
|
||||||
{
|
|
||||||
public partial class GameGridView : UserControl
|
|
||||||
{
|
|
||||||
private ApplicationData _selectedApplication;
|
|
||||||
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
|
|
||||||
RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
|
|
||||||
|
|
||||||
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
|
|
||||||
{
|
|
||||||
add { AddHandler(ApplicationOpenedEvent, value); }
|
|
||||||
remove { RemoveHandler(ApplicationOpenedEvent, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
|
|
||||||
{
|
|
||||||
if (sender is ListBox listBox)
|
|
||||||
{
|
|
||||||
if (listBox.SelectedItem is ApplicationData selected)
|
|
||||||
{
|
|
||||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
|
||||||
{
|
|
||||||
if (sender is ListBox listBox)
|
|
||||||
{
|
|
||||||
_selectedApplication = listBox.SelectedItem as ApplicationData;
|
|
||||||
|
|
||||||
(DataContext as MainWindowViewModel).GridSelectedApplication = _selectedApplication;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApplicationData SelectedApplication => _selectedApplication;
|
|
||||||
|
|
||||||
public GameGridView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
AvaloniaXamlLoader.Load(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MenuBase_OnMenuOpened(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var selection = SelectedApplication;
|
|
||||||
|
|
||||||
if (selection != null)
|
|
||||||
{
|
|
||||||
if (sender is ContextMenu menu)
|
|
||||||
{
|
|
||||||
bool canHaveUserSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
|
||||||
bool canHaveDeviceSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.DeviceSaveDataSize > 0;
|
|
||||||
bool canHaveBcatSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
|
||||||
|
|
||||||
((menu.Items as AvaloniaList<object>)[2] as MenuItem).IsEnabled = canHaveUserSave;
|
|
||||||
((menu.Items as AvaloniaList<object>)[3] as MenuItem).IsEnabled = canHaveDeviceSave;
|
|
||||||
((menu.Items as AvaloniaList<object>)[4] as MenuItem).IsEnabled = canHaveBcatSave;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
using Avalonia.Collections;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Input;
|
|
||||||
using Avalonia.Interactivity;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using LibHac.Common;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Ui.App.Common;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
|
||||||
{
|
|
||||||
public partial class GameListView : UserControl
|
|
||||||
{
|
|
||||||
private ApplicationData _selectedApplication;
|
|
||||||
public static readonly RoutedEvent<ApplicationOpenedEventArgs> ApplicationOpenedEvent =
|
|
||||||
RoutedEvent.Register<GameGridView, ApplicationOpenedEventArgs>(nameof(ApplicationOpened), RoutingStrategies.Bubble);
|
|
||||||
|
|
||||||
public event EventHandler<ApplicationOpenedEventArgs> ApplicationOpened
|
|
||||||
{
|
|
||||||
add { AddHandler(ApplicationOpenedEvent, value); }
|
|
||||||
remove { RemoveHandler(ApplicationOpenedEvent, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GameList_DoubleTapped(object sender, RoutedEventArgs args)
|
|
||||||
{
|
|
||||||
if (sender is ListBox listBox)
|
|
||||||
{
|
|
||||||
if (listBox.SelectedItem is ApplicationData selected)
|
|
||||||
{
|
|
||||||
RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GameList_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
|
||||||
{
|
|
||||||
if (sender is ListBox listBox)
|
|
||||||
{
|
|
||||||
_selectedApplication = listBox.SelectedItem as ApplicationData;
|
|
||||||
|
|
||||||
(DataContext as MainWindowViewModel).ListSelectedApplication = _selectedApplication;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApplicationData SelectedApplication => _selectedApplication;
|
|
||||||
|
|
||||||
public GameListView()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
AvaloniaXamlLoader.Load(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)
|
|
||||||
{
|
|
||||||
(DataContext as MainWindowViewModel).SearchText = (sender as TextBox).Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MenuBase_OnMenuOpened(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var selection = SelectedApplication;
|
|
||||||
|
|
||||||
if (selection != null)
|
|
||||||
{
|
|
||||||
if (sender is ContextMenu menu)
|
|
||||||
{
|
|
||||||
bool canHaveUserSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.UserAccountSaveDataSize > 0;
|
|
||||||
bool canHaveDeviceSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.DeviceSaveDataSize > 0;
|
|
||||||
bool canHaveBcatSave = !Utilities.IsZeros(selection.ControlHolder.ByteSpan) && selection.ControlHolder.Value.BcatDeliveryCacheStorageSize > 0;
|
|
||||||
|
|
||||||
((menu.Items as AvaloniaList<object>)[2] as MenuItem).IsEnabled = canHaveUserSave;
|
|
||||||
((menu.Items as AvaloniaList<object>)[3] as MenuItem).IsEnabled = canHaveDeviceSave;
|
|
||||||
((menu.Items as AvaloniaList<object>)[4] as MenuItem).IsEnabled = canHaveBcatSave;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
x:Class="Ryujinx.Ava.UI.Controls.InputDialog"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Focusable="True">
|
|
||||||
<Grid
|
|
||||||
Margin="5,10,5,5"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock HorizontalAlignment="Center" Text="{Binding Message}" />
|
|
||||||
<TextBox
|
|
||||||
Grid.Row="1"
|
|
||||||
Width="300"
|
|
||||||
Margin="10"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
MaxLength="{Binding MaxLength}"
|
|
||||||
Text="{Binding Input, Mode=TwoWay}" />
|
|
||||||
<TextBlock
|
|
||||||
Grid.Row="2"
|
|
||||||
Margin="5,5,5,10"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
Text="{Binding SubMessage}" />
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
@ -1,57 +0,0 @@
|
|||||||
using Avalonia.Controls;
|
|
||||||
using FluentAvalonia.UI.Controls;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
|
||||||
using Ryujinx.Ava.UI.Models;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
|
||||||
{
|
|
||||||
public partial class InputDialog : UserControl
|
|
||||||
{
|
|
||||||
public string Message { get; set; }
|
|
||||||
public string Input { get; set; }
|
|
||||||
public string SubMessage { get; set; }
|
|
||||||
|
|
||||||
public uint MaxLength { get; }
|
|
||||||
|
|
||||||
public InputDialog(string message, string input = "", string subMessage = "", uint maxLength = int.MaxValue)
|
|
||||||
{
|
|
||||||
Message = message;
|
|
||||||
Input = input;
|
|
||||||
SubMessage = subMessage;
|
|
||||||
MaxLength = maxLength;
|
|
||||||
|
|
||||||
DataContext = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputDialog()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<(UserResult Result, string Input)> ShowInputDialog(string title, string message,
|
|
||||||
string input = "", string subMessage = "", uint maxLength = int.MaxValue)
|
|
||||||
{
|
|
||||||
UserResult result = UserResult.Cancel;
|
|
||||||
|
|
||||||
InputDialog content = new InputDialog(message, input, subMessage, maxLength);
|
|
||||||
ContentDialog contentDialog = new ContentDialog
|
|
||||||
{
|
|
||||||
Title = title,
|
|
||||||
PrimaryButtonText = LocaleManager.Instance[LocaleKeys.InputDialogOk],
|
|
||||||
SecondaryButtonText = "",
|
|
||||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.InputDialogCancel],
|
|
||||||
Content = content,
|
|
||||||
PrimaryButtonCommand = MiniCommand.Create(() =>
|
|
||||||
{
|
|
||||||
result = UserResult.Ok;
|
|
||||||
input = content.Input;
|
|
||||||
})
|
|
||||||
};
|
|
||||||
await contentDialog.ShowAsync();
|
|
||||||
|
|
||||||
return (result, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Markup.Xaml;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
using SPB.Graphics.OpenGL;
|
|
||||||
using SPB.Windowing;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Controls
|
|
||||||
{
|
|
||||||
public partial class RendererHost : UserControl, IDisposable
|
|
||||||
{
|
|
||||||
private readonly GraphicsDebugLevel _graphicsDebugLevel;
|
|
||||||
private EmbeddedWindow _currentWindow;
|
|
||||||
|
|
||||||
public bool IsVulkan { get; private set; }
|
|
||||||
|
|
||||||
public RendererHost(GraphicsDebugLevel graphicsDebugLevel)
|
|
||||||
{
|
|
||||||
_graphicsDebugLevel = graphicsDebugLevel;
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RendererHost()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateOpenGL()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
|
|
||||||
_currentWindow = new OpenGLEmbeddedWindow(3, 3, _graphicsDebugLevel);
|
|
||||||
Initialize();
|
|
||||||
|
|
||||||
IsVulkan = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
_currentWindow.WindowCreated += CurrentWindow_WindowCreated;
|
|
||||||
_currentWindow.SizeChanged += CurrentWindow_SizeChanged;
|
|
||||||
Content = _currentWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateVulkan()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
|
|
||||||
_currentWindow = new VulkanEmbeddedWindow();
|
|
||||||
Initialize();
|
|
||||||
|
|
||||||
IsVulkan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenGLContextBase GetContext()
|
|
||||||
{
|
|
||||||
if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
|
|
||||||
{
|
|
||||||
return openGlEmbeddedWindow.Context;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnDetachedFromVisualTree(e);
|
|
||||||
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CurrentWindow_SizeChanged(object sender, Size e)
|
|
||||||
{
|
|
||||||
SizeChanged?.Invoke(sender, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CurrentWindow_WindowCreated(object sender, IntPtr e)
|
|
||||||
{
|
|
||||||
RendererInitialized?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MakeCurrent()
|
|
||||||
{
|
|
||||||
if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
|
|
||||||
{
|
|
||||||
openGlEmbeddedWindow.MakeCurrent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MakeCurrent(SwappableNativeWindowBase window)
|
|
||||||
{
|
|
||||||
if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
|
|
||||||
{
|
|
||||||
openGlEmbeddedWindow.MakeCurrent(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SwapBuffers()
|
|
||||||
{
|
|
||||||
if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
|
|
||||||
{
|
|
||||||
openGlEmbeddedWindow.SwapBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public event EventHandler<EventArgs> RendererInitialized;
|
|
||||||
public event Action<object, Size> SizeChanged;
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_currentWindow != null)
|
|
||||||
{
|
|
||||||
_currentWindow.WindowCreated -= CurrentWindow_WindowCreated;
|
|
||||||
_currentWindow.SizeChanged -= CurrentWindow_SizeChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SurfaceKHR CreateVulkanSurface(Instance instance, Vk api)
|
|
||||||
{
|
|
||||||
return (_currentWindow is VulkanEmbeddedWindow vulkanEmbeddedWindow)
|
|
||||||
? vulkanEmbeddedWindow.CreateSurface(instance)
|
|
||||||
: default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
using SPB.Graphics;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
[SupportedOSPlatform("linux")]
|
|
||||||
internal class AvaloniaGlxContext : SPB.Platform.GLX.GLXOpenGLContext
|
|
||||||
{
|
|
||||||
public AvaloniaGlxContext(IntPtr handle)
|
|
||||||
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
|
|
||||||
{
|
|
||||||
ContextHandle = handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
using SPB.Graphics;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
internal class AvaloniaWglContext : SPB.Platform.WGL.WGLOpenGLContext
|
|
||||||
{
|
|
||||||
public AvaloniaWglContext(IntPtr handle)
|
|
||||||
: base(FramebufferFormat.Default, 0, 0, 0, false, null)
|
|
||||||
{
|
|
||||||
ContextHandle = handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,235 +0,0 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Input;
|
|
||||||
using Avalonia.Platform;
|
|
||||||
using SPB.Graphics;
|
|
||||||
using SPB.Platform;
|
|
||||||
using SPB.Platform.GLX;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static Ryujinx.Ava.UI.Helpers.Win32NativeInterop;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
public class EmbeddedWindow : NativeControlHost
|
|
||||||
{
|
|
||||||
private WindowProc _wndProcDelegate;
|
|
||||||
private string _className;
|
|
||||||
|
|
||||||
protected GLXWindow X11Window { get; set; }
|
|
||||||
protected IntPtr WindowHandle { get; set; }
|
|
||||||
protected IntPtr X11Display { get; set; }
|
|
||||||
protected IntPtr NsView { get; set; }
|
|
||||||
protected IntPtr MetalLayer { get; set; }
|
|
||||||
|
|
||||||
private UpdateBoundsCallbackDelegate _updateBoundsCallback;
|
|
||||||
|
|
||||||
public event EventHandler<IntPtr> WindowCreated;
|
|
||||||
public event EventHandler<Size> SizeChanged;
|
|
||||||
|
|
||||||
protected virtual void OnWindowDestroyed() { }
|
|
||||||
protected virtual void OnWindowDestroying()
|
|
||||||
{
|
|
||||||
WindowHandle = IntPtr.Zero;
|
|
||||||
X11Display = IntPtr.Zero;
|
|
||||||
NsView = IntPtr.Zero;
|
|
||||||
MetalLayer = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EmbeddedWindow()
|
|
||||||
{
|
|
||||||
var stateObserverable = this.GetObservable(BoundsProperty);
|
|
||||||
|
|
||||||
stateObserverable.Subscribe(StateChanged);
|
|
||||||
|
|
||||||
Initialized += NativeEmbeddedWindow_Initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void OnWindowCreated() { }
|
|
||||||
|
|
||||||
private void NativeEmbeddedWindow_Initialized(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
OnWindowCreated();
|
|
||||||
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
WindowCreated?.Invoke(this, WindowHandle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StateChanged(Rect rect)
|
|
||||||
{
|
|
||||||
SizeChanged?.Invoke(this, rect.Size);
|
|
||||||
_updateBoundsCallback?.Invoke(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle parent)
|
|
||||||
{
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
return CreateLinux(parent);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
return CreateWin32(parent);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
return CreateMacOs(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.CreateNativeControlCore(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DestroyNativeControlCore(IPlatformHandle control)
|
|
||||||
{
|
|
||||||
OnWindowDestroying();
|
|
||||||
|
|
||||||
if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
DestroyLinux();
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
DestroyWin32(control);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
DestroyMacOS();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
base.DestroyNativeControlCore(control);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnWindowDestroyed();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
|
||||||
protected virtual IPlatformHandle CreateLinux(IPlatformHandle parent)
|
|
||||||
{
|
|
||||||
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
|
|
||||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
|
||||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
|
||||||
|
|
||||||
return new PlatformHandle(WindowHandle, "X11");
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
IPlatformHandle CreateWin32(IPlatformHandle parent)
|
|
||||||
{
|
|
||||||
_className = "NativeWindow-" + Guid.NewGuid();
|
|
||||||
_wndProcDelegate = WndProc;
|
|
||||||
var wndClassEx = new WNDCLASSEX
|
|
||||||
{
|
|
||||||
cbSize = Marshal.SizeOf<WNDCLASSEX>(),
|
|
||||||
hInstance = GetModuleHandle(null),
|
|
||||||
lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate),
|
|
||||||
style = ClassStyles.CS_OWNDC,
|
|
||||||
lpszClassName = Marshal.StringToHGlobalUni(_className),
|
|
||||||
hCursor = CreateArrowCursor()
|
|
||||||
};
|
|
||||||
|
|
||||||
var atom = RegisterClassEx(ref wndClassEx);
|
|
||||||
|
|
||||||
var handle = CreateWindowEx(
|
|
||||||
0,
|
|
||||||
_className,
|
|
||||||
"NativeWindow",
|
|
||||||
WindowStyles.WS_CHILD,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
640,
|
|
||||||
480,
|
|
||||||
parent.Handle,
|
|
||||||
IntPtr.Zero,
|
|
||||||
IntPtr.Zero,
|
|
||||||
IntPtr.Zero);
|
|
||||||
|
|
||||||
WindowHandle = handle;
|
|
||||||
|
|
||||||
Marshal.FreeHGlobal(wndClassEx.lpszClassName);
|
|
||||||
|
|
||||||
return new PlatformHandle(WindowHandle, "HWND");
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
IntPtr WndProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
|
|
||||||
{
|
|
||||||
var point = new Point((long)lParam & 0xFFFF, ((long)lParam >> 16) & 0xFFFF);
|
|
||||||
var root = VisualRoot as Window;
|
|
||||||
bool isLeft = false;
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
case WindowsMessages.LBUTTONDOWN:
|
|
||||||
case WindowsMessages.RBUTTONDOWN:
|
|
||||||
isLeft = msg == WindowsMessages.LBUTTONDOWN;
|
|
||||||
this.RaiseEvent(new PointerPressedEventArgs(
|
|
||||||
this,
|
|
||||||
new Pointer(0, PointerType.Mouse, true),
|
|
||||||
root,
|
|
||||||
this.TranslatePoint(point, root).Value,
|
|
||||||
(ulong)Environment.TickCount64,
|
|
||||||
new PointerPointProperties(isLeft ? RawInputModifiers.LeftMouseButton : RawInputModifiers.RightMouseButton, isLeft ? PointerUpdateKind.LeftButtonPressed : PointerUpdateKind.RightButtonPressed),
|
|
||||||
KeyModifiers.None));
|
|
||||||
break;
|
|
||||||
case WindowsMessages.LBUTTONUP:
|
|
||||||
case WindowsMessages.RBUTTONUP:
|
|
||||||
isLeft = msg == WindowsMessages.LBUTTONUP;
|
|
||||||
this.RaiseEvent(new PointerReleasedEventArgs(
|
|
||||||
this,
|
|
||||||
new Pointer(0, PointerType.Mouse, true),
|
|
||||||
root,
|
|
||||||
this.TranslatePoint(point, root).Value,
|
|
||||||
(ulong)Environment.TickCount64,
|
|
||||||
new PointerPointProperties(isLeft ? RawInputModifiers.LeftMouseButton : RawInputModifiers.RightMouseButton, isLeft ? PointerUpdateKind.LeftButtonReleased : PointerUpdateKind.RightButtonReleased),
|
|
||||||
KeyModifiers.None,
|
|
||||||
isLeft ? MouseButton.Left : MouseButton.Right));
|
|
||||||
break;
|
|
||||||
case WindowsMessages.MOUSEMOVE:
|
|
||||||
this.RaiseEvent(new PointerEventArgs(
|
|
||||||
PointerMovedEvent,
|
|
||||||
this,
|
|
||||||
new Pointer(0, PointerType.Mouse, true),
|
|
||||||
root,
|
|
||||||
this.TranslatePoint(point, root).Value,
|
|
||||||
(ulong)Environment.TickCount64,
|
|
||||||
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.Other),
|
|
||||||
KeyModifiers.None));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("macos")]
|
|
||||||
IPlatformHandle CreateMacOs(IPlatformHandle parent)
|
|
||||||
{
|
|
||||||
MetalLayer = MetalHelper.GetMetalLayer(out IntPtr nsView, out _updateBoundsCallback);
|
|
||||||
|
|
||||||
NsView = nsView;
|
|
||||||
|
|
||||||
return new PlatformHandle(nsView, "NSView");
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyLinux()
|
|
||||||
{
|
|
||||||
X11Window?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
void DestroyWin32(IPlatformHandle handle)
|
|
||||||
{
|
|
||||||
DestroyWindow(handle.Handle);
|
|
||||||
UnregisterClass(_className, GetModuleHandle(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform("macos")]
|
|
||||||
void DestroyMacOS()
|
|
||||||
{
|
|
||||||
MetalHelper.DestroyMetalLayer(NsView, MetalLayer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using Avalonia.OpenGL;
|
|
||||||
using SPB.Graphics.OpenGL;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
internal static class IGlContextExtension
|
|
||||||
{
|
|
||||||
public static OpenGLContextBase AsOpenGLContextBase(this IGlContext context)
|
|
||||||
{
|
|
||||||
var handle = (IntPtr)context.GetType().GetProperty("Handle").GetValue(context);
|
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
return new AvaloniaWglContext(handle);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
return new AvaloniaGlxContext(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Avalonia;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
public delegate void UpdateBoundsCallbackDelegate(Rect rect);
|
|
||||||
|
|
||||||
[SupportedOSPlatform("macos")]
|
|
||||||
static partial class MetalHelper
|
|
||||||
{
|
|
||||||
private const string LibObjCImport = "/usr/lib/libobjc.A.dylib";
|
|
||||||
|
|
||||||
private struct Selector
|
|
||||||
{
|
|
||||||
public readonly IntPtr NativePtr;
|
|
||||||
|
|
||||||
public unsafe Selector(string value)
|
|
||||||
{
|
|
||||||
int size = System.Text.Encoding.UTF8.GetMaxByteCount(value.Length);
|
|
||||||
byte* data = stackalloc byte[size];
|
|
||||||
|
|
||||||
fixed (char* pValue = value)
|
|
||||||
{
|
|
||||||
System.Text.Encoding.UTF8.GetBytes(pValue, value.Length, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
NativePtr = sel_registerName(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator Selector(string value) => new Selector(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static unsafe IntPtr GetClass(string value)
|
|
||||||
{
|
|
||||||
int size = System.Text.Encoding.UTF8.GetMaxByteCount(value.Length);
|
|
||||||
byte* data = stackalloc byte[size];
|
|
||||||
|
|
||||||
fixed (char* pValue = value)
|
|
||||||
{
|
|
||||||
System.Text.Encoding.UTF8.GetBytes(pValue, value.Length, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objc_getClass(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct NSPoint
|
|
||||||
{
|
|
||||||
public double X;
|
|
||||||
public double Y;
|
|
||||||
|
|
||||||
public NSPoint(double x, double y)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct NSRect
|
|
||||||
{
|
|
||||||
public NSPoint Pos;
|
|
||||||
public NSPoint Size;
|
|
||||||
|
|
||||||
public NSRect(double x, double y, double width, double height)
|
|
||||||
{
|
|
||||||
Pos = new NSPoint(x, y);
|
|
||||||
Size = new NSPoint(width, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IntPtr GetMetalLayer(out IntPtr nsView, out UpdateBoundsCallbackDelegate updateBounds)
|
|
||||||
{
|
|
||||||
// Create a new CAMetalLayer.
|
|
||||||
IntPtr layerClass = GetClass("CAMetalLayer");
|
|
||||||
IntPtr metalLayer = IntPtr_objc_msgSend(layerClass, "alloc");
|
|
||||||
objc_msgSend(metalLayer, "init");
|
|
||||||
|
|
||||||
// Create a child NSView to render into.
|
|
||||||
IntPtr nsViewClass = GetClass("NSView");
|
|
||||||
IntPtr child = IntPtr_objc_msgSend(nsViewClass, "alloc");
|
|
||||||
objc_msgSend(child, "init", new NSRect(0, 0, 0, 0));
|
|
||||||
|
|
||||||
// Make its renderer our metal layer.
|
|
||||||
objc_msgSend(child, "setWantsLayer:", (byte)1);
|
|
||||||
objc_msgSend(child, "setLayer:", metalLayer);
|
|
||||||
objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
|
|
||||||
|
|
||||||
// Ensure the scale factor is up to date.
|
|
||||||
updateBounds = (Rect rect) => {
|
|
||||||
objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
|
|
||||||
};
|
|
||||||
|
|
||||||
nsView = child;
|
|
||||||
return metalLayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DestroyMetalLayer(IntPtr nsView, IntPtr metalLayer)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static unsafe partial IntPtr sel_registerName(byte* data);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static unsafe partial IntPtr objc_getClass(byte* data);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static partial void objc_msgSend(IntPtr receiver, Selector selector);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport)]
|
|
||||||
private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value);
|
|
||||||
|
|
||||||
[LibraryImport(LibObjCImport, EntryPoint = "objc_msgSend")]
|
|
||||||
private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
using OpenTK.Graphics.OpenGL;
|
|
||||||
using Ryujinx.Common.Configuration;
|
|
||||||
using SPB.Graphics;
|
|
||||||
using SPB.Graphics.OpenGL;
|
|
||||||
using SPB.Platform;
|
|
||||||
using SPB.Platform.WGL;
|
|
||||||
using SPB.Windowing;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
public class OpenGLEmbeddedWindow : EmbeddedWindow
|
|
||||||
{
|
|
||||||
private readonly int _major;
|
|
||||||
private readonly int _minor;
|
|
||||||
private readonly GraphicsDebugLevel _graphicsDebugLevel;
|
|
||||||
private SwappableNativeWindowBase _window;
|
|
||||||
public OpenGLContextBase Context { get; set; }
|
|
||||||
|
|
||||||
public OpenGLEmbeddedWindow(int major, int minor, GraphicsDebugLevel graphicsDebugLevel)
|
|
||||||
{
|
|
||||||
_major = major;
|
|
||||||
_minor = minor;
|
|
||||||
_graphicsDebugLevel = graphicsDebugLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnWindowDestroying()
|
|
||||||
{
|
|
||||||
Context.Dispose();
|
|
||||||
base.OnWindowDestroying();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnWindowCreated()
|
|
||||||
{
|
|
||||||
base.OnWindowCreated();
|
|
||||||
|
|
||||||
if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
_window = new WGLWindow(new NativeHandle(WindowHandle));
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
_window = X11Window;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new PlatformNotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags = OpenGLContextFlags.Compat;
|
|
||||||
if (_graphicsDebugLevel != GraphicsDebugLevel.None)
|
|
||||||
{
|
|
||||||
flags |= OpenGLContextFlags.Debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context = PlatformHelper.CreateOpenGLContext(FramebufferFormat.Default, _major, _minor, flags);
|
|
||||||
|
|
||||||
Context.Initialize(_window);
|
|
||||||
Context.MakeCurrent(_window);
|
|
||||||
|
|
||||||
var bindingsContext = new OpenToolkitBindingsContext(Context.GetProcAddress);
|
|
||||||
|
|
||||||
GL.LoadBindings(bindingsContext);
|
|
||||||
Context.MakeCurrent(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MakeCurrent()
|
|
||||||
{
|
|
||||||
Context?.MakeCurrent(_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MakeCurrent(NativeWindowBase window)
|
|
||||||
{
|
|
||||||
Context?.MakeCurrent(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SwapBuffers()
|
|
||||||
{
|
|
||||||
_window.SwapBuffers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
using Avalonia.Platform;
|
|
||||||
using Silk.NET.Vulkan;
|
|
||||||
using SPB.Graphics.Vulkan;
|
|
||||||
using SPB.Platform.GLX;
|
|
||||||
using SPB.Platform.Metal;
|
|
||||||
using SPB.Platform.Win32;
|
|
||||||
using SPB.Platform.X11;
|
|
||||||
using SPB.Windowing;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
|
||||||
{
|
|
||||||
public class VulkanEmbeddedWindow : EmbeddedWindow
|
|
||||||
{
|
|
||||||
private NativeWindowBase _window;
|
|
||||||
|
|
||||||
[SupportedOSPlatform("linux")]
|
|
||||||
protected override IPlatformHandle CreateLinux(IPlatformHandle parent)
|
|
||||||
{
|
|
||||||
X11Window = new GLXWindow(new NativeHandle(X11.DefaultDisplay), new NativeHandle(parent.Handle));
|
|
||||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
|
||||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
|
||||||
|
|
||||||
X11Window.Hide();
|
|
||||||
|
|
||||||
return new PlatformHandle(WindowHandle, "X11");
|
|
||||||
}
|
|
||||||
|
|
||||||
public SurfaceKHR CreateSurface(Instance instance)
|
|
||||||
{
|
|
||||||
if (OperatingSystem.IsWindows())
|
|
||||||
{
|
|
||||||
_window = new SimpleWin32Window(new NativeHandle(WindowHandle));
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsLinux())
|
|
||||||
{
|
|
||||||
_window = new SimpleX11Window(new NativeHandle(X11Display), new NativeHandle(WindowHandle));
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.IsMacOS())
|
|
||||||
{
|
|
||||||
_window = new SimpleMetalWindow(new NativeHandle(NsView), new NativeHandle(MetalLayer));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new PlatformNotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SurfaceKHR((ulong?)VulkanHelper.CreateWindowSurface(instance.Handle, _window));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models
|
|
||||||
{
|
|
||||||
public class Amiibo
|
|
||||||
{
|
|
||||||
public struct AmiiboJson
|
|
||||||
{
|
|
||||||
[JsonPropertyName("amiibo")] public List<AmiiboApi> Amiibo { get; set; }
|
|
||||||
[JsonPropertyName("lastUpdated")] public DateTime LastUpdated { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct AmiiboApi
|
|
||||||
{
|
|
||||||
[JsonPropertyName("name")] public string Name { get; set; }
|
|
||||||
[JsonPropertyName("head")] public string Head { get; set; }
|
|
||||||
[JsonPropertyName("tail")] public string Tail { get; set; }
|
|
||||||
[JsonPropertyName("image")] public string Image { get; set; }
|
|
||||||
[JsonPropertyName("amiiboSeries")] public string AmiiboSeries { get; set; }
|
|
||||||
[JsonPropertyName("character")] public string Character { get; set; }
|
|
||||||
[JsonPropertyName("gameSeries")] public string GameSeries { get; set; }
|
|
||||||
[JsonPropertyName("type")] public string Type { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("release")] public Dictionary<string, string> Release { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("gamesSwitch")] public List<AmiiboApiGamesSwitch> GamesSwitch { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetId()
|
|
||||||
{
|
|
||||||
return Head + Tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
if (obj is AmiiboApi amiibo)
|
|
||||||
{
|
|
||||||
return amiibo.Head + amiibo.Tail == Head + Tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return base.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AmiiboApiGamesSwitch
|
|
||||||
{
|
|
||||||
[JsonPropertyName("amiiboUsage")] public List<AmiiboApiUsage> AmiiboUsage { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("gameID")] public List<string> GameId { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("gameName")] public string GameName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AmiiboApiUsage
|
|
||||||
{
|
|
||||||
[JsonPropertyName("Usage")] public string Usage { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("write")] public bool Write { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using LibHac.Ns;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models
|
|
||||||
{
|
|
||||||
internal class TitleUpdateModel
|
|
||||||
{
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
public bool IsNoUpdate { get; }
|
|
||||||
public ApplicationControlProperty Control { get; }
|
|
||||||
public string Path { get; }
|
|
||||||
|
|
||||||
public string Label => IsNoUpdate
|
|
||||||
? LocaleManager.Instance[LocaleKeys.NoUpdate]
|
|
||||||
: string.Format(LocaleManager.Instance[LocaleKeys.TitleUpdateVersionLabel], Control.DisplayVersionString.ToString(),
|
|
||||||
Path);
|
|
||||||
|
|
||||||
public TitleUpdateModel(ApplicationControlProperty control, string path, bool isNoUpdate = false)
|
|
||||||
{
|
|
||||||
Control = control;
|
|
||||||
Path = path;
|
|
||||||
IsNoUpdate = isNoUpdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
<UserControl
|
|
||||||
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsInputView"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
|
||||||
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
|
|
||||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
x:CompileBindings="True"
|
|
||||||
x:DataType="viewModels:SettingsViewModel">
|
|
||||||
<Design.DataContext>
|
|
||||||
<viewModels:SettingsViewModel />
|
|
||||||
</Design.DataContext>
|
|
||||||
<ScrollViewer
|
|
||||||
Name="InputPage"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
HorizontalScrollBarVisibility="Disabled"
|
|
||||||
VerticalScrollBarVisibility="Auto">
|
|
||||||
<Border Classes="settings">
|
|
||||||
<StackPanel Margin="4" Orientation="Vertical">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<CheckBox Margin="5,0"
|
|
||||||
ToolTip.Tip="{locale:Locale DockModeToggleTooltip}"
|
|
||||||
IsChecked="{Binding EnableDockedMode}">
|
|
||||||
<TextBlock VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale SettingsTabInputEnableDockedMode}" />
|
|
||||||
</CheckBox>
|
|
||||||
<CheckBox Margin="5,0"
|
|
||||||
ToolTip.Tip="{locale:Locale DirectKeyboardTooltip}"
|
|
||||||
IsChecked="{Binding EnableKeyboard}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabInputDirectKeyboardAccess}" />
|
|
||||||
</CheckBox>
|
|
||||||
<CheckBox Margin="5,0"
|
|
||||||
ToolTip.Tip="{locale:Locale DirectMouseTooltip}"
|
|
||||||
IsChecked="{Binding EnableMouse}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabInputDirectMouseAccess}" />
|
|
||||||
</CheckBox>
|
|
||||||
</StackPanel>
|
|
||||||
<window:ControllerSettingsWindow Name="ControllerSettings" Margin="0" MinHeight="600" />
|
|
||||||
</StackPanel>
|
|
||||||
</Border>
|
|
||||||
</ScrollViewer>
|
|
||||||
</UserControl>
|
|
@ -1,172 +0,0 @@
|
|||||||
<window:StyleableWindow
|
|
||||||
x:Class="Ryujinx.Ava.UI.Windows.DownloadableContentManagerWindow"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
|
|
||||||
Width="800"
|
|
||||||
Height="500"
|
|
||||||
MinWidth="800"
|
|
||||||
MinHeight="500"
|
|
||||||
MaxWidth="800"
|
|
||||||
MaxHeight="500"
|
|
||||||
SizeToContent="Height"
|
|
||||||
WindowStartupLocation="CenterOwner"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Focusable="True">
|
|
||||||
<Grid Name="DownloadableContentGrid" Margin="15">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="*" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Name="Heading"
|
|
||||||
Grid.Row="1"
|
|
||||||
MaxWidth="500"
|
|
||||||
Margin="20,15,20,20"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
LineHeight="18"
|
|
||||||
TextAlignment="Center"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
<DockPanel
|
|
||||||
Grid.Row="2"
|
|
||||||
Margin="0"
|
|
||||||
HorizontalAlignment="Left">
|
|
||||||
<Button
|
|
||||||
Name="EnableAllButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding EnableAll}">
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerEnableAllButton}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="DisableAllButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding DisableAll}">
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerDisableAllButton}" />
|
|
||||||
</Button>
|
|
||||||
</DockPanel>
|
|
||||||
<Border
|
|
||||||
Grid.Row="3"
|
|
||||||
Margin="5"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
BorderThickness="1">
|
|
||||||
<ScrollViewer
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
VerticalScrollBarVisibility="Auto">
|
|
||||||
<DataGrid
|
|
||||||
Name="DlcDataGrid"
|
|
||||||
MinHeight="200"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
CanUserReorderColumns="False"
|
|
||||||
CanUserResizeColumns="True"
|
|
||||||
CanUserSortColumns="True"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
Items="{Binding _downloadableContents}"
|
|
||||||
SelectionMode="Extended"
|
|
||||||
VerticalScrollBarVisibility="Auto">
|
|
||||||
<DataGrid.Styles>
|
|
||||||
<Styles>
|
|
||||||
<Style Selector="DataGridCell:nth-child(3), DataGridCell:nth-child(4)">
|
|
||||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
|
||||||
</Style>
|
|
||||||
</Styles>
|
|
||||||
<Styles>
|
|
||||||
<Style Selector="DataGridCell:nth-child(1)">
|
|
||||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Right" />
|
|
||||||
</Style>
|
|
||||||
</Styles>
|
|
||||||
</DataGrid.Styles>
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTemplateColumn Width="90">
|
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<CheckBox
|
|
||||||
Width="50"
|
|
||||||
MinWidth="40"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
IsChecked="{Binding Enabled}" />
|
|
||||||
</DataTemplate>
|
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
|
||||||
<DataGridTemplateColumn.Header>
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerTableHeadingEnabledLabel}" />
|
|
||||||
</DataGridTemplateColumn.Header>
|
|
||||||
</DataGridTemplateColumn>
|
|
||||||
<DataGridTextColumn Width="140" Binding="{Binding TitleId}">
|
|
||||||
<DataGridTextColumn.Header>
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerTableHeadingTitleIdLabel}" />
|
|
||||||
</DataGridTextColumn.Header>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Width="280" Binding="{Binding FullPath}">
|
|
||||||
<DataGridTextColumn.Header>
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerTableHeadingFullPathLabel}" />
|
|
||||||
</DataGridTextColumn.Header>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
<DataGridTextColumn Binding="{Binding ContainerPath}">
|
|
||||||
<DataGridTextColumn.Header>
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerTableHeadingContainerPathLabel}" />
|
|
||||||
</DataGridTextColumn.Header>
|
|
||||||
</DataGridTextColumn>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</ScrollViewer>
|
|
||||||
</Border>
|
|
||||||
<DockPanel
|
|
||||||
Grid.Row="4"
|
|
||||||
Margin="0"
|
|
||||||
HorizontalAlignment="Stretch">
|
|
||||||
<DockPanel Margin="0" HorizontalAlignment="Left">
|
|
||||||
<Button
|
|
||||||
Name="AddButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding Add}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="RemoveButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding RemoveSelected}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralRemove}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="RemoveAllButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding RemoveAll}">
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
|
|
||||||
</Button>
|
|
||||||
</DockPanel>
|
|
||||||
<DockPanel Margin="0" HorizontalAlignment="Right">
|
|
||||||
<Button
|
|
||||||
Name="SaveButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding SaveAndClose}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="CancelButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding Close}">
|
|
||||||
<TextBlock Text="{locale:Locale InputDialogCancel}" />
|
|
||||||
</Button>
|
|
||||||
</DockPanel>
|
|
||||||
</DockPanel>
|
|
||||||
</Grid>
|
|
||||||
</window:StyleableWindow>
|
|
@ -1,115 +0,0 @@
|
|||||||
<window:StyleableWindow
|
|
||||||
x:Class="Ryujinx.Ava.UI.Windows.TitleUpdateWindow"
|
|
||||||
xmlns="https://github.com/avaloniaui"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
|
|
||||||
Width="600"
|
|
||||||
Height="400"
|
|
||||||
MinWidth="600"
|
|
||||||
MinHeight="400"
|
|
||||||
MaxWidth="600"
|
|
||||||
MaxHeight="400"
|
|
||||||
SizeToContent="Height"
|
|
||||||
WindowStartupLocation="CenterOwner"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Focusable="True">
|
|
||||||
<Grid Margin="15">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
<RowDefinition Height="*" />
|
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Name="Heading"
|
|
||||||
Grid.Row="1"
|
|
||||||
MaxWidth="500"
|
|
||||||
Margin="20,15,20,20"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
LineHeight="18"
|
|
||||||
TextAlignment="Center"
|
|
||||||
TextWrapping="Wrap" />
|
|
||||||
<Border
|
|
||||||
Grid.Row="2"
|
|
||||||
Margin="5"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
BorderBrush="Gray"
|
|
||||||
BorderThickness="1">
|
|
||||||
<ScrollViewer
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
HorizontalScrollBarVisibility="Auto"
|
|
||||||
VerticalScrollBarVisibility="Auto">
|
|
||||||
<ItemsControl
|
|
||||||
Margin="10"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Items="{Binding _titleUpdates}">
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<RadioButton
|
|
||||||
Padding="8,0"
|
|
||||||
VerticalContentAlignment="Center"
|
|
||||||
GroupName="Update"
|
|
||||||
IsChecked="{Binding IsEnabled, Mode=TwoWay}">
|
|
||||||
<Label
|
|
||||||
Margin="0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Content="{Binding Label}"
|
|
||||||
FontSize="12" />
|
|
||||||
</RadioButton>
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</ScrollViewer>
|
|
||||||
</Border>
|
|
||||||
<DockPanel
|
|
||||||
Grid.Row="3"
|
|
||||||
Margin="0"
|
|
||||||
HorizontalAlignment="Stretch">
|
|
||||||
<DockPanel Margin="0" HorizontalAlignment="Left">
|
|
||||||
<Button
|
|
||||||
Name="AddButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding Add}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="RemoveButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding RemoveSelected}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralRemove}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="RemoveAllButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding RemoveAll}">
|
|
||||||
<TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
|
|
||||||
</Button>
|
|
||||||
</DockPanel>
|
|
||||||
<DockPanel Margin="0" HorizontalAlignment="Right">
|
|
||||||
<Button
|
|
||||||
Name="SaveButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding Save}">
|
|
||||||
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Name="CancelButton"
|
|
||||||
MinWidth="90"
|
|
||||||
Margin="5"
|
|
||||||
Command="{Binding Close}">
|
|
||||||
<TextBlock Text="{locale:Locale InputDialogCancel}" />
|
|
||||||
</Button>
|
|
||||||
</DockPanel>
|
|
||||||
</DockPanel>
|
|
||||||
</Grid>
|
|
||||||
</window:StyleableWindow>
|
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration
|
|
||||||
{
|
|
||||||
public enum BackendThreading
|
|
||||||
{
|
|
||||||
Auto,
|
|
||||||
Off,
|
|
||||||
On
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration
|
|
||||||
{
|
|
||||||
public enum GraphicsBackend
|
|
||||||
{
|
|
||||||
Vulkan,
|
|
||||||
OpenGl
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
|
||||||
{
|
|
||||||
public enum MotionInputBackendType : byte
|
|
||||||
{
|
|
||||||
Invalid,
|
|
||||||
GamepadDriver,
|
|
||||||
CemuHook
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
|
||||||
{
|
|
||||||
public enum StickInputId : byte
|
|
||||||
{
|
|
||||||
Unbound,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
|
|
||||||
Count
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
[Flags]
|
|
||||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
|
||||||
public enum ControllerType : int
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
ProController = 1 << 0,
|
|
||||||
Handheld = 1 << 1,
|
|
||||||
JoyconPair = 1 << 2,
|
|
||||||
JoyconLeft = 1 << 3,
|
|
||||||
JoyconRight = 1 << 4,
|
|
||||||
Invalid = 1 << 5,
|
|
||||||
Pokeball = 1 << 6,
|
|
||||||
SystemExternal = 1 << 29,
|
|
||||||
System = 1 << 30
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
public class GenericInputConfigurationCommon<Button> : InputConfig where Button : unmanaged
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Left JoyCon Controller Bindings
|
|
||||||
/// </summary>
|
|
||||||
public LeftJoyconCommonConfig<Button> LeftJoycon { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Right JoyCon Controller Bindings
|
|
||||||
/// </summary>
|
|
||||||
public RightJoyconCommonConfig<Button> RightJoycon { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
public enum InputBackendType
|
|
||||||
{
|
|
||||||
Invalid,
|
|
||||||
WindowKeyboard,
|
|
||||||
GamepadSDL2,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid.Keyboard
|
|
||||||
{
|
|
||||||
public class JoyconConfigKeyboardStick<Key> where Key: unmanaged
|
|
||||||
{
|
|
||||||
public Key StickUp { get; set; }
|
|
||||||
public Key StickDown { get; set; }
|
|
||||||
public Key StickLeft { get; set; }
|
|
||||||
public Key StickRight { get; set; }
|
|
||||||
public Key StickButton { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
public class LeftJoyconCommonConfig<Button>
|
|
||||||
{
|
|
||||||
public Button ButtonMinus { get; set; }
|
|
||||||
public Button ButtonL { get; set; }
|
|
||||||
public Button ButtonZl { get; set; }
|
|
||||||
public Button ButtonSl { get; set; }
|
|
||||||
public Button ButtonSr { get; set; }
|
|
||||||
public Button DpadUp { get; set; }
|
|
||||||
public Button DpadDown { get; set; }
|
|
||||||
public Button DpadLeft { get; set; }
|
|
||||||
public Button DpadRight { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
|
||||||
public enum PlayerIndex : int
|
|
||||||
{
|
|
||||||
Player1 = 0,
|
|
||||||
Player2 = 1,
|
|
||||||
Player3 = 2,
|
|
||||||
Player4 = 3,
|
|
||||||
Player5 = 4,
|
|
||||||
Player6 = 5,
|
|
||||||
Player7 = 6,
|
|
||||||
Player8 = 7,
|
|
||||||
Handheld = 8,
|
|
||||||
Unknown = 9,
|
|
||||||
Auto = 10 // Shouldn't be used directly
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid
|
|
||||||
{
|
|
||||||
public class RightJoyconCommonConfig<Button>
|
|
||||||
{
|
|
||||||
public Button ButtonPlus { get; set; }
|
|
||||||
public Button ButtonR { get; set; }
|
|
||||||
public Button ButtonZr { get; set; }
|
|
||||||
public Button ButtonSl { get; set; }
|
|
||||||
public Button ButtonSr { get; set; }
|
|
||||||
public Button ButtonX { get; set; }
|
|
||||||
public Button ButtonB { get; set; }
|
|
||||||
public Button ButtonY { get; set; }
|
|
||||||
public Button ButtonA { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Common.Configuration
|
|
||||||
{
|
|
||||||
public enum MemoryManagerMode : byte
|
|
||||||
{
|
|
||||||
SoftwarePageTable,
|
|
||||||
HostMapped,
|
|
||||||
HostMappedUnsafe
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
|
||||||
{
|
|
||||||
internal class DefaultLogFormatter : ILogFormatter
|
|
||||||
{
|
|
||||||
private static readonly ObjectPool<StringBuilder> _stringBuilderPool = SharedPools.Default<StringBuilder>();
|
|
||||||
|
|
||||||
public string Format(LogEventArgs args)
|
|
||||||
{
|
|
||||||
StringBuilder sb = _stringBuilderPool.Allocate();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sb.Clear();
|
|
||||||
|
|
||||||
sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", args.Time);
|
|
||||||
sb.Append($" |{args.Level.ToString()[0]}| ");
|
|
||||||
|
|
||||||
if (args.ThreadName != null)
|
|
||||||
{
|
|
||||||
sb.Append(args.ThreadName);
|
|
||||||
sb.Append(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(args.Message);
|
|
||||||
|
|
||||||
if (args.Data != null)
|
|
||||||
{
|
|
||||||
PropertyInfo[] props = args.Data.GetType().GetProperties();
|
|
||||||
|
|
||||||
sb.Append(" {");
|
|
||||||
|
|
||||||
foreach (var prop in props)
|
|
||||||
{
|
|
||||||
sb.Append(prop.Name);
|
|
||||||
sb.Append(": ");
|
|
||||||
|
|
||||||
if (typeof(Array).IsAssignableFrom(prop.PropertyType))
|
|
||||||
{
|
|
||||||
Array array = (Array)prop.GetValue(args.Data);
|
|
||||||
foreach (var item in array)
|
|
||||||
{
|
|
||||||
sb.Append(item.ToString());
|
|
||||||
sb.Append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array.Length > 0)
|
|
||||||
{
|
|
||||||
sb.Remove(sb.Length - 2, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(prop.GetValue(args.Data));
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(" ; ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We remove the final ';' from the string
|
|
||||||
if (props.Length > 0)
|
|
||||||
{
|
|
||||||
sb.Remove(sb.Length - 3, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_stringBuilderPool.Release(sb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Logging
|
|
||||||
{
|
|
||||||
public class LogEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public readonly LogLevel Level;
|
|
||||||
public readonly TimeSpan Time;
|
|
||||||
public readonly string ThreadName;
|
|
||||||
|
|
||||||
public readonly string Message;
|
|
||||||
public readonly object Data;
|
|
||||||
|
|
||||||
public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message)
|
|
||||||
{
|
|
||||||
Level = level;
|
|
||||||
Time = time;
|
|
||||||
ThreadName = threadName;
|
|
||||||
Message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message, object data)
|
|
||||||
{
|
|
||||||
Level = level;
|
|
||||||
Time = time;
|
|
||||||
ThreadName = threadName;
|
|
||||||
Message = message;
|
|
||||||
Data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Memory
|
|
||||||
{
|
|
||||||
public ref struct SpanReader
|
|
||||||
{
|
|
||||||
private ReadOnlySpan<byte> _input;
|
|
||||||
|
|
||||||
public int Length => _input.Length;
|
|
||||||
|
|
||||||
public SpanReader(ReadOnlySpan<byte> input)
|
|
||||||
{
|
|
||||||
_input = input;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Read<T>() where T : unmanaged
|
|
||||||
{
|
|
||||||
T value = MemoryMarshal.Cast<byte, T>(_input)[0];
|
|
||||||
|
|
||||||
_input = _input.Slice(Unsafe.SizeOf<T>());
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlySpan<byte> GetSpan(int size)
|
|
||||||
{
|
|
||||||
ReadOnlySpan<byte> data = _input.Slice(0, size);
|
|
||||||
|
|
||||||
_input = _input.Slice(size);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T ReadAt<T>(int offset) where T : unmanaged
|
|
||||||
{
|
|
||||||
return MemoryMarshal.Cast<byte, T>(_input.Slice(offset))[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlySpan<byte> GetSpanAt(int offset, int size)
|
|
||||||
{
|
|
||||||
return _input.Slice(offset, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Skip(int size)
|
|
||||||
{
|
|
||||||
_input = _input.Slice(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
using Ryujinx.Common.Configuration.Hid;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Utilities
|
|
||||||
{
|
|
||||||
public class JsonHelper
|
|
||||||
{
|
|
||||||
public static JsonNamingPolicy SnakeCase { get; }
|
|
||||||
|
|
||||||
private class SnakeCaseNamingPolicy : JsonNamingPolicy
|
|
||||||
{
|
|
||||||
public override string ConvertName(string name)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(name))
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
for (int i = 0; i < name.Length; i++)
|
|
||||||
{
|
|
||||||
char c = name[i];
|
|
||||||
|
|
||||||
if (char.IsUpper(c))
|
|
||||||
{
|
|
||||||
if (i == 0 || char.IsUpper(name[i - 1]))
|
|
||||||
{
|
|
||||||
builder.Append(char.ToLowerInvariant(c));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.Append("_");
|
|
||||||
builder.Append(char.ToLowerInvariant(c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
builder.Append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static JsonHelper()
|
|
||||||
{
|
|
||||||
SnakeCase = new SnakeCaseNamingPolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonSerializerOptions GetDefaultSerializerOptions(bool prettyPrint = false)
|
|
||||||
{
|
|
||||||
JsonSerializerOptions options = new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
DictionaryKeyPolicy = SnakeCase,
|
|
||||||
PropertyNamingPolicy = SnakeCase,
|
|
||||||
WriteIndented = prettyPrint,
|
|
||||||
AllowTrailingCommas = true,
|
|
||||||
ReadCommentHandling = JsonCommentHandling.Skip
|
|
||||||
};
|
|
||||||
|
|
||||||
options.Converters.Add(new JsonStringEnumConverter());
|
|
||||||
options.Converters.Add(new JsonInputConfigConverter());
|
|
||||||
options.Converters.Add(new JsonMotionConfigControllerConverter());
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T Deserialize<T>(Stream stream)
|
|
||||||
{
|
|
||||||
using (BinaryReader reader = new BinaryReader(stream))
|
|
||||||
{
|
|
||||||
return JsonSerializer.Deserialize<T>(reader.ReadBytes((int)(stream.Length - stream.Position)), GetDefaultSerializerOptions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T DeserializeFromFile<T>(string path)
|
|
||||||
{
|
|
||||||
return Deserialize<T>(File.ReadAllText(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T Deserialize<T>(string json)
|
|
||||||
{
|
|
||||||
return JsonSerializer.Deserialize<T>(json, GetDefaultSerializerOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Serialize<TValue>(Stream stream, TValue obj, bool prettyPrint = false)
|
|
||||||
{
|
|
||||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
|
||||||
{
|
|
||||||
writer.Write(SerializeToUtf8Bytes(obj, prettyPrint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string Serialize<TValue>(TValue obj, bool prettyPrint = false)
|
|
||||||
{
|
|
||||||
return JsonSerializer.Serialize(obj, GetDefaultSerializerOptions(prettyPrint));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] SerializeToUtf8Bytes<T>(T obj, bool prettyPrint = false)
|
|
||||||
{
|
|
||||||
return JsonSerializer.SerializeToUtf8Bytes(obj, GetDefaultSerializerOptions(prettyPrint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Ryujinx.Common.Utilities
|
|
||||||
{
|
|
||||||
public static class StreamUtils
|
|
||||||
{
|
|
||||||
public static byte[] StreamToBytes(Stream input)
|
|
||||||
{
|
|
||||||
using (MemoryStream stream = new MemoryStream())
|
|
||||||
{
|
|
||||||
input.CopyTo(stream);
|
|
||||||
|
|
||||||
return stream.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using Ryujinx.Memory.Tracking;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Tracking
|
|
||||||
{
|
|
||||||
public class CpuMultiRegionHandle : IMultiRegionHandle
|
|
||||||
{
|
|
||||||
private readonly MultiRegionHandle _impl;
|
|
||||||
|
|
||||||
public bool Dirty => _impl.Dirty;
|
|
||||||
|
|
||||||
internal CpuMultiRegionHandle(MultiRegionHandle impl)
|
|
||||||
{
|
|
||||||
_impl = impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => _impl.Dispose();
|
|
||||||
public void ForceDirty(ulong address, ulong size) => _impl.ForceDirty(address, size);
|
|
||||||
public IEnumerable<IRegionHandle> GetHandles() => _impl.GetHandles();
|
|
||||||
public void QueryModified(Action<ulong, ulong> modifiedAction) => _impl.QueryModified(modifiedAction);
|
|
||||||
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction) => _impl.QueryModified(address, size, modifiedAction);
|
|
||||||
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction, int sequenceNumber) => _impl.QueryModified(address, size, modifiedAction, sequenceNumber);
|
|
||||||
public void RegisterAction(ulong address, ulong size, RegionSignal action) => _impl.RegisterAction(address, size, action);
|
|
||||||
public void RegisterPreciseAction(ulong address, ulong size, PreciseRegionSignal action) => _impl.RegisterPreciseAction(address, size, action);
|
|
||||||
public void SignalWrite() => _impl.SignalWrite();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
using Ryujinx.Memory.Tracking;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Tracking
|
|
||||||
{
|
|
||||||
public class CpuRegionHandle : IRegionHandle
|
|
||||||
{
|
|
||||||
private readonly RegionHandle _impl;
|
|
||||||
|
|
||||||
public bool Dirty => _impl.Dirty;
|
|
||||||
public bool Unmapped => _impl.Unmapped;
|
|
||||||
public ulong Address => _impl.Address;
|
|
||||||
public ulong Size => _impl.Size;
|
|
||||||
public ulong EndAddress => _impl.EndAddress;
|
|
||||||
|
|
||||||
internal CpuRegionHandle(RegionHandle impl)
|
|
||||||
{
|
|
||||||
_impl = impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => _impl.Dispose();
|
|
||||||
public bool DirtyOrVolatile() => _impl.DirtyOrVolatile();
|
|
||||||
public void ForceDirty() => _impl.ForceDirty();
|
|
||||||
public IRegionHandle GetHandle() => _impl;
|
|
||||||
public void RegisterAction(RegionSignal action) => _impl.RegisterAction(action);
|
|
||||||
public void RegisterPreciseAction(PreciseRegionSignal action) => _impl.RegisterPreciseAction(action);
|
|
||||||
public void RegisterDirtyEvent(Action action) => _impl.RegisterDirtyEvent(action);
|
|
||||||
public void Reprotect(bool asDirty = false) => _impl.Reprotect(asDirty);
|
|
||||||
|
|
||||||
public bool OverlapsWith(ulong address, ulong size) => _impl.OverlapsWith(address, size);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
using Ryujinx.Memory.Tracking;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Tracking
|
|
||||||
{
|
|
||||||
public class CpuSmartMultiRegionHandle : IMultiRegionHandle
|
|
||||||
{
|
|
||||||
private readonly SmartMultiRegionHandle _impl;
|
|
||||||
|
|
||||||
public bool Dirty => _impl.Dirty;
|
|
||||||
|
|
||||||
internal CpuSmartMultiRegionHandle(SmartMultiRegionHandle impl)
|
|
||||||
{
|
|
||||||
_impl = impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() => _impl.Dispose();
|
|
||||||
public void ForceDirty(ulong address, ulong size) => _impl.ForceDirty(address, size);
|
|
||||||
public void RegisterAction(RegionSignal action) => _impl.RegisterAction(action);
|
|
||||||
public void RegisterPreciseAction(PreciseRegionSignal action) => _impl.RegisterPreciseAction(action);
|
|
||||||
public void QueryModified(Action<ulong, ulong> modifiedAction) => _impl.QueryModified(modifiedAction);
|
|
||||||
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction) => _impl.QueryModified(address, size, modifiedAction);
|
|
||||||
public void QueryModified(ulong address, ulong size, Action<ulong, ulong> modifiedAction, int sequenceNumber) => _impl.QueryModified(address, size, modifiedAction, sequenceNumber);
|
|
||||||
public void SignalWrite() => _impl.SignalWrite();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum BlendFactor
|
|
||||||
{
|
|
||||||
Zero = 1,
|
|
||||||
One,
|
|
||||||
SrcColor,
|
|
||||||
OneMinusSrcColor,
|
|
||||||
SrcAlpha,
|
|
||||||
OneMinusSrcAlpha,
|
|
||||||
DstAlpha,
|
|
||||||
OneMinusDstAlpha,
|
|
||||||
DstColor,
|
|
||||||
OneMinusDstColor,
|
|
||||||
SrcAlphaSaturate,
|
|
||||||
Src1Color = 0x10,
|
|
||||||
OneMinusSrc1Color,
|
|
||||||
Src1Alpha,
|
|
||||||
OneMinusSrc1Alpha,
|
|
||||||
ConstantColor = 0xc001,
|
|
||||||
OneMinusConstantColor,
|
|
||||||
ConstantAlpha,
|
|
||||||
OneMinusConstantAlpha,
|
|
||||||
|
|
||||||
ZeroGl = 0x4000,
|
|
||||||
OneGl = 0x4001,
|
|
||||||
SrcColorGl = 0x4300,
|
|
||||||
OneMinusSrcColorGl = 0x4301,
|
|
||||||
SrcAlphaGl = 0x4302,
|
|
||||||
OneMinusSrcAlphaGl = 0x4303,
|
|
||||||
DstAlphaGl = 0x4304,
|
|
||||||
OneMinusDstAlphaGl = 0x4305,
|
|
||||||
DstColorGl = 0x4306,
|
|
||||||
OneMinusDstColorGl = 0x4307,
|
|
||||||
SrcAlphaSaturateGl = 0x4308,
|
|
||||||
Src1ColorGl = 0xc900,
|
|
||||||
OneMinusSrc1ColorGl = 0xc901,
|
|
||||||
Src1AlphaGl = 0xc902,
|
|
||||||
OneMinusSrc1AlphaGl = 0xc903
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum BlendOp
|
|
||||||
{
|
|
||||||
Add = 1,
|
|
||||||
Subtract,
|
|
||||||
ReverseSubtract,
|
|
||||||
Minimum,
|
|
||||||
Maximum,
|
|
||||||
|
|
||||||
AddGl = 0x8006,
|
|
||||||
MinimumGl = 0x8007,
|
|
||||||
MaximumGl = 0x8008,
|
|
||||||
SubtractGl = 0x800a,
|
|
||||||
ReverseSubtractGl = 0x800b
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum Face
|
|
||||||
{
|
|
||||||
Front = 0x404,
|
|
||||||
Back = 0x405,
|
|
||||||
FrontAndBack = 0x408
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public readonly struct ImageCrop
|
|
||||||
{
|
|
||||||
public int Left { get; }
|
|
||||||
public int Right { get; }
|
|
||||||
public int Top { get; }
|
|
||||||
public int Bottom { get; }
|
|
||||||
public bool FlipX { get; }
|
|
||||||
public bool FlipY { get; }
|
|
||||||
public bool IsStretched { get; }
|
|
||||||
public float AspectRatioX { get; }
|
|
||||||
public float AspectRatioY { get; }
|
|
||||||
|
|
||||||
public ImageCrop(
|
|
||||||
int left,
|
|
||||||
int right,
|
|
||||||
int top,
|
|
||||||
int bottom,
|
|
||||||
bool flipX,
|
|
||||||
bool flipY,
|
|
||||||
bool isStretched,
|
|
||||||
float aspectRatioX,
|
|
||||||
float aspectRatioY)
|
|
||||||
{
|
|
||||||
Left = left;
|
|
||||||
Right = right;
|
|
||||||
Top = top;
|
|
||||||
Bottom = bottom;
|
|
||||||
FlipX = flipX;
|
|
||||||
FlipY = flipY;
|
|
||||||
IsStretched = isStretched;
|
|
||||||
AspectRatioX = aspectRatioX;
|
|
||||||
AspectRatioY = aspectRatioY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,242 +0,0 @@
|
|||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Program;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture;
|
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL.Multithreading
|
|
||||||
{
|
|
||||||
static class CommandHelper
|
|
||||||
{
|
|
||||||
private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer);
|
|
||||||
|
|
||||||
private static int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1;
|
|
||||||
private static CommandDelegate[] _lookup = new CommandDelegate[_totalCommands];
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private static ref T GetCommand<T>(Span<byte> memory)
|
|
||||||
{
|
|
||||||
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GetMaxCommandSize()
|
|
||||||
{
|
|
||||||
Assembly assembly = typeof(CommandHelper).Assembly;
|
|
||||||
|
|
||||||
IEnumerable<Type> commands = assembly.GetTypes().Where(type => typeof(IGALCommand).IsAssignableFrom(type) && type.IsValueType);
|
|
||||||
|
|
||||||
int maxSize = commands.Max(command =>
|
|
||||||
{
|
|
||||||
MethodInfo method = typeof(Unsafe).GetMethod(nameof(Unsafe.SizeOf));
|
|
||||||
MethodInfo generic = method.MakeGenericMethod(command);
|
|
||||||
int size = (int)generic.Invoke(null, null);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
});
|
|
||||||
|
|
||||||
InitLookup();
|
|
||||||
|
|
||||||
return maxSize + 1; // 1 byte reserved for command size.
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void InitLookup()
|
|
||||||
{
|
|
||||||
_lookup[(int)CommandType.Action] = (memory, threaded, renderer) =>
|
|
||||||
ActionCommand.Run(ref GetCommand<ActionCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CreateBuffer] = (memory, threaded, renderer) =>
|
|
||||||
CreateBufferCommand.Run(ref GetCommand<CreateBufferCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CreateProgram] = (memory, threaded, renderer) =>
|
|
||||||
CreateProgramCommand.Run(ref GetCommand<CreateProgramCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CreateSampler] = (memory, threaded, renderer) =>
|
|
||||||
CreateSamplerCommand.Run(ref GetCommand<CreateSamplerCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CreateSync] = (memory, threaded, renderer) =>
|
|
||||||
CreateSyncCommand.Run(ref GetCommand<CreateSyncCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CreateTexture] = (memory, threaded, renderer) =>
|
|
||||||
CreateTextureCommand.Run(ref GetCommand<CreateTextureCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.GetCapabilities] = (memory, threaded, renderer) =>
|
|
||||||
GetCapabilitiesCommand.Run(ref GetCommand<GetCapabilitiesCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.PreFrame] = (memory, threaded, renderer) =>
|
|
||||||
PreFrameCommand.Run(ref GetCommand<PreFrameCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ReportCounter] = (memory, threaded, renderer) =>
|
|
||||||
ReportCounterCommand.Run(ref GetCommand<ReportCounterCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ResetCounter] = (memory, threaded, renderer) =>
|
|
||||||
ResetCounterCommand.Run(ref GetCommand<ResetCounterCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.UpdateCounters] = (memory, threaded, renderer) =>
|
|
||||||
UpdateCountersCommand.Run(ref GetCommand<UpdateCountersCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.BufferDispose] = (memory, threaded, renderer) =>
|
|
||||||
BufferDisposeCommand.Run(ref GetCommand<BufferDisposeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.BufferGetData] = (memory, threaded, renderer) =>
|
|
||||||
BufferGetDataCommand.Run(ref GetCommand<BufferGetDataCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.BufferSetData] = (memory, threaded, renderer) =>
|
|
||||||
BufferSetDataCommand.Run(ref GetCommand<BufferSetDataCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.CounterEventDispose] = (memory, threaded, renderer) =>
|
|
||||||
CounterEventDisposeCommand.Run(ref GetCommand<CounterEventDisposeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CounterEventFlush] = (memory, threaded, renderer) =>
|
|
||||||
CounterEventFlushCommand.Run(ref GetCommand<CounterEventFlushCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.ProgramDispose] = (memory, threaded, renderer) =>
|
|
||||||
ProgramDisposeCommand.Run(ref GetCommand<ProgramDisposeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ProgramGetBinary] = (memory, threaded, renderer) =>
|
|
||||||
ProgramGetBinaryCommand.Run(ref GetCommand<ProgramGetBinaryCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ProgramCheckLink] = (memory, threaded, renderer) =>
|
|
||||||
ProgramCheckLinkCommand.Run(ref GetCommand<ProgramCheckLinkCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.SamplerDispose] = (memory, threaded, renderer) =>
|
|
||||||
SamplerDisposeCommand.Run(ref GetCommand<SamplerDisposeCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.TextureCopyTo] = (memory, threaded, renderer) =>
|
|
||||||
TextureCopyToCommand.Run(ref GetCommand<TextureCopyToCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureCopyToScaled] = (memory, threaded, renderer) =>
|
|
||||||
TextureCopyToScaledCommand.Run(ref GetCommand<TextureCopyToScaledCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureCopyToSlice] = (memory, threaded, renderer) =>
|
|
||||||
TextureCopyToSliceCommand.Run(ref GetCommand<TextureCopyToSliceCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureCreateView] = (memory, threaded, renderer) =>
|
|
||||||
TextureCreateViewCommand.Run(ref GetCommand<TextureCreateViewCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureGetData] = (memory, threaded, renderer) =>
|
|
||||||
TextureGetDataCommand.Run(ref GetCommand<TextureGetDataCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureGetDataSlice] = (memory, threaded, renderer) =>
|
|
||||||
TextureGetDataSliceCommand.Run(ref GetCommand<TextureGetDataSliceCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureRelease] = (memory, threaded, renderer) =>
|
|
||||||
TextureReleaseCommand.Run(ref GetCommand<TextureReleaseCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureSetData] = (memory, threaded, renderer) =>
|
|
||||||
TextureSetDataCommand.Run(ref GetCommand<TextureSetDataCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureSetDataSlice] = (memory, threaded, renderer) =>
|
|
||||||
TextureSetDataSliceCommand.Run(ref GetCommand<TextureSetDataSliceCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureSetDataSliceRegion] = (memory, threaded, renderer) =>
|
|
||||||
TextureSetDataSliceRegionCommand.Run(ref GetCommand<TextureSetDataSliceRegionCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureSetStorage] = (memory, threaded, renderer) =>
|
|
||||||
TextureSetStorageCommand.Run(ref GetCommand<TextureSetStorageCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.WindowPresent] = (memory, threaded, renderer) =>
|
|
||||||
WindowPresentCommand.Run(ref GetCommand<WindowPresentCommand>(memory), threaded, renderer);
|
|
||||||
|
|
||||||
_lookup[(int)CommandType.Barrier] = (memory, threaded, renderer) =>
|
|
||||||
BarrierCommand.Run(ref GetCommand<BarrierCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.BeginTransformFeedback] = (memory, threaded, renderer) =>
|
|
||||||
BeginTransformFeedbackCommand.Run(ref GetCommand<BeginTransformFeedbackCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ClearBuffer] = (memory, threaded, renderer) =>
|
|
||||||
ClearBufferCommand.Run(ref GetCommand<ClearBufferCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ClearRenderTargetColor] = (memory, threaded, renderer) =>
|
|
||||||
ClearRenderTargetColorCommand.Run(ref GetCommand<ClearRenderTargetColorCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.ClearRenderTargetDepthStencil] = (memory, threaded, renderer) =>
|
|
||||||
ClearRenderTargetDepthStencilCommand.Run(ref GetCommand<ClearRenderTargetDepthStencilCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CommandBufferBarrier] = (memory, threaded, renderer) =>
|
|
||||||
CommandBufferBarrierCommand.Run(ref GetCommand<CommandBufferBarrierCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.CopyBuffer] = (memory, threaded, renderer) =>
|
|
||||||
CopyBufferCommand.Run(ref GetCommand<CopyBufferCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DispatchCompute] = (memory, threaded, renderer) =>
|
|
||||||
DispatchComputeCommand.Run(ref GetCommand<DispatchComputeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.Draw] = (memory, threaded, renderer) =>
|
|
||||||
DrawCommand.Run(ref GetCommand<DrawCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawIndexed] = (memory, threaded, renderer) =>
|
|
||||||
DrawIndexedCommand.Run(ref GetCommand<DrawIndexedCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawIndexedIndirect] = (memory, threaded, renderer) =>
|
|
||||||
DrawIndexedIndirectCommand.Run(ref GetCommand<DrawIndexedIndirectCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawIndexedIndirectCount] = (memory, threaded, renderer) =>
|
|
||||||
DrawIndexedIndirectCountCommand.Run(ref GetCommand<DrawIndexedIndirectCountCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawIndirect] = (memory, threaded, renderer) =>
|
|
||||||
DrawIndirectCommand.Run(ref GetCommand<DrawIndirectCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawIndirectCount] = (memory, threaded, renderer) =>
|
|
||||||
DrawIndirectCountCommand.Run(ref GetCommand<DrawIndirectCountCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.DrawTexture] = (memory, threaded, renderer) =>
|
|
||||||
DrawTextureCommand.Run(ref GetCommand<DrawTextureCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.EndHostConditionalRendering] = (memory, threaded, renderer) =>
|
|
||||||
EndHostConditionalRenderingCommand.Run(renderer);
|
|
||||||
_lookup[(int)CommandType.EndTransformFeedback] = (memory, threaded, renderer) =>
|
|
||||||
EndTransformFeedbackCommand.Run(ref GetCommand<EndTransformFeedbackCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetAlphaTest] = (memory, threaded, renderer) =>
|
|
||||||
SetAlphaTestCommand.Run(ref GetCommand<SetAlphaTestCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetBlendState] = (memory, threaded, renderer) =>
|
|
||||||
SetBlendStateCommand.Run(ref GetCommand<SetBlendStateCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetDepthBias] = (memory, threaded, renderer) =>
|
|
||||||
SetDepthBiasCommand.Run(ref GetCommand<SetDepthBiasCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetDepthClamp] = (memory, threaded, renderer) =>
|
|
||||||
SetDepthClampCommand.Run(ref GetCommand<SetDepthClampCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetDepthMode] = (memory, threaded, renderer) =>
|
|
||||||
SetDepthModeCommand.Run(ref GetCommand<SetDepthModeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetDepthTest] = (memory, threaded, renderer) =>
|
|
||||||
SetDepthTestCommand.Run(ref GetCommand<SetDepthTestCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetFaceCulling] = (memory, threaded, renderer) =>
|
|
||||||
SetFaceCullingCommand.Run(ref GetCommand<SetFaceCullingCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetFrontFace] = (memory, threaded, renderer) =>
|
|
||||||
SetFrontFaceCommand.Run(ref GetCommand<SetFrontFaceCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetStorageBuffers] = (memory, threaded, renderer) =>
|
|
||||||
SetStorageBuffersCommand.Run(ref GetCommand<SetStorageBuffersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetTransformFeedbackBuffers] = (memory, threaded, renderer) =>
|
|
||||||
SetTransformFeedbackBuffersCommand.Run(ref GetCommand<SetTransformFeedbackBuffersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetUniformBuffers] = (memory, threaded, renderer) =>
|
|
||||||
SetUniformBuffersCommand.Run(ref GetCommand<SetUniformBuffersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetImage] = (memory, threaded, renderer) =>
|
|
||||||
SetImageCommand.Run(ref GetCommand<SetImageCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetIndexBuffer] = (memory, threaded, renderer) =>
|
|
||||||
SetIndexBufferCommand.Run(ref GetCommand<SetIndexBufferCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetLineParameters] = (memory, threaded, renderer) =>
|
|
||||||
SetLineParametersCommand.Run(ref GetCommand<SetLineParametersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetLogicOpState] = (memory, threaded, renderer) =>
|
|
||||||
SetLogicOpStateCommand.Run(ref GetCommand<SetLogicOpStateCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetMultisampleState] = (memory, threaded, renderer) =>
|
|
||||||
SetMultisampleStateCommand.Run(ref GetCommand<SetMultisampleStateCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetPatchParameters] = (memory, threaded, renderer) =>
|
|
||||||
SetPatchParametersCommand.Run(ref GetCommand<SetPatchParametersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetPointParameters] = (memory, threaded, renderer) =>
|
|
||||||
SetPointParametersCommand.Run(ref GetCommand<SetPointParametersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetPolygonMode] = (memory, threaded, renderer) =>
|
|
||||||
SetPolygonModeCommand.Run(ref GetCommand<SetPolygonModeCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetPrimitiveRestart] = (memory, threaded, renderer) =>
|
|
||||||
SetPrimitiveRestartCommand.Run(ref GetCommand<SetPrimitiveRestartCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetPrimitiveTopology] = (memory, threaded, renderer) =>
|
|
||||||
SetPrimitiveTopologyCommand.Run(ref GetCommand<SetPrimitiveTopologyCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetProgram] = (memory, threaded, renderer) =>
|
|
||||||
SetProgramCommand.Run(ref GetCommand<SetProgramCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetRasterizerDiscard] = (memory, threaded, renderer) =>
|
|
||||||
SetRasterizerDiscardCommand.Run(ref GetCommand<SetRasterizerDiscardCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetRenderTargetColorMasks] = (memory, threaded, renderer) =>
|
|
||||||
SetRenderTargetColorMasksCommand.Run(ref GetCommand<SetRenderTargetColorMasksCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetRenderTargetScale] = (memory, threaded, renderer) =>
|
|
||||||
SetRenderTargetScaleCommand.Run(ref GetCommand<SetRenderTargetScaleCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetRenderTargets] = (memory, threaded, renderer) =>
|
|
||||||
SetRenderTargetsCommand.Run(ref GetCommand<SetRenderTargetsCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetScissor] = (memory, threaded, renderer) =>
|
|
||||||
SetScissorsCommand.Run(ref GetCommand<SetScissorsCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetStencilTest] = (memory, threaded, renderer) =>
|
|
||||||
SetStencilTestCommand.Run(ref GetCommand<SetStencilTestCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetTextureAndSampler] = (memory, threaded, renderer) =>
|
|
||||||
SetTextureAndSamplerCommand.Run(ref GetCommand<SetTextureAndSamplerCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetUserClipDistance] = (memory, threaded, renderer) =>
|
|
||||||
SetUserClipDistanceCommand.Run(ref GetCommand<SetUserClipDistanceCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetVertexAttribs] = (memory, threaded, renderer) =>
|
|
||||||
SetVertexAttribsCommand.Run(ref GetCommand<SetVertexAttribsCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetVertexBuffers] = (memory, threaded, renderer) =>
|
|
||||||
SetVertexBuffersCommand.Run(ref GetCommand<SetVertexBuffersCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.SetViewports] = (memory, threaded, renderer) =>
|
|
||||||
SetViewportsCommand.Run(ref GetCommand<SetViewportsCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureBarrier] = (memory, threaded, renderer) =>
|
|
||||||
TextureBarrierCommand.Run(ref GetCommand<TextureBarrierCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TextureBarrierTiled] = (memory, threaded, renderer) =>
|
|
||||||
TextureBarrierTiledCommand.Run(ref GetCommand<TextureBarrierTiledCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TryHostConditionalRendering] = (memory, threaded, renderer) =>
|
|
||||||
TryHostConditionalRenderingCommand.Run(ref GetCommand<TryHostConditionalRenderingCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.TryHostConditionalRenderingFlush] = (memory, threaded, renderer) =>
|
|
||||||
TryHostConditionalRenderingFlushCommand.Run(ref GetCommand<TryHostConditionalRenderingFlushCommand>(memory), threaded, renderer);
|
|
||||||
_lookup[(int)CommandType.UpdateRenderScale] = (memory, threaded, renderer) =>
|
|
||||||
UpdateRenderScaleCommand.Run(ref GetCommand<UpdateRenderScaleCommand>(memory), threaded, renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer)
|
|
||||||
{
|
|
||||||
_lookup[memory[memory.Length - 1]](memory, threaded, renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|
||||||
{
|
|
||||||
struct EndHostConditionalRenderingCommand : IGALCommand
|
|
||||||
{
|
|
||||||
public CommandType CommandType => CommandType.EndHostConditionalRendering;
|
|
||||||
|
|
||||||
public static void Run(IRenderer renderer)
|
|
||||||
{
|
|
||||||
renderer.Pipeline.EndHostConditionalRendering();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|
||||||
{
|
|
||||||
interface IGALCommand
|
|
||||||
{
|
|
||||||
CommandType CommandType { get; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|
||||||
{
|
|
||||||
struct CreateBufferCommand : IGALCommand
|
|
||||||
{
|
|
||||||
public CommandType CommandType => CommandType.CreateBuffer;
|
|
||||||
private BufferHandle _threadedHandle;
|
|
||||||
private int _size;
|
|
||||||
|
|
||||||
public void Set(BufferHandle threadedHandle, int size)
|
|
||||||
{
|
|
||||||
_threadedHandle = threadedHandle;
|
|
||||||
_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Run(ref CreateBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
|
||||||
{
|
|
||||||
threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL.Multithreading.Model
|
|
||||||
{
|
|
||||||
unsafe struct PinnedSpan<T> where T : unmanaged
|
|
||||||
{
|
|
||||||
private void* _ptr;
|
|
||||||
private int _size;
|
|
||||||
|
|
||||||
public PinnedSpan(ReadOnlySpan<T> span)
|
|
||||||
{
|
|
||||||
_ptr = Unsafe.AsPointer(ref MemoryMarshal.GetReference(span));
|
|
||||||
_size = span.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadOnlySpan<T> Get()
|
|
||||||
{
|
|
||||||
return new ReadOnlySpan<T>(_ptr, _size * Unsafe.SizeOf<T>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public readonly struct ScreenCaptureImageInfo
|
|
||||||
{
|
|
||||||
public ScreenCaptureImageInfo(int width, int height, bool isBgra, byte[] data, bool flipX, bool flipY)
|
|
||||||
{
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
IsBgra = isBgra;
|
|
||||||
Data = data;
|
|
||||||
FlipX = flipX;
|
|
||||||
FlipY = flipY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Width { get; }
|
|
||||||
public int Height { get; }
|
|
||||||
public byte[] Data { get; }
|
|
||||||
public bool IsBgra { get; }
|
|
||||||
public bool FlipX { get; }
|
|
||||||
public bool FlipY { get; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public readonly struct ShaderBindings
|
|
||||||
{
|
|
||||||
public IReadOnlyCollection<int> UniformBufferBindings { get; }
|
|
||||||
public IReadOnlyCollection<int> StorageBufferBindings { get; }
|
|
||||||
public IReadOnlyCollection<int> TextureBindings { get; }
|
|
||||||
public IReadOnlyCollection<int> ImageBindings { get; }
|
|
||||||
|
|
||||||
public ShaderBindings(
|
|
||||||
IReadOnlyCollection<int> uniformBufferBindings,
|
|
||||||
IReadOnlyCollection<int> storageBufferBindings,
|
|
||||||
IReadOnlyCollection<int> textureBindings,
|
|
||||||
IReadOnlyCollection<int> imageBindings)
|
|
||||||
{
|
|
||||||
UniformBufferBindings = uniformBufferBindings;
|
|
||||||
StorageBufferBindings = storageBufferBindings;
|
|
||||||
TextureBindings = textureBindings;
|
|
||||||
ImageBindings = imageBindings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public readonly struct StencilTestDescriptor
|
|
||||||
{
|
|
||||||
public bool TestEnable { get; }
|
|
||||||
|
|
||||||
public CompareOp FrontFunc { get; }
|
|
||||||
public StencilOp FrontSFail { get; }
|
|
||||||
public StencilOp FrontDpPass { get; }
|
|
||||||
public StencilOp FrontDpFail { get; }
|
|
||||||
public int FrontFuncRef { get; }
|
|
||||||
public int FrontFuncMask { get; }
|
|
||||||
public int FrontMask { get; }
|
|
||||||
public CompareOp BackFunc { get; }
|
|
||||||
public StencilOp BackSFail { get; }
|
|
||||||
public StencilOp BackDpPass { get; }
|
|
||||||
public StencilOp BackDpFail { get; }
|
|
||||||
public int BackFuncRef { get; }
|
|
||||||
public int BackFuncMask { get; }
|
|
||||||
public int BackMask { get; }
|
|
||||||
|
|
||||||
public StencilTestDescriptor(
|
|
||||||
bool testEnable,
|
|
||||||
CompareOp frontFunc,
|
|
||||||
StencilOp frontSFail,
|
|
||||||
StencilOp frontDpPass,
|
|
||||||
StencilOp frontDpFail,
|
|
||||||
int frontFuncRef,
|
|
||||||
int frontFuncMask,
|
|
||||||
int frontMask,
|
|
||||||
CompareOp backFunc,
|
|
||||||
StencilOp backSFail,
|
|
||||||
StencilOp backDpPass,
|
|
||||||
StencilOp backDpFail,
|
|
||||||
int backFuncRef,
|
|
||||||
int backFuncMask,
|
|
||||||
int backMask)
|
|
||||||
{
|
|
||||||
TestEnable = testEnable;
|
|
||||||
FrontFunc = frontFunc;
|
|
||||||
FrontSFail = frontSFail;
|
|
||||||
FrontDpPass = frontDpPass;
|
|
||||||
FrontDpFail = frontDpFail;
|
|
||||||
FrontFuncRef = frontFuncRef;
|
|
||||||
FrontFuncMask = frontFuncMask;
|
|
||||||
FrontMask = frontMask;
|
|
||||||
BackFunc = backFunc;
|
|
||||||
BackSFail = backSFail;
|
|
||||||
BackDpPass = backDpPass;
|
|
||||||
BackDpFail = backDpFail;
|
|
||||||
BackFuncRef = backFuncRef;
|
|
||||||
BackFuncMask = backFuncMask;
|
|
||||||
BackMask = backMask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A texture cache that automatically removes older textures that are not used for some time.
|
|
||||||
/// The cache works with a rotated list with a fixed size. When new textures are added, the
|
|
||||||
/// old ones at the bottom of the list are deleted.
|
|
||||||
/// </summary>
|
|
||||||
class AutoDeleteCache : IEnumerable<Texture>
|
|
||||||
{
|
|
||||||
private const int MaxCapacity = 2048;
|
|
||||||
|
|
||||||
private readonly LinkedList<Texture> _textures;
|
|
||||||
private readonly ConcurrentQueue<Texture> _deferredRemovals;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of the automatic deletion cache.
|
|
||||||
/// </summary>
|
|
||||||
public AutoDeleteCache()
|
|
||||||
{
|
|
||||||
_textures = new LinkedList<Texture>();
|
|
||||||
_deferredRemovals = new ConcurrentQueue<Texture>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new texture to the cache, even if the texture added is already on the cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Using this method is only recommended if you know that the texture is not yet on the cache,
|
|
||||||
/// otherwise it would store the same texture more than once.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="texture">The texture to be added to the cache</param>
|
|
||||||
public void Add(Texture texture)
|
|
||||||
{
|
|
||||||
texture.IncrementReferenceCount();
|
|
||||||
|
|
||||||
texture.CacheNode = _textures.AddLast(texture);
|
|
||||||
|
|
||||||
if (_textures.Count > MaxCapacity)
|
|
||||||
{
|
|
||||||
Texture oldestTexture = _textures.First.Value;
|
|
||||||
|
|
||||||
if (!oldestTexture.CheckModified(false))
|
|
||||||
{
|
|
||||||
// The texture must be flushed if it falls out of the auto delete cache.
|
|
||||||
// Flushes out of the auto delete cache do not trigger write tracking,
|
|
||||||
// as it is expected that other overlapping textures exist that have more up-to-date contents.
|
|
||||||
|
|
||||||
oldestTexture.Group.SynchronizeDependents(oldestTexture);
|
|
||||||
oldestTexture.FlushModified(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
_textures.RemoveFirst();
|
|
||||||
|
|
||||||
oldestTexture.DecrementReferenceCount();
|
|
||||||
|
|
||||||
oldestTexture.CacheNode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_deferredRemovals.Count > 0)
|
|
||||||
{
|
|
||||||
while (_deferredRemovals.TryDequeue(out Texture textureToRemove))
|
|
||||||
{
|
|
||||||
Remove(textureToRemove, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new texture to the cache, or just moves it to the top of the list if the
|
|
||||||
/// texture is already on the cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Moving the texture to the top of the list prevents it from being deleted,
|
|
||||||
/// as the textures on the bottom of the list are deleted when new ones are added.
|
|
||||||
/// </remarks>
|
|
||||||
/// <param name="texture">The texture to be added, or moved to the top</param>
|
|
||||||
public void Lift(Texture texture)
|
|
||||||
{
|
|
||||||
if (texture.CacheNode != null)
|
|
||||||
{
|
|
||||||
if (texture.CacheNode != _textures.Last)
|
|
||||||
{
|
|
||||||
_textures.Remove(texture.CacheNode);
|
|
||||||
|
|
||||||
texture.CacheNode = _textures.AddLast(texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Add(texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a texture from the cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texture">The texture to be removed from the cache</param>
|
|
||||||
/// <param name="flush">True to remove the texture if it was on the cache</param>
|
|
||||||
/// <returns>True if the texture was found and removed, false otherwise</returns>
|
|
||||||
public bool Remove(Texture texture, bool flush)
|
|
||||||
{
|
|
||||||
if (texture.CacheNode == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove our reference to this texture.
|
|
||||||
if (flush)
|
|
||||||
{
|
|
||||||
texture.FlushModified(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
_textures.Remove(texture.CacheNode);
|
|
||||||
|
|
||||||
texture.CacheNode = null;
|
|
||||||
|
|
||||||
return texture.DecrementReferenceCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queues removal of a texture from the cache in a thread safe way.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texture">The texture to be removed from the cache</param>
|
|
||||||
public void RemoveDeferred(Texture texture)
|
|
||||||
{
|
|
||||||
_deferredRemovals.Enqueue(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<Texture> GetEnumerator()
|
|
||||||
{
|
|
||||||
return _textures.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return _textures.GetEnumerator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.Gpu.Memory
|
|
||||||
{
|
|
||||||
public class UnmapEventArgs
|
|
||||||
{
|
|
||||||
public ulong Address { get; }
|
|
||||||
public ulong Size { get; }
|
|
||||||
|
|
||||||
public UnmapEventArgs(ulong address, ulong size)
|
|
||||||
{
|
|
||||||
Address = address;
|
|
||||||
Size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|
||||||
{
|
|
||||||
internal enum PredictionMode
|
|
||||||
{
|
|
||||||
DcPred = 0, // Average of above and left pixels
|
|
||||||
VPred = 1, // Vertical
|
|
||||||
HPred = 2, // Horizontal
|
|
||||||
D45Pred = 3, // Directional 45 deg = round(arctan(1 / 1) * 180 / pi)
|
|
||||||
D135Pred = 4, // Directional 135 deg = 180 - 45
|
|
||||||
D117Pred = 5, // Directional 117 deg = 180 - 63
|
|
||||||
D153Pred = 6, // Directional 153 deg = 180 - 27
|
|
||||||
D207Pred = 7, // Directional 207 deg = 180 + 27
|
|
||||||
D63Pred = 8, // Directional 63 deg = round(arctan(2 / 1) * 180 / pi)
|
|
||||||
TmPred = 9, // True-motion
|
|
||||||
NearestMv = 10,
|
|
||||||
NearMv = 11,
|
|
||||||
ZeroMv = 12,
|
|
||||||
NewMv = 13,
|
|
||||||
MbModeCount = 14
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|
||||||
{
|
|
||||||
internal enum SegLvlFeatures
|
|
||||||
{
|
|
||||||
SegLvlAltQ = 0, // Use alternate Quantizer ....
|
|
||||||
SegLvlAltLf = 1, // Use alternate loop filter value...
|
|
||||||
SegLvlRefFrame = 2, // Optional Segment reference frame
|
|
||||||
SegLvlSkip = 3, // Optional Segment (0,0) + skip mode
|
|
||||||
SegLvlMax = 4 // Number of features supported
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.Nvdec.Vp9.Types
|
|
||||||
{
|
|
||||||
public enum TxMode
|
|
||||||
{
|
|
||||||
Only4X4 = 0, // Only 4x4 transform used
|
|
||||||
Allow8X8 = 1, // Allow block transform size up to 8x8
|
|
||||||
Allow16X16 = 2, // Allow block transform size up to 16x16
|
|
||||||
Allow32X32 = 3, // Allow block transform size up to 32x32
|
|
||||||
TxModeSelect = 4, // Transform specified for each block
|
|
||||||
TxModes = 5
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user