Compare commits
679 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0178b20983 | |||
| f9142a1c56 | |||
| b19209c45c | |||
| 73b5b9d7b7 | |||
| 0a9d646bd7 | |||
| 24edfe2190 | |||
| 0bb8127372 | |||
| 1b8a69154f | |||
| f2155b49e2 | |||
| 62c9b99e72 | |||
| 2a344e1d87 | |||
| ae14aa991d | |||
| 2885c8a4ab | |||
| 3d411431c6 | |||
| 1800faf0dd | |||
| 19ded3809f | |||
| 40cd255051 | |||
| ad4677a67c | |||
| d9e0d016c6 | |||
| c570fd03d1 | |||
| 1e0565f17b | |||
| 3ff464641a | |||
| 7cb3d305d4 | |||
| e46dba43ad | |||
| afad96a52a | |||
| 1a00341e6b | |||
| 3388c8ed09 | |||
| 6d4967ffef | |||
| b27366e1e6 | |||
| 95a29b5d1d | |||
| d320867569 | |||
| aabd388070 | |||
| 7db6594358 | |||
| 388ca1c645 | |||
| 7c04b00e2b | |||
| dac0644f07 | |||
| 7d103fe0f0 | |||
| 901d9f3f6e | |||
| ddc9e74aa8 | |||
| 12690de9de | |||
| 6b30cdac09 | |||
| ccb7528a59 | |||
| 01ed8a07af | |||
| a9f399d6cc | |||
| a527a485f8 | |||
| f0c8f6d47b | |||
| a29dc3893f | |||
| c6f392bf6c | |||
| f2ded2fdb7 | |||
| 080737fd1f | |||
| 1040757556 | |||
| 38d612e5ba | |||
| c20aa2ad5f | |||
| a7c3753c5a | |||
| ebf72eb126 | |||
| be49a80bc7 | |||
| 23da770364 | |||
| 6186ac0245 | |||
| 364c33060b | |||
| 3922f76ab5 | |||
| bb2c9196f5 | |||
| 1c8d3e0dca | |||
| 6b556a5206 | |||
| bbd308a908 | |||
| b5b8f7c35a | |||
| de592267fe | |||
| 5bb89328d0 | |||
| 75fbb3d551 | |||
| eb0fb2fef7 | |||
| b1b92e95ab | |||
| 3a68b7ac0d | |||
| 3976018980 | |||
| 1dac708323 | |||
| d4187242b9 | |||
| 61c0d81667 | |||
| c3e4b6da46 | |||
| 38c7cf474d | |||
| ec4cbe5380 | |||
| 465ca97531 | |||
| 2f7a2d5134 | |||
| c1b5af21f0 | |||
| cfb788941c | |||
| 69435dd951 | |||
| 3b09a39576 | |||
| 53f81ce9c7 | |||
| e064380a7d | |||
| 9375e255e1 | |||
| a56fc57a83 | |||
| 4f75dc06b9 | |||
| d3b7a5146c | |||
| bc487f43f7 | |||
| 088ac71930 | |||
| 27cad422b9 | |||
| 5a63271f0e | |||
| 9a35684507 | |||
| 0d2714a1d9 | |||
| 553e4b28bf | |||
| b579e45ed7 | |||
| 1662bcfae4 | |||
| 8652b7d358 | |||
| 1cf8aacc11 | |||
| 13ef4c1236 | |||
| 68dd25a4a5 | |||
| bcb1c6c080 | |||
| 2372116acc | |||
| 508dd2b509 | |||
| 61b69eeed2 | |||
| dc8652806e | |||
| af6db7d895 | |||
| 64ec99be33 | |||
| 53e906d0f3 | |||
| 780a6a7b40 | |||
| 737fbf661a | |||
| c0243a92d0 | |||
| 3a8fcd1b0b | |||
| 04d9693b51 | |||
| 0023716053 | |||
| 37b46df738 | |||
| ba06198012 | |||
| acf9caa4ae | |||
| d69e345bc0 | |||
| c5b25fa132 | |||
| 262ecda2bf | |||
| f243539362 | |||
| ec33891f6f | |||
| f007188fa0 | |||
| 170fd813f0 | |||
| 4c59359cf7 | |||
| ddf25b7869 | |||
| 4914f3b2c3 | |||
| 08faed7d86 | |||
| 989e0f28d6 | |||
| 54f41095e9 | |||
| faaa72d398 | |||
| 97b36eb53c | |||
| 2503525016 | |||
| e96fedfefe | |||
| f279d8d6d1 | |||
| 4bfba20877 | |||
| 504bd93007 | |||
| 2f2fe72808 | |||
| 5babf47e70 | |||
| 78a588cacb | |||
| 205f8a6479 | |||
| 34c1e1a9ad | |||
| 0885884839 | |||
| c471120a80 | |||
| 3202cc7021 | |||
| fc34b3f144 | |||
| fb974a4551 | |||
| 3d99fea575 | |||
| feb04c64a8 | |||
| d3dbf9e83f | |||
| 9b6d7a5275 | |||
| 754fd03750 | |||
| adfa5d63bb | |||
| 81ff956a48 | |||
| daefe27fec | |||
| 6106ff8b31 | |||
| 1e6c180690 | |||
| d1a950d59f | |||
| 641fadc1fb | |||
| 5299061282 | |||
| d0c029c83e | |||
| 5aced2e44b | |||
| 18ab42dc83 | |||
| a748508bc9 | |||
| 8b453e6a3b | |||
| 3196ada481 | |||
| 7c4734c24d | |||
| 813f7b50c1 | |||
| 6532d2b650 | |||
| e0baad417a | |||
| f6759de1e9 | |||
| 7648171fe2 | |||
| 71c3264ea7 | |||
| 49455965c0 | |||
| 5f0467b084 | |||
| 6adcabda29 | |||
| 52b67b46fc | |||
| a700e3b39e | |||
| 4fbbdf8732 | |||
| 9a91fef337 | |||
| 53cc067c17 | |||
| d3183708e8 | |||
| 44771150b7 | |||
| ac2b2d82d2 | |||
| 11c42eb8d4 | |||
| dc0230c476 | |||
| 0a8c343e6e | |||
| afdbef1a81 | |||
| f659338e5e | |||
| 4a82d81efe | |||
| 6b4208be9b | |||
| 3d78c7f43a | |||
| 34df4509af | |||
| 6c3b2b938a | |||
| 59588b12c8 | |||
| 3eaa29e7c2 | |||
| c3c2bb7ad8 | |||
| 0e64c74a78 | |||
| d2dc57585c | |||
| e0fe7989e9 | |||
| 709305df0e | |||
| 24445123fc | |||
| 450a64b58b | |||
| b3a9c8d83f | |||
| 35c92723c7 | |||
| 719e7a9d56 | |||
| eed9e56bf4 | |||
| 1d214ed26a | |||
| 2d9d92b7d7 | |||
| 240cb2d627 | |||
| bd69466e94 | |||
| e6a7597444 | |||
| 1852b370d7 | |||
| 12fa7c41f6 | |||
| fc85ed8730 | |||
| 65f10ff840 | |||
| 6809d84a00 | |||
| 2752cd1390 | |||
| 10b56415e8 | |||
| bd87c80943 | |||
| f71e7ef1cc | |||
| 756ad17c2c | |||
| 29c1b20b41 | |||
| aa5097e0d4 | |||
| 2ccfee2e45 | |||
| bf1311b902 | |||
| 71efb3bc84 | |||
| 439bdde849 | |||
| c7fed20f3c | |||
| 3dd6e5664c | |||
| d4ee308ffd | |||
| a272f3e3b9 | |||
| f6027719d2 | |||
| 38402e78c0 | |||
| eae1ac6558 | |||
| 0b019401bd | |||
| 73cda2324a | |||
| 3dba894369 | |||
| 659ee81e80 | |||
| 99c307a68e | |||
| d28eea342a | |||
| 29078bc428 | |||
| 6bcb5ae66b | |||
| cf1e68fb0e | |||
| 43288a6760 | |||
| 9ee7d04560 | |||
| 16bf215d8a | |||
| 99ed77da8c | |||
| b9f733c401 | |||
| 18966d424c | |||
| c725b886e1 | |||
| 9b7eaf5117 | |||
| 36a55660bf | |||
| 0946e5945f | |||
| 8ec1a5627d | |||
| df718bcb0f | |||
| 8eefbcae45 | |||
| 8cf28730cb | |||
| f894e2b9a2 | |||
| e3cd31f057 | |||
| 05086cda3b | |||
| 7c2d6f8a23 | |||
| 7423abb136 | |||
| 310fa7127d | |||
| 3250c16cdc | |||
| 02f35383bd | |||
| 1d5fef4930 | |||
| dddea008e9 | |||
| dd8ec8f09e | |||
| 98dbbd84ac | |||
| 382a27cb2f | |||
| eeda958f33 | |||
| 2f9cac8d18 | |||
| 9d432187aa | |||
| b13165f95a | |||
| 110c20d25f | |||
| 4def7f143c | |||
| 908d524631 | |||
| 6c74274502 | |||
| ee8cd82e9d | |||
| 820e692e57 | |||
| 5b95cfda40 | |||
| b2c4fed39c | |||
| 96c6dc01eb | |||
| f545532556 | |||
| 8ac9968096 | |||
| a9ee9a69a4 | |||
| 46a50265a3 | |||
| 41e9e0b965 | |||
| 388d090b91 | |||
| 1a60fb3c96 | |||
| baa2768a69 | |||
| 04fb86556a | |||
| 90cf47cdce | |||
| bf96cbe980 | |||
| 66dc1cc15d | |||
| a05e3f02b8 | |||
| 8ec01450f8 | |||
| b2962e0522 | |||
| 8980fc5524 | |||
| f54da22f6f | |||
| cebc0ec4a1 | |||
| 812224f7f7 | |||
| d78e2dad29 | |||
| 7e35679ec2 | |||
| b39f457363 | |||
| 18b7955384 | |||
| 0e625e6928 | |||
| 65ae85061f | |||
| e2c1547d95 | |||
| 2d5a427bd4 | |||
| 45bd0d1f25 | |||
| f38084f0cf | |||
| 0d929a210f | |||
| 057f5beac6 | |||
| 26021e11f7 | |||
| 941ecc76a1 | |||
| 12806af6aa | |||
| 55886b0a50 | |||
| 577b5ef2bd | |||
| 780c38a5e5 | |||
| 6756bf7d4b | |||
| 9c0b2338cf | |||
| a0ef1a672c | |||
| 1fd265d316 | |||
| e3b23822fd | |||
| ab3c8268f0 | |||
| 6f306121a6 | |||
| 8399516475 | |||
| a60ea61291 | |||
| 64cff74861 | |||
| e2c1e656b9 | |||
| cdc1d0c02b | |||
| 151a0955cf | |||
| 40406bd3fe | |||
| 1cc3e6e510 | |||
| 064ab58f3c | |||
| 85c0a2e602 | |||
| 809e880bd1 | |||
| 7df093c94b | |||
| f572e29a13 | |||
| 681a6ef73c | |||
| bf37087a10 | |||
| a18b46d8ad | |||
| 74bb90b414 | |||
| 8334767c16 | |||
| 0d126afb1f | |||
| b7d80ab335 | |||
| b0e376ae76 | |||
| a3bcb6c15a | |||
| 88269636d3 | |||
| 4f5076346d | |||
| 89de913e95 | |||
| 0e73c4598e | |||
| 6b8aef9fdd | |||
| 1811dd67bf | |||
| 6d4379059c | |||
| a0f3704b41 | |||
| 9274b3f14d | |||
| 0a3e540a10 | |||
| 4657afd899 | |||
| 2082f06443 | |||
| b49f8623f6 | |||
| 69e4138223 | |||
| 5fec8666e3 | |||
| 8af4a94864 | |||
| ab873129f8 | |||
| 6155207407 | |||
| 98a58daf57 | |||
| 0aaa40cd53 | |||
| a6b44ea1bb | |||
| ca0ca2e5a8 | |||
| 14a388b3fe | |||
| 82a8d96fba | |||
| ad3ea966cb | |||
| 8d9dd1d19c | |||
| 337ee77a99 | |||
| c09991ebdb | |||
| 5188293242 | |||
| 2805fe0a06 | |||
| b4757b514d | |||
| 630edde10f | |||
| e9e139c364 | |||
| 60c01ef9a9 | |||
| 5dbadccd7f | |||
| 49a968219f | |||
| 8b934abcf2 | |||
| fa74d3e88c | |||
| 1123e25136 | |||
| 7c15001042 | |||
| bf388e5428 | |||
| 661be41c5a | |||
| 8be4ac6869 | |||
| 81f9259063 | |||
| a97424d46c | |||
| b639f3c8ec | |||
| 13ca1a7f09 | |||
| 16098c38c8 | |||
| c4b259e0f8 | |||
| e04855a0da | |||
| 8199f97e7a | |||
| 2eef3ab645 | |||
| d56ec56458 | |||
| 0293415db1 | |||
| 6e935d9d84 | |||
| 99ae561caa | |||
| 3f8421fc17 | |||
| 324b1039cf | |||
| 961d905433 | |||
| 3c79f3943f | |||
| 1e7b2c052a | |||
| ff082b98cb | |||
| 3236931416 | |||
| ed0c798252 | |||
| 5943b802d7 | |||
| b875a86e1d | |||
| 0a35a62235 | |||
| e98b07de03 | |||
| de5217745c | |||
| ec53adc2b7 | |||
| b57ab74ee7 | |||
| 69368d972d | |||
| a00f9e4211 | |||
| 3cb9cd7724 | |||
| 9632d0ab8a | |||
| 68b68e676b | |||
| c7ced46707 | |||
| ecc194cb62 | |||
| a1b4ffcf52 | |||
| ae809ad320 | |||
| 7d1c18a569 | |||
| 71f034c4ea | |||
| b156b40f8f | |||
| 8d5a9dc722 | |||
| 06dc6909c4 | |||
| c639b7d5f4 | |||
| a38e144320 | |||
| 059c45f202 | |||
| eccceea7fb | |||
| ad340c3007 | |||
| c214f45e14 | |||
| c8620070b9 | |||
| 61a371b106 | |||
| 5210df6882 | |||
| edb7991979 | |||
| 90d6069a16 | |||
| 880a4e3ca6 | |||
| 18e30c7e44 | |||
| 0113224cb6 | |||
| d1bd936765 | |||
| 2c41eecdb1 | |||
| 1a9e38a1dd | |||
| 9f3f619774 | |||
| 795e234c6f | |||
| 23fdcbfeb8 | |||
| ee3e36672c | |||
| 119b4e4529 | |||
| cc6112cbc4 | |||
| f16c9cd3c6 | |||
| 9e4c24baa3 | |||
| 801609fb78 | |||
| 4c8630d29f | |||
| 4e426af114 | |||
| 5b66fe47db | |||
| 7ae9b15b5c | |||
| 67323994fc | |||
| fcc7a7452a | |||
| 1bb0caed6f | |||
| 23a445619b | |||
| 837d9ca688 | |||
| 9b121a6414 | |||
| 5f1aafb961 | |||
| 615ff08d1a | |||
| 3320d1e1c7 | |||
| 3deb177ab7 | |||
| 41dad58489 | |||
| cb8a240f1a | |||
| 871ef2cdfe | |||
| 6c0bc43776 | |||
| a16d18d83c | |||
| e499c3c6e3 | |||
| ddd261c943 | |||
| a1f9ff0aaa | |||
| d636ea9338 | |||
| 1747e68d1d | |||
| c4c710d39d | |||
| 9a5dbda063 | |||
| bd9c876e36 | |||
| 903d847058 | |||
| 789e42e26f | |||
| 85e11ca341 | |||
| 0da81d22d3 | |||
| 52b993095d | |||
| 363e0a40e5 | |||
| 7ea0a6d642 | |||
| 035d410a89 | |||
| b0b42071f2 | |||
| 5c24009eb5 | |||
| 00340f33c3 | |||
| 01c285fc4a | |||
| 87797e117e | |||
| a5cc9a5517 | |||
| 806acf8cd0 | |||
| 04f6302ecc | |||
| 1df977fae2 | |||
| 9105c2cf4a | |||
| 6d43fcf8fb | |||
| fafae1cbb5 | |||
| 419e673d5b | |||
| 48f47de95c | |||
| 44a1df4353 | |||
| 13b3c78c7f | |||
| e362c2c078 | |||
| 814adbb8c4 | |||
| cf86b6c107 | |||
| 12a83e5a1c | |||
| 0f769eec81 | |||
| 0737c788fc | |||
| 3fe9aea5b5 | |||
| ab6ba848b8 | |||
| 0a38800e44 | |||
| 6be5618d22 | |||
| 95d9462a71 | |||
| e05cd9f47b | |||
| aa09302ca0 | |||
| 6d6b9fd269 | |||
| 6d265452cf | |||
| 65d20f2d08 | |||
| a229e30b08 | |||
| d246a37b11 | |||
| e839595053 | |||
| a711eb31f4 | |||
| b117a6d4cd | |||
| 36b1004e26 | |||
| c75c47fdd2 | |||
| 0f626c8d30 | |||
| 021783dcc1 | |||
| 1f339862db | |||
| 4446d9ce4b | |||
| 92b08a4faf | |||
| d311b4bd53 | |||
| a6dfc3be2f | |||
| 750e7b73e3 | |||
| 6a36967e6f | |||
| d6d7ade6e3 | |||
| 151d98df51 | |||
| fa744e53d3 | |||
| e0df2c584f | |||
| 3c88477270 | |||
| df46e5137c | |||
| ffe8133865 | |||
| 7140e82189 | |||
| cb743da215 | |||
| 4d24ba1f35 | |||
| 87411da95f | |||
| d25d1ecb3a | |||
| 2a00a88e2a | |||
| b01220d2c5 | |||
| 58dd2bff41 | |||
| f34773ed73 | |||
| 9b5cc7cda7 | |||
| 77db8f04b9 | |||
| 9319bc579c | |||
| 73784b9e12 | |||
| 533f960854 | |||
| 765208a181 | |||
| 4417701ea7 | |||
| f66eaf8f44 | |||
| 0dd9c386ee | |||
| af8c871411 | |||
| 50e1e6596e | |||
| d8897c585d | |||
| 7d32dc312f | |||
| eff1e4bd7e | |||
| ac50b46608 | |||
| a0e2a3db1d | |||
| 0cc981ec18 | |||
| 8170b91f76 | |||
| d1a7bb0136 | |||
| 56caa10e56 | |||
| 926496b59d | |||
| 102d30db2d | |||
| 5281a85b67 | |||
| de28c812e8 | |||
| eea73deab3 | |||
| 67c02e3522 | |||
| 19dd2a693b | |||
| 3df133652a | |||
| 80d2034083 | |||
| db9389d24c | |||
| c996be321c | |||
| 6ff6a4989a | |||
| 2655255d4d | |||
| 8485afa3a5 | |||
| 2759091ede | |||
| ae02b71a85 | |||
| 4445569bb0 | |||
| a604394b20 | |||
| dd8a337b14 | |||
| 0572d44996 | |||
| 38aa116c59 | |||
| 61666bae69 | |||
| 362a26a404 | |||
| 81fa3da101 | |||
| bd1fb86492 | |||
| 238298f695 | |||
| 194f7375da | |||
| 3581c5b078 | |||
| c5572acd38 | |||
| acc2fea7e3 | |||
| 3dc7b64fa1 | |||
| 79f2c21dfb | |||
| df36c44bc2 | |||
| c4db65cc08 | |||
| c86ddb3b7d | |||
| a1aebdc5d6 | |||
| b49a1f27eb | |||
| e7fd84e031 | |||
| 9d9e18f614 | |||
| c8199de188 | |||
| fc331da883 | |||
| b6d3fa8c66 | |||
| 3cebea1801 | |||
| 2e9ee81dcd | |||
| cf4da5c4d1 | |||
| 9d1ec0b319 | |||
| 9c5108c1ca | |||
| 2807be7080 | |||
| ec7b18dab5 | |||
| b9e20dc5c9 | |||
| cfdc852f03 | |||
| 92514e33bb | |||
| 572a2a06d1 | |||
| f076fcd539 | |||
| 4ac59875af | |||
| 780ca38f2f | |||
| 97ea5e9dba | |||
| 9e83bc6544 | |||
| 37aefe5811 | |||
| d686b48f65 | |||
| f319362e35 | |||
| 0d9b1654ec | |||
| 940e726754 | |||
| f43824762a | |||
| cd53bb7eff | |||
| 60fc90bb8e | |||
| a9437d69ab | |||
| 5d91caebe9 | |||
| eb4131e1c7 | |||
| 07f0ba213e | |||
| 48382564d1 | |||
| 274386a078 | |||
| 557d015662 | |||
| 5985f0eefa | |||
| 82258915da | |||
| 11a1f090d3 | |||
| a0d48c588a | |||
| 5e2424da58 | |||
| 72a6696f5c | |||
| 9087116ee5 | |||
| 89e0dcba5e | |||
| 7698064f5a | |||
| ab31e96385 | |||
| a9dcad629b | |||
| e49679484a | |||
| 290226539f | |||
| 75efc79930 | |||
| 905496e926 | |||
| 64579eef7e | |||
| e0a648240f | |||
| 7bad8f3348 | |||
| 11a197a387 | |||
| ee1384341e | |||
| fb01ed55e5 | |||
| 5a0a5d9ff1 | |||
| 58e3232710 |
@@ -7,11 +7,12 @@ git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }'
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/install-freebsd.sh)
|
||||
# libc++ isn't in llvm* packages, so download manually
|
||||
fetch https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-13.0.1-rc1.tar.gz
|
||||
tar xf llvm*.tar.gz
|
||||
export CC=clang13 CXX=clang++13
|
||||
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/llvm-project-15.0.6.src.tar.xz
|
||||
tar xf llvm*.tar.xz
|
||||
export CC=clang15 CXX=clang++15
|
||||
cmake -B libcxx_build -G Ninja -S llvm*/libcxx \
|
||||
-DLLVM_CCACHE_BUILD=ON \
|
||||
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=libcxx_prefix
|
||||
cmake --build libcxx_build
|
||||
cmake --install libcxx_build
|
||||
@@ -20,6 +21,7 @@ export LDFLAGS="$LDFLAGS -nostdlib++ -L$PWD/libcxx_prefix/lib -l:libc++.a -lcxxr
|
||||
|
||||
CONFIGURE_ARGS="
|
||||
-DWITH_LLVM=OFF
|
||||
-DUSE_SDL=OFF
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF
|
||||
-DUSE_SYSTEM_FFMPEG=ON
|
||||
|
||||
@@ -51,6 +51,7 @@ cmake .. \
|
||||
-DCMAKE_AR="$AR" \
|
||||
-DCMAKE_RANLIB="$RANLIB" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SDL=OFF \
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY \
|
||||
-G Ninja
|
||||
|
||||
|
||||
+42
-12
@@ -1,15 +1,43 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
brew update
|
||||
brew install llvm@13 sdl2 nasm qt@5 ninja cmake glew git p7zip create-dmg ccache
|
||||
brew install -f --overwrite llvm@14 nasm ninja git p7zip create-dmg ccache
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=11.6
|
||||
#/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
arch -x86_64 /usr/local/homebrew/bin/brew install -f --overwrite llvm@14 sdl2 glew cmake
|
||||
|
||||
#export MACOSX_DEPLOYMENT_TARGET=12.0
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
export Qt5_DIR="/usr/local/opt/qt@5/lib/cmake/Qt5"
|
||||
export PATH="/usr/local/opt/llvm@13/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin"
|
||||
export LDFLAGS="-L/usr/local/opt/llvm@13/lib -Wl,-rpath,/usr/local/opt/llvm@13/lib"
|
||||
export CPPFLAGS="-I/usr/local/opt/llvm@13/include -msse -msse2 -mcx16 -no-pie"
|
||||
|
||||
export BREW_PATH;
|
||||
BREW_PATH="$(brew --prefix)"
|
||||
export BREW_X64_PATH;
|
||||
BREW_X64_PATH="$("/usr/local/homebrew/bin/brew" --prefix)"
|
||||
export BREW_BIN="/usr/local/bin"
|
||||
export BREW_SBIN="/usr/local/sbin"
|
||||
export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=X86'
|
||||
|
||||
export WORKDIR;
|
||||
WORKDIR="$(pwd)"
|
||||
|
||||
#get Qt
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
pip3 install pipenv
|
||||
pipenv run pip3 install py7zr requests semantic_version lxml
|
||||
pipenv run ./qt-downloader macos desktop 5.15.2 clang_64 --opensource
|
||||
cd ..
|
||||
|
||||
export Qt5_DIR="$WORKDIR/qt-downloader/5.15.2/clang_64/lib/cmake/Qt5"
|
||||
export SDL2_DIR="$BREW_X64_PATH/opt/sdl2/lib/cmake/SDL2"
|
||||
|
||||
export PATH="$BREW_PATH/opt/llvm@14/bin:$WORKDIR/qt-downloader/5.15.2/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
|
||||
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib"
|
||||
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -no-pie"
|
||||
export LIBRARY_PATH="$BREW_X64_PATH/lib"
|
||||
export LD_LIBRARY_PATH="$BREW_X64_PATH/lib"
|
||||
|
||||
git submodule update --init --recursive --depth 1
|
||||
|
||||
@@ -18,16 +46,18 @@ sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVer
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
cmake .. \
|
||||
-DUSE_DISCORD_RPC=OFF -DUSE_VULKAN=ON -DUSE_ALSA=OFF -DUSE_PULSE=OFF -DUSE_AUDIOUNIT=ON \
|
||||
-DLLVM_CCACHE_BUILD=OFF -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF \
|
||||
"$BREW_X64_PATH/bin/cmake" .. \
|
||||
-DUSE_SDL=ON -DUSE_DISCORD_RPC=OFF -DUSE_VULKAN=ON -DUSE_ALSA=OFF -DUSE_PULSE=OFF -DUSE_AUDIOUNIT=ON \
|
||||
-DLLVM_CCACHE_BUILD=OFF -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_UTILS=OFF -DLLVM_USE_PERF=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_SYSTEM_MVK=OFF \
|
||||
$CMAKE_EXTRA_OPTS \
|
||||
-DLLVM_TARGET_ARCH=X86_64 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_IGNORE_PATH="$BREW_PATH/lib" \
|
||||
-G Ninja
|
||||
|
||||
ninja; build_status=$?;
|
||||
"$BREW_PATH/bin/ninja"; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
@@ -36,4 +66,4 @@ cd ..
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
.ci/deploy-mac.sh
|
||||
fi
|
||||
fi
|
||||
|
||||
+8
-4
@@ -18,10 +18,14 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
# Embed newer libstdc++ for distros that don't come with it (ubuntu 16.04)
|
||||
mkdir -p appdir/usr/optional/ ; mkdir -p appdir/usr/optional/libstdc++/
|
||||
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./appdir/usr/optional/libstdc++/
|
||||
|
||||
|
||||
# Remove libwayland-client because it has platform-dependent exports and breaks other OSes
|
||||
rm -f ./appdir/usr/lib/libwayland-client.so*
|
||||
|
||||
|
||||
# Remove libgmodule and libglib due to g_source_set_static_name symbol conflict with host libraries
|
||||
rm -f ./appdir/usr/lib/libgmodule-2.0.so*
|
||||
rm -f ./appdir/usr/lib/libglib-2.0.so*
|
||||
|
||||
# Install latest appimage runner
|
||||
rm ./appdir/AppRun
|
||||
curl -sL https://github.com/RPCS3/AppImageKit-checkrt/releases/download/continuous2/AppRun-patched-x86_64 -o ./appdir/AppRun
|
||||
@@ -39,7 +43,7 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
|
||||
# Package it up and send it off
|
||||
./squashfs-root/usr/bin/appimagetool "$APPDIR"
|
||||
|
||||
|
||||
ls
|
||||
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
|
||||
@@ -57,7 +61,7 @@ if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
FILESIZE=$(stat -c %s ./rpcs3*.AppImage)
|
||||
SHA256SUM=$(sha256sum ./rpcs3*.AppImage | awk '{ print $1 }')
|
||||
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
|
||||
|
||||
|
||||
fi
|
||||
|
||||
if [ "$DEPLOY_PPA" = "true" ]; then
|
||||
|
||||
+5
-3
@@ -14,7 +14,9 @@ echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
|
||||
|
||||
cd bin
|
||||
mkdir "rpcs3.app/Contents/lib/"
|
||||
cp "/usr/local/opt/llvm@13/lib/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
|
||||
|
||||
cp "/usr/local/Homebrew/opt/llvm@14/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
|
||||
|
||||
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQmlModels.framework" \
|
||||
@@ -33,7 +35,7 @@ echo "IconIndex=0" >> Quickstart.url
|
||||
|
||||
DMG_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos.dmg"
|
||||
|
||||
create-dmg --volname RPCS3 \
|
||||
/opt/homebrew/bin/create-dmg --volname RPCS3 \
|
||||
--window-size 800 400 \
|
||||
--icon-size 100 \
|
||||
--icon rpcs3.app 200 190 \
|
||||
@@ -45,7 +47,7 @@ create-dmg --volname RPCS3 \
|
||||
"$DMG_FILEPATH" \
|
||||
RPCS3.app
|
||||
|
||||
7z a -mx9 rpcs3-v"${COMM_TAG}"-"${COMM_COUNT}"-"${COMM_HASH}"_macos.7z RPCS3.app
|
||||
/opt/homebrew/bin/7z a -mx9 rpcs3-v"${COMM_TAG}"-"${COMM_COUNT}"-"${COMM_HASH}"_macos.7z RPCS3.app
|
||||
|
||||
FILESIZE=$(stat -f %z "$DMG_FILEPATH")
|
||||
SHA256SUM=$(shasum -a 256 "$DMG_FILEPATH" | awk '{ print $1 }')
|
||||
|
||||
@@ -9,7 +9,7 @@ export ASSUME_ALWAYS_YES=true
|
||||
pkg info # debug
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/build-freebsd.sh)
|
||||
pkg install llvm13
|
||||
pkg install llvm15
|
||||
|
||||
# Mandatory dependencies (qt5-dbus and qt5-gui are pulled via qt5-widgets)
|
||||
pkg install git ccache cmake ninja qt5-qmake qt5-buildtools qt5-widgets qt5-concurrent qt5-multimedia qt5-svg glew openal-soft ffmpeg
|
||||
|
||||
@@ -21,7 +21,7 @@ QT_MM_URL="${QT_HOST}${QT_PREFIX}qtmultimedia${QT_SUFFIX}"
|
||||
QT_SVG_URL="${QT_HOST}${QT_PREFIX}qtsvg${QT_SUFFIX}"
|
||||
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win/llvmlibs_mt.7z'
|
||||
GLSLANG_URL='https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z'
|
||||
VULKAN_SDK_URL="https://www.dropbox.com/s/o918fc11pfk8x9c/VulkanSDK-${VULKAN_VER}-Installer.exe"
|
||||
VULKAN_SDK_URL="https://www.dropbox.com/s/cs77c3iv5mbo0bt/VulkanSDK-${VULKAN_VER}-Installer.exe"
|
||||
|
||||
DEP_URLS=" \
|
||||
$QT_BASE_URL \
|
||||
|
||||
+9
-7
@@ -23,8 +23,8 @@ windows_task:
|
||||
QT_VER_MSVC: 'msvc2019'
|
||||
QT_DATE: '202011130602'
|
||||
QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64
|
||||
VULKAN_VER: '1.3.204.0'
|
||||
VULKAN_SDK_SHA: '41f4996335cc5a545d7b2f6e5ff29cf3867789aae4be053a7069aa93408861fa'
|
||||
VULKAN_VER: '1.3.224.1'
|
||||
VULKAN_SDK_SHA: '2029e652e39ee6a6036cff3765da31e1e6c595fd2413d3cd111dfab7855621ea'
|
||||
VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER}
|
||||
CACHE_DIR: "./cache"
|
||||
UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
|
||||
@@ -61,7 +61,7 @@ windows_task:
|
||||
|
||||
linux_task:
|
||||
container:
|
||||
image: rpcs3/rpcs3-ci-bionic:1.5
|
||||
image: rpcs3/rpcs3-ci-bionic:1.6
|
||||
cpu: 4
|
||||
memory: 16G
|
||||
env:
|
||||
@@ -120,15 +120,17 @@ freebsd_task:
|
||||
script: "./.ci/build-freebsd.sh"
|
||||
|
||||
macos_task:
|
||||
timeout_in: 120m
|
||||
timeout_in: 12000m
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache_dir
|
||||
matrix:
|
||||
- name: Cirrus macOS
|
||||
osx_instance:
|
||||
image: monterey-xcode-13.3
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-monterey-xcode:14
|
||||
mac_script:
|
||||
- mkdir artifacts
|
||||
- chmod +x ".ci/build-mac.sh"
|
||||
- chmod +x ".ci/deploy-mac.sh"
|
||||
- ".ci/build-mac.sh"
|
||||
env:
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
|
||||
@@ -141,7 +143,7 @@ macos_task:
|
||||
RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
|
||||
artifacts:
|
||||
name: Artifact
|
||||
path: "artifacts/rpcs3-*_macos.*"
|
||||
path: "artifacts/*"
|
||||
push_script: |
|
||||
if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
|
||||
source './.ci/export-cirrus-vars.sh'
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ Cpp11BracedListStyle: true
|
||||
IndentCaseLabels: false
|
||||
SortIncludes: false
|
||||
ReflowComments: true
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignTrailingComments: true
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
|
||||
@@ -29,8 +29,8 @@ body:
|
||||
Please provide the _exact_ build (or commit) information that introduced the regression you're reporting.
|
||||
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
|
||||
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
|
||||
|
||||
Make sure you're running with settings as close to default as possible
|
||||
|
||||
Make sure you're running with settings as close to default as possible
|
||||
* **Do NOT enable any emulator game patches when reporting issues**
|
||||
* Only change settings that are required for the game to work
|
||||
- type: input
|
||||
@@ -48,7 +48,7 @@ body:
|
||||
Obtaining the log file:
|
||||
* Run the game until you find the regression.
|
||||
* Completely close RPCS3 and locate the log file.
|
||||
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
@@ -70,21 +70,21 @@ body:
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
* Captures will be stored in RPCS3 folder → captures.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: captures
|
||||
attributes:
|
||||
label: Attach capture files for visual issues
|
||||
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System configuration
|
||||
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
|
||||
@@ -28,13 +28,13 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
# Log files
|
||||
|
||||
|
||||
Provide a log file that includes the bug you're reporting.
|
||||
|
||||
|
||||
Obtaining the log file:
|
||||
* Run the game until you find the regression.
|
||||
* Completely close RPCS3 and locate the log file.
|
||||
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
@@ -55,21 +55,21 @@ body:
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
* Captures will be stored in RPCS3 folder → captures.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: captures
|
||||
attributes:
|
||||
label: Attach capture files for visual issues
|
||||
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System configuration
|
||||
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
|
||||
@@ -29,7 +29,7 @@ body:
|
||||
* Why your feature is important to RPCS3.
|
||||
* If the feature is implemented in other projects, attach screenshots.
|
||||
* If this feature is something that a game is trying to use, upload a log file for it.
|
||||
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
|
||||
@@ -122,6 +122,9 @@ yaml-cpp.pc
|
||||
/3rdparty/libusb_cmake/config.h
|
||||
/3rdparty/libusb_cmake/libusb-1.0.pc
|
||||
|
||||
# miniupnp
|
||||
/3rdparty/miniupnp/x64/*
|
||||
|
||||
# ssl certificate
|
||||
cacert.pem
|
||||
|
||||
|
||||
@@ -76,3 +76,10 @@
|
||||
path = 3rdparty/SoundTouch/soundtouch
|
||||
url = ../../RPCS3/soundtouch.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/libsdl-org/SDL"]
|
||||
path = 3rdparty/libsdl-org/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/miniupnp/miniupnp"]
|
||||
path = 3rdparty/miniupnp/miniupnp
|
||||
url = https://github.com/miniupnp/miniupnp.git
|
||||
|
||||
Vendored
+46
-12
@@ -142,7 +142,7 @@ add_subdirectory(SoundTouch EXCLUDE_FROM_ALL)
|
||||
# libevdev
|
||||
set(LIBEVDEV_TARGET 3rdparty_dummy_lib)
|
||||
if(USE_LIBEVDEV)
|
||||
pkg_check_modules(LIBEVDEV libevdev)
|
||||
pkg_check_modules(LIBEVDEV libevdev libudev)
|
||||
if(LIBEVDEV_FOUND)
|
||||
add_library(3rdparty_libevdev INTERFACE)
|
||||
target_compile_definitions(3rdparty_libevdev INTERFACE -DHAVE_LIBEVDEV)
|
||||
@@ -165,10 +165,10 @@ if(USE_VULKAN)
|
||||
message("-- RPCS3: MoltenVK submodule")
|
||||
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
|
||||
)
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK"
|
||||
)
|
||||
|
||||
add_library(moltenvk_lib SHARED IMPORTED)
|
||||
@@ -222,21 +222,28 @@ set(FAUDIO_TARGET 3rdparty_dummy_lib)
|
||||
if(USE_FAUDIO)
|
||||
# FAudio depends on SDL2
|
||||
find_package(SDL2)
|
||||
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.12)
|
||||
message(WARNING
|
||||
"-- RPCS3: FAudio requires SDL 2.0.9 or newer. Please note, this warning"
|
||||
"can also be displayed with SDL2 versions between 2.0.9-2.0.12, as the"
|
||||
"CMake config files are not correctly installed. Since a valid SDL2"
|
||||
">=2.0.9 version cannot be found, building with FAudio will be skipped.")
|
||||
set(USE_FAUDIO False)
|
||||
else()
|
||||
if (USE_SYSTEM_FAUDIO)
|
||||
if (USE_SYSTEM_FAUDIO)
|
||||
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.0.12)
|
||||
message(WARNING
|
||||
"-- RPCS3: System FAudio requires SDL 2.0.9 or newer. Please note, this warning"
|
||||
"can also be displayed with SDL2 versions between 2.0.9-2.0.12, as the"
|
||||
"CMake config files are not correctly installed. Since a valid SDL2"
|
||||
">=2.0.9 version cannot be found, building with FAudio will be skipped.")
|
||||
set(USE_FAUDIO OFF CACHE BOOL "Disabled using system FAudio with SDL < 2.0.12" FORCE)
|
||||
else()
|
||||
message(STATUS "RPCS3: Using system FAudio")
|
||||
find_package(FAudio REQUIRED CONFIGS FAudioConfig.cmake FAudio-config.cmake)
|
||||
add_library(3rdparty_FAudio INTERFACE)
|
||||
target_link_libraries(3rdparty_FAudio INTERFACE FAudio)
|
||||
target_compile_definitions(3rdparty_FAudio INTERFACE -DHAVE_FAUDIO)
|
||||
set(FAUDIO_TARGET 3rdparty_FAudio)
|
||||
endif()
|
||||
else()
|
||||
if (NOT SDL2_FOUND OR SDL2_VERSION VERSION_LESS 2.24.0)
|
||||
message(WARNING
|
||||
"-- RPCS3: 3rdparty FAudio requires SDL 2.24.0 or newer. Since a valid SDL2"
|
||||
">=2.24.0 version cannot be found, building with FAudio will be skipped.")
|
||||
set(USE_FAUDIO OFF CACHE BOOL "Disabled FAudio with SDL < 2.24.0" FORCE)
|
||||
else()
|
||||
message(STATUS "RPCS3: Using builtin FAudio")
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library")
|
||||
@@ -329,6 +336,31 @@ add_subdirectory(wolfssl EXCLUDE_FROM_ALL)
|
||||
# CURL
|
||||
add_subdirectory(curl EXCLUDE_FROM_ALL)
|
||||
|
||||
# SDL2
|
||||
set(SDL2_TARGET 3rdparty_dummy_lib)
|
||||
if(USE_SDL)
|
||||
if(USE_SYSTEM_SDL)
|
||||
find_package(SDL2)
|
||||
if(SDL2_FOUND AND NOT SDL2_VERSION VERSION_LESS 2.24.0)
|
||||
message(STATUS "Using system SDL2")
|
||||
add_library(3rdparty_sdl2 INTERFACE)
|
||||
target_compile_definitions(3rdparty_sdl2 INTERFACE -DHAVE_SDL2=1)
|
||||
set(SDL2_TARGET 3rdparty_sdl2)
|
||||
else()
|
||||
message(FATAL_ERROR "SDL2 is not available on this system")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Using static SDL2 from 3rdparty")
|
||||
add_library(3rdparty_sdl2 INTERFACE)
|
||||
target_compile_definitions(3rdparty_sdl2 INTERFACE -DHAVE_SDL2=1)
|
||||
add_subdirectory(libsdl-org EXCLUDE_FROM_ALL)
|
||||
set(SDL2_TARGET 3rdparty_sdl2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# MINIUPNP
|
||||
add_subdirectory(miniupnp EXCLUDE_FROM_ALL)
|
||||
|
||||
# add nice ALIAS targets for ease of use
|
||||
if(USE_SYSTEM_LIBUSB)
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-shared)
|
||||
@@ -355,3 +387,5 @@ add_library(3rdparty::glew ALIAS 3rdparty_glew)
|
||||
add_library(3rdparty::wolfssl ALIAS wolfssl)
|
||||
add_library(3rdparty::libcurl ALIAS libcurl)
|
||||
add_library(3rdparty::soundtouch ALIAS soundtouch)
|
||||
add_library(3rdparty::sdl2 ALIAS ${SDL2_TARGET})
|
||||
add_library(3rdparty::miniupnpc ALIAS libminiupnpc-static)
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/FAudio updated: e787ed7655...c42b6814c2
Vendored
+1
-1
@@ -4,7 +4,7 @@ include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(moltenvk
|
||||
GIT_REPOSITORY https://github.com/KhronosGroup/MoltenVK.git
|
||||
GIT_TAG 1112005
|
||||
GIT_TAG fb581e4
|
||||
BUILD_IN_SOURCE 1
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
|
||||
CONFIGURE_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/fetchDependencies" --macos
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/SPIRV/SPIRV-Headers updated: 4995a2f272...85a1ed200d
Vendored
+1
-1
Submodule 3rdparty/SPIRV/SPIRV-Tools updated: 7826e1941e...eb0a36633d
Vendored
+1
-1
Submodule 3rdparty/cubeb/cubeb updated: dc511c6b35...70b4e3db78
Vendored
+1
-1
Submodule 3rdparty/curl/curl updated: 45ac4d0194...c12fb3ddaf
Vendored
+9
-3
@@ -66,12 +66,12 @@
|
||||
<ClCompile Include="curl\lib\base64.c" />
|
||||
<ClCompile Include="curl\lib\bufref.c" />
|
||||
<ClCompile Include="curl\lib\c-hyper.c" />
|
||||
<ClCompile Include="curl\lib\cfilters.c" />
|
||||
<ClCompile Include="curl\lib\conncache.c" />
|
||||
<ClCompile Include="curl\lib\connect.c" />
|
||||
<ClCompile Include="curl\lib\content_encoding.c" />
|
||||
<ClCompile Include="curl\lib\cookie.c" />
|
||||
<ClCompile Include="curl\lib\curl_addrinfo.c" />
|
||||
<ClCompile Include="curl\lib\curl_ctype.c" />
|
||||
<ClCompile Include="curl\lib\curl_des.c" />
|
||||
<ClCompile Include="curl\lib\curl_endian.c" />
|
||||
<ClCompile Include="curl\lib\curl_fnmatch.c" />
|
||||
@@ -90,7 +90,6 @@
|
||||
<ClCompile Include="curl\lib\curl_threads.c" />
|
||||
<ClCompile Include="curl\lib\dict.c" />
|
||||
<ClCompile Include="curl\lib\doh.c" />
|
||||
<ClCompile Include="curl\lib\dotdot.c" />
|
||||
<ClCompile Include="curl\lib\dynbuf.c" />
|
||||
<ClCompile Include="curl\lib\easy.c" />
|
||||
<ClCompile Include="curl\lib\easygetopt.c" />
|
||||
@@ -123,7 +122,7 @@
|
||||
<ClCompile Include="curl\lib\http_negotiate.c" />
|
||||
<ClCompile Include="curl\lib\http_ntlm.c" />
|
||||
<ClCompile Include="curl\lib\http_proxy.c" />
|
||||
<ClCompile Include="curl\lib\idn_win32.c" />
|
||||
<ClCompile Include="curl\lib\idn.c" />
|
||||
<ClCompile Include="curl\lib\if2ip.c" />
|
||||
<ClCompile Include="curl\lib\imap.c" />
|
||||
<ClCompile Include="curl\lib\inet_ntop.c" />
|
||||
@@ -140,6 +139,7 @@
|
||||
<ClCompile Include="curl\lib\multi.c" />
|
||||
<ClCompile Include="curl\lib\netrc.c" />
|
||||
<ClCompile Include="curl\lib\nonblock.c" />
|
||||
<ClCompile Include="curl\lib\noproxy.c" />
|
||||
<ClCompile Include="curl\lib\openldap.c" />
|
||||
<ClCompile Include="curl\lib\parsedate.c" />
|
||||
<ClCompile Include="curl\lib\pingpong.c" />
|
||||
@@ -215,6 +215,7 @@
|
||||
<ClCompile Include="curl\lib\vtls\sectransp.c" />
|
||||
<ClCompile Include="curl\lib\vtls\vtls.c" />
|
||||
<ClCompile Include="curl\lib\vtls\wolfssl.c" />
|
||||
<ClCompile Include="curl\lib\ws.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="curl\include\curl\curl.h" />
|
||||
@@ -232,6 +233,7 @@
|
||||
<ClInclude Include="curl\lib\asyn.h" />
|
||||
<ClInclude Include="curl\lib\bufref.h" />
|
||||
<ClInclude Include="curl\lib\c-hyper.h" />
|
||||
<ClInclude Include="curl\lib\cfilters.h" />
|
||||
<ClInclude Include="curl\lib\config-amigaos.h" />
|
||||
<ClInclude Include="curl\lib\config-dos.h" />
|
||||
<ClInclude Include="curl\lib\config-mac.h" />
|
||||
@@ -288,6 +290,7 @@
|
||||
<ClInclude Include="curl\lib\formdata.h" />
|
||||
<ClInclude Include="curl\lib\ftp.h" />
|
||||
<ClInclude Include="curl\lib\ftplistparser.h" />
|
||||
<ClInclude Include="curl\lib\functypes.h" />
|
||||
<ClInclude Include="curl\lib\getinfo.h" />
|
||||
<ClInclude Include="curl\lib\gopher.h" />
|
||||
<ClInclude Include="curl\lib\h2h3.h" />
|
||||
@@ -303,6 +306,7 @@
|
||||
<ClInclude Include="curl\lib\http_negotiate.h" />
|
||||
<ClInclude Include="curl\lib\http_ntlm.h" />
|
||||
<ClInclude Include="curl\lib\http_proxy.h" />
|
||||
<ClInclude Include="curl\lib\idn.h" />
|
||||
<ClInclude Include="curl\lib\if2ip.h" />
|
||||
<ClInclude Include="curl\lib\imap.h" />
|
||||
<ClInclude Include="curl\lib\inet_ntop.h" />
|
||||
@@ -315,6 +319,7 @@
|
||||
<ClInclude Include="curl\lib\multiif.h" />
|
||||
<ClInclude Include="curl\lib\netrc.h" />
|
||||
<ClInclude Include="curl\lib\nonblock.h" />
|
||||
<ClInclude Include="curl\lib\noproxy.h" />
|
||||
<ClInclude Include="curl\lib\parsedate.h" />
|
||||
<ClInclude Include="curl\lib\pingpong.h" />
|
||||
<ClInclude Include="curl\lib\pop3.h" />
|
||||
@@ -380,6 +385,7 @@
|
||||
<ClInclude Include="curl\lib\vtls\sectransp.h" />
|
||||
<ClInclude Include="curl\lib\vtls\vtls.h" />
|
||||
<ClInclude Include="curl\lib\vtls\wolfssl.h" />
|
||||
<ClInclude Include="curl\lib\ws.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="curl\lib\libcurl.rc" />
|
||||
|
||||
+27
-9
@@ -48,9 +48,6 @@
|
||||
<ClCompile Include="curl\lib\curl_addrinfo.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\curl_ctype.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\curl_des.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -105,9 +102,6 @@
|
||||
<ClCompile Include="curl\lib\doh.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\dotdot.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\easy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -180,9 +174,6 @@
|
||||
<ClCompile Include="curl\lib\http_proxy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\idn_win32.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\if2ip.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -483,6 +474,18 @@
|
||||
<ClCompile Include="curl\lib\fopen.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\noproxy.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\ws.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\cfilters.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="curl\lib\idn.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="curl\include\curl\curl.h">
|
||||
@@ -974,6 +977,21 @@
|
||||
<ClInclude Include="curl\lib\fopen.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\functypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\noproxy.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\ws.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\cfilters.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="curl\lib\idn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="curl\lib\libcurl.rc">
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/flatbuffers updated: 615616cb55...06c5c7ed0b
Vendored
+1
-1
Submodule 3rdparty/glslang/glslang updated: adbf0d3106...10423ec659
Vendored
+1
-1
Submodule 3rdparty/hidapi/hidapi updated: c2aa9dd37c...ecf1b62882
Vendored
+1
-1
Submodule 3rdparty/libpng/libpng updated: a40189cf88...07b8803110
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
option(SDL2_DISABLE_SDL2MAIN "" ON)
|
||||
option(SDL2_DISABLE_INSTALL "" ON)
|
||||
option(SDL2_DISABLE_UNINSTALL "" ON)
|
||||
option(SDL_SHARED OFF)
|
||||
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
|
||||
option(SDL_STATIC ON)
|
||||
set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
|
||||
option(SDL_TEST OFF)
|
||||
set(SDL_TEST_ENABLED_BY_DEFAULT OFF)
|
||||
set(OPT_DEF_LIBC ON)
|
||||
add_subdirectory(SDL EXCLUDE_FROM_ALL)
|
||||
+1
Submodule 3rdparty/libsdl-org/SDL added at adf31f6ec0
Vendored
+461
@@ -0,0 +1,461 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SDL\include\begin_code.h" />
|
||||
<ClInclude Include="SDL\include\close_code.h" />
|
||||
<ClInclude Include="SDL\include\SDL.h" />
|
||||
<ClInclude Include="SDL\include\SDL_assert.h" />
|
||||
<ClInclude Include="SDL\include\SDL_atomic.h" />
|
||||
<ClInclude Include="SDL\include\SDL_audio.h" />
|
||||
<ClInclude Include="SDL\include\SDL_bits.h" />
|
||||
<ClInclude Include="SDL\include\SDL_blendmode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_clipboard.h" />
|
||||
<ClInclude Include="SDL\include\SDL_config.h" />
|
||||
<ClInclude Include="SDL\include\SDL_config_windows.h" />
|
||||
<ClInclude Include="SDL\include\SDL_copying.h" />
|
||||
<ClInclude Include="SDL\include\SDL_cpuinfo.h" />
|
||||
<ClInclude Include="SDL\include\SDL_egl.h" />
|
||||
<ClInclude Include="SDL\include\SDL_endian.h" />
|
||||
<ClInclude Include="SDL\include\SDL_error.h" />
|
||||
<ClInclude Include="SDL\include\SDL_events.h" />
|
||||
<ClInclude Include="SDL\include\SDL_filesystem.h" />
|
||||
<ClInclude Include="SDL\include\SDL_gamecontroller.h" />
|
||||
<ClInclude Include="SDL\include\SDL_gesture.h" />
|
||||
<ClInclude Include="SDL\include\SDL_guid.h" />
|
||||
<ClInclude Include="SDL\include\SDL_haptic.h" />
|
||||
<ClInclude Include="SDL\include\SDL_hints.h" />
|
||||
<ClInclude Include="SDL\include\SDL_hidapi.h" />
|
||||
<ClInclude Include="SDL\include\SDL_joystick.h" />
|
||||
<ClInclude Include="SDL\include\SDL_keyboard.h" />
|
||||
<ClInclude Include="SDL\include\SDL_keycode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_loadso.h" />
|
||||
<ClInclude Include="SDL\include\SDL_locale.h" />
|
||||
<ClInclude Include="SDL\include\SDL_log.h" />
|
||||
<ClInclude Include="SDL\include\SDL_main.h" />
|
||||
<ClInclude Include="SDL\include\SDL_messagebox.h" />
|
||||
<ClInclude Include="SDL\include\SDL_metal.h" />
|
||||
<ClInclude Include="SDL\include\SDL_misc.h" />
|
||||
<ClInclude Include="SDL\include\SDL_mouse.h" />
|
||||
<ClInclude Include="SDL\include\SDL_mutex.h" />
|
||||
<ClInclude Include="SDL\include\SDL_name.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengl.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengl_glext.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2ext.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2platform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_khrplatform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_pixels.h" />
|
||||
<ClInclude Include="SDL\include\SDL_platform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_power.h" />
|
||||
<ClInclude Include="SDL\include\SDL_quit.h" />
|
||||
<ClInclude Include="SDL\include\SDL_rect.h" />
|
||||
<ClInclude Include="SDL\include\SDL_render.h" />
|
||||
<ClInclude Include="SDL\include\SDL_revision.h" />
|
||||
<ClInclude Include="SDL\include\SDL_rwops.h" />
|
||||
<ClInclude Include="SDL\include\SDL_scancode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_sensor.h" />
|
||||
<ClInclude Include="SDL\include\SDL_shape.h" />
|
||||
<ClInclude Include="SDL\include\SDL_stdinc.h" />
|
||||
<ClInclude Include="SDL\include\SDL_surface.h" />
|
||||
<ClInclude Include="SDL\include\SDL_system.h" />
|
||||
<ClInclude Include="SDL\include\SDL_syswm.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_assert.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_common.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_compare.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_crc32.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_font.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_fuzzer.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_harness.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_images.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_log.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_md5.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_memory.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_random.h" />
|
||||
<ClInclude Include="SDL\include\SDL_thread.h" />
|
||||
<ClInclude Include="SDL\include\SDL_timer.h" />
|
||||
<ClInclude Include="SDL\include\SDL_touch.h" />
|
||||
<ClInclude Include="SDL\include\SDL_types.h" />
|
||||
<ClInclude Include="SDL\include\SDL_version.h" />
|
||||
<ClInclude Include="SDL\include\SDL_video.h" />
|
||||
<ClInclude Include="SDL\include\SDL_vulkan.h" />
|
||||
<ClInclude Include="SDL\src\audio\directsound\SDL_directsound.h" />
|
||||
<ClInclude Include="SDL\src\audio\disk\SDL_diskaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\dummy\SDL_dummyaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_audio_c.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_audiodev_c.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_sysaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_wave.h" />
|
||||
<ClInclude Include="SDL\src\audio\wasapi\SDL_wasapi.h" />
|
||||
<ClInclude Include="SDL\src\audio\winmm\SDL_winmm.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_directx.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_hid.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_immdevice.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_windows.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_xinput.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_overrides.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_procs.h" />
|
||||
<ClInclude Include="SDL\src\events\blank_cursor.h" />
|
||||
<ClInclude Include="SDL\src\events\default_cursor.h" />
|
||||
<ClInclude Include="SDL\src\events\scancodes_windows.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_clipboardevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_displayevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_dropevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_events_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_gesture_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_keyboard_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_mouse_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_touch_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_windowevents_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\SDL_haptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\SDL_syshaptic.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_dinputhaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_windowshaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_xinputhaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\hidapi\hidapi\hidapi.h" />
|
||||
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\controller_type.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_gamecontrollerdb.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_joystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_sysjoystick.h" />
|
||||
<ClInclude Include="SDL\src\joystick\usb_ids.h" />
|
||||
<ClInclude Include="SDL\src\joystick\virtual\SDL_virtualjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_dinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_rawinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_windowsjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_xinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\libm\math_libm.h" />
|
||||
<ClInclude Include="SDL\src\libm\math_private.h" />
|
||||
<ClInclude Include="SDL\src\locale\SDL_syslocale.h" />
|
||||
<ClInclude Include="SDL\src\misc\SDL_sysurl.h" />
|
||||
<ClInclude Include="SDL\src\power\SDL_syspower.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d\SDL_shaders_d3d.h" />
|
||||
<ClInclude Include="SDL\src\render\opengles2\SDL_gles2funcs.h" />
|
||||
<ClInclude Include="SDL\src\render\opengles2\SDL_shaders_gles2.h" />
|
||||
<ClInclude Include="SDL\src\render\opengl\SDL_glfuncs.h" />
|
||||
<ClInclude Include="SDL\src\render\opengl\SDL_shaders_gl.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_d3dmath.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_sysrender.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_yuv_sw_c.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendfillrect.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendline.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendpoint.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_draw.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_drawline.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_drawpoint.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_rotate.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_triangle.h" />
|
||||
<ClInclude Include="SDL\src\SDL_assert_c.h" />
|
||||
<ClInclude Include="SDL\src\SDL_dataqueue.h" />
|
||||
<ClInclude Include="SDL\src\SDL_error_c.h" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps3.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_wii.c" />
|
||||
<ClCompile Include="SDL\src\SDL_guid.c" />
|
||||
<ClInclude Include="SDL\src\SDL_hints_c.h" />
|
||||
<ClInclude Include="SDL\src\SDL_internal.h" />
|
||||
<ClInclude Include="SDL\src\SDL_list.h" />
|
||||
<ClInclude Include="SDL\src\SDL_log_c.h" />
|
||||
<ClInclude Include="SDL\src\sensor\dummy\SDL_dummysensor.h" />
|
||||
<ClInclude Include="SDL\src\sensor\SDL_sensor_c.h" />
|
||||
<ClInclude Include="SDL\src\sensor\SDL_syssensor.h" />
|
||||
<ClInclude Include="SDL\src\sensor\windows\SDL_windowssensor.h" />
|
||||
<ClInclude Include="SDL\src\thread\SDL_systhread.h" />
|
||||
<ClInclude Include="SDL\src\thread\SDL_thread_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\generic\SDL_syscond_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\windows\SDL_sysmutex_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\windows\SDL_systhread_c.h" />
|
||||
<ClInclude Include="SDL\src\timer\SDL_timer_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullevents_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullframebuffer_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_icd.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_layer.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_platform.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_sdk_platform.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.hpp" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_android.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_beta.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_core.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_directfb.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_fuchsia.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ggp.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ios.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_macos.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_metal.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_vi.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_wayland.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_win32.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xcb.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib_xrandr.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_auto.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_copy.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_slow.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_egl_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_pixels_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_rect_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_RLEaccel_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_shape_internals.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_sysvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_vulkan_internal.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_yuv_c.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_msctf.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_vkeys.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsevents.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsframebuffer.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowskeyboard.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmessagebox.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmodes.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmouse.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengl.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengles.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsshape.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsvulkan.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowswindow.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\wmmsg.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse_func.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std_func.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SDL\src\atomic\SDL_atomic.c" />
|
||||
<ClCompile Include="SDL\src\atomic\SDL_spinlock.c" />
|
||||
<ClCompile Include="SDL\src\audio\directsound\SDL_directsound.c" />
|
||||
<ClCompile Include="SDL\src\audio\disk\SDL_diskaudio.c" />
|
||||
<ClCompile Include="SDL\src\audio\dummy\SDL_dummyaudio.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audio.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiocvt.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiodev.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiotypecvt.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_mixer.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_wave.c" />
|
||||
<ClCompile Include="SDL\src\audio\winmm\SDL_winmm.c" />
|
||||
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
|
||||
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi_win32.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_hid.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_immdevice.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_windows.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_xinput.c" />
|
||||
<ClCompile Include="SDL\src\cpuinfo\SDL_cpuinfo.c" />
|
||||
<ClCompile Include="SDL\src\dynapi\SDL_dynapi.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_clipboardevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_displayevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_dropevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_events.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_gesture.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_keyboard.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_mouse.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_quit.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_touch.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_windowevents.c" />
|
||||
<ClCompile Include="SDL\src\file\SDL_rwops.c" />
|
||||
<ClCompile Include="SDL\src\filesystem\windows\SDL_sysfilesystem.c" />
|
||||
<ClCompile Include="SDL\src\haptic\dummy\SDL_syshaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\SDL_haptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_dinputhaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_windowshaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_xinputhaptic.c" />
|
||||
<ClCompile Include="SDL\src\hidapi\SDL_hidapi.c" />
|
||||
<ClCompile Include="SDL\src\joystick\controller_type.c" />
|
||||
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapijoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_luna.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps4.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps5.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_shield.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_stadia.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
|
||||
<ClCompile Include="SDL\src\joystick\SDL_gamecontroller.c" />
|
||||
<ClCompile Include="SDL\src\joystick\SDL_joystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\virtual\SDL_virtualjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_dinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_rawinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_windowsjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_windows_gaming_input.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_xinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_atan2.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_exp.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_fmod.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_log.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_log10.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_pow.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_rem_pio2.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_sqrt.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_cos.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_rem_pio2.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_sin.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_tan.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_atan.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_copysign.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_cos.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_fabs.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_floor.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_scalbn.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_sin.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_tan.c" />
|
||||
<ClCompile Include="SDL\src\loadso\windows\SDL_sysloadso.c" />
|
||||
<ClCompile Include="SDL\src\locale\SDL_locale.c" />
|
||||
<ClCompile Include="SDL\src\locale\windows\SDL_syslocale.c" />
|
||||
<ClCompile Include="SDL\src\misc\SDL_url.c" />
|
||||
<ClCompile Include="SDL\src\misc\windows\SDL_sysurl.c" />
|
||||
<ClCompile Include="SDL\src\power\SDL_power.c" />
|
||||
<ClCompile Include="SDL\src\power\windows\SDL_syspower.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d12\SDL_render_d3d12.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d\SDL_render_d3d.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d11\SDL_render_d3d11.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d\SDL_shaders_d3d.c" />
|
||||
<ClCompile Include="SDL\src\render\opengl\SDL_render_gl.c" />
|
||||
<ClCompile Include="SDL\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="SDL\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="SDL\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_render.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_yuv_sw.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendfillrect.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendline.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendpoint.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_drawline.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_drawpoint.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_rotate.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_triangle.c" />
|
||||
<ClCompile Include="SDL\src\SDL.c" />
|
||||
<ClCompile Include="SDL\src\SDL_assert.c" />
|
||||
<ClCompile Include="SDL\src\SDL_dataqueue.c" />
|
||||
<ClCompile Include="SDL\src\SDL_list.c" />
|
||||
<ClCompile Include="SDL\src\SDL_error.c" />
|
||||
<ClCompile Include="SDL\src\SDL_hints.c" />
|
||||
<ClCompile Include="SDL\src\SDL_log.c" />
|
||||
<ClCompile Include="SDL\src\SDL_utils.c" />
|
||||
<ClCompile Include="SDL\src\sensor\dummy\SDL_dummysensor.c" />
|
||||
<ClCompile Include="SDL\src\sensor\SDL_sensor.c" />
|
||||
<ClCompile Include="SDL\src\sensor\windows\SDL_windowssensor.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_crc16.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_crc32.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_getenv.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_iconv.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_malloc.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_mslibc.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_qsort.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_stdlib.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_string.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_strtokr.c" />
|
||||
<ClCompile Include="SDL\src\thread\generic\SDL_syscond.c" />
|
||||
<ClCompile Include="SDL\src\thread\SDL_thread.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_syscond_cv.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_sysmutex.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_syssem.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_systhread.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_systls.c" />
|
||||
<ClCompile Include="SDL\src\timer\SDL_timer.c" />
|
||||
<ClCompile Include="SDL\src\timer\windows\SDL_systimer.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullevents.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullframebuffer.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullvideo.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_0.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_1.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_A.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_auto.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_copy.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_N.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_slow.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_bmp.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_clipboard.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_egl.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_fillrect.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_pixels.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_rect.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_RLEaccel.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_shape.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_stretch.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_surface.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_video.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_vulkan_utils.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_yuv.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsevents.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsframebuffer.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmodes.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmouse.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengl.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengles.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsshape.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsvideo.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsvulkan.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowswindow.c" />
|
||||
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_default.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_debug.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\rpcs3_release.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck>false</SDLCheck>
|
||||
<AdditionalIncludeDirectories>SDL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
+413
@@ -0,0 +1,413 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SDL\src\SDL_guid.c" />
|
||||
<ClCompile Include="SDL\src\atomic\SDL_atomic.c" />
|
||||
<ClCompile Include="SDL\src\atomic\SDL_spinlock.c" />
|
||||
<ClCompile Include="SDL\src\audio\directsound\SDL_directsound.c" />
|
||||
<ClCompile Include="SDL\src\audio\disk\SDL_diskaudio.c" />
|
||||
<ClCompile Include="SDL\src\audio\dummy\SDL_dummyaudio.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audio.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiocvt.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiodev.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_audiotypecvt.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_mixer.c" />
|
||||
<ClCompile Include="SDL\src\audio\SDL_wave.c" />
|
||||
<ClCompile Include="SDL\src\audio\winmm\SDL_winmm.c" />
|
||||
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi.c" />
|
||||
<ClCompile Include="SDL\src\audio\wasapi\SDL_wasapi_win32.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_hid.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_immdevice.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_windows.c" />
|
||||
<ClCompile Include="SDL\src\core\windows\SDL_xinput.c" />
|
||||
<ClCompile Include="SDL\src\cpuinfo\SDL_cpuinfo.c" />
|
||||
<ClCompile Include="SDL\src\dynapi\SDL_dynapi.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_clipboardevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_displayevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_dropevents.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_events.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_gesture.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_keyboard.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_mouse.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_quit.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_touch.c" />
|
||||
<ClCompile Include="SDL\src\events\SDL_windowevents.c" />
|
||||
<ClCompile Include="SDL\src\file\SDL_rwops.c" />
|
||||
<ClCompile Include="SDL\src\filesystem\windows\SDL_sysfilesystem.c" />
|
||||
<ClCompile Include="SDL\src\haptic\dummy\SDL_syshaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\SDL_haptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_dinputhaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_windowshaptic.c" />
|
||||
<ClCompile Include="SDL\src\haptic\windows\SDL_xinputhaptic.c" />
|
||||
<ClCompile Include="SDL\src\hidapi\SDL_hidapi.c" />
|
||||
<ClCompile Include="SDL\src\joystick\controller_type.c" />
|
||||
<ClCompile Include="SDL\src\joystick\dummy\SDL_sysjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapijoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_combined.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_luna.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps4.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps5.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_shield.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_stadia.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_switch.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
|
||||
<ClCompile Include="SDL\src\joystick\SDL_gamecontroller.c" />
|
||||
<ClCompile Include="SDL\src\joystick\SDL_joystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\virtual\SDL_virtualjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_dinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_rawinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_windowsjoystick.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_windows_gaming_input.c" />
|
||||
<ClCompile Include="SDL\src\joystick\windows\SDL_xinputjoystick.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_atan2.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_exp.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_fmod.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_log.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_log10.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_pow.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_rem_pio2.c" />
|
||||
<ClCompile Include="SDL\src\libm\e_sqrt.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_cos.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_rem_pio2.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_sin.c" />
|
||||
<ClCompile Include="SDL\src\libm\k_tan.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_atan.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_copysign.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_cos.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_fabs.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_floor.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_scalbn.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_sin.c" />
|
||||
<ClCompile Include="SDL\src\libm\s_tan.c" />
|
||||
<ClCompile Include="SDL\src\loadso\windows\SDL_sysloadso.c" />
|
||||
<ClCompile Include="SDL\src\locale\SDL_locale.c" />
|
||||
<ClCompile Include="SDL\src\locale\windows\SDL_syslocale.c" />
|
||||
<ClCompile Include="SDL\src\misc\SDL_url.c" />
|
||||
<ClCompile Include="SDL\src\misc\windows\SDL_sysurl.c" />
|
||||
<ClCompile Include="SDL\src\power\SDL_power.c" />
|
||||
<ClCompile Include="SDL\src\power\windows\SDL_syspower.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d12\SDL_render_d3d12.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d\SDL_render_d3d.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d11\SDL_render_d3d11.c" />
|
||||
<ClCompile Include="SDL\src\render\direct3d\SDL_shaders_d3d.c" />
|
||||
<ClCompile Include="SDL\src\render\opengl\SDL_render_gl.c" />
|
||||
<ClCompile Include="SDL\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="SDL\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="SDL\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_render.c" />
|
||||
<ClCompile Include="SDL\src\render\SDL_yuv_sw.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendfillrect.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendline.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_blendpoint.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_drawline.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_drawpoint.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_render_sw.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_rotate.c" />
|
||||
<ClCompile Include="SDL\src\render\software\SDL_triangle.c" />
|
||||
<ClCompile Include="SDL\src\SDL.c" />
|
||||
<ClCompile Include="SDL\src\SDL_assert.c" />
|
||||
<ClCompile Include="SDL\src\SDL_dataqueue.c" />
|
||||
<ClCompile Include="SDL\src\SDL_list.c" />
|
||||
<ClCompile Include="SDL\src\SDL_error.c" />
|
||||
<ClCompile Include="SDL\src\SDL_hints.c" />
|
||||
<ClCompile Include="SDL\src\SDL_log.c" />
|
||||
<ClCompile Include="SDL\src\SDL_utils.c" />
|
||||
<ClCompile Include="SDL\src\sensor\dummy\SDL_dummysensor.c" />
|
||||
<ClCompile Include="SDL\src\sensor\SDL_sensor.c" />
|
||||
<ClCompile Include="SDL\src\sensor\windows\SDL_windowssensor.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_crc16.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_crc32.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_getenv.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_iconv.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_malloc.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_mslibc.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_qsort.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_stdlib.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_string.c" />
|
||||
<ClCompile Include="SDL\src\stdlib\SDL_strtokr.c" />
|
||||
<ClCompile Include="SDL\src\thread\generic\SDL_syscond.c" />
|
||||
<ClCompile Include="SDL\src\thread\SDL_thread.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_syscond_cv.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_sysmutex.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_syssem.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_systhread.c" />
|
||||
<ClCompile Include="SDL\src\thread\windows\SDL_systls.c" />
|
||||
<ClCompile Include="SDL\src\timer\SDL_timer.c" />
|
||||
<ClCompile Include="SDL\src\timer\windows\SDL_systimer.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullevents.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullframebuffer.c" />
|
||||
<ClCompile Include="SDL\src\video\dummy\SDL_nullvideo.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_0.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_1.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_A.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_auto.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_copy.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_N.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_blit_slow.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_bmp.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_clipboard.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_egl.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_fillrect.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_pixels.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_rect.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_RLEaccel.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_shape.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_stretch.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_surface.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_video.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_vulkan_utils.c" />
|
||||
<ClCompile Include="SDL\src\video\SDL_yuv.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsclipboard.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsevents.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsframebuffer.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowskeyboard.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmessagebox.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmodes.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsmouse.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengl.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsopengles.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsshape.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsvideo.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowsvulkan.c" />
|
||||
<ClCompile Include="SDL\src\video\windows\SDL_windowswindow.c" />
|
||||
<ClCompile Include="SDL\src\video\yuv2rgb\yuv_rgb.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_ps3.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_steam.c" />
|
||||
<ClCompile Include="SDL\src\joystick\hidapi\SDL_hidapi_wii.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SDL\include\begin_code.h" />
|
||||
<ClInclude Include="SDL\include\close_code.h" />
|
||||
<ClInclude Include="SDL\include\SDL.h" />
|
||||
<ClInclude Include="SDL\include\SDL_assert.h" />
|
||||
<ClInclude Include="SDL\include\SDL_atomic.h" />
|
||||
<ClInclude Include="SDL\include\SDL_audio.h" />
|
||||
<ClInclude Include="SDL\include\SDL_bits.h" />
|
||||
<ClInclude Include="SDL\include\SDL_blendmode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_clipboard.h" />
|
||||
<ClInclude Include="SDL\include\SDL_config.h" />
|
||||
<ClInclude Include="SDL\include\SDL_config_windows.h" />
|
||||
<ClInclude Include="SDL\include\SDL_copying.h" />
|
||||
<ClInclude Include="SDL\include\SDL_cpuinfo.h" />
|
||||
<ClInclude Include="SDL\include\SDL_egl.h" />
|
||||
<ClInclude Include="SDL\include\SDL_endian.h" />
|
||||
<ClInclude Include="SDL\include\SDL_error.h" />
|
||||
<ClInclude Include="SDL\include\SDL_events.h" />
|
||||
<ClInclude Include="SDL\include\SDL_filesystem.h" />
|
||||
<ClInclude Include="SDL\include\SDL_gamecontroller.h" />
|
||||
<ClInclude Include="SDL\include\SDL_gesture.h" />
|
||||
<ClInclude Include="SDL\include\SDL_guid.h" />
|
||||
<ClInclude Include="SDL\include\SDL_haptic.h" />
|
||||
<ClInclude Include="SDL\include\SDL_hints.h" />
|
||||
<ClInclude Include="SDL\include\SDL_hidapi.h" />
|
||||
<ClInclude Include="SDL\include\SDL_joystick.h" />
|
||||
<ClInclude Include="SDL\include\SDL_keyboard.h" />
|
||||
<ClInclude Include="SDL\include\SDL_keycode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_loadso.h" />
|
||||
<ClInclude Include="SDL\include\SDL_locale.h" />
|
||||
<ClInclude Include="SDL\include\SDL_log.h" />
|
||||
<ClInclude Include="SDL\include\SDL_main.h" />
|
||||
<ClInclude Include="SDL\include\SDL_messagebox.h" />
|
||||
<ClInclude Include="SDL\include\SDL_metal.h" />
|
||||
<ClInclude Include="SDL\include\SDL_misc.h" />
|
||||
<ClInclude Include="SDL\include\SDL_mouse.h" />
|
||||
<ClInclude Include="SDL\include\SDL_mutex.h" />
|
||||
<ClInclude Include="SDL\include\SDL_name.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengl.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengl_glext.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2ext.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_gl2platform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_opengles2_khrplatform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_pixels.h" />
|
||||
<ClInclude Include="SDL\include\SDL_platform.h" />
|
||||
<ClInclude Include="SDL\include\SDL_power.h" />
|
||||
<ClInclude Include="SDL\include\SDL_quit.h" />
|
||||
<ClInclude Include="SDL\include\SDL_rect.h" />
|
||||
<ClInclude Include="SDL\include\SDL_render.h" />
|
||||
<ClInclude Include="SDL\include\SDL_revision.h" />
|
||||
<ClInclude Include="SDL\include\SDL_rwops.h" />
|
||||
<ClInclude Include="SDL\include\SDL_scancode.h" />
|
||||
<ClInclude Include="SDL\include\SDL_sensor.h" />
|
||||
<ClInclude Include="SDL\include\SDL_shape.h" />
|
||||
<ClInclude Include="SDL\include\SDL_stdinc.h" />
|
||||
<ClInclude Include="SDL\include\SDL_surface.h" />
|
||||
<ClInclude Include="SDL\include\SDL_system.h" />
|
||||
<ClInclude Include="SDL\include\SDL_syswm.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_assert.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_common.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_compare.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_crc32.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_font.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_fuzzer.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_harness.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_images.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_log.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_md5.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_memory.h" />
|
||||
<ClInclude Include="SDL\include\SDL_test_random.h" />
|
||||
<ClInclude Include="SDL\include\SDL_thread.h" />
|
||||
<ClInclude Include="SDL\include\SDL_timer.h" />
|
||||
<ClInclude Include="SDL\include\SDL_touch.h" />
|
||||
<ClInclude Include="SDL\include\SDL_types.h" />
|
||||
<ClInclude Include="SDL\include\SDL_version.h" />
|
||||
<ClInclude Include="SDL\include\SDL_video.h" />
|
||||
<ClInclude Include="SDL\include\SDL_vulkan.h" />
|
||||
<ClInclude Include="SDL\src\audio\directsound\SDL_directsound.h" />
|
||||
<ClInclude Include="SDL\src\audio\disk\SDL_diskaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\dummy\SDL_dummyaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_audio_c.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_audiodev_c.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_sysaudio.h" />
|
||||
<ClInclude Include="SDL\src\audio\SDL_wave.h" />
|
||||
<ClInclude Include="SDL\src\audio\wasapi\SDL_wasapi.h" />
|
||||
<ClInclude Include="SDL\src\audio\winmm\SDL_winmm.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_directx.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_hid.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_immdevice.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_windows.h" />
|
||||
<ClInclude Include="SDL\src\core\windows\SDL_xinput.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_overrides.h" />
|
||||
<ClInclude Include="SDL\src\dynapi\SDL_dynapi_procs.h" />
|
||||
<ClInclude Include="SDL\src\events\blank_cursor.h" />
|
||||
<ClInclude Include="SDL\src\events\default_cursor.h" />
|
||||
<ClInclude Include="SDL\src\events\scancodes_windows.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_clipboardevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_displayevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_dropevents_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_events_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_gesture_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_keyboard_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_mouse_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_touch_c.h" />
|
||||
<ClInclude Include="SDL\src\events\SDL_windowevents_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\SDL_haptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\SDL_syshaptic.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_dinputhaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_windowshaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\haptic\windows\SDL_xinputhaptic_c.h" />
|
||||
<ClInclude Include="SDL\src\hidapi\hidapi\hidapi.h" />
|
||||
<ClInclude Include="SDL\src\hidapi\SDL_hidapi_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\controller_type.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_rumble.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_gamecontrollerdb.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_joystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\SDL_sysjoystick.h" />
|
||||
<ClInclude Include="SDL\src\joystick\usb_ids.h" />
|
||||
<ClInclude Include="SDL\src\joystick\virtual\SDL_virtualjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_dinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_rawinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_windowsjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\joystick\windows\SDL_xinputjoystick_c.h" />
|
||||
<ClInclude Include="SDL\src\libm\math_libm.h" />
|
||||
<ClInclude Include="SDL\src\libm\math_private.h" />
|
||||
<ClInclude Include="SDL\src\locale\SDL_syslocale.h" />
|
||||
<ClInclude Include="SDL\src\misc\SDL_sysurl.h" />
|
||||
<ClInclude Include="SDL\src\power\SDL_syspower.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d11\SDL_shaders_d3d11.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d12\SDL_shaders_d3d12.h" />
|
||||
<ClInclude Include="SDL\src\render\direct3d\SDL_shaders_d3d.h" />
|
||||
<ClInclude Include="SDL\src\render\opengles2\SDL_gles2funcs.h" />
|
||||
<ClInclude Include="SDL\src\render\opengles2\SDL_shaders_gles2.h" />
|
||||
<ClInclude Include="SDL\src\render\opengl\SDL_glfuncs.h" />
|
||||
<ClInclude Include="SDL\src\render\opengl\SDL_shaders_gl.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_d3dmath.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_sysrender.h" />
|
||||
<ClInclude Include="SDL\src\render\SDL_yuv_sw_c.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendfillrect.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendline.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_blendpoint.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_draw.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_drawline.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_drawpoint.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_render_sw_c.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_rotate.h" />
|
||||
<ClInclude Include="SDL\src\render\software\SDL_triangle.h" />
|
||||
<ClInclude Include="SDL\src\SDL_assert_c.h" />
|
||||
<ClInclude Include="SDL\src\SDL_dataqueue.h" />
|
||||
<ClInclude Include="SDL\src\SDL_error_c.h" />
|
||||
<ClInclude Include="SDL\src\SDL_hints_c.h" />
|
||||
<ClInclude Include="SDL\src\SDL_internal.h" />
|
||||
<ClInclude Include="SDL\src\SDL_list.h" />
|
||||
<ClInclude Include="SDL\src\SDL_log_c.h" />
|
||||
<ClInclude Include="SDL\src\sensor\dummy\SDL_dummysensor.h" />
|
||||
<ClInclude Include="SDL\src\sensor\SDL_sensor_c.h" />
|
||||
<ClInclude Include="SDL\src\sensor\SDL_syssensor.h" />
|
||||
<ClInclude Include="SDL\src\sensor\windows\SDL_windowssensor.h" />
|
||||
<ClInclude Include="SDL\src\thread\SDL_systhread.h" />
|
||||
<ClInclude Include="SDL\src\thread\SDL_thread_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\generic\SDL_syscond_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\windows\SDL_sysmutex_c.h" />
|
||||
<ClInclude Include="SDL\src\thread\windows\SDL_systhread_c.h" />
|
||||
<ClInclude Include="SDL\src\timer\SDL_timer_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullevents_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullframebuffer_c.h" />
|
||||
<ClInclude Include="SDL\src\video\dummy\SDL_nullvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_icd.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_layer.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_platform.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vk_sdk_platform.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan.hpp" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_android.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_beta.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_core.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_directfb.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_fuchsia.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ggp.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_ios.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_macos.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_metal.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_vi.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_wayland.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_win32.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xcb.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib.h" />
|
||||
<ClInclude Include="SDL\src\video\khronos\vulkan\vulkan_xlib_xrandr.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_auto.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_copy.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_blit_slow.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_egl_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_pixels_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_rect_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_RLEaccel_c.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_shape_internals.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_sysvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_vulkan_internal.h" />
|
||||
<ClInclude Include="SDL\src\video\SDL_yuv_c.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_msctf.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_vkeys.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsclipboard.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsevents.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsframebuffer.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowskeyboard.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmessagebox.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmodes.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsmouse.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengl.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsopengles.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsshape.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsvideo.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowsvulkan.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\SDL_windowswindow.h" />
|
||||
<ClInclude Include="SDL\src\video\windows\wmmsg.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_sse_func.h" />
|
||||
<ClInclude Include="SDL\src\video\yuv2rgb\yuv_rgb_std_func.h" />
|
||||
<ClInclude Include="SDL\src\joystick\hidapi\SDL_hidapi_nintendo.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
option (UPNPC_BUILD_STATIC "Build static library" TRUE)
|
||||
option (UPNPC_BUILD_SHARED "Build shared library" FALSE)
|
||||
option (UPNPC_BUILD_TESTS "Build test executables" FALSE)
|
||||
option (UPNPC_BUILD_SAMPLE "Build sample executables" FALSE)
|
||||
option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
|
||||
option (UPNPC_NO_INSTALL "Disable installation" TRUE)
|
||||
|
||||
add_subdirectory(miniupnp/miniupnpc EXCLUDE_FROM_ALL)
|
||||
+1
Submodule 3rdparty/miniupnp/miniupnp added at f4a739d730
+138
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{5228f863-e0dd-4de7-aa7b-5c52b14cd4d0}</ProjectGuid>
|
||||
<RootNamespace>miniupnpcstatic</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
|
||||
cscript genminiupnpcstrings.vbs</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS; _CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>generated;miniupnp\miniupnpc;miniupnp\miniupnpc\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd $(ProjectDir)miniupnp\miniupnpc\msvc
|
||||
cscript genminiupnpcstrings.vbs</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\addr_is_reserved.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\connecthostport.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\igd_desc_parse.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minisoap.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minissdpc.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\miniupnpc.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\miniwget.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\minixml.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\portlistingparse.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\receivedata.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpcommands.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpdev.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnperrors.c" />
|
||||
<ClCompile Include="miniupnp\miniupnpc\src\upnpreplyparse.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\addr_is_reserved.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\connecthostport.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\igd_desc_parse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minisoap.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minissdpc.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\miniupnpcstrings.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpctypes.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniupnpc_declspec.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\miniwget.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\miniwget_private.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\minixml.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\portlistingparse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\receivedata.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpcommands.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpdev.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnperrors.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\include\upnpreplyparse.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\src\win32_snprintf.h" />
|
||||
<ClInclude Include="miniupnp\miniupnpc\rc_version.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
+94
-105
@@ -24,6 +24,7 @@
|
||||
#define close_portable(a) (close(a))
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <poll.h>
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -79,13 +80,13 @@ namespace pine
|
||||
* A preallocated buffer used to store all IPC replies.
|
||||
* to the size of 50.000 MsgWrite64 IPC calls.
|
||||
*/
|
||||
char* m_ret_buffer;
|
||||
std::vector<char> m_ret_buffer;
|
||||
|
||||
/**
|
||||
* IPC messages buffer.
|
||||
* A preallocated buffer used to store all IPC messages.
|
||||
*/
|
||||
char* m_ipc_buffer;
|
||||
std::vector<char> m_ipc_buffer;
|
||||
|
||||
/**
|
||||
* IPC Command messages opcodes.
|
||||
@@ -118,8 +119,8 @@ namespace pine
|
||||
*/
|
||||
struct IPCBuffer
|
||||
{
|
||||
int size; /**< Size of the buffer. */
|
||||
char* buffer; /**< Buffer. */
|
||||
usz size{}; /**< Size of the buffer. */
|
||||
char* buffer{}; /**< Buffer. */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -144,13 +145,30 @@ namespace pine
|
||||
*/
|
||||
IPCBuffer ParseCommand(char* buf, char* ret_buffer, u32 buf_size)
|
||||
{
|
||||
u32 ret_cnt = 5;
|
||||
u32 buf_cnt = 0;
|
||||
usz ret_cnt = 5;
|
||||
usz buf_cnt = 0;
|
||||
|
||||
const auto error = [&]()
|
||||
{
|
||||
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
|
||||
};
|
||||
|
||||
const auto write_string = [&](const std::string& str)
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, str.size() + 1 + sizeof(u32), buf_size))
|
||||
return false;
|
||||
ToArray(ret_buffer, ::narrow<u32>(str.size() + 1), ret_cnt);
|
||||
ret_cnt += sizeof(u32);
|
||||
memcpy(&ret_buffer[ret_cnt], str.data(), str.size());
|
||||
ret_cnt += str.size();
|
||||
ret_buffer[ret_cnt++] = '\0';
|
||||
return true;
|
||||
};
|
||||
|
||||
while (buf_cnt < buf_size)
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 1, ret_cnt, 0, buf_size))
|
||||
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
|
||||
return error();
|
||||
buf_cnt++;
|
||||
// example IPC messages: MsgRead/Write
|
||||
// refer to the client doc for more info on the format
|
||||
@@ -169,10 +187,10 @@ namespace pine
|
||||
case MsgRead8:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 1, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr(a))
|
||||
goto error;
|
||||
return error();
|
||||
const u8 res = Impl::read8(a);
|
||||
ToArray(ret_buffer, res, ret_cnt);
|
||||
ret_cnt += 1;
|
||||
@@ -182,10 +200,10 @@ namespace pine
|
||||
case MsgRead16:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 2, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<2>(a))
|
||||
goto error;
|
||||
return error();
|
||||
const u16 res = Impl::read16(a);
|
||||
ToArray(ret_buffer, res, ret_cnt);
|
||||
ret_cnt += 2;
|
||||
@@ -195,10 +213,10 @@ namespace pine
|
||||
case MsgRead32:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 4, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<4>(a))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 res = Impl::read32(a);
|
||||
ToArray(ret_buffer, res, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
@@ -208,10 +226,10 @@ namespace pine
|
||||
case MsgRead64:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 4, ret_cnt, 8, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<8>(a))
|
||||
goto error;
|
||||
return error();
|
||||
u64 res = Impl::read64(a);
|
||||
ToArray(ret_buffer, res, ret_cnt);
|
||||
ret_cnt += 8;
|
||||
@@ -221,10 +239,10 @@ namespace pine
|
||||
case MsgWrite8:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 1 + 4, ret_cnt, 0, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr(a, vm::page_writable))
|
||||
goto error;
|
||||
return error();
|
||||
Impl::write8(a, FromArray<u8>(&buf[buf_cnt], 4));
|
||||
buf_cnt += 5;
|
||||
break;
|
||||
@@ -232,10 +250,10 @@ namespace pine
|
||||
case MsgWrite16:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 2 + 4, ret_cnt, 0, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<2>(a, vm::page_writable))
|
||||
goto error;
|
||||
return error();
|
||||
Impl::write16(a, FromArray<u16>(&buf[buf_cnt], 4));
|
||||
buf_cnt += 6;
|
||||
break;
|
||||
@@ -243,10 +261,10 @@ namespace pine
|
||||
case MsgWrite32:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 4 + 4, ret_cnt, 0, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<4>(a, vm::page_writable))
|
||||
goto error;
|
||||
return error();
|
||||
Impl::write32(a, FromArray<u32>(&buf[buf_cnt], 4));
|
||||
buf_cnt += 8;
|
||||
break;
|
||||
@@ -254,32 +272,24 @@ namespace pine
|
||||
case MsgWrite64:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 8 + 4, ret_cnt, 0, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
const u32 a = FromArray<u32>(&buf[buf_cnt], 0);
|
||||
if (!Impl::template check_addr<8>(a, vm::page_writable))
|
||||
goto error;
|
||||
return error();
|
||||
Impl::write64(a, FromArray<u64>(&buf[buf_cnt], 4));
|
||||
buf_cnt += 12;
|
||||
break;
|
||||
}
|
||||
case MsgVersion:
|
||||
{
|
||||
char version[256] = {};
|
||||
sprintf(version, "RPCS3 %s", Impl::get_version_and_branch().c_str());
|
||||
const u32 size = strlen(version) + 1;
|
||||
version[size] = 0x00;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
|
||||
goto error;
|
||||
ToArray(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], version, size);
|
||||
ret_cnt += size;
|
||||
if (!write_string("RPCS3 " + Impl::get_version_and_branch()))
|
||||
return error();
|
||||
break;
|
||||
}
|
||||
case MsgStatus:
|
||||
{
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, 4, buf_size))
|
||||
goto error;
|
||||
return error();
|
||||
EmuStatus status = Impl::get_status();
|
||||
ToArray(ret_buffer, status, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
@@ -288,76 +298,35 @@ namespace pine
|
||||
}
|
||||
case MsgTitle:
|
||||
{
|
||||
const auto title_string = Impl::get_title();
|
||||
const auto size = title_string.size() + 1;
|
||||
char* title = new char[size];
|
||||
sprintf(title, "%s", title_string.c_str());
|
||||
title[size] = 0x00;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
|
||||
goto error;
|
||||
ToArray(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], title, size);
|
||||
ret_cnt += size;
|
||||
delete[] title;
|
||||
if (!write_string(Impl::get_title()))
|
||||
return error();
|
||||
break;
|
||||
}
|
||||
case MsgID:
|
||||
{
|
||||
const auto title_id_string = Impl::get_title_ID();
|
||||
const auto size = title_id_string.size() + 1;
|
||||
char* title_id = new char[size];
|
||||
sprintf(title_id, "%s", title_id_string.c_str());
|
||||
title_id[size] = 0x00;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
|
||||
goto error;
|
||||
ToArray(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], title_id, size);
|
||||
ret_cnt += size;
|
||||
delete[] title_id;
|
||||
if (!write_string(Impl::get_title_ID()))
|
||||
return error();
|
||||
break;
|
||||
}
|
||||
case MsgUUID:
|
||||
{
|
||||
const auto hash_string = Impl::get_executable_hash();
|
||||
const auto size = hash_string.size() + 1;
|
||||
char* hash = new char[size];
|
||||
sprintf(hash, "%s", hash_string.c_str());
|
||||
hash[size] = 0x00;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size + 4, buf_size))
|
||||
goto error;
|
||||
ToArray(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], hash, size);
|
||||
ret_cnt += size;
|
||||
delete[] hash;
|
||||
if (!write_string(Impl::get_executable_hash()))
|
||||
return error();
|
||||
break;
|
||||
}
|
||||
case MsgGameVersion:
|
||||
{
|
||||
const auto game_version_string = Impl::get_app_version();
|
||||
const auto size = game_version_string.size() + 1;
|
||||
char* game_version = new char[size];
|
||||
sprintf(game_version, "%s", game_version_string.c_str());
|
||||
game_version[size] = 0x00;
|
||||
if (!SafetyChecks(buf_cnt, 0, ret_cnt, size, buf_size))
|
||||
goto error;
|
||||
ToArray(ret_buffer, size, ret_cnt);
|
||||
ret_cnt += 4;
|
||||
memcpy(&ret_buffer[ret_cnt], game_version, size);
|
||||
ret_cnt += size;
|
||||
delete[] game_version;
|
||||
if (!write_string(Impl::get_app_version()))
|
||||
return error();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
error:
|
||||
return IPCBuffer{ 5, MakeFailIPC(ret_buffer) };
|
||||
return error();
|
||||
}
|
||||
}
|
||||
}
|
||||
return IPCBuffer{ static_cast<int>(ret_cnt), MakeOkIPC(ret_buffer, ret_cnt) };
|
||||
return IPCBuffer{ ret_cnt, MakeOkIPC(ret_buffer, ret_cnt) };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,26 +335,48 @@ namespace pine
|
||||
* size: size of the IPC buffer.
|
||||
* return value: buffer containing the status code allocated of size
|
||||
*/
|
||||
static inline char* MakeOkIPC(char* ret_buffer, uint32_t size = 5)
|
||||
static inline char* MakeOkIPC(char* ret_buffer, usz size = 5)
|
||||
{
|
||||
ToArray<uint32_t>(ret_buffer, size, 0);
|
||||
ToArray(ret_buffer, ::narrow<u32>(size), 0);
|
||||
ret_buffer[4] = IPC_OK;
|
||||
return ret_buffer;
|
||||
}
|
||||
|
||||
static inline char* MakeFailIPC(char* ret_buffer, uint32_t size = 5)
|
||||
static inline char* MakeFailIPC(char* ret_buffer, usz size = 5)
|
||||
{
|
||||
ToArray<uint32_t>(ret_buffer, size, 0);
|
||||
ToArray(ret_buffer, ::narrow<u32>(size), 0);
|
||||
ret_buffer[4] = IPC_FAIL;
|
||||
return ret_buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an open socket for IPC communication.
|
||||
* return value: -1 if a fatal failure happened, 0 otherwise.
|
||||
* return value: false if a fatal failure happened, true otherwise.
|
||||
*/
|
||||
int StartSocket()
|
||||
bool StartSocket()
|
||||
{
|
||||
::pollfd poll_fd{};
|
||||
|
||||
for (int pending_connection = 0; pending_connection != 1;)
|
||||
{
|
||||
if (thread_ctrl::state() == thread_state::aborting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memset(&poll_fd, 0, sizeof(poll_fd));
|
||||
poll_fd.events = POLLIN;
|
||||
poll_fd.revents = 0;
|
||||
poll_fd.fd = m_sock;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Try to wait for an incoming connection
|
||||
pending_connection = ::WSAPoll(&poll_fd, 1, 10);
|
||||
#else
|
||||
pending_connection = ::poll(&poll_fd, 1, 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_msgsock = accept(m_sock, 0, 0);
|
||||
|
||||
if (m_msgsock == -1)
|
||||
@@ -403,10 +394,10 @@ namespace pine
|
||||
{
|
||||
#endif
|
||||
Impl::error("IPC: An unrecoverable error happened! Shutting down...");
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Thread used to relay IPC commands.
|
||||
@@ -414,10 +405,10 @@ namespace pine
|
||||
{
|
||||
// we allocate once buffers to not have to do mallocs for each IPC
|
||||
// request, as malloc is expansive when we optimize for µs.
|
||||
m_ret_buffer = new char[MAX_IPC_RETURN_SIZE];
|
||||
m_ipc_buffer = new char[MAX_IPC_SIZE];
|
||||
m_ret_buffer.resize(MAX_IPC_RETURN_SIZE);
|
||||
m_ipc_buffer.resize(MAX_IPC_SIZE);
|
||||
|
||||
if (StartSocket() < 0)
|
||||
if (!StartSocket())
|
||||
return;
|
||||
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
@@ -437,7 +428,7 @@ namespace pine
|
||||
if (tmp_length <= 0)
|
||||
{
|
||||
receive_length = 0;
|
||||
if (StartSocket() < 0)
|
||||
if (!StartSocket())
|
||||
return;
|
||||
break;
|
||||
}
|
||||
@@ -447,7 +438,7 @@ namespace pine
|
||||
// if we got at least the final size then update
|
||||
if (end_length == 4 && receive_length >= 4)
|
||||
{
|
||||
end_length = FromArray<u32>(m_ipc_buffer, 0);
|
||||
end_length = FromArray<u32>(m_ipc_buffer.data(), 0);
|
||||
// we'd like to avoid a client trying to do OOB
|
||||
if (end_length > MAX_IPC_SIZE || end_length < 4)
|
||||
{
|
||||
@@ -464,12 +455,12 @@ namespace pine
|
||||
// disconnects
|
||||
if (receive_length != 0)
|
||||
{
|
||||
pine_server::IPCBuffer res = ParseCommand(&m_ipc_buffer[4], m_ret_buffer, static_cast<u32>(end_length) - 4);
|
||||
pine_server::IPCBuffer res = ParseCommand(&m_ipc_buffer[4], m_ret_buffer.data(), static_cast<u32>(end_length) - 4);
|
||||
|
||||
// if we cannot send back our answer restart the socket
|
||||
if (write_portable(m_msgsock, res.buffer, res.size) < 0)
|
||||
{
|
||||
if (StartSocket() < 0)
|
||||
if (!StartSocket())
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -485,9 +476,9 @@ namespace pine
|
||||
* NB: implicitely inlined
|
||||
*/
|
||||
template <typename T>
|
||||
static char* ToArray(char* res_array, T res, int i)
|
||||
static char* ToArray(char* res_array, T res, usz i)
|
||||
{
|
||||
memcpy((res_array + i), reinterpret_cast<char*>(&res), sizeof(T));
|
||||
memcpy(res_array + i, reinterpret_cast<char*>(&res), sizeof(T));
|
||||
return res_array;
|
||||
}
|
||||
|
||||
@@ -508,7 +499,7 @@ namespace pine
|
||||
* Ensures an IPC message isn't too big.
|
||||
* return value: false if checks failed, true otherwise.
|
||||
*/
|
||||
static inline bool SafetyChecks(u32 command_len, int command_size, u32 reply_len, int reply_size = 0, u32 buf_size = MAX_IPC_SIZE - 1)
|
||||
static inline bool SafetyChecks(usz command_len, usz command_size, usz reply_len, usz reply_size = 0, usz buf_size = MAX_IPC_SIZE - 1)
|
||||
{
|
||||
bool res = ((command_len + command_size) > buf_size ||
|
||||
(reply_len + reply_size) >= MAX_IPC_RETURN_SIZE);
|
||||
@@ -614,8 +605,6 @@ namespace pine
|
||||
~pine_server()
|
||||
{
|
||||
Cleanup();
|
||||
delete[] m_ret_buffer;
|
||||
delete[] m_ipc_buffer;
|
||||
}
|
||||
|
||||
}; // class pine_server
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/pugixml updated: dd50fa5b45...a0e0643363
Vendored
+2
-1
@@ -5,9 +5,10 @@ if(USE_SYSTEM_WOLFSSL)
|
||||
target_link_libraries(wolfssl INTERFACE PkgConfig::WolfSSL)
|
||||
else()
|
||||
# TODO(cjj19970505@live.cn)
|
||||
# OPENSSL_EXTRA, WOLFSSL_DES_ECB and HAVE_SNI are unconfigurable from CMake cache.
|
||||
# OPENSSL_EXTRA, and HAVE_SNI are unconfigurable from CMake cache.
|
||||
# but they do have it in a TODO list (wolfssl/CMakeList, 1021)
|
||||
add_compile_definitions(OPENSSL_EXTRA WOLFSSL_DES_ECB HAVE_SNI HAVE_WRITE_DUP)
|
||||
add_compile_definitions(FP_MAX_BITS=8192)
|
||||
|
||||
set(WOLFSSL_TLS13 "no" CACHE INTERNAL "")
|
||||
set(WOLFSSL_SHA224 "yes" CACHE INTERNAL "")
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/wolfssl/wolfssl updated: 57aac1c50b...4fbd4fd36a
Vendored
+1
-1
Submodule 3rdparty/zlib/zlib updated: 21767c654d...04f42ceca4
+3
-3
@@ -11,7 +11,7 @@ Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Bu
|
||||
* [Python 3.6+](https://www.python.org/downloads/) (add to PATH)
|
||||
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
|
||||
* [Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community)
|
||||
* [Vulkan SDK 1.2.198+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
|
||||
* [Vulkan SDK 1.3.224+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
|
||||
|
||||
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.15.2\msvc2019_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2019)**
|
||||
|
||||
@@ -22,8 +22,8 @@ These are the essentials tools to build RPCS3 on Linux. Some of them can be inst
|
||||
* Clang 12+ or GCC 11+
|
||||
* [CMake 3.16.9+](https://www.cmake.org/download/)
|
||||
* [Qt 5.15.2](https://www.qt.io/download-qt-installer)
|
||||
* [Vulkan SDK 1.2.198+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
|
||||
* [SDL2](https://www.libsdl.org/download-2.0.php) (for the FAudio backend)
|
||||
* [Vulkan SDK 1.3.224+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
|
||||
* [SDL2](https://github.com/libsdl-org/SDL/releases) (for the FAudio backend)
|
||||
|
||||
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
|
||||
|
||||
+5
-3
@@ -21,6 +21,8 @@ option(USE_DISCORD_RPC "Discord rich presence integration" OFF)
|
||||
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
|
||||
option(USE_VULKAN "Vulkan render backend" ON)
|
||||
option(USE_PRECOMPILED_HEADERS "Use precompiled headers" OFF)
|
||||
option(USE_SDL "Enables SDL input handler" OFF)
|
||||
option(USE_SYSTEM_SDL "Prefer system SDL instead of the builtin one" OFF)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/buildfiles/cmake")
|
||||
|
||||
@@ -104,9 +106,9 @@ if(WIN32)
|
||||
add_definitions(-D_WIN32_WINNT=0x0602)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
include_directories(/opt/local/include)
|
||||
link_directories(/opt/local/lib)
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
|
||||
include_directories(/opt/homebrew/include)
|
||||
link_directories(/opt/homebrew/lib)
|
||||
endif()
|
||||
|
||||
# Warnings are silenced for 3rdparty code
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
RPCS3
|
||||
=====
|
||||
|
||||
[](https://dev.azure.com/nekotekina/nekotekina/_build?definitionId=4&branchName=master)
|
||||
[&logo=cirrus-ci)](https://cirrus-ci.com/github/RPCS3/rpcs3)
|
||||
[](https://discord.me/rpcs3)
|
||||
[](https://cirrus-ci.com/github/RPCS3/rpcs3)
|
||||
[](https://discord.me/rpcs3)
|
||||
|
||||
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows and Linux.
|
||||
The world's first free and open-source PlayStation 3 emulator/debugger, written in C++ for Windows, Linux, macOS and FreeBSD.
|
||||
|
||||
You can find some basic information on our [**website**](https://rpcs3.net/). Game info is being populated on the [**Wiki**](https://wiki.rpcs3.net/).
|
||||
For discussion about this emulator, PS3 emulation, and game compatibility reports, please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
For discussion about this emulator, PS3 emulation, and game compatibility reports, please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.gg/RPCS3).
|
||||
|
||||
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
|
||||
|
||||
+92
-12
@@ -1,7 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Config.h"
|
||||
#include "util/types.hpp"
|
||||
|
||||
#include "util/yaml.hpp"
|
||||
|
||||
#include <charconv>
|
||||
@@ -60,9 +59,15 @@ std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
|
||||
bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
s64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
int sign = +1;
|
||||
|
||||
@@ -72,7 +77,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
start += 1;
|
||||
}
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
|
||||
{
|
||||
// Limited hex support
|
||||
base = 16;
|
||||
@@ -91,7 +96,7 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max)
|
||||
|
||||
if (result < min || result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_int64('%s'): out of bounds (%d..%d)", value, min, max);
|
||||
if (out) cfg_log.error("cfg::try_to_int64('%s'): out of bounds (val=%d, min=%d, max=%d)", value, result, min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -106,12 +111,18 @@ std::vector<std::string> cfg::make_uint_range(u64 min, u64 max)
|
||||
|
||||
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
if (start[0] == '0' && value.size() >= 2 && (start[1] == 'x' || start[1] == 'X'))
|
||||
{
|
||||
// Limited hex support
|
||||
base = 16;
|
||||
@@ -128,7 +139,7 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||
|
||||
if (result < min || result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_uint64('%s'): out of bounds (%u..%u)", value, min, max);
|
||||
if (out) cfg_log.error("cfg::try_to_uint64('%s'): out of bounds (val=%u, min=%u, max=%u)", value, result, min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,6 +147,63 @@ bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_float_range(f64 min, f64 max)
|
||||
{
|
||||
return {std::to_string(min), std::to_string(max)};
|
||||
}
|
||||
|
||||
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float(): called with an empty string");
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::from_chars float is yet to be implemented on Xcode it seems
|
||||
// And strtod doesn't support ranged view so we need to ensure it meets a null terminator
|
||||
const std::string str = std::string{value};
|
||||
|
||||
char* end_check{};
|
||||
const double result = std::strtod(str.data(), &end_check);
|
||||
|
||||
if (end_check != str.data() + str.size())
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float('%s'): invalid float", value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result < min || result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_float('%s'): out of bounds (val=%f, min=%f, max=%f)", value, result, min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out) *out = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_to_string(std::string* out, const f64& value)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if (out) *out = std::to_string(value);
|
||||
return true;
|
||||
#else
|
||||
std::array<char, 32> str{};
|
||||
|
||||
if (auto [ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), value, std::chars_format::fixed); ec == std::errc())
|
||||
{
|
||||
if (out) *out = std::string(str.data(), ptr);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_string(): could not convert value '%f' to string. error='%s'", value, std::make_error_code(ec).message());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
|
||||
{
|
||||
u64 max = umax;
|
||||
@@ -162,8 +230,8 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
}
|
||||
|
||||
u64 result;
|
||||
const char* start = &value.front();
|
||||
const char* end = &value.back() + 1;
|
||||
const char* start = value.data();
|
||||
const char* end = start + value.size();
|
||||
int base = 10;
|
||||
|
||||
if (start[0] == '0' && (start[1] == 'x' || start[1] == 'X'))
|
||||
@@ -183,7 +251,7 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
|
||||
if (result > max)
|
||||
{
|
||||
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
|
||||
if (out) cfg_log.error("cfg::try_to_enum_value('%s'): out of bounds(val=%u, min=0, max=%u)", value, result, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -511,6 +579,18 @@ void cfg::log_entry::from_default()
|
||||
set_map({});
|
||||
}
|
||||
|
||||
std::pair<u16, u16> cfg::device_info::get_usb_ids() const
|
||||
{
|
||||
auto string_to_hex = [](const std::string& str) -> u16
|
||||
{
|
||||
u16 value = 0x0000;
|
||||
if (!str.empty() && std::from_chars(str.data(), str.data() + str.size(), value, 16).ec != std::errc{})
|
||||
cfg_log.error("Failed to parse hex from string \"%s\"", str);
|
||||
return value;
|
||||
};
|
||||
return {string_to_hex(vid), string_to_hex(pid)};
|
||||
}
|
||||
|
||||
void cfg::device_entry::set_map(map_of_type<device_info>&& map)
|
||||
{
|
||||
m_map = std::move(map);
|
||||
|
||||
+140
-9
@@ -20,6 +20,9 @@ namespace cfg
|
||||
// Format min and max unsigned values
|
||||
std::vector<std::string> make_uint_range(u64 min, u64 max);
|
||||
|
||||
// Format min and max float values
|
||||
std::vector<std::string> make_float_range(f64 min, f64 max);
|
||||
|
||||
// Internal hack
|
||||
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view);
|
||||
|
||||
@@ -77,7 +80,13 @@ namespace cfg
|
||||
// Convert to string (optional)
|
||||
virtual std::string to_string() const
|
||||
{
|
||||
return{};
|
||||
return {};
|
||||
}
|
||||
|
||||
// Convert default to string (optional)
|
||||
virtual std::string def_to_string() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Try to convert from string (optional)
|
||||
@@ -86,7 +95,7 @@ namespace cfg
|
||||
// Get string list (optional)
|
||||
virtual std::vector<std::string> to_list() const
|
||||
{
|
||||
return{};
|
||||
return {};
|
||||
}
|
||||
|
||||
// Set multiple values. Implementation-specific, optional.
|
||||
@@ -160,11 +169,24 @@ namespace cfg
|
||||
return m_value ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
return def ? "true" : "false";
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
if (value == "false")
|
||||
if (value.size() != 4 && value.size() != 5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char copy[5];
|
||||
std::transform(value.begin(), value.end(), std::begin(copy), ::tolower);
|
||||
|
||||
if (value.size() == 5 && std::string_view{copy, 5} == "false")
|
||||
m_value = false;
|
||||
else if (value == "true")
|
||||
else if (value.size() == 4 && std::string_view{copy, 4} == "true")
|
||||
m_value = true;
|
||||
else
|
||||
return false;
|
||||
@@ -221,6 +243,13 @@ namespace cfg
|
||||
return result; // TODO: ???
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
std::string result;
|
||||
fmt_class_string<T>::format(result, fmt_unveil<T>::get(def));
|
||||
return result; // TODO: ???
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
u64 result;
|
||||
@@ -256,8 +285,8 @@ namespace cfg
|
||||
int_type def;
|
||||
|
||||
// Expose range
|
||||
static const s64 max = Max;
|
||||
static const s64 min = Min;
|
||||
static constexpr s64 max = Max;
|
||||
static constexpr s64 min = Min;
|
||||
|
||||
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)), bool dynamic = false)
|
||||
: _base(type::_int, owner, name, dynamic)
|
||||
@@ -286,6 +315,11 @@ namespace cfg
|
||||
return std::to_string(m_value);
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
return std::to_string(def);
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
s64 result;
|
||||
@@ -300,6 +334,7 @@ namespace cfg
|
||||
|
||||
void set(const s64& value)
|
||||
{
|
||||
ensure(value >= Min && value <= Max);
|
||||
m_value = static_cast<int_type>(value);
|
||||
}
|
||||
|
||||
@@ -309,6 +344,90 @@ namespace cfg
|
||||
}
|
||||
};
|
||||
|
||||
// Float entry with custom Min/Max range.
|
||||
template <s32 Min, s32 Max>
|
||||
class _float final : public _base
|
||||
{
|
||||
static_assert(Min < Max, "Invalid cfg::_float range");
|
||||
|
||||
using float_type = f64;
|
||||
atomic_t<float_type> m_value;
|
||||
|
||||
public:
|
||||
float_type def;
|
||||
|
||||
// Expose range
|
||||
static constexpr float_type max = Max;
|
||||
static constexpr float_type min = Min;
|
||||
|
||||
_float(node* owner, const std::string& name, float_type def = std::min<float_type>(Max, std::max<float_type>(Min, 0)), bool dynamic = false)
|
||||
: _base(type::_int, owner, name, dynamic)
|
||||
, m_value(def)
|
||||
, def(def)
|
||||
{
|
||||
}
|
||||
|
||||
operator float_type() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
float_type get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void from_default() override
|
||||
{
|
||||
m_value = def;
|
||||
}
|
||||
|
||||
std::string to_string() const override
|
||||
{
|
||||
std::string result;
|
||||
if (try_to_string(&result, m_value))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return "0.0";
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
std::string result;
|
||||
if (try_to_string(&result, def))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return "0.0";
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
f64 result;
|
||||
if (try_to_float(&result, value, Min, Max))
|
||||
{
|
||||
m_value = static_cast<float_type>(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void set(const f64& value)
|
||||
{
|
||||
ensure(value >= Min && value <= Max);
|
||||
m_value = static_cast<float_type>(value);
|
||||
}
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return make_float_range(Min, Max);
|
||||
}
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
using int32 = _int<s32{smin}, s32{smax}>;
|
||||
|
||||
@@ -330,8 +449,8 @@ namespace cfg
|
||||
int_type def;
|
||||
|
||||
// Expose range
|
||||
static const u64 max = Max;
|
||||
static const u64 min = Min;
|
||||
static constexpr u64 max = Max;
|
||||
static constexpr u64 min = Min;
|
||||
|
||||
uint(node* owner, const std::string& name, int_type def = std::max<int_type>(Min, 0), bool dynamic = false)
|
||||
: _base(type::uint, owner, name, dynamic)
|
||||
@@ -360,6 +479,11 @@ namespace cfg
|
||||
return std::to_string(m_value);
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
return std::to_string(def);
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
u64 result;
|
||||
@@ -374,6 +498,7 @@ namespace cfg
|
||||
|
||||
void set(const u64& value)
|
||||
{
|
||||
ensure(value >= Min && value <= Max);
|
||||
m_value = static_cast<int_type>(value);
|
||||
}
|
||||
|
||||
@@ -431,6 +556,11 @@ namespace cfg
|
||||
return *m_value.load().get();
|
||||
}
|
||||
|
||||
std::string def_to_string() const override
|
||||
{
|
||||
return def;
|
||||
}
|
||||
|
||||
bool from_string(std::string_view value, bool /*dynamic*/ = false) override
|
||||
{
|
||||
m_value = std::string(value);
|
||||
@@ -464,7 +594,7 @@ namespace cfg
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return{ m_set.begin(), m_set.end() };
|
||||
return { m_set.begin(), m_set.end() };
|
||||
}
|
||||
|
||||
bool from_list(std::vector<std::string>&& list) override
|
||||
@@ -529,6 +659,7 @@ namespace cfg
|
||||
std::string serial;
|
||||
std::string vid;
|
||||
std::string pid;
|
||||
std::pair<u16, u16> get_usb_ids() const;
|
||||
};
|
||||
|
||||
class device_entry final : public _base
|
||||
|
||||
+151
-16
@@ -437,6 +437,9 @@ std::string fs::get_parent_dir(std::string_view path, u32 levels)
|
||||
|
||||
bool fs::stat(const std::string& path, stat_t& info)
|
||||
{
|
||||
// Ensure consistent information on failure
|
||||
info = {};
|
||||
|
||||
if (auto device = get_virtual_device(path))
|
||||
{
|
||||
return device->stat(path, info);
|
||||
@@ -1103,10 +1106,12 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
class windows_file final : public file_base
|
||||
{
|
||||
const HANDLE m_handle;
|
||||
atomic_t<u64> m_pos;
|
||||
|
||||
public:
|
||||
windows_file(HANDLE handle)
|
||||
: m_handle(handle)
|
||||
, m_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1162,7 +1167,39 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
|
||||
|
||||
DWORD nread = 0;
|
||||
ensure(ReadFile(m_handle, data, size, &nread, nullptr)); // "file::read"
|
||||
OVERLAPPED ovl{};
|
||||
const u64 pos = m_pos;
|
||||
ovl.Offset = DWORD(pos);
|
||||
ovl.OffsetHigh = DWORD(pos >> 32);
|
||||
ensure(ReadFile(m_handle, data, size, &nread, &ovl) || GetLastError() == ERROR_HANDLE_EOF); // "file::read"
|
||||
nread_sum += nread;
|
||||
m_pos += nread;
|
||||
|
||||
if (nread < size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
count -= size;
|
||||
data += size;
|
||||
}
|
||||
|
||||
return nread_sum;
|
||||
}
|
||||
|
||||
u64 read_at(u64 offset, void* buffer, u64 count) override
|
||||
{
|
||||
u64 nread_sum = 0;
|
||||
|
||||
for (char* data = static_cast<char*>(buffer); count;)
|
||||
{
|
||||
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
|
||||
|
||||
DWORD nread = 0;
|
||||
OVERLAPPED ovl{};
|
||||
ovl.Offset = DWORD(offset);
|
||||
ovl.OffsetHigh = DWORD(offset >> 32);
|
||||
ensure(ReadFile(m_handle, data, size, &nread, &ovl) || GetLastError() == ERROR_HANDLE_EOF); // "file::read"
|
||||
nread_sum += nread;
|
||||
|
||||
if (nread < size)
|
||||
@@ -1172,6 +1209,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
count -= size;
|
||||
data += size;
|
||||
offset += size;
|
||||
}
|
||||
|
||||
return nread_sum;
|
||||
@@ -1186,8 +1224,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
|
||||
|
||||
DWORD nwritten = 0;
|
||||
ensure(WriteFile(m_handle, data, size, &nwritten, nullptr)); // "file::write"
|
||||
OVERLAPPED ovl{};
|
||||
const u64 pos = m_pos;
|
||||
ovl.Offset = DWORD(pos);
|
||||
ovl.OffsetHigh = DWORD(pos >> 32);
|
||||
ensure(WriteFile(m_handle, data, size, &nwritten, &ovl)); // "file::write"
|
||||
nwritten_sum += nwritten;
|
||||
m_pos += nwritten;
|
||||
|
||||
if (nwritten < size)
|
||||
{
|
||||
@@ -1208,20 +1251,19 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
fmt::throw_exception("Invalid whence (0x%x)", whence);
|
||||
}
|
||||
|
||||
LARGE_INTEGER pos;
|
||||
pos.QuadPart = offset;
|
||||
const s64 new_pos =
|
||||
whence == fs::seek_set ? offset :
|
||||
whence == fs::seek_cur ? offset + m_pos :
|
||||
whence == fs::seek_end ? offset + size() : -1;
|
||||
|
||||
const DWORD mode =
|
||||
whence == seek_set ? FILE_BEGIN :
|
||||
whence == seek_cur ? FILE_CURRENT : FILE_END;
|
||||
|
||||
if (!SetFilePointerEx(m_handle, pos, &pos, mode))
|
||||
if (new_pos < 0)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
fs::g_tls_error = fs::error::inval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pos.QuadPart;
|
||||
m_pos = new_pos;
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
u64 size() override
|
||||
@@ -1340,16 +1382,55 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
u64 read(void* buffer, u64 count) override
|
||||
{
|
||||
const auto result = ::read(m_fd, buffer, count);
|
||||
ensure(result != -1); // "file::read"
|
||||
u64 result = 0;
|
||||
|
||||
// Loop because (huge?) read can be processed partially
|
||||
while (auto r = ::read(m_fd, buffer, count))
|
||||
{
|
||||
ensure(r > 0); // "file::read"
|
||||
count -= r;
|
||||
result += r;
|
||||
buffer = static_cast<u8*>(buffer) + r;
|
||||
if (!count)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u64 read_at(u64 offset, void* buffer, u64 count) override
|
||||
{
|
||||
u64 result = 0;
|
||||
|
||||
// For safety; see read()
|
||||
while (auto r = ::pread(m_fd, buffer, count, offset))
|
||||
{
|
||||
ensure(r > 0); // "file::read_at"
|
||||
count -= r;
|
||||
offset += r;
|
||||
result += r;
|
||||
buffer = static_cast<u8*>(buffer) + r;
|
||||
if (!count)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u64 write(const void* buffer, u64 count) override
|
||||
{
|
||||
const auto result = ::write(m_fd, buffer, count);
|
||||
ensure(result != -1); // "file::write"
|
||||
u64 result = 0;
|
||||
|
||||
// For safety; see read()
|
||||
while (auto r = ::write(m_fd, buffer, count))
|
||||
{
|
||||
ensure(r > 0); // "file::write"
|
||||
count -= r;
|
||||
result += r;
|
||||
buffer = static_cast<const u8*>(buffer) + r;
|
||||
if (!count)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1463,6 +1544,21 @@ fs::file::file(const void* ptr, usz size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 read_at(u64 offset, void* buffer, u64 count) override
|
||||
{
|
||||
if (offset < m_size)
|
||||
{
|
||||
// Get readable size
|
||||
if (const u64 result = std::min<u64>(count, m_size - offset))
|
||||
{
|
||||
std::memcpy(buffer, m_ptr + offset, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 write(const void*, u64) override
|
||||
{
|
||||
return 0;
|
||||
@@ -1828,7 +1924,7 @@ bool fs::remove_all(const std::string& path, bool remove_root, bool is_no_dir_ok
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
|
||||
u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment, atomic_t<bool>* cancel_flag)
|
||||
{
|
||||
u64 result = 0;
|
||||
|
||||
@@ -1841,6 +1937,11 @@ u64 fs::get_dir_size(const std::string& path, u64 rounding_alignment)
|
||||
|
||||
for (const auto& entry : root_dir)
|
||||
{
|
||||
if (cancel_flag && *cancel_flag)
|
||||
{
|
||||
return umax;
|
||||
}
|
||||
|
||||
if (entry.name == "." || entry.name == "..")
|
||||
{
|
||||
continue;
|
||||
@@ -1948,6 +2049,40 @@ fs::file fs::make_gather(std::vector<fs::file> files)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 read_at(u64 start, void* buffer, u64 size) override
|
||||
{
|
||||
if (start < end)
|
||||
{
|
||||
u64 pos = start;
|
||||
|
||||
// Get readable size
|
||||
if (const u64 max = std::min<u64>(size, end - pos))
|
||||
{
|
||||
u8* buf_out = static_cast<u8*>(buffer);
|
||||
u64 buf_max = max;
|
||||
|
||||
for (auto it = ends.upper_bound(pos); it != ends.end(); ++it)
|
||||
{
|
||||
const u64 count = std::min<u64>(it->first - pos, buf_max);
|
||||
const u64 read = files[it->second].read_at(files[it->second].size() + pos - it->first, buf_out, count);
|
||||
|
||||
buf_out += count;
|
||||
buf_max -= count;
|
||||
pos += read;
|
||||
|
||||
if (read < count || buf_max == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pos - start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 write(const void*, u64) override
|
||||
{
|
||||
return 0;
|
||||
|
||||
+34
-3
@@ -74,7 +74,7 @@ namespace fs
|
||||
|
||||
using enable_bitcopy = std::true_type;
|
||||
|
||||
constexpr bool operator==(const stat_t&) const = default;
|
||||
constexpr bool operator==(const stat_t&) const = default;
|
||||
};
|
||||
|
||||
// Helper, layout is equal to iovec struct
|
||||
@@ -93,6 +93,7 @@ namespace fs
|
||||
virtual void sync();
|
||||
virtual bool trunc(u64 length) = 0;
|
||||
virtual u64 read(void* buffer, u64 size) = 0;
|
||||
virtual u64 read_at(u64 offset, void* buffer, u64 size) = 0;
|
||||
virtual u64 write(const void* buffer, u64 size) = 0;
|
||||
virtual u64 seek(s64 offset, seek_mode whence) = 0;
|
||||
virtual u64 size() = 0;
|
||||
@@ -301,6 +302,17 @@ namespace fs
|
||||
return m_file->read(buffer, count);
|
||||
}
|
||||
|
||||
// Read the data from the file at specified offset in thread-safe manner
|
||||
u64 read_at(u64 offset, void* buffer, u64 count,
|
||||
u32 line = __builtin_LINE(),
|
||||
u32 col = __builtin_COLUMN(),
|
||||
const char* file = __builtin_FILE(),
|
||||
const char* func = __builtin_FUNCTION()) const
|
||||
{
|
||||
if (!m_file) xnull({line, col, file, func});
|
||||
return m_file->read_at(offset, buffer, count);
|
||||
}
|
||||
|
||||
// Write the data to the file and return the amount of data actually written
|
||||
u64 write(const void* buffer, u64 count,
|
||||
u32 line = __builtin_LINE(),
|
||||
@@ -657,7 +669,7 @@ namespace fs
|
||||
bool remove_all(const std::string& path, bool remove_root = true, bool is_no_dir_ok = false);
|
||||
|
||||
// Get size of all files recursively
|
||||
u64 get_dir_size(const std::string& path, u64 rounding_alignment = 1);
|
||||
u64 get_dir_size(const std::string& path, u64 rounding_alignment = 1, atomic_t<bool>* cancel_flag = nullptr);
|
||||
|
||||
enum class error : uint
|
||||
{
|
||||
@@ -724,6 +736,24 @@ namespace fs
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 read_at(u64 offset, void* buffer, u64 size) override
|
||||
{
|
||||
const u64 end = obj.size();
|
||||
|
||||
if (offset < end)
|
||||
{
|
||||
// Get readable size
|
||||
if (const u64 max = std::min<u64>(size, end - offset))
|
||||
{
|
||||
std::copy(obj.cbegin() + offset, obj.cbegin() + offset + max, static_cast<value_type*>(buffer));
|
||||
update_time();
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 write(const void* buffer, u64 size) override
|
||||
{
|
||||
const u64 old_size = obj.size();
|
||||
@@ -793,7 +823,8 @@ namespace fs
|
||||
|
||||
if (write)
|
||||
{
|
||||
m_stat.mtime = std::max(m_stat.atime, ++m_stat.mtime);
|
||||
m_stat.mtime++;
|
||||
m_stat.mtime = std::max(m_stat.atime, m_stat.mtime);
|
||||
m_stat.ctime = m_stat.mtime;
|
||||
}
|
||||
}
|
||||
|
||||
+143
-83
@@ -20,6 +20,34 @@ LOG_CHANNEL(jit_log, "JIT");
|
||||
|
||||
void jit_announce(uptr func, usz size, std::string_view name)
|
||||
{
|
||||
#ifdef __linux__
|
||||
static const struct tmp_perf_map
|
||||
{
|
||||
std::string name{fmt::format("/tmp/perf-%d.map", getpid())};
|
||||
fs::file data{name, fs::rewrite + fs::append};
|
||||
|
||||
tmp_perf_map() = default;
|
||||
tmp_perf_map(const tmp_perf_map&) = delete;
|
||||
tmp_perf_map& operator=(const tmp_perf_map&) = delete;
|
||||
|
||||
~tmp_perf_map()
|
||||
{
|
||||
fs::remove_file(name);
|
||||
}
|
||||
} s_map;
|
||||
|
||||
if (size && name.size())
|
||||
{
|
||||
s_map.data.write(fmt::format("%x %x %s\n", func, size, name));
|
||||
}
|
||||
|
||||
if (!func && !size && !name.size())
|
||||
{
|
||||
fs::remove_file(s_map.name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!size)
|
||||
{
|
||||
jit_log.error("Empty function announced: %s (%p)", name, func);
|
||||
@@ -83,12 +111,6 @@ void jit_announce(uptr func, usz size, std::string_view name)
|
||||
dump.write(reinterpret_cast<uchar*>(func), size);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static const fs::file s_map(fmt::format("/tmp/perf-%d.map", getpid()), fs::rewrite + fs::append);
|
||||
|
||||
s_map.write(fmt::format("%x %x %s\n", func, size, name));
|
||||
#endif
|
||||
}
|
||||
|
||||
static u8* get_jit_memory()
|
||||
@@ -357,7 +379,7 @@ asmjit::inline_runtime::~inline_runtime()
|
||||
asmjit::simd_builder::simd_builder(CodeHolder* ch) noexcept
|
||||
: native_asm(ch)
|
||||
{
|
||||
_init(true);
|
||||
_init(0);
|
||||
consts[~v128()] = this->newLabel();
|
||||
}
|
||||
|
||||
@@ -365,9 +387,9 @@ asmjit::simd_builder::~simd_builder()
|
||||
{
|
||||
}
|
||||
|
||||
void asmjit::simd_builder::_init(bool full)
|
||||
void asmjit::simd_builder::_init(uint new_vsize)
|
||||
{
|
||||
if (full && utils::has_avx512_icl())
|
||||
if ((!new_vsize && utils::has_avx512_icl()) || new_vsize == 64)
|
||||
{
|
||||
v0 = x86::zmm0;
|
||||
v1 = x86::zmm1;
|
||||
@@ -377,7 +399,7 @@ void asmjit::simd_builder::_init(bool full)
|
||||
v5 = x86::zmm5;
|
||||
vsize = 64;
|
||||
}
|
||||
else if (full && utils::has_avx2())
|
||||
else if ((!new_vsize && utils::has_avx2()) || new_vsize == 32)
|
||||
{
|
||||
v0 = x86::ymm0;
|
||||
v1 = x86::ymm1;
|
||||
@@ -395,12 +417,13 @@ void asmjit::simd_builder::_init(bool full)
|
||||
v3 = x86::xmm3;
|
||||
v4 = x86::xmm4;
|
||||
v5 = x86::xmm5;
|
||||
vsize = 16;
|
||||
vsize = new_vsize ? new_vsize : 16;
|
||||
}
|
||||
|
||||
if (full && utils::has_avx512())
|
||||
if (utils::has_avx512())
|
||||
{
|
||||
vmask = -1;
|
||||
if (!new_vsize)
|
||||
vmask = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -480,6 +503,10 @@ void asmjit::simd_builder::vec_clobbering_test(u32 esize, const Operand& v, cons
|
||||
{
|
||||
this->emit(x86::Inst::kIdVptest, v, rhs);
|
||||
}
|
||||
else if (esize == 16 && utils::has_avx())
|
||||
{
|
||||
this->emit(x86::Inst::kIdVptest, v, rhs);
|
||||
}
|
||||
else if (esize == 16 && utils::has_sse41())
|
||||
{
|
||||
this->emit(x86::Inst::kIdPtest, v, rhs);
|
||||
@@ -504,6 +531,54 @@ void asmjit::simd_builder::vec_clobbering_test(u32 esize, const Operand& v, cons
|
||||
}
|
||||
}
|
||||
|
||||
void asmjit::simd_builder::vec_broadcast_gpr(u32 esize, const Operand& v, const x86::Gp& r)
|
||||
{
|
||||
if (esize == 2)
|
||||
{
|
||||
if (utils::has_avx512())
|
||||
this->emit(x86::Inst::kIdVpbroadcastw, v, r.r32());
|
||||
else if (utils::has_avx())
|
||||
{
|
||||
this->emit(x86::Inst::kIdVmovd, v, r.r32());
|
||||
if (utils::has_avx2())
|
||||
this->emit(x86::Inst::kIdVpbroadcastw, v, v);
|
||||
else
|
||||
{
|
||||
this->emit(x86::Inst::kIdVpunpcklwd, v, v, v);
|
||||
this->emit(x86::Inst::kIdVpshufd, v, v, Imm(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->emit(x86::Inst::kIdMovd, v, r.r32());
|
||||
this->emit(x86::Inst::kIdPunpcklwd, v, v);
|
||||
this->emit(x86::Inst::kIdPshufd, v, v, Imm(0));
|
||||
}
|
||||
}
|
||||
else if (esize == 4)
|
||||
{
|
||||
if (utils::has_avx512())
|
||||
this->emit(x86::Inst::kIdVpbroadcastd, v, r.r32());
|
||||
else if (utils::has_avx())
|
||||
{
|
||||
this->emit(x86::Inst::kIdVmovd, v, r.r32());
|
||||
if (utils::has_avx2())
|
||||
this->emit(x86::Inst::kIdVpbroadcastd, v, v);
|
||||
else
|
||||
this->emit(x86::Inst::kIdVpshufd, v, v, Imm(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->emit(x86::Inst::kIdMovd, v, r.r32());
|
||||
this->emit(x86::Inst::kIdPshufd, v, v, Imm(0));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::throw_exception("Unimplemented");
|
||||
}
|
||||
}
|
||||
|
||||
asmjit::x86::Mem asmjit::simd_builder::ptr_scale_for_vec(u32 esize, const x86::Gp& base, const x86::Gp& index)
|
||||
{
|
||||
switch (ensure(esize))
|
||||
@@ -530,7 +605,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
|
||||
this->emit(x86::Inst::kIdVpinsrw, x86::Xmm(v.id()), x86::Xmm(v.id()), src, Imm(0));
|
||||
else if (vsize == 2)
|
||||
this->emit(x86::Inst::kIdPinsrw, v, src, Imm(0));
|
||||
else if (vmask && vmask < 8)
|
||||
else if ((vmask && vmask < 8) || vsize >= 64)
|
||||
this->emit(x86::Inst::kIdVmovdqu16, v, src);
|
||||
else
|
||||
return vec_load_unaligned(vsize, v, src);
|
||||
@@ -542,7 +617,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
|
||||
this->emit(x86::Inst::kIdVmovd, x86::Xmm(v.id()), src);
|
||||
else if (vsize == 4)
|
||||
this->emit(x86::Inst::kIdMovd, v, src);
|
||||
else if (vmask && vmask < 8)
|
||||
else if ((vmask && vmask < 8) || vsize >= 64)
|
||||
this->emit(x86::Inst::kIdVmovdqu32, v, src);
|
||||
else
|
||||
return vec_load_unaligned(vsize, v, src);
|
||||
@@ -554,7 +629,7 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
|
||||
this->emit(x86::Inst::kIdVmovq, x86::Xmm(v.id()), src);
|
||||
else if (vsize == 8)
|
||||
this->emit(x86::Inst::kIdMovq, v, src);
|
||||
else if (vmask && vmask < 8)
|
||||
else if ((vmask && vmask < 8) || vsize >= 64)
|
||||
this->emit(x86::Inst::kIdVmovdqu64, v, src);
|
||||
else
|
||||
return vec_load_unaligned(vsize, v, src);
|
||||
@@ -562,7 +637,9 @@ void asmjit::simd_builder::vec_load_unaligned(u32 esize, const Operand& v, const
|
||||
else if (esize >= 16)
|
||||
{
|
||||
ensure(vsize >= 16);
|
||||
if (utils::has_avx())
|
||||
if ((vmask && vmask < 8) || vsize >= 64)
|
||||
this->emit(x86::Inst::kIdVmovdqu64, v, src); // Not really needed
|
||||
else if (utils::has_avx())
|
||||
this->emit(x86::Inst::kIdVmovdqu, v, src);
|
||||
else
|
||||
this->emit(x86::Inst::kIdMovups, v, src);
|
||||
@@ -636,7 +713,7 @@ void asmjit::simd_builder::_vec_binary_op(x86::Inst::Id sse_op, x86::Inst::Id ve
|
||||
{
|
||||
if (utils::has_avx())
|
||||
{
|
||||
if (vex_op == x86::Inst::kIdNone || this->_extraReg.isReg())
|
||||
if (evex_op != x86::Inst::kIdNone && (vex_op == x86::Inst::kIdNone || this->_extraReg.isReg() || vsize >= 64))
|
||||
{
|
||||
this->evex().emit(evex_op, dst, lhs, rhs);
|
||||
}
|
||||
@@ -694,40 +771,31 @@ void asmjit::simd_builder::vec_umax(u32 esize, const Operand& dst, const Operand
|
||||
fmt::throw_exception("Unimplemented");
|
||||
}
|
||||
|
||||
void asmjit::simd_builder::vec_umin_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp)
|
||||
void asmjit::simd_builder::vec_cmp_eq(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs)
|
||||
{
|
||||
using enum x86::Inst::Id;
|
||||
if (!utils::has_sse41())
|
||||
{
|
||||
fmt::throw_exception("Unimplemented");
|
||||
}
|
||||
|
||||
ensure(src != tmp);
|
||||
|
||||
if (esize == 2)
|
||||
{
|
||||
this->emit(utils::has_avx() ? kIdVphminposuw : kIdPhminposuw, x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->emit(utils::has_avx() ? kIdVpextrw : kIdPextrw, dst, x86::Xmm(tmp.id()), Imm(0));
|
||||
}
|
||||
else if (esize == 4)
|
||||
{
|
||||
if (utils::has_avx())
|
||||
if (vsize == 64)
|
||||
{
|
||||
this->vpsrldq(x86::Xmm(tmp.id()), x86::Xmm(src.id()), 8);
|
||||
this->vpminud(x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->vpsrldq(x86::Xmm(src.id()), x86::Xmm(tmp.id()), 4);
|
||||
this->vpminud(x86::Xmm(src.id()), x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->vmovd(dst.r32(), x86::Xmm(src.id()));
|
||||
this->evex().emit(kIdVpcmpeqw, x86::k0, lhs, rhs);
|
||||
this->evex().emit(kIdVpmovm2w, dst, x86::k0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->movdqa(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->psrldq(x86::Xmm(tmp.id()), 8);
|
||||
this->pminud(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->movdqa(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->psrldq(x86::Xmm(src.id()), 4);
|
||||
this->pminud(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->movd(dst.r32(), x86::Xmm(src.id()));
|
||||
_vec_binary_op(kIdPcmpeqw, kIdVpcmpeqw, kIdNone, dst, lhs, rhs);
|
||||
}
|
||||
}
|
||||
else if (esize == 4)
|
||||
{
|
||||
if (vsize == 64)
|
||||
{
|
||||
this->evex().emit(kIdVpcmpeqd, x86::k0, lhs, rhs);
|
||||
this->evex().emit(kIdVpmovm2d, dst, x86::k0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vec_binary_op(kIdPcmpeqw, kIdVpcmpeqw, kIdNone, dst, lhs, rhs);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -736,50 +804,42 @@ void asmjit::simd_builder::vec_umin_horizontal_i128(u32 esize, const x86::Gp& ds
|
||||
}
|
||||
}
|
||||
|
||||
void asmjit::simd_builder::vec_umax_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp)
|
||||
void asmjit::simd_builder::vec_extract_high(u32, const Operand& dst, const Operand& src)
|
||||
{
|
||||
using enum x86::Inst::Id;
|
||||
if (!utils::has_sse41())
|
||||
{
|
||||
fmt::throw_exception("Unimplemented");
|
||||
}
|
||||
|
||||
ensure(src != tmp);
|
||||
|
||||
if (esize == 2)
|
||||
{
|
||||
vec_set_all_ones(x86::Xmm(tmp.id()));
|
||||
vec_xor(esize, x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->emit(utils::has_avx() ? kIdVphminposuw : kIdPhminposuw, x86::Xmm(tmp.id()), x86::Xmm(tmp.id()));
|
||||
this->emit(utils::has_avx() ? kIdVpextrw : kIdPextrw, dst, x86::Xmm(tmp.id()), Imm(0));
|
||||
this->not_(dst.r16());
|
||||
}
|
||||
else if (esize == 4)
|
||||
{
|
||||
if (utils::has_avx())
|
||||
{
|
||||
this->vpsrldq(x86::Xmm(tmp.id()), x86::Xmm(src.id()), 8);
|
||||
this->vpmaxud(x86::Xmm(tmp.id()), x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->vpsrldq(x86::Xmm(src.id()), x86::Xmm(tmp.id()), 4);
|
||||
this->vpmaxud(x86::Xmm(src.id()), x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->vmovd(dst.r32(), x86::Xmm(src.id()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->movdqa(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->psrldq(x86::Xmm(tmp.id()), 8);
|
||||
this->pmaxud(x86::Xmm(tmp.id()), x86::Xmm(src.id()));
|
||||
this->movdqa(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->psrldq(x86::Xmm(src.id()), 4);
|
||||
this->pmaxud(x86::Xmm(src.id()), x86::Xmm(tmp.id()));
|
||||
this->movd(dst.r32(), x86::Xmm(src.id()));
|
||||
}
|
||||
}
|
||||
if (vsize == 32)
|
||||
this->vextracti32x8(x86::Ymm(dst.id()), x86::Zmm(src.id()), 1);
|
||||
else if (vsize == 16)
|
||||
this->vextracti128(x86::Xmm(dst.id()), x86::Ymm(src.id()), 1);
|
||||
else
|
||||
{
|
||||
fmt::throw_exception("Unimplemented");
|
||||
if (utils::has_avx())
|
||||
this->vpsrldq(x86::Xmm(dst.id()), x86::Xmm(src.id()), vsize);
|
||||
else
|
||||
{
|
||||
this->movdqa(x86::Xmm(dst.id()), x86::Xmm(src.id()));
|
||||
this->psrldq(x86::Xmm(dst.id()), vsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void asmjit::simd_builder::vec_extract_gpr(u32 esize, const x86::Gp& dst, const Operand& src)
|
||||
{
|
||||
if (esize == 8 && utils::has_avx())
|
||||
this->vmovq(dst.r64(), x86::Xmm(src.id()));
|
||||
else if (esize == 8)
|
||||
this->movq(dst.r64(), x86::Xmm(src.id()));
|
||||
else if (esize == 4 && utils::has_avx())
|
||||
this->vmovd(dst.r32(), x86::Xmm(src.id()));
|
||||
else if (esize == 4)
|
||||
this->movd(dst.r32(), x86::Xmm(src.id()));
|
||||
else if (esize == 2 && utils::has_avx())
|
||||
this->vpextrw(dst.r32(), x86::Xmm(src.id()), 0);
|
||||
else if (esize == 2)
|
||||
this->pextrw(dst.r32(), x86::Xmm(src.id()), 0);
|
||||
else
|
||||
fmt::throw_exception("Unimplemented");
|
||||
}
|
||||
|
||||
#endif /* X86 */
|
||||
|
||||
#ifdef LLVM_AVAILABLE
|
||||
|
||||
+74
-28
@@ -226,12 +226,13 @@ namespace asmjit
|
||||
|
||||
void operator()() noexcept;
|
||||
|
||||
void _init(bool full);
|
||||
void _init(uint new_vsize = 0);
|
||||
void vec_cleanup_ret();
|
||||
void vec_set_all_zeros(const Operand& v);
|
||||
void vec_set_all_ones(const Operand& v);
|
||||
void vec_set_const(const Operand& v, const v128& value);
|
||||
void vec_clobbering_test(u32 esize, const Operand& v, const Operand& rhs);
|
||||
void vec_broadcast_gpr(u32 esize, const Operand& v, const x86::Gp& r);
|
||||
|
||||
// return x86::ptr(base, ctr, X, 0) where X is set for esize accordingly
|
||||
x86::Mem ptr_scale_for_vec(u32 esize, const x86::Gp& base, const x86::Gp& index);
|
||||
@@ -260,11 +261,18 @@ namespace asmjit
|
||||
_vec_binary_op(kIdPor, kIdVpor, kIdVpord, dst, lhs, rhs);
|
||||
}
|
||||
|
||||
void vec_andn(u32, const Operand& dst, const Operand& lhs, const Operand& rhs)
|
||||
{
|
||||
using enum x86::Inst::Id;
|
||||
_vec_binary_op(kIdPandn, kIdVpandn, kIdVpandnd, dst, lhs, rhs);
|
||||
}
|
||||
|
||||
void vec_umin(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
|
||||
void vec_umax(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
|
||||
void vec_cmp_eq(u32 esize, const Operand& dst, const Operand& lhs, const Operand& rhs);
|
||||
|
||||
void vec_umin_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp);
|
||||
void vec_umax_horizontal_i128(u32 esize, const x86::Gp& dst, const Operand& src, const Operand& tmp);
|
||||
void vec_extract_high(u32 esize, const Operand& dst, const Operand& src);
|
||||
void vec_extract_gpr(u32 esize, const x86::Gp& dst, const Operand& src);
|
||||
|
||||
simd_builder& keep_if_not_masked()
|
||||
{
|
||||
@@ -287,7 +295,7 @@ namespace asmjit
|
||||
return *this;
|
||||
}
|
||||
|
||||
void build_loop(u32 esize, auto reg_ctr, auto reg_cnt, auto&& build, auto&& reduce)
|
||||
void build_loop(u32 esize, const x86::Gp& reg_ctr, const x86::Gp& reg_cnt, auto&& build, auto&& reduce)
|
||||
{
|
||||
ensure((esize & (esize - 1)) == 0);
|
||||
ensure(esize <= vsize);
|
||||
@@ -299,47 +307,85 @@ namespace asmjit
|
||||
const u32 step = vsize / esize;
|
||||
|
||||
this->xor_(reg_ctr.r32(), reg_ctr.r32()); // Reset counter reg
|
||||
this->sub(reg_cnt, step);
|
||||
this->cmp(reg_cnt, step);
|
||||
this->jb(next); // If count < step, skip main loop body
|
||||
this->align(AlignMode::kCode, 16);
|
||||
this->bind(body);
|
||||
this->sub(reg_cnt, step);
|
||||
build();
|
||||
this->add(reg_ctr, step);
|
||||
this->sub(reg_cnt, step);
|
||||
this->ja(body);
|
||||
this->cmp(reg_cnt, step);
|
||||
this->jae(body);
|
||||
this->bind(next);
|
||||
if (!vmask)
|
||||
reduce();
|
||||
this->add(reg_cnt, step);
|
||||
this->jz(exit);
|
||||
|
||||
if (vmask)
|
||||
{
|
||||
// Build single last iteration (masked)
|
||||
this->bzhi(reg_cnt, x86::Mem(consts[~u128()], 0), reg_cnt);
|
||||
this->kmovq(x86::k7, reg_cnt);
|
||||
this->test(reg_cnt, reg_cnt);
|
||||
this->jz(exit);
|
||||
|
||||
if (esize == 1 && vsize == 64)
|
||||
{
|
||||
this->bzhi(reg_cnt.r64(), x86::Mem(consts[~u128()], 0), reg_cnt.r64());
|
||||
this->kmovq(x86::k7, reg_cnt.r64());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->bzhi(reg_cnt.r32(), x86::Mem(consts[~u128()], 0), reg_cnt.r32());
|
||||
this->kmovd(x86::k7, reg_cnt.r32());
|
||||
}
|
||||
|
||||
vmask = 7;
|
||||
build();
|
||||
vmask = -1;
|
||||
reduce();
|
||||
|
||||
// Rollout reduction step
|
||||
this->bind(exit);
|
||||
while (true)
|
||||
{
|
||||
vsize /= 2;
|
||||
if (vsize < esize)
|
||||
break;
|
||||
this->_init(vsize);
|
||||
reduce();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build tail loop (reduced vector width)
|
||||
Label body = this->newLabel();
|
||||
this->align(AlignMode::kCode, 16);
|
||||
this->bind(body);
|
||||
const uint vsz = vsize / step;
|
||||
this->_init(false);
|
||||
vsize = vsz;
|
||||
build();
|
||||
this->_init(true);
|
||||
this->inc(reg_ctr);
|
||||
this->sub(reg_cnt, 1);
|
||||
this->ja(body);
|
||||
// Build unrolled loop tail (reduced vector width)
|
||||
while (true)
|
||||
{
|
||||
vsize /= 2;
|
||||
if (vsize < esize)
|
||||
break;
|
||||
|
||||
// Shall not clobber flags
|
||||
this->_init(vsize);
|
||||
reduce();
|
||||
|
||||
if (vsize == esize)
|
||||
{
|
||||
// Last "iteration"
|
||||
this->test(reg_cnt, reg_cnt);
|
||||
this->jz(exit);
|
||||
build();
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 step = vsize / esize;
|
||||
Label next = this->newLabel();
|
||||
this->cmp(reg_cnt, step);
|
||||
this->jb(next);
|
||||
build();
|
||||
this->add(reg_ctr, step);
|
||||
this->sub(reg_cnt, step);
|
||||
this->bind(next);
|
||||
}
|
||||
}
|
||||
|
||||
this->bind(exit);
|
||||
}
|
||||
|
||||
this->bind(exit);
|
||||
this->_init(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,12 @@ std::string utf16_to_utf8(std::u16string_view src)
|
||||
return converter.to_bytes(src.data());
|
||||
}
|
||||
|
||||
std::u16string utf8_to_utf16(std::string_view src)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter{};
|
||||
return converter.from_bytes(src.data());
|
||||
}
|
||||
|
||||
std::wstring utf8_to_wchar(std::string_view src)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -449,7 +455,7 @@ struct fmt::cfmt_src
|
||||
{
|
||||
// Hack: use known function pointers to determine type
|
||||
#define TYPE(type) \
|
||||
if (sup[extra].fmt_string == &fmt_class_string<type>::format) return sizeof(type);
|
||||
if (sup[extra].fmt_string == &fmt_class_string<type>::format) return sizeof(type);
|
||||
|
||||
TYPE(int);
|
||||
TYPE(llong);
|
||||
@@ -457,10 +463,11 @@ struct fmt::cfmt_src
|
||||
TYPE(short);
|
||||
if (std::is_signed<char>::value) TYPE(char);
|
||||
TYPE(long);
|
||||
TYPE(u128);
|
||||
TYPE(s128);
|
||||
|
||||
#undef TYPE
|
||||
if (sup[extra].fmt_string == &fmt_class_string<u128>::format)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -237,6 +237,29 @@ struct fmt_class_string<wchar_t*, void> : fmt_class_string<const wchar_t*>
|
||||
{
|
||||
};
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
template <typename T>
|
||||
concept StringConvertible = requires (T & t)
|
||||
{
|
||||
{ t.to_string() } -> std::convertible_to<std::string>;
|
||||
};
|
||||
}
|
||||
|
||||
template <fmt::StringConvertible T>
|
||||
struct fmt_class_string<T, void>
|
||||
{
|
||||
static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg)
|
||||
{
|
||||
return *reinterpret_cast<const T*>(static_cast<uptr>(arg));
|
||||
}
|
||||
|
||||
static void format(std::string& out, u64 arg)
|
||||
{
|
||||
out += get_object(arg).to_string();
|
||||
}
|
||||
};
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
// Both uchar and std::byte are allowed
|
||||
|
||||
+8
-1
@@ -11,12 +11,13 @@
|
||||
std::wstring utf8_to_wchar(std::string_view src);
|
||||
std::string wchar_to_utf8(std::wstring_view src);
|
||||
std::string utf16_to_utf8(std::u16string_view src);
|
||||
std::u16string utf8_to_utf16(std::string_view src);
|
||||
|
||||
// Copy null-terminated string from a std::string or a char array to a char array with truncation
|
||||
template <typename D, typename T>
|
||||
inline void strcpy_trunc(D& dst, const T& src)
|
||||
{
|
||||
const usz count = std::size(src) >= std::size(dst) ? std::size(dst) - 1 : std::size(src);
|
||||
const usz count = std::size(src) >= std::size(dst) ? std::max<usz>(std::size(dst), 1) - 1 : std::size(src);
|
||||
std::memcpy(std::data(dst), std::data(src), count);
|
||||
std::memset(std::data(dst) + count, 0, std::size(dst) - count);
|
||||
}
|
||||
@@ -27,6 +28,12 @@ bool try_to_int64(s64* out, std::string_view value, s64 min, s64 max);
|
||||
// Convert string to unsigned integer
|
||||
bool try_to_uint64(u64* out, std::string_view value, u64 min, u64 max);
|
||||
|
||||
// Convert string to float
|
||||
bool try_to_float(f64* out, std::string_view value, f64 min, f64 max);
|
||||
|
||||
// Convert float to string locale independent
|
||||
bool try_to_string(std::string* out, const f64& value);
|
||||
|
||||
// Get the file extension of a file path ("png", "jpg", etc.)
|
||||
std::string get_file_extension(const std::string& file_path);
|
||||
|
||||
|
||||
+16
-14
@@ -16,7 +16,9 @@
|
||||
#include <process.h>
|
||||
#include <sysinfoapi.h>
|
||||
#else
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#define _XOPEN_SOURCE
|
||||
#define __USE_GNU
|
||||
@@ -94,27 +96,21 @@ thread_local bool g_tls_access_violation_recovered = false;
|
||||
extern thread_local std::string(*g_tls_log_prefix)();
|
||||
|
||||
// Report error and call std::abort(), defined in main.cpp
|
||||
[[noreturn]] void report_fatal_error(std::string_view);
|
||||
[[noreturn]] void report_fatal_error(std::string_view text, bool is_html = false, bool include_help_text = true);
|
||||
|
||||
std::string dump_useful_thread_info()
|
||||
{
|
||||
thread_local volatile bool guard = false;
|
||||
|
||||
std::string result;
|
||||
|
||||
// In case the dumping function was the cause for the exception/access violation
|
||||
// Avoid recursion
|
||||
if (std::exchange(guard, true))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (auto cpu = get_current_cpu_thread())
|
||||
{
|
||||
cpu->dump_all(result);
|
||||
// Wrap it to disable some internal exceptions when printing (not thrown on main thread)
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
cpu->dump_all(result);
|
||||
});
|
||||
}
|
||||
|
||||
guard = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1800,7 +1796,7 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
|
||||
const bool is_executing = err & 0x10;
|
||||
const bool is_writing = err & 0x2;
|
||||
#elif defined(ARCH_ARM64)
|
||||
const bool is_executing = uptr(info->si_addr) == RIP(context);
|
||||
const bool is_executing = uptr(info->si_addr) == uptr(RIP(context));
|
||||
const u32 insn = is_executing ? 0 : *reinterpret_cast<u32*>(RIP(context));
|
||||
const bool is_writing = (insn & 0xbfff0000) == 0x0c000000
|
||||
|| (insn & 0xbfe00000) == 0x0c800000
|
||||
@@ -1925,7 +1921,10 @@ const bool s_terminate_handler_set = []() -> bool
|
||||
std::set_terminate([]()
|
||||
{
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
logs::listener::sync_all();
|
||||
utils::trap();
|
||||
}
|
||||
|
||||
report_fatal_error("RPCS3 has abnormally terminated.");
|
||||
});
|
||||
@@ -2063,7 +2062,7 @@ void thread_base::set_name(std::string name)
|
||||
u64 thread_base::finalize(thread_state result_state) noexcept
|
||||
{
|
||||
// Report pending errors
|
||||
error_code::error_report(0, 0, 0, 0);
|
||||
error_code::error_report(0, nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
#ifdef _WIN32
|
||||
static thread_local ULONG64 tls_cycles{};
|
||||
@@ -2648,7 +2647,10 @@ void thread_base::exec()
|
||||
sig_log.fatal("Thread terminated due to fatal error: %s", reason);
|
||||
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
logs::listener::sync_all();
|
||||
utils::trap();
|
||||
}
|
||||
|
||||
if (const auto _this = g_tls_this_thread)
|
||||
{
|
||||
|
||||
+499
-131
File diff suppressed because it is too large
Load Diff
+51
-1
@@ -18,6 +18,13 @@ namespace patch_key
|
||||
static const std::string patch = "Patch";
|
||||
static const std::string patch_version = "Patch Version";
|
||||
static const std::string version = "Version";
|
||||
static const std::string enabled = "Enabled";
|
||||
static const std::string config_values = "Configurable Values";
|
||||
static const std::string value = "Value";
|
||||
static const std::string type = "Type";
|
||||
static const std::string min = "Min";
|
||||
static const std::string max = "Max";
|
||||
static const std::string allowed_values = "Allowed Values";
|
||||
}
|
||||
|
||||
inline static const std::string patch_engine_version = "1.2";
|
||||
@@ -47,6 +54,14 @@ enum class patch_type
|
||||
utf8, // Text of string (not null-terminated automatically)
|
||||
};
|
||||
|
||||
enum class patch_configurable_type
|
||||
{
|
||||
double_range,
|
||||
double_enum,
|
||||
long_range,
|
||||
long_enum
|
||||
};
|
||||
|
||||
class patch_engine
|
||||
{
|
||||
public:
|
||||
@@ -63,7 +78,40 @@ public:
|
||||
mutable u32 alloc_addr = 0; // Used to save optional allocation address (if occured)
|
||||
};
|
||||
|
||||
using patch_app_versions = std::unordered_map<std::string /*app_version*/, bool /*enabled*/>;
|
||||
struct patch_allowed_value
|
||||
{
|
||||
std::string label;
|
||||
f64 value{};
|
||||
|
||||
bool operator==(const patch_allowed_value& other) const
|
||||
{
|
||||
return value == other.value && label == other.label;
|
||||
}
|
||||
};
|
||||
|
||||
struct patch_config_value
|
||||
{
|
||||
f64 value{};
|
||||
f64 min{};
|
||||
f64 max{};
|
||||
patch_configurable_type type{};
|
||||
std::vector<patch_allowed_value> allowed_values;
|
||||
|
||||
bool operator==(const patch_config_value& other) const
|
||||
{
|
||||
return value == other.value && min == other.min && max == other.max && type == other.type && allowed_values == other.allowed_values;
|
||||
}
|
||||
|
||||
void set_and_check_value(f64 new_value, const std::string& name);
|
||||
};
|
||||
|
||||
struct patch_config_values
|
||||
{
|
||||
bool enabled{};
|
||||
std::map<std::string, patch_config_value> config_values;
|
||||
};
|
||||
|
||||
using patch_app_versions = std::unordered_map<std::string /*app_version*/, patch_config_values>;
|
||||
using patch_serials = std::unordered_map<std::string /*serial*/, patch_app_versions>;
|
||||
using patch_titles = std::unordered_map<std::string /*serial*/, patch_serials>;
|
||||
|
||||
@@ -78,10 +126,12 @@ public:
|
||||
std::string author{};
|
||||
std::string notes{};
|
||||
std::string source_path{};
|
||||
std::map<std::string, patch_config_value> default_config_values;
|
||||
|
||||
// Redundant information for accessibility (see patch_container)
|
||||
std::string hash{};
|
||||
std::string version{};
|
||||
std::map<std::string, patch_config_value> actual_config_values;
|
||||
};
|
||||
|
||||
struct patch_container
|
||||
|
||||
+33
-20
@@ -367,9 +367,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx.type)
|
||||
const usz src_type = src.type(ctx.args);
|
||||
|
||||
if (!ctx.type || src_type > 8)
|
||||
{
|
||||
ctx.type = static_cast<u8>(src.type(ctx.args));
|
||||
ctx.type = static_cast<u8>(src_type);
|
||||
|
||||
if (!ctx.type)
|
||||
{
|
||||
@@ -379,7 +381,13 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
|
||||
// Sign-extended argument expected
|
||||
const u64 val = src.template get<u64>(ctx.args);
|
||||
const bool negative = ctx.type && static_cast<s64>(val) < 0;
|
||||
bool negative = ctx.type && ctx.type <= 8 && static_cast<s64>(val) < 0;
|
||||
|
||||
if (ctx.type == 16)
|
||||
{
|
||||
u128 val2 = *reinterpret_cast<const u128*>(val);
|
||||
negative = !!(val2 & (u128{1} << 127));
|
||||
}
|
||||
|
||||
const usz start = out.size();
|
||||
|
||||
@@ -398,15 +406,14 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
out.push_back(' ');
|
||||
}
|
||||
|
||||
if (ctx.type == 16)
|
||||
if (ctx.type >= 16)
|
||||
{
|
||||
// TODO: support negative values (s128)
|
||||
u128 val2 = *reinterpret_cast<u128*>(val);
|
||||
write_decimal(val2, ctx.prec);
|
||||
u128 val2 = *reinterpret_cast<const u128*>(val);
|
||||
write_decimal(negative ? u128{} - val2 : val2, ctx.prec);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_decimal(negative ? 0 - val : val, ctx.prec);
|
||||
write_decimal(negative ? u64{} - val : val, ctx.prec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,9 +445,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx.type)
|
||||
const usz src_type = src.type(ctx.args);
|
||||
|
||||
if (!ctx.type || src_type > 8)
|
||||
{
|
||||
ctx.type = static_cast<u8>(src.type(ctx.args));
|
||||
ctx.type = static_cast<u8>(src_type);
|
||||
|
||||
if (!ctx.type)
|
||||
{
|
||||
@@ -471,9 +480,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
|
||||
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
|
||||
{
|
||||
if (ctx.type == 16)
|
||||
if (ctx.type >= 16)
|
||||
{
|
||||
u128 val2 = *reinterpret_cast<u128*>(val);
|
||||
u128 val2 = *reinterpret_cast<const u128*>(val);
|
||||
write_octal(val2, ctx.prec);
|
||||
}
|
||||
else
|
||||
@@ -504,9 +513,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx.type)
|
||||
const usz src_type = src.type(ctx.args);
|
||||
|
||||
if (!ctx.type || src_type > 8)
|
||||
{
|
||||
ctx.type = static_cast<u8>(src.type(ctx.args));
|
||||
ctx.type = static_cast<u8>(src_type);
|
||||
|
||||
if (!ctx.type)
|
||||
{
|
||||
@@ -537,9 +548,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
|
||||
if ((ctx.alter && val) || !ctx.dot || ctx.prec)
|
||||
{
|
||||
if (ctx.type == 16)
|
||||
if (ctx.type >= 16)
|
||||
{
|
||||
u128 val2 = *reinterpret_cast<u128*>(val);
|
||||
u128 val2 = *reinterpret_cast<const u128*>(val);
|
||||
write_hex(val2, ch == 'X', ctx.prec);
|
||||
}
|
||||
else
|
||||
@@ -576,9 +587,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ctx.type)
|
||||
const usz src_type = src.type(ctx.args);
|
||||
|
||||
if (!ctx.type || src_type > 8)
|
||||
{
|
||||
ctx.type = static_cast<u8>(src.type(ctx.args));
|
||||
ctx.type = static_cast<u8>(src_type);
|
||||
|
||||
if (!ctx.type)
|
||||
{
|
||||
@@ -599,9 +612,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
|
||||
if (!ctx.dot || ctx.prec)
|
||||
{
|
||||
if (ctx.type == 16)
|
||||
if (ctx.type >= 16)
|
||||
{
|
||||
u128 val2 = *reinterpret_cast<u128*>(val);
|
||||
u128 val2 = *reinterpret_cast<const u128*>(val);
|
||||
write_decimal(val2, ctx.prec);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -777,9 +777,9 @@ struct color4_base
|
||||
};
|
||||
|
||||
constexpr color4_base()
|
||||
: x{}
|
||||
, y{}
|
||||
, z{}
|
||||
: x{ T{0} }
|
||||
, y{ T{0} }
|
||||
, z{ T{0} }
|
||||
, w{ T(1) }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -359,6 +359,14 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
// Withdraw the list in reverse order (LIFO/FILO)
|
||||
lf_queue_slice<T> pop_all_reversed()
|
||||
{
|
||||
lf_queue_slice<T> result;
|
||||
result.m_head = m_head.exchange(nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Apply func(data) to each element, return the total length
|
||||
template <typename F>
|
||||
usz apply(F func)
|
||||
|
||||
+28
-2
@@ -4,17 +4,43 @@
|
||||
|
||||
namespace utils
|
||||
{
|
||||
namespace stack_trace
|
||||
{
|
||||
// Printing utilities
|
||||
|
||||
template <typename T>
|
||||
concept Logger = requires (T& t, const std::string& msg)
|
||||
{
|
||||
{ t.print(msg) };
|
||||
};
|
||||
|
||||
struct print_to_log
|
||||
{
|
||||
logs::channel& log;
|
||||
|
||||
public:
|
||||
print_to_log(logs::channel& chan)
|
||||
: log(chan)
|
||||
{}
|
||||
|
||||
void print(const std::string& s)
|
||||
{
|
||||
log.error("%s", s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<void*> get_backtrace(int max_depth = 255);
|
||||
std::vector<std::string> get_backtrace_symbols(const std::vector<void*>& stack);
|
||||
|
||||
FORCE_INLINE void print_trace(logs::channel& logger, int max_depth = 255)
|
||||
FORCE_INLINE void print_trace(stack_trace::Logger auto& logger, int max_depth = 255)
|
||||
{
|
||||
const auto trace = get_backtrace(max_depth);
|
||||
const auto lines = get_backtrace_symbols(trace);
|
||||
|
||||
for (const auto& line : lines)
|
||||
{
|
||||
logger.error("%s", line);
|
||||
logger.print(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace utils
|
||||
|
||||
if (lo())
|
||||
{
|
||||
version += "." + std::to_string(lo());
|
||||
version += '.';
|
||||
version += std::to_string(lo());
|
||||
}
|
||||
|
||||
if (type() != version_type::release)
|
||||
@@ -40,7 +41,8 @@ namespace utils
|
||||
version += "-" + postfix();
|
||||
}
|
||||
|
||||
version += " " + utils::to_string(type());
|
||||
version += ' ';
|
||||
version += utils::to_string(type());
|
||||
|
||||
if (type_index() > 1)
|
||||
{
|
||||
|
||||
+2
-2
@@ -70,8 +70,8 @@ jobs:
|
||||
QT_VER_MSVC: 'msvc2019'
|
||||
QT_DATE: '202011130602'
|
||||
QTDIR: C:\Qt\$(QT_VER)\$(QT_VER_MSVC)_64
|
||||
VULKAN_VER: '1.3.204.0'
|
||||
VULKAN_SDK_SHA: '41f4996335cc5a545d7b2f6e5ff29cf3867789aae4be053a7069aa93408861fa'
|
||||
VULKAN_VER: '1.3.224.1'
|
||||
VULKAN_SDK_SHA: '2029e652e39ee6a6036cff3765da31e1e6c595fd2413d3cd111dfab7855621ea'
|
||||
VULKAN_SDK: C:\VulkanSDK\$(VULKAN_VER)
|
||||
CACHE_DIR: ./cache
|
||||
UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
TheMitoSan Dark-Theme for RPCS3
|
||||
/*
|
||||
TheMitoSan Dark-Theme for RPCS3
|
||||
Based on Kuroi (Dark) by Ani
|
||||
by themitosan @ twitter.com/themitosan
|
||||
Ani @ https://github.com/AniLeo
|
||||
@@ -135,7 +135,7 @@ QPushButton::disabled {
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: #333;
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
@@ -193,7 +193,7 @@ QListWidget::item:hover {
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
QLabel#l_controller {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
@@ -230,8 +230,8 @@ QLabel#color_button {
|
||||
}
|
||||
|
||||
/* Search bar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
Envy theme for RPCS3 by drysalter (https://github.com/drysalter)
|
||||
03/04/2019
|
||||
*/
|
||||
@@ -19,7 +19,7 @@ Candy Red: #ff007a
|
||||
Yellow: #f2d571
|
||||
Fuchsia: #ff00ff
|
||||
Orange: #ff6000
|
||||
Cyan: #3498d8
|
||||
Cyan: #3498d8
|
||||
|
||||
*/
|
||||
|
||||
@@ -209,7 +209,7 @@ QRadioButton::indicator:unchecked {
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #4d5058;
|
||||
background-color: #4d5058;
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
@@ -272,7 +272,7 @@ QSlider::handle:horizontal {
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
@@ -335,7 +335,7 @@ QPushButton:disabled {
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d3038, stop: 1 #2d3038);
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d3038, stop: 1 #2d3038);
|
||||
}
|
||||
|
||||
/* Spinboxes */
|
||||
@@ -479,7 +479,7 @@ QListWidget::indicator:disabled {
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
QLabel#l_controller {
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ QLabel#color_button {
|
||||
}
|
||||
|
||||
/* Search bar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #ecf0f1;
|
||||
background-color: #2d3038;
|
||||
border: 1px solid #f8f8f8;
|
||||
@@ -513,14 +513,14 @@ QLineEdit#mw_searchbar {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
color: #ecf0f1;
|
||||
background-color: #2d3038;
|
||||
border: 1px solid #8cf944;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ QTableView {
|
||||
|
||||
QTableView::item:hover {
|
||||
color: #8cf944;
|
||||
}
|
||||
}
|
||||
|
||||
/* Game Icon Background */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
ModernBlue Theme for RPCS3
|
||||
/*
|
||||
ModernBlue Theme for RPCS3
|
||||
by themitosan @ twitter.com/themitosan
|
||||
(2017.12.12)
|
||||
*/
|
||||
@@ -124,7 +124,7 @@ QGroupBox::title {
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
background-color: #46598b;
|
||||
color: #fff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
QPushButton::disabled {
|
||||
@@ -133,7 +133,7 @@ QPushButton::disabled {
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: #172038;
|
||||
background-color: #172038;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
@@ -190,7 +190,7 @@ QListWidget::item:hover {
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
QLabel#l_controller {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -227,8 +227,8 @@ QLabel#color_button {
|
||||
}
|
||||
|
||||
/* Search bar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ QToolButton:hover {
|
||||
}
|
||||
|
||||
/* Search bar in Main Toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #999999;
|
||||
@@ -113,15 +113,15 @@ QLineEdit#mw_searchbar {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
color: #0074e7;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #0071ec;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ QSlider::handle:horizontal {
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
@@ -242,7 +242,7 @@ QRadioButton::indicator:unchecked {
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #455971;
|
||||
background-color: #455971;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
@@ -533,7 +533,7 @@ QProgressBar::chunk {
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
QLabel#l_controller {
|
||||
color: #0074e7;
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ QHeaderView::section {
|
||||
background-color: #111525;
|
||||
color: #FFFFFF;
|
||||
padding-top: 3px;
|
||||
padding-left: 3px;
|
||||
padding-left: 3px;
|
||||
height: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ QToolButton:hover {
|
||||
}
|
||||
|
||||
/* Search bar in Main Toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #999999;
|
||||
@@ -113,15 +113,15 @@ QLineEdit#mw_searchbar {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #0071ec;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #0071ec;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ QSlider::handle:horizontal {
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:disabled {
|
||||
@@ -254,7 +254,7 @@ QRadioButton::indicator:unchecked {
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #455971;
|
||||
background-color: #455971;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
@@ -552,7 +552,7 @@ QProgressBar::chunk {
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
QLabel#l_controller {
|
||||
color: #4343c1;
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ QHeaderView::section {
|
||||
background-color: #FFFFFF;
|
||||
color: #455971;
|
||||
padding-top: 3px;
|
||||
padding-left: 3px;
|
||||
padding-left: 3px;
|
||||
height: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
@@ -456,10 +456,10 @@ QSlider#sizeSlider::groove:horizontal {
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
On Patch Creator, it's the patch validation label
|
||||
since we can't avoid repainting color, let's bold it instead
|
||||
*/
|
||||
QLabel#validLabel {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Common default props for defining properties with macros. Import right after Microsoft.Cpp.Default.props -->
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
@@ -8,4 +8,4 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
+1
-1
Submodule llvm updated: 5521155be5...9b52b6c39a
@@ -1,11 +1,12 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29306.81
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32929.385
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "3rdparty\asmjit\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emucore", "rpcs3\emucore.vcxproj", "{C4A10229-4712-4BD2-B63E-50D93C67A038}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404} = {939FE206-1182-ABC3-1234-FEAB88E98404}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@@ -40,22 +41,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "3rdparty\yaml-c
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxproj", "{70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
|
||||
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {A107C21C-418A-4697-BB10-20C3AA60E2E4}
|
||||
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
|
||||
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {78CB2F39-B809-4A06-8329-8C0A19119D3D}
|
||||
{3384223A-6D97-4799-9862-359F85312892} = {3384223A-6D97-4799-9862-359F85312892}
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
|
||||
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
|
||||
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {9610627D-20FE-4B07-8CE3-9FF68A5F1EC2}
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A} = {FDA7B080-03B0-48C8-B24F-88118981422A}
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21} = {508c291a-3d18-49f5-b25d-f7c8db92cb21}
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}
|
||||
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
|
||||
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
|
||||
{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C} = {5B146DEA-9ACE-4D32-A7FD-3F42464DD69C}
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
|
||||
{3EE5F075-B546-42C4-B6A8-E3CCEF38B78D} = {3EE5F075-B546-42C4-B6A8-E3CCEF38B78D}
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21} = {508C291A-3D18-49F5-B25D-F7C8DB92CB21}
|
||||
{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C} = {5B146DEA-9ACE-4D32-A7FD-3F42464DD69C}
|
||||
{60F89955-91C6-3A36-8000-13C592FEC2DF} = {60F89955-91C6-3A36-8000-13C592FEC2DF}
|
||||
{78CB2F39-B809-4A06-8329-8C0A19119D3D} = {78CB2F39-B809-4A06-8329-8C0A19119D3D}
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}
|
||||
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
|
||||
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {9610627D-20FE-4B07-8CE3-9FF68A5F1EC2}
|
||||
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {A107C21C-418A-4697-BB10-20C3AA60E2E4}
|
||||
{AC40FF01-426E-4838-A317-66354CEFAE88} = {AC40FF01-426E-4838-A317-66354CEFAE88}
|
||||
{C4A10229-4712-4BD2-B63E-50D93C67A038} = {C4A10229-4712-4BD2-B63E-50D93C67A038}
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {D6973076-9317-4EF2-A0B8-B7A18AC0713E}
|
||||
{DA6F56B4-06A4-441D-AD70-AC5A7D51FADB} = {DA6F56B4-06A4-441D-AD70-AC5A7D51FADB}
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A} = {FDA7B080-03B0-48C8-B24F-88118981422A}
|
||||
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "3rdparty\hidapi\hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
|
||||
@@ -73,7 +75,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "3rdparty\curl\li
|
||||
{73973223-5EE8-41CA-8E88-1D60E89A237B} = {73973223-5EE8-41CA-8E88-1D60E89A237B}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRV", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv", "3rdparty\SPIRV\spirv.vcxproj", "{4CBD3DDD-5555-49A4-A44D-DD3D8CB516A1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdParty", "3rdParty", "{6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}"
|
||||
EndProject
|
||||
@@ -83,13 +85,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cubeb", "rpcs3\Cubeb.vcxpro
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcubeb", "3rdparty\cubeb\libcubeb.vcxproj", "{FDA7B080-03B0-48C8-B24F-88118981422A}"
|
||||
EndProject
|
||||
Project("{508c291a-3d18-49f5-b25d-f7c8db92cb21}") = "soundtouch", "3rdparty\SoundTouch\soundtouch.vcxproj", "{508c291a-3d18-49f5-b25d-f7c8db92cb21}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundtouch", "3rdparty\SoundTouch\soundtouch.vcxproj", "{508C291A-3D18-49F5-B25D-F7C8DB92CB21}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL", "3rdparty\libsdl-org\SDL.vcxproj", "{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pine", "pine", "{A55DA1B5-CC17-4525-BE7F-1659CE17BB56}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
3rdparty\pine\pine_server.h = 3rdparty\pine\pine_server.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc_static", "3rdparty\miniupnp\miniupnpc_static.vcxproj", "{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -176,10 +182,18 @@ Global
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A}.Debug|x64.Build.0 = Debug|x64
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A}.Release|x64.ActiveCfg = Release|x64
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A}.Release|x64.Build.0 = Release|x64
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Debug|x64.Build.0 = Debug|x64
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Release|x64.ActiveCfg = Release|x64
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21}.Release|x64.Build.0 = Release|x64
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Debug|x64.Build.0 = Debug|x64
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Release|x64.ActiveCfg = Release|x64
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21}.Release|x64.Build.0 = Release|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Debug|x64.Build.0 = Debug|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.ActiveCfg = Release|x64
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA}.Release|x64.Build.0 = Release|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Debug|x64.Build.0 = Debug|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.ActiveCfg = Release|x64
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -206,8 +220,10 @@ Global
|
||||
{A37E4273-85DB-4217-B775-CE971B87D9DF} = {B0AC29FD-7B01-4B5E-9C8D-0A081E4C5668}
|
||||
{9610627D-20FE-4B07-8CE3-9FF68A5F1EC2} = {10FBF193-D532-4CCF-B875-4C7091A7F6C2}
|
||||
{FDA7B080-03B0-48C8-B24F-88118981422A} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{508c291a-3d18-49f5-b25d-f7c8db92cb21} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{508C291A-3D18-49F5-B25D-F7C8DB92CB21} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{A55DA1B5-CC17-4525-BE7F-1659CE17BB56} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
{5228F863-E0DD-4DE7-AA7B-5C52B14CD4D0} = {6C3B64A0-8F8A-4DC4-8C0B-D71EBEED7FA8}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
|
||||
|
||||
@@ -66,10 +66,12 @@ set(RPCS3_SRC
|
||||
Input/ds4_pad_handler.cpp
|
||||
Input/dualsense_pad_handler.cpp
|
||||
Input/evdev_joystick_handler.cpp
|
||||
Input/evdev_gun_handler.cpp
|
||||
Input/hid_pad_handler.cpp
|
||||
Input/keyboard_pad_handler.cpp
|
||||
Input/mm_joystick_handler.cpp
|
||||
Input/pad_thread.cpp
|
||||
Input/sdl_pad_handler.cpp
|
||||
Input/xinput_pad_handler.cpp
|
||||
)
|
||||
|
||||
@@ -185,13 +187,13 @@ elseif(WIN32)
|
||||
|
||||
# If Qt5 is installed from vcpkg
|
||||
list(APPEND _QT5_TOOLS_PATHS "${Qt5_DIR}/../../../tools/qt5$<$<CONFIG:Debug>:/debug>/bin/")
|
||||
|
||||
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND set PATH=${_QT5_TOOLS_PATHS}$<SEMICOLON>%PATH%
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/bin" "$<TARGET_FILE_DIR:rpcs3>"
|
||||
# If Qt5 is installed from vcpkg, add binary path to PATH
|
||||
# otherwise windeployqt tool won't be able to locate necessary dlls
|
||||
COMMAND set PATH=${Qt5_DIR}/../../../$<$<CONFIG:Debug>:debug/>bin/$<SEMICOLON>%PATH%
|
||||
COMMAND set PATH=${Qt5_DIR}/../../../$<$<CONFIG:Debug>:debug/>bin/$<SEMICOLON>%PATH%
|
||||
COMMAND "${_WINDEPLOYQT}" --no-angle --no-compiler-runtime --no-opengl-sw --no-patchqt --no-translations --no-quick --plugindir "$<TARGET_FILE_DIR:rpcs3>/qt/plugins" $<$<CONFIG:Debug>:--debug> $<$<CONFIG:Release>:--release> "$<TARGET_FILE:rpcs3>")
|
||||
endif()
|
||||
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ int aes_crypt_cbc( aes_context *ctx,
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* both
|
||||
* both
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
|
||||
@@ -245,7 +245,7 @@ constexpr s64 PAID_30 = 0x1070000023000001L; // spu_token_processor.self; CoreOS
|
||||
constexpr s64 PAID_31 = 0x1070000024000001L; // sv_iso_spu_module.self; CoreOS; same for CEX DEX DECR
|
||||
constexpr s64 PAID_32 = 0x1070000025000001L; // aim_spu_module.self; CoreOS; same for CEX DEX DECR
|
||||
constexpr s64 PAID_33 = 0x1070000026000001L; // ss_sc_init.self; [2.43 JIG PUP]
|
||||
constexpr s64 PAID_34 = 0x1070000027000001L; // dispatcher.fself; lv1;
|
||||
constexpr s64 PAID_34 = 0x1070000027000001L; // dispatcher.fself; lv1;
|
||||
constexpr s64 PAID_35 = 0x1070000028000001L; // factory_data_mngr_server.fself; JIG lv1 proc
|
||||
constexpr s64 PAID_36 = 0x1070000029000001L; // fdm_spu_module.self; [2.43 JIG PUP]
|
||||
constexpr s64 PAID_37 = 0x107000002A000001L;
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
|
||||
LOG_CHANNEL(edat_log, "EDAT");
|
||||
|
||||
// Static variables are being modified concurrently in ec.cpp, for now use a mutex
|
||||
static shared_mutex ec_mtx;
|
||||
|
||||
void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv)
|
||||
{
|
||||
int mode = crypto_mode & 0xF0000000;
|
||||
@@ -482,8 +479,6 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
unsigned char signature_s[0x15] = { 0 };
|
||||
unsigned char zero_buf[0x15] = { 0 };
|
||||
|
||||
std::lock_guard lock(ec_mtx);
|
||||
|
||||
// Setup ECDSA curve and public key.
|
||||
ecdsa_set_curve(VSH_CURVE_P, VSH_CURVE_A, VSH_CURVE_B, VSH_CURVE_N, VSH_CURVE_GX, VSH_CURVE_GY);
|
||||
ecdsa_set_pub(VSH_PUB);
|
||||
|
||||
@@ -115,6 +115,11 @@ public:
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
u64 read_at(u64 offset, void* buffer, u64 size) override
|
||||
{
|
||||
return ReadData(offset, static_cast<u8*>(buffer), size);
|
||||
}
|
||||
|
||||
u64 write(const void*, u64) override
|
||||
{
|
||||
return 0;
|
||||
|
||||
+332
-91
@@ -4,12 +4,17 @@
|
||||
#include "key_vault.h"
|
||||
#include "util/logs.hpp"
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include "Utilities/Thread.h"
|
||||
#include "Utilities/mutex.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/VFS.h"
|
||||
#include "unpkg.h"
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
LOG_CHANNEL(pkg_log, "PKG");
|
||||
|
||||
package_reader::package_reader(const std::string& path)
|
||||
@@ -61,6 +66,7 @@ bool package_reader::read_header()
|
||||
return false;
|
||||
}
|
||||
|
||||
pkg_log.notice("Path: '%s'", m_path);
|
||||
pkg_log.notice("Header: pkg_magic = 0x%x = \"%s\"", +m_header.pkg_magic, std::string(reinterpret_cast<const char*>(&m_header.pkg_magic), 4));
|
||||
pkg_log.notice("Header: pkg_type = 0x%x = %d", m_header.pkg_type, m_header.pkg_type);
|
||||
pkg_log.notice("Header: pkg_platform = 0x%x = %d", m_header.pkg_platform, m_header.pkg_platform);
|
||||
@@ -189,8 +195,7 @@ bool package_reader::read_metadata()
|
||||
|
||||
// Read title ID and use it as an installation directory
|
||||
m_install_dir.resize(9);
|
||||
archive_seek(55);
|
||||
archive_read(&m_install_dir.front(), m_install_dir.size());
|
||||
archive_read_block(55, &m_install_dir.front(), m_install_dir.size());
|
||||
|
||||
// Read package metadata
|
||||
|
||||
@@ -509,9 +514,9 @@ bool package_reader::read_param_sfo()
|
||||
|
||||
std::vector<PKGEntry> entries(m_header.file_count);
|
||||
|
||||
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
|
||||
std::memcpy(entries.data(), m_bufs.back().get(), entries.size() * sizeof(PKGEntry));
|
||||
|
||||
for (const auto& entry : entries)
|
||||
for (const PKGEntry& entry : entries)
|
||||
{
|
||||
if (entry.name_size > 256)
|
||||
{
|
||||
@@ -523,7 +528,7 @@ bool package_reader::read_param_sfo()
|
||||
|
||||
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
|
||||
|
||||
const std::string_view name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
|
||||
const std::string_view name{reinterpret_cast<char*>(m_bufs.back().get()), entry.name_size};
|
||||
|
||||
// We're looking for the PARAM.SFO file, if there is any
|
||||
if (usz ndelim = name.find_first_not_of('/'); ndelim == umax || name.substr(ndelim) != "PARAM.SFO")
|
||||
@@ -538,13 +543,13 @@ bool package_reader::read_param_sfo()
|
||||
{
|
||||
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
|
||||
|
||||
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
|
||||
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()).size() != block_size)
|
||||
{
|
||||
pkg_log.error("Failed to decrypt PARAM.SFO file");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tmp.write(m_buf.get(), block_size) != block_size)
|
||||
if (tmp.write(m_bufs.back().get(), block_size) != block_size)
|
||||
{
|
||||
pkg_log.error("Failed to write to temporary PARAM.SFO file");
|
||||
return false;
|
||||
@@ -553,7 +558,7 @@ bool package_reader::read_param_sfo()
|
||||
|
||||
tmp.seek(0);
|
||||
|
||||
m_psf = psf::load_object(tmp);
|
||||
m_psf = psf::load_object(tmp, name);
|
||||
|
||||
if (m_psf.empty())
|
||||
{
|
||||
@@ -563,11 +568,9 @@ bool package_reader::read_param_sfo()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkg_log.error("Failed to create temporary PARAM.SFO file");
|
||||
return false;
|
||||
}
|
||||
|
||||
pkg_log.error("Failed to create temporary PARAM.SFO file");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -610,13 +613,14 @@ package_error package_reader::check_target_app_version() const
|
||||
return package_error::no_error;
|
||||
}
|
||||
|
||||
const fs::file installed_sfo_file(rpcs3::utils::get_hdd0_dir() + "game/" + std::string(title_id) + "/PARAM.SFO");
|
||||
const std::string sfo_path = rpcs3::utils::get_hdd0_dir() + "game/" + std::string(title_id) + "/PARAM.SFO";
|
||||
const fs::file installed_sfo_file(sfo_path);
|
||||
if (!installed_sfo_file)
|
||||
{
|
||||
if (!target_app_ver.empty())
|
||||
{
|
||||
// We are unable to compare anything with the target app version
|
||||
pkg_log.error("A target app version is required (%s), but no PARAM.SFO was found for %s", target_app_ver, title_id);
|
||||
pkg_log.error("A target app version is required (%s), but no PARAM.SFO was found for %s. (path='%s', error=%s)", target_app_ver, title_id, sfo_path, fs::g_tls_error);
|
||||
return package_error::app_version;
|
||||
}
|
||||
|
||||
@@ -624,7 +628,7 @@ package_error package_reader::check_target_app_version() const
|
||||
return package_error::no_error;
|
||||
}
|
||||
|
||||
const auto installed_psf = psf::load_object(installed_sfo_file);
|
||||
const auto installed_psf = psf::load_object(installed_sfo_file, sfo_path);
|
||||
|
||||
const auto installed_title_id = psf::get_string(installed_psf, "TITLE_ID", "");
|
||||
const auto installed_app_ver = psf::get_string(installed_psf, "APP_VER", "");
|
||||
@@ -686,16 +690,16 @@ package_error package_reader::check_target_app_version() const
|
||||
return package_error::app_version;
|
||||
}
|
||||
|
||||
fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, u8 *custom_klic, bool verbose = false);
|
||||
|
||||
bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
bool package_reader::set_install_path()
|
||||
{
|
||||
if (!m_is_valid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get full path and create the directory
|
||||
m_install_path.clear();
|
||||
|
||||
// Get full path
|
||||
std::string dir = rpcs3::utils::get_hdd0_dir();
|
||||
|
||||
// Based on https://www.psdevwiki.com/ps3/PKG_files#ContentType
|
||||
@@ -730,14 +734,30 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
dir += m_install_dir + '/';
|
||||
|
||||
// If false, an existing directory is being overwritten: cannot cancel the operation
|
||||
const bool was_null = !fs::is_dir(dir);
|
||||
m_was_null = !fs::is_dir(dir);
|
||||
|
||||
if (!fs::create_path(dir))
|
||||
m_install_path = dir;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool package_reader::fill_data(std::map<std::string, install_entry*>& all_install_entries)
|
||||
{
|
||||
if (!m_is_valid)
|
||||
{
|
||||
pkg_log.error("Could not create the installation directory %s", dir);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fs::create_path(m_install_path))
|
||||
{
|
||||
pkg_log.error("Could not create the installation directory %s (error=%s)", m_install_path, fs::g_tls_error);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_install_entries.clear();
|
||||
m_bootable_file_path.clear();
|
||||
m_entry_indexer = 0;
|
||||
m_written_bytes = 0;
|
||||
|
||||
if (!decrypt_data())
|
||||
{
|
||||
return false;
|
||||
@@ -747,26 +767,146 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
|
||||
std::vector<PKGEntry> entries(m_header.file_count);
|
||||
|
||||
std::memcpy(entries.data(), m_buf.get(), entries.size() * sizeof(PKGEntry));
|
||||
std::memcpy(entries.data(), m_bufs.back().get(), entries.size() * sizeof(PKGEntry));
|
||||
|
||||
// Create directories first
|
||||
for (const auto& entry : entries)
|
||||
{
|
||||
if (entry.name_size > 256)
|
||||
if (entry.name_size > PKG_MAX_FILENAME_SIZE)
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("PKG name size is too big (0x%x)", entry.name_size);
|
||||
break;
|
||||
}
|
||||
|
||||
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
|
||||
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
|
||||
|
||||
const std::string name{reinterpret_cast<char*>(m_bufs.back().get()), entry.name_size};
|
||||
std::string path = m_install_path + vfs::escape(name);
|
||||
|
||||
if (entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS))
|
||||
{
|
||||
pkg_log.todo("Entry with unknown type or padding: type=0x%08x, pad=0x%x, name='%s'", entry.type, entry.pad, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
pkg_log.notice("Entry: type=0x%08x, name='%s'", entry.type, name);
|
||||
}
|
||||
|
||||
const u8 entry_type = entry.type & 0xff;
|
||||
|
||||
switch (entry_type)
|
||||
{
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
case 0x12:
|
||||
{
|
||||
if (fs::is_dir(path))
|
||||
{
|
||||
pkg_log.warning("Reused existing directory %s", path);
|
||||
}
|
||||
else if (fs::create_path(path))
|
||||
{
|
||||
pkg_log.notice("Created directory %s", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Failed to create directory %s", path);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// TODO: check for valid utf8 characters
|
||||
const std::string true_path = std::filesystem::weakly_canonical(path).string();
|
||||
if (true_path.empty())
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Failed to get weakly_canonical path for '%s'", path);
|
||||
break;
|
||||
}
|
||||
|
||||
auto map_ptr = &*all_install_entries.try_emplace(true_path).first;
|
||||
|
||||
m_install_entries.push_back({
|
||||
.weak_reference = map_ptr,
|
||||
.name = name,
|
||||
.file_offset = entry.file_offset,
|
||||
.file_size = entry.file_size,
|
||||
.type = entry.type,
|
||||
.pad = entry.pad
|
||||
});
|
||||
|
||||
if (map_ptr->second && !(entry.type & PKG_FILE_ENTRY_OVERWRITE))
|
||||
{
|
||||
// Cannot override
|
||||
continue;
|
||||
}
|
||||
|
||||
// Link
|
||||
map_ptr->second = &m_install_entries.back();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_failures != 0)
|
||||
{
|
||||
pkg_log.error("Package installation failed: %s", m_install_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, u8 *custom_klic, bool verbose = false);
|
||||
|
||||
void package_reader::extract_worker(thread_key thread_data_key)
|
||||
{
|
||||
while (m_num_failures == 0 && !m_aborted)
|
||||
{
|
||||
// Make sure m_entry_indexer does not exceed m_install_entries
|
||||
const usz index = m_entry_indexer.fetch_op([this](usz& v)
|
||||
{
|
||||
if (v < m_install_entries.size())
|
||||
{
|
||||
v++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}).first;
|
||||
|
||||
if (index >= m_install_entries.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const install_entry& entry = ::at32(m_install_entries, index);
|
||||
|
||||
if (!entry.is_dominating())
|
||||
{
|
||||
// Overwritten by another entry
|
||||
m_written_bytes += entry.file_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool is_psp = (entry.type & PKG_FILE_ENTRY_PSP) != 0u;
|
||||
|
||||
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data());
|
||||
const std::string& path = entry.weak_reference->first;
|
||||
const std::string& name = entry.name;
|
||||
|
||||
const std::string name{reinterpret_cast<char*>(m_buf.get()), entry.name_size};
|
||||
const std::string path = dir + vfs::escape(name);
|
||||
|
||||
const bool log_error = entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS);
|
||||
(log_error ? pkg_log.error : pkg_log.notice)("Entry 0x%08x: %s (pad=0x%x)", entry.type, name, entry.pad);
|
||||
if (entry.pad || (entry.type & ~PKG_FILE_ENTRY_KNOWN_BITS))
|
||||
{
|
||||
pkg_log.todo("Entry with unknown type or padding: type=0x%08x, pad=0x%x, name='%s'", entry.type, entry.pad, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
pkg_log.notice("Entry: type=0x%08x, name='%s'", entry.type, name);
|
||||
}
|
||||
|
||||
switch (const u8 entry_type = entry.type & 0xff)
|
||||
{
|
||||
@@ -798,43 +938,33 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
|
||||
if (entry_type == PKG_FILE_ENTRY_NPDRMEDAT)
|
||||
{
|
||||
pkg_log.todo("NPDRM EDAT!");
|
||||
pkg_log.warning("NPDRM EDAT!");
|
||||
}
|
||||
|
||||
if (fs::file out = is_buffered ? fs::make_stream<std::vector<u8>>() : fs::file{ path, fs::rewrite })
|
||||
if (fs::file out = is_buffered ? fs::make_stream<std::vector<u8>>() : fs::file{ path, did_overwrite ? fs::rewrite : fs::write_new })
|
||||
{
|
||||
bool extract_success = true;
|
||||
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
|
||||
{
|
||||
const u64 block_size = std::min<u64>(BUF_SIZE, entry.file_size - pos);
|
||||
|
||||
if (decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data()) != block_size)
|
||||
const std::span<const char> data_span = decrypt(entry.file_offset + pos, block_size, is_psp ? PKG_AES_KEY2 : m_dec_key.data(), thread_data_key);
|
||||
|
||||
if (data_span.size() != block_size)
|
||||
{
|
||||
extract_success = false;
|
||||
pkg_log.error("Failed to extract file %s", path);
|
||||
pkg_log.error("Failed to extract file %s (data_span.size=%d, block_size=%d)", path, data_span.size(), block_size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (out.write(m_buf.get(), block_size) != block_size)
|
||||
if (out.write(data_span.data(), block_size) != block_size)
|
||||
{
|
||||
extract_success = false;
|
||||
pkg_log.error("Failed to write file %s", path);
|
||||
pkg_log.error("Failed to write file %s (error=%s)", path, fs::g_tls_error);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sync.fetch_add((block_size + 0.0) / m_header.data_size) < 0.)
|
||||
{
|
||||
if (was_null)
|
||||
{
|
||||
pkg_log.error("Package installation cancelled: %s", dir);
|
||||
out.close();
|
||||
fs::remove_all(dir, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot cancel the installation
|
||||
sync += 1.;
|
||||
}
|
||||
m_written_bytes += block_size;
|
||||
}
|
||||
|
||||
if (is_buffered)
|
||||
@@ -842,8 +972,8 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
out = DecryptEDAT(out, name, 1, reinterpret_cast<u8*>(&m_header.klicensee), true);
|
||||
if (!out || !fs::write_file(path, fs::rewrite, static_cast<fs::container_stream<std::vector<u8>>*>(out.release().get())->obj))
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Failed to create file %s", path);
|
||||
m_num_failures++;
|
||||
pkg_log.error("Failed to create file %s (error=%s)", path, fs::g_tls_error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -857,93 +987,192 @@ bool package_reader::extract_data(atomic_t<double>& sync)
|
||||
else
|
||||
{
|
||||
pkg_log.notice("Created file %s", path);
|
||||
|
||||
if (name == "USRDIR/EBOOT.BIN" && entry.file_size > 4)
|
||||
{
|
||||
// Expose the creation of a bootable file
|
||||
m_bootable_file_path = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num_failures++;
|
||||
m_num_failures++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Failed to create file %s", path);
|
||||
m_num_failures++;
|
||||
pkg_log.error("Failed to create file %s (is_buffered=%d, did_overwrite=%d, error=%s)", path, is_buffered, did_overwrite, fs::g_tls_error);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
case 0x12:
|
||||
default:
|
||||
{
|
||||
if (fs::create_dir(path))
|
||||
m_num_failures++;
|
||||
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
package_error package_reader::extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths)
|
||||
{
|
||||
package_error error = package_error::no_error;
|
||||
usz num_failures = 0;
|
||||
|
||||
// Set paths first in order to know if the install dir was empty before starting any installations.
|
||||
// This will also allow us to remove all the new packages in one path at once if any of them fail.
|
||||
for (package_reader& reader : readers)
|
||||
{
|
||||
reader.m_result = result::not_started;
|
||||
|
||||
if (!reader.set_install_path())
|
||||
{
|
||||
error = package_error::other;
|
||||
reader.m_result = result::error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (package_reader& reader : readers)
|
||||
{
|
||||
// Use a seperate map for each reader. We need to check if the target app version exists for each package in sequence.
|
||||
std::map<std::string, install_entry*> all_install_entries;
|
||||
|
||||
if (error == package_error::no_error)
|
||||
{
|
||||
// Check if this package is allowed to be installed on top of the existing data
|
||||
error = reader.check_target_app_version();
|
||||
}
|
||||
|
||||
if (error == package_error::no_error)
|
||||
{
|
||||
reader.m_result = result::started;
|
||||
|
||||
// Parse the files to be installed and create all paths.
|
||||
if (!reader.fill_data(all_install_entries))
|
||||
{
|
||||
pkg_log.notice("Created directory %s", path);
|
||||
error = package_error::other;
|
||||
}
|
||||
else if (fs::is_dir(path))
|
||||
}
|
||||
|
||||
reader.m_bufs.resize(std::min<usz>(utils::get_thread_count(), reader.m_install_entries.size()));
|
||||
reader.m_num_failures = error == package_error::no_error ? 0 : 1;
|
||||
|
||||
atomic_t<usz> thread_indexer = 0;
|
||||
|
||||
named_thread_group workers("PKG Installer "sv, std::max<u32>(::narrow<u32>(reader.m_bufs.size()), 1) - 1, [&]()
|
||||
{
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
});
|
||||
|
||||
reader.extract_worker(thread_key{thread_indexer++});
|
||||
workers.join();
|
||||
|
||||
num_failures += reader.m_num_failures;
|
||||
|
||||
reader.m_bufs.clear();
|
||||
reader.m_bufs.shrink_to_fit();
|
||||
|
||||
// We don't count this package as aborted if all entries were processed.
|
||||
if (reader.m_num_failures || (reader.m_aborted && reader.m_entry_indexer < reader.m_install_entries.size()))
|
||||
{
|
||||
// Clear boot path. We don't want to propagate potentially broken paths to the caller.
|
||||
reader.m_bootable_file_path.clear();
|
||||
|
||||
bool cleaned = reader.m_was_null;
|
||||
|
||||
if (reader.m_was_null && fs::is_dir(reader.m_install_path))
|
||||
{
|
||||
pkg_log.warning("Reused existing directory %s", path);
|
||||
pkg_log.notice("Removing partial installation ('%s')", reader.m_install_path);
|
||||
|
||||
if (!fs::remove_all(reader.m_install_path, true))
|
||||
{
|
||||
pkg_log.notice("Failed to remove partial installation ('%s') (error=%s)", reader.m_install_path, fs::g_tls_error);
|
||||
cleaned = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.m_num_failures)
|
||||
{
|
||||
pkg_log.error("Package failed to install ('%s')", reader.m_install_path);
|
||||
reader.m_result = cleaned ? result::error_cleaned : result::error;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Failed to create directory %s", path);
|
||||
pkg_log.warning("Package installation aborted ('%s')", reader.m_install_path);
|
||||
reader.m_result = cleaned ? result::aborted_cleaned : result::aborted;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.m_result = result::success;
|
||||
|
||||
if (reader.get_progress(1) != 1)
|
||||
{
|
||||
num_failures++;
|
||||
pkg_log.error("Unknown PKG entry type (0x%x) %s", entry.type, name);
|
||||
}
|
||||
pkg_log.warning("Missing %d bytes from PKG total files size.", reader.m_header.data_size - reader.m_written_bytes);
|
||||
reader.m_written_bytes = reader.m_header.data_size; // Mark as completed anyway
|
||||
}
|
||||
|
||||
// May be empty
|
||||
bootable_paths.emplace_back(std::move(reader.m_bootable_file_path));
|
||||
}
|
||||
|
||||
if (num_failures == 0)
|
||||
if (num_failures > 0)
|
||||
{
|
||||
pkg_log.success("Package successfully installed to %s", dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs::remove_all(dir, true);
|
||||
pkg_log.error("Package installation failed: %s", dir);
|
||||
error = package_error::other;
|
||||
}
|
||||
|
||||
return num_failures == 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
void package_reader::archive_seek(const s64 new_offset, const fs::seek_mode damode)
|
||||
{
|
||||
if (m_file) m_file.seek(new_offset, damode);
|
||||
};
|
||||
}
|
||||
|
||||
u64 package_reader::archive_read(void* data_ptr, const u64 num_bytes)
|
||||
{
|
||||
return m_file ? m_file.read(data_ptr, num_bytes) : 0;
|
||||
};
|
||||
}
|
||||
|
||||
u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||
std::span<const char> package_reader::archive_read_block(u64 offset, void* data_ptr, u64 num_bytes)
|
||||
{
|
||||
const usz read_n = m_file.read_at(offset, data_ptr, num_bytes);
|
||||
|
||||
return {static_cast<const char*>(data_ptr), read_n};
|
||||
}
|
||||
|
||||
std::span<const char> package_reader::decrypt(u64 offset, u64 size, const uchar* key, thread_key thread_data_key)
|
||||
{
|
||||
if (!m_is_valid)
|
||||
{
|
||||
return 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_buf)
|
||||
if (m_bufs.empty())
|
||||
{
|
||||
// Assume in single-threaded mode still
|
||||
m_bufs.resize(1);
|
||||
}
|
||||
|
||||
auto& local_buf = ::at32(m_bufs, thread_data_key.unique_num);
|
||||
|
||||
if (!local_buf)
|
||||
{
|
||||
// Allocate buffer with BUF_SIZE size or more if required
|
||||
m_buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * m_header.file_count) / sizeof(u128)]);
|
||||
local_buf.reset(new u128[std::max<u64>(BUF_SIZE, sizeof(PKGEntry) * m_header.file_count) / sizeof(u128)]);
|
||||
}
|
||||
|
||||
archive_seek(m_header.data_offset + offset);
|
||||
|
||||
// Read the data and set available size
|
||||
const u64 read = archive_read(m_buf.get(), size);
|
||||
const auto data_span = archive_read_block(m_header.data_offset + offset, local_buf.get(), size);
|
||||
ensure(data_span.data() == static_cast<void*>(local_buf.get()));
|
||||
|
||||
// Get block count
|
||||
const u64 blocks = (read + 15) / 16;
|
||||
const u64 blocks = (data_span.size() + 15) / 16;
|
||||
|
||||
if (m_header.pkg_type == PKG_RELEASE_TYPE_DEBUG)
|
||||
{
|
||||
@@ -969,7 +1198,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||
|
||||
sha1(reinterpret_cast<const u8*>(input), sizeof(input), hash.data);
|
||||
|
||||
m_buf[i] ^= hash._v128;
|
||||
local_buf[i] ^= hash._v128;
|
||||
}
|
||||
}
|
||||
else if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE)
|
||||
@@ -989,7 +1218,7 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||
|
||||
aes_crypt_ecb(&ctx, AES_ENCRYPT, reinterpret_cast<const u8*>(&input), reinterpret_cast<u8*>(&key));
|
||||
|
||||
m_buf[i] ^= key;
|
||||
local_buf[i] ^= key;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -998,5 +1227,17 @@ u64 package_reader::decrypt(u64 offset, u64 size, const uchar* key)
|
||||
}
|
||||
|
||||
// Return the amount of data written in buf
|
||||
return read;
|
||||
};
|
||||
return data_span;
|
||||
}
|
||||
|
||||
int package_reader::get_progress(int maximum) const
|
||||
{
|
||||
const usz wr = m_written_bytes;
|
||||
|
||||
return wr >= m_header.data_size ? maximum : ::narrow<int>(wr * maximum / m_header.data_size);
|
||||
}
|
||||
|
||||
void package_reader::abort_extract()
|
||||
{
|
||||
m_aborted = true;
|
||||
}
|
||||
|
||||
+64
-7
@@ -6,12 +6,15 @@
|
||||
#include "Utilities/File.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <span>
|
||||
#include <deque>
|
||||
|
||||
// Constants
|
||||
enum
|
||||
enum : u32
|
||||
{
|
||||
PKG_HEADER_SIZE = 0xC0, // sizeof(pkg_header) + sizeof(pkg_unk_checksum)
|
||||
PKG_HEADER_SIZE2 = 0x280,
|
||||
PKG_MAX_FILENAME_SIZE = 256,
|
||||
};
|
||||
|
||||
enum : u16
|
||||
@@ -303,35 +306,89 @@ enum class package_error
|
||||
|
||||
class package_reader
|
||||
{
|
||||
struct thread_key
|
||||
{
|
||||
const usz unique_num = umax;
|
||||
};
|
||||
|
||||
struct install_entry
|
||||
{
|
||||
typename std::map<std::string, install_entry*>::value_type* weak_reference{};
|
||||
std::string name;
|
||||
|
||||
u64 file_offset{};
|
||||
u64 file_size{};
|
||||
u32 type{};
|
||||
u32 pad{};
|
||||
|
||||
// Check if the entry is the same one registered in entries to install
|
||||
bool is_dominating() const
|
||||
{
|
||||
return weak_reference->second == this;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
package_reader(const std::string& path);
|
||||
~package_reader();
|
||||
|
||||
enum result
|
||||
{
|
||||
not_started,
|
||||
started,
|
||||
success,
|
||||
aborted,
|
||||
aborted_cleaned,
|
||||
error,
|
||||
error_cleaned
|
||||
};
|
||||
|
||||
bool is_valid() const { return m_is_valid; }
|
||||
package_error check_target_app_version() const;
|
||||
bool extract_data(atomic_t<double>& sync);
|
||||
static package_error extract_data(std::deque<package_reader>& readers, std::deque<std::string>& bootable_paths);
|
||||
psf::registry get_psf() const { return m_psf; }
|
||||
result get_result() const { return m_result; };
|
||||
|
||||
int get_progress(int maximum = 100) const;
|
||||
|
||||
void abort_extract();
|
||||
|
||||
private:
|
||||
bool read_header();
|
||||
bool read_metadata();
|
||||
bool read_param_sfo();
|
||||
bool decrypt_data();
|
||||
void archive_seek(const s64 new_offset, const fs::seek_mode damode = fs::seek_set);
|
||||
u64 archive_read(void* data_ptr, const u64 num_bytes);
|
||||
u64 decrypt(u64 offset, u64 size, const uchar* key);
|
||||
void archive_seek(s64 new_offset, const fs::seek_mode damode = fs::seek_set);
|
||||
u64 archive_read(void* data_ptr, u64 num_bytes);
|
||||
bool set_install_path();
|
||||
bool fill_data(std::map<std::string, install_entry*>& all_install_entries);
|
||||
std::span<const char> archive_read_block(u64 offset, void* data_ptr, u64 num_bytes);
|
||||
std::span<const char> decrypt(u64 offset, u64 size, const uchar* key, thread_key thread_data_key = {0});
|
||||
void extract_worker(thread_key thread_data_key);
|
||||
|
||||
const usz BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
std::deque<install_entry> m_install_entries;
|
||||
std::string m_install_path;
|
||||
atomic_t<bool> m_aborted = false;
|
||||
atomic_t<usz> m_num_failures = 0;
|
||||
atomic_t<usz> m_entry_indexer = 0;
|
||||
atomic_t<usz> m_written_bytes = 0;
|
||||
bool m_was_null = false;
|
||||
|
||||
static constexpr usz BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
|
||||
bool m_is_valid = false;
|
||||
result m_result = result::not_started;
|
||||
|
||||
std::string m_path{};
|
||||
std::string m_install_dir{};
|
||||
fs::file m_file{};
|
||||
std::unique_ptr<u128[]> m_buf{};
|
||||
std::vector<std::unique_ptr<u128[]>> m_bufs{};
|
||||
std::array<uchar, 16> m_dec_key{};
|
||||
|
||||
PKGHeader m_header{};
|
||||
PKGMetaData m_metadata{};
|
||||
psf::registry m_psf{};
|
||||
|
||||
// Expose bootable file installed (if installed such)
|
||||
std::string m_bootable_file_path;
|
||||
};
|
||||
|
||||
@@ -111,7 +111,7 @@ std::pair<AudioChannelCnt, AudioChannelCnt> AudioBackend::get_channel_count_and_
|
||||
audio_out_configuration& audio_out_cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(audio_out_cfg.mtx);
|
||||
ensure(device_index < audio_out_cfg.out.size());
|
||||
const audio_out_configuration::audio_out& out = audio_out_cfg.out.at(device_index);
|
||||
const audio_out_configuration::audio_out& out = ::at32(audio_out_cfg.out, device_index);
|
||||
return out.get_channel_count_and_downmixer();
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ AudioChannelCnt AudioBackend::get_max_channel_count(u32 device_index)
|
||||
audio_out_configuration& audio_out_cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(audio_out_cfg.mtx);
|
||||
ensure(device_index < audio_out_cfg.out.size());
|
||||
const audio_out_configuration::audio_out& out = audio_out_cfg.out.at(device_index);
|
||||
const audio_out_configuration::audio_out& out = ::at32(audio_out_cfg.out, device_index);
|
||||
|
||||
AudioChannelCnt count = AudioChannelCnt::STEREO;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ enum class AudioChannelCnt : u32
|
||||
enum class AudioStateEvent : u32
|
||||
{
|
||||
UNSPECIFIED_ERROR,
|
||||
DEFAULT_DEVICE_CHANGED,
|
||||
DEFAULT_DEVICE_MAYBE_CHANGED,
|
||||
};
|
||||
|
||||
class AudioBackend
|
||||
@@ -226,7 +226,7 @@ protected:
|
||||
AudioFreq m_sampling_rate = AudioFreq::FREQ_48K;
|
||||
AudioChannelCnt m_channels = AudioChannelCnt::STEREO;
|
||||
|
||||
shared_mutex m_cb_mutex{};
|
||||
std::timed_mutex m_cb_mutex{};
|
||||
std::function<u32(u32, void *)> m_write_callback{};
|
||||
|
||||
shared_mutex m_state_cb_mutex{};
|
||||
|
||||
@@ -22,14 +22,14 @@ CubebBackend::CubebBackend()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (int err = cubeb_init(&m_ctx, "RPCS3", nullptr))
|
||||
cubeb *ctx{};
|
||||
if (int err = cubeb_init(&ctx, "RPCS3", nullptr))
|
||||
{
|
||||
Cubeb.error("cubeb_init() failed: %i", err);
|
||||
m_ctx = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (int err = cubeb_register_device_collection_changed(m_ctx, CUBEB_DEVICE_TYPE_OUTPUT, device_collection_changed_cb, this))
|
||||
if (int err = cubeb_register_device_collection_changed(ctx, CUBEB_DEVICE_TYPE_OUTPUT, device_collection_changed_cb, this))
|
||||
{
|
||||
Cubeb.error("cubeb_register_device_collection_changed() failed: %i", err);
|
||||
}
|
||||
@@ -38,7 +38,10 @@ CubebBackend::CubebBackend()
|
||||
m_dev_collection_cb_enabled = true;
|
||||
}
|
||||
|
||||
Cubeb.notice("Using backend %s", cubeb_get_backend_id(m_ctx));
|
||||
Cubeb.notice("Using backend %s", cubeb_get_backend_id(ctx));
|
||||
|
||||
std::lock_guard cb_lock{m_state_cb_mutex};
|
||||
m_ctx = ctx;
|
||||
}
|
||||
|
||||
CubebBackend::~CubebBackend()
|
||||
@@ -78,8 +81,19 @@ bool CubebBackend::Operational()
|
||||
|
||||
bool CubebBackend::DefaultDeviceChanged()
|
||||
{
|
||||
std::lock_guard lock{m_dev_sw_mutex};
|
||||
return !m_reset_req.observe() && m_default_dev_changed;
|
||||
if (m_default_device.empty() || m_reset_req.observe())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
device_handle device = GetDevice();
|
||||
if (!device.handle)
|
||||
{
|
||||
Cubeb.error("Selected device not found. Trying alternative approach...");
|
||||
device = GetDefaultDeviceAlt(m_sampling_rate, m_sample_size, m_channels);
|
||||
}
|
||||
|
||||
return !device.handle || device.id != m_default_device;
|
||||
}
|
||||
|
||||
bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
|
||||
@@ -90,20 +104,23 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
return false;
|
||||
}
|
||||
|
||||
std::lock_guard lock(m_cb_mutex);
|
||||
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
|
||||
CloseUnlocked();
|
||||
Close();
|
||||
std::lock_guard lock{m_cb_mutex};
|
||||
|
||||
const bool use_default_device = dev_id.empty() || dev_id == audio_device_enumerator::DEFAULT_DEV_ID;
|
||||
auto [dev_handle, dev_ident, dev_ch_cnt] = GetDevice(use_default_device ? "" : dev_id);
|
||||
|
||||
if (!dev_handle)
|
||||
if (use_default_device) Cubeb.notice("Trying to open default device");
|
||||
else Cubeb.notice("Trying to open device with dev_id='%s'", dev_id);
|
||||
|
||||
device_handle device = GetDevice(use_default_device ? "" : dev_id);
|
||||
|
||||
if (!device.handle)
|
||||
{
|
||||
if (use_default_device)
|
||||
{
|
||||
std::tie(dev_handle, dev_ident, dev_ch_cnt) = GetDefaultDeviceAlt(freq, sample_size, ch_cnt);
|
||||
device = GetDefaultDeviceAlt(freq, sample_size, ch_cnt);
|
||||
|
||||
if (!dev_handle)
|
||||
if (!device.handle)
|
||||
{
|
||||
Cubeb.error("Cannot detect default device. Channel count detection unavailable.");
|
||||
}
|
||||
@@ -115,15 +132,21 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
}
|
||||
}
|
||||
|
||||
if (dev_ch_cnt == 0)
|
||||
if (device.ch_cnt == 0)
|
||||
{
|
||||
Cubeb.error("Device reported invalid channel count, using stereo instead");
|
||||
dev_ch_cnt = 2;
|
||||
device.ch_cnt = 2;
|
||||
}
|
||||
|
||||
if (use_default_device)
|
||||
{
|
||||
std::lock_guard lock{m_state_cb_mutex};
|
||||
m_default_device = device.id;
|
||||
}
|
||||
|
||||
m_sampling_rate = freq;
|
||||
m_sample_size = sample_size;
|
||||
m_channels = static_cast<AudioChannelCnt>(std::min(static_cast<u32>(convert_channel_count(dev_ch_cnt)), static_cast<u32>(ch_cnt)));
|
||||
m_channels = static_cast<AudioChannelCnt>(std::min(static_cast<u32>(convert_channel_count(device.ch_cnt)), static_cast<u32>(ch_cnt)));
|
||||
full_sample_size = get_channels() * get_sample_size();
|
||||
|
||||
cubeb_stream_params stream_param{};
|
||||
@@ -141,7 +164,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
fmt::throw_exception("Invalid audio channel count");
|
||||
}
|
||||
}();
|
||||
stream_param.prefs = m_dev_collection_cb_enabled && dev_handle ? CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING : CUBEB_STREAM_PREF_NONE;
|
||||
stream_param.prefs = m_dev_collection_cb_enabled && device.handle ? CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING : CUBEB_STREAM_PREF_NONE;
|
||||
|
||||
u32 min_latency{};
|
||||
if (int err = cubeb_get_min_latency(m_ctx, &stream_param, &min_latency))
|
||||
@@ -152,7 +175,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
|
||||
const u32 stream_latency = std::max(static_cast<u32>(AUDIO_MIN_LATENCY * get_sampling_rate()), min_latency);
|
||||
|
||||
if (int err = cubeb_stream_init(m_ctx, &m_stream, "Main stream", nullptr, nullptr, dev_handle, &stream_param, stream_latency, data_cb, state_cb, this))
|
||||
if (int err = cubeb_stream_init(m_ctx, &m_stream, "Main stream", nullptr, nullptr, device.handle, &stream_param, stream_latency, data_cb, state_cb, this))
|
||||
{
|
||||
Cubeb.error("cubeb_stream_init() failed: %i", err);
|
||||
m_stream = nullptr;
|
||||
@@ -162,7 +185,7 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
if (int err = cubeb_stream_start(m_stream))
|
||||
{
|
||||
Cubeb.error("cubeb_stream_start() failed: %i", err);
|
||||
CloseUnlocked();
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -171,15 +194,10 @@ bool CubebBackend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSize
|
||||
Cubeb.error("cubeb_stream_set_volume() failed: %i", err);
|
||||
}
|
||||
|
||||
if (use_default_device)
|
||||
{
|
||||
m_current_device = dev_ident;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CubebBackend::CloseUnlocked()
|
||||
void CubebBackend::Close()
|
||||
{
|
||||
if (m_stream != nullptr)
|
||||
{
|
||||
@@ -189,21 +207,17 @@ void CubebBackend::CloseUnlocked()
|
||||
}
|
||||
|
||||
cubeb_stream_destroy(m_stream);
|
||||
m_stream = nullptr;
|
||||
}
|
||||
|
||||
m_playing = false;
|
||||
m_last_sample.fill(0);
|
||||
{
|
||||
std::lock_guard lock{m_cb_mutex};
|
||||
m_stream = nullptr;
|
||||
m_playing = false;
|
||||
m_last_sample.fill(0);
|
||||
}
|
||||
|
||||
m_default_dev_changed = false;
|
||||
m_current_device.clear();
|
||||
}
|
||||
|
||||
void CubebBackend::Close()
|
||||
{
|
||||
std::lock_guard lock(m_cb_mutex);
|
||||
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
|
||||
CloseUnlocked();
|
||||
std::lock_guard lock{m_state_cb_mutex};
|
||||
m_default_device.clear();
|
||||
}
|
||||
|
||||
void CubebBackend::Play()
|
||||
@@ -253,10 +267,13 @@ f64 CubebBackend::GetCallbackFrameLen()
|
||||
return std::max<f64>(AUDIO_MIN_LATENCY, static_cast<f64>(stream_latency) / get_sampling_rate());
|
||||
}
|
||||
|
||||
std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_view dev_id)
|
||||
CubebBackend::device_handle CubebBackend::GetDevice(std::string_view dev_id)
|
||||
{
|
||||
const bool default_dev = dev_id.empty();
|
||||
|
||||
if (default_dev) Cubeb.notice("Searching for default device");
|
||||
else Cubeb.notice("Searching for device with dev_id='%s'", dev_id);
|
||||
|
||||
cubeb_device_collection dev_collection{};
|
||||
if (int err = cubeb_enumerate_devices(m_ctx, CUBEB_DEVICE_TYPE_OUTPUT, &dev_collection))
|
||||
{
|
||||
@@ -274,14 +291,24 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
|
||||
return {};
|
||||
}
|
||||
|
||||
std::tuple<cubeb_devid, std::string, u32> result{};
|
||||
Cubeb.notice("Found %d possible output devices", dev_collection.count);
|
||||
|
||||
device_handle result{};
|
||||
|
||||
for (u64 dev_idx = 0; dev_idx < dev_collection.count; dev_idx++)
|
||||
{
|
||||
const cubeb_device_info& dev_info = dev_collection.device[dev_idx];
|
||||
const std::string dev_ident{dev_info.device_id};
|
||||
|
||||
if (dev_ident.empty())
|
||||
device_handle device{};
|
||||
device.handle = dev_info.devid;
|
||||
device.ch_cnt = dev_info.max_channels;
|
||||
|
||||
if (dev_info.device_id)
|
||||
{
|
||||
device.id = dev_info.device_id;
|
||||
}
|
||||
|
||||
if (device.id.empty())
|
||||
{
|
||||
Cubeb.error("device_id is missing from device");
|
||||
continue;
|
||||
@@ -291,17 +318,26 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
|
||||
{
|
||||
if (dev_info.preferred & CUBEB_DEVICE_PREF_MULTIMEDIA)
|
||||
{
|
||||
result = {dev_info.devid, dev_ident, dev_info.max_channels};
|
||||
result = std::move(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (dev_ident == dev_id)
|
||||
else if (device.id == dev_id)
|
||||
{
|
||||
result = {dev_info.devid, dev_ident, dev_info.max_channels};
|
||||
result = std::move(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.handle)
|
||||
{
|
||||
Cubeb.notice("Found device '%s' with %d channels", result.id, result.ch_cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cubeb.notice("No device found for dev_id='%s'", dev_id);
|
||||
}
|
||||
|
||||
if (int err = cubeb_device_collection_destroy(m_ctx, &dev_collection))
|
||||
{
|
||||
Cubeb.error("cubeb_device_collection_destroy() failed: %i", err);
|
||||
@@ -310,8 +346,10 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDevice(std::string_vi
|
||||
return result;
|
||||
};
|
||||
|
||||
std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
|
||||
CubebBackend::device_handle CubebBackend::GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt)
|
||||
{
|
||||
Cubeb.notice("Starting alternative search for default device with freq=%d, sample_size=%d and ch_cnt=%d", static_cast<u32>(freq), static_cast<u32>(sample_size), static_cast<u32>(ch_cnt));
|
||||
|
||||
cubeb_stream_params param =
|
||||
{
|
||||
.format = sample_size == AudioSampleSize::S16 ? CUBEB_SAMPLE_S16NE : CUBEB_SAMPLE_FLOAT32NE,
|
||||
@@ -340,14 +378,19 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(Audi
|
||||
|
||||
cubeb_device* crnt_dev{};
|
||||
|
||||
if (int err = cubeb_stream_get_current_device(tmp_stream, &crnt_dev))
|
||||
if (int err = cubeb_stream_get_current_device(tmp_stream, &crnt_dev); err != CUBEB_OK || !crnt_dev)
|
||||
{
|
||||
Cubeb.error("cubeb_stream_get_current_device() failed: %i", err);
|
||||
Cubeb.error("cubeb_stream_get_current_device() failed: err=%i, crnt_dev=%d", err, !!crnt_dev);
|
||||
cubeb_stream_destroy(tmp_stream);
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::string out_dev_name{crnt_dev->output_name};
|
||||
std::string out_dev_name;
|
||||
|
||||
if (crnt_dev->output_name)
|
||||
{
|
||||
out_dev_name = crnt_dev->output_name;
|
||||
}
|
||||
|
||||
if (int err = cubeb_stream_device_destroy(tmp_stream, crnt_dev))
|
||||
{
|
||||
@@ -358,19 +401,46 @@ std::tuple<cubeb_devid, std::string, u32> CubebBackend::GetDefaultDeviceAlt(Audi
|
||||
|
||||
if (out_dev_name.empty())
|
||||
{
|
||||
Cubeb.notice("No default device available");
|
||||
return {};
|
||||
}
|
||||
|
||||
return GetDevice(out_dev_name);
|
||||
}
|
||||
|
||||
long CubebBackend::data_cb(cubeb_stream* /* stream */, void* user_ptr, void const* /* input_buffer */, void* output_buffer, long nframes)
|
||||
long CubebBackend::data_cb(cubeb_stream* stream, void* user_ptr, void const* /* input_buffer */, void* output_buffer, long nframes)
|
||||
{
|
||||
if (nframes <= 0)
|
||||
{
|
||||
Cubeb.error("data_cb called with nframes=%d", nframes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!output_buffer)
|
||||
{
|
||||
Cubeb.error("data_cb called with invalid output_buffer");
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
if (!stream)
|
||||
{
|
||||
Cubeb.error("data_cb called with invalid stream");
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
|
||||
ensure(cubeb);
|
||||
|
||||
std::unique_lock lock(cubeb->m_cb_mutex, std::defer_lock);
|
||||
|
||||
if (nframes && !cubeb->m_reset_req.observe() && lock.try_lock() && cubeb->m_write_callback && cubeb->m_playing)
|
||||
if (!cubeb->m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && cubeb->m_write_callback && cubeb->m_playing)
|
||||
{
|
||||
if (stream != cubeb->m_stream)
|
||||
{
|
||||
// Cubeb.error("data_cb called with unknown stream");
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
const u32 sample_size = cubeb->full_sample_size.observe();
|
||||
const u32 bytes_req = nframes * sample_size;
|
||||
u32 written = std::min(cubeb->m_write_callback(bytes_req, output_buffer), bytes_req);
|
||||
@@ -390,65 +460,102 @@ long CubebBackend::data_cb(cubeb_stream* /* stream */, void* user_ptr, void cons
|
||||
{
|
||||
// Stream parameters are modified only after stream_destroy. stream_destroy will return
|
||||
// only after this callback returns, so it's safe to access full_sample_size here.
|
||||
memset(output_buffer, 0, nframes * cubeb->full_sample_size.observe());
|
||||
memset(output_buffer, 0, nframes * cubeb->full_sample_size);
|
||||
}
|
||||
|
||||
return nframes;
|
||||
}
|
||||
|
||||
void CubebBackend::state_cb(cubeb_stream* /* stream */, void* user_ptr, cubeb_state state)
|
||||
void CubebBackend::state_cb(cubeb_stream* stream, void* user_ptr, cubeb_state state)
|
||||
{
|
||||
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
|
||||
if (!stream)
|
||||
{
|
||||
Cubeb.error("state_cb called with invalid stream");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == CUBEB_STATE_ERROR)
|
||||
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
|
||||
ensure(cubeb);
|
||||
|
||||
std::lock_guard lock(cubeb->m_state_cb_mutex);
|
||||
|
||||
if (stream != cubeb->m_stream)
|
||||
{
|
||||
Cubeb.error("state_cb called with unknown stream");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CUBEB_STATE_ERROR:
|
||||
{
|
||||
Cubeb.error("Stream entered error state");
|
||||
|
||||
std::lock_guard lock(cubeb->m_state_cb_mutex);
|
||||
|
||||
if (!cubeb->m_reset_req.test_and_set() && cubeb->m_state_callback)
|
||||
{
|
||||
cubeb->m_state_callback(AudioStateEvent::UNSPECIFIED_ERROR);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CUBEB_STATE_STARTED:
|
||||
{
|
||||
Cubeb.notice("Stream started");
|
||||
break;
|
||||
}
|
||||
case CUBEB_STATE_STOPPED:
|
||||
{
|
||||
Cubeb.notice("Stream stopped");
|
||||
break;
|
||||
}
|
||||
case CUBEB_STATE_DRAINED:
|
||||
{
|
||||
Cubeb.notice("Stream drained");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Cubeb.notice("Stream entered unknown state %d", static_cast<u32>(state));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CubebBackend::device_collection_changed_cb(cubeb* /* context */, void* user_ptr)
|
||||
void CubebBackend::device_collection_changed_cb(cubeb* context, void* user_ptr)
|
||||
{
|
||||
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
|
||||
|
||||
Cubeb.notice("Device collection changed");
|
||||
std::lock_guard lock{cubeb->m_dev_sw_mutex};
|
||||
|
||||
// Non default device is used (or default device cannot be detected)
|
||||
if (cubeb->m_current_device.empty())
|
||||
if (!context)
|
||||
{
|
||||
Cubeb.error("device_collection_changed_cb called with invalid stream");
|
||||
return;
|
||||
}
|
||||
|
||||
CubebBackend* const cubeb = static_cast<CubebBackend*>(user_ptr);
|
||||
ensure(cubeb);
|
||||
|
||||
if (cubeb->m_reset_req.observe())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto [handle, dev_id, ch_cnt] = cubeb->GetDevice();
|
||||
if (!handle)
|
||||
{
|
||||
std::tie(handle, dev_id, ch_cnt) = cubeb->GetDefaultDeviceAlt(cubeb->m_sampling_rate, cubeb->m_sample_size, cubeb->m_channels);
|
||||
}
|
||||
|
||||
std::lock_guard cb_lock{cubeb->m_state_cb_mutex};
|
||||
|
||||
if (!handle)
|
||||
if (context != cubeb->m_ctx)
|
||||
{
|
||||
// No devices available
|
||||
if (!cubeb->m_reset_req.test_and_set() && cubeb->m_state_callback)
|
||||
{
|
||||
cubeb->m_state_callback(AudioStateEvent::UNSPECIFIED_ERROR);
|
||||
}
|
||||
Cubeb.error("device_collection_changed_cb called with unkown context");
|
||||
return;
|
||||
}
|
||||
else if (!cubeb->m_reset_req.observe() && dev_id != cubeb->m_current_device)
|
||||
{
|
||||
cubeb->m_default_dev_changed = true;
|
||||
|
||||
if (cubeb->m_state_callback)
|
||||
{
|
||||
cubeb->m_state_callback(AudioStateEvent::DEFAULT_DEVICE_CHANGED);
|
||||
}
|
||||
// Non default device is used (or default device cannot be detected)
|
||||
if (cubeb->m_default_device.empty())
|
||||
{
|
||||
Cubeb.notice("Skipping default device notification");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cubeb->m_state_callback)
|
||||
{
|
||||
cubeb->m_state_callback(AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,8 @@ private:
|
||||
|
||||
atomic_t<bool> m_reset_req = false;
|
||||
|
||||
shared_mutex m_dev_sw_mutex{};
|
||||
std::string m_current_device{};
|
||||
bool m_default_dev_changed = false;
|
||||
// Protected by callback mutex
|
||||
std::string m_default_device{};
|
||||
|
||||
bool m_dev_collection_cb_enabled = false;
|
||||
|
||||
@@ -55,8 +54,13 @@ private:
|
||||
static void state_cb(cubeb_stream* stream, void* user_ptr, cubeb_state state);
|
||||
static void device_collection_changed_cb(cubeb* context, void* user_ptr);
|
||||
|
||||
void CloseUnlocked();
|
||||
struct device_handle
|
||||
{
|
||||
cubeb_devid handle{};
|
||||
std::string id;
|
||||
u32 ch_cnt{};
|
||||
};
|
||||
|
||||
std::tuple<cubeb_devid, std::string /* dev_ident */, u32 /* ch_cnt */> GetDevice(std::string_view dev_id = "");
|
||||
std::tuple<cubeb_devid, std::string /* dev_ident */, u32 /* ch_cnt */> GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt);
|
||||
device_handle GetDevice(std::string_view dev_id = "");
|
||||
device_handle GetDefaultDeviceAlt(AudioFreq freq, AudioSampleSize sample_size, AudioChannelCnt ch_cnt);
|
||||
};
|
||||
|
||||
@@ -234,7 +234,7 @@ void FAudioBackend::OnVoiceProcessingPassStart_func(FAudioVoiceCallback *cb_obj,
|
||||
FAudioBackend *faudio = static_cast<FAudioBackend *>(cb_obj);
|
||||
|
||||
std::unique_lock lock(faudio->m_cb_mutex, std::defer_lock);
|
||||
if (BytesRequired && !faudio->m_reset_req.observe() && lock.try_lock() && faudio->m_write_callback && faudio->m_playing)
|
||||
if (BytesRequired && !faudio->m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && faudio->m_write_callback && faudio->m_playing)
|
||||
{
|
||||
ensure(BytesRequired <= faudio->m_data_buf.size(), "FAudio internal buffer is too small. Report to developers!");
|
||||
|
||||
|
||||
@@ -80,12 +80,6 @@ XAudio2Backend::XAudio2Backend()
|
||||
return;
|
||||
}
|
||||
|
||||
if (HRESULT hr = enumerator->RegisterEndpointNotificationCallback(this); FAILED(hr))
|
||||
{
|
||||
XAudio.error("RegisterEndpointNotificationCallback() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
return;
|
||||
}
|
||||
|
||||
// All succeeded, "commit"
|
||||
m_xaudio2_instance = std::move(instance);
|
||||
m_device_enumerator = std::move(enumerator);
|
||||
@@ -125,7 +119,7 @@ bool XAudio2Backend::Operational()
|
||||
|
||||
bool XAudio2Backend::DefaultDeviceChanged()
|
||||
{
|
||||
std::lock_guard lock{m_dev_sw_mutex};
|
||||
std::lock_guard lock{m_state_cb_mutex};
|
||||
return !m_reset_req.observe() && m_default_dev_changed;
|
||||
}
|
||||
|
||||
@@ -162,9 +156,12 @@ void XAudio2Backend::CloseUnlocked()
|
||||
m_master_voice = nullptr;
|
||||
}
|
||||
|
||||
m_device_enumerator->UnregisterEndpointNotificationCallback(this);
|
||||
|
||||
m_playing = false;
|
||||
m_last_sample.fill(0);
|
||||
|
||||
std::lock_guard lock(m_state_cb_mutex);
|
||||
m_default_dev_changed = false;
|
||||
m_current_device.clear();
|
||||
}
|
||||
@@ -172,7 +169,6 @@ void XAudio2Backend::CloseUnlocked()
|
||||
void XAudio2Backend::Close()
|
||||
{
|
||||
std::lock_guard lock(m_cb_mutex);
|
||||
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
|
||||
CloseUnlocked();
|
||||
}
|
||||
|
||||
@@ -207,7 +203,6 @@ bool XAudio2Backend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSi
|
||||
}
|
||||
|
||||
std::lock_guard lock(m_cb_mutex);
|
||||
std::lock_guard dev_sw_lock{m_dev_sw_mutex};
|
||||
CloseUnlocked();
|
||||
|
||||
const bool use_default_device = dev_id.empty() || dev_id == audio_device_enumerator::DEFAULT_DEV_ID;
|
||||
@@ -282,6 +277,13 @@ bool XAudio2Backend::Open(std::string_view dev_id, AudioFreq freq, AudioSampleSi
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HRESULT hr = m_device_enumerator->RegisterEndpointNotificationCallback(this); FAILED(hr))
|
||||
{
|
||||
XAudio.error("RegisterEndpointNotificationCallback() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
CloseUnlocked();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HRESULT hr = m_source_voice->SetVolume(1.0f); FAILED(hr))
|
||||
{
|
||||
XAudio.error("SetVolume() failed: %s (0x%08x)", std::system_category().message(hr), static_cast<u32>(hr));
|
||||
@@ -331,7 +333,7 @@ f64 XAudio2Backend::GetCallbackFrameLen()
|
||||
void XAudio2Backend::OnVoiceProcessingPassStart(UINT32 BytesRequired)
|
||||
{
|
||||
std::unique_lock lock(m_cb_mutex, std::defer_lock);
|
||||
if (BytesRequired && !m_reset_req.observe() && lock.try_lock() && m_write_callback && m_playing)
|
||||
if (BytesRequired && !m_reset_req.observe() && lock.try_lock_for(std::chrono::microseconds{50}) && m_write_callback && m_playing)
|
||||
{
|
||||
ensure(BytesRequired <= m_data_buf.size(), "XAudio internal buffer is too small. Report to developers!");
|
||||
|
||||
@@ -386,7 +388,7 @@ HRESULT XAudio2Backend::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWS
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::lock_guard lock{m_dev_sw_mutex};
|
||||
std::lock_guard lock(m_state_cb_mutex);
|
||||
|
||||
// Non default device is used
|
||||
if (m_current_device.empty())
|
||||
@@ -404,7 +406,7 @@ HRESULT XAudio2Backend::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWS
|
||||
|
||||
if (m_state_callback)
|
||||
{
|
||||
m_state_callback(AudioStateEvent::DEFAULT_DEVICE_CHANGED);
|
||||
m_state_callback(AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ private:
|
||||
|
||||
Microsoft::WRL::ComPtr<IMMDeviceEnumerator> m_device_enumerator{};
|
||||
|
||||
shared_mutex m_dev_sw_mutex{};
|
||||
// Protected by state callback mutex
|
||||
std::string m_current_device{};
|
||||
bool m_default_dev_changed = false;
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ target_include_directories(rpcs3_emu
|
||||
PUBLIC
|
||||
${RPCS3_SRC_DIR})
|
||||
|
||||
|
||||
# Utilities
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
../util/atomic.cpp
|
||||
../util/media_utils.cpp
|
||||
../util/video_provider.cpp
|
||||
../util/logs.cpp
|
||||
../util/yaml.cpp
|
||||
../util/vm_native.cpp
|
||||
@@ -117,7 +117,6 @@ target_sources(rpcs3_emu PRIVATE
|
||||
../Loader/TRP.cpp
|
||||
)
|
||||
|
||||
|
||||
# Audio
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Audio/audio_resampler.cpp
|
||||
@@ -160,6 +159,10 @@ target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::soundtouch)
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::miniupnpc)
|
||||
|
||||
# Cell
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Cell/MFC.cpp
|
||||
@@ -188,6 +191,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
Cell/lv2/sys_event.cpp
|
||||
Cell/lv2/sys_event_flag.cpp
|
||||
Cell/lv2/sys_fs.cpp
|
||||
Cell/lv2/sys_game.cpp
|
||||
Cell/lv2/sys_gamepad.cpp
|
||||
Cell/lv2/sys_gpio.cpp
|
||||
Cell/lv2/sys_hid.cpp
|
||||
@@ -322,6 +326,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
Cell/Modules/cellVoice.cpp
|
||||
Cell/Modules/cellVpost.cpp
|
||||
Cell/Modules/cellWebBrowser.cpp
|
||||
Cell/Modules/HLE_PATCHES.cpp
|
||||
Cell/Modules/libad_async.cpp
|
||||
Cell/Modules/libad_core.cpp
|
||||
Cell/Modules/libmedi.cpp
|
||||
@@ -339,7 +344,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
Cell/Modules/sceNpUtil.cpp
|
||||
Cell/Modules/StaticHLE.cpp
|
||||
Cell/Modules/sys_crashdump.cpp
|
||||
Cell/Modules/sys_game.cpp
|
||||
Cell/Modules/sys_game_.cpp
|
||||
Cell/Modules/sys_heap.cpp
|
||||
Cell/Modules/sys_io_.cpp
|
||||
Cell/Modules/sys_libc_.cpp
|
||||
@@ -381,12 +386,14 @@ target_link_libraries(rpcs3_emu
|
||||
# Io
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Io/camera_config.cpp
|
||||
Io/recording_config.cpp
|
||||
Io/interception.cpp
|
||||
Io/KeyboardHandler.cpp
|
||||
Io/pad_config.cpp
|
||||
Io/pad_config_types.cpp
|
||||
Io/PadHandler.cpp
|
||||
Io/usb_device.cpp
|
||||
Io/usb_vfs.cpp
|
||||
Io/Skylander.cpp
|
||||
Io/GHLtar.cpp
|
||||
Io/Buzz.cpp
|
||||
@@ -408,6 +415,8 @@ target_sources(rpcs3_emu PRIVATE
|
||||
NP/np_structs_extra.cpp
|
||||
NP/rpcn_client.cpp
|
||||
NP/rpcn_config.cpp
|
||||
NP/upnp_config.cpp
|
||||
NP/upnp_handler.cpp
|
||||
)
|
||||
|
||||
# Memory
|
||||
@@ -415,7 +424,6 @@ target_sources(rpcs3_emu PRIVATE
|
||||
Memory/vm.cpp
|
||||
)
|
||||
|
||||
|
||||
# RSX
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
RSX/gcm_enums.cpp
|
||||
@@ -435,12 +443,20 @@ target_sources(rpcs3_emu PRIVATE
|
||||
RSX/Common/TextureUtils.cpp
|
||||
RSX/Common/texture_cache.cpp
|
||||
RSX/Null/NullGSRender.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu_components.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu_main_menu.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu_message_box.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu_page.cpp
|
||||
RSX/Overlays/HomeMenu/overlay_home_menu_settings.cpp
|
||||
RSX/Overlays/overlay_animated_icon.cpp
|
||||
RSX/Overlays/overlay_animation.cpp
|
||||
RSX/Overlays/overlay_controls.cpp
|
||||
RSX/Overlays/overlay_cursor.cpp
|
||||
RSX/Overlays/overlay_edit_text.cpp
|
||||
RSX/Overlays/overlay_fonts.cpp
|
||||
RSX/Overlays/overlay_list_view.cpp
|
||||
RSX/Overlays/overlay_manager.cpp
|
||||
RSX/Overlays/overlay_media_list_dialog.cpp
|
||||
RSX/Overlays/overlay_message.cpp
|
||||
RSX/Overlays/overlay_message_dialog.cpp
|
||||
@@ -449,10 +465,10 @@ target_sources(rpcs3_emu PRIVATE
|
||||
RSX/Overlays/overlay_perf_metrics.cpp
|
||||
RSX/Overlays/overlay_progress_bar.cpp
|
||||
RSX/Overlays/overlay_save_dialog.cpp
|
||||
RSX/Overlays/overlay_shader_compile_notification.cpp
|
||||
RSX/Overlays/overlay_user_list_dialog.cpp
|
||||
RSX/Overlays/overlay_utils.cpp
|
||||
RSX/Overlays/overlays.cpp
|
||||
RSX/Overlays/overlay_shader_compile_notification.cpp
|
||||
RSX/Overlays/overlay_trophy_notification.cpp
|
||||
RSX/Overlays/Shaders/shader_loading_dialog.cpp
|
||||
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
|
||||
@@ -467,6 +483,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||
RSX/Capture/rsx_replay.cpp
|
||||
RSX/GL/glutils/blitter.cpp
|
||||
RSX/GL/glutils/buffer_object.cpp
|
||||
RSX/GL/glutils/capabilities.cpp
|
||||
RSX/GL/glutils/common.cpp
|
||||
RSX/GL/glutils/fbo.cpp
|
||||
RSX/GL/glutils/image.cpp
|
||||
@@ -539,7 +556,7 @@ endif()
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::ffmpeg
|
||||
3rdparty::ffmpeg 3rdparty::sdl2
|
||||
3rdparty::opengl 3rdparty::stblib
|
||||
3rdparty::vulkan 3rdparty::glew
|
||||
3rdparty::libusb 3rdparty::wolfssl
|
||||
@@ -550,7 +567,7 @@ target_link_libraries(rpcs3_emu
|
||||
if(APPLE)
|
||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
||||
if (${HAVE_CLOCK_GETTIME})
|
||||
target_compile_definitions(rpcs3_emu PUBLIC -DHAVE_CLOCK_GETTIME)
|
||||
target_compile_definitions(rpcs3_emu PUBLIC -DHAVE_CLOCK_GETTIME)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
+142
-35
@@ -5,6 +5,7 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/Memory/vm_locking.h"
|
||||
#include "Emu/Memory/vm_reservation.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/GDB.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
@@ -54,6 +55,9 @@ void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
|
||||
case cpu_flag::memory: return "mem";
|
||||
case cpu_flag::pending: return "pend";
|
||||
case cpu_flag::pending_recheck: return "pend-re";
|
||||
case cpu_flag::notify: return "ntf";
|
||||
case cpu_flag::yield: return "y";
|
||||
case cpu_flag::preempt: return "PREEMPT";
|
||||
case cpu_flag::dbg_global_pause: return "G-PAUSE";
|
||||
case cpu_flag::dbg_pause: return "PAUSE";
|
||||
case cpu_flag::dbg_step: return "STEP";
|
||||
@@ -84,15 +88,18 @@ struct cpu_prof
|
||||
// Total number of samples
|
||||
u64 samples = 0, idle = 0;
|
||||
|
||||
// Avoid printing replicas
|
||||
bool printed = false;
|
||||
// Avoid printing replicas or when not much changed
|
||||
u64 new_samples = 0;
|
||||
|
||||
static constexpr u64 min_print_samples = 500;
|
||||
static constexpr u64 min_print_all_samples = min_print_samples * 20;
|
||||
|
||||
void reset()
|
||||
{
|
||||
freq.clear();
|
||||
samples = 0;
|
||||
idle = 0;
|
||||
printed = false;
|
||||
new_samples = 0;
|
||||
}
|
||||
|
||||
static std::string format(const std::multimap<u64, u64, std::greater<u64>>& chart, u64 samples, u64 idle, bool extended_print = false)
|
||||
@@ -128,8 +135,13 @@ struct cpu_prof
|
||||
// Print info
|
||||
void print(const std::shared_ptr<cpu_thread>& ptr)
|
||||
{
|
||||
if (printed || samples == idle)
|
||||
if (new_samples < min_print_samples || samples == idle)
|
||||
{
|
||||
if (cpu_flag::exit - ptr->state)
|
||||
{
|
||||
profiler.notice("Thread \"%s\" [0x%08x]: %u samples, %u new (%.4f%% idle): Not enough new samples have been collected since the last print.", ptr->get_name(), ptr->id, samples, new_samples, 100. * idle / samples);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,13 +155,22 @@ struct cpu_prof
|
||||
|
||||
// Print results
|
||||
const std::string results = format(chart, samples, idle);
|
||||
profiler.notice("Thread \"%s\" [0x%08x]: %u samples (%.4f%% idle):%s", ptr->get_name(), ptr->id, samples, 100. * idle / samples, results);
|
||||
profiler.notice("Thread \"%s\" [0x%08x]: %u samples, %u new (%.4f%% idle):%s", ptr->get_name(), ptr->id, samples, new_samples, 100. * idle / samples, results);
|
||||
|
||||
printed = true;
|
||||
new_samples = 0;
|
||||
}
|
||||
|
||||
static void print_all(const std::unordered_map<std::shared_ptr<cpu_thread>, sample_info>& threads)
|
||||
static void print_all(std::unordered_map<std::shared_ptr<cpu_thread>, sample_info>& threads)
|
||||
{
|
||||
u64 new_samples = 0;
|
||||
|
||||
// Print all results and cleanup
|
||||
for (auto& [ptr, info] : threads)
|
||||
{
|
||||
new_samples += info.new_samples;
|
||||
info.print(ptr);
|
||||
}
|
||||
|
||||
std::multimap<u64, u64, std::greater<u64>> chart;
|
||||
|
||||
std::unordered_map<u64, u64, value_hash<u64>> freq;
|
||||
@@ -158,7 +179,7 @@ struct cpu_prof
|
||||
|
||||
for (auto& [_, info] : threads)
|
||||
{
|
||||
// This function collects thread information regardless of 'printed' member state
|
||||
// This function collects thread information regardless of 'new_samples' member state
|
||||
for (auto& [name, count] : info.freq)
|
||||
{
|
||||
freq[name] += count;
|
||||
@@ -168,18 +189,24 @@ struct cpu_prof
|
||||
idle += info.idle;
|
||||
}
|
||||
|
||||
for (auto& [name, count] : freq)
|
||||
{
|
||||
chart.emplace(count, name);
|
||||
}
|
||||
|
||||
if (samples == idle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_samples < min_print_all_samples && thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
profiler.notice("All Threads: %u samples, %u new (%.4f%% idle): Not enough new samples have been collected since the last print.", samples, new_samples, 100. * idle / samples);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& [name, count] : freq)
|
||||
{
|
||||
chart.emplace(count, name);
|
||||
}
|
||||
|
||||
const std::string results = format(chart, samples, idle, true);
|
||||
profiler.notice("All Threads: %u samples (%.4f%% idle):%s", samples, 100. * idle / samples, results);
|
||||
profiler.notice("All Threads: %u samples, %u new (%.4f%% idle):%s", samples, new_samples, 100. * idle / samples, results);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -240,7 +267,7 @@ struct cpu_prof
|
||||
// Sample active threads
|
||||
for (auto& [ptr, info] : threads)
|
||||
{
|
||||
if (cpu_flag::exit - ptr->state)
|
||||
if (auto state = +ptr->state; cpu_flag::exit - state)
|
||||
{
|
||||
// Get short function hash
|
||||
const u64 name = atomic_storage<u64>::load(ptr->block_hash);
|
||||
@@ -248,9 +275,10 @@ struct cpu_prof
|
||||
// Append occurrence
|
||||
info.samples++;
|
||||
|
||||
if (auto state = +ptr->state; !::is_paused(state) && !::is_stopped(state) && cpu_flag::wait - state)
|
||||
if (cpu_flag::wait - state)
|
||||
{
|
||||
info.freq[name]++;
|
||||
info.new_samples++;
|
||||
|
||||
// Append verification time to fixed common name 0000000...chunk-0x3fffc
|
||||
if (name >> 16 && (name & 0xffff) == 0)
|
||||
@@ -258,6 +286,12 @@ struct cpu_prof
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state & (cpu_flag::dbg_pause + cpu_flag::dbg_global_pause))
|
||||
{
|
||||
// Idle state caused by emulation pause is not accounted for
|
||||
continue;
|
||||
}
|
||||
|
||||
info.idle++;
|
||||
}
|
||||
}
|
||||
@@ -271,11 +305,13 @@ struct cpu_prof
|
||||
{
|
||||
profiler.success("Flushing profiling results...");
|
||||
|
||||
// Print all results and cleanup
|
||||
for (auto& [ptr, info] : threads)
|
||||
{
|
||||
info.print(ptr);
|
||||
}
|
||||
sample_info::print_all(threads);
|
||||
}
|
||||
|
||||
if (Emu.IsPaused())
|
||||
{
|
||||
thread_ctrl::wait_for(5000);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Wait, roughly for 20µs
|
||||
@@ -283,11 +319,6 @@ struct cpu_prof
|
||||
}
|
||||
|
||||
// Print all remaining results
|
||||
for (auto& [ptr, info] : threads)
|
||||
{
|
||||
info.print(ptr);
|
||||
}
|
||||
|
||||
sample_info::print_all(threads);
|
||||
}
|
||||
|
||||
@@ -574,6 +605,7 @@ void cpu_thread::operator()()
|
||||
if (!(state0 & cpu_flag::stop))
|
||||
{
|
||||
cpu_task();
|
||||
state += cpu_flag::wait;
|
||||
|
||||
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
|
||||
{
|
||||
@@ -583,7 +615,7 @@ void cpu_thread::operator()()
|
||||
continue;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_on(state, state0);
|
||||
state.wait(state0);
|
||||
|
||||
if (state & cpu_flag::ret && state.test_and_reset(cpu_flag::ret))
|
||||
{
|
||||
@@ -635,20 +667,22 @@ cpu_thread::cpu_thread(u32 id)
|
||||
|
||||
void cpu_thread::cpu_wait(bs_t<cpu_flag> old)
|
||||
{
|
||||
thread_ctrl::wait_on(state, old);
|
||||
state.wait(old);
|
||||
}
|
||||
|
||||
static atomic_t<u32> s_dummy_atomic = 0;
|
||||
|
||||
bool cpu_thread::check_state() noexcept
|
||||
{
|
||||
bool cpu_sleep_called = false;
|
||||
bool cpu_can_stop = true;
|
||||
bool escape, retval;
|
||||
bool escape{}, retval{};
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Process all flags in a single atomic op
|
||||
bs_t<cpu_flag> state1;
|
||||
const auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
||||
auto state0 = state.fetch_op([&](bs_t<cpu_flag>& flags)
|
||||
{
|
||||
bool store = false;
|
||||
|
||||
@@ -688,7 +722,6 @@ bool cpu_thread::check_state() noexcept
|
||||
{
|
||||
// Sticky flag, indicates check_state() is not allowed to return true
|
||||
flags -= cpu_flag::temp;
|
||||
flags -= cpu_flag::wait;
|
||||
cpu_can_stop = false;
|
||||
store = true;
|
||||
}
|
||||
@@ -730,7 +763,7 @@ bool cpu_thread::check_state() noexcept
|
||||
if (!is_stopped(flags) && flags.none_of(cpu_flag::ret))
|
||||
{
|
||||
// Check pause flags which hold thread inside check_state (ignore suspend/debug flags on cpu_flag::temp)
|
||||
if (flags & (cpu_flag::pause + cpu_flag::memory) || (cpu_can_stop && flags & (cpu_flag::dbg_global_pause + cpu_flag::dbg_pause + cpu_flag::suspend)))
|
||||
if (flags & (cpu_flag::pause + cpu_flag::memory) || (cpu_can_stop && flags & (cpu_flag::dbg_global_pause + cpu_flag::dbg_pause + cpu_flag::suspend + cpu_flag::yield + cpu_flag::preempt)))
|
||||
{
|
||||
if (!(flags & cpu_flag::wait))
|
||||
{
|
||||
@@ -738,6 +771,12 @@ bool cpu_thread::check_state() noexcept
|
||||
store = true;
|
||||
}
|
||||
|
||||
if (flags & (cpu_flag::yield + cpu_flag::preempt) && cpu_can_stop)
|
||||
{
|
||||
flags -= (cpu_flag::yield + cpu_flag::preempt);
|
||||
store = true;
|
||||
}
|
||||
|
||||
escape = false;
|
||||
state1 = flags;
|
||||
return store;
|
||||
@@ -753,9 +792,9 @@ bool cpu_thread::check_state() noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cpu_can_stop && !(flags & cpu_flag::wait))
|
||||
if (flags & cpu_flag::wait)
|
||||
{
|
||||
flags += cpu_flag::wait;
|
||||
flags -= cpu_flag::wait;
|
||||
store = true;
|
||||
}
|
||||
|
||||
@@ -767,6 +806,34 @@ bool cpu_thread::check_state() noexcept
|
||||
return store;
|
||||
}).first;
|
||||
|
||||
if (state0 & cpu_flag::preempt && cpu_can_stop)
|
||||
{
|
||||
if (cpu_flag::wait - state0)
|
||||
{
|
||||
if (!escape || !retval)
|
||||
{
|
||||
// Yield itself
|
||||
state0 += cpu_flag::yield;
|
||||
escape = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (const u128 bits = s_cpu_bits)
|
||||
{
|
||||
reader_lock lock(s_cpu_lock);
|
||||
|
||||
cpu_counter::for_all_cpu(bits & s_cpu_bits, [](cpu_thread* cpu)
|
||||
{
|
||||
if (cpu->state.none_of(cpu_flag::wait + cpu_flag::yield))
|
||||
{
|
||||
cpu->state += cpu_flag::yield;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (escape)
|
||||
{
|
||||
if (s_tls_thread_slot == umax && !retval)
|
||||
@@ -855,6 +922,32 @@ bool cpu_thread::check_state() noexcept
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state0 & cpu_flag::yield && cpu_flag::wait - state0 && cpu_can_stop)
|
||||
{
|
||||
if (auto spu = try_get<spu_thread>())
|
||||
{
|
||||
if (spu->raddr && spu->rtime == vm::reservation_acquire(spu->raddr) && spu->getllar_spin_count < 10)
|
||||
{
|
||||
// Reservation operation is a critical section (but this may result in false positives)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (auto ppu = try_get<ppu_thread>())
|
||||
{
|
||||
if (ppu->raddr && ppu->rtime == vm::reservation_acquire(ppu->raddr))
|
||||
{
|
||||
// Same
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Short sleep when yield flag is present alone (makes no sense when other methods which can stop thread execution have been done)
|
||||
// Pass a mask of a single bit which is often unused to avoid notifications
|
||||
s_dummy_atomic.wait(0, 1u << 30, atomic_wait_timeout{80'000});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -892,6 +985,14 @@ cpu_thread& cpu_thread::operator=(thread_state)
|
||||
if (old & cpu_flag::wait && old.none_of(cpu_flag::again + cpu_flag::exit))
|
||||
{
|
||||
state.notify_one(cpu_flag::exit);
|
||||
|
||||
if (auto thread = try_get<spu_thread>())
|
||||
{
|
||||
if (u32 resv = atomic_storage<u32>::load(thread->raddr))
|
||||
{
|
||||
vm::reservation_notifier(resv).notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
@@ -1232,13 +1333,19 @@ u32 CPUDisAsm::DisAsmBranchTarget(s32 /*imm*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates()
|
||||
extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock)
|
||||
{
|
||||
const u64 start = get_system_time();
|
||||
|
||||
// Attempt to lock for half a second, if somehow takes longer abort it
|
||||
do
|
||||
{
|
||||
if (revert_lock)
|
||||
{
|
||||
// Revert the operation of this function
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpu_thread::suspend_all(nullptr, {}, []()
|
||||
{
|
||||
return idm::select<named_thread<spu_thread>>([](u32, spu_thread& spu)
|
||||
|
||||
@@ -25,6 +25,8 @@ enum class cpu_flag : u32
|
||||
pending, // Thread has postponed work
|
||||
pending_recheck, // Thread needs to recheck if there is pending work before ::pending removal
|
||||
notify, // Flag meant solely to allow atomic notification on state without changing other flags
|
||||
yield, // Thread is being requested to yield its execution time if it's running
|
||||
preempt, // Thread is being requested to preempt the execution of all CPU threads
|
||||
|
||||
dbg_global_pause, // Emulation paused
|
||||
dbg_pause, // Thread paused
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "util/types.hpp"
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Utilities/BitField.h"
|
||||
#include "Utilities/JIT.h"
|
||||
@@ -3442,6 +3443,11 @@ public:
|
||||
template <typename T1, typename T2, typename T3>
|
||||
value_t<u8[16]> vperm2b(T1 a, T2 b, T3 c)
|
||||
{
|
||||
if (!utils::has_fast_vperm2b())
|
||||
{
|
||||
return vperm2b256to128(a, b, c);
|
||||
}
|
||||
|
||||
value_t<u8[16]> result;
|
||||
|
||||
const auto data0 = a.eval(m_ir);
|
||||
|
||||
+35
-16
@@ -3,35 +3,54 @@
|
||||
#include "util/types.hpp"
|
||||
#include "Utilities/StrFmt.h"
|
||||
|
||||
namespace logs
|
||||
{
|
||||
struct message;
|
||||
}
|
||||
|
||||
// Error code type (return type), implements error reporting.
|
||||
class error_code
|
||||
{
|
||||
s32 value;
|
||||
|
||||
public:
|
||||
error_code() = default;
|
||||
|
||||
// Implementation must be provided independently
|
||||
static s32 error_report(s32 result, const char* fmt, const fmt_type_info* sup, const u64* args);
|
||||
|
||||
// Common constructor
|
||||
template<typename ET>
|
||||
error_code(const ET& value)
|
||||
: value(error_report(static_cast<s32>(value), " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
|
||||
template <typename ET> requires requires (ET v) { static_cast<s32>(v); }
|
||||
error_code(const logs::message* ch, const ET& value) noexcept
|
||||
: value(error_report(static_cast<s32>(value), ch, " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
|
||||
{
|
||||
}
|
||||
|
||||
// Error constructor (2 args)
|
||||
template<typename ET, typename T>
|
||||
error_code(const ET& value, const T& arg)
|
||||
: value(error_report(static_cast<s32>(value), " : %s, %s", fmt::type_info_v<ET, T>, fmt_args_t<ET, T>{fmt_unveil<ET>::get(value), fmt_unveil<T>::get(arg)}))
|
||||
template <typename ET, typename T> requires requires (ET v) { static_cast<s32>(v); }
|
||||
error_code(const logs::message* ch, const ET& value, const T& arg) noexcept
|
||||
: value(error_report(static_cast<s32>(value), ch, " : %s, %s", fmt::type_info_v<ET, T>, fmt_args_t<ET, T>{fmt_unveil<ET>::get(value), fmt_unveil<T>::get(arg)}))
|
||||
{
|
||||
}
|
||||
|
||||
// Formatting constructor (error, format string, variadic list)
|
||||
template <typename ET, typename... Args> requires (sizeof...(Args) > 0)
|
||||
error_code(const ET& value, const const_str& fmt, const Args&... args)
|
||||
: value(error_report(static_cast<s32>(value), fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...}))
|
||||
template <typename ET, typename... Args> requires requires (ET v) { static_cast<s32>(v); }
|
||||
error_code(const logs::message* ch, const ET& value, const const_str& fmt, const Args&... args) noexcept
|
||||
: value(error_report(static_cast<s32>(value), ch, fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...}))
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Implementation must be provided independently
|
||||
static s32 error_report(s32 result, const logs::message* channel, const char* fmt, const fmt_type_info* sup, const u64* args);
|
||||
|
||||
error_code() = default;
|
||||
|
||||
// Constructor without channel
|
||||
template <typename... Args> requires (sizeof...(Args) > 0 && !(std::is_same_v<std::decay_t<std::remove_pointer_t<Args>>, logs::message> || ...))
|
||||
error_code(const Args&... args) noexcept
|
||||
: error_code(std::add_pointer_t<const logs::message>{}, args...)
|
||||
{
|
||||
}
|
||||
|
||||
// Constructor with channel
|
||||
template <typename... Args>
|
||||
error_code(const logs::message& ch, const Args&... args) noexcept
|
||||
: error_code(std::addressof(ch), args...)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -51,7 +70,7 @@ enum CellNotAnError : s32
|
||||
|
||||
// Constructor specialization that doesn't trigger reporting
|
||||
template <>
|
||||
constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value)
|
||||
constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value) noexcept
|
||||
: value(value)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Utilities/Thread.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_spu.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
// SONIC THE HEDGEDOG: a fix for a race condition between SPUs and PPUs causing missing graphics (SNR is overriden when non-empty)
|
||||
void WaitForSPUsToEmptySNRs(ppu_thread& ppu, u32 spu_id, u32 snr_mask)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
auto [spu, group] = lv2_spu_group::get_thread(spu_id);
|
||||
|
||||
if ((!spu && spu_id != umax) || snr_mask % 4 == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait until specified SNRs are reported empty at least once
|
||||
for (bool has_busy = true; has_busy && !ppu.is_stopped(); std::this_thread::yield())
|
||||
{
|
||||
has_busy = false;
|
||||
|
||||
auto for_one = [&](u32, spu_thread& spu)
|
||||
{
|
||||
if ((snr_mask & 1) && spu.ch_snr1.get_count())
|
||||
{
|
||||
has_busy = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((snr_mask & 2) && spu.ch_snr2.get_count())
|
||||
{
|
||||
has_busy = true;
|
||||
}
|
||||
};
|
||||
|
||||
if (spu)
|
||||
{
|
||||
// Wait for a single SPU
|
||||
for_one(spu->id, *spu);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for all SPUs
|
||||
idm::select<named_thread<spu_thread>>(for_one);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::hle_patches)("RPCS3_HLE_LIBRARY", []()
|
||||
{
|
||||
REG_FUNC(RPCS3_HLE_LIBRARY, WaitForSPUsToEmptySNRs);
|
||||
});
|
||||
@@ -162,8 +162,8 @@ bool statichle_handler::check_against_patterns(vm::cptr<u8>& data, u32 size, u32
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto sfunc = &smodule->functions.at(pat.fnid);
|
||||
const u32 target = g_fxo->get<ppu_function_manager>().func_addr(sfunc->index) + 4;
|
||||
const auto sfunc = &::at32(smodule->functions, pat.fnid);
|
||||
const u32 target = g_fxo->get<ppu_function_manager>().func_addr(sfunc->index, true);
|
||||
|
||||
// write stub
|
||||
vm::write32(addr, ppu_instructions::LIS(0, (target&0xFFFF0000)>>16));
|
||||
|
||||
@@ -282,15 +282,10 @@ public:
|
||||
|
||||
struct AudioReader
|
||||
{
|
||||
u32 addr;
|
||||
u32 size;
|
||||
bool init;
|
||||
bool has_ats;
|
||||
|
||||
AudioReader()
|
||||
: init(false)
|
||||
{
|
||||
}
|
||||
u32 addr{};
|
||||
u32 size{};
|
||||
bool init{};
|
||||
bool has_ats{};
|
||||
|
||||
} reader;
|
||||
|
||||
@@ -304,13 +299,14 @@ public:
|
||||
u32 memBias = 0;
|
||||
|
||||
AdecTask task;
|
||||
u64 last_pts, first_pts;
|
||||
u64 last_pts{};
|
||||
u64 first_pts{};
|
||||
|
||||
u32 ch_out;
|
||||
u32 ch_cfg;
|
||||
u32 frame_size;
|
||||
u32 sample_rate;
|
||||
bool use_ats_headers;
|
||||
u32 ch_out{};
|
||||
u32 ch_cfg{};
|
||||
u32 frame_size{};
|
||||
u32 sample_rate{};
|
||||
bool use_ats_headers{};
|
||||
|
||||
AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg)
|
||||
: ppu_thread({}, "", 0)
|
||||
@@ -454,30 +450,8 @@ public:
|
||||
if (adecIsAtracX(type)) last_pts -= 0x10000; // hack
|
||||
}
|
||||
|
||||
struct AVPacketHolder : AVPacket
|
||||
{
|
||||
AVPacketHolder(u32 data_size)
|
||||
{
|
||||
av_init_packet(this);
|
||||
|
||||
if (data_size)
|
||||
{
|
||||
this->data = static_cast<u8*>(av_calloc(1, data_size + AV_INPUT_BUFFER_PADDING_SIZE));
|
||||
this->size = data_size + AV_INPUT_BUFFER_PADDING_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->data = nullptr;
|
||||
this->size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~AVPacketHolder()
|
||||
{
|
||||
av_free(data);
|
||||
}
|
||||
|
||||
} au(0);
|
||||
AVPacket* packet = av_packet_alloc();
|
||||
std::unique_ptr<AVPacket, decltype([](AVPacket* p){av_packet_unref(p);})> packet_(packet);
|
||||
|
||||
if (just_started && just_finished)
|
||||
{
|
||||
@@ -544,8 +518,6 @@ public:
|
||||
just_started = false;
|
||||
}
|
||||
|
||||
bool last_frame = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (Emu.IsStopped() || is_closed)
|
||||
@@ -554,14 +526,7 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
last_frame = av_read_frame(fmt, &au) < 0;
|
||||
if (last_frame)
|
||||
{
|
||||
//break;
|
||||
av_free(au.data);
|
||||
au.data = NULL;
|
||||
au.size = 0;
|
||||
}
|
||||
av_read_frame(fmt, packet);
|
||||
|
||||
struct AdecFrameHolder : AdecFrame
|
||||
{
|
||||
|
||||
@@ -158,6 +158,7 @@ audio_ringbuffer::audio_ringbuffer(cell_audio_config& _cfg)
|
||||
|
||||
cb_ringbuf.set_buf_size(static_cast<u32>(static_cast<u32>(cfg.backend_ch_cnt) * cfg.audio_sampling_rate * cfg.audio_sample_size * buffer_dur_mult));
|
||||
backend->SetWriteCallback(std::bind(&audio_ringbuffer::backend_write_callback, this, std::placeholders::_1, std::placeholders::_2));
|
||||
backend->SetStateCallback(std::bind(&audio_ringbuffer::backend_state_callback, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
audio_ringbuffer::~audio_ringbuffer()
|
||||
@@ -191,6 +192,14 @@ u32 audio_ringbuffer::backend_write_callback(u32 size, void *buf)
|
||||
return static_cast<u32>(cb_ringbuf.pop(buf, size, true));
|
||||
}
|
||||
|
||||
void audio_ringbuffer::backend_state_callback(AudioStateEvent event)
|
||||
{
|
||||
if (event == AudioStateEvent::DEFAULT_DEVICE_MAYBE_CHANGED)
|
||||
{
|
||||
backend_device_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
u64 audio_ringbuffer::get_timestamp()
|
||||
{
|
||||
return get_system_time();
|
||||
@@ -683,7 +692,6 @@ void cell_audio_thread::reset_counters()
|
||||
m_start_time = ringbuffer->get_timestamp();
|
||||
m_last_period_end = m_start_time;
|
||||
m_dynamic_period = 0;
|
||||
m_backend_failed = false;
|
||||
m_audio_should_restart = true;
|
||||
}
|
||||
|
||||
@@ -720,9 +728,13 @@ void cell_audio_thread::operator()()
|
||||
|
||||
u32 untouched_expected = 0;
|
||||
|
||||
u32 loop_count = 0;
|
||||
|
||||
// Main cellAudio loop
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
loop_count++;
|
||||
|
||||
const auto update_req = m_update_configuration.observe();
|
||||
if (update_req != audio_backend_update::NONE)
|
||||
{
|
||||
@@ -735,37 +747,8 @@ void cell_audio_thread::operator()()
|
||||
update_config(update_req == audio_backend_update::ALL);
|
||||
}
|
||||
|
||||
if (!ringbuffer->get_operational_status())
|
||||
{
|
||||
if (m_backend_failed)
|
||||
{
|
||||
thread_ctrl::wait_for(500 * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellAudio.warning("Backend stopped unexpectedly (likely device change). Attempting to recover...");
|
||||
}
|
||||
|
||||
update_config(true);
|
||||
m_backend_failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ringbuffer->device_changed())
|
||||
{
|
||||
cellAudio.warning("Default device changed, attempting to switch...");
|
||||
update_config(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_backend_failed)
|
||||
{
|
||||
cellAudio.warning("Backend recovered");
|
||||
m_backend_failed = false;
|
||||
}
|
||||
|
||||
const bool emu_paused = Emu.IsPaused();
|
||||
const u64 timestamp = ringbuffer->update(emu_paused);
|
||||
const u64 timestamp = ringbuffer->update(emu_paused || m_backend_failed);
|
||||
|
||||
if (emu_paused)
|
||||
{
|
||||
@@ -803,6 +786,36 @@ void cell_audio_thread::operator()()
|
||||
continue;
|
||||
}
|
||||
|
||||
bool operational = ringbuffer->get_operational_status();
|
||||
|
||||
if (!operational && loop_count % 128 == 0)
|
||||
{
|
||||
update_config(true);
|
||||
operational = ringbuffer->get_operational_status();
|
||||
}
|
||||
|
||||
if (ringbuffer->device_changed())
|
||||
{
|
||||
cellAudio.warning("Default device changed, attempting to switch...");
|
||||
update_config(false);
|
||||
|
||||
if (operational != ringbuffer->get_operational_status())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_backend_failed && !operational)
|
||||
{
|
||||
cellAudio.error("Backend stopped unexpectedly (likely device change). Attempting to recover...");
|
||||
m_backend_failed = true;
|
||||
}
|
||||
else if (m_backend_failed && operational)
|
||||
{
|
||||
cellAudio.success("Backend recovered");
|
||||
m_backend_failed = false;
|
||||
}
|
||||
|
||||
if (!cfg.buffering_enabled)
|
||||
{
|
||||
const u64 period_end = (m_counter * cfg.audio_block_period) + m_start_time;
|
||||
@@ -906,7 +919,7 @@ void cell_audio_thread::operator()()
|
||||
// As such, if the game doesn't touch buffers for too long we advance time hoping the game recovers
|
||||
if (
|
||||
(untouched == active_ports && time_since_last_period > cfg.fully_untouched_timeout) ||
|
||||
(time_since_last_period > cfg.partially_untouched_timeout)
|
||||
(time_since_last_period > cfg.partially_untouched_timeout) || g_cfg.audio.disable_sampling_skip
|
||||
)
|
||||
{
|
||||
// There's no audio in the buffers, simply advance time and hope the game recovers
|
||||
@@ -1859,12 +1872,13 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
{
|
||||
for (u32 i = 0; i < CELL_AUDIO_BLOCK_SAMPLES; i++)
|
||||
{
|
||||
// Channel order in src is Front Left, Center, Front Right, Surround Left, Surround Right, LFE
|
||||
dst[i * 8 + 0] += src[i * 6 + 0] * volume; // mix L ch
|
||||
dst[i * 8 + 1] += src[i * 6 + 1] * volume; // mix R ch
|
||||
dst[i * 8 + 2] += src[i * 6 + 2] * volume; // mix center
|
||||
dst[i * 8 + 3] += src[i * 6 + 3] * volume; // mix LFE
|
||||
dst[i * 8 + 4] += src[i * 6 + 4] * volume; // mix rear L
|
||||
dst[i * 8 + 5] += src[i * 6 + 5] * volume; // mix rear R
|
||||
dst[i * 8 + 1] += src[i * 6 + 2] * volume; // mix R ch
|
||||
dst[i * 8 + 2] += src[i * 6 + 1] * volume; // mix center
|
||||
dst[i * 8 + 3] += src[i * 6 + 5] * volume; // mix LFE
|
||||
dst[i * 8 + 4] += src[i * 6 + 3] * volume; // mix rear L
|
||||
dst[i * 8 + 5] += src[i * 6 + 4] * volume; // mix rear R
|
||||
//dst[i * 8 + 6] += 0.0f; // side L
|
||||
//dst[i * 8 + 7] += 0.0f; // side R
|
||||
}
|
||||
|
||||
@@ -292,6 +292,7 @@ private:
|
||||
audio_resampler resampler{};
|
||||
|
||||
atomic_t<bool> backend_active = false;
|
||||
atomic_t<bool> backend_device_changed = false;
|
||||
bool playing = false;
|
||||
|
||||
u64 update_timestamp = 0;
|
||||
@@ -310,6 +311,7 @@ private:
|
||||
|
||||
void commit_data(f32* buf, u32 sample_cnt);
|
||||
u32 backend_write_callback(u32 size, void *buf);
|
||||
void backend_state_callback(AudioStateEvent event);
|
||||
|
||||
public:
|
||||
audio_ringbuffer(cell_audio_config &cfg);
|
||||
@@ -345,9 +347,9 @@ public:
|
||||
return backend->Operational();
|
||||
}
|
||||
|
||||
bool device_changed() const
|
||||
bool device_changed()
|
||||
{
|
||||
return backend->DefaultDeviceChanged();
|
||||
return backend_device_changed.test_and_reset() && backend->DefaultDeviceChanged();
|
||||
}
|
||||
|
||||
std::string_view get_backend_name() const
|
||||
@@ -425,5 +427,5 @@ using cell_audio = named_thread<cell_audio_thread>;
|
||||
namespace audio
|
||||
{
|
||||
cell_audio_config::raw_config get_raw_config();
|
||||
void configure_audio(bool force_reset = false);
|
||||
extern void configure_audio(bool force_reset = false);
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ void fmt_class_string<CellAudioOutError>::format(std::string& out, u64 arg)
|
||||
|
||||
audio_out_configuration::audio_out_configuration()
|
||||
{
|
||||
audio_out& primary_output = out.at(CELL_AUDIO_OUT_PRIMARY);
|
||||
audio_out& secondary_output = out.at(CELL_AUDIO_OUT_SECONDARY);
|
||||
audio_out& primary_output = ::at32(out, CELL_AUDIO_OUT_PRIMARY);
|
||||
audio_out& secondary_output = ::at32(out, CELL_AUDIO_OUT_SECONDARY);
|
||||
|
||||
std::vector<CellAudioOutSoundMode>& primary_modes = primary_output.sound_modes;
|
||||
std::vector<CellAudioOutSoundMode>& secondary_modes = secondary_output.sound_modes;
|
||||
|
||||
const psf::registry sfo = psf::load_object(fs::file(Emu.GetSfoDir(true) + "/PARAM.SFO"));
|
||||
const psf::registry sfo = psf::load_object(Emu.GetSfoDir(true) + "/PARAM.SFO");
|
||||
const s32 sound_format = psf::get_integer(sfo, "SOUND_FORMAT", psf::sound_format_flag::lpcm_2); // Default to Linear PCM 2 Ch.
|
||||
|
||||
const bool supports_lpcm_2 = (sound_format & psf::sound_format_flag::lpcm_2); // Linear PCM 2 Ch.
|
||||
@@ -58,8 +58,8 @@ audio_out_configuration::audio_out_configuration()
|
||||
|
||||
const auto add_sound_mode = [&](u32 index, u8 type, u8 channel, u8 fs, u32 layout, bool supported)
|
||||
{
|
||||
audio_out& output = out.at(index);
|
||||
bool& selected = initial_mode_selected.at(index);
|
||||
audio_out& output = ::at32(out, index);
|
||||
bool& selected = ::at32(initial_mode_selected, index);
|
||||
|
||||
CellAudioOutSoundMode mode{};
|
||||
mode.type = type;
|
||||
@@ -103,7 +103,7 @@ audio_out_configuration::audio_out_configuration()
|
||||
{
|
||||
// Linear PCM 5.1 Ch. 48 kHz
|
||||
add_sound_mode(CELL_AUDIO_OUT_PRIMARY, CELL_AUDIO_OUT_CODING_TYPE_LPCM, CELL_AUDIO_OUT_CHNUM_6, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr, supports_lpcm_5_1);
|
||||
|
||||
|
||||
// Dolby Digital 5.1 Ch.
|
||||
add_sound_mode(CELL_AUDIO_OUT_PRIMARY, CELL_AUDIO_OUT_CODING_TYPE_AC3, CELL_AUDIO_OUT_CHNUM_6, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr, supports_ac3);
|
||||
|
||||
@@ -161,8 +161,8 @@ audio_out_configuration::audio_out_configuration()
|
||||
// The secondary output only supports Linear PCM 2 Ch.
|
||||
add_sound_mode(CELL_AUDIO_OUT_SECONDARY, CELL_AUDIO_OUT_CODING_TYPE_LPCM, CELL_AUDIO_OUT_CHNUM_2, CELL_AUDIO_OUT_FS_48KHZ, CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH, true);
|
||||
|
||||
ensure(!primary_modes.empty() && initial_mode_selected.at(CELL_AUDIO_OUT_PRIMARY));
|
||||
ensure(!secondary_modes.empty() && initial_mode_selected.at(CELL_AUDIO_OUT_SECONDARY));
|
||||
ensure(!primary_modes.empty() && ::at32(initial_mode_selected, CELL_AUDIO_OUT_PRIMARY));
|
||||
ensure(!secondary_modes.empty() && ::at32(initial_mode_selected, CELL_AUDIO_OUT_SECONDARY));
|
||||
|
||||
for (const CellAudioOutSoundMode& mode : primary_modes)
|
||||
{
|
||||
@@ -238,7 +238,7 @@ error_code cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32
|
||||
// Check if the requested audio parameters are available and find the max supported channel count
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
|
||||
for (const CellAudioOutSoundMode& mode : out.sound_modes)
|
||||
{
|
||||
@@ -265,7 +265,7 @@ error_code cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32
|
||||
// Check if the requested audio parameters are available
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
|
||||
for (const CellAudioOutSoundMode& mode : out.sound_modes)
|
||||
{
|
||||
@@ -319,7 +319,7 @@ error_code cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudio
|
||||
{
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
|
||||
_state.state = out.state;
|
||||
_state.encoder = out.encoder;
|
||||
@@ -360,7 +360,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
|
||||
{
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
|
||||
// Apparently the set config does not necessarily have to exist in the list of sound modes.
|
||||
|
||||
@@ -406,7 +406,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
{
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED;
|
||||
::at32(cfg.out, audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_DISABLED;
|
||||
}
|
||||
|
||||
audio::configure_audio(true);
|
||||
@@ -414,7 +414,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
|
||||
|
||||
{
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
cfg.out.at(audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED;
|
||||
::at32(cfg.out, audioOut).state = CELL_AUDIO_OUT_OUTPUT_STATE_ENABLED;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -455,7 +455,7 @@ error_code cellAudioOutGetConfiguration(u32 audioOut, vm::ptr<CellAudioOutConfig
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
|
||||
// Return the active config.
|
||||
CellAudioOutConfiguration _config{};
|
||||
@@ -516,7 +516,7 @@ error_code cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<Cell
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
ensure(audioOut < cfg.out.size());
|
||||
const audio_out_configuration::audio_out& out = cfg.out.at(audioOut);
|
||||
const audio_out_configuration::audio_out& out = ::at32(cfg.out, audioOut);
|
||||
ensure(out.sound_modes.size() <= 16);
|
||||
|
||||
CellAudioOutDeviceInfo _info{};
|
||||
@@ -528,7 +528,7 @@ error_code cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr<Cell
|
||||
|
||||
for (usz i = 0; i < out.sound_modes.size(); i++)
|
||||
{
|
||||
_info.availableModes[i] = out.sound_modes.at(i);
|
||||
_info.availableModes[i] = ::at32(out.sound_modes, i);
|
||||
}
|
||||
|
||||
*info = _info;
|
||||
@@ -557,7 +557,7 @@ error_code cellAudioOutSetCopyControl(u32 audioOut, u32 control)
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
std::lock_guard lock(cfg.mtx);
|
||||
|
||||
cfg.out.at(audioOut).copy_control = control;
|
||||
::at32(cfg.out, audioOut).copy_control = control;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ error_code cellAudioOutGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioOutDev
|
||||
|
||||
error_code cellVideoOutSetGamma(u32 videoOut, f32 gamma)
|
||||
{
|
||||
cellAvconfExt.warning("cellVideoOutSetGamma(videoOut=%d, gamma=%f)", videoOut, gamma);
|
||||
cellAvconfExt.trace("cellVideoOutSetGamma(videoOut=%d, gamma=%f)", videoOut, gamma);
|
||||
|
||||
if (gamma < 0.8f || gamma > 1.2f)
|
||||
{
|
||||
|
||||
@@ -147,7 +147,7 @@ void camera_context::save(utils::serial& ar)
|
||||
|
||||
GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera);
|
||||
|
||||
ar(notify_data_map, start_timestamp, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num);
|
||||
ar(notify_data_map, start_timestamp_us, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num);
|
||||
}
|
||||
|
||||
static bool check_dev_num(s32 dev_num)
|
||||
@@ -175,7 +175,7 @@ static error_code check_camera_info(const VariantOfCellCameraInfo& info)
|
||||
return CELL_CAMERA_ERROR_BAD_FRAMERATE;
|
||||
}
|
||||
|
||||
auto check_fps = [fps = info.framerate](const std::vector<s32>& range)
|
||||
auto check_fps = [fps = info.framerate](std::initializer_list<s32> range)
|
||||
{
|
||||
return std::find(range.begin(), range.end(), fps) != range.end();
|
||||
};
|
||||
@@ -1268,7 +1268,7 @@ error_code cellCameraStart(s32 dev_num)
|
||||
|
||||
// TODO: Yet another CELL_CAMERA_ERROR_TIMEOUT
|
||||
|
||||
g_camera.start_timestamp = get_guest_system_time();
|
||||
g_camera.start_timestamp_us = get_guest_system_time();
|
||||
g_camera.is_streaming = true;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1372,7 +1372,7 @@ error_code cellCameraReadEx(s32 dev_num, vm::ptr<CellCameraReadEx> read)
|
||||
return CELL_CAMERA_ERROR_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
g_camera.bytes_read = bytes_read;
|
||||
g_camera.bytes_read = ::narrow<u32>(bytes_read);
|
||||
|
||||
cellCamera.trace("cellCameraRead: frame_number=%d, width=%d, height=%d. bytes_read=%d (passed to game: frame=%d, bytesread=%d)",
|
||||
frame_number, width, height, bytes_read, read ? read->frame.get() : 0, read ? read->bytesread.get() : 0);
|
||||
@@ -1385,18 +1385,18 @@ error_code cellCameraReadEx(s32 dev_num, vm::ptr<CellCameraReadEx> read)
|
||||
|
||||
if (has_new_frame)
|
||||
{
|
||||
g_camera.frame_timestamp = (get_guest_system_time() - g_camera.start_timestamp);
|
||||
g_camera.frame_timestamp_us = get_guest_system_time() - g_camera.start_timestamp_us;
|
||||
}
|
||||
|
||||
if (read) // NULL returns CELL_OK
|
||||
{
|
||||
read->timestamp = g_camera.frame_timestamp;
|
||||
read->timestamp = g_camera.frame_timestamp_us;
|
||||
read->frame = g_camera.frame_num;
|
||||
read->bytesread = g_camera.bytes_read;
|
||||
|
||||
auto& shared_data = g_fxo->get<gem_camera_shared>();
|
||||
|
||||
shared_data.frame_timestamp.store(read->timestamp);
|
||||
shared_data.frame_timestamp_us.store(read->timestamp);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@@ -1672,7 +1672,7 @@ void camera_context::operator()()
|
||||
const u64 camera_id = 0;
|
||||
|
||||
data2 = image_data_size << 32 | buffer_number << 16 | camera_id;
|
||||
data3 = get_guest_system_time() - start_timestamp; // timestamp
|
||||
data3 = get_guest_system_time() - start_timestamp_us; // timestamp
|
||||
}
|
||||
else // CELL_CAMERA_READ_FUNCCALL, also default
|
||||
{
|
||||
@@ -1801,7 +1801,7 @@ void camera_context::reset_state()
|
||||
pbuf_locked[0] = false;
|
||||
pbuf_locked[1] = false;
|
||||
has_new_frame = false;
|
||||
frame_timestamp = 0;
|
||||
frame_timestamp_us = 0;
|
||||
bytes_read = 0;
|
||||
|
||||
if (info.buffer)
|
||||
|
||||
@@ -384,7 +384,7 @@ struct CellCameraReadEx
|
||||
be_t<s32> version;
|
||||
be_t<u32> frame;
|
||||
be_t<u32> bytesread;
|
||||
be_t<s64> timestamp;
|
||||
be_t<u64> timestamp; // system_time_t (microseconds)
|
||||
vm::bptr<u8> pbuf;
|
||||
};
|
||||
|
||||
@@ -422,7 +422,7 @@ public:
|
||||
|
||||
shared_mutex mutex;
|
||||
shared_mutex mutex_notify_data_map;
|
||||
u64 start_timestamp = 0;
|
||||
u64 start_timestamp_us = 0;
|
||||
|
||||
atomic_t<u8> read_mode{CELL_CAMERA_READ_FUNCCALL};
|
||||
atomic_t<bool> is_streaming{false};
|
||||
@@ -444,7 +444,7 @@ public:
|
||||
attr_t attr[500]{};
|
||||
atomic_t<bool> has_new_frame = false;
|
||||
atomic_t<u32> frame_num = 0;
|
||||
atomic_t<u32> frame_timestamp = 0;
|
||||
atomic_t<u64> frame_timestamp_us = 0;
|
||||
atomic_t<u32> bytes_read = 0;
|
||||
|
||||
atomic_t<u8> init = 0;
|
||||
@@ -471,11 +471,9 @@ using camera_thread = named_thread<camera_context>;
|
||||
/// Shared data between cellGem and cellCamera
|
||||
struct gem_camera_shared
|
||||
{
|
||||
atomic_t<s64> frame_timestamp{}; // latest read timestamp from cellCamera (cellCameraRead(Ex))
|
||||
atomic_t<u64> frame_timestamp_us{}; // latest read timestamp from cellCamera (cellCameraRead(Ex))
|
||||
atomic_t<s32> width{640};
|
||||
atomic_t<s32> height{480};
|
||||
atomic_t<s32> size{0};
|
||||
atomic_t<CellCameraFormat> format{CELL_CAMERA_RAW8};
|
||||
};
|
||||
|
||||
static inline s32 get_video_buffer_size(s32 width, s32 height);
|
||||
|
||||
@@ -52,7 +52,7 @@ struct cross_controller
|
||||
|
||||
close_msg_dialog();
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
sysutil_register_cb([this, status](ppu_thread& ppu) -> s32
|
||||
{
|
||||
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_FINALIZED, status, vm::null, userdata);
|
||||
return CELL_OK;
|
||||
@@ -74,9 +74,9 @@ struct cross_controller
|
||||
// TODO: Show icons from comboplay_plugin.rco in dialog. Maybe use a new dialog or add an optional icon to this one.
|
||||
error_code res = open_msg_dialog(false, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF, vm::make_str(msg), msg_dialog_callback, userdata);
|
||||
|
||||
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
||||
sysutil_register_cb([this, res](ppu_thread& ppu) -> s32
|
||||
{
|
||||
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, res == CELL_OK ? CELL_OK : CELL_CROSS_CONTROLLER_ERROR_INTERNAL, vm::null, userdata);
|
||||
callback(ppu, CELL_CROSS_CONTROLLER_STATUS_INITIALIZED, res == CELL_OK ? +CELL_OK : +CELL_CROSS_CONTROLLER_ERROR_INTERNAL, vm::null, userdata);
|
||||
return CELL_OK;
|
||||
});
|
||||
|
||||
|
||||
@@ -230,17 +230,12 @@ disc_change_manager::~disc_change_manager()
|
||||
|
||||
error_code disc_change_manager::register_callbacks(vm::ptr<CellGameDiscEjectCallback> func_eject, vm::ptr<CellGameDiscInsertCallback> func_insert)
|
||||
{
|
||||
if (!func_eject || !func_insert)
|
||||
{
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
std::lock_guard lock(mtx);
|
||||
|
||||
eject_callback = func_eject;
|
||||
insert_callback = func_insert;
|
||||
|
||||
Emu.GetCallbacks().enable_disc_eject(true);
|
||||
Emu.GetCallbacks().enable_disc_eject(!!func_eject);
|
||||
Emu.GetCallbacks().enable_disc_insert(false);
|
||||
|
||||
return CELL_OK;
|
||||
@@ -420,16 +415,16 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
||||
else
|
||||
{
|
||||
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
|
||||
const psf::registry psf = psf::load_object(fs::file(local_dir +"/PARAM.SFO"));
|
||||
const psf::registry psf = psf::load_object(local_dir + "/PARAM.SFO");
|
||||
|
||||
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
|
||||
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
||||
if (psf.contains("ATTRIBUTE")) get->getParam.attribute = psf.at("ATTRIBUTE").as_integer();
|
||||
if (psf.contains("RESOLUTION")) get->getParam.resolution = psf.at("RESOLUTION").as_integer();
|
||||
if (psf.contains("SOUND_FORMAT")) get->getParam.soundFormat = psf.at("SOUND_FORMAT").as_integer();
|
||||
if (psf.contains("TITLE")) strcpy_trunc(get->getParam.title, psf.at("TITLE").as_string());
|
||||
if (psf.contains("APP_VER")) strcpy_trunc(get->getParam.dataVersion, psf.at("APP_VER").as_string());
|
||||
if (psf.contains("TITLE_ID")) strcpy_trunc(get->getParam.titleId, psf.at("TITLE_ID").as_string());
|
||||
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = ::at32(psf, "PARENTAL_LEVEL").as_integer();
|
||||
if (psf.contains("ATTRIBUTE")) get->getParam.attribute = ::at32(psf, "ATTRIBUTE").as_integer();
|
||||
if (psf.contains("RESOLUTION")) get->getParam.resolution = ::at32(psf, "RESOLUTION").as_integer();
|
||||
if (psf.contains("SOUND_FORMAT")) get->getParam.soundFormat = ::at32(psf, "SOUND_FORMAT").as_integer();
|
||||
if (psf.contains("TITLE")) strcpy_trunc(get->getParam.title, ::at32(psf, "TITLE").as_string());
|
||||
if (psf.contains("APP_VER")) strcpy_trunc(get->getParam.dataVersion, ::at32(psf, "APP_VER").as_string());
|
||||
if (psf.contains("TITLE_ID")) strcpy_trunc(get->getParam.titleId, ::at32(psf, "TITLE_ID").as_string());
|
||||
|
||||
for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++)
|
||||
{
|
||||
@@ -471,7 +466,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
||||
// psf::assign(sfo, "CATEGORY", psf::string(3, "HG"));
|
||||
// }
|
||||
|
||||
// psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, setParam->titleId));
|
||||
// psf::assign(sfo, "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, setParam->titleId));
|
||||
// psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->title));
|
||||
// psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, setParam->dataVersion));
|
||||
// psf::assign(sfo, "PARENTAL_LEVEL", +setParam->parentalLevel);
|
||||
@@ -675,7 +670,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
|
||||
*attributes = 0; // TODO
|
||||
// TODO: dirName might be a read only string when BootCheck is called on a disc game. (e.g. Ben 10 Ultimate Alien: Cosmic Destruction)
|
||||
|
||||
sfo = psf::load_object(fs::file(vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO")));
|
||||
sfo = psf::load_object(vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO"));
|
||||
}
|
||||
else if (cat == "GD")
|
||||
{
|
||||
@@ -684,7 +679,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
|
||||
*type = CELL_GAME_GAMETYPE_DISC;
|
||||
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
|
||||
|
||||
sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
|
||||
sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -693,7 +688,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
|
||||
*type = CELL_GAME_GAMETYPE_HDD;
|
||||
*attributes = 0; // TODO
|
||||
|
||||
sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
|
||||
sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
|
||||
dir = Emu.GetTitleID();
|
||||
}
|
||||
|
||||
@@ -728,7 +723,7 @@ error_code cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> r
|
||||
return CELL_GAME_ERROR_NOTPATCH;
|
||||
}
|
||||
|
||||
psf::registry sfo = psf::load_object(fs::file(vfs::get(Emu.GetDir() + "PARAM.SFO")));
|
||||
psf::registry sfo = psf::load_object(vfs::get(Emu.GetDir() + "PARAM.SFO"));
|
||||
|
||||
auto& perm = g_fxo->get<content_permission>();
|
||||
|
||||
@@ -995,7 +990,7 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
|
||||
psf::assign(sfo, "CATEGORY", psf::string(3, "GD"));
|
||||
}
|
||||
|
||||
psf::assign(sfo, "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, setParam->titleId));
|
||||
psf::assign(sfo, "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, setParam->titleId, true));
|
||||
psf::assign(sfo, "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->title));
|
||||
psf::assign(sfo, "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, setParam->dataVersion));
|
||||
psf::assign(sfo, "PARENTAL_LEVEL", +setParam->parentalLevel);
|
||||
@@ -1010,6 +1005,14 @@ error_code cellGameDataCheckCreate2(ppu_thread& ppu, u32 version, vm::cptr<char>
|
||||
psf::assign(sfo, fmt::format("TITLE_%02d", i), psf::string(CELL_GAME_SYSP_TITLE_SIZE, setParam->titleLang[i]));
|
||||
}
|
||||
|
||||
if (!psf::check_registry(sfo))
|
||||
{
|
||||
// This results in CELL_OK, broken SFO and CELL_GAMEDATA_ERROR_BROKEN on the next load
|
||||
// Avoid creation for now
|
||||
cellGame.error("Broken SFO paramters: %s", sfo);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
fs::pending_file temp(vfs::get(dir + "/PARAM.SFO"));
|
||||
temp.file.write(psf::save_object(sfo));
|
||||
ensure(temp.commit());
|
||||
@@ -1130,7 +1133,7 @@ error_code cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<c
|
||||
perm.sfo =
|
||||
{
|
||||
{ "CATEGORY", psf::string(3, "GD") },
|
||||
{ "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, init->titleId) },
|
||||
{ "TITLE_ID", psf::string(TITLEID_SFO_ENTRY_SIZE, init->titleId) },
|
||||
{ "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, init->title) },
|
||||
{ "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, init->version) },
|
||||
};
|
||||
@@ -1536,7 +1539,8 @@ error_code cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
error_msg += "\n" + get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, fmt::format("%s", dirName).c_str());
|
||||
error_msg += '\n';
|
||||
error_msg += get_localized_string(localized_string_id::CELL_GAME_ERROR_DIR_NAME, fmt::format("%s", dirName).c_str());
|
||||
}
|
||||
|
||||
return open_exit_dialog(error_msg, type > CELL_GAME_ERRDIALOG_NOSPACE);
|
||||
@@ -1702,7 +1706,7 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
|
||||
}
|
||||
|
||||
// Always sets 0 at first dword
|
||||
*utils::bless<nse_t<u32, 1>>(getParam->titleId + 0) = 0;
|
||||
write_to_ptr<u32>(getParam->titleId, 0);
|
||||
|
||||
// This is also called by non-disc games, see NPUB90029
|
||||
static const std::string dir = "/dev_bdvd/PS3_GAME"s;
|
||||
@@ -1712,10 +1716,10 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
|
||||
return CELL_DISCGAME_ERROR_NOT_DISCBOOT;
|
||||
}
|
||||
|
||||
const psf::registry psf = psf::load_object(fs::file(vfs::get(dir + "/PARAM.SFO")));
|
||||
const psf::registry psf = psf::load_object(vfs::get(dir + "/PARAM.SFO"));
|
||||
|
||||
if (psf.contains("PARENTAL_LEVEL")) getParam->parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
||||
if (psf.contains("TITLE_ID")) strcpy_trunc(getParam->titleId, psf.at("TITLE_ID").as_string());
|
||||
if (psf.contains("PARENTAL_LEVEL")) getParam->parentalLevel = ::at32(psf, "PARENTAL_LEVEL").as_integer();
|
||||
if (psf.contains("TITLE_ID")) strcpy_trunc(getParam->titleId, ::at32(psf, "TITLE_ID").as_string());
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user