Merge pull request #444 from project-slippi/slippi

merge latest into playback debug fast
This commit is contained in:
Jas Laferriere
2025-09-10 13:06:37 -04:00
committed by GitHub
60 changed files with 2383 additions and 5776 deletions

View File

@@ -60,7 +60,7 @@ jobs:
DXSDK_DIR: "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\"
ES_USERNAME: ${{ secrets.ES_USERNAME }}
name: "Windows ${{ matrix.build_type }}"
runs-on: windows-2019
runs-on: windows-2022
steps:
- name: "Checkout"
uses: actions/checkout@v3
@@ -140,8 +140,10 @@ jobs:
Invoke-WebRequest -Uri https://www.ssl.com/download/codesigntool-for-windows/ -UseBasicParsing -OutFile ".\CodeSignTool.zip"
7z x CodeSignTool.zip
Remove-Item CodeSignTool.zip
} else {
cd .\CodeSignTool
}
./CodeSignTool.bat sign -credential_id="${{ secrets.ES_CREDENTIAL_ID }}" -username="${{ secrets.ES_USERNAME }}" -password="${{ secrets.ES_PASSWORD }}" -totp_secret="${{ secrets.ES_TOTP_SECRET }}" -input_file_path="${{ github.workspace }}\Binary\x64\Slippi Dolphin.exe" -override="true"
.\CodeSignTool.bat sign -credential_id="${{ secrets.ES_CREDENTIAL_ID }}" -username="${{ secrets.ES_USERNAME }}" -password="${{ secrets.ES_PASSWORD }}" -totp_secret="${{ secrets.ES_TOTP_SECRET }}" -input_file_path="${{ github.workspace }}\Binary\x64\Slippi Dolphin.exe" -override="true"
- name: "Package ${{ matrix.build_type }} Dolphin"
working-directory: ${{ github.workspace }}
run: |
@@ -174,7 +176,7 @@ jobs:
artifact_name: linux-playback
build_config: playback
name: "Ubuntu ${{ matrix.build_type }}"
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: "Checkout"
uses: actions/checkout@v3
@@ -229,7 +231,8 @@ jobs:
libpng-dev \
qtbase5-private-dev \
libxxf86vm-dev \
x11proto-xinerama-dev
x11proto-xinerama-dev \
libfuse2
- id: rust_ver
name: Grab Rust Version
shell: bash
@@ -315,7 +318,6 @@ jobs:
run: |
rm '/usr/local/bin/2to3' || true
echo "HOMEBREW_NO_AUTO_UPDATE=1" >> $GITHUB_ENV
brew upgrade cmake
brew install \
ffmpeg@2.8 \
libpng \
@@ -324,6 +326,7 @@ jobs:
sound-touch \
hidapi \
python@3.10
# brew upgrade cmake
- id: rust_ver
name: Grab Rust Version
shell: bash

View File

@@ -13,7 +13,7 @@ jobs:
run: |
echo "VERSION=$(echo ${{ github.ref }} | cut -d "v" -f 2)" >> $GITHUB_ENV
- name: Download latest artifacts
uses: dawidd6/action-download-artifact@v2
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: pr-build.yml

3
.gitmodules vendored
View File

@@ -5,3 +5,6 @@
[submodule "Externals/SlippiRustExtensions"]
path = Externals/SlippiRustExtensions
url = https://github.com/project-slippi/slippi-rust-extensions.git
[submodule "Externals/corrosion"]
path = Externals/corrosion
url = https://github.com/corrosion-rs/corrosion

View File

@@ -177,6 +177,7 @@ BE8100B0 806DAFC0
BA8100B0 800100E4
382100E0 7C0803A6
881F0008 00000000
040DEBE8 38000000 #Playback/Core/PreventDressRemoval.asm
C206B0DC 0000004B #Playback/Core/RestoreGameFrame.asm
7C0802A6 90010004
9421FF20 BE8100B0
@@ -491,6 +492,15 @@ C2377544 00000002 #Playback/Core/FastForward/IncrementPadIndex.asm
40A2000C 38000001
981E0003 00000000
04376A88 881F0001 #Playback/Core/FastForward/PadAlwaysUseMasterIndex.asm
C222576C 00000008 #Playback/Core/FastForward/PreventDevelopControlsInFFW.asm
48000009 00000000
7CA802A6 88850000
800D9368 806DAFC0
80630000 88630000
2C030003 98650000
4182000C 2C040003
40820008 38000000
60000000 00000000
C21A45A0 00000007 #Playback/Core/Scene/Boot to Playback Scene.asm
48000019 7C6802A6
3C80803D 6084ADA8
@@ -852,11 +862,15 @@ C216E8C8 00000005 #Playback/Core/Stadium/Enable Home Run Contest Distance.asm
4182000C 819F0044
4800000C 3D808018
618C1998 00000000
C21A4CB4 00000004 #Common/AllocBuffer.asm
38600080 3D808037
618CF1E4 7D8903A6
4E800421 906DAFC4
38000000 00000000
C21A4CB4 00000008 #Common/AllocBuffer.asm
806DAFC4 2C030000
41820014 3D808037
618CF1B0 7D8903A6
4E800421 38600080
3D808037 618CF1E4
7D8903A6 4E800421
906DAFC4 38000000
60000000 00000000
C20055F8 0000000F #Common/GetIsFollower.asm
7C0802A6 90010004
9421FF20 BE8100B0
@@ -1011,12 +1025,12 @@ C216D884 00000030 #Recording/SendGameEnd.asm
BA8100B0 800100E4
382100E0 7C0803A6
819F2514 00000000
C216E74C 00000111 #Recording/SendGameInfo.asm
C216E74C 00000119 #Recording/SendGameInfo.asm
7C0802A6 90010004
9421FF20 BE8100B0
3D808000 618C5604
7D8903A6 4E800421
2C030000 4182084C
2C030000 41820888
38600005 3D808037
618CF1E4 7D8903A6
4E800421 7C7B1B78
@@ -1060,7 +1074,7 @@ B07E0015 3860003D
38600041 987E0023
38600008 B07E0024
38600036 987E0026
3C600312 60630000
3C600313 60630000
907E0027 387E002B
7FE4FB78 38A00138
3D808000 618C31F4
@@ -1115,176 +1129,184 @@ B07E0015 3860003D
4E800421 3A940001
2C140004 4180FF88
8862F234 987E01C7
8862F23C 987E01C8
3C608048 80639D30
5463443E B07E01C9
3B200000 3C608048
3C604BFB 60633EA1
3C80801D 6084457C
80840000 7C032000
38600000 41820024
3C60801D 6063457C
80830000 5485302E
38800040 7C8523D6
7C632214 88630008
987E01C8 3C608048
80639D30 5463443E
2C030208 4082017C
38600000 3D808000
618C5610 7D8903A6
4E800421 7C791B78
3A800000 3ABF0060
3AFE01CB 3B590034
1C74001F 7F03BA14
1ED40024 7ED6AA14
88760001 2C030000
40820028 1C74001F
7C83D214 7F03C378
38A0001F 3D808000
618C31F4 7D8903A6
4E800421 4800001C
7F03C378 3880001F
3D808000 618CC160
B07E01C9 3B200000
3C608048 80639D30
5463443E 2C030208
4082017C 38600000
3D808000 618C5610
7D8903A6 4E800421
3A940001 2C140004
4180FFA0 3A800000
3ABF0060 3AFE0247
3B5900CF 1C74000A
7C791B78 3A800000
3ABF0060 3AFE01CB
3B590036 1C74001F
7F03BA14 1ED40024
7ED6AA14 88760001
2C030000 40820028
1C74000A 7C83D214
7F03C378 38A0000A
1C74001F 7C83D214
7F03C378 38A0001F
3D808000 618C31F4
7D8903A6 4E800421
4800001C 7F03C378
3880000A 3D808000
3880001F 3D808000
618CC160 7D8903A6
4E800421 3A940001
2C140004 4180FFA0
3A800000 3ABF0060
3AFE026F 3B5900F7
1C74001D 7F03BA14
3AFE0247 3B5900D1
1C74000A 7F03BA14
1ED40024 7ED6AA14
88760001 2C030000
40820028 1C74001D
40820028 1C74000A
7C83D214 7F03C378
38A0001D 3D808000
38A0000A 3D808000
618C31F4 7D8903A6
4E800421 4800001C
7F03C378 3880001D
7F03C378 3880000A
3D808000 618CC160
7D8903A6 4E800421
3A940001 2C140004
4180FFA0 4800001C
387E01CB 38800118
4180FFA0 3A800000
3ABF0060 3AFE026F
3B5900F9 1C74001D
7F03BA14 1ED40024
7ED6AA14 88760001
2C030000 40820028
1C74001D 7C83D214
7F03C378 38A0001D
3D808000 618C31F4
7D8903A6 4E800421
4800001C 7F03C378
3880001D 3D808000
618CC160 7D8903A6
4E800421 3A940001
2C140004 4180FFA0
4800001C 387E01CB
38800118 3D808000
618CC160 7D8903A6
4E800421 3D808000
618CADF4 7D8903A6
4E800421 987E02E3
2C190000 41820044
387E02E4 38990396
38A00033 3D808000
618C31F4 7D8903A6
4E800421 3C60803D
6063AD40 80630000
81830088 A06C0001
907E0317 886C0006
907E031B 4800001C
387E02E4 3880003B
3D808000 618CC160
7D8903A6 4E800421
3D808000 618CADF4
2C190000 41820018
7F23CB78 3D808037
618CF1B0 7D8903A6
4E800421 7FC3F378
3880031F 38A00001
3D808000 618C55F0
7D8903A6 4E800421
987E02E3 2C190000
41820044 387E02E4
38990394 38A00033
3D808000 618C31F4
38600205 3D808037
618CF1E4 7D8903A6
4E800421 7C751B78
3C608000 60635600
80630000 3AE30008
38600010 98750000
3860003D 98750203
38600200 B0750201
38600000 98750204
3AC00000 7C76E050
2C030200 41810010
B0750201 38600001
98750204 38750001
7EE4BB78 7C84B214
A0B50201 3D808000
618C31F4 7D8903A6
4E800421 7EA3AB78
38800205 38A00001
3D808000 618C55F0
7D8903A6 4E800421
3C60803D 6063AD40
80630000 81830088
A06C0001 907E0317
886C0006 907E031B
4800001C 387E02E4
3880003B 3D808000
618CC160 7D8903A6
4E800421 2C190000
41820018 7F23CB78
3AD60200 7C16E000
4180FFA4 7EA3AB78
3D808037 618CF1B0
7D8903A6 4E800421
7FC3F378 3880031F
38A00001 3D808000
618C55F0 7D8903A6
4E800421 38600205
3D808037 618CF1E4
38600004 38800007
38A00000 3D808039
618C01F0 7D8903A6
4E800421 48000021
7C8802A6 38A00000
3D808038 618CFD54
7D8903A6 4E800421
7C751B78 3C608000
60635600 80630000
3AE30008 38600010
98750000 3860003D
98750203 38600200
B0750201 38600000
98750204 3AC00000
7C76E050 2C030200
41810010 B0750201
38600001 98750204
38750001 7EE4BB78
7C84B214 A0B50201
3D808000 618C31F4
7D8903A6 4E800421
7EA3AB78 38800205
38A00001 3D808000
618C55F0 7D8903A6
4E800421 3AD60200
7C16E000 4180FFA4
7EA3AB78 3D808037
618CF1B0 7D8903A6
4E800421 38600004
38800007 38A00000
3D808039 618C01F0
7D8903A6 4E800421
48000021 7C8802A6
38A00000 3D808038
618CFD54 7D8903A6
4E800421 48000070
4E800021 7C0802A6
90010004 9421FF20
BE8100B0 806DB64C
83A30000 838DB650
7FBDE214 3860003A
987D0000 806DB654
907D0001 3C60804D
80635F90 907D0005
3C608048 80639D60
907D0009 838DB650
3B9C000D 938DB650
BA8100B0 800100E4
382100E0 7C0803A6
4E800020 38600004
38800007 38A00000
3D808039 618C01F0
7D8903A6 4E800421
48000021 7C8802A6
38A0000F 3D808038
618CFD54 7D8903A6
4E800421 4800012C
4E800021 7C0802A6
90010004 9421FF20
BE8100B0 806DB64C
83E30000 83CDB650
7FFFF214 3B600000
806DC18C 83A30024
2C1D0000 418200E0
3B7B0001 2C1B000F
418100D4 839D002C
3860003B 987F0000
806DB654 907F0001
807C0010 B07F0005
807C0024 987F0007
807C002C 907F0008
807C0040 907F000C
807C0044 907F0010
807C004C 907F0014
807C0050 907F0018
807C0C9C B07F001C
807C0D44 907F001E
807C001C 907F0022
887C0DD7 987F0026
887C0DDB 987F0027
887C0DEB 987F0028
887C0DEF 987F0029
807C0518 2C030000
41820018 8063002C
2C030000 4182000C
8863000C 48000008
3860FFFF 987F002A
A07C0DA8 B07F002B
83CDB650 3BDE002D
93CDB650 3BFF002D
83BD0008 2C1D0000
4082FF28 BA8100B0
48000070 4E800021
7C0802A6 90010004
9421FF20 BE8100B0
806DB64C 83A30000
838DB650 7FBDE214
3860003A 987D0000
806DB654 907D0001
3C60804D 80635F90
907D0005 3C608048
80639D60 907D0009
838DB650 3B9C000D
938DB650 BA8100B0
800100E4 382100E0
7C0803A6 4E800020
38600004 38800007
38A00000 3D808039
618C01F0 7D8903A6
4E800421 48000021
7C8802A6 38A0000F
3D808038 618CFD54
7D8903A6 4E800421
4800012C 4E800021
7C0802A6 90010004
9421FF20 BE8100B0
806DB64C 83E30000
83CDB650 7FFFF214
3B600000 806DC18C
83A30024 2C1D0000
418200E0 3B7B0001
2C1B000F 418100D4
839D002C 3860003B
987F0000 806DB654
907F0001 807C0010
B07F0005 807C0024
987F0007 807C002C
907F0008 807C0040
907F000C 807C0044
907F0010 807C004C
907F0014 807C0050
907F0018 807C0C9C
B07F001C 807C0D44
907F001E 807C001C
907F0022 887C0DD7
987F0026 887C0DDB
987F0027 887C0DEB
987F0028 887C0DEF
987F0029 807C0518
2C030000 41820018
8063002C 2C030000
4182000C 8863000C
48000008 3860FFFF
987F002A A07C0DA8
B07F002B 83CDB650
3BDE002D 93CDB650
3BFF002D 83BD0008
2C1D0000 4082FF28
BA8100B0 800100E4
382100E0 7C0803A6
3C608017 00000000
4E800020 BA8100B0
800100E4 382100E0
7C0803A6 3C608017
60000000 00000000
C206DA34 00000038 #Recording/SendGamePostFrame.asm
7C0802A6 90010004
9421FF20 BE8100B0

View File

@@ -176,6 +176,7 @@ BE8100B0 806DAFC0
BA8100B0 800100E4
382100E0 7C0803A6
881F0008 00000000
040DEBE8 38000000 #Playback/Core/PreventDressRemoval.asm
C206B0DC 0000004B #Playback/Core/RestoreGameFrame.asm
7C0802A6 90010004
9421FF20 BE8100B0
@@ -490,6 +491,15 @@ C2377544 00000002 #Playback/Core/FastForward/IncrementPadIndex.asm
40A2000C 38000001
981E0003 00000000
04376A88 881F0001 #Playback/Core/FastForward/PadAlwaysUseMasterIndex.asm
C222576C 00000008 #Playback/Core/FastForward/PreventDevelopControlsInFFW.asm
48000009 00000000
7CA802A6 88850000
800D9368 806DAFC0
80630000 88630000
2C030003 98650000
4182000C 2C040003
40820008 38000000
60000000 00000000
C21A45A0 00000007 #Playback/Core/Scene/Boot to Playback Scene.asm
48000019 7C6802A6
3C80803D 6084ADA8
@@ -851,11 +861,15 @@ C216E8C8 00000005 #Playback/Core/Stadium/Enable Home Run Contest Distance.asm
4182000C 819F0044
4800000C 3D808018
618C1998 00000000
C21A4CB4 00000004 #Common/AllocBuffer.asm
38600080 3D808037
618CF1E4 7D8903A6
4E800421 906DAFC4
38000000 00000000
C21A4CB4 00000008 #Common/AllocBuffer.asm
806DAFC4 2C030000
41820014 3D808037
618CF1B0 7D8903A6
4E800421 38600080
3D808037 618CF1E4
7D8903A6 4E800421
906DAFC4 38000000
60000000 00000000
C20055F8 0000000F #Common/GetIsFollower.asm
7C0802A6 90010004
9421FF20 BE8100B0
@@ -1010,12 +1024,12 @@ C216D884 00000030 #Recording/SendGameEnd.asm
BA8100B0 800100E4
382100E0 7C0803A6
819F2514 00000000
C216E74C 00000111 #Recording/SendGameInfo.asm
C216E74C 00000119 #Recording/SendGameInfo.asm
7C0802A6 90010004
9421FF20 BE8100B0
3D808000 618C5604
7D8903A6 4E800421
2C030000 4182084C
2C030000 41820888
38600005 3D808037
618CF1E4 7D8903A6
4E800421 7C7B1B78
@@ -1059,7 +1073,7 @@ B07E0015 3860003D
38600041 987E0023
38600008 B07E0024
38600036 987E0026
3C600312 60630000
3C600313 60630000
907E0027 387E002B
7FE4FB78 38A00138
3D808000 618C31F4
@@ -1114,176 +1128,184 @@ B07E0015 3860003D
4E800421 3A940001
2C140004 4180FF88
8862F234 987E01C7
8862F23C 987E01C8
3C608048 80639D30
5463443E B07E01C9
3B200000 3C608048
3C604BFB 60633EA1
3C80801D 6084457C
80840000 7C032000
38600000 41820024
3C60801D 6063457C
80830000 5485302E
38800040 7C8523D6
7C632214 88630008
987E01C8 3C608048
80639D30 5463443E
2C030208 4082017C
38600000 3D808000
618C5610 7D8903A6
4E800421 7C791B78
3A800000 3ABF0060
3AFE01CB 3B590034
1C74001F 7F03BA14
1ED40024 7ED6AA14
88760001 2C030000
40820028 1C74001F
7C83D214 7F03C378
38A0001F 3D808000
618C31F4 7D8903A6
4E800421 4800001C
7F03C378 3880001F
3D808000 618CC160
B07E01C9 3B200000
3C608048 80639D30
5463443E 2C030208
4082017C 38600000
3D808000 618C5610
7D8903A6 4E800421
3A940001 2C140004
4180FFA0 3A800000
3ABF0060 3AFE0247
3B5900CF 1C74000A
7C791B78 3A800000
3ABF0060 3AFE01CB
3B590036 1C74001F
7F03BA14 1ED40024
7ED6AA14 88760001
2C030000 40820028
1C74000A 7C83D214
7F03C378 38A0000A
1C74001F 7C83D214
7F03C378 38A0001F
3D808000 618C31F4
7D8903A6 4E800421
4800001C 7F03C378
3880000A 3D808000
3880001F 3D808000
618CC160 7D8903A6
4E800421 3A940001
2C140004 4180FFA0
3A800000 3ABF0060
3AFE026F 3B5900F7
1C74001D 7F03BA14
3AFE0247 3B5900D1
1C74000A 7F03BA14
1ED40024 7ED6AA14
88760001 2C030000
40820028 1C74001D
40820028 1C74000A
7C83D214 7F03C378
38A0001D 3D808000
38A0000A 3D808000
618C31F4 7D8903A6
4E800421 4800001C
7F03C378 3880001D
7F03C378 3880000A
3D808000 618CC160
7D8903A6 4E800421
3A940001 2C140004
4180FFA0 4800001C
387E01CB 38800118
4180FFA0 3A800000
3ABF0060 3AFE026F
3B5900F9 1C74001D
7F03BA14 1ED40024
7ED6AA14 88760001
2C030000 40820028
1C74001D 7C83D214
7F03C378 38A0001D
3D808000 618C31F4
7D8903A6 4E800421
4800001C 7F03C378
3880001D 3D808000
618CC160 7D8903A6
4E800421 3A940001
2C140004 4180FFA0
4800001C 387E01CB
38800118 3D808000
618CC160 7D8903A6
4E800421 3D808000
618CADF4 7D8903A6
4E800421 987E02E3
2C190000 41820044
387E02E4 38990396
38A00033 3D808000
618C31F4 7D8903A6
4E800421 3C60803D
6063AD40 80630000
81830088 A06C0001
907E0317 886C0006
907E031B 4800001C
387E02E4 3880003B
3D808000 618CC160
7D8903A6 4E800421
3D808000 618CADF4
2C190000 41820018
7F23CB78 3D808037
618CF1B0 7D8903A6
4E800421 7FC3F378
3880031F 38A00001
3D808000 618C55F0
7D8903A6 4E800421
987E02E3 2C190000
41820044 387E02E4
38990394 38A00033
3D808000 618C31F4
38600205 3D808037
618CF1E4 7D8903A6
4E800421 7C751B78
3C608000 60635600
80630000 3AE30008
38600010 98750000
3860003D 98750203
38600200 B0750201
38600000 98750204
3AC00000 7C76E050
2C030200 41810010
B0750201 38600001
98750204 38750001
7EE4BB78 7C84B214
A0B50201 3D808000
618C31F4 7D8903A6
4E800421 7EA3AB78
38800205 38A00001
3D808000 618C55F0
7D8903A6 4E800421
3C60803D 6063AD40
80630000 81830088
A06C0001 907E0317
886C0006 907E031B
4800001C 387E02E4
3880003B 3D808000
618CC160 7D8903A6
4E800421 2C190000
41820018 7F23CB78
3AD60200 7C16E000
4180FFA4 7EA3AB78
3D808037 618CF1B0
7D8903A6 4E800421
7FC3F378 3880031F
38A00001 3D808000
618C55F0 7D8903A6
4E800421 38600205
3D808037 618CF1E4
38600004 38800007
38A00000 3D808039
618C01F0 7D8903A6
4E800421 48000021
7C8802A6 38A00000
3D808038 618CFD54
7D8903A6 4E800421
7C751B78 3C608000
60635600 80630000
3AE30008 38600010
98750000 3860003D
98750203 38600200
B0750201 38600000
98750204 3AC00000
7C76E050 2C030200
41810010 B0750201
38600001 98750204
38750001 7EE4BB78
7C84B214 A0B50201
3D808000 618C31F4
7D8903A6 4E800421
7EA3AB78 38800205
38A00001 3D808000
618C55F0 7D8903A6
4E800421 3AD60200
7C16E000 4180FFA4
7EA3AB78 3D808037
618CF1B0 7D8903A6
4E800421 38600004
38800007 38A00000
3D808039 618C01F0
7D8903A6 4E800421
48000021 7C8802A6
38A00000 3D808038
618CFD54 7D8903A6
4E800421 48000070
4E800021 7C0802A6
90010004 9421FF20
BE8100B0 806DB64C
83A30000 838DB650
7FBDE214 3860003A
987D0000 806DB654
907D0001 3C60804D
80635F90 907D0005
3C608048 80639D60
907D0009 838DB650
3B9C000D 938DB650
BA8100B0 800100E4
382100E0 7C0803A6
4E800020 38600004
38800007 38A00000
3D808039 618C01F0
7D8903A6 4E800421
48000021 7C8802A6
38A0000F 3D808038
618CFD54 7D8903A6
4E800421 4800012C
4E800021 7C0802A6
90010004 9421FF20
BE8100B0 806DB64C
83E30000 83CDB650
7FFFF214 3B600000
806DC18C 83A30024
2C1D0000 418200E0
3B7B0001 2C1B000F
418100D4 839D002C
3860003B 987F0000
806DB654 907F0001
807C0010 B07F0005
807C0024 987F0007
807C002C 907F0008
807C0040 907F000C
807C0044 907F0010
807C004C 907F0014
807C0050 907F0018
807C0C9C B07F001C
807C0D44 907F001E
807C001C 907F0022
887C0DD7 987F0026
887C0DDB 987F0027
887C0DEB 987F0028
887C0DEF 987F0029
807C0518 2C030000
41820018 8063002C
2C030000 4182000C
8863000C 48000008
3860FFFF 987F002A
A07C0DA8 B07F002B
83CDB650 3BDE002D
93CDB650 3BFF002D
83BD0008 2C1D0000
4082FF28 BA8100B0
48000070 4E800021
7C0802A6 90010004
9421FF20 BE8100B0
806DB64C 83A30000
838DB650 7FBDE214
3860003A 987D0000
806DB654 907D0001
3C60804D 80635F90
907D0005 3C608048
80639D60 907D0009
838DB650 3B9C000D
938DB650 BA8100B0
800100E4 382100E0
7C0803A6 4E800020
38600004 38800007
38A00000 3D808039
618C01F0 7D8903A6
4E800421 48000021
7C8802A6 38A0000F
3D808038 618CFD54
7D8903A6 4E800421
4800012C 4E800021
7C0802A6 90010004
9421FF20 BE8100B0
806DB64C 83E30000
83CDB650 7FFFF214
3B600000 806DC18C
83A30024 2C1D0000
418200E0 3B7B0001
2C1B000F 418100D4
839D002C 3860003B
987F0000 806DB654
907F0001 807C0010
B07F0005 807C0024
987F0007 807C002C
907F0008 807C0040
907F000C 807C0044
907F0010 807C004C
907F0014 807C0050
907F0018 807C0C9C
B07F001C 807C0D44
907F001E 807C001C
907F0022 887C0DD7
987F0026 887C0DDB
987F0027 887C0DEB
987F0028 887C0DEF
987F0029 807C0518
2C030000 41820018
8063002C 2C030000
4182000C 8863000C
48000008 3860FFFF
987F002A A07C0DA8
B07F002B 83CDB650
3BDE002D 93CDB650
3BFF002D 83BD0008
2C1D0000 4082FF28
BA8100B0 800100E4
382100E0 7C0803A6
3C608017 00000000
4E800020 BA8100B0
800100E4 382100E0
7C0803A6 3C608017
60000000 00000000
C206DA34 00000038 #Recording/SendGamePostFrame.asm
7C0802A6 90010004
9421FF20 BE8100B0

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,13 @@
"Annotation": "External/Unplugging Closes CSS Door/Unplugging Closes CSS Door.asm",
"Tags": ""
},
{
"InjectionAddress": "801239A8",
"Name": "Full friendlies codes",
"Codetype": "Auto",
"Annotation": "External/FreezeGlitchFix/FreezeGlitchFix.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "804DC47C",
"Name": "Full friendlies codes",

View File

@@ -34,6 +34,13 @@
"Codetype": "Auto",
"Annotation": "External/Unplugging Closes CSS Door/Unplugging Closes CSS Door.asm",
"Tags": ""
},
{
"InjectionAddress": "801239A8",
"Name": "Stealth tournament codes",
"Codetype": "Auto",
"Annotation": "External/FreezeGlitchFix/FreezeGlitchFix.asm",
"Tags": "[affects-gameplay]"
}
]
}

View File

@@ -35,6 +35,13 @@
"Annotation": "External/Unplugging Closes CSS Door/Unplugging Closes CSS Door.asm",
"Tags": ""
},
{
"InjectionAddress": "801239A8",
"Name": "Full tournament codes",
"Codetype": "Auto",
"Annotation": "External/FreezeGlitchFix/FreezeGlitchFix.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "804DC47C",
"Name": "Full tournament codes",

View File

@@ -0,0 +1,11 @@
{
"Details": [
{
"InjectionAddress": "804DEC1C",
"Name": "Frozen Stadium",
"Codetype": "Auto",
"Annotation": "External/Frozen PS/Toggle/FrzPkmToggleEnable.asm",
"Tags": ""
}
]
}

View File

@@ -22,11 +22,11 @@
"Tags": ""
},
{
"InjectionAddress": "804DEC1C",
"InjectionAddress": "801D457C",
"Name": "Frozen Stadium",
"Codetype": "Auto",
"Annotation": "External/Frozen PS/Toggle/FrzPkmToggleEnable.asm",
"Tags": ""
"Tags": "[affects-gameplay]"
}
]
}

View File

@@ -0,0 +1,60 @@
{
"Details": [
{
"Annotation": "Common/Preload Stadium Transformations/Core/GetPreloadedTransition.asm",
"Codetype": "Auto",
"InjectionAddress": "801D460C",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Core/Init isLoaded Bool.asm",
"Codetype": "Auto",
"InjectionAddress": "801D14C8",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Core/Load Transformation.asm",
"Codetype": "Auto",
"InjectionAddress": "801D45EC",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Core/Reset isLoaded.asm",
"Codetype": "Auto",
"InjectionAddress": "801D4F14",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Core/SkipNormalDecision1.asm",
"Codetype": "Auto",
"InjectionAddress": "801D4610",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Core/SkipNormalDecision2.asm",
"Codetype": "Auto",
"InjectionAddress": "801D4724",
"Name": "Required: Slippi Recording",
"Tags": "[affects-gameplay]"
},
{
"Annotation": "Common/Preload Stadium Transformations/Toggle/PsPreloadToggleEnable.asm",
"Codetype": "Auto",
"InjectionAddress": "804DEC18",
"Name": "Required: Slippi Recording",
"Tags": ""
},
{
"Annotation": "Online/Core/PreventFileAlarms/FreezeStadium.asm",
"Codetype": "Auto",
"InjectionAddress": "801D4578",
"Name": "Required: Slippi Online",
"Tags": "[affects-gameplay]"
}
]
}

View File

@@ -0,0 +1,11 @@
{
"Details": [
{
"InjectionAddress": "802652F0",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/CSS/InitSheikSelector.asm",
"Tags": ""
}
]
}

View File

@@ -196,13 +196,6 @@
"Annotation": "",
"Tags": ""
},
{
"InjectionAddress": "8021AAE4",
"Name": "Required: General Codes",
"Codetype": "04",
"Annotation": "",
"Tags": ""
},
{
"InjectionAddress": "8025B8BC",
"Name": "Required: General Codes",
@@ -539,55 +532,6 @@
"Annotation": "Common/IncrementFrameIndex.asm",
"Tags": ""
},
{
"InjectionAddress": "801D460C",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/GetPreloadedTransition.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D14C8",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/Init isLoaded Bool.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D45EC",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/Load Transformation.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D4F14",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/Reset isLoaded.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D4610",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/SkipNormalDecision1.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D4724",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Core/SkipNormalDecision2.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "804DEC18",
"Name": "Required: Slippi Recording",
"Codetype": "Auto",
"Annotation": "Common/Preload Stadium Transformations/Toggle/PsPreloadToggleEnable.asm",
"Tags": ""
},
{
"InjectionAddress": "801C154C",
"Name": "Required: Slippi Recording",
@@ -791,6 +735,48 @@
"Annotation": "Online/Core/Hacks/PreventPadAlarmDuringRollback.asm",
"Tags": ""
},
{
"InjectionAddress": "8021AAE4",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/FD/DesyncProofBGTransformations.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D2D38",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/Stadium/ChangeJumbotronText.asm",
"Tags": ""
},
{
"InjectionAddress": "801C65C8",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/Stadium/CustomZeroBuffer.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D4760",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/Stadium/GrPsxIsValid.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "801D457C",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/Stadium/IngameCheckIfFrozen.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "800165AC",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/Hacks/Stadium/StadiumFileLoad.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "8038E910",
"Name": "Required: Slippi Online",
@@ -812,13 +798,6 @@
"Annotation": "Online/Core/Music/VolumeChange.asm",
"Tags": ""
},
{
"InjectionAddress": "801D4578",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Core/PreventFileAlarms/FreezeStadium.asm",
"Tags": "[affects-gameplay]"
},
{
"InjectionAddress": "80023FFC",
"Name": "Required: Slippi Online",
@@ -910,13 +889,6 @@
"Annotation": "Online/Menus/CSS/IncreaseTextHeap.asm",
"Tags": ""
},
{
"InjectionAddress": "802652F0",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/CSS/InitSheikSelector.asm",
"Tags": ""
},
{
"InjectionAddress": "80264534",
"Name": "Required: Slippi Online",
@@ -1190,6 +1162,48 @@
"Annotation": "Online/Menus/SSS/ExitSSSUponStageSelect.asm",
"Tags": ""
},
{
"InjectionAddress": "80259E90",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/CheckForFrozenOnStageName.asm",
"Tags": ""
},
{
"InjectionAddress": "80259E34",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/CheckForToggledOnStageName.asm",
"Tags": ""
},
{
"InjectionAddress": "8025A530",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/CursorOnHoverStadium.asm",
"Tags": ""
},
{
"InjectionAddress": "80259FB4",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/IncMaxNames.asm",
"Tags": ""
},
{
"InjectionAddress": "8025AC6C",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/StageSelectTextProc.asm",
"Tags": ""
},
{
"InjectionAddress": "80259FAC",
"Name": "Required: Slippi Online",
"Codetype": "Auto",
"Annotation": "Online/Menus/SSS/FrozenStadiumToggle/StoreNameId.asm",
"Tags": ""
},
{
"InjectionAddress": "8022B044",
"Name": "Required: Slippi Online",
@@ -1974,6 +1988,13 @@
"Annotation": "",
"Tags": ""
},
{
"InjectionAddress": "8021AAE0",
"Name": "Optional: Freeze Final Destination Background",
"Codetype": "Auto",
"Annotation": "External/FreezeFDSlippi/FreezeFDSlippi.asm",
"Tags": ""
},
{
"InjectionAddress": "803BB05C",
"Name": "Optional: Widescreen 16:9",

1
Externals/corrosion vendored Submodule

Submodule Externals/corrosion added at b1fab72165

View File

@@ -1,134 +0,0 @@
cmake_minimum_required(VERSION 3.15)
project(Corrosion
VERSION 0.4.0
LANGUAGES NONE
HOMEPAGE_URL "https://corrosion-rs.github.io/corrosion/"
)
# Default behavior:
# - If the project is being used as a subdirectory, then don't build tests and
# don't enable any languages.
# - If this is a top level project, then build tests and enable the C++ compiler
if (NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(_CORROSION_TOP_LEVEL OFF)
else()
set(_CORROSION_TOP_LEVEL ON)
endif()
# ==== Corrosion Configuration ====
option(
CORROSION_DEV_MODE
"Enables some additional features if you're developing Corrosion"
${_CORROSION_TOP_LEVEL}
)
option(
CORROSION_BUILD_TESTS
"Build Corrosion test project"
${_CORROSION_TOP_LEVEL}
)
set(
CORROSION_GENERATOR_EXECUTABLE CACHE STRING
"Use prebuilt, non-bootstrapped corrosion-generator")
mark_as_advanced(CORROSION_GENERATOR_EXECUTABLE)
if (CORROSION_GENERATOR_EXECUTABLE)
add_executable(Corrosion::Generator IMPORTED GLOBAL)
set_property(
TARGET Corrosion::Generator
PROPERTY IMPORTED_LOCATION ${CORROSION_GENERATOR_EXECUTABLE})
set(CORROSION_INSTALL_EXECUTABLE_DEFAULT OFF)
elseif(CORROSION_NATIVE_TOOLING OR CMAKE_VERSION VERSION_LESS 3.19.0)
set(CORROSION_INSTALL_EXECUTABLE_DEFAULT "ON")
else()
set(CORROSION_INSTALL_EXECUTABLE_DEFAULT OFF)
endif()
option(
CORROSION_INSTALL_EXECUTABLE
"Controls whether corrosion-generator is installed with the package"
${CORROSION_INSTALL_EXECUTABLE_DEFAULT}
)
mark_as_advanced(CORROSION_INSTALL_EXECUTABLE)
if (_CORROSION_TOP_LEVEL)
# We need to enable a language for corrosions test to work.
# For projects using corrosion this is not needed
enable_language(C)
endif()
# This little bit self-hosts the Corrosion toolchain to build the generator
# tool.
#
# It is strongly encouraged to install Corrosion separately and use
# `find_package(Corrosion REQUIRED)` instead if that works with your workflow.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(Corrosion)
# Testing
if (CORROSION_BUILD_TESTS)
include(CTest)
add_subdirectory(test)
endif()
# If Corrosion is a subdirectory, do not enable its install code
if (NOT _CORROSION_TOP_LEVEL)
return()
endif()
# Installation
include(GNUInstallDirs)
if(CORROSION_INSTALL_EXECUTABLE)
# Builds the generator executable
corrosion_import_crate(MANIFEST_PATH generator/Cargo.toml)
set(_CORROSION_GENERATOR_DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}")
corrosion_install(
TARGETS corrosion-generator
DESTINATION "${_CORROSION_GENERATOR_DESTINATION}"
)
else()
message(DEBUG "Not installing corrosion-generator since "
"`CORROSION_INSTALL_EXECUTABLE` is set to ${CORROSION_INSTALL_EXECUTABLE}"
)
endif()
# Generate the Config file
include(CMakePackageConfigHelpers)
configure_package_config_file(
cmake/CorrosionConfig.cmake.in CorrosionConfig.cmake
INSTALL_DESTINATION
"${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion"
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY
SameMinorVersion # TODO: Should be SameMajorVersion when 1.0 is released
ARCH_INDEPENDENT
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/CorrosionConfigVersion.cmake"
DESTINATION
"${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Corrosion"
)
# These CMake scripts are needed both for the install and as a subdirectory
install(
FILES
cmake/Corrosion.cmake
cmake/CorrosionGenerator.cmake
cmake/FindRust.cmake
DESTINATION
"${CMAKE_INSTALL_FULL_DATADIR}/cmake"
)

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Andrew Gaspar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,40 +0,0 @@
# Corrosion
[![Build Status](https://github.com/corrosion-rs/corrosion/actions/workflows/test.yaml/badge.svg)](https://github.com/corrosion-rs/corrosion/actions?query=branch%3Amaster)
[![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://corrosion-rs.github.io/corrosion/)
![License](https://img.shields.io/badge/license-MIT-blue)
Corrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake
project. Corrosion can automatically import executables, static libraries, and dynamic libraries
from a workspace or package manifest (`Cargo.toml` file).
## Features
- Automatic Import of Executable, Static, and Shared Libraries from Rust Crate
- Easy Installation of Rust Executables
- Trivially Link Rust Executables to C/C++ Libraries in Tree
- Multi-Config Generator Support
- Simple Cross-Compilation
## Sample Usage with FetchContent
Using the CMake `FetchContent` module allows you to easily integrate corrosion into your build.
Other methods including installing corrosion or adding it as a subdirectory are covered in the
[setup chapter](https://corrosion-rs.github.io/corrosion/setup_corrosion.html) of the
corrosion [documentation](https://corrosion-rs.github.io/corrosion/).
```cmake
include(FetchContent)
FetchContent_Declare(
Corrosion
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
GIT_TAG v0.3 # Optionally specify a commit hash, version tag or branch here
)
FetchContent_MakeAvailable(Corrosion)
# Import targets defined in a package or workspace manifest `Cargo.toml` file
corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)
add_executable(your_cpp_bin main.cpp)
target_link_libraries(your_cpp_bin PUBLIC rust-lib)
```

View File

@@ -1,302 +0,0 @@
# Unreleased
## Breaking Changes
- The Visual Studio Generators now require at least CMake 3.20.
This was previously announced in the 0.3.0 release notes.
- The previously deprecated function `corrosion_set_linker_language()`
will now raise an error when called and may be removed without further
notice in future stable releases. Use `corrosion_set_linker()` instead.
- Improved the FindRust target triple detection, which may cause different behavior in some cases.
The detection does not require an enabled language anymore and will always fall back
to the default host target triple. A warning is issued if target triple detection failed.
## Potentially Breaking Changes
- Corrosion now sets the `IMPORTED_NO_SONAME` property for shared rust libraries, since by
default they won't have an `soname` field.
If you add a rustflag like `-Clink-arg=-Wl,-soname,libmycrate.so` in your project,
you should set this property to false on the shared rust library.
## New features
- `corrosion_import_crate()` has two new options `LOCKED` and `FROZEN` which pass the
`--locked` and `--frozen` flags to all invocations of cargo. Only with CMake >= 3.19.
## Other changes
- When installing Corrosion with CMake >= 3.19, the legacy Generator tool is
no longer built and installed by default.
- Corrosion now issues a warning when setting the linker or setting linker
options for a Rust static library.
- Corrosion no longer enables the `C` language when CMake is in crosscompiling mode and
no languages where previously enabled. This is not considered a breaking change.
- `corrosion_import_crate()` now warns about unexpected arguments.
## Fixes
- Fix building when the `dev` profile is explicitly set by the user.
## Experimental status (may be changed or removed before a stable release)
- Experimental cxxbridge and cbindgen integration.
- Add a helper function to parse the package version from a Cargo.toml file
- Expose rustup toolchains discovered by `FindRust` in the following cache variables
which contain a list.
- `Rust_RUSTUP_TOOLCHAINS`: List of toolchains names
- `Rust_RUSTUP_TOOLCHAINS_VERSION`: List of `rustc` version of the toolchains
- `Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH`: List of the path to `rustc`
- `Rust_RUSTUP_TOOLCHAINS_CARGO_PATH`: List of the path to `cargo`. Entries may be `NOTFOUND` if cargo
is not available for that toolchain.
- Add target properties `INTERFACE_CORROSION_RUSTC` and `INTERFACE_CORROSION_CARGO`, which may
be set to paths to `rustc` and `cargo` respectively to override the toolchain for a specific
target.
# 0.3.5 (2023-03-19)
- Fix building the Legacy Generator on Rust toolchains < 1.56 ([#365])
[#365]: https://github.com/corrosion-rs/corrosion/pull/365
# 0.3.4 (2023-03-02)
## Fixes
- Fix hostbuild (when CMake/Cargo is configured for cross-compiling) if clang is used ([#338]).
## Other
- Pass `--no-deps` to cargo metadata ([#334]).
- Bump the legacy generator dependencies
[#334]: https://github.com/corrosion-rs/corrosion/pull/334
[#338]: https://github.com/corrosion-rs/corrosion/pull/338
# 0.3.3 (2023-02-17)
## New features (Only available on CMake >= 3.19)
- Add new `IMPORTED_CRATES` flag to `corrosion_import_crate()` to retrieve the list of imported crates in the current
scope ([#312](https://github.com/corrosion-rs/corrosion/pull/312)).
## Fixes
- Fix imported location target property when the rust target name contains dashes
and a custom OUTPUT_DIRECTORY was specified by the user ([#322](https://github.com/corrosion-rs/corrosion/pull/322)).
- Fix building for custom rust target-triples ([#316](https://github.com/corrosion-rs/corrosion/pull/316))
# 0.3.2 (2023-01-11)
## New features (Only available on CMake >= 3.19)
- Add new `CRATE_TYPES` flag to `corrosion_import_crate()` to restrict which
crate types should be imported ([#269](https://github.com/corrosion-rs/corrosion/pull/269)).
- Add `NO_LINKER_OVERRIDE` flag to let Rust choose the default linker for the target
instead of what Corrosion thinks is the appropriate linker driver ([#272](https://github.com/corrosion-rs/corrosion/pull/272)).
## Fixes
- Fix clean target when cross-compiling ([#291](https://github.com/corrosion-rs/corrosion/pull/291)).
- Don't set the linker for Rust static libraries ([#275](https://github.com/corrosion-rs/corrosion/pull/275)).
- Minor fixes in FindRust [#297](https://github.com/corrosion-rs/corrosion/pull/297):
- fix a logic error in the version detection
- fix a logic error in `QUIET` mode when rustup is not found.
# 0.3.1 (2022-12-13)
### Fixes
- Fix a regression in detecting the MSVC abi ([#256])
- Fix an issue on macOS 13 which affected rust crates compiling C++ code in build scripts ([#254]).
- Fix corrosion not respecting `CMAKE_<XYZ>_OUTPUT_DIRECTORY` values ([#268]).
- Don't override rusts linker choice for the msvc abi (previously this was only skipped for msvc generators) ([#271])
[#254]: https://github.com/corrosion-rs/corrosion/pull/254
[#256]: https://github.com/corrosion-rs/corrosion/pull/256
[#268]: https://github.com/corrosion-rs/corrosion/pull/268
[#271]: https://github.com/corrosion-rs/corrosion/pull/271
# 0.3.0 (2022-10-31)
## Breaking
- The minimum supported rust version (MSRV) was increased to 1.46, due to a cargo issue that recently
surfaced on CI when using crates.io. On MacOS 12 and Windows-2022 at least Rust 1.54 is required.
- MacOS 10 and 11 are no longer officially supported and untested in CI.
- The minimum required CMake version is now 3.15.
- Adding a `PRE_BUILD` custom command on a `cargo-build_<target_name>` CMake target will no
longer work as expected. To support executing user defined commands before cargo build is
invoked users should use the newly added targets `cargo-prebuild` (before all cargo build invocations)
or `cargo-prebuild_<target_name>` as a dependency target.
Example: `add_dependencies(cargo-prebuild code_generator_target)`
### Breaking: Removed previously deprecated functionality
- Removed `add_crate()` function. Use `corrosio_import_crate()` instead.
- Removed `cargo_link_libraries()` function. Use `corrosion_link_libraries()` instead.
- Removed experimental CMake option `CORROSION_EXPERIMENTAL_PARSER`.
The corresponding stable option is `CORROSION_NATIVE_TOOLING` albeit with inverted semantics.
- Previously Corrosion would set the `HOST_CC` and `HOST_CXX` environment variables when invoking
cargo build, if the environment variables `CC` and `CXX` outside of CMake where set.
However this did not work as expected in all cases and sometimes the `HOST_CC` variable would be set
to a cross-compiler for unknown reasons. For this reason `HOST_CC` and `HOST_CXX` are not set by
corrosion anymore, but users can still set them manually if required via `corrosion_set_env_vars()`.
- The `CARGO_RUST_FLAGS` family of cache variables were removed. Corrosion does not internally use them
anymore.
## Potentially breaking
- The working directory when invoking `cargo build` was changed to the directory of the Manifest
file. This now allows cargo to pick up `.cargo/config.toml` files located in the source tree.
([205](https://github.com/corrosion-rs/corrosion/pull/205))
- Corrosion internally invokes `cargo build`. When passing arguments to `cargo build`, Corrosion
now uses the CMake `VERBATIM` option. In rare cases this may require you to change how you quote
parameters passed to corrosion (e.g. via `corrosion_add_target_rustflags()`).
For example setting a `cfg` option previously required double escaping the rustflag like this
`"--cfg=something=\\\"value\\\""`, but now it can be passed to corrosion without any escapes:
`--cfg=something="value"`.
- Corrosion now respects the CMake `OUTPUT_DIRECTORY` target properties. More details in the "New features" section.
## New features
- Support setting rustflags for only the main target and none of its dependencies ([215](https://github.com/corrosion-rs/corrosion/pull/215)).
A new function `corrosion_add_target_local_rustflags(target_name rustc_flag [more_flags ...])`
is added for this purpose.
This is useful in cases where you only need rustflags on the main-crate, but need to set different
flags for different targets. Without "local" Rustflags this would require rebuilds of the
dependencies when switching targets.
- Support explicitly selecting a linker ([208](https://github.com/corrosion-rs/corrosion/pull/208)).
The linker can be selected via `corrosion_set_linker(target_name linker)`.
Please note that this only has an effect for targets, where the final linker invocation is done
by cargo, i.e. targets where foreign code is linked into rust code and not the other way around.
- Corrosion now respects the CMake `OUTPUT_DIRECTORY` target properties and copies build artifacts to the expected
locations ([217](https://github.com/corrosion-rs/corrosion/pull/217)), if the properties are set.
This feature requires at least CMake 3.19 and is enabled by default if supported. Please note that the `OUTPUT_NAME`
target properties are currently not supported.
Specifically, the following target properties are now respected:
- [ARCHIVE_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.html)
- [LIBRARY_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html)
- [RUNTIME_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html)
- [PDB_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/PDB_OUTPUT_DIRECTORY.html)
- Corrosion now supports packages with potentially multiple binaries (bins) and a library (lib) at the
same time. The only requirement is that the names of all `bin`s and `lib`s in the whole project must be unique.
Users can set the names in the `Cargo.toml` by adding `name = <unique_name>` in the `[[bin]]` and `[lib]` tables.
- FindRust now has improved support for the `VERSION` option of `find_package` and will now attempt to find a matching
toolchain version. Previously it was only checked if the default toolchain matched to required version.
- For rustup managed toolchains a CMake error is issued with a helpful message if the required target for
the selected toolchain is not installed.
## Fixes
- Fix a CMake developer Warning when a Multi-Config Generator and Rust executable targets
([#213](https://github.com/corrosion-rs/corrosion/pull/213)).
- FindRust now respects the `QUIET` option to `find_package()` in most cases.
## Deprecation notice
- Support for the MSVC Generators with CMake toolchains before 3.20 is deprecated and will be removed in the next
release (v0.4). All other Multi-config Generators already require CMake 3.20.
## Internal Changes
- The CMake Generator written in Rust and `CorrosionGenerator.cmake` which are responsible for parsing
`cargo metadata` output to create corresponding CMake targets for all Rust targets now share most code.
This greatly simplified the CMake generator written in Rust and makes it much easier maintaining and adding
new features regardless of how `cargo metadata` is parsed.
# 0.2.2 (2022-09-01)
## Fixes
- Do not use C++17 in the tests (makes tests work with older C++ compilers) ([184](https://github.com/corrosion-rs/corrosion/pull/184))
- Fix finding cargo on NixOS ([192](https://github.com/corrosion-rs/corrosion/pull/192))
- Fix issue with Rustflags test when using a Build type other than Debug and Release ([203](https://github.com/corrosion-rs/corrosion/pull/203)).
# 0.2.1 (2022-05-07)
## Fixes
- Fix missing variables provided by corrosion, when corrosion is used as a subdirectory ([181](https://github.com/corrosion-rs/corrosion/pull/181)):
Public [Variables](https://github.com/corrosion-rs/corrosion#information-provided-by-corrosion) set
by Corrosion were not visible when using Corrosion as a subdirectory, due to the wrong scope of
the variables. This was fixed by promoting the respective variables to Cache variables.
# 0.2.0 (2022-05-05)
## Breaking changes
- Removed the integrator build script ([#156](https://github.com/corrosion-rs/corrosion/pull/156)).
The build script provided by corrosion (for rust code that links in foreign code) is no longer necessary,
so users can just remove the dependency.
## Deprecations
- Direct usage of the following target properties has been deprecated. The names of the custom properties are
no longer considered part of the public API and may change in the future. Instead, please use the functions
provided by corrosion. Internally different property names are used depending on the CMake version.
- `CORROSION_FEATURES`, `CORROSION_ALL_FEATURES`, `CORROSION_NO_DEFAULT_FEATURES`. Instead please use
`corrosion_set_features()`. See the updated Readme for details.
- `CORROSION_ENVIRONMENT_VARIABLES`. Please use `corrosion_set_env_vars()` instead.
- `CORROSION_USE_HOST_BUILD`. Please use `corrosion_set_hostbuild()` instead.
- The Minimum CMake version will likely be increased for the next major release. At the very least we want to drop
support for CMake 3.12, but requiring CMake 3.16 or even 3.18 is also on the table. If you are using a CMake version
that would be no longer supported by corrosion, please comment on issue
[#168](https://github.com/corrosion-rs/corrosion/issues/168), so that we can gauge the number of affected users.
## New features
- Add `NO_STD` option to `corrosion_import_crate` ([#154](https://github.com/corrosion-rs/corrosion/pull/154)).
- Remove the requirement of building the Rust based generator crate for CMake >= 3.19. This makes using corrosion as
a subdirectory as fast as the installed version (since everything is done in CMake).
([#131](https://github.com/corrosion-rs/corrosion/pull/131), [#161](https://github.com/corrosion-rs/corrosion/pull/161))
If you do choose to install Corrosion, then by default the old Generator is still compiled and installed, so you can
fall back to using it in case you use multiple cmake versions on the same machine for different projects.
## Fixes
- Fix Corrosion on MacOS 11 and 12 ([#167](https://github.com/corrosion-rs/corrosion/pull/167) and
[#164](https://github.com/corrosion-rs/corrosion/pull/164)).
- Improve robustness of parsing the LLVM version (exported in `Rust_LLVM_VERSION`). It now also works for
Rust versions, where the LLVM version is reported as `MAJOR.MINOR`. ([#148](https://github.com/corrosion-rs/corrosion/pull/148))
- Fix a bug which occurred when Corrosion was added multiple times via `add_subdirectory()`
([#143](https://github.com/corrosion-rs/corrosion/pull/143)).
- Set `CC_<target_triple_undercore>` and `CXX_<target_triple_undercore>` environment variables for the invocation of
`cargo build` to the compilers selected by CMake (if any)
([#138](https://github.com/corrosion-rs/corrosion/pull/138) and [#161](https://github.com/corrosion-rs/corrosion/pull/161)).
This should ensure that C dependencies built in cargo buildscripts via [cc-rs](https://github.com/alexcrichton/cc-rs)
use the same compiler as CMake built dependencies. Users can override the compiler by specifying the higher
priority environment variable variants with dashes instead of underscores (See cc-rs documentation for details).
- Fix Ninja-Multiconfig Generator support for CMake versions >= 3.20. Previous CMake versions are missing a feature,
which prevents us from supporting the Ninja-Multiconfig generator. ([#137](https://github.com/corrosion-rs/corrosion/pull/137))
# 0.1.0 (2022-02-01)
This is the first release of corrosion after it was moved to the new corrosion-rs organization.
Since there are no previous releases, this is not a complete changelog but only lists changes since
September 2021.
## New features
- [Add --profile support for rust >= 1.57](https://github.com/corrosion-rs/corrosion/pull/130):
Allows users to specify a custom cargo profile with
`corrosion_import_crate(... PROFILE <profilename>)`.
- [Add support for specifying per-target Rustflags](https://github.com/corrosion-rs/corrosion/pull/127):
Rustflags can be added via `corrosion_add_target_rustflags(<target_name> [rustflags1...])`
- [Add `Rust_IS_NIGHTLY` and `Rust_LLVM_VERSION` variables](https://github.com/corrosion-rs/corrosion/pull/123):
This may be useful if you want to conditionally enabled features when using a nightly toolchain
or a specific LLVM Version.
- [Let `FindRust` fail gracefully if rustc is not found](https://github.com/corrosion-rs/corrosion/pull/111):
This allows using `FindRust` in a more general setting (without corrosion).
- [Add support for cargo feature selection](https://github.com/corrosion-rs/corrosion/pull/108):
See the [README](https://github.com/corrosion-rs/corrosion#cargo-feature-selection) for details on
how to select features.
## Fixes
- [Fix the cargo-clean target](https://github.com/corrosion-rs/corrosion/pull/129)
- [Fix #84: CorrosionConfig.cmake looks in wrong place for Corrosion::Generator when CMAKE_INSTALL_LIBEXEC is an absolute path](https://github.com/corrosion-rs/corrosion/pull/122/commits/6f29af3ac53917ca2e0638378371e715a18a532d)
- [Fix #116: (Option CORROSION_INSTALL_EXECUTABLE not working)](https://github.com/corrosion-rs/corrosion/commit/97d44018fac1b1a2a7c095288c628f5bbd9b3184)
- [Fix building on Windows with rust >= 1.57](https://github.com/corrosion-rs/corrosion/pull/120)
## Known issues:
- Corrosion is currently not working on macos-11 and newer. See issue [#104](https://github.com/corrosion-rs/corrosion/issues/104).
Contributions are welcome.

View File

@@ -1,5 +0,0 @@
status = [
"bors-ci-status",
]
timeout_sec = 1800

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +0,0 @@
@PACKAGE_INIT@
if (Corrosion_FOUND)
return()
endif()
list(APPEND CMAKE_MODULE_PATH "@CMAKE_INSTALL_FULL_DATADIR@/cmake")
set(CORROSION_NATIVE_TOOLING_INSTALLED @CORROSION_NATIVE_TOOLING@)
if(CORROSION_NATIVE_TOOLING_INSTALLED AND NOT TARGET Corrosion::Generator)
add_executable(Corrosion::Generator IMPORTED GLOBAL)
set_property(
TARGET Corrosion::Generator
PROPERTY IMPORTED_LOCATION "@CMAKE_INSTALL_FULL_LIBEXECDIR@/corrosion-generator")
endif()
include(Corrosion)

View File

@@ -1,303 +0,0 @@
function(_cargo_metadata out manifest)
set(OPTIONS LOCKED FROZEN)
set(ONE_VALUE_KEYWORDS "")
set(MULTI_VALUE_KEYWORDS "")
cmake_parse_arguments(PARSE_ARGV 2 CM "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")
if(DEFINED CM_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Internal error - unexpected arguments: ${CM_UNPARSED_ARGUMENTS}")
elseif(DEFINED CM_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "Internal error - the following keywords had no associated value(s):"
"${CM_KEYWORDS_MISSING_VALUES}")
endif()
set(cargo_locked "")
set(cargo_frozen "")
if(LOCKED)
set(cargo_locked "--locked")
endif()
if(FROZEN)
set(cargo_frozen "--frozen")
endif()
execute_process(
COMMAND
${CMAKE_COMMAND} -E env
"CARGO_BUILD_RUSTC=${_CORROSION_RUSTC}"
"${_CORROSION_CARGO}"
metadata
--manifest-path "${manifest}"
--format-version 1
# We don't care about non-workspace dependencies
--no-deps
${cargo_locked}
${cargo_frozen}
OUTPUT_VARIABLE json
COMMAND_ERROR_IS_FATAL ANY
)
set(${out} "${json}" PARENT_SCOPE)
endfunction()
# Add targets (crates) of one package
function(_generator_add_package_targets)
set(OPTIONS NO_LINKER_OVERRIDE)
set(ONE_VALUE_KEYWORDS WORKSPACE_MANIFEST_PATH PACKAGE_MANIFEST_PATH PACKAGE_NAME PACKAGE_VERSION TARGETS_JSON OUT_CREATED_TARGETS)
set(MULTI_VALUE_KEYWORDS CRATE_TYPES)
cmake_parse_arguments(PARSE_ARGV 0 GAPT "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}")
if(DEFINED GAPT_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Internal error - unexpected arguments: ${GAPT_UNPARSED_ARGUMENTS}")
elseif(DEFINED GAPT_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "Internal error - the following keywords had no associated value(s):"
"${GAPT_KEYWORDS_MISSING_VALUES}")
endif()
_corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GAPT no_linker_override)
set(workspace_manifest_path "${GAPT_WORKSPACE_MANIFEST_PATH}")
set(package_manifest_path "${GAPT_PACKAGE_MANIFEST_PATH}")
set(package_name "${GAPT_PACKAGE_NAME}")
set(package_version "${GAPT_PACKAGE_VERSION}")
set(targets "${GAPT_TARGETS_JSON}")
set(out_created_targets "${GAPT_OUT_CREATED_TARGETS}")
set(crate_types "${GAPT_CRATE_TYPES}")
set(corrosion_targets "")
file(TO_CMAKE_PATH "${package_manifest_path}" manifest_path)
string(JSON targets_len LENGTH "${targets}")
math(EXPR targets_len-1 "${targets_len} - 1")
message(DEBUG "Found ${targets_len} targets in package ${package_name}")
foreach(ix RANGE ${targets_len-1})
string(JSON target GET "${targets}" ${ix})
string(JSON target_name GET "${target}" "name")
string(JSON target_kind GET "${target}" "kind")
string(JSON target_kind_len LENGTH "${target_kind}")
string(JSON target_name GET "${target}" "name")
math(EXPR target_kind_len-1 "${target_kind_len} - 1")
set(kinds)
foreach(ix RANGE ${target_kind_len-1})
string(JSON kind GET "${target_kind}" ${ix})
if(NOT crate_types OR ${kind} IN_LIST crate_types)
list(APPEND kinds ${kind})
endif()
endforeach()
if(TARGET "${target_name}"
AND ("staticlib" IN_LIST kinds OR "cdylib" IN_LIST kinds OR "bin" IN_LIST kinds)
)
message(WARNING "Failed to import Rust crate ${target_name} (kind: `${target_kind}`) because a target "
"with the same name already exists. Skipping this target.\n"
"Help: If you are importing a package which exposes both a `lib` and "
"a `bin` target, please consider explicitly naming the targets in your `Cargo.toml` manifest.\n"
"Note: If you have multiple different packages which have targets with the same name, please note that "
"this is currently not supported by Corrosion. Feel free to open an issue on Github to request "
"supporting this scenario."
)
# Skip this target to prevent a hard error.
continue()
endif()
if("staticlib" IN_LIST kinds OR "cdylib" IN_LIST kinds)
set(archive_byproducts "")
set(shared_lib_byproduct "")
set(pdb_byproduct "")
_corrosion_add_library_target(
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
TARGET_NAME "${target_name}"
LIB_KINDS ${kinds}
OUT_ARCHIVE_OUTPUT_BYPRODUCTS archive_byproducts
OUT_SHARED_LIB_BYPRODUCTS shared_lib_byproduct
OUT_PDB_BYPRODUCT pdb_byproduct
)
set(byproducts "")
list(APPEND byproducts "${archive_byproducts}" "${shared_lib_byproduct}" "${pdb_byproduct}")
set(cargo_build_out_dir "")
_add_cargo_build(
cargo_build_out_dir
PACKAGE ${package_name}
TARGET ${target_name}
MANIFEST_PATH "${manifest_path}"
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
TARGET_KINDS "${kinds}"
BYPRODUCTS "${byproducts}"
# Optional
${no_linker_override}
)
if(archive_byproducts)
_corrosion_copy_byproducts(
${target_name} ARCHIVE_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${archive_byproducts}"
)
endif()
if(shared_lib_byproduct)
_corrosion_copy_byproducts(
${target_name} LIBRARY_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${shared_lib_byproduct}"
)
endif()
if(pdb_byproduct)
_corrosion_copy_byproducts(
${target_name} PDB_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${pdb_byproduct}"
)
endif()
list(APPEND corrosion_targets ${target_name})
# Note: "bin" is mutually exclusive with "staticlib/cdylib", since `bin`s are seperate crates from libraries.
elseif("bin" IN_LIST kinds)
set(bin_byproduct "")
set(pdb_byproduct "")
_corrosion_add_bin_target("${workspace_manifest_path}" "${target_name}"
"bin_byproduct" "pdb_byproduct"
)
set(byproducts "")
list(APPEND byproducts "${bin_byproduct}" "${pdb_byproduct}")
set(cargo_build_out_dir "")
_add_cargo_build(
cargo_build_out_dir
PACKAGE "${package_name}"
TARGET "${target_name}"
MANIFEST_PATH "${manifest_path}"
WORKSPACE_MANIFEST_PATH "${workspace_manifest_path}"
TARGET_KINDS "bin"
BYPRODUCTS "${byproducts}"
# Optional
${no_linker_override}
)
_corrosion_copy_byproducts(
${target_name} RUNTIME_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${bin_byproduct}"
)
if(pdb_byproduct)
_corrosion_copy_byproducts(
${target_name} PDB_OUTPUT_DIRECTORY "${cargo_build_out_dir}" "${pdb_byproduct}"
)
endif()
list(APPEND corrosion_targets ${target_name})
else()
# ignore other kinds (like examples, tests, build scripts, ...)
endif()
endforeach()
if(NOT corrosion_targets)
message(DEBUG "No relevant targets found in package ${package_name} - Ignoring")
else()
set_target_properties(${corrosion_targets} PROPERTIES INTERFACE_COR_PACKAGE_MANIFEST_PATH "${package_manifest_path}")
endif()
set(${out_created_targets} "${corrosion_targets}" PARENT_SCOPE)
endfunction()
# Add all cargo targets defined in the packages defined in the Cargo.toml manifest at
# `MANIFEST_PATH`.
function(_generator_add_cargo_targets)
set(options NO_LINKER_OVERRIDE)
set(one_value_args MANIFEST_PATH IMPORTED_CRATES)
set(multi_value_args CRATES CRATE_TYPES)
cmake_parse_arguments(
GGC
"${options}"
"${one_value_args}"
"${multi_value_args}"
${ARGN}
)
_corrosion_option_passthrough_helper(NO_LINKER_OVERRIDE GGC no_linker_override)
_corrosion_arg_passthrough_helper(CRATE_TYPES GGC crate_types)
_cargo_metadata(json "${GGC_MANIFEST_PATH}")
string(JSON packages GET "${json}" "packages")
string(JSON workspace_members GET "${json}" "workspace_members")
string(JSON pkgs_len LENGTH "${packages}")
math(EXPR pkgs_len-1 "${pkgs_len} - 1")
string(JSON ws_mems_len LENGTH ${workspace_members})
math(EXPR ws_mems_len-1 "${ws_mems_len} - 1")
set(created_targets "")
foreach(ix RANGE ${pkgs_len-1})
string(JSON pkg GET "${packages}" ${ix})
string(JSON pkg_id GET "${pkg}" "id")
string(JSON pkg_name GET "${pkg}" "name")
string(JSON pkg_manifest_path GET "${pkg}" "manifest_path")
string(JSON pkg_version GET "${pkg}" "version")
if(DEFINED GGC_CRATES)
if(NOT pkg_name IN_LIST GGC_CRATES)
message(DEBUG "Package `${pkg_name}` was not in the `CRATES` allowlist passed to "
"corrosion_import_crate. Ignoring the package."
)
continue()
endif()
endif()
# probably this loop is not necessary at all, since when using --no-deps, the
# contents of packages should already be only workspace members!
unset(pkg_is_ws_member)
foreach(ix RANGE ${ws_mems_len-1})
string(JSON ws_mem GET "${workspace_members}" ${ix})
if(ws_mem STREQUAL pkg_id)
set(pkg_is_ws_member YES)
break()
endif()
endforeach()
if(NOT DEFINED pkg_is_ws_member)
# Since we pass `--no-deps` to cargo metadata now, I think this situation can't happen, but lets check for
# it anyway, just to discover any potential issues.
# If nobody complains for a while, it should be safe to remove this check and the previous loop, which
# should speed up the configuration process.
message(WARNING "The package `${pkg_name}` unexpectedly is not part of the workspace."
"Please open an issue at corrosion with some background information on the package"
)
endif()
string(JSON targets GET "${pkg}" "targets")
_generator_add_package_targets(
WORKSPACE_MANIFEST_PATH "${GGC_MANIFEST_PATH}"
PACKAGE_MANIFEST_PATH "${pkg_manifest_path}"
PACKAGE_NAME "${pkg_name}"
PACKAGE_VERSION "${pkg_version}"
TARGETS_JSON "${targets}"
OUT_CREATED_TARGETS curr_created_targets
${no_linker_override}
${crate_types}
)
list(APPEND created_targets "${curr_created_targets}")
endforeach()
if(NOT created_targets)
message(FATAL_ERROR "found no targets in ${pkgs_len} packages")
else()
message(DEBUG "Corrosion created the following CMake targets: ${created_targets}")
endif()
if(GGC_IMPORTED_CRATES)
set(${GGC_IMPORTED_CRATES} "${created_targets}" PARENT_SCOPE)
endif()
foreach(target_name ${created_targets})
foreach(output_var RUNTIME_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY)
get_target_property(output_dir ${target_name} "${output_var}")
if (NOT output_dir AND DEFINED "CMAKE_${output_var}")
set_property(TARGET ${target_name} PROPERTY ${output_var} "${CMAKE_${output_var}}")
endif()
foreach(config_type ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER "${config_type}" config_type_upper)
get_target_property(output_dir ${target_name} "${output_var}_${config_type_upper}")
if (NOT output_dir AND DEFINED "CMAKE_${output_var}_${config_type_upper}")
set_property(TARGET ${target_name} PROPERTY "${output_var}_${config_type_upper}" "${CMAKE_${output_var}_${config_type_upper}}")
endif()
endforeach()
endforeach()
endforeach()
endfunction()

View File

@@ -1,728 +0,0 @@
#[=======================================================================[.rst:
FindRust
--------
Find Rust
This module finds an installed rustc compiler and the cargo build tool. If Rust
is managed by rustup it determines the available toolchains and returns a
concrete Rust version, not a rustup proxy.
#]=======================================================================]
cmake_minimum_required(VERSION 3.12)
# search for Cargo here and set up a bunch of cool flags and stuff
include(FindPackageHandleStandardArgs)
# Print error message and return.
macro(_findrust_failed)
if("${Rust_FIND_REQUIRED}")
message(FATAL_ERROR ${ARGN})
elseif(NOT "${Rust_FIND_QUIETLY}")
message(WARNING ${ARGN})
endif()
# Note: PARENT_SCOPE is the scope of the caller of the caller of this macro.
set(Rust_FOUND "" PARENT_SCOPE)
return()
endmacro()
# Checks if the actual version of a Rust toolchain matches the VERSION requirements specified in find_package.
function(_findrust_version_ok ACTUAL_VERSION OUT_IS_OK)
if(DEFINED Rust_FIND_VERSION_RANGE)
if(Rust_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE")
set(COMPARSION_OPERATOR "VERSION_LESS_EQUAL")
elseif(Rust_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE")
set(COMPARSION_OPERATOR "VERSION_LESS")
else()
message(FATAL_ERROR "Unexpected value in `<PackageName>_FIND_VERSION_RANGE_MAX`: "
"`${Rust_FIND_VERSION_RANGE_MAX}`.")
endif()
if(("${ACTUAL_VERSION}" VERSION_GREATER_EQUAL "${Rust_FIND_VERSION_RANGE_MIN}")
AND
( "${ACTUAL_VERSION}" ${COMPARSION_OPERATOR} "${Rust_FIND_VERSION_RANGE_MAX}" )
)
set("${OUT_IS_OK}" TRUE PARENT_SCOPE)
else()
set("${OUT_IS_OK}" FALSE PARENT_SCOPE)
endif()
elseif(DEFINED Rust_FIND_VERSION)
if(Rust_VERSION_EXACT)
set(COMPARISON_OPERATOR VERSION_EQUAL)
else()
set(COMPARISON_OPERATOR VERSION_GREATER_EQUAL)
endif()
if(_TOOLCHAIN_${_TOOLCHAIN_SELECTED}_VERSION "${COMPARISON_OPERATOR}" Rust_FIND_VERSION)
set("${OUT_IS_OK}" TRUE PARENT_SCOPE)
else()
set("${OUT_IS_OK}" FALSE PARENT_SCOPE)
endif()
else()
# if no VERSION requirement was specified, the version is always okay.
set("${OUT_IS_OK}" TRUE PARENT_SCOPE)
endif()
endfunction()
function(_corrosion_strip_target_triple input_triple_or_path output_triple)
# If the target_triple is a path to a custom target specification file, then strip everything
# except the filename from `target_triple`.
get_filename_component(target_triple_ext "${input_triple_or_path}" EXT)
set(target_triple "${input_triple_or_path}")
if(target_triple_ext)
if(target_triple_ext STREQUAL ".json")
get_filename_component(target_triple "${input_triple_or_path}" NAME_WE)
endif()
endif()
set(${output_triple} "${target_triple}" PARENT_SCOPE)
endfunction()
function(_corrosion_parse_target_triple target_triple out_arch out_vendor out_os out_env)
_corrosion_strip_target_triple(${target_triple} target_triple)
# The vendor part may be left out from the target triple, and since `env` is also optional,
# we determine if vendor is present by matching against a list of known vendors.
set(known_vendors
"apple"
"esp" # riscv32imc-esp-espidf
"fortanix"
"kmc"
"pc"
"nintendo"
"nvidia"
"openwrt"
"alpine"
"unknown"
"uwp" # aarch64-uwp-windows-msvc
"wrs" # e.g. aarch64-wrs-vxworks
"sony"
"sun"
)
# todo: allow users to add additional vendors to the list via a cmake variable.
list(JOIN known_vendors "|" known_vendors_joined)
# vendor is optional - We detect if vendor is present by matching against a known list of
# vendors. The next field is the OS, which we assume to always be present, while the last field
# is again optional and contains the environment.
string(REGEX MATCH
"^([a-z0-9_\.]+)-((${known_vendors_joined})-)?([a-z0-9_]+)(-([a-z0-9_]+))?$"
whole_match
"${target_triple}"
)
if((NOT whole_match) AND (NOT CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED))
message(WARNING "Failed to parse target-triple `${target_triple}`."
"Corrosion attempts to link required C libraries depending on the OS "
"specified in the Rust target-triple for Linux, MacOS and windows.\n"
"Note: If you are targeting a different OS you can surpress this warning by"
" setting the CMake cache variable "
"`CORROSION_NO_WARN_PARSE_TARGET_TRIPLE_FAILED`."
"Please consider opening an issue on github if you encounter this warning."
)
endif()
message(DEBUG "Parsed Target triple: arch: ${CMAKE_MATCH_1}, vendor: ${CMAKE_MATCH_3}, "
"OS: ${CMAKE_MATCH_4}, env: ${CMAKE_MATCH_6}")
set("${out_arch}" "${CMAKE_MATCH_1}" PARENT_SCOPE)
set("${out_vendor}" "${CMAKE_MATCH_3}" PARENT_SCOPE)
set("${out_os}" "${CMAKE_MATCH_4}" PARENT_SCOPE)
set("${out_env}" "${CMAKE_MATCH_6}" PARENT_SCOPE)
endfunction()
# Hardcoded, best effort approach
function(_corrosion_determine_libs arch vendor os env out_libs)
if(os STREQUAL "windows")
list(APPEND libs "advapi32" "userenv" "ws2_32")
if(env STREQUAL "msvc")
list(APPEND libs "$<$<CONFIG:Debug>:msvcrtd>")
# CONFIG takes a comma seperated list starting with CMake 3.19, but we still need to
# support older CMake versions.
set(config_is_release "$<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>,$<CONFIG:RelWithDebInfo>>")
list(APPEND libs "$<${config_is_release}:msvcrt>")
elseif(env STREQUAL "gnu")
list(APPEND libs "gcc_eh" "pthread")
endif()
if(Rust_VERSION VERSION_LESS "1.33.0")
list(APPEND libs "shell32" "kernel32")
endif()
if(Rust_VERSION VERSION_GREATER_EQUAL "1.57.0")
list(APPEND libs "bcrypt")
endif()
elseif(vendor STREQUAL "apple" AND os STREQUAL "darwin")
list(APPEND libs "System" "resolv" "c" "m")
elseif(os STREQUAL "linux")
list(APPEND libs "dl" "rt" "pthread" "gcc_s" "c" "m" "util")
endif()
set("${out_libs}" "${libs}" PARENT_SCOPE)
endfunction()
if (NOT "${Rust_TOOLCHAIN}" STREQUAL "$CACHE{Rust_TOOLCHAIN}")
# Promote Rust_TOOLCHAIN to a cache variable if it is not already a cache variable
set(Rust_TOOLCHAIN ${Rust_TOOLCHAIN} CACHE STRING "Requested rustup toolchain" FORCE)
endif()
# This block checks to see if we're prioritizing a rustup-managed toolchain.
if (DEFINED Rust_TOOLCHAIN)
# If the user specifies `Rust_TOOLCHAIN`, then look for `rustup` first, rather than `rustc`.
find_program(Rust_RUSTUP rustup PATHS "$ENV{HOME}/.cargo/bin")
if(Rust_RUSTUP)
set(_RESOLVE_RUSTUP_TOOLCHAINS ON)
else()
set(_RESOLVE_RUSTUP_TOOLCHAINS OFF)
if(NOT "${Rust_FIND_QUIETLY}")
message(
WARNING "CMake variable `Rust_TOOLCHAIN` specified, but `rustup` was not found. "
"Ignoring toolchain and looking for a Rust toolchain not managed by rustup.")
endif()
endif()
else()
# If we aren't definitely using a rustup toolchain, look for rustc first - the user may have
# a toolchain installed via a method other than rustup higher in the PATH, which should be
# preferred. However, if the first-found rustc is a rustup proxy, then we'll revert to
# finding the preferred toolchain via rustup.
# Uses `Rust_COMPILER` to let user-specified `rustc` win. But we will still "override" the
# user's setting if it is pointing to `rustup`. Default rustup install path is provided as a
# backup if a toolchain cannot be found in the user's PATH.
if (DEFINED Rust_COMPILER)
set(_Rust_COMPILER_TEST "${Rust_COMPILER}")
set(_USER_SPECIFIED_RUSTC ON)
if(NOT (EXISTS "${_Rust_COMPILER_TEST}" AND NOT IS_DIRECTORY "${_Rust_COMPILER_TEST}"))
set(_ERROR_MESSAGE "Rust_COMPILER was set to `${Rust_COMPILER}`, but this file does "
"not exist."
)
_findrust_failed(${_ERROR_MESSAGE})
return()
endif()
else()
find_program(_Rust_COMPILER_TEST rustc PATHS "$ENV{HOME}/.cargo/bin")
if(NOT EXISTS "${_Rust_COMPILER_TEST}")
set(_ERROR_MESSAGE "`rustc` not found in PATH or `$ENV{HOME}/.cargo/bin`.\n"
"Hint: Check if `rustc` is in PATH or manually specify the location "
"by setting `Rust_COMPILER` to the path to `rustc`.")
_findrust_failed(${_ERROR_MESSAGE})
endif()
endif()
# Check if the discovered rustc is actually a "rustup" proxy.
execute_process(
COMMAND
${CMAKE_COMMAND} -E env
RUSTUP_FORCE_ARG0=rustup
"${_Rust_COMPILER_TEST}" --version
OUTPUT_VARIABLE _RUSTC_VERSION_RAW
ERROR_VARIABLE _RUSTC_VERSION_STDERR
RESULT_VARIABLE _RUSTC_VERSION_RESULT
)
if(NOT (_RUSTC_VERSION_RESULT EQUAL "0"))
_findrust_failed("`${_Rust_COMPILER_TEST} --version` failed with ${_RUSTC_VERSION_RESULT}\n"
"rustc stderr:\n${_RUSTC_VERSION_STDERR}"
)
endif()
if (_RUSTC_VERSION_RAW MATCHES "rustup [0-9\\.]+")
if (_USER_SPECIFIED_RUSTC)
message(
WARNING "User-specified Rust_COMPILER pointed to rustup's rustc proxy. Corrosion's "
"FindRust will always try to evaluate to an actual Rust toolchain, and so the "
"user-specified Rust_COMPILER will be discarded in favor of the default "
"rustup-managed toolchain."
)
unset(Rust_COMPILER)
unset(Rust_COMPILER CACHE)
endif()
set(_RESOLVE_RUSTUP_TOOLCHAINS ON)
# Get `rustup` next to the `rustc` proxy
get_filename_component(_RUST_PROXIES_PATH "${_Rust_COMPILER_TEST}" DIRECTORY)
find_program(Rust_RUSTUP rustup HINTS "${_RUST_PROXIES_PATH}" NO_DEFAULT_PATH)
endif()
unset(_Rust_COMPILER_TEST CACHE)
endif()
# At this point, the only thing we should have evaluated is a path to `rustup` _if that's what the
# best source for a Rust toolchain was determined to be_.
# List of user variables that will override any toolchain-provided setting
set(_Rust_USER_VARS Rust_COMPILER Rust_CARGO Rust_CARGO_TARGET Rust_CARGO_HOST_TARGET)
foreach(_VAR ${_Rust_USER_VARS})
if (DEFINED "${_VAR}")
set(${_VAR}_CACHED "${${_VAR}}" CACHE INTERNAL "Internal cache of ${_VAR}")
else()
unset(${_VAR}_CACHED CACHE)
endif()
endforeach()
# Discover what toolchains are installed by rustup, if the discovered `rustc` is a proxy from
# `rustup`, then select either the default toolchain, or the requested toolchain Rust_TOOLCHAIN
if (_RESOLVE_RUSTUP_TOOLCHAINS)
execute_process(
COMMAND
"${Rust_RUSTUP}" toolchain list --verbose
OUTPUT_VARIABLE _TOOLCHAINS_RAW
)
string(REPLACE "\n" ";" _TOOLCHAINS_RAW "${_TOOLCHAINS_RAW}")
set(_DISCOVERED_TOOLCHAINS "")
set(_DISCOVERED_TOOLCHAINS_RUSTC_PATH "")
set(_DISCOVERED_TOOLCHAINS_CARGO_PATH "")
set(_DISCOVERED_TOOLCHAINS_VERSION "")
foreach(_TOOLCHAIN_RAW ${_TOOLCHAINS_RAW})
if (_TOOLCHAIN_RAW MATCHES "([a-zA-Z0-9\\._\\-]+)[ \t\r\n]?(\\(default\\) \\(override\\)|\\(default\\)|\\(override\\))?[ \t\r\n]+(.+)")
set(_TOOLCHAIN "${CMAKE_MATCH_1}")
set(_TOOLCHAIN_TYPE "${CMAKE_MATCH_2}")
set(_TOOLCHAIN_PATH "${CMAKE_MATCH_3}")
set(_TOOLCHAIN_${_TOOLCHAIN}_PATH "${CMAKE_MATCH_3}")
if (_TOOLCHAIN_TYPE MATCHES ".*\\(default\\).*")
set(_TOOLCHAIN_DEFAULT "${_TOOLCHAIN}")
endif()
if (_TOOLCHAIN_TYPE MATCHES ".*\\(override\\).*")
set(_TOOLCHAIN_OVERRIDE "${_TOOLCHAIN}")
endif()
execute_process(
COMMAND
"${_TOOLCHAIN_PATH}/bin/rustc" --version
OUTPUT_VARIABLE _TOOLCHAIN_RAW_VERSION
)
if (_TOOLCHAIN_RAW_VERSION MATCHES "rustc ([0-9]+)\\.([0-9]+)\\.([0-9]+)(-nightly)?")
list(APPEND _DISCOVERED_TOOLCHAINS "${_TOOLCHAIN}")
list(APPEND _DISCOVERED_TOOLCHAINS_RUSTC_PATH "${_TOOLCHAIN_PATH}/bin/rustc")
list(APPEND _DISCOVERED_TOOLCHAINS_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
# We need this variable to determine the default toolchain, since `foreach(... IN ZIP_LISTS ...)`
# requires CMake 3.17. As a workaround we define this variable to lookup the version when iterating
# through the `_DISCOVERED_TOOLCHAINS` lists.
set(_TOOLCHAIN_${_TOOLCHAIN}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
if(CMAKE_MATCH_4)
set(_TOOLCHAIN_${_TOOLCHAIN}_IS_NIGHTLY "TRUE")
else()
set(_TOOLCHAIN_${_TOOLCHAIN}_IS_NIGHTLY "FALSE")
endif()
if(EXISTS "${_TOOLCHAIN_PATH}/bin/cargo")
list(APPEND _DISCOVERED_TOOLCHAINS_CARGO_PATH "${_TOOLCHAIN_PATH}/bin/cargo")
else()
list(APPEND _DISCOVERED_TOOLCHAINS_CARGO_PATH "NOTFOUND")
endif()
else()
message(AUTHOR_WARNING "Unexpected output from `rustc --version` for Toolchain `${_TOOLCHAIN}`: "
"`${_TOOLCHAIN_RAW_VERSION}`.\n"
"Ignoring this toolchain."
)
endif()
else()
message(AUTHOR_WARNING "Didn't recognize toolchain: ${_TOOLCHAIN_RAW}. Ignoring this toolchain.\n"
"Rustup toolchain list output( `${Rust_RUSTUP} toolchain list --verbose`):\n"
"${_TOOLCHAINS_RAW}"
)
endif()
endforeach()
# Expose a list of available rustup toolchains.
list(LENGTH _DISCOVERED_TOOLCHAINS _toolchain_len)
list(LENGTH _DISCOVERED_TOOLCHAINS_RUSTC_PATH _toolchain_rustc_len)
list(LENGTH _DISCOVERED_TOOLCHAINS_CARGO_PATH _toolchain_cargo_len)
list(LENGTH _DISCOVERED_TOOLCHAINS_VERSION _toolchain_version_len)
if(NOT
(_toolchain_len EQUAL _toolchain_rustc_len
AND _toolchain_cargo_len EQUAL _toolchain_version_len
AND _toolchain_len EQUAL _toolchain_cargo_len)
)
message(FATAL_ERROR "Internal error - list length mismatch."
"List lengths: ${_toolchain_len} toolchains, ${_toolchain_rustc_len} rustc, ${_toolchain_cargo_len} cargo,"
" ${_toolchain_version_len} version. The lengths should be the same."
)
endif()
set(Rust_RUSTUP_TOOLCHAINS CACHE INTERNAL "List of available Rustup toolchains" "${_DISCOVERED_TOOLCHAINS}")
set(Rust_RUSTUP_TOOLCHAINS_RUSTC_PATH
CACHE INTERNAL
"List of the rustc paths corresponding to the toolchain at the same index in `Rust_RUSTUP_TOOLCHAINS`."
"${_DISCOVERED_TOOLCHAINS_RUSTC_PATH}"
)
set(Rust_RUSTUP_TOOLCHAINS_CARGO_PATH
CACHE INTERNAL
"List of the cargo paths corresponding to the toolchain at the same index in `Rust_RUSTUP_TOOLCHAINS`. \
May also be `NOTFOUND` if the toolchain does not have a cargo executable."
"${_DISCOVERED_TOOLCHAINS_CARGO_PATH}"
)
set(Rust_RUSTUP_TOOLCHAINS_VERSION
CACHE INTERNAL
"List of the rust toolchain version corresponding to the toolchain at the same index in \
`Rust_RUSTUP_TOOLCHAINS`."
"${_DISCOVERED_TOOLCHAINS_VERSION}"
)
# Rust_TOOLCHAIN is preferred over a requested version if it is set.
if (NOT DEFINED Rust_TOOLCHAIN)
if (NOT DEFINED _TOOLCHAIN_OVERRIDE)
set(_TOOLCHAIN_SELECTED "${_TOOLCHAIN_DEFAULT}")
else()
set(_TOOLCHAIN_SELECTED "${_TOOLCHAIN_OVERRIDE}")
endif()
# Check default toolchain first.
_findrust_version_ok("_TOOLCHAIN_${_TOOLCHAIN_SELECTED}_VERSION" _VERSION_OK)
if(NOT "${_VERSION_OK}")
foreach(_TOOLCHAIN "${_DISCOVERED_TOOLCHAINS}")
_findrust_version_ok("_TOOLCHAIN_${_TOOLCHAIN}_VERSION" _VERSION_OK)
if("${_VERSION_OK}")
set(_TOOLCHAIN_SELECTED "${_TOOLCHAIN}")
break()
endif()
endforeach()
# Check if we found a suitable version in the for loop.
if(NOT "${_VERSION_OK}")
string(REPLACE ";" "\n" _DISCOVERED_TOOLCHAINS "${_DISCOVERED_TOOLCHAINS}")
_findrust_failed("Failed to find a Rust toolchain matching the version requirements of "
"${Rust_FIND_VERSION}. Available toolchains: ${_DISCOVERED_TOOLCHAINS}")
endif()
endif()
endif()
set(Rust_TOOLCHAIN "${_TOOLCHAIN_SELECTED}" CACHE STRING "The rustup toolchain to use")
set_property(CACHE Rust_TOOLCHAIN PROPERTY STRINGS "${_DISCOVERED_TOOLCHAINS}")
if(NOT Rust_FIND_QUIETLY)
message(STATUS "Rust Toolchain: ${Rust_TOOLCHAIN}")
endif()
if (NOT Rust_TOOLCHAIN IN_LIST _DISCOVERED_TOOLCHAINS)
# If the precise toolchain wasn't found, try appending the default host
execute_process(
COMMAND
"${Rust_RUSTUP}" show
RESULT_VARIABLE _SHOW_RESULT
OUTPUT_VARIABLE _SHOW_RAW
)
if(NOT "${_SHOW_RESULT}" EQUAL "0")
_findrust_failed("Command `${Rust_RUSTUP} show` failed")
endif()
if (_SHOW_RAW MATCHES "Default host: ([a-zA-Z0-9_\\-]*)\n")
set(_DEFAULT_HOST "${CMAKE_MATCH_1}")
else()
_findrust_failed("Failed to parse \"Default host\" from `${Rust_RUSTUP} show`. Got: ${_SHOW_RAW}")
endif()
if (NOT "${Rust_TOOLCHAIN}-${_DEFAULT_HOST}" IN_LIST _DISCOVERED_TOOLCHAINS)
set(_NOT_FOUND_MESSAGE "Could not find toolchain '${Rust_TOOLCHAIN}'\n"
"Available toolchains:\n"
)
foreach(_TOOLCHAIN ${_DISCOVERED_TOOLCHAINS})
list(APPEND _NOT_FOUND_MESSAGE " `${_TOOLCHAIN}`\n")
endforeach()
_findrust_failed(${_NOT_FOUND_MESSAGE})
endif()
set(_RUSTUP_TOOLCHAIN_FULL "${Rust_TOOLCHAIN}-${_DEFAULT_HOST}")
else()
set(_RUSTUP_TOOLCHAIN_FULL "${Rust_TOOLCHAIN}")
endif()
set(_RUST_TOOLCHAIN_PATH "${_TOOLCHAIN_${_RUSTUP_TOOLCHAIN_FULL}_PATH}")
if(NOT "${Rust_FIND_QUIETLY}")
message(VERBOSE "Rust toolchain ${_RUSTUP_TOOLCHAIN_FULL}")
message(VERBOSE "Rust toolchain path ${_RUST_TOOLCHAIN_PATH}")
endif()
# Is overridden if the user specifies `Rust_COMPILER` explicitly.
find_program(
Rust_COMPILER_CACHED
rustc
HINTS "${_RUST_TOOLCHAIN_PATH}/bin"
NO_DEFAULT_PATH)
else()
find_program(Rust_COMPILER_CACHED rustc)
if (EXISTS "${Rust_COMPILER_CACHED}")
# rustc is expected to be at `<toolchain_path>/bin/rustc`.
get_filename_component(_RUST_TOOLCHAIN_PATH "${Rust_COMPILER_CACHED}" DIRECTORY)
get_filename_component(_RUST_TOOLCHAIN_PATH "${_RUST_TOOLCHAIN_PATH}" DIRECTORY)
endif()
endif()
if (NOT EXISTS "${Rust_COMPILER_CACHED}")
set(_NOT_FOUND_MESSAGE "The rustc executable was not found. "
"Rust not installed or ~/.cargo/bin not added to path?\n"
"Hint: Consider setting `Rust_COMPILER` to the absolute path of `rustc`."
)
_findrust_failed(${_NOT_FOUND_MESSAGE})
endif()
if (_RESOLVE_RUSTUP_TOOLCHAINS)
set(_NOT_FOUND_MESSAGE "Rust was detected to be managed by rustup, but failed to find `cargo` "
"next to `rustc` in `${_RUST_TOOLCHAIN_PATH}/bin`. This can happen for custom toolchains, "
"if cargo was not built. "
"Please manually specify the path to a compatible `cargo` by setting `Rust_CARGO`."
)
find_program(
Rust_CARGO_CACHED
cargo
HINTS "${_RUST_TOOLCHAIN_PATH}/bin"
NO_DEFAULT_PATH
)
# note: maybe can use find_package_handle_standard_args here, if we remove the _CACHED postfix.
# not sure why that is here...
if(NOT EXISTS "${Rust_CARGO_CACHED}")
_findrust_failed(${_NOT_FOUND_MESSAGE})
endif()
set(Rust_TOOLCHAIN_IS_RUSTUP_MANAGED TRUE CACHE INTERNAL "" FORCE)
else()
set(_NOT_FOUND_MESSAGE "Failed to find `cargo` in PATH and `${_RUST_TOOLCHAIN_PATH}/bin`.\n"
"Please ensure cargo is in PATH or manually specify the path to a compatible `cargo` by "
"setting `Rust_CARGO`."
)
# On some systems (e.g. NixOS) cargo is not managed by rustup and also not next to rustc.
find_program(
Rust_CARGO_CACHED
cargo
HINTS "${_RUST_TOOLCHAIN_PATH}/bin"
)
# note: maybe can use find_package_handle_standard_args here, if we remove the _CACHED postfix.
# not sure why that is here...
if(NOT EXISTS "${Rust_CARGO_CACHED}")
_findrust_failed(${_NOT_FOUND_MESSAGE})
endif()
endif()
execute_process(
COMMAND "${Rust_CARGO_CACHED}" --version --verbose
OUTPUT_VARIABLE _CARGO_VERSION_RAW
RESULT_VARIABLE _CARGO_VERSION_RESULT
)
# todo: check if cargo is a required component!
if(NOT ( "${_CARGO_VERSION_RESULT}" EQUAL "0" ))
_findrust_failed("Failed to get cargo version.\n"
"`${Rust_CARGO_CACHED} --version` failed with error: `${_CARGO_VERSION_RESULT}"
)
endif()
# todo: don't set cache variables here, but let find_package_handle_standard_args do the promotion
# later.
if (_CARGO_VERSION_RAW MATCHES "cargo ([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(Rust_CARGO_VERSION_MAJOR "${CMAKE_MATCH_1}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION_MINOR "${CMAKE_MATCH_2}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION_PATCH "${CMAKE_MATCH_3}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION "${Rust_CARGO_VERSION_MAJOR}.${Rust_CARGO_VERSION_MINOR}.${Rust_CARGO_VERSION_PATCH}" CACHE INTERNAL "" FORCE)
# Workaround for the version strings where the `cargo ` prefix is missing.
elseif(_CARGO_VERSION_RAW MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(Rust_CARGO_VERSION_MAJOR "${CMAKE_MATCH_1}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION_MINOR "${CMAKE_MATCH_2}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION_PATCH "${CMAKE_MATCH_3}" CACHE INTERNAL "" FORCE)
set(Rust_CARGO_VERSION "${Rust_CARGO_VERSION_MAJOR}.${Rust_CARGO_VERSION_MINOR}.${Rust_CARGO_VERSION_PATCH}" CACHE INTERNAL "" FORCE)
else()
_findrust_failed(
"Failed to parse cargo version. `cargo --version` evaluated to (${_CARGO_VERSION_RAW}). "
"Expected a <Major>.<Minor>.<Patch> version triple."
)
endif()
execute_process(
COMMAND "${Rust_COMPILER_CACHED}" --version --verbose
OUTPUT_VARIABLE _RUSTC_VERSION_RAW
RESULT_VARIABLE _RUSTC_VERSION_RESULT
)
if(NOT ( "${_RUSTC_VERSION_RESULT}" EQUAL "0" ))
_findrust_failed("Failed to get rustc version.\n"
"${Rust_COMPILER_CACHED} --version failed with error: `${_RUSTC_VERSION_RESULT}`")
endif()
if (_RUSTC_VERSION_RAW MATCHES "rustc ([0-9]+)\\.([0-9]+)\\.([0-9]+)(-nightly)?")
set(Rust_VERSION_MAJOR "${CMAKE_MATCH_1}" CACHE INTERNAL "" FORCE)
set(Rust_VERSION_MINOR "${CMAKE_MATCH_2}" CACHE INTERNAL "" FORCE)
set(Rust_VERSION_PATCH "${CMAKE_MATCH_3}" CACHE INTERNAL "" FORCE)
set(Rust_VERSION "${Rust_VERSION_MAJOR}.${Rust_VERSION_MINOR}.${Rust_VERSION_PATCH}" CACHE INTERNAL "" FORCE)
if(CMAKE_MATCH_4)
set(Rust_IS_NIGHTLY 1 CACHE INTERNAL "" FORCE)
else()
set(Rust_IS_NIGHTLY 0 CACHE INTERNAL "" FORCE)
endif()
else()
_findrust_failed("Failed to parse rustc version. `${Rust_COMPILER_CACHED} --version --verbose` "
"evaluated to:\n`${_RUSTC_VERSION_RAW}`"
)
endif()
if (_RUSTC_VERSION_RAW MATCHES "host: ([a-zA-Z0-9_\\-]*)\n")
set(Rust_DEFAULT_HOST_TARGET "${CMAKE_MATCH_1}")
set(Rust_CARGO_HOST_TARGET_CACHED "${Rust_DEFAULT_HOST_TARGET}" CACHE STRING "Host triple")
else()
_findrust_failed(
"Failed to parse rustc host target. `rustc --version --verbose` evaluated to:\n${_RUSTC_VERSION_RAW}"
)
endif()
if (_RUSTC_VERSION_RAW MATCHES "LLVM version: ([0-9]+)\\.([0-9]+)(\\.([0-9]+))?")
set(Rust_LLVM_VERSION_MAJOR "${CMAKE_MATCH_1}" CACHE INTERNAL "" FORCE)
set(Rust_LLVM_VERSION_MINOR "${CMAKE_MATCH_2}" CACHE INTERNAL "" FORCE)
# With the Rust toolchain 1.44.1 the reported LLVM version is 9.0, i.e. without a patch version.
# Since cmake regex does not support non-capturing groups, just ignore Match 3.
set(Rust_LLVM_VERSION_PATCH "${CMAKE_MATCH_4}" CACHE INTERNAL "" FORCE)
set(Rust_LLVM_VERSION "${Rust_LLVM_VERSION_MAJOR}.${Rust_LLVM_VERSION_MINOR}.${Rust_LLVM_VERSION_PATCH}" CACHE INTERNAL "" FORCE)
elseif(NOT Rust_FIND_QUIETLY)
message(
WARNING
"Failed to parse rustc LLVM version. `rustc --version --verbose` evaluated to:\n${_RUSTC_VERSION_RAW}"
)
endif()
if (NOT Rust_CARGO_TARGET_CACHED)
unset(_CARGO_ARCH)
unset(_CARGO_ABI)
if (WIN32)
if (CMAKE_VS_PLATFORM_NAME)
if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
set(_CARGO_ARCH i686)
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
set(_CARGO_ARCH x86_64)
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM64")
set(_CARGO_ARCH aarch64)
else()
message(WARNING "VS Platform '${CMAKE_VS_PLATFORM_NAME}' not recognized")
endif()
endif()
# Fallback path
if(NOT DEFINED _CARGO_ARCH)
# Possible values for windows when not cross-compiling taken from here:
# https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details
# When cross-compiling the user is expected to supply the value, so we match more variants.
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64|amd64|x86_64)$")
set(_CARGO_ARCH x86_64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|arm64|aarch64)$")
set(_CARGO_ARCH aarch64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(X86|x86|i686)$")
set(_CARGO_ARCH i686)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i586")
set(_CARGO_ARCH i586)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "IA64")
message(FATAL_ERROR "No rust target for Intel Itanium.")
elseif(NOT "${CMAKE_SYSTEM_PROCESSOR}")
message(WARNING "Failed to detect target architecture. Please set `CMAKE_SYSTEM_PROCESSOR`"
" to your target architecture or set `Rust_CARGO_TARGET` to your cargo target triple."
)
else()
message(WARNING "Failed to detect target architecture. Please set "
"`Rust_CARGO_TARGET` to your cargo target triple."
)
endif()
endif()
set(_CARGO_VENDOR "pc-windows")
# The MSVC Generators will always target the msvc ABI.
# For other generators we check the compiler ID and compiler target (if present)
# If no compiler is set and we are not cross-compiling then we just choose the
# default rust host target.
if(DEFINED MSVC
OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC"
OR "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC"
OR "${CMAKE_CXX_COMPILER_TARGET}" MATCHES "-msvc$"
OR "${CMAKE_C_COMPILER_TARGET}" MATCHES "-msvc$"
)
set(_CARGO_ABI msvc)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"
OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU"
OR "${CMAKE_CXX_COMPILER_TARGET}" MATCHES "-gnu$"
OR "${CMAKE_C_COMPILER_TARGET}" MATCHES "-gnu$"
OR (NOT CMAKE_CROSSCOMPILING AND "${Rust_DEFAULT_HOST_TARGET}" MATCHES "-gnu$")
)
set(_CARGO_ABI gnu)
elseif(NOT "${CMAKE_CROSSCOMPILING}" AND "${Rust_DEFAULT_HOST_TARGET}" MATCHES "-msvc$")
# We first check if the gnu branch matches to ensure this fallback is only used
# if no compiler is enabled.
set(_CARGO_ABI msvc)
else()
message(WARNING "Could not determine the target ABI. Please specify `Rust_CARGO_TARGET` manually.")
endif()
if(DEFINED _CARGO_ARCH AND DEFINED _CARGO_VENDOR AND DEFINED _CARGO_ABI)
set(Rust_CARGO_TARGET_CACHED "${_CARGO_ARCH}-${_CARGO_VENDOR}-${_CARGO_ABI}"
CACHE STRING "Target triple")
endif()
elseif (ANDROID)
if (CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a)
if (CMAKE_ANDROID_ARM_MODE)
set(_Rust_ANDROID_TARGET armv7-linux-androideabi)
else ()
set(_Rust_ANDROID_TARGET thumbv7neon-linux-androideabi)
endif()
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a)
set(_Rust_ANDROID_TARGET aarch64-linux-android)
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL x86)
set(_Rust_ANDROID_TARGET i686-linux-android)
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL x86_64)
set(_Rust_ANDROID_TARGET x86_64-linux-android)
endif()
if (_Rust_ANDROID_TARGET)
set(Rust_CARGO_TARGET_CACHED "${_Rust_ANDROID_TARGET}" CACHE STRING "Target triple")
endif()
endif()
# Fallback to the default host target
if(NOT Rust_CARGO_TARGET_CACHED)
if(CMAKE_CROSSCOMPILING)
message(WARNING "CMake is in cross-compiling mode, but the cargo target-triple could not be inferred."
"Falling back to the default host target. Please consider manually setting `Rust_CARGO_TARGET`."
)
endif()
set(Rust_CARGO_TARGET_CACHED "${Rust_DEFAULT_HOST_TARGET}" CACHE STRING "Target triple")
endif()
message(STATUS "Rust Target: ${Rust_CARGO_TARGET_CACHED}")
endif()
if(Rust_CARGO_TARGET_CACHED STREQUAL Rust_DEFAULT_HOST_TARGET)
set(Rust_CROSSCOMPILING FALSE CACHE INTERNAL "Rust is configured for cross-compiling")
else()
set(Rust_CROSSCOMPILING TRUE CACHE INTERNAL "Rust is configured for cross-compiling")
endif()
_corrosion_parse_target_triple("${Rust_CARGO_TARGET_CACHED}" rust_arch rust_vendor rust_os rust_env)
_corrosion_determine_libs("${rust_arch}" "${rust_vendor}" "${rust_os}" "${rust_env}" rust_libs)
set(Rust_CARGO_TARGET_ARCH "${rust_arch}" CACHE INTERNAL "Target architecture")
set(Rust_CARGO_TARGET_VENDOR "${rust_vendor}" CACHE INTERNAL "Target vendor")
set(Rust_CARGO_TARGET_OS "${rust_os}" CACHE INTERNAL "Target Operating System")
set(Rust_CARGO_TARGET_ENV "${rust_env}" CACHE INTERNAL "Target environment")
set(Rust_CARGO_TARGET_LINK_NATIVE_LIBS "${rust_libs}" CACHE INTERNAL
"Required native libraries when linking Rust static libraries")
# Set the input variables as non-cache variables so that the variables are available after
# `find_package`, even if the values were evaluated to defaults.
foreach(_VAR ${_Rust_USER_VARS})
set(${_VAR} "${${_VAR}_CACHED}")
# Ensure cached variables have type INTERNAL
set(${_VAR}_CACHED "${${_VAR}_CACHED}" CACHE INTERNAL "Internal cache of ${_VAR}")
endforeach()
find_package_handle_standard_args(
Rust
REQUIRED_VARS Rust_COMPILER Rust_VERSION Rust_CARGO Rust_CARGO_VERSION Rust_CARGO_TARGET Rust_CARGO_HOST_TARGET
VERSION_VAR Rust_VERSION
)
if(NOT TARGET Rust::Rustc)
add_executable(Rust::Rustc IMPORTED GLOBAL)
set_property(
TARGET Rust::Rustc
PROPERTY IMPORTED_LOCATION "${Rust_COMPILER_CACHED}"
)
add_executable(Rust::Cargo IMPORTED GLOBAL)
set_property(
TARGET Rust::Cargo
PROPERTY IMPORTED_LOCATION "${Rust_CARGO_CACHED}"
)
set(Rust_FOUND true)
endif()

View File

@@ -1,184 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "camino"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2"
dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
dependencies = [
"serde",
]
[[package]]
name = "cargo_metadata"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a1ec454bc3eead8719cb56e15dbbfecdbc14e4b3a3ae4936cc6e31f5fc0d07"
dependencies = [
"camino",
"cargo-platform",
"semver",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"bitflags",
"textwrap",
"unicode-width",
]
[[package]]
name = "corrosion-generator"
version = "0.1.0"
dependencies = [
"cargo_metadata",
"clap",
"serde",
"thiserror",
]
[[package]]
name = "itoa"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "proc-macro2"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "semver"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
dependencies = [
"serde",
]
[[package]]
name = "serde"
version = "1.0.156"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.156"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"

View File

@@ -1,23 +0,0 @@
[package]
name = "corrosion-generator"
version = "0.1.0"
authors = ["Andrew Gaspar <andrew.gaspar@outlook.com>"]
license = "MIT"
edition = "2018"
[dependencies]
cargo_metadata = "0.15"
# The crates below are indirect dependencies of cargo metadata,
# We explicitly specify maximum versions to allow building the generator
# with older toolchains.
# Version 1.0.157 upgrades to syn 2.0 and raises MSRV to 1.56
serde = { version = ">=1, <1.0.157", default-features=false }
# Version 1.0.40 upgrades to syn 2.0 and raises MSRV to 1.56
thiserror = { version = ">=1, <1.0.40", default-features=false }
[dependencies.clap]
version = "2.34"
default-features = false
# Make sure this crate still compiles while it is checked out
# in a sub-directory of a repository that has a Cargo.toml.
[workspace]

View File

@@ -1,95 +0,0 @@
use std::path::PathBuf;
use cargo_metadata::Metadata;
use clap::{App, Arg};
mod subcommands {
pub mod gen_cmake;
}
use subcommands::*;
// common options
const MANIFEST_PATH: &str = "manifest-path";
const CARGO_EXECUTABLE: &str = "cargo-executable";
const VERBOSE: &str = "verbose";
const LOCKED: &str = "locked";
const FROZEN: &str = "frozen";
pub struct GeneratorSharedArgs {
pub manifest_path: PathBuf,
pub cargo_executable: PathBuf,
pub metadata: Metadata,
pub verbose: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let matches = App::new("CMake Generator for Cargo")
.version("0.1")
.author("Andrew Gaspar <andrew.gaspar@outlook.com>")
.about("Generates CMake files for Cargo projects")
.arg(
Arg::with_name(MANIFEST_PATH)
.long("manifest-path")
.value_name("Cargo.toml")
.help("Specifies the target Cargo project")
.required(true)
.takes_value(true),
)
.arg(
Arg::with_name(CARGO_EXECUTABLE)
.long("cargo")
.value_name("EXECUTABLE")
.required(true)
.help("Path to the cargo executable to use"),
)
.arg(
Arg::with_name(VERBOSE)
.long("verbose")
.help("Request verbose output"),
)
.arg(
Arg::with_name(LOCKED)
.long("locked")
.help("Pass --locked to cargo invocations"),
)
.arg(
Arg::with_name(FROZEN)
.long("frozen")
.help("Pass --frozen to cargo invocations"),
)
.subcommand(gen_cmake::subcommand())
.get_matches();
let mut cmd = cargo_metadata::MetadataCommand::new();
cmd.no_deps();
if matches.is_present(LOCKED) {
cmd.other_options(["--locked".into()]);
}
if matches.is_present(FROZEN) {
cmd.other_options(["--frozen".into()]);
}
let manifest_path = matches.value_of(MANIFEST_PATH).unwrap();
let cargo_executable = matches.value_of(CARGO_EXECUTABLE).unwrap();
cmd.manifest_path(manifest_path);
cmd.cargo_path(cargo_executable);
let metadata = cmd.exec()?;
let shared_args = GeneratorSharedArgs {
manifest_path: manifest_path.into(),
cargo_executable: cargo_executable.into(),
metadata,
verbose: matches.is_present(VERBOSE),
};
match matches.subcommand() {
(gen_cmake::GEN_CMAKE, Some(matches)) => gen_cmake::invoke(&shared_args, matches)?,
_ => unreachable!(),
};
// We should never reach this statement
std::process::exit(1);
}

View File

@@ -1,160 +0,0 @@
use std::{
fs::{create_dir_all, File},
io::{stdout, Write},
path::Path,
rc::Rc,
};
use clap::{App, Arg, ArgMatches, SubCommand};
mod target;
// Command name
pub const GEN_CMAKE: &str = "gen-cmake";
// Options
const OUT_FILE: &str = "out-file";
const CONFIGURATION_ROOT: &str = "configuration-root";
const CRATES: &str = "crates";
const IMPORTED_CRATES: &str = "imported-crates";
const CRATE_TYPE: &str = "crate-type";
const PASSTHROUGH_ADD_CARGO_BUILD: &str = "passthrough-acb";
pub fn subcommand() -> App<'static, 'static> {
SubCommand::with_name(GEN_CMAKE)
.arg(
Arg::with_name(CONFIGURATION_ROOT)
.long("configuration-root")
.value_name("DIRECTORY")
.takes_value(true)
.help(
"Specifies a root directory for configuration folders. E.g. Win32 \
in VS Generator.",
),
)
.arg(
Arg::with_name(CRATES)
.long("crates")
.value_name("crates")
.takes_value(true)
.multiple(true)
.require_delimiter(true)
.help("Specifies which crates of the workspace to import"),
)
.arg(
Arg::with_name(CRATE_TYPE)
.long(CRATE_TYPE)
.value_name("kind")
.possible_values(&["staticlib", "cdylib", "bin"])
.multiple(true)
.value_delimiter(";")
.help("Only import the specified crate types")
)
.arg(
Arg::with_name(OUT_FILE)
.short("o")
.long("out-file")
.value_name("FILE")
.help("Output CMake file name. Defaults to stdout."),
)
.arg(
Arg::with_name(IMPORTED_CRATES)
.long(IMPORTED_CRATES)
.value_name("variable_name")
.takes_value(true)
.help("Save a list of the imported target names into c CMake variable with the given name"),
)
.arg(
Arg::with_name(PASSTHROUGH_ADD_CARGO_BUILD)
.long(PASSTHROUGH_ADD_CARGO_BUILD)
.takes_value(true)
.multiple(true)
.value_delimiter(std::char::from_u32(0x1f).unwrap().to_string().as_str())
.help("Passthrough arguments to the _add_cargo_build invocation(s) in CMake")
)
}
pub fn invoke(
args: &crate::GeneratorSharedArgs,
matches: &ArgMatches,
) -> Result<(), Box<dyn std::error::Error>> {
let mut out_file: Box<dyn Write> = if let Some(path) = matches.value_of(OUT_FILE) {
let path = Path::new(path);
if let Some(parent) = path.parent() {
create_dir_all(parent).expect("Failed to create directory!");
}
let file = File::create(path).expect("Unable to open out-file!");
Box::new(file)
} else {
Box::new(stdout())
};
writeln!(
out_file,
"\
cmake_minimum_required(VERSION 3.15)
"
)?;
let crates = matches
.values_of(CRATES)
.map_or(Vec::new(), |c| c.collect());
let crate_kinds: Option<Vec<&str>> = matches.values_of(CRATE_TYPE).map(|c| c.collect());
let workspace_manifest_path = Rc::new(args.manifest_path.clone());
let targets: Vec<_> = args
.metadata
.packages
.iter()
.filter(|p| {
args.metadata.workspace_members.contains(&p.id)
&& (crates.is_empty() || crates.contains(&p.name.as_str()))
})
.cloned()
.map(Rc::new)
.flat_map(|package| {
package
.targets
.iter()
.filter_map(|t| {
target::CargoTarget::from_metadata(
package.clone(),
t.clone(),
workspace_manifest_path.clone(),
&crate_kinds,
)
})
.collect::<Vec<_>>()
})
.collect();
let passthrough_args: Vec<String> = matches
.values_of(PASSTHROUGH_ADD_CARGO_BUILD)
.map(|values| {
// Add quotes around each argument for CMake to preserve which arguments belong together.
values
.filter(|val| !val.is_empty())
.map(|val| format!("\"{}\"", val))
.collect()
})
.unwrap_or_default();
let passthrough_str = passthrough_args.join(" ");
for target in &targets {
target
.emit_cmake_target(&mut out_file, &passthrough_str)
.unwrap();
}
if let Some(imported_crate_list_name) = matches.value_of(IMPORTED_CRATES) {
let imported_targets: Vec<_> = targets.iter().map(|target| target.target_name()).collect();
let imported_targets_list = imported_targets.join(";");
writeln!(
out_file,
"set({} \"{}\")",
imported_crate_list_name, imported_targets_list
)?;
}
writeln!(out_file)?;
std::process::exit(0);
}

View File

@@ -1,216 +0,0 @@
use std::error::Error;
use std::path::PathBuf;
use std::rc::Rc;
#[derive(Clone)]
pub enum CargoTargetType {
Executable,
Library {
has_staticlib: bool,
has_cdylib: bool,
},
}
#[derive(Clone)]
pub struct CargoTarget {
cargo_package: Rc<cargo_metadata::Package>,
cargo_target: cargo_metadata::Target,
target_type: CargoTargetType,
workspace_manifest_path: Rc<PathBuf>,
}
impl CargoTargetType {
fn to_string(&self) -> String {
let mut s = String::new();
match self {
Self::Executable => {
s.push_str("bin");
}
Self::Library {
has_staticlib,
has_cdylib,
} => {
if *has_staticlib {
s.push_str("staticlib")
}
if *has_cdylib {
s.push_str(" cdylib")
}
}
}
s
}
}
impl CargoTarget {
pub fn from_metadata(
cargo_package: Rc<cargo_metadata::Package>,
cargo_target: cargo_metadata::Target,
workspace_manifest_path: Rc<PathBuf>,
// If Some, only import crates if the kind variant is given in crate_kinds.
crate_kinds: &Option<Vec<&str>>,
) -> Option<Self> {
let filtered_kinds: Vec<String> = cargo_target
.kind
.clone()
.into_iter()
.filter(|kind| match crate_kinds {
None => true,
Some(allowed_kinds_subset) => allowed_kinds_subset.contains(&&**kind),
})
.collect();
let target_type = if filtered_kinds
.iter()
.any(|k| k.as_str() == "staticlib" || k.as_str() == "cdylib")
{
CargoTargetType::Library {
has_staticlib: filtered_kinds.iter().any(|k| k == "staticlib"),
has_cdylib: filtered_kinds.iter().any(|k| k == "cdylib"),
}
} else if filtered_kinds.iter().any(|k| k == "bin") {
CargoTargetType::Executable
} else {
return None;
};
Some(Self {
cargo_package,
cargo_target,
target_type,
workspace_manifest_path,
})
}
pub(crate) fn target_name(&self) -> &str {
&self.cargo_target.name
}
pub fn emit_cmake_target(
&self,
out_file: &mut dyn std::io::Write,
passthrough_add_cargo_build: &str,
) -> Result<(), Box<dyn Error>> {
writeln!(
out_file,
"set(byproducts \"\")
set(cargo_build_out_dir \"\")
set(archive_byproducts \"\")
set(shared_lib_byproduct \"\")
set(pdb_byproduct \"\")
set(bin_byproduct \"\")
"
)?;
let ws_manifest = self
.workspace_manifest_path
.to_str()
.expect("Non-utf8 path encountered")
.replace("\\", "/");
match self.target_type {
CargoTargetType::Library {
has_staticlib,
has_cdylib,
} => {
assert!(has_staticlib || has_cdylib);
let ws_manifest = self
.workspace_manifest_path
.to_str()
.expect("Non-utf8 path encountered")
.replace("\\", "/");
let mut lib_kinds = if has_staticlib { "staticlib" } else { "" }.to_string();
if has_cdylib {
if has_staticlib {
lib_kinds.push(' ');
}
lib_kinds.push_str("cdylib")
}
writeln!(
out_file,
"
_corrosion_add_library_target(
WORKSPACE_MANIFEST_PATH \"{workspace_manifest_path}\"
TARGET_NAME \"{target_name}\"
LIB_KINDS {lib_kinds}
OUT_ARCHIVE_OUTPUT_BYPRODUCTS archive_byproducts
OUT_SHARED_LIB_BYPRODUCTS shared_lib_byproduct
OUT_PDB_BYPRODUCT pdb_byproduct
)
list(APPEND byproducts
\"${{archive_byproducts}}\"
\"${{shared_lib_byproduct}}\"
\"${{pdb_byproduct}}\"
)
",
workspace_manifest_path = ws_manifest,
target_name = self.cargo_target.name,
lib_kinds = lib_kinds,
)?;
}
CargoTargetType::Executable => {
writeln!(
out_file,
"
_corrosion_add_bin_target(\"{workspace_manifest_path}\" \"{target_name}\"
bin_byproduct pdb_byproduct
)
set(byproducts \"\")
list(APPEND byproducts \"${{bin_byproduct}}\" \"${{pdb_byproduct}}\")
",
workspace_manifest_path = ws_manifest,
target_name = self.cargo_target.name,
)?;
}
};
let target_kinds = self.target_type.to_string();
writeln!(out_file,
"
set(cargo_build_out_dir \"\")
_add_cargo_build(
cargo_build_out_dir
PACKAGE \"{package_name}\"
TARGET \"{target_name}\"
MANIFEST_PATH \"{package_manifest_path}\"
WORKSPACE_MANIFEST_PATH \"{workspace_manifest_path}\"
TARGET_KINDS {target_kinds}
BYPRODUCTS \"${{byproducts}}\"
{passthrough_add_cargo_build}
)
set_target_properties({target_name} PROPERTIES
INTERFACE_COR_PACKAGE_MANIFEST_PATH \"{package_manifest_path}\"
)
if(archive_byproducts)
_corrosion_copy_byproducts(
{target_name} ARCHIVE_OUTPUT_DIRECTORY \"${{cargo_build_out_dir}}\" \"${{archive_byproducts}}\"
)
endif()
if(shared_lib_byproduct)
_corrosion_copy_byproducts(
{target_name} LIBRARY_OUTPUT_DIRECTORY \"${{cargo_build_out_dir}}\" \"${{shared_lib_byproduct}}\"
)
endif()
if(pdb_byproduct)
_corrosion_copy_byproducts(
{target_name} PDB_OUTPUT_DIRECTORY \"${{cargo_build_out_dir}}\" \"${{pdb_byproduct}}\"
)
endif()
if(bin_byproduct)
_corrosion_copy_byproducts(
{target_name} RUNTIME_OUTPUT_DIRECTORY \"${{cargo_build_out_dir}}\" \"${{bin_byproduct}}\"
)
endif()
",
package_name = self.cargo_package.name,
target_name = self.cargo_target.name,
package_manifest_path = self.cargo_package.manifest_path.as_str().replace("\\", "/"),
workspace_manifest_path = ws_manifest,
target_kinds = target_kinds,
passthrough_add_cargo_build = passthrough_add_cargo_build,
)?;
Ok(())
}
}

View File

@@ -804,15 +804,18 @@ std::string GetSysDirectory()
return sysDir;
}
// This returns the folder where certain configuration files are stored (i.e,
// `user.json`, etc).
//
// On Linux platforms, the user.json file lives in the XDG_CONFIG_HOME/SlippiOnline
// directory in order to deal with the fact that we want the configuration for AppImage
// builds to be mutable.
std::string GetSlippiUserJSONPath()
std::string GetSlippiUserConfigFolder()
{
#if defined(__APPLE__)
std::string userFilePath = File::GetApplicationSupportDirectory() + "/Slippi/user.json";
std::string userFilePath = File::GetApplicationSupportDirectory() + "/Slippi";
#else
std::string userFilePath = File::GetUserPath(F_USERJSON_IDX);
std::string userFilePath = File::GetUserPath(D_SLIPPI_IDX);
#endif
return userFilePath;
}

View File

@@ -152,8 +152,8 @@ void SetUserPath(unsigned int dir_index, const std::string &path);
// probably doesn't belong here
std::string GetThemeDir(const std::string &theme_name);
// Gets the path where a Slippi user.json file lives.
std::string GetSlippiUserJSONPath();
// Gets the path where Slippi config files (e.g, user.json) live.
std::string GetSlippiUserConfigFolder();
// Returns the path to where the sys file are
std::string GetSysDirectory();

View File

@@ -33,9 +33,9 @@
// if releasing both builds, use `release: {combined_version}` or `release: {netplay_version} | {playback_version}`
// for releasing a single build, use `release(netplay): {netplay_version}` or `release(playback): {playback_version}`
#ifndef IS_PLAYBACK
#define SLIPPI_REV_STR "3.4.4" // netplay version
#define SLIPPI_REV_STR "3.5.1" // netplay version
#else
#define SLIPPI_REV_STR "3.4.5" // playback version
#define SLIPPI_REV_STR "3.5.1" // playback version
#endif
#ifdef IS_PLAYBACK
const std::string scm_rev_str = "Faster Melee - Slippi (" SLIPPI_REV_STR ") - Playback" DEBUGFAST_INDICATOR;

View File

@@ -295,6 +295,8 @@ void SConfig::SaveCoreSettings(IniFile &ini)
core->Set("SlippiReplayDir", m_strSlippiReplayDir);
core->Set("SlippiReplayRegenerateDir", m_strSlippiRegenerateReplayDir);
core->Set("SlippiPlaybackDisplayFrameIndex", m_slippiEnableFrameIndex);
core->Set("SlippiPlayerRankDisplay", bSlippiPlayerRankDisplay);
core->Set("SlippiOpponentRankDisplay", bSlippiOpponentRankDisplay);
core->Set("BlockingPipes", m_blockingPipes);
core->Set("MemcardAPath", m_strMemoryCardA);
core->Set("MemcardBPath", m_strMemoryCardB);
@@ -646,6 +648,8 @@ void SConfig::LoadCoreSettings(IniFile &ini)
if (m_strSlippiRegenerateReplayDir.empty())
m_strSlippiRegenerateReplayDir = default_regenerate_dir;
core->Get("SlippiPlaybackDisplayFrameIndex", &m_slippiEnableFrameIndex, false);
core->Get("SlippiPlayerRankDisplay", &bSlippiPlayerRankDisplay, true);
core->Get("SlippiOpponentRankDisplay", &bSlippiOpponentRankDisplay, true);
core->Get("BlockingPipes", &m_blockingPipes, false);
core->Get("MemcardAPath", &m_strMemoryCardA);
core->Get("MemcardBPath", &m_strMemoryCardB);

View File

@@ -150,6 +150,8 @@ struct SConfig : NonCopyable
bool bAdapterWarning = true;
bool bReduceTimingDispersion = false;
bool bSlippiPlayerRankDisplay = true;
bool bSlippiOpponentRankDisplay = true;
bool bSlippiJukeboxEnabled = true;
int iSlippiJukeboxVolume = 100;

View File

@@ -153,12 +153,12 @@ CEXISlippi::CEXISlippi()
// https://github.com/dolphin-emu/dolphin/blob/7f450f1d7e7d37bd2300f3a2134cb443d07251f9/Source/Core/Core/Movie.cpp#L246-L249
std::string isoPath = SConfig::GetInstance().m_strFilename;
// @TODO: Eventually we should move `GetSlippiUserJSONPath` out of the File module.
std::string userJSONPath = File::GetSlippiUserJSONPath();
// @TODO: Eventually we should move `GetSlippiUserConfigFolder` out of the File module.
std::string userConfigFolder = File::GetSlippiUserConfigFolder();
SlippiRustEXIConfig slprs_exi_config;
slprs_exi_config.iso_path = isoPath.c_str();
slprs_exi_config.user_json_path = userJSONPath.c_str();
slprs_exi_config.user_config_folder = userConfigFolder.c_str();
slprs_exi_config.scm_slippi_semver_str = scm_slippi_semver_str.c_str();
slprs_exi_config.osd_add_msg_fn = OSDMessageHandler;
@@ -167,11 +167,11 @@ CEXISlippi::CEXISlippi()
m_slippiserver = SlippiSpectateServer::getInstance();
user = std::make_unique<SlippiUser>(slprs_exi_device_ptr);
g_playbackStatus = std::make_unique<SlippiPlaybackStatus>();
matchmaking = std::make_unique<SlippiMatchmaking>(user.get());
matchmaking = std::make_unique<SlippiMatchmaking>(slprs_exi_device_ptr, user.get());
gameFileLoader = std::make_unique<SlippiGameFileLoader>();
g_replayComm = std::make_unique<SlippiReplayComm>();
directCodes = std::make_unique<SlippiDirectCodes>("direct-codes.json");
teamsCodes = std::make_unique<SlippiDirectCodes>("teams-codes.json");
directCodes = std::make_unique<SlippiDirectCodes>(slprs_exi_device_ptr, SlippiDirectCodes::DIRECT);
teamsCodes = std::make_unique<SlippiDirectCodes>(slprs_exi_device_ptr, SlippiDirectCodes::TEAMS);
generator = std::default_random_engine(Common::Timer::GetTimeMs());
@@ -316,7 +316,7 @@ CEXISlippi::~CEXISlippi()
{
ERROR_LOG(SLIPPI_ONLINE, "Exit during in-progress ranked game: %s", activeMatchId.c_str());
slprs_exi_device_report_match_abandonment(slprs_exi_device_ptr, activeMatchId.c_str());
slprs_exi_device_report_match_status(slprs_exi_device_ptr, activeMatchId.c_str(), "abandoned", false);
}
handleConnectionCleanup();
@@ -2053,6 +2053,7 @@ void CEXISlippi::prepareOnlineMatchState()
u8 remotePlayersReady = 0;
auto userInfo = user->GetUserInfo();
u16 alt_stage_mode = 0;
if (mmState == SlippiMatchmaking::ProcessState::CONNECTION_SUCCESS)
{
@@ -2147,6 +2148,8 @@ void CEXISlippi::prepareOnlineMatchState()
std::string oppName = "";
std::string p1Name = "";
std::string p2Name = "";
s8 p1Rank = 0;
s8 p2Rank = 0;
u8 chatMessageId = 0;
u8 chatMessagePlayerIdx = 0;
u8 sentChatMessageId = 0;
@@ -2159,6 +2162,8 @@ void CEXISlippi::prepareOnlineMatchState()
// in CSS p1 is always current player and p2 is opponent
localPlayerName = p1Name = userInfo.displayName;
oppName = p2Name = "Player 2";
p1Rank = 8;
p2Rank = 15;
#endif
SlippiDesyncRecoveryResp desync_recovery;
@@ -2304,6 +2309,7 @@ void CEXISlippi::prepareOnlineMatchState()
// Stage selected by this player, use that selection
stageId = selections->stageId;
alt_stage_mode = selections->alt_stage_mode;
break;
}
@@ -2438,6 +2444,12 @@ void CEXISlippi::prepareOnlineMatchState()
*gameBitField3 = pauseAllowed ? *gameBitField3 & 0xF7 : *gameBitField3 | 0x8;
//*gameBitField3 = *gameBitField3 | 0x8;
// Overwrite alt_stage_mode if in ranked
if (!pauseAllowed)
{
alt_stage_mode = 0;
}
// Group players into left/right side for team splash screen display
for (int i = 0; i < 4; i++)
{
@@ -2480,6 +2492,25 @@ void CEXISlippi::prepareOnlineMatchState()
m_read_queue.push_back((u8)chatMessageId);
m_read_queue.push_back((u8)chatMessagePlayerIdx);
bool isRanked = lastSearch.mode == SlippiMatchmaking::OnlinePlayMode::RANKED;
if (isRanked)
{
// This has to be outside the player ready block because in game setup 2 the players are not
// ready at the start
bool showLocaLRank = SConfig::GetInstance().bSlippiPlayerRankDisplay;
bool showOppRank = SConfig::GetInstance().bSlippiOpponentRankDisplay;
std::array<s8, 2> ranks = {0, 0};
ranks[localPlayerIndex] = showLocaLRank ? matchmaking->GetPlayerRank(localPlayerIndex) : -1;
ranks[remotePlayerIndex] = showOppRank ? matchmaking->GetPlayerRank(remotePlayerIndex) : -1;
p1Rank = ranks[0];
p2Rank = ranks[1];
}
m_read_queue.push_back(p1Rank);
m_read_queue.push_back(p2Rank);
// Add player groupings for VS splash screen
leftTeamPlayers.resize(4, 0);
rightTeamPlayers.resize(4, 0);
@@ -2579,6 +2610,9 @@ void CEXISlippi::prepareOnlineMatchState()
std::string matchId = recentMmResult.id;
matchId.resize(51);
m_read_queue.insert(m_read_queue.end(), matchId.begin(), matchId.end());
// Add alt stage mode to output
m_read_queue.push_back(static_cast<u8>(alt_stage_mode));
}
u16 CEXISlippi::getRandomStage()
@@ -2613,6 +2647,7 @@ void CEXISlippi::setMatchSelections(u8 *payload)
s.stageId = Common::swap16(&payload[4]);
u8 stageSelectOption = payload[6];
// u8 onlineMode = payload[7];
s.alt_stage_mode = payload[8];
s.isStageSelected = stageSelectOption == 1 || stageSelectOption == 3;
if (stageSelectOption == 3)
@@ -2620,8 +2655,8 @@ void CEXISlippi::setMatchSelections(u8 *payload)
// If stage requested is random, select a random stage
s.stageId = getRandomStage();
}
INFO_LOG(SLIPPI, "LPS set char: %d, iSS: %d, %d, stage: %d, team: %d", s.isCharacterSelected, stageSelectOption,
s.isStageSelected, s.stageId, s.teamId);
INFO_LOG(SLIPPI, "LPS set char: %d, iSS: %d, %d, stage: %d, alt stage: %d, team: %d",
s.isCharacterSelected, stageSelectOption, s.isStageSelected, s.stageId, s.alt_stage_mode, s.teamId);
s.rngOffset = generator() % 0xFFFF;
@@ -2906,7 +2941,7 @@ void CEXISlippi::handleConnectionCleanup()
cleanup.detach();
// Reset matchmaking
matchmaking = std::make_unique<SlippiMatchmaking>(user.get());
matchmaking = std::make_unique<SlippiMatchmaking>(slprs_exi_device_ptr, user.get());
// Disconnect netplay client
slippi_netplay = nullptr;
@@ -3115,10 +3150,36 @@ void CEXISlippi::handleCompleteSet(const SlippiExiTypes::ReportSetCompletionQuer
auto userInfo = user->GetUserInfo();
slprs_exi_device_report_match_completion(slprs_exi_device_ptr, lastMatchId.c_str(), query.endMode);
auto status = query.endMode == 0 ? "normal_completion" : "abnormal_completion";
slprs_exi_device_report_match_status(slprs_exi_device_ptr, lastMatchId.c_str(), status, true);
}
}
void CEXISlippi::handleMatchStatusUpdate(const SlippiExiTypes::ReportMatchStatusUpdateQuery& query)
{
auto lastMatchId = recentMmResult.id;
if (lastMatchId.find("mode.ranked") == std::string::npos)
{
return; // Only report match status updates for ranked matches
}
auto statusMapRes = statusIdxMap.find(query.statusIdx);
if (statusMapRes == statusIdxMap.end())
{
ERROR_LOG(SLIPPI_ONLINE, "Invalid status index: %d", query.statusIdx);
return; // Invalid status index
}
auto statusString = statusMapRes->second;
INFO_LOG(SLIPPI_ONLINE, "Reporting match status update: %s, Status: %s", lastMatchId.c_str(), statusString.c_str());
// Report asynchronously when called from the game
slprs_exi_device_report_match_status(
slprs_exi_device_ptr, lastMatchId.c_str(), statusString.c_str(), true
);
}
void CEXISlippi::handleGetPlayerSettings()
{
m_read_queue.clear();
@@ -3161,6 +3222,30 @@ void CEXISlippi::handleGetPlayerSettings()
m_read_queue.insert(m_read_queue.end(), data_ptr, data_ptr + sizeof(SlippiExiTypes::GetPlayerSettingsResponse));
}
void CEXISlippi::handleGetRank()
{
RustRankInfo rank_info = slprs_get_rank_info(slprs_exi_device_ptr);
m_read_queue.clear();
// Determine rank info visibility
u8 local_rank_enabled = static_cast<u8>(SConfig::GetInstance().bSlippiPlayerRankDisplay);
u8 opp_rank_enabled = static_cast<u8>(SConfig::GetInstance().bSlippiOpponentRankDisplay);
u8 rank_visibility = local_rank_enabled | (opp_rank_enabled << 1);
// Push rank data header
m_read_queue.push_back(rank_visibility);
m_read_queue.push_back(static_cast<u8>(rank_info.fetch_status));
// ERROR_LOG_FMT(SLIPPI_ONLINE, "Update count: {}", rank_info.rating_update_count);
// Push rank data
m_read_queue.push_back(static_cast<u8>(rank_info.rank));
appendWordToBuffer(&m_read_queue, *(u32 *)(&rank_info.rating_ordinal));
appendWordToBuffer(&m_read_queue, static_cast<u32>(rank_info.rating_update_count));
appendWordToBuffer(&m_read_queue, *(u32 *)(&rank_info.rating_change));
m_read_queue.push_back(static_cast<u8>(rank_info.rank_change));
}
void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
{
u8 *memPtr = Memory::GetPointer(_uAddr);
@@ -3196,6 +3281,7 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
{
m_slippiserver->write(&memPtr[0], _uSize);
g_needInputForFrame = true;
return;
}
INFO_LOG(EXPANSIONINTERFACE, "EXI SLIPPI DMAWrite: addr: 0x%08x size: %d, bufLoc:[%02x %02x %02x %02x %02x]",
@@ -3330,6 +3416,9 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
case CMD_REPORT_SET_COMPLETE:
handleCompleteSet(SlippiExiTypes::Convert<SlippiExiTypes::ReportSetCompletionQuery>(&memPtr[bufLoc]));
break;
case CMD_REPORT_MATCH_STATUS_UPDATE:
handleMatchStatusUpdate(SlippiExiTypes::Convert<SlippiExiTypes::ReportMatchStatusUpdateQuery>(&memPtr[bufLoc]));
break;
case CMD_GET_PLAYER_SETTINGS:
handleGetPlayerSettings();
break;
@@ -3348,6 +3437,16 @@ void CEXISlippi::DMAWrite(u32 _uAddr, u32 _uSize)
slprs_jukebox_set_melee_music_volume(slprs_exi_device_ptr, args.volume);
break;
}
case CMD_GET_RANK:
{
handleGetRank();
break;
}
case CMD_FETCH_RANK:
{
slprs_fetch_match_result(slprs_exi_device_ptr, recentMmResult.id.c_str());
break;
}
default:
writeToFileAsync(&memPtr[bufLoc], payloadLen + 1, "");
m_slippiserver->write(&memPtr[bufLoc], payloadLen + 1);

View File

@@ -92,6 +92,7 @@ class CEXISlippi : public IEXIDevice
CMD_GP_FETCH_STEP = 0xC1,
CMD_REPORT_SET_COMPLETE = 0xC2,
CMD_GET_PLAYER_SETTINGS = 0xC3,
CMD_REPORT_MATCH_STATUS_UPDATE = 0xC4,
// Misc
CMD_LOG_MESSAGE = 0xD0,
@@ -105,6 +106,9 @@ class CEXISlippi : public IEXIDevice
CMD_CHANGE_MUSIC_VOLUME = 0xD8,
CMD_PREMADE_TEXT_LENGTH = 0xE1,
CMD_PREMADE_TEXT_LOAD = 0xE2,
CMD_GET_RANK = 0xE3,
CMD_FETCH_RANK = 0xE4,
CMD_GET_RANK_VISIBILITY = 0xE5
};
enum
@@ -115,6 +119,29 @@ class CEXISlippi : public IEXIDevice
FRAME_RESP_FASTFORWARD = 3,
};
// This is a mapping of u8s to status updates such that we dont have to send
// strings from the game
std::unordered_map<u8, std::string> statusIdxMap = {
{1, "connecting"},
{10, "game_setup_1"},
{11, "game_setup_2"},
{12, "game_setup_3"},
{13, "game_setup_4"}, // These are just here if we ever have longer than bo3s
{14, "game_setup_5"},
{15, "game_setup_6"},
{16, "game_setup_7"}, // Surely we never have more than bo7s
{20, "game_start_1"},
{21, "game_start_2"},
{22, "game_start_3"},
{23, "game_start_4"},
{24, "game_start_5"},
{25, "game_start_6"},
{26, "game_start_7"},
{30, "normal_completion"},
{31, "abnormal_completion"},
{40, "abandoned"},
};
std::unordered_map<u8, u32> payloadSizes = {
// The actual size of this command will be sent in one byte
// after the command is received. The other receive command IDs
@@ -136,7 +163,7 @@ class CEXISlippi : public IEXIDevice
{CMD_LOAD_SAVESTATE, 32},
{CMD_GET_MATCH_STATE, 0},
{CMD_FIND_OPPONENT, 19},
{CMD_SET_MATCH_SELECTIONS, 8},
{CMD_SET_MATCH_SELECTIONS, 9},
{CMD_SEND_CHAT_MESSAGE, 2},
{CMD_OPEN_LOGIN, 0},
{CMD_LOGOUT, 0},
@@ -151,6 +178,7 @@ class CEXISlippi : public IEXIDevice
{CMD_GP_FETCH_STEP, static_cast<u32>(sizeof(SlippiExiTypes::GpFetchStepQuery) - 1)},
{CMD_REPORT_SET_COMPLETE, static_cast<u32>(sizeof(SlippiExiTypes::ReportSetCompletionQuery) - 1)},
{CMD_GET_PLAYER_SETTINGS, 0},
{CMD_REPORT_MATCH_STATUS_UPDATE, static_cast<u32>(sizeof(SlippiExiTypes::ReportMatchStatusUpdateQuery) - 1)},
// Misc
{CMD_LOG_MESSAGE, 0xFFFF}, // Variable size... will only work if by itself
@@ -164,6 +192,9 @@ class CEXISlippi : public IEXIDevice
{CMD_CHANGE_MUSIC_VOLUME, static_cast<u32>(sizeof(SlippiExiTypes::ChangeMusicVolumeQuery) - 1)},
{CMD_PREMADE_TEXT_LENGTH, 0x2},
{CMD_PREMADE_TEXT_LOAD, 0x2},
{CMD_GET_RANK, 0x0},
{CMD_FETCH_RANK, 0x0},
{CMD_GET_RANK_VISIBILITY, 0x0},
};
struct WriteMessage
@@ -230,7 +261,9 @@ class CEXISlippi : public IEXIDevice
void handleGamePrepStepComplete(const SlippiExiTypes::GpCompleteStepQuery &query);
void prepareGamePrepOppStep(const SlippiExiTypes::GpFetchStepQuery &query);
void handleCompleteSet(const SlippiExiTypes::ReportSetCompletionQuery &query);
void handleMatchStatusUpdate(const SlippiExiTypes::ReportMatchStatusUpdateQuery &query);
void handleGetPlayerSettings();
void handleGetRank();
// replay playback stuff
void prepareGameInfo(u8 *payload);

View File

@@ -1,230 +1,41 @@
#include "SlippiRustExtensions.h"
#include "SlippiDirectCodes.h"
#ifdef _WIN32
#include "AtlBase.h"
#include "AtlConv.h"
#endif
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "Common/Thread.h"
#include "Core/ConfigManager.h"
#include <codecvt>
#include <locale>
#include <time.h>
#include <json.hpp>
using json = nlohmann::json;
SlippiDirectCodes::SlippiDirectCodes(std::string fileName)
{
m_fileName = fileName;
// Prevent additional file reads, if we've already loaded data to memory.
// if (directCodeInfos.empty())
ReadFile();
Sort();
DirectCodeKind mapCode(uint8_t code_kind) {
return code_kind == SlippiDirectCodes::DIRECT ?
DirectCodeKind::DirectCodes :
DirectCodeKind::TeamsCodes;
}
SlippiDirectCodes::~SlippiDirectCodes()
SlippiDirectCodes::SlippiDirectCodes(uintptr_t rs_exi_device_ptr, uint8_t code_kind)
{
// Add additional cleanup behavior here? Just added something
// So compiler wouldn't nag.
return;
slprs_exi_device_ptr = rs_exi_device_ptr;
kind = code_kind;
}
void SlippiDirectCodes::ReadFile()
{
std::string directCodesFilePath = getCodesFilePath();
INFO_LOG(SLIPPI_ONLINE, "Looking for direct codes file at %s", directCodesFilePath.c_str());
if (!File::Exists(directCodesFilePath))
{
// Attempt to create empty file with array as parent json item.
if (File::CreateFullPath(directCodesFilePath) && File::CreateEmptyFile(directCodesFilePath))
{
File::WriteStringToFile("[\n]", directCodesFilePath);
}
else
{
WARN_LOG(SLIPPI_ONLINE, "Was unable to create %s", directCodesFilePath.c_str());
}
}
std::string directCodesFileContents;
File::ReadFileToString(directCodesFilePath, directCodesFileContents);
directCodeInfos = parseFile(directCodesFileContents);
}
SlippiDirectCodes::~SlippiDirectCodes() {}
void SlippiDirectCodes::AddOrUpdateCode(std::string code)
{
WARN_LOG(SLIPPI_ONLINE, "Attempting to add or update direct code: %s", code.c_str());
time_t curTime;
time(&curTime);
u8 dateTimeStrLength = sizeof "20171015T095717";
std::vector<char> dateTimeBuf(dateTimeStrLength);
strftime(&dateTimeBuf[0], dateTimeStrLength, "%Y%m%dT%H%M%S", localtime(&curTime));
std::string timestamp(&dateTimeBuf[0]);
bool found = false;
for (auto it = directCodeInfos.begin(); it != directCodeInfos.end(); ++it)
{
if (it->connectCode == code)
{
found = true;
it->lastPlayed = timestamp;
}
}
if (!found)
{
CodeInfo newDirectCode = {code, timestamp, false};
directCodeInfos.push_back(newDirectCode);
}
// TODO: Maybe remove from here?
// Or start a thread that is periodically called, if file writes will happen enough.
WriteFile();
}
void SlippiDirectCodes::Sort(u8 sortByProperty)
{
switch (sortByProperty)
{
case SORT_BY_TIME:
std::sort(directCodeInfos.begin(), directCodeInfos.end(),
[](const CodeInfo a, const CodeInfo b) -> bool { return a.lastPlayed > b.lastPlayed; });
break;
case SORT_BY_NAME:
std::sort(directCodeInfos.begin(), directCodeInfos.end(),
[](const CodeInfo a, const CodeInfo b) -> bool { return a.connectCode < b.connectCode; });
break;
}
}
std::string SlippiDirectCodes::Autocomplete(std::string startText)
{
// Pre-sort direct codes.
Sort();
// Find first entry in our sorted vector that starts with the given text.
for (auto it = directCodeInfos.begin(); it != directCodeInfos.end(); it++)
{
if (it->connectCode.rfind(startText, 0) == 0)
{
return it->connectCode;
}
}
return startText;
slprs_user_direct_codes_add_or_update(slprs_exi_device_ptr, mapCode(kind), code.c_str());
}
std::string SlippiDirectCodes::get(int index)
{
Sort();
char *code = slprs_user_direct_codes_get_code_at_index(slprs_exi_device_ptr, mapCode(kind), index);
// To be safe, just do an extra copy into a full C++ string type - i.e, the ownership
// that we're passing out from behind this method is clear.
std::string connectCode = std::string(code);
if (index < directCodeInfos.size() && index >= 0)
{
return directCodeInfos.at(index).connectCode;
}
// Since the C string was allocated on the Rust side, we need to free it using that allocator.
slprs_user_direct_codes_free_code(code);
INFO_LOG(SLIPPI_ONLINE, "Out of bounds name entry index %d", index);
return (index >= directCodeInfos.size()) ? "1" : "";
return connectCode;
}
int SlippiDirectCodes::length()
{
return (int)directCodeInfos.size();
}
void SlippiDirectCodes::WriteFile()
{
std::string directCodesFilePath = getCodesFilePath();
// Outer empty array.
json fileData = json::array();
// Inner contents.
json directCodeData = json::object();
// TODO Define constants for string literals.
for (auto it = directCodeInfos.begin(); it != directCodeInfos.end(); ++it)
{
directCodeData["connectCode"] = it->connectCode;
directCodeData["lastPlayed"] = it->lastPlayed;
directCodeData["isFavorite"] = it->isFavorite;
fileData.emplace_back(directCodeData);
}
File::WriteStringToFile(fileData.dump(), directCodesFilePath);
}
std::string SlippiDirectCodes::getCodesFilePath()
{
std::string fileName = m_fileName + ".json";
std::string directCodesPath = File::GetUserPath(D_SLIPPI_IDX) + m_fileName;
return directCodesPath;
}
inline std::string readString(json obj, std::string key)
{
auto item = obj.find(key);
if (item == obj.end() || item.value().is_null())
{
return "";
}
return obj[key];
}
inline bool readBool(json obj, std::string key)
{
auto item = obj.find(key);
if (item == obj.end() || item.value().is_null())
{
return false;
}
return obj[key];
}
std::vector<SlippiDirectCodes::CodeInfo> SlippiDirectCodes::parseFile(std::string fileContents)
{
std::vector<SlippiDirectCodes::CodeInfo> directCodes;
json res = json::parse(fileContents, nullptr, false);
// Unlike the user.json, the encapsulating type should be an array.
if (res.is_discarded() || !res.is_array())
{
WARN_LOG(SLIPPI_ONLINE, "Malformed json in direct codes file.");
return directCodes;
}
// Retrieve all saved direct codes and related info
for (auto it = res.begin(); it != res.end(); ++it)
{
if (it.value().is_object())
{
CodeInfo curDirectCode;
curDirectCode.connectCode = readString(*it, "connectCode");
curDirectCode.lastPlayed = readString(*it, "lastPlayed");
curDirectCode.isFavorite = readBool(*it, "favorite");
directCodes.push_back(curDirectCode);
}
}
return directCodes;
return slprs_user_direct_codes_get_length(slprs_exi_device_ptr, mapCode(kind));
}

View File

@@ -1,39 +1,34 @@
#pragma once
#include "Common/CommonTypes.h"
#include <atomic>
#include <string>
#include <thread>
#include <vector>
// This class is currently a shim for the Rust codes interface. We're doing it this way
// to migrate things over without needing to do larger invasive changes.
//
// The remaining methods on here are simply layers that direct the call over to the Rust
// side. A quirk of this is that we're using the EXI device pointer, so this class absolutely
// cannot outlive the EXI device - but we control that and just need to do our due diligence
// when making changes.
class SlippiDirectCodes
{
public:
static const uint8_t SORT_BY_TIME = 1;
static const uint8_t SORT_BY_FAVORITE = 2;
static const uint8_t SORT_BY_NAME = 3;
// We can't currently expose `SlippiRustExtensions.h` in header files, so
// we export these two types for code clarity and map them in the implementation.
static const uint8_t DIRECT = 0;
static const uint8_t TEAMS = 1;
struct CodeInfo
{
std::string connectCode = "";
std::string lastPlayed = "";
bool isFavorite = false;
};
SlippiDirectCodes(std::string fileName);
SlippiDirectCodes(uintptr_t rs_exi_device_ptr, uint8_t kind);
~SlippiDirectCodes();
void ReadFile();
void AddOrUpdateCode(std::string code);
std::string get(int index);
int length();
void Sort(u8 sortByProperty = SlippiDirectCodes::SORT_BY_TIME);
std::string Autocomplete(std::string startText);
void AddOrUpdateCode(std::string code);
protected:
void WriteFile();
std::string getCodesFilePath();
std::vector<CodeInfo> parseFile(std::string fileContents);
std::vector<CodeInfo> directCodeInfos;
std::string m_fileName;
};
// A pointer to a "shadow" EXI Device that lives on the Rust side of things.
// Do *not* do any cleanup of this! The EXI device will handle it.
uintptr_t slprs_exi_device_ptr;
// An internal marker for what kind of codes we're reading/reporting.
uint8_t kind;
};

View File

@@ -43,6 +43,12 @@ struct ReportSetCompletionQuery
u8 endMode;
};
struct ReportMatchStatusUpdateQuery
{
u8 command;
u8 statusIdx;
};
struct GpCompleteStepQuery
{
u8 command;

View File

@@ -32,6 +32,18 @@ u32 SlippiGameFileLoader::LoadFile(std::string fileName, std::string &data)
return (u32)data.size();
}
if (grpsx_strings.count(fileName))
{
std::vector<u8> buf;
FileMon::ReadFileWithName(fileName, buf);
std::string contents(buf.begin(), buf.end());
fileCache[fileName] = contents;
data = fileCache[fileName];
INFO_LOG(SLIPPI, "Preloaded Transformation: %s -> %d", fileName.c_str(), (u32)data.size());
return (u32)data.size();
}
INFO_LOG(SLIPPI, "Loading file: %s", fileName.c_str());
std::string gameFilePath = getFilePath(fileName);

View File

@@ -5,12 +5,16 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <set>
class SlippiGameFileLoader
{
public:
u32 LoadFile(std::string fileName, std::string &contents);
// static stadium transformation files
std::set<std::string> grpsx_strings = {"GrPs1.dat", "GrPs2.dat", "GrPs3.dat", "GrPs4.dat"};
protected:
std::unordered_map<std::string, std::string> fileCache;
open_vcdiff::VCDiffDecoder decoder;

View File

@@ -6,6 +6,8 @@
#include <string>
#include <vector>
#include "SlippiRustExtensions.h"
#if defined __linux__ && HAVE_ALSA
#elif defined __APPLE__
#include <arpa/inet.h>
@@ -25,12 +27,14 @@ std::string MmMessageType::CREATE_TICKET = "create-ticket";
std::string MmMessageType::CREATE_TICKET_RESP = "create-ticket-resp";
std::string MmMessageType::GET_TICKET_RESP = "get-ticket-resp";
SlippiMatchmaking::SlippiMatchmaking(SlippiUser *user)
SlippiMatchmaking::SlippiMatchmaking(uintptr_t rs_exi_device_ptr, SlippiUser *user)
{
m_user = user;
m_state = ProcessState::IDLE;
m_errorMsg = "";
slprs_exi_device_ptr = rs_exi_device_ptr;
m_client = nullptr;
m_server = nullptr;
@@ -527,6 +531,15 @@ void SlippiMatchmaking::handleMatchmaking()
playerInfo.chatMessages = m_user->GetDefaultChatMessages();
}
json rankEl = el["rank"];
if (rankEl.is_object())
{
playerInfo.rankedRating = rankEl.value("rating", 0.0f);
playerInfo.rankedUpdateCount = rankEl.value("updateCount", 0);
playerInfo.rankedGlobalPlacement = rankEl.value("globalPlacement", 0);
playerInfo.rankedRegionalPlacement = rankEl.value("regionalPlacement", 0);
}
m_playerInfo.push_back(playerInfo);
if (isLocal)
@@ -605,6 +618,12 @@ void SlippiMatchmaking::handleMatchmaking()
// Disconnect and destroy enet client to mm server
terminateMmConnection();
// If ranked, report to backend that we are attempting to connect to this match
if (matchId.find("mode.ranked") != std::string::npos)
{
slprs_exi_device_report_match_status(slprs_exi_device_ptr, matchId.c_str(), "connecting", true);
}
m_state = ProcessState::OPPONENT_CONNECTING;
ERROR_LOG(SLIPPI_ONLINE, "[Matchmaking] Opponent found. isDecider: %s", m_isHost ? "true" : "false");
}
@@ -624,6 +643,125 @@ std::vector<u16> SlippiMatchmaking::GetStages()
return m_allowedStages;
}
// This is kind of duplicate code from what exists in rust. Maybe eventually it should be remove
// and exist only on the rust side
SlippiMatchmaking::SlippiRank SlippiMatchmaking::GetPlayerRank(u8 port)
{
if (port >= m_playerInfo.size())
{
return SlippiRank::Unranked;
}
auto info = m_playerInfo[port];
float rating = info.rankedRating;
int updateCount = info.rankedUpdateCount;
int global = info.rankedGlobalPlacement;
int regional = info.rankedRegionalPlacement;
if (updateCount < 5)
{
return SlippiRank::Unranked;
}
if (rating <= 765.42f)
{
return SlippiRank::Bronze1;
}
if (rating > 765.43f && rating <= 913.71f)
{
return SlippiRank::Bronze2;
}
if (rating > 913.72f && rating <= 1054.86f)
{
return SlippiRank::Bronze3;
}
if (rating > 1054.87f && rating <= 1188.87f)
{
return SlippiRank::Silver1;
}
if (rating > 1188.88f && rating <= 1315.74f)
{
return SlippiRank::Silver2;
}
if (rating > 1315.75f && rating <= 1435.47f)
{
return SlippiRank::Silver3;
}
if (rating > 1435.48f && rating <= 1548.06f)
{
return SlippiRank::Gold1;
}
if (rating > 1548.07f && rating <= 1653.51f)
{
return SlippiRank::Gold2;
}
if (rating > 1653.52f && rating <= 1751.82f)
{
return SlippiRank::Gold3;
}
if (rating > 1751.83f && rating <= 1842.99f)
{
return SlippiRank::Platinum1;
}
if (rating > 1843.0f && rating <= 1927.02f)
{
return SlippiRank::Platinum2;
}
if (rating > 1927.03f && rating <= 2003.91f)
{
return SlippiRank::Platinum3;
}
if (rating > 2003.92f && rating <= 2073.66f)
{
return SlippiRank::Diamond1;
}
if (rating > 2073.67f && rating <= 2136.27f)
{
return SlippiRank::Diamond2;
}
if (rating > 2136.28f && rating <= 2191.74f)
{
return SlippiRank::Diamond3;
}
if (rating >= 2191.75f && (global > 0 || regional > 0))
{
return SlippiRank::Grandmaster;
}
if (rating > 2191.75f && rating <= 2274.99f)
{
return SlippiRank::Master1;
}
if (rating > 2275.0f && rating <= 2350.0f)
{
return SlippiRank::Master2;
}
if (rating > 2350.0f)
{
return SlippiRank::Master3;
}
return SlippiRank::Unranked;
}
SlippiMatchmaking::MatchmakeResult SlippiMatchmaking::GetMatchmakeResult()
{
return m_mmResult;

View File

@@ -19,7 +19,7 @@ using json = nlohmann::json;
class SlippiMatchmaking
{
public:
SlippiMatchmaking(SlippiUser *user);
SlippiMatchmaking(uintptr_t rs_exi_device_ptr, SlippiUser *user);
~SlippiMatchmaking();
enum OnlinePlayMode
@@ -40,6 +40,30 @@ class SlippiMatchmaking
ERROR_ENCOUNTERED,
};
enum SlippiRank
{
Unranked,
Bronze1,
Bronze2,
Bronze3,
Silver1,
Silver2,
Silver3,
Gold1,
Gold2,
Gold3,
Platinum1,
Platinum2,
Platinum3,
Diamond1,
Diamond2,
Diamond3,
Master1,
Master2,
Master3,
Grandmaster
};
struct MatchSearchSettings
{
OnlinePlayMode mode = OnlinePlayMode::RANKED;
@@ -62,6 +86,7 @@ class SlippiMatchmaking
int LocalPlayerIndex();
std::vector<SlippiUser::UserInfo> GetPlayerInfo();
std::string GetPlayerName(u8 port);
SlippiRank GetPlayerRank(u8 port);
std::vector<u16> GetStages();
u8 RemotePlayerCount();
MatchmakeResult GetMatchmakeResult();
@@ -104,6 +129,10 @@ class SlippiMatchmaking
std::unique_ptr<SlippiNetplayClient> m_netplayClient;
// A pointer to a "shadow" EXI Device that lives on the Rust side of things.
// Do *not* do any cleanup of this! The EXI device will handle it.
uintptr_t slprs_exi_device_ptr;
const std::unordered_map<ProcessState, bool> searchingStates = {
{ProcessState::INITIALIZING, true},
{ProcessState::MATCHMAKING, true},

View File

@@ -534,6 +534,7 @@ void SlippiNetplayClient::writeToPacket(sf::Packet &packet, SlippiPlayerSelectio
packet << s.stageId << s.isStageSelected;
packet << s.rngOffset;
packet << s.teamId;
packet << s.alt_stage_mode;
}
void SlippiNetplayClient::WriteChatMessageToPacket(sf::Packet &packet, int messageId, u8 playerIdx)
@@ -639,6 +640,11 @@ std::unique_ptr<SlippiPlayerSelections> SlippiNetplayClient::readSelectionsFromP
ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection");
s->error = true;
}
if (!(packet >> s->alt_stage_mode))
{
ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection");
s->error = true;
}
return std::move(s);
}

View File

@@ -83,6 +83,7 @@ class SlippiPlayerSelections
u16 stageId = 0;
bool isStageSelected = false;
u8 alt_stage_mode{};
u32 rngOffset = 0;
@@ -97,6 +98,7 @@ class SlippiPlayerSelections
{
this->stageId = s.stageId;
this->isStageSelected = true;
this->alt_stage_mode = s.alt_stage_mode;
}
if (s.isCharacterSelected)

View File

@@ -93,6 +93,9 @@ void SlippiSavestate::initBackupLocs()
{0x804d77bc, 0x4}, // ???
{0x804de7f0, 0x10}, // ???
// XFB / VI Memory
{0x804c0980, 0x15F8},
// Camera Blocks, Temporarily added here
//{0x80452c7c, 0x2B0}, // Cam Block 1, including gaps
//{0x806e516c, 0xA8}, // Cam Block 2, including gaps

View File

@@ -33,6 +33,11 @@ class SlippiUser
std::vector<std::string> chatMessages;
bool isBot = false;
float rankedRating = 0;
int rankedUpdateCount = 0;
int rankedGlobalPlacement = 0;
int rankedRegionalPlacement = 0;
};
SlippiUser(uintptr_t rs_exi_device_ptr);

View File

@@ -101,6 +101,10 @@ void SlippiNetplayConfigPane::InitializeGUI()
_("Make inputs feel more console-like for overclocked GCC to USB "
"adapters at the cost of 1.6ms of input lag (2ms for single-port official adapter)."));
m_slippi_show_player_rank =
new wxCheckBox(this, wxID_ANY, _("Show your rank (Character Select and Ranked Setup Screen)"));
m_slippi_show_opponent_rank = new wxCheckBox(this, wxID_ANY, _("Show opponent's rank (Ranked Setup Screen)"));
m_slippi_jukebox_enabled_checkbox = new wxCheckBox(this, wxID_ANY, _("Enable Music"));
// WASAPI does not work with this and we want a note for the user.
@@ -180,6 +184,17 @@ void SlippiNetplayConfigPane::InitializeGUI()
main_sizer->Add(sbSlippiInputSettings, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
main_sizer->AddSpacer(space5);
wxStaticBoxSizer *const sbRankSettings =
new wxStaticBoxSizer(wxVERTICAL, this, _("Rank Settings"));
sbRankSettings->AddSpacer(space5);
sbRankSettings->Add(m_slippi_show_player_rank, 0, wxLEFT | wxRIGHT, space5);
sbRankSettings->AddSpacer(space5);
sbRankSettings->Add(m_slippi_show_opponent_rank, 0, wxLEFT | wxRIGHT, space5);
sbRankSettings->AddSpacer(space5);
main_sizer->Add(sbRankSettings, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
main_sizer->AddSpacer(space5);
wxStaticBoxSizer *const sbSlippiJukeboxSettings =
new wxStaticBoxSizer(wxVERTICAL, this, _("Slippi Jukebox Settings (Beta)"));
sbSlippiJukeboxSettings->AddSpacer(space5);
@@ -233,6 +248,9 @@ void SlippiNetplayConfigPane::LoadGUIValues()
m_reduce_timing_dispersion_checkbox->SetValue(startup_params.bReduceTimingDispersion);
m_slippi_show_player_rank->SetValue(startup_params.bSlippiPlayerRankDisplay);
m_slippi_show_opponent_rank->SetValue(startup_params.bSlippiOpponentRankDisplay);
m_slippi_jukebox_enabled_checkbox->SetValue(enableJukebox);
m_slippi_jukebox_volume_slider->SetValue(startup_params.iSlippiJukeboxVolume);
m_jukebox_volume_text->SetLabel(wxString::Format("%d %%", startup_params.iSlippiJukeboxVolume));
@@ -267,6 +285,9 @@ void SlippiNetplayConfigPane::BindEvents()
m_reduce_timing_dispersion_checkbox->Bind(wxEVT_CHECKBOX, &SlippiNetplayConfigPane::OnReduceTimingDispersionToggle,
this);
m_slippi_show_player_rank->Bind(wxEVT_CHECKBOX, &SlippiNetplayConfigPane::OnToggleShowPlayerRank, this);
m_slippi_show_opponent_rank->Bind(wxEVT_CHECKBOX, &SlippiNetplayConfigPane::OnToggleShowOpponentRank, this);
m_slippi_jukebox_enabled_checkbox->Bind(wxEVT_CHECKBOX, &SlippiNetplayConfigPane::OnToggleJukeboxEnabled, this);
m_slippi_jukebox_volume_slider->Bind(wxEVT_SLIDER, &SlippiNetplayConfigPane::OnJukeboxVolumeUpdate, this);
}
@@ -353,6 +374,16 @@ void SlippiNetplayConfigPane::OnReduceTimingDispersionToggle(wxCommandEvent &eve
SConfig::GetInstance().bReduceTimingDispersion = m_reduce_timing_dispersion_checkbox->GetValue();
}
void SlippiNetplayConfigPane::OnToggleShowPlayerRank(wxCommandEvent &event)
{
SConfig::GetInstance().bSlippiPlayerRankDisplay = m_slippi_show_player_rank->GetValue();
}
void SlippiNetplayConfigPane::OnToggleShowOpponentRank(wxCommandEvent &event)
{
SConfig::GetInstance().bSlippiOpponentRankDisplay = m_slippi_show_opponent_rank->GetValue();
}
void SlippiNetplayConfigPane::OnToggleJukeboxEnabled(wxCommandEvent &event)
{
bool isEnabled = m_slippi_jukebox_enabled_checkbox->GetValue();

View File

@@ -42,6 +42,10 @@ class SlippiNetplayConfigPane final : public wxPanel
void OnQuickChatChanged(wxCommandEvent &event);
void OnReduceTimingDispersionToggle(wxCommandEvent &event);
void PopulateEnableChatChoiceBox();
void OnToggleJukeboxEnabled(wxCommandEvent &event);
void OnJukeboxVolumeUpdate(wxCommandEvent &event);
void OnToggleShowPlayerRank(wxCommandEvent &event);
void OnToggleShowOpponentRank(wxCommandEvent &event);
wxArrayString m_slippi_enable_quick_chat_strings;
@@ -59,11 +63,12 @@ class SlippiNetplayConfigPane final : public wxPanel
wxCheckBox *m_reduce_timing_dispersion_checkbox;
void OnToggleJukeboxEnabled(wxCommandEvent &event);
wxCheckBox *m_slippi_show_player_rank;
wxCheckBox *m_slippi_show_opponent_rank;
wxCheckBox *m_slippi_jukebox_enabled_checkbox;
DolphinSlider *m_slippi_jukebox_volume_slider;
wxStaticText *m_jukebox_volume_text;
void OnJukeboxVolumeUpdate(wxCommandEvent &event);
};
class SlippiPlaybackConfigPane final : public wxPanel

View File

@@ -6,9 +6,10 @@
// TODO: ugly
#ifdef _WIN32
#include "VideoBackends/DX9/VideoBackend.h"
#include "VideoBackends/DX11/VideoBackend.h"
#include "VideoBackends/D3D12/VideoBackend.h"
#include "VideoBackends/DX11/VideoBackend.h"
#include "VideoBackends/DX9/VideoBackend.h"
#endif
#include "VideoBackends/OGL/VideoBackend.h"
#include "VideoBackends/Software/VideoBackend.h"
@@ -19,14 +20,15 @@
#endif
std::vector<std::unique_ptr<VideoBackendBase>> g_available_video_backends;
VideoBackendBase* g_video_backend = nullptr;
static VideoBackendBase* s_default_backend = nullptr;
VideoBackendBase *g_video_backend = nullptr;
static VideoBackendBase *s_default_backend = nullptr;
#ifdef _WIN32
#include <windows.h>
#include <VersionHelpers.h>
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
#include <windows.h>
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
#endif
// A runtime method for determining whether to allow
@@ -38,31 +40,31 @@ static VideoBackendBase* s_default_backend = nullptr;
static bool PlatformSupportsVulkan()
{
#if defined(VK_USE_PLATFORM_METAL_EXT)
// We want to only allow Vulkan to be loaded on macOS 14 (Mojave) or higher.
// Bail out if we're on macOS and can't detect it, or the version is lower.
//
// This code is borrowed liberally from mainline Dolphin.
id processInfo = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(
objc_getClass("NSProcessInfo"), sel_getUid("processInfo"));
if (!processInfo)
return false;
// We want to only allow Vulkan to be loaded on macOS 14 (Mojave) or higher.
// Bail out if we're on macOS and can't detect it, or the version is lower.
//
// This code is borrowed liberally from mainline Dolphin.
id processInfo =
reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(objc_getClass("NSProcessInfo"), sel_getUid("processInfo"));
if (!processInfo)
return false;
struct OSVersion // NSOperatingSystemVersion
{
size_t major_version; // NSInteger majorVersion
size_t minor_version; // NSInteger minorVersion
size_t patch_version; // NSInteger patchVersion
};
struct OSVersion // NSOperatingSystemVersion
{
size_t major_version; // NSInteger majorVersion
size_t minor_version; // NSInteger minorVersion
size_t patch_version; // NSInteger patchVersion
};
// const bool meets_requirement = [processInfo isOperatingSystemAtLeastVersion:required_version];
constexpr OSVersion required_version = {10, 14, 0};
const bool meets_requirement = reinterpret_cast<bool (*)(id, SEL, OSVersion)>(objc_msgSend)(
processInfo, sel_getUid("isOperatingSystemAtLeastVersion:"), required_version);
return meets_requirement;
// const bool meets_requirement = [processInfo isOperatingSystemAtLeastVersion:required_version];
constexpr OSVersion required_version = {10, 14, 0};
const bool meets_requirement = reinterpret_cast<bool (*)(id, SEL, OSVersion)>(objc_msgSend)(
processInfo, sel_getUid("isOperatingSystemAtLeastVersion:"), required_version);
return meets_requirement;
#endif
// Vulkan support defaults to true (supported).
return true;
// Vulkan support defaults to true (supported).
return true;
}
void VideoBackendBase::PopulateList()
@@ -85,32 +87,25 @@ void VideoBackendBase::PopulateList()
// disable OGL video Backend while is merged from master
g_available_video_backends.push_back(std::make_unique<OGL::VideoBackend>());
// on macOS, we want to push users to use Vulkan on 10.14+ (Mojave onwards). OpenGL has been
// long deprecated by Apple there and is a known stumbling block for performance for new players.
// we want to push macOS users to Vulkan since OpenGL has been long deprecated
// by Apple and is a known stumbling block for performance for new players.
//
// That said, we still support High Sierra, which can't use Metal (it will load, but lacks certain critical pieces).
//
// This mirrors a recent (2021) change in mainline Dolphin, so should be relatively safe to do here as well. All
// we're doing is shoving Vulkan to the front if it's macOS 10.14 or later, so it loads first.
if(PlatformSupportsVulkan()) {
#ifdef __APPLE__
if (__builtin_available(macOS 10.14, *)) {
g_available_video_backends.emplace(
g_available_video_backends.begin(),
std::make_unique<Vulkan::VideoBackend>()
);
}
else
// That said, we have seen issues with Vulkan on Playback builds and defaulting to
// OpenGL should be fine in our supported versions since it translates to Metal under the hood.
if (PlatformSupportsVulkan())
{
#if defined(__APPLE__) && !defined(IS_PLAYBACK)
g_available_video_backends.emplace(g_available_video_backends.begin(),
std::make_unique<Vulkan::VideoBackend>());
#else
g_available_video_backends.push_back(std::make_unique<Vulkan::VideoBackend>());
#endif
{
g_available_video_backends.push_back(std::make_unique<Vulkan::VideoBackend>());
}
}
}
// Disable software video backend as is currently not working
//g_available_video_backends.push_back(std::make_unique<SW::VideoSoftware>());
// g_available_video_backends.push_back(std::make_unique<SW::VideoSoftware>());
for (auto& backend : g_available_video_backends)
for (auto &backend : g_available_video_backends)
{
if (backend)
{
@@ -125,12 +120,12 @@ void VideoBackendBase::ClearList()
g_available_video_backends.clear();
}
void VideoBackendBase::ActivateBackend(const std::string& name)
void VideoBackendBase::ActivateBackend(const std::string &name)
{
if (name.empty()) // If nullptr, set it to the default backend (expected behavior)
g_video_backend = s_default_backend;
for (auto& backend : g_available_video_backends)
for (auto &backend : g_available_video_backends)
if (name == backend->GetName())
g_video_backend = backend.get();
}

View File

@@ -89,6 +89,9 @@ fi
# remomve libs that will cause conflicts
rm ./AppDir/usr/lib/libgmodule*
# Remove librsvg2, which causes a crash on fedora 41+ systems
rm ./AppDir/usr/lib/librsvg-2.so.2
# Bake appimage
UPDATE_INFORMATION="${UPDATE_INFORMATION}" OUTPUT="${OUTPUT}" ./Tools/linuxdeploy-update-plugin --appdir=./AppDir/

View File

@@ -21,7 +21,7 @@ fi
mkdir -p build
pushd build
cmake ${CMAKE_FLAGS} ..
make -j7
make -j$(sysctl -n hw.ncpu)
popd
# Copy the Sys folder in