Compare commits
842 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4d99f93db | |||
| 801adb0947 | |||
| b3f5d6d85b | |||
| 04c808b8ab | |||
| e55d216619 | |||
| e334a43169 | |||
| cca6a19cdd | |||
| 64aff7f019 | |||
| 2962e05f26 | |||
| 27aeaf66bc | |||
| 9672ad53cd | |||
| b6b7d7b48c | |||
| ec8c5453bc | |||
| fd839243ec | |||
| ede816387f | |||
| 796a6646f7 | |||
| dd79a5efb7 | |||
| e41b234dc4 | |||
| d2eba2387b | |||
| 6811ec562c | |||
| fcbf91b7cb | |||
| 4ec3e968ff | |||
| 3dd6961ee5 | |||
| 232e815f17 | |||
| ebdb0781fa | |||
| 84e44d3372 | |||
| 2a37a4bcea | |||
| 928719b658 | |||
| 7a00b5f809 | |||
| cfdd298693 | |||
| 7b0d834477 | |||
| e4a7e8c058 | |||
| 1d3c18f4e2 | |||
| 9a2338a5ca | |||
| 38a06c4b14 | |||
| cf44038435 | |||
| 8304043d00 | |||
| a921fe3351 | |||
| 35a3bed91a | |||
| 3317e13b64 | |||
| 32b5b11a83 | |||
| eed32cf3a4 | |||
| 3e28e4b1e0 | |||
| fe6ff8622a | |||
| f9aea076ae | |||
| 0aea33687e | |||
| 9d981de96d | |||
| b70908c8f3 | |||
| 6165bd68c0 | |||
| 94dd6c2007 | |||
| 896cfd2ade | |||
| 0b720aeb59 | |||
| 2d29a33ea8 | |||
| b3c1759853 | |||
| ec9b896fbf | |||
| c43a126f62 | |||
| 8cf025bf71 | |||
| 2b55bde104 | |||
| 02fe1ef7ff | |||
| 4ac1e2d8f5 | |||
| 93d5c0a38e | |||
| 2740fafa64 | |||
| 54952f6ad6 | |||
| a85a8796d3 | |||
| 606601441d | |||
| 2882220cbd | |||
| 8517ccfdfa | |||
| 7db2e2537f | |||
| 7a3aa02dc1 | |||
| 7c5bde4aeb | |||
| c67c97844e | |||
| 5d1b7eb945 | |||
| ca8b0da141 | |||
| 141072023b | |||
| 9cd5325962 | |||
| be98554b40 | |||
| 67dac94704 | |||
| 35e61c77e0 | |||
| 9c64318e8a | |||
| b0d0f51d8d | |||
| bd8cbcdb21 | |||
| dca29def5e | |||
| 5e299111cc | |||
| dfe709d464 | |||
| 5817e2a359 | |||
| 87ffa04a2b | |||
| b3aff3a1c6 | |||
| eedf96e1f4 | |||
| 7408f50d71 | |||
| 86a8b5924a | |||
| 8a31c7a7c8 | |||
| 62414cee15 | |||
| 960c8e6538 | |||
| 0af342a978 | |||
| dd86aa472d | |||
| 6535fb0603 | |||
| 11a43e25d7 | |||
| 92e6dee60f | |||
| c5440c95c8 | |||
| 4cfff8ea4a | |||
| 1444492eab | |||
| 050339bb3e | |||
| 500a4fa2fb | |||
| 51188db717 | |||
| 0d88f037ff | |||
| d8402008dd | |||
| 0dce6be8cb | |||
| 80827aa31a | |||
| 6540fecdc3 | |||
| f342f4b826 | |||
| 56011cbddd | |||
| 42ff93d30c | |||
| f2a2dfda3a | |||
| f0c267ecb0 | |||
| a0f0c418d7 | |||
| 7f85b18b46 | |||
| 9f854dba98 | |||
| 503d43889d | |||
| 0dc7841d0f | |||
| 13367071b0 | |||
| 2040a11585 | |||
| 8debdfcd09 | |||
| 08c581947d | |||
| 4df1c16099 | |||
| 9f9309055f | |||
| d41d7b5e24 | |||
| f8f3067deb | |||
| d45c743877 | |||
| 4f22559ff0 | |||
| cf16ee5eb5 | |||
| ae46333e99 | |||
| 87bf0386c4 | |||
| b3f4cd3a95 | |||
| 7fda07eb5b | |||
| 519fe9309e | |||
| 527b1bb071 | |||
| 19825366f5 | |||
| a902874b01 | |||
| 95f22b76c6 | |||
| a4896eb6df | |||
| 30c72b105e | |||
| 14ac70dfbf | |||
| 4b82006984 | |||
| 4f00af6000 | |||
| 6d3fc3a386 | |||
| a6c94a0eaf | |||
| cd4e895c04 | |||
| 629d8e3a51 | |||
| 6d0f2ae58a | |||
| a560498cd4 | |||
| d48d424b19 | |||
| 0a5b6ad928 | |||
| a832581201 | |||
| ecb3b62787 | |||
| 96527eee5b | |||
| 5c904bf3e2 | |||
| cbcd06d1dc | |||
| 3ce18fd960 | |||
| 94d33003a3 | |||
| 25e47e0de0 | |||
| 8866a3d6a9 | |||
| 8150095e8f | |||
| f051f53e15 | |||
| 2f12226ff9 | |||
| d4c635a83c | |||
| 697128464b | |||
| 0559e929d4 | |||
| efcb46658b | |||
| 01720afba9 | |||
| e21b8eb95b | |||
| 033836d88c | |||
| 112ad9dda2 | |||
| 05813c7e90 | |||
| 6e89e4ebbf | |||
| 4ad784d614 | |||
| c219417f62 | |||
| 5bd17a44c9 | |||
| 72fb3ba794 | |||
| f0bd0b5a7c | |||
| d689a6e47b | |||
| e40b76b253 | |||
| 7508ae6e65 | |||
| 1e5e0f3b5e | |||
| 949f33c8a4 | |||
| c6993d3f1c | |||
| e1db6cef6f | |||
| 829047ecdb | |||
| 8886414013 | |||
| f63e89f9b4 | |||
| ec2db8edbc | |||
| 997e3046e3 | |||
| 65134f73d6 | |||
| 76a1fd5c88 | |||
| 1de90bdb1f | |||
| 738cfccbba | |||
| 230c3d55b6 | |||
| fcc75c8b0f | |||
| 22994d15fb | |||
| c53f0dd7b5 | |||
| b56b425b19 | |||
| b44b44b3c4 | |||
| 71c56b719c | |||
| 090c71aa7c | |||
| 49aefc0795 | |||
| 85b1152e29 | |||
| d17be2c2ec | |||
| cf4d715284 | |||
| 2b721b9e29 | |||
| 492c9e3c7c | |||
| 070c3af50f | |||
| a98a2b79d0 | |||
| 6128fffd3e | |||
| 66c1143a65 | |||
| f5f0a5aa19 | |||
| 78ecacabcb | |||
| 9a7c2784f0 | |||
| 4e4c896136 | |||
| e2574ff100 | |||
| 79ddf55937 | |||
| b5a2f0df68 | |||
| 1b140c8e97 | |||
| 95b6883ad4 | |||
| d9c311737d | |||
| a268415121 | |||
| ea2f4d57fa | |||
| 113a49e00c | |||
| 34b06453f9 | |||
| 998717659f | |||
| 009e01a347 | |||
| 397e5dd1ea | |||
| 736ec4035e | |||
| c062000288 | |||
| cb5c26f2b5 | |||
| 1e2f81dd33 | |||
| c01f1a8968 | |||
| cfa1416d64 | |||
| 1a1eff66bc | |||
| bc1617758c | |||
| 6126a98111 | |||
| e1293b14f8 | |||
| f5ee8c1292 | |||
| 0a88a23bf5 | |||
| cbfa6cc91f | |||
| 38d4e3c184 | |||
| 7398cfc950 | |||
| 22e4ef147a | |||
| 9ff6486c85 | |||
| c727760537 | |||
| 3de885c7a6 | |||
| 3d6c211382 | |||
| 94af3b3f03 | |||
| ae055f6792 | |||
| 17c8ac9ab8 | |||
| c4d8ef4340 | |||
| efbae02a22 | |||
| f3551cedb7 | |||
| 6c6b973342 | |||
| 2898309f68 | |||
| fc09572648 | |||
| d8f753f1e8 | |||
| 537d3f2548 | |||
| d7a2d42d8f | |||
| 0979207cc6 | |||
| 2016a33277 | |||
| ab228d6407 | |||
| 78e447e28c | |||
| 2548057ea0 | |||
| 956270d9be | |||
| c072c511a1 | |||
| 9ca6546dec | |||
| 0cc672dcb3 | |||
| 219a5382f7 | |||
| 7840cd914e | |||
| c47f4fd59e | |||
| b9130dd663 | |||
| d1db6a6827 | |||
| 6fba3dd90c | |||
| 9d9e158b9a | |||
| d57b4dc8f3 | |||
| db4bc6f6be | |||
| 92c08be387 | |||
| 50736263d2 | |||
| 20dd7c0200 | |||
| b6cfa5c9b9 | |||
| 6d65d3424f | |||
| 4c2fb54b99 | |||
| ad10eb391e | |||
| 71e809a78b | |||
| 0f11939faf | |||
| ae93b417ec | |||
| d69e8288ad | |||
| ce04a797c3 | |||
| b5d5113803 | |||
| 690cdff0d3 | |||
| 1e0289bcb2 | |||
| 503e023815 | |||
| d57124d075 | |||
| 146e43b6ec | |||
| 13a557fe67 | |||
| 3d8389457e | |||
| 2bce367488 | |||
| 43f919c04b | |||
| 1ee7b91646 | |||
| e043412be4 | |||
| 232a35b6fc | |||
| 948c1df969 | |||
| a124ec4a26 | |||
| d0eae7bab1 | |||
| 22917084d9 | |||
| ebb1ae6408 | |||
| 23094b48bb | |||
| be521ff0ab | |||
| 32f8f40a4a | |||
| 1fcf62fdf0 | |||
| 27fca2ed33 | |||
| 1641be5e0c | |||
| 31afd046b0 | |||
| 9ce7b8a401 | |||
| 009c55fcba | |||
| 4ff77a8555 | |||
| 8249d51aa8 | |||
| 1ee675e1f4 | |||
| 2b9c315374 | |||
| d26b25816d | |||
| b893a75002 | |||
| c32c1b0a62 | |||
| 6a32f716db | |||
| 59ee74a275 | |||
| 0fa3bcc336 | |||
| 358169507c | |||
| b645ebdb04 | |||
| 25bba9bf56 | |||
| f113cfe5c0 | |||
| c9501b60ab | |||
| 6be7c58fa4 | |||
| c963c51a60 | |||
| 23432d420d | |||
| a070a414a6 | |||
| e9e87b8bd9 | |||
| 499035512b | |||
| 8e942eb50c | |||
| 806a7bbf04 | |||
| cd0ef99df5 | |||
| ade291e73d | |||
| 517a2bc34a | |||
| a935203a18 | |||
| b9b591bf02 | |||
| 3602d45cb7 | |||
| a0f2ade55d | |||
| 5753b3222e | |||
| d021d9e14a | |||
| 89a31292dc | |||
| 5d45a3e47d | |||
| 17d0dcb7a2 | |||
| d52953fca6 | |||
| 0fe26f8293 | |||
| 185fd3d257 | |||
| 5928dd826c | |||
| b94730fa95 | |||
| b29a89807e | |||
| 3f00b485a0 | |||
| 8dafc8e542 | |||
| e515d9b83a | |||
| c90186cf35 | |||
| 98156d2a2c | |||
| 4104d7a6a1 | |||
| 86119f58d6 | |||
| 9d166c5bed | |||
| 296e0105c4 | |||
| 9d0f5aedf3 | |||
| e4671c29a6 | |||
| 8a1cf2c913 | |||
| ca82dd7200 | |||
| c655036920 | |||
| 5f34c0c59a | |||
| 9d314ca4ca | |||
| bca5f94b3f | |||
| ea8409dcfd | |||
| acb14320da | |||
| 4a5bbba277 | |||
| f6f3b40ecc | |||
| 655eff29e8 | |||
| db5d56a22d | |||
| 0d906d6974 | |||
| ac3982d2b0 | |||
| 595ad15499 | |||
| 13671d9684 | |||
| 1e327ad31b | |||
| 370dcd9d6e | |||
| 0b97d12a7b | |||
| f1e939936a | |||
| 44265aa27d | |||
| 635695ac78 | |||
| a555504142 | |||
| cba828384d | |||
| a02a8642b0 | |||
| b91bcdbbca | |||
| 349e7c8708 | |||
| 35dc98be06 | |||
| ac7e89660f | |||
| 801fa0113f | |||
| c9b0a4afd0 | |||
| 8f2647555a | |||
| 331fe01762 | |||
| db926ee671 | |||
| 81a3b49c2f | |||
| c4667133c4 | |||
| 497f0c26e7 | |||
| 65581acbf9 | |||
| d6db61c594 | |||
| b3513cd7fa | |||
| d361eedbec | |||
| 57196f0504 | |||
| 527f7a437a | |||
| 652e32341d | |||
| 8646e90832 | |||
| b190e1f50b | |||
| 39fa1d7031 | |||
| f9ad635856 | |||
| 2bc0ea37ab | |||
| e8a516529b | |||
| 1dedeb37bf | |||
| b2e08100ff | |||
| 9dc0368079 | |||
| 447029a700 | |||
| 31994dd3b2 | |||
| 0333942795 | |||
| dfd50d0185 | |||
| 790962425c | |||
| 99c1f87289 | |||
| 66946a83e6 | |||
| 8a6b5ca71f | |||
| 09c9996f31 | |||
| bf557ea6e6 | |||
| 78c7ef3039 | |||
| f90f68d129 | |||
| cafa4521ee | |||
| 141d78344a | |||
| d9d7634f8b | |||
| 32776db8a6 | |||
| ef587d4cdc | |||
| f2cac26154 | |||
| 6e92516070 | |||
| e118c9e5da | |||
| c638e82678 | |||
| fb1d8cb548 | |||
| 5760aa2e57 | |||
| e4fca8274e | |||
| f48589005d | |||
| 8ebe02ce32 | |||
| 3a5d1c6b15 | |||
| 34964e0e4f | |||
| d9ab2c7104 | |||
| 57eb892153 | |||
| 71b71537a0 | |||
| b839cc9d5b | |||
| 507ec8252b | |||
| c348fec84b | |||
| 6ab3011eef | |||
| d616ce223c | |||
| 370b9e196d | |||
| 46ba53f122 | |||
| c3b234f972 | |||
| 9a26c0abda | |||
| 7de3c410cf | |||
| 9abb303569 | |||
| ceaa669494 | |||
| a6cde36dc4 | |||
| 8009e53642 | |||
| a245d9fb24 | |||
| 0ef7b2aaff | |||
| dc749d3975 | |||
| 85920253b3 | |||
| 6416fee986 | |||
| bf7ee2de4c | |||
| 2cf139c7a8 | |||
| 164a7636bf | |||
| e3f68c66d8 | |||
| edb1a32bb1 | |||
| 32bdd8ef7b | |||
| 4037225e98 | |||
| 9aa08313e3 | |||
| cb78522620 | |||
| 45a13d0319 | |||
| 05eb1e9193 | |||
| 214bb3ec87 | |||
| 88290d9fab | |||
| 4182f9984d | |||
| 3c7d8a1099 | |||
| 9f0090772a | |||
| 4b443be881 | |||
| b840f6da28 | |||
| e3cf3ab6b8 | |||
| e02e27b2b3 | |||
| 1c439f6198 | |||
| 88c20afd3a | |||
| a016728a9e | |||
| a69329fe02 | |||
| 26d131ef29 | |||
| 91897fa69d | |||
| f95ec8a37c | |||
| b138d25b97 | |||
| a921af1e96 | |||
| 43ae4b3f33 | |||
| 007108100e | |||
| 4e75d2c2f7 | |||
| adc7d96683 | |||
| 16401722f1 | |||
| b2d0ca83fb | |||
| 09eb633f69 | |||
| 3753d27aba | |||
| c481472faf | |||
| 82295d131a | |||
| ea554ae828 | |||
| 1eed421774 | |||
| 2f6707d0a0 | |||
| f33b81545e | |||
| a74fd27e3d | |||
| cc8c635855 | |||
| 7cf11c7637 | |||
| 6b01c2f9f5 | |||
| 22f61caf9f | |||
| 786dc6ef40 | |||
| 6c5ea068c9 | |||
| 1f82a26a9c | |||
| 3623f4343f | |||
| 8194c92f1c | |||
| 5d33d9a3d9 | |||
| 7492f335e9 | |||
| fce9d6a7b8 | |||
| 7ead021aa7 | |||
| feb77793df | |||
| f1ff75d815 | |||
| 13d8e33d9a | |||
| 4e2650af91 | |||
| ca08418dc1 | |||
| 5141590729 | |||
| fd2bc95a7b | |||
| 9aa9cbf1d8 | |||
| 87d493fe1b | |||
| e883f4f880 | |||
| 767eaaa82a | |||
| caa6895310 | |||
| ea0f04e130 | |||
| f480ba13c0 | |||
| c1e245ae73 | |||
| b639584acc | |||
| b0a24665e5 | |||
| 8a4778ba8c | |||
| 9c346c92f3 | |||
| 2bec304cca | |||
| f246a8666a | |||
| a703460fc6 | |||
| ba1ec1d5d6 | |||
| 45ce8db6cb | |||
| 4bd022f778 | |||
| 6c34d7104e | |||
| 54dc617f39 | |||
| 15bd3b8724 | |||
| 2b4da18709 | |||
| d48dc29e55 | |||
| 69d2ea35b9 | |||
| a4c4ee9cb2 | |||
| bc42719c48 | |||
| 6b7cd458e3 | |||
| 1d5c52f476 | |||
| 48cb265c2c | |||
| 63f9b8e0c6 | |||
| ec9aa74008 | |||
| 4e3ec162e2 | |||
| 6feffe6ff6 | |||
| f56a6548b0 | |||
| 1bc5e27507 | |||
| 1294e0d189 | |||
| e09c6ea4b4 | |||
| 716737ecf2 | |||
| c24b74398f | |||
| 301dd82819 | |||
| 3bd29b8bac | |||
| ea1c9a2e17 | |||
| 468e1e90c8 | |||
| be6d9af1ab | |||
| 243df38360 | |||
| 3cbccdd760 | |||
| 4cd1c25729 | |||
| 32396ba366 | |||
| f12bd8068c | |||
| abe7188acf | |||
| 60f3059d22 | |||
| 463b1b220d | |||
| 7ad1646c2c | |||
| 06a85f00d1 | |||
| a668560c68 | |||
| ee319f7c13 | |||
| 2ade3c594c | |||
| aca61fdcf9 | |||
| 8754bbd444 | |||
| dd9bd1338b | |||
| 3e0b45719d | |||
| b02503963e | |||
| c83e65f29e | |||
| b7b93eae13 | |||
| 2eac59f59a | |||
| ac473eb400 | |||
| 42448cf3e5 | |||
| 524aac75ed | |||
| 3925cb59ac | |||
| dc9118ef50 | |||
| 467ef2afca | |||
| cb5dd1353b | |||
| bb0609372d | |||
| 258df80bf6 | |||
| a24ede4f40 | |||
| 3a5f4ed757 | |||
| 450e2c9a0e | |||
| ae5a4b697e | |||
| 1e9d3346d1 | |||
| 9446bd2d3f | |||
| 6f76e34104 | |||
| 67f098627a | |||
| ff11d9a3bd | |||
| 9497270da5 | |||
| 2b4bc588dc | |||
| 888cb9d673 | |||
| f25587d24c | |||
| 777a99d01b | |||
| 7865982208 | |||
| 52c589ed3d | |||
| 9060177dbd | |||
| 1152317b47 | |||
| b929c13c45 | |||
| 092cfef060 | |||
| 8f333117eb | |||
| baf42430d6 | |||
| f995771143 | |||
| bad0415f05 | |||
| 136fc8cfe3 | |||
| b97a1aeca2 | |||
| c1edae73c5 | |||
| 8deb20e928 | |||
| e064b92058 | |||
| d52df9352c | |||
| fe593de6d7 | |||
| df3b46a611 | |||
| 0d415407c7 | |||
| f40320bcae | |||
| c34821ded2 | |||
| 38cc92ec45 | |||
| 8da78c098c | |||
| eba8e2284b | |||
| 969af86eba | |||
| b307aff9eb | |||
| 1c462abc37 | |||
| 3304e3b0b7 | |||
| f028737db8 | |||
| a9014a8cac | |||
| e21504d52d | |||
| aa44ef1f44 | |||
| d555eeb0f4 | |||
| af86d1d77a | |||
| 52a12185a0 | |||
| 1d947daa81 | |||
| ec2d882199 | |||
| 40142420c1 | |||
| 0736fc8b28 | |||
| a54d9c527f | |||
| 9736773c04 | |||
| 3354f068fc | |||
| 12dc3c1872 | |||
| a4495c35b7 | |||
| a5ed30a8c0 | |||
| f04a0a2bb6 | |||
| 0a604e39f1 | |||
| cc3809fbfe | |||
| e4e86455f2 | |||
| 3249000511 | |||
| 0f7af391d7 | |||
| 366e4c2422 | |||
| b7470cfc1a | |||
| 443fde760f | |||
| f30af3ccd2 | |||
| 7625f7df11 | |||
| 8dbf2638e2 | |||
| d7ad991b7e | |||
| 3bfe921a7a | |||
| 2119566da7 | |||
| 182054b8af | |||
| 3c0564c9b7 | |||
| 90490f775d | |||
| 8185ef7610 | |||
| 801e6114b6 | |||
| a3f65084df | |||
| 1ed2055ec1 | |||
| 16f86b2458 | |||
| f2bbae9db4 | |||
| 8eb59271a5 | |||
| d6025c6764 | |||
| 47ca1b1dda | |||
| 6502d933df | |||
| f15eb88f59 | |||
| 1916cc1691 | |||
| f369aeab7a | |||
| 0e9313d2df | |||
| d873802b9c | |||
| 7e0b941e9f | |||
| d77fed6105 | |||
| a254a203bb | |||
| 71b88cdc82 | |||
| a9eb321814 | |||
| 956d039415 | |||
| 581b205f73 | |||
| 6c40b9f3e0 | |||
| d6bf18eabc | |||
| 32ae7e466c | |||
| 7ea04d5d76 | |||
| 4b381fbbb1 | |||
| 1880a17f79 | |||
| 31304f4234 | |||
| 3794f65bb6 | |||
| 849411693a | |||
| 466d58ccef | |||
| 41b87cf577 | |||
| 86ad204636 | |||
| dbc8e70ddd | |||
| 3a4e3fa53a | |||
| d731c07ade | |||
| adc59f9810 | |||
| b879b32271 | |||
| 03fca73cf4 | |||
| 1a13d3ae4e | |||
| 1f845a3634 | |||
| 3eb2bcad39 | |||
| 63bbe459ea | |||
| f2aaad11bb | |||
| 3ef16bee47 | |||
| bb65e45614 | |||
| 5260f4b47d | |||
| 385485204b | |||
| 74eeacd091 | |||
| 1a44446250 | |||
| a49a0f2a86 | |||
| 85cb703633 | |||
| 3a4083263e | |||
| 612160a8ff | |||
| 17c49d21a5 | |||
| 745f8f9627 | |||
| e9b6beadfc | |||
| 388d49db80 | |||
| 980c3d6fe8 | |||
| 3b01e59cd4 | |||
| a08cd0fe38 | |||
| 8623899499 | |||
| 6d4c9f2d41 | |||
| 30636f0199 | |||
| 0aa9243557 | |||
| eae5b9e049 | |||
| 688aabc6c9 | |||
| 4a28319edf | |||
| 1875dc3f18 | |||
| 358558aaa7 | |||
| 04dda44225 | |||
| 21bc6c7a87 | |||
| 9d4d3d9443 | |||
| f4ebcb0029 | |||
| 7c379432dd | |||
| dccb4a4888 | |||
| b9e7b085fe | |||
| a80f1a6ed4 | |||
| 0395fb9955 | |||
| 10dc3dadee | |||
| 563e205a72 | |||
| fa628f0ac4 | |||
| 3a071a9c07 | |||
| 6ef9dcd62e | |||
| ef071ebb6b | |||
| a43e7c172c | |||
| 7470388e5a | |||
| 26bcd0a4de | |||
| bd259c8ae4 | |||
| fc253165e2 | |||
| b7da3ea5cd | |||
| ce8c92262d | |||
| f272a5f779 | |||
| 61bd2ea799 | |||
| 3c9f03968c | |||
| 4ea76def7c | |||
| 986c750fdc | |||
| efe067bfa0 | |||
| e38b7aee5a | |||
| d82362fa1d | |||
| ebb24375d1 | |||
| fb64b28886 | |||
| 7f6a410770 | |||
| 765d15f23f | |||
| f143035af1 | |||
| 9ee2867247 | |||
| 7b344b7654 | |||
| 6c5d9fffaa | |||
| 240ba39d16 | |||
| de5379a69f | |||
| a22297f205 | |||
| d4459af4b3 | |||
| ad6b0ee122 | |||
| b107718869 | |||
| f5163cc4ff | |||
| 923700a167 | |||
| c325534f07 | |||
| 14ddb0c5b4 | |||
| 4c72f7c1de | |||
| 3b9f9dd4c5 | |||
| 45c31a99a3 | |||
| 63a9421634 | |||
| 92ff7c4c24 | |||
| 56e24f8993 | |||
| a8621ebc22 | |||
| d4888a4973 | |||
| 4a1499e0be | |||
| fe79e541dd | |||
| 17a5e0bc98 | |||
| 982b2ab88f | |||
| d6995f40c7 | |||
| fa647bc121 | |||
| 84d42ecb65 | |||
| 0861226271 | |||
| e3ee481f01 | |||
| 19ff95da70 | |||
| 38887bc03e | |||
| 4c593959fd | |||
| 67cdec577f | |||
| a36d3af3b4 | |||
| 27af05da1a | |||
| b36cb66129 | |||
| 12990f3ca3 | |||
| 9e39e2d2c4 | |||
| 3653c2eb0d | |||
| faf5221b0d | |||
| c434e0ce27 | |||
| 9ed9d7e947 | |||
| 9d4b19b97a | |||
| 8920eda321 | |||
| f4afd56e67 | |||
| f47d3a761b |
@@ -0,0 +1,2 @@
|
||||
patreon: Nekotekina
|
||||
custom: https://rpcs3.net/alipay
|
||||
@@ -48,3 +48,7 @@
|
||||
path = 3rdparty/libpng
|
||||
url = https://github.com/glennrp/libpng.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/libusb"]
|
||||
path = 3rdparty/libusb
|
||||
url = https://github.com/RPCS3/libusb.git
|
||||
ignore = dirty
|
||||
|
||||
+12
-14
@@ -1,27 +1,25 @@
|
||||
language: cpp
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env:
|
||||
- NAME="Linux build"
|
||||
- COMPILER="gcc"
|
||||
dist: trusty
|
||||
services: docker
|
||||
cache: ccache
|
||||
install: "docker pull rpcs3/rpcs3-travis-trusty:1.0"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-trusty:1.0 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
|
||||
# - os: linux
|
||||
# env:
|
||||
# - NAME="Linux build"
|
||||
# - COMPILER="gcc"
|
||||
# services: docker
|
||||
# cache: ccache
|
||||
# install: "docker pull rpcs3/rpcs3-travis-trusty:1.1"
|
||||
# script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-trusty:1.1 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
|
||||
- os: linux
|
||||
env:
|
||||
- NAME="Linux build"
|
||||
- COMPILER="clang"
|
||||
- DEPLOY_APPIMAGE="true"
|
||||
dist: trusty
|
||||
services: docker
|
||||
cache: ccache
|
||||
install: "docker pull rpcs3/rpcs3-travis-trusty:1.0"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-trusty:1.0 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
|
||||
install: "docker pull rpcs3/rpcs3-travis-trusty:1.1"
|
||||
script: 'travis_wait docker run -v $(pwd):/rpcs3 -v "$HOME/.ccache":/root/.ccache --env-file .travis/travis.env rpcs3/rpcs3-travis-trusty:1.1 /bin/bash -ex /rpcs3/.travis/build-linux.bash'
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
osx_image: xcode10.2
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
@@ -31,7 +29,7 @@ matrix:
|
||||
- qt
|
||||
script: "/bin/bash -ex .travis/build-mac.bash"
|
||||
cache: ccache
|
||||
|
||||
|
||||
git:
|
||||
depth: false # Unshallow clone to obtain proper GIT_VERSION
|
||||
submodules: false
|
||||
|
||||
@@ -8,7 +8,7 @@ export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/x86_64-linux-gnu:$QT_BASE_DIR/lib
|
||||
|
||||
cd rpcs3
|
||||
|
||||
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/xxHash 3rdparty/yaml-cpp Vulkan/glslang
|
||||
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/xxHash 3rdparty/yaml-cpp 3rdparty/libusb Vulkan/glslang
|
||||
|
||||
# Download pre-compiled llvm libs
|
||||
curl -sLO https://github.com/RPCS3/llvm/releases/download/continuous-linux-master/llvmlibs-linux.tar.gz
|
||||
@@ -28,8 +28,8 @@ fi
|
||||
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_LLVM_SUBMODULE=OFF -DLLVM_DIR=llvmlibs/lib/cmake/llvm/ -DUSE_NATIVE_INSTRUCTIONS=OFF -G Ninja
|
||||
|
||||
ninja
|
||||
ninja; build_status=$?;
|
||||
|
||||
cd ..
|
||||
# If it compiled succesfully let's deploy
|
||||
if [ $? -eq 0 ] && [ -n "$GITHUB_TOKEN" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then /bin/bash -ex .travis/deploy-linux.bash ; fi
|
||||
if [ $build_status -eq 0 ] && [ -n "$GITHUB_TOKEN" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then /bin/bash -ex .travis/deploy-linux.bash ; fi
|
||||
|
||||
@@ -2,14 +2,10 @@ export CCACHE_SLOPPINESS=pch_defines,time_macros
|
||||
export CMAKE_PREFIX_PATH=/usr/local/opt/qt5/
|
||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
|
||||
# Allow using optional on 10.13
|
||||
sudo perl -pi -e 'BEGIN{undef $/;} s/(_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS[ ]+\\\n[^\n]+10)\.14/\1.13/;' \
|
||||
$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__config
|
||||
|
||||
# Setup vulkan and gfx-rs/portability
|
||||
curl -sLO https://github.com/gfx-rs/portability/releases/download/latest/gfx-portability-macos-latest.zip
|
||||
unzip -: gfx-portability-macos-latest.zip
|
||||
curl -sLO https://github.com/KhronosGroup/Vulkan-Headers/archive/sdk-1.1.92.0.zip
|
||||
curl -sLO https://github.com/KhronosGroup/Vulkan-Headers/archive/sdk-1.1.106.0.zip
|
||||
unzip -: sdk-*.zip
|
||||
mkdir vulkan-sdk
|
||||
ln -s ${PWD}/Vulkan-Headers*/include vulkan-sdk/include
|
||||
@@ -19,7 +15,7 @@ cp target/release/libportability.dylib vulkan-sdk/lib/libVulkan.dylib
|
||||
install_name_tool -id ${PWD}/vulkan-sdk/lib/libVulkan.dylib vulkan-sdk/lib/libVulkan.dylib
|
||||
export VULKAN_SDK=${PWD}/vulkan-sdk
|
||||
|
||||
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/xxHash 3rdparty/yaml-cpp Vulkan/glslang
|
||||
git submodule update --quiet --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng 3rdparty/cereal 3rdparty/hidapi 3rdparty/libusb 3rdparty/xxHash 3rdparty/yaml-cpp Vulkan/glslang
|
||||
|
||||
mkdir build; cd build
|
||||
cmake .. -DWITH_LLVM=OFF -DUSE_NATIVE_INSTRUCTIONS=OFF -G Ninja
|
||||
|
||||
Vendored
+15
@@ -86,6 +86,20 @@ else()
|
||||
endif()
|
||||
|
||||
|
||||
# libusb
|
||||
if(CMAKE_SYSTEM MATCHES "DragonFly|FreeBSD")
|
||||
# Always use system libusb as reference implementation isn't supported
|
||||
add_library(usb-1.0-static INTERFACE)
|
||||
target_link_libraries(usb-1.0-static INTERFACE usb)
|
||||
elseif(MSVC)
|
||||
# Windows time.h defines timespec but doesn't add any flag for it, which makes libusb attempt to define it again
|
||||
add_definitions(-DHAVE_STRUCT_TIMESPEC=1)
|
||||
add_subdirectory(libusb EXCLUDE_FROM_ALL)
|
||||
else()
|
||||
add_subdirectory(libusb EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
|
||||
# yaml-cpp
|
||||
# We don't want to install yaml-cpp but its cmake file doesn't have option
|
||||
# to disable it...
|
||||
@@ -342,6 +356,7 @@ include(llvm.cmake)
|
||||
|
||||
|
||||
# add nice ALIAS targets for ease of use
|
||||
add_library(3rdparty::libusb ALIAS usb-1.0-static)
|
||||
add_library(3rdparty::zlib ALIAS 3rdparty_zlib)
|
||||
add_library(3rdparty::pugixml ALIAS pugixml)
|
||||
add_library(3rdparty::yaml-cpp ALIAS yaml-cpp)
|
||||
|
||||
+16763
-9359
File diff suppressed because it is too large
Load Diff
Vendored
+105
@@ -0,0 +1,105 @@
|
||||
<?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">
|
||||
<ProjectGuid>{A107C21C-418A-4697-BB10-20C3AA60E2E4}</ProjectGuid>
|
||||
<RootNamespace>hidapi</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>15.0.26323.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib/</OutDir>
|
||||
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)lib/</OutDir>
|
||||
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>hidapi\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>setupapi.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>hidapi\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>setupapi.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="hidapi\windows\hid.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hidapi\hidapi\hidapi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="hidapi\windows\hid.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hidapi\hidapi\hidapi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Vendored
+1
-1
Submodule 3rdparty/libpng updated: b78804f9a2...eddf902320
Vendored
+2
-2
@@ -16,16 +16,16 @@
|
||||
<RootNamespace>libpng</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\3rdparty\zlib.props" />
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
+1
Submodule 3rdparty/libusb added at 7cfa00e9d7
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.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">
|
||||
<ProjectName>libusb-1.0 (static)</ProjectName>
|
||||
<ProjectGuid>{349EE8F9-7D25-4909-AAF5-FF3FADE72187}</ProjectGuid>
|
||||
<RootNamespace>libusb</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization Condition="'$(Configuration)'=='Release'">true</WholeProgramOptimization>
|
||||
</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" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir>$(SolutionDir)lib/</OutDir>
|
||||
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)/</IntDir>
|
||||
<TargetName>libusb-1.0</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>libusb\msvc;libusb\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Condition="'$(Configuration)'=='Debug'">
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<ClCompile Condition="'$(Configuration)'=='Release'">
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)libusb-1.0.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="libusb\libusb\core.c" />
|
||||
<ClCompile Include="libusb\libusb\descriptor.c" />
|
||||
<ClCompile Include="libusb\libusb\hotplug.c" />
|
||||
<ClCompile Include="libusb\libusb\io.c" />
|
||||
<ClCompile Include="libusb\libusb\os\poll_windows.c" />
|
||||
<ClCompile Include="libusb\libusb\strerror.c" />
|
||||
<ClCompile Include="libusb\libusb\sync.c" />
|
||||
<ClCompile Include="libusb\libusb\os\threads_windows.c" />
|
||||
<ClCompile Include="libusb\libusb\os\windows_nt_common.c" />
|
||||
<ClCompile Include="libusb\libusb\os\windows_usbdk.c" />
|
||||
<ClCompile Include="libusb\libusb\os\windows_winusb.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="libusb\msvc\config.h" />
|
||||
<ClInclude Include="libusb\libusb\hotplug.h" />
|
||||
<ClInclude Include="libusb\libusb\libusb.h" />
|
||||
<ClInclude Include="libusb\libusb\libusbi.h" />
|
||||
<ClInclude Include="libusb\libusb\os\poll_windows.h" />
|
||||
<ClInclude Include="libusb\libusb\os\threads_windows.h" />
|
||||
<ClInclude Include="libusb\libusb\version.h" />
|
||||
<ClInclude Include="libusb\libusb\version_nano.h" />
|
||||
<ClInclude Include="libusb\libusb\os\windows_common.h" />
|
||||
<ClInclude Include="libusb\libusb\os\windows_nt_common.h" />
|
||||
<ClInclude Include="libusb\libusb\os\windows_nt_shared_types.h" />
|
||||
<ClInclude Include="libusb\libusb\os\windows_usbdk.h" />
|
||||
<ClInclude Include="libusb\libusb\os\windows_winusb.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
+5
-5
@@ -26,7 +26,7 @@ if(WITH_LLVM)
|
||||
set(CMAKE_CXX_FLAGS ${CXX_FLAGS_OLD})
|
||||
|
||||
# now tries to find LLVM again
|
||||
find_package(LLVM 8.0 CONFIG)
|
||||
find_package(LLVM 9.0 CONFIG)
|
||||
if(NOT LLVM_FOUND)
|
||||
message(FATAL_ERROR "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
|
||||
endif()
|
||||
@@ -39,11 +39,11 @@ if(WITH_LLVM)
|
||||
set(LLVM_DIR ${CMAKE_SOURCE_DIR}/${LLVM_DIR})
|
||||
endif()
|
||||
|
||||
find_package(LLVM 8.0 CONFIG)
|
||||
find_package(LLVM 9.0 CONFIG)
|
||||
|
||||
if (NOT LLVM_FOUND)
|
||||
if (LLVM_VERSION AND LLVM_VERSION_MAJOR LESS 8)
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 8.0. \
|
||||
if (LLVM_VERSION AND LLVM_VERSION_MAJOR LESS 9)
|
||||
message(FATAL_ERROR "Found LLVM version ${LLVM_VERSION}. Required version 9.0. \
|
||||
Enable BUILD_LLVM_SUBMODULE option to build LLVM from included as a git submodule.")
|
||||
endif()
|
||||
|
||||
@@ -52,7 +52,7 @@ if(WITH_LLVM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(LLVM_LIBS LLVMMCJIT LLVMX86CodeGen)
|
||||
set(LLVM_LIBS LLVMMCJIT LLVMX86CodeGen LLVMX86AsmParser)
|
||||
|
||||
add_library(3rdparty_llvm INTERFACE)
|
||||
target_link_libraries(3rdparty_llvm INTERFACE ${LLVM_LIBS})
|
||||
|
||||
Vendored
+2
-2
@@ -9,15 +9,15 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{EB33566E-DA7F-4D28-9077-88C0B7C77E35}</ProjectGuid>
|
||||
<RootNamespace>pnglibconf</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\3rdparty\zlib.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/pugixml updated: 8436f2a69b...8bf806c035
Vendored
+138
-53
@@ -1,4 +1,4 @@
|
||||
/* stb_image - v2.19 - public domain image loader - http://nothings.org/stb
|
||||
/* stb_image - v2.22 - public domain image loader - http://nothings.org/stb
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
@@ -48,6 +48,9 @@ LICENSE
|
||||
|
||||
RECENT REVISION HISTORY:
|
||||
|
||||
2.22 (2019-03-04) gif fixes, fix warnings
|
||||
2.21 (2019-02-25) fix typo in comment
|
||||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||
2.19 (2018-02-11) fix warning
|
||||
2.18 (2018-01-30) fix warnings
|
||||
2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
|
||||
@@ -84,6 +87,7 @@ RECENT REVISION HISTORY:
|
||||
Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
|
||||
Arseny Kapoulkine
|
||||
John-Mark Allen
|
||||
Carmelo J Fdez-Aguera
|
||||
|
||||
Bug & warning fixes
|
||||
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
|
||||
@@ -99,7 +103,7 @@ RECENT REVISION HISTORY:
|
||||
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
|
||||
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
|
||||
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
|
||||
Christian Floisand Kevin Schmidt github:darealshinji
|
||||
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
|
||||
Blazej Dariusz Roszkowski github:Michaelangel007
|
||||
*/
|
||||
|
||||
@@ -161,6 +165,16 @@ RECENT REVISION HISTORY:
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// UNICODE:
|
||||
//
|
||||
// If compiling for Windows and you wish to use Unicode filenames, compile
|
||||
// with
|
||||
// #define STBI_WINDOWS_UTF8
|
||||
// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert
|
||||
// Windows wchar_t filenames to utf8.
|
||||
//
|
||||
// ===========================================================================
|
||||
//
|
||||
// Philosophy
|
||||
//
|
||||
// stb libraries are designed with the following priorities:
|
||||
@@ -171,12 +185,12 @@ RECENT REVISION HISTORY:
|
||||
//
|
||||
// Sometimes I let "good performance" creep up in priority over "easy to maintain",
|
||||
// and for best performance I may provide less-easy-to-use APIs that give higher
|
||||
// performance, in addition to the easy to use ones. Nevertheless, it's important
|
||||
// performance, in addition to the easy-to-use ones. Nevertheless, it's important
|
||||
// to keep in mind that from the standpoint of you, a client of this library,
|
||||
// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
|
||||
//
|
||||
// Some secondary priorities arise directly from the first two, some of which
|
||||
// make more explicit reasons why performance can't be emphasized.
|
||||
// provide more explicit reasons why performance can't be emphasized.
|
||||
//
|
||||
// - Portable ("ease of use")
|
||||
// - Small source code footprint ("easy to maintain")
|
||||
@@ -219,11 +233,10 @@ RECENT REVISION HISTORY:
|
||||
//
|
||||
// HDR image support (disable by defining STBI_NO_HDR)
|
||||
//
|
||||
// stb_image now supports loading HDR images in general, and currently
|
||||
// the Radiance .HDR file format, although the support is provided
|
||||
// generically. You can still load any file through the existing interface;
|
||||
// if you attempt to load an HDR file, it will be automatically remapped to
|
||||
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// stb_image supports loading HDR images in general, and currently the Radiance
|
||||
// .HDR file format specifically. You can still load any file through the existing
|
||||
// interface; if you attempt to load an HDR file, it will be automatically remapped
|
||||
// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
|
||||
// both of these constants can be reconfigured through this interface:
|
||||
//
|
||||
// stbi_hdr_to_ldr_gamma(2.2f);
|
||||
@@ -257,7 +270,7 @@ RECENT REVISION HISTORY:
|
||||
//
|
||||
// By default we convert iphone-formatted PNGs back to RGB, even though
|
||||
// they are internally encoded differently. You can disable this conversion
|
||||
// by by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
||||
// by calling stbi_convert_iphone_png_to_rgb(0), in which case
|
||||
// you will always just get the native iphone "format" through (which
|
||||
// is BGR stored in RGB).
|
||||
//
|
||||
@@ -319,6 +332,7 @@ enum
|
||||
STBI_rgb_alpha = 4
|
||||
};
|
||||
|
||||
#include <stdlib.h>
|
||||
typedef unsigned char stbi_uc;
|
||||
typedef unsigned short stbi_us;
|
||||
|
||||
@@ -326,11 +340,13 @@ typedef unsigned short stbi_us;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef STBIDEF
|
||||
#ifdef STB_IMAGE_STATIC
|
||||
#define STBIDEF static
|
||||
#else
|
||||
#define STBIDEF extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -355,10 +371,6 @@ typedef struct
|
||||
|
||||
STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
#ifndef STBI_NO_GIF
|
||||
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
|
||||
@@ -366,6 +378,14 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in
|
||||
// for stbi_load_from_file, file pointer is left pointing immediately after image
|
||||
#endif
|
||||
|
||||
#ifndef STBI_NO_GIF
|
||||
STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
|
||||
#endif
|
||||
|
||||
#ifdef STBI_WINDOWS_UTF8
|
||||
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////
|
||||
//
|
||||
// 16-bits-per-channel interface
|
||||
@@ -525,6 +545,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
|
||||
#define STBI_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define STBI_EXTERN extern "C"
|
||||
#else
|
||||
#define STBI_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#ifdef __cplusplus
|
||||
@@ -649,14 +675,18 @@ static int stbi__cpuid3(void)
|
||||
|
||||
#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
||||
|
||||
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
||||
static int stbi__sse2_available(void)
|
||||
{
|
||||
int info3 = stbi__cpuid3();
|
||||
return ((info3 >> 26) & 1) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // assume GCC-style if not VC++
|
||||
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
|
||||
#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2)
|
||||
static int stbi__sse2_available(void)
|
||||
{
|
||||
// If we're even attempting to compile this on GCC/Clang, that means
|
||||
@@ -664,6 +694,8 @@ static int stbi__sse2_available(void)
|
||||
// instructions at will, and so are we.
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1070,6 +1102,7 @@ static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_GIF
|
||||
static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
|
||||
{
|
||||
int slice;
|
||||
@@ -1081,6 +1114,7 @@ static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int byt
|
||||
bytes += slice_size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
@@ -1131,7 +1165,7 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
|
||||
return (stbi__uint16 *) result;
|
||||
}
|
||||
|
||||
#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR)
|
||||
#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR)
|
||||
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
if (stbi__vertically_flip_on_load && result != NULL) {
|
||||
@@ -1143,10 +1177,38 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
|
||||
STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
|
||||
{
|
||||
return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static FILE *stbi__fopen(char const *filename, char const *mode)
|
||||
{
|
||||
FILE *f;
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
|
||||
wchar_t wMode[64];
|
||||
wchar_t wFilename[1024];
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
|
||||
return 0;
|
||||
|
||||
if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
|
||||
return 0;
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
if (0 != _wfopen_s(&f, wFilename, wMode))
|
||||
f = 0;
|
||||
#else
|
||||
f = _wfopen(wFilename, wMode);
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
if (0 != fopen_s(&f, filename, mode))
|
||||
f=0;
|
||||
#else
|
||||
@@ -1539,18 +1601,18 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
||||
// convert source image with img_n components to one with req_comp components;
|
||||
// avoid switch per pixel, so use switch per scanline and massive macros
|
||||
switch (STBI__COMBO(img_n, req_comp)) {
|
||||
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break;
|
||||
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break;
|
||||
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break;
|
||||
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
||||
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break;
|
||||
STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break;
|
||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||
default: STBI_ASSERT(0);
|
||||
}
|
||||
#undef STBI__CASE
|
||||
@@ -1588,18 +1650,18 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
|
||||
// convert source image with img_n components to one with req_comp components;
|
||||
// avoid switch per pixel, so use switch per scanline and massive macros
|
||||
switch (STBI__COMBO(img_n, req_comp)) {
|
||||
STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break;
|
||||
STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break;
|
||||
STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break;
|
||||
STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break;
|
||||
STBI__CASE(2,1) { dest[0]=src[0]; } break;
|
||||
STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break;
|
||||
STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break;
|
||||
STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break;
|
||||
STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break;
|
||||
STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break;
|
||||
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
|
||||
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
|
||||
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
|
||||
default: STBI_ASSERT(0);
|
||||
}
|
||||
#undef STBI__CASE
|
||||
@@ -1623,7 +1685,11 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
||||
for (k=0; k < n; ++k) {
|
||||
output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
|
||||
}
|
||||
if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
|
||||
}
|
||||
if (n < comp) {
|
||||
for (i=0; i < x*y; ++i) {
|
||||
output[i*comp + n] = data[i*comp + n]/255.0f;
|
||||
}
|
||||
}
|
||||
STBI_FREE(data);
|
||||
return output;
|
||||
@@ -3596,7 +3662,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
||||
int k;
|
||||
unsigned int i,j;
|
||||
stbi_uc *output;
|
||||
stbi_uc *coutput[4];
|
||||
stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
stbi__resample res_comp[4];
|
||||
|
||||
@@ -3717,7 +3783,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
||||
if (n == 1)
|
||||
for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
|
||||
else
|
||||
for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
|
||||
for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4731,7 +4797,7 @@ static void stbi__de_iphone(stbi__png *z)
|
||||
static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
{
|
||||
stbi_uc palette[1024], pal_img_n=0;
|
||||
stbi_uc has_trans=0, tc[3];
|
||||
stbi_uc has_trans=0, tc[3]={0};
|
||||
stbi__uint16 tc16[3];
|
||||
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
||||
int first=1,k,interlace=0, color=0, is_iphone=0;
|
||||
@@ -5009,11 +5075,11 @@ static int stbi__high_bit(unsigned int z)
|
||||
{
|
||||
int n=0;
|
||||
if (z == 0) return -1;
|
||||
if (z >= 0x10000) n += 16, z >>= 16;
|
||||
if (z >= 0x00100) n += 8, z >>= 8;
|
||||
if (z >= 0x00010) n += 4, z >>= 4;
|
||||
if (z >= 0x00004) n += 2, z >>= 2;
|
||||
if (z >= 0x00002) n += 1, z >>= 1;
|
||||
if (z >= 0x10000) { n += 16; z >>= 16; }
|
||||
if (z >= 0x00100) { n += 8; z >>= 8; }
|
||||
if (z >= 0x00010) { n += 4; z >>= 4; }
|
||||
if (z >= 0x00004) { n += 2; z >>= 2; }
|
||||
if (z >= 0x00002) { n += 1; z >>= 1; }
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -5030,7 +5096,7 @@ static int stbi__bitcount(unsigned int a)
|
||||
// extract an arbitrarily-aligned N-bit value (N=bits)
|
||||
// from v, and then make it 8-bits long and fractionally
|
||||
// extend it to full full range.
|
||||
static int stbi__shiftsigned(int v, int shift, int bits)
|
||||
static int stbi__shiftsigned(unsigned int v, int shift, int bits)
|
||||
{
|
||||
static unsigned int mul_table[9] = {
|
||||
0,
|
||||
@@ -5207,6 +5273,8 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||
out[z++] = pal[color][0];
|
||||
out[z++] = pal[color][1];
|
||||
out[z++] = pal[color][2];
|
||||
if (target == 4) out[z++] = 255;
|
||||
if (i+1 == (int) s->img_x) break;
|
||||
if((--bit_offset) < 0) {
|
||||
bit_offset = 7;
|
||||
v = stbi__get8(s);
|
||||
@@ -5299,7 +5367,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||
stbi_uc *p1 = out + j *s->img_x*target;
|
||||
stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
|
||||
for (i=0; i < (int) s->img_x*target; ++i) {
|
||||
t = p1[i], p1[i] = p2[i], p2[i] = t;
|
||||
t = p1[i]; p1[i] = p2[i]; p2[i] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5789,7 +5857,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||
// Else if n is 128, noop.
|
||||
// Endloop
|
||||
|
||||
// The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
|
||||
// The RLE-compressed data is preceded by a 2-byte data count for each row in the data,
|
||||
// which we're going to just skip.
|
||||
stbi__skip(s, h * channelCount * 2 );
|
||||
|
||||
@@ -6342,22 +6410,27 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
||||
int first_frame;
|
||||
int pi;
|
||||
int pcount;
|
||||
STBI_NOTUSED(req_comp);
|
||||
|
||||
// on first frame, any non-written pixels get the background colour (non-transparent)
|
||||
first_frame = 0;
|
||||
if (g->out == 0) {
|
||||
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
g->history = (stbi_uc *) stbi__malloc(g->w * g->h);
|
||||
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
|
||||
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
||||
if (!stbi__mad3sizes_valid(4, g->w, g->h, 0))
|
||||
return stbi__errpuc("too large", "GIF image is too large");
|
||||
pcount = g->w * g->h;
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * pcount);
|
||||
g->background = (stbi_uc *) stbi__malloc(4 * pcount);
|
||||
g->history = (stbi_uc *) stbi__malloc(pcount);
|
||||
if (!g->out || !g->background || !g->history)
|
||||
return stbi__errpuc("outofmem", "Out of memory");
|
||||
|
||||
// image is treated as "tranparent" at the start - ie, nothing overwrites the current background;
|
||||
// image is treated as "transparent" at the start - ie, nothing overwrites the current background;
|
||||
// background colour is only used for pixels that are not rendered first frame, after that "background"
|
||||
// color refers to teh color that was there the previous frame.
|
||||
memset( g->out, 0x00, 4 * g->w * g->h );
|
||||
memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
|
||||
memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
|
||||
// color refers to the color that was there the previous frame.
|
||||
memset(g->out, 0x00, 4 * pcount);
|
||||
memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent)
|
||||
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
|
||||
first_frame = 1;
|
||||
} else {
|
||||
// second frame - how do we dispoase of the previous one?
|
||||
@@ -6418,6 +6491,13 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
||||
g->cur_x = g->start_x;
|
||||
g->cur_y = g->start_y;
|
||||
|
||||
// if the width of the specified rectangle is 0, that means
|
||||
// we may not see *any* pixels or the image is malformed;
|
||||
// to make sure this is caught, move the current y down to
|
||||
// max_y (which is what out_gif_code checks).
|
||||
if (w == 0)
|
||||
g->cur_y = g->max_y;
|
||||
|
||||
g->lflags = stbi__get8(s);
|
||||
|
||||
if (g->lflags & 0x40) {
|
||||
@@ -6437,7 +6517,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
||||
return stbi__errpuc("missing color table", "Corrupt GIF");
|
||||
|
||||
o = stbi__process_gif_raster(s, g);
|
||||
if (o == NULL) return NULL;
|
||||
if (!o) return NULL;
|
||||
|
||||
// if this was the first frame,
|
||||
pcount = g->w * g->h;
|
||||
@@ -6565,6 +6645,7 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||
stbi_uc *u = 0;
|
||||
stbi__gif g;
|
||||
memset(&g, 0, sizeof(g));
|
||||
STBI_NOTUSED(ri);
|
||||
|
||||
u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
|
||||
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
|
||||
@@ -6576,6 +6657,9 @@ static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req
|
||||
// can be done for multiple frames.
|
||||
if (req_comp && req_comp != 4)
|
||||
u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
|
||||
} else if (g.out) {
|
||||
// if there was an error and we allocated an image buffer, free it!
|
||||
STBI_FREE(g.out);
|
||||
}
|
||||
|
||||
// free buffers needed for multiple frame loading;
|
||||
@@ -7238,6 +7322,7 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
|
||||
|
||||
/*
|
||||
revision history:
|
||||
2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs
|
||||
2.19 (2018-02-11) fix warning
|
||||
2.18 (2018-01-30) fix warnings
|
||||
2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
|
||||
|
||||
Vendored
+58
-29
@@ -1,4 +1,4 @@
|
||||
// stb_truetype.h - v1.19 - public domain
|
||||
// stb_truetype.h - v1.21 - public domain
|
||||
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
|
||||
//
|
||||
// This library processes TrueType files:
|
||||
@@ -49,6 +49,8 @@
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.21 (2019-02-25) fix warning
|
||||
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
||||
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
|
||||
// 1.18 (2018-01-29) add missing function
|
||||
// 1.17 (2017-07-23) make more arguments const; doc fix
|
||||
@@ -75,7 +77,7 @@
|
||||
//
|
||||
// USAGE
|
||||
//
|
||||
// Include this file in whatever places neeed to refer to it. In ONE C/C++
|
||||
// Include this file in whatever places need to refer to it. In ONE C/C++
|
||||
// file, write:
|
||||
// #define STB_TRUETYPE_IMPLEMENTATION
|
||||
// before the #include of this file. This expands out the actual
|
||||
@@ -242,19 +244,6 @@
|
||||
// recommend it.
|
||||
//
|
||||
//
|
||||
// SOURCE STATISTICS (based on v0.6c, 2050 LOC)
|
||||
//
|
||||
// Documentation & header file 520 LOC \___ 660 LOC documentation
|
||||
// Sample code 140 LOC /
|
||||
// Truetype parsing 620 LOC ---- 620 LOC TrueType
|
||||
// Software rasterization 240 LOC \ .
|
||||
// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
|
||||
// Bitmap management 100 LOC /
|
||||
// Baked bitmap interface 70 LOC /
|
||||
// Font name matching & access 150 LOC ---- 150
|
||||
// C runtime library abstraction 60 LOC ---- 60
|
||||
//
|
||||
//
|
||||
// PERFORMANCE MEASUREMENTS FOR 1.06:
|
||||
//
|
||||
// 32-bit 64-bit
|
||||
@@ -556,6 +545,8 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
|
||||
//
|
||||
// It's inefficient; you might want to c&p it and optimize it.
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
|
||||
// Query the font vertical metrics without having to create a font first.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -641,6 +632,12 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
||||
// To use with PackFontRangesGather etc., you must set it before calls
|
||||
// call to PackFontRangesGatherRects.
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
|
||||
// If skip != 0, this tells stb_truetype to skip any codepoints for which
|
||||
// there is no corresponding glyph. If skip=0, which is the default, then
|
||||
// codepoints without a glyph recived the font's "missing character" glyph,
|
||||
// typically an empty box by convention.
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
|
||||
int char_index, // character to display
|
||||
float *xpos, float *ypos, // pointers to current position in screen pixel space
|
||||
@@ -669,6 +666,7 @@ struct stbtt_pack_context {
|
||||
int height;
|
||||
int stride_in_bytes;
|
||||
int padding;
|
||||
int skip_missing;
|
||||
unsigned int h_oversample, v_oversample;
|
||||
unsigned char *pixels;
|
||||
void *nodes;
|
||||
@@ -694,7 +692,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
|
||||
// file will only define one font and it always be at offset 0, so it will
|
||||
// return '0' for index 0, and -1 for all other indices.
|
||||
|
||||
// The following structure is defined publically so you can declare one on
|
||||
// The following structure is defined publicly so you can declare one on
|
||||
// the stack or as a global or etc, but you should treat it as opaque.
|
||||
struct stbtt_fontinfo
|
||||
{
|
||||
@@ -733,6 +731,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
|
||||
// and you want a speed-up, call this function with the character you're
|
||||
// going to process, then use glyph-based functions instead of the
|
||||
// codepoint-based functions.
|
||||
// Returns 0 if the character codepoint is not defined in the font.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -820,7 +819,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
|
||||
// returns # of vertices and fills *vertices with the pointer to them
|
||||
// these are expressed in "unscaled" coordinates
|
||||
//
|
||||
// The shape is a series of countours. Each one starts with
|
||||
// The shape is a series of contours. Each one starts with
|
||||
// a STBTT_moveto, then consists of a series of mixed
|
||||
// STBTT_lineto and STBTT_curveto segments. A lineto
|
||||
// draws a line from previous endpoint to its x,y; a curveto
|
||||
@@ -916,7 +915,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
||||
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
|
||||
// These functions compute a discretized SDF field for a single character, suitable for storing
|
||||
// in a single-channel texture, sampling with bilinear filtering, and testing against
|
||||
// larger than some threshhold to produce scalable fonts.
|
||||
// larger than some threshold to produce scalable fonts.
|
||||
// info -- the font
|
||||
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
|
||||
// glyph/codepoint -- the character to generate the SDF for
|
||||
@@ -2463,6 +2462,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
|
||||
if (valueFormat2 != 0) return 0;
|
||||
|
||||
STBTT_assert(coverageIndex < pairSetCount);
|
||||
STBTT__NOTUSED(pairSetCount);
|
||||
|
||||
needle=glyph2;
|
||||
r=pairValueCount-1;
|
||||
@@ -3160,7 +3160,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
|
||||
if (e->y0 != e->y1) {
|
||||
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
|
||||
if (z != NULL) {
|
||||
STBTT_assert(z->ey >= scan_y_top);
|
||||
if (j == 0 && off_y != 0) {
|
||||
if (z->ey < scan_y_top) {
|
||||
// this can happen due to subpixel positioning and some kind of fp rounding error i think
|
||||
z->ey = scan_y_top;
|
||||
}
|
||||
}
|
||||
STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
|
||||
// insert at front
|
||||
z->next = active;
|
||||
active = z;
|
||||
@@ -3229,7 +3235,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
|
||||
|
||||
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
|
||||
{
|
||||
/* threshhold for transitioning to insertion sort */
|
||||
/* threshold for transitioning to insertion sort */
|
||||
while (n > 12) {
|
||||
stbtt__edge t;
|
||||
int c01,c12,c,m,i,j;
|
||||
@@ -3364,7 +3370,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
|
||||
points[n].y = y;
|
||||
}
|
||||
|
||||
// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
|
||||
{
|
||||
// midpoint
|
||||
@@ -3789,6 +3795,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
|
||||
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
|
||||
spc->h_oversample = 1;
|
||||
spc->v_oversample = 1;
|
||||
spc->skip_missing = 0;
|
||||
|
||||
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
|
||||
|
||||
@@ -3814,6 +3821,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
||||
spc->v_oversample = v_oversample;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
|
||||
{
|
||||
spc->skip_missing = skip;
|
||||
}
|
||||
|
||||
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
|
||||
|
||||
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
|
||||
@@ -3967,13 +3979,17 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
||||
int x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
int glyph = stbtt_FindGlyphIndex(info, codepoint);
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
0,0,
|
||||
&x0,&y0,&x1,&y1);
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
if (glyph == 0 && spc->skip_missing) {
|
||||
rects[k].w = rects[k].h = 0;
|
||||
} else {
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
0,0,
|
||||
&x0,&y0,&x1,&y1);
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
}
|
||||
++k;
|
||||
}
|
||||
}
|
||||
@@ -4026,7 +4042,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
|
||||
sub_y = stbtt__oversample_shift(spc->v_oversample);
|
||||
for (j=0; j < ranges[i].num_chars; ++j) {
|
||||
stbrp_rect *r = &rects[k];
|
||||
if (r->was_packed) {
|
||||
if (r->was_packed && r->w != 0 && r->h != 0) {
|
||||
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
||||
int advance, lsb, x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
@@ -4140,6 +4156,19 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *
|
||||
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
|
||||
{
|
||||
int i_ascent, i_descent, i_lineGap;
|
||||
float scale;
|
||||
stbtt_fontinfo info;
|
||||
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
|
||||
scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
|
||||
stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
|
||||
*ascent = (float) i_ascent * scale;
|
||||
*descent = (float) i_descent * scale;
|
||||
*lineGap = (float) i_lineGap * scale;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
|
||||
{
|
||||
float ipw = 1.0f / pw, iph = 1.0f / ph;
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/xxHash updated: 3064d42e7d...7cc9639699
Vendored
+2
-2
@@ -12,12 +12,12 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{939FE206-1182-ABC3-1234-FEAB88E98404}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/yaml-cpp updated: c90c08ccc9...eca9cfd648
Vendored
+2
-2
@@ -13,13 +13,13 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{FDC361C5-7734-493B-8CFB-037308B35122}</ProjectGuid>
|
||||
<RootNamespace>yamlcpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
Vendored
+2
-3
@@ -27,17 +27,16 @@
|
||||
<ProjectGuid>{60F89955-91C6-3A36-8000-13C592FEC2DF}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>zlib</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\3rdparty\zlib.props" />
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
# Building
|
||||
|
||||
Only Windows and Linux are officially supported for building. However, various other platforms are capable of building RPCS3.
|
||||
Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Building).
|
||||
|
||||
## Setup your environment
|
||||
|
||||
### Windows 7 or later
|
||||
|
||||
* [CMake 3.8.2+](https://www.cmake.org/download/) (add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (add to PATH)
|
||||
* [Qt 5.10+](https://www.qt.io/download-qt-installer) (Avoid 5.11.1, due to a bug)
|
||||
* [Visual Studio 2017](https://visualstudio.microsoft.com/vs/older-downloads/)
|
||||
* [Vulkan SDK 1.1.97.0+](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.10.0\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
|
||||
|
||||
### Linux
|
||||
|
||||
These are the essentials tools to build RPCS3 on Linux. Some of them can be installed through your favorite package manager.
|
||||
|
||||
* Clang 5.0+ or GCC 8.1+
|
||||
* [CMake 3.8.2+](https://www.cmake.org/download/)
|
||||
* [Qt 5.10+](https://www.qt.io/download-qt-installer) (Avoid 5.11.1, due to a bug)
|
||||
* [Vulkan SDK 1.1.97.0+](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html))
|
||||
|
||||
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
sudo pacman -S glew openal cmake vulkan-validation-layers qt5-base qt5-declarative
|
||||
|
||||
#### Debian & Ubuntu
|
||||
|
||||
sudo apt-get install cmake build-essential libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default libevdev-dev qtdeclarative5-dev qtbase5-private-dev
|
||||
|
||||
##### GCC 8.x installation
|
||||
|
||||
If the `gcc-8` package is not available on your system, use the following command
|
||||
```
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
```
|
||||
Then
|
||||
```
|
||||
sudo apt-get update
|
||||
sudo apt-get install gcc-8 g++-8
|
||||
```
|
||||
|
||||
You can either use `update-alternatives` to setup `gcc-8`/`g++-8` as your default compilers or prefix any `cmake` command by `CXX=g++-8 CC=gcc-8 ` to use it.
|
||||
|
||||
##### Vulkan SDK
|
||||
|
||||
For Ubuntu systems, it is strongly recommended to use the PPA from [LunarG](https://packages.lunarg.com/) which will provide a compatible Vulkan SDK to compile RPCS3. If your Vulkan SDK is older, it can lead to compilation errors.
|
||||
|
||||
Ubuntu 18.04 (Bionic Beaver)
|
||||
```
|
||||
wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
|
||||
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.1.106-bionic.list http://packages.lunarg.com/vulkan/1.1.106/lunarg-vulkan-1.1.106-bionic.list
|
||||
sudo apt update
|
||||
sudo apt install vulkan-sdk
|
||||
```
|
||||
|
||||
Ubuntu 16.04 (Xenial Xerus)
|
||||
```
|
||||
wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
|
||||
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.1.106-xenial.list http://packages.lunarg.com/vulkan/1.1.106/lunarg-vulkan-1.1.106-xenial.list
|
||||
sudo apt update
|
||||
sudo apt install vulkan-sdk
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
|
||||
sudo dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-devel vulkan-devel
|
||||
|
||||
#### OpenSUSE
|
||||
|
||||
sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel glew-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt5-qtbase-devel libevdev-devel
|
||||
|
||||
## Setup the project
|
||||
|
||||
Clone and initialize the repository
|
||||
|
||||
```
|
||||
git clone https://github.com/RPCS3/rpcs3.git
|
||||
cd rpcs3
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
#### Configuring the Qt plugin (if used)
|
||||
|
||||
1) Go to the Qt5 menu and edit Qt5 options.
|
||||
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.10.0\msvc2017_64`.
|
||||
3) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
#### Building the projects
|
||||
|
||||
Open `rpcs3.sln`. The recommended build configuration is `Release - LLVM` for all purposes.
|
||||
|
||||
You may want to download precompiled [LLVM libs](https://github.com/RPCS3/llvm/releases/download/continuous-master/llvmlibs.7z) and extract to root rpcs3 folder (which contains `rpcs3.sln`), as well as download and extract [additional libs](https://drive.google.com/uc?export=download&id=1A2eOMmCO714i0U7J0qI4aEMKnuWl8l_R) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
|
||||
|
||||
If you're not using precompiled libs, build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*.
|
||||
|
||||
`Build > Build Solution`
|
||||
|
||||
### Linux
|
||||
|
||||
While still in the project root:
|
||||
|
||||
1) `cd .. && mkdir rpcs3_build && cd rpcs3_build`
|
||||
2) `cmake ../rpcs3/ && make` or `CXX=g++-8 CC=gcc-8 cmake ../rpcs3/ && make` to force these compilers
|
||||
3) Run RPCS3 with `./bin/rpcs3`
|
||||
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
If desired, use the various build options in [CMakeLists](https://github.com/RPCS3/rpcs3/blob/master/CMakeLists.txt).
|
||||
+26
-5
@@ -2,20 +2,25 @@ cmake_minimum_required(VERSION 3.8.2)
|
||||
|
||||
project(rpcs3)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)
|
||||
message(FATAL_ERROR "RPCS3 requires at least gcc-8.")
|
||||
endif()
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
message(FATAL_ERROR "RPCS3 requires at least clang-5.0.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(WITH_GDB "WITH_GDB" OFF)
|
||||
option(USE_NATIVE_INSTRUCTIONS "USE_NATIVE_INSTRUCTIONS makes rpcs3 compile with -march=native, which is useful for local builds, but not good for packages." ON)
|
||||
|
||||
option(WITH_LLVM "Enable usage of LLVM library" ON)
|
||||
option(BUILD_LLVM_SUBMODULE "Build LLVM from git submodule" ON)
|
||||
|
||||
option(USE_ALSA "ALSA audio backend" ON)
|
||||
option(USE_PULSE "PulseAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
|
||||
option(USE_DISCORD_RPC "Discord rich presence integration" ON)
|
||||
|
||||
option(USE_SYSTEM_ZLIB "Prefer system ZLIB instead of the builtin one" ON)
|
||||
|
||||
option(USE_VULKAN "Vulkan render backend" ON)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/rpcs3/cmake_modules")
|
||||
@@ -56,10 +61,26 @@ if(APPLE)
|
||||
link_directories(/opt/local/lib)
|
||||
endif()
|
||||
|
||||
# Warnings are silenced for 3rdparty code
|
||||
set(CMAKE_CXX_FLAGS -w)
|
||||
set(CMAKE_C_FLAGS -w)
|
||||
set(LLVM_ENABLE_WARNINGS OFF CACHE BOOL "")
|
||||
|
||||
if(MSVC)
|
||||
add_compile_options(/wd4530) # C++ exception handler used, but unwind semantics are not enabled
|
||||
endif()
|
||||
|
||||
add_subdirectory(Vulkan EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(asmjitsrc EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(3rdparty)
|
||||
|
||||
unset(CMAKE_CXX_FLAGS)
|
||||
unset(CMAKE_C_FLAGS)
|
||||
|
||||
if (NOT WIN32)
|
||||
add_compile_options(-pthread)
|
||||
endif()
|
||||
|
||||
# TODO: do real installation, including copying directory structure
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_BINARY_DIR}/bin")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_BINARY_DIR}/bin")
|
||||
|
||||
@@ -11,7 +11,6 @@ For discussion about this emulator, PS3 emulation, and game compatibility report
|
||||
|
||||
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to help the project but do not code, the best way to help out is to test games and make bug reports. See:
|
||||
@@ -25,71 +24,15 @@ If you want to contribute as a developer, please take a look at the following pa
|
||||
|
||||
You should also contact any of the developers in the forums or in the Discord server to learn more about the current state of the emulator.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
### Windows
|
||||
* [Visual Studio 2017](https://www.visualstudio.com/en/downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
|
||||
* [CMake 3.8.2+](https://www.cmake.org/download/) (add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (add to PATH)
|
||||
* [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) (See "Install the SDK" [here](https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html))
|
||||
* [Qt 5.10+](https://www.qt.io/download-open-source/) (Avoid 5.11.1, due to a bug)
|
||||
|
||||
|
||||
**Either add the** `QTDIR` **environment variable, e.g.** `<QtInstallFolder>\5.11.2\msvc2017_64\` **, or use the [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools-19123)**
|
||||
|
||||
### Linux
|
||||
* [Qt 5.10+](https://www.qt.io/download-open-source/) (Avoid 5.11.1, due to a bug)
|
||||
* GCC 7.3+ or Clang 5.0+
|
||||
* CMake 3.8.2+
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libpulse-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default libevdev-dev`
|
||||
* Arch: `sudo pacman -S glew openal cmake vulkan-validation-layers qt5-base qt5-declarative`
|
||||
* Fedora: `sudo dnf install alsa-lib-devel cmake glew glew-devel libatomic libevdev-devel libudev-devel openal-devel qt5-devel vulkan-devel`
|
||||
* OpenSUSE: `sudo zypper install git cmake libasound2 libpulse-devel openal-soft-devel glew-devel zlib-devel libedit-devel vulkan-devel libudev-devel libqt5-qtbase-devel libevdev-devel`
|
||||
|
||||
**If you have an NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
Only Windows and Linux are officially supported for building. However, various other platforms are capable of building RPCS3. Other instructions may be found [here](https://wiki.rpcs3.net/index.php?title=Building).
|
||||
See [BUILDING.md](BUILDING.md) for more information about how to setup an environment to build RPCS3.
|
||||
|
||||
Clone and initialize the repository:
|
||||
## Running
|
||||
|
||||
1) `git clone https://github.com/RPCS3/rpcs3.git`
|
||||
2) `cd rpcs3/`
|
||||
3) `git submodule update --init`
|
||||
Check our friendly [quickstart](https://rpcs3.net/quickstart) guide to make sure your computer meets the minimum system requirements to run RPCS3.
|
||||
|
||||
### Windows
|
||||
#### Configuring the Qt plugin (if used)
|
||||
|
||||
1) Go to the Qt5 menu and edit Qt5 options.
|
||||
2) Add the path to your Qt installation with compiler e.g. `<QtInstallFolder>\5.11.2\msvc2017_64`.
|
||||
3) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
#### Building the projects
|
||||
|
||||
Open `rpcs3.sln`. The recommended build configuration is `Release - LLVM` for all purposes.
|
||||
|
||||
You may want to download precompiled [LLVM libs](https://github.com/RPCS3/llvm/releases/download/continuous-master/llvmlibs.7z) and extract to root rpcs3 folder (which contains `rpcs3.sln`), as well as download and extract [additional libs](https://drive.google.com/uc?export=download&id=1A2eOMmCO714i0U7J0qI4aEMKnuWl8l_R) to `lib\%CONFIGURATION%-x64\` to speed up compilation time (unoptimised/debug libs are currently not available precompiled).
|
||||
|
||||
If you're not using precompiled libs, build the projects in *__BUILD_BEFORE* folder: right-click on every project > *Build*.
|
||||
|
||||
|
||||
`Build > Build Solution`
|
||||
|
||||
|
||||
### Linux
|
||||
|
||||
While still in the project root:
|
||||
|
||||
1) `cd .. && mkdir rpcs3_build && cd rpcs3_build`
|
||||
2) `cmake ../rpcs3/ && make GitVersion && make`
|
||||
3) Run RPCS3 with `./bin/rpcs3`
|
||||
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
If desired, use the various build options in [CMakeLists](https://github.com/RPCS3/rpcs3/blob/master/CMakeLists.txt).
|
||||
Don't forget to have your graphics driver up to date and to install the [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572) if you are a Windows user.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
|
||||
// Unfinished. Only std::default_delete will work as expected.
|
||||
template<typename T, typename D>
|
||||
|
||||
+21
-24
@@ -380,13 +380,12 @@ struct se_storage<T, 2, 2>
|
||||
|
||||
static inline u16 to(const T& src)
|
||||
{
|
||||
return swap(reinterpret_cast<const u16&>(src));
|
||||
return swap(std::bit_cast<u16>(src));
|
||||
}
|
||||
|
||||
static inline T from(u16 src)
|
||||
{
|
||||
const u16 result = swap(src);
|
||||
return reinterpret_cast<const T&>(result);
|
||||
return std::bit_cast<T, u16>(swap(src));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -406,13 +405,12 @@ struct se_storage<T, 4, 4>
|
||||
|
||||
static inline u32 to(const T& src)
|
||||
{
|
||||
return swap(reinterpret_cast<const u32&>(src));
|
||||
return swap(std::bit_cast<u32>(src));
|
||||
}
|
||||
|
||||
static inline T from(u32 src)
|
||||
{
|
||||
const u32 result = swap(src);
|
||||
return reinterpret_cast<const T&>(result);
|
||||
return std::bit_cast<T, u32>(swap(src));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -432,13 +430,12 @@ struct se_storage<T, 8, 8>
|
||||
|
||||
static inline u64 to(const T& src)
|
||||
{
|
||||
return swap(reinterpret_cast<const u64&>(src));
|
||||
return swap(std::bit_cast<u64>(src));
|
||||
}
|
||||
|
||||
static inline T from(u64 src)
|
||||
{
|
||||
const u64 result = swap(src);
|
||||
return reinterpret_cast<const T&>(result);
|
||||
return std::bit_cast<T, u64>(swap(src));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -454,13 +451,12 @@ struct se_storage<T, 16, 16>
|
||||
|
||||
static inline v128 to(const T& src)
|
||||
{
|
||||
return swap(reinterpret_cast<const v128&>(src));
|
||||
return swap(std::bit_cast<v128>(src));
|
||||
}
|
||||
|
||||
static inline T from(const v128& src)
|
||||
{
|
||||
const v128 result = swap(src);
|
||||
return reinterpret_cast<const T&>(result);
|
||||
return std::bit_cast<T, v128>(swap(src));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -494,6 +490,11 @@ public:
|
||||
return storage::from(m_data);
|
||||
}
|
||||
|
||||
stype& raw()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
se_t& operator=(const se_t&) = default;
|
||||
|
||||
se_t& operator=(type value)
|
||||
@@ -524,33 +525,29 @@ class se_t<T, false, Align>
|
||||
|
||||
stype m_data;
|
||||
|
||||
static stype init(type value)
|
||||
{
|
||||
stype result;
|
||||
std::memcpy(&result, &value, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
public:
|
||||
se_t() = default;
|
||||
|
||||
se_t(type value)
|
||||
: m_data(init(value))
|
||||
: m_data(std::bit_cast<stype>(value))
|
||||
{
|
||||
}
|
||||
|
||||
type value() const
|
||||
{
|
||||
type result;
|
||||
std::memcpy(&result, &m_data, sizeof(result));
|
||||
return result;
|
||||
return std::bit_cast<type>(m_data);
|
||||
}
|
||||
|
||||
stype& raw()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
se_t& operator=(const se_t& value) = default;
|
||||
|
||||
se_t& operator=(type value)
|
||||
{
|
||||
std::memcpy(&m_data, &value, sizeof(m_data));
|
||||
m_data = std::bit_cast<stype>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <limits>
|
||||
|
||||
template<typename T, uint N>
|
||||
struct bf_base
|
||||
@@ -15,11 +16,11 @@ struct bf_base
|
||||
// Field bitsize
|
||||
static constexpr uint bitsize = N;
|
||||
|
||||
// Value mask
|
||||
static constexpr utype vmask = static_cast<utype>(~utype{} >> (bitmax - bitsize));
|
||||
|
||||
// All ones mask
|
||||
static constexpr utype mask1 = static_cast<utype>(~utype{});
|
||||
static constexpr utype mask1 = std::numeric_limits<utype>::max();
|
||||
|
||||
// Value mask
|
||||
static constexpr utype vmask = mask1 >> (bitmax - bitsize);
|
||||
|
||||
protected:
|
||||
type m_data;
|
||||
|
||||
+10
-6
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
@@ -133,7 +133,7 @@ namespace cfg
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool get() const
|
||||
const bool& get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
@@ -184,7 +184,7 @@ namespace cfg
|
||||
return m_value;
|
||||
}
|
||||
|
||||
T get() const
|
||||
const T& get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
@@ -235,6 +235,10 @@ namespace cfg
|
||||
public:
|
||||
int_type def;
|
||||
|
||||
// Expose range
|
||||
static const s64 max = Max;
|
||||
static const s64 min = Min;
|
||||
|
||||
_int(node* owner, const std::string& name, int_type def = std::min<int_type>(Max, std::max<int_type>(Min, 0)))
|
||||
: _base(type::_int, owner, name)
|
||||
, m_value(def)
|
||||
@@ -247,7 +251,7 @@ namespace cfg
|
||||
return m_value;
|
||||
}
|
||||
|
||||
int_type get() const
|
||||
const int_type& get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
@@ -347,7 +351,7 @@ namespace cfg
|
||||
{
|
||||
}
|
||||
|
||||
std::set<std::string> get_set() const
|
||||
const std::set<std::string>& get_set() const
|
||||
{
|
||||
return m_set;
|
||||
}
|
||||
@@ -382,7 +386,7 @@ namespace cfg
|
||||
{
|
||||
}
|
||||
|
||||
std::map<std::string, logs::level> get_map() const
|
||||
const std::map<std::string, logs::level>& get_map() const
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
|
||||
+113
-22
@@ -125,6 +125,7 @@ static fs::error to_error(DWORD e)
|
||||
#include <sys/types.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/uio.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
@@ -137,6 +138,8 @@ static fs::error to_error(DWORD e)
|
||||
#include <mach-o/dyld.h>
|
||||
#elif defined(__linux__) || defined(__sun)
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/fs.h>
|
||||
#else
|
||||
#include <fstream>
|
||||
#endif
|
||||
@@ -192,6 +195,43 @@ namespace fs
|
||||
// Do notning
|
||||
}
|
||||
|
||||
fs::native_handle fs::file_base::get_handle()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
u64 file_base::write_gather(const iovec_clone* buffers, u64 buf_count)
|
||||
{
|
||||
u64 total = 0;
|
||||
|
||||
for (u64 i = 0; i < buf_count; i++)
|
||||
{
|
||||
if (!buffers[i].iov_base || buffers[i].iov_len + total < total)
|
||||
{
|
||||
g_tls_error = error::inval;
|
||||
return -1;
|
||||
}
|
||||
|
||||
total += buffers[i].iov_len;
|
||||
}
|
||||
|
||||
const auto buf = std::make_unique<uchar[]>(total);
|
||||
|
||||
u64 copied = 0;
|
||||
|
||||
for (u64 i = 0; i < buf_count; i++)
|
||||
{
|
||||
std::memcpy(buf.get() + copied, buffers[i].iov_base, buffers[i].iov_len);
|
||||
copied += buffers[i].iov_len;
|
||||
}
|
||||
|
||||
return this->write(buf.get(), total);
|
||||
}
|
||||
|
||||
dir_base::~dir_base()
|
||||
{
|
||||
}
|
||||
@@ -600,6 +640,21 @@ bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
|
||||
|
||||
return true;
|
||||
#else
|
||||
|
||||
#ifdef __linux__
|
||||
if (syscall(SYS_renameat2, AT_FDCWD, from.c_str(), AT_FDCWD, to.c_str(), overwrite ? 0 : 1 /* RENAME_NOREPLACE */) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the filesystem doesn't support RENAME_NOREPLACE, it returns EINVAL. Retry with fallback method in that case.
|
||||
if (errno != EINVAL || overwrite)
|
||||
{
|
||||
g_tls_error = to_error(errno);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!overwrite && exists(to))
|
||||
{
|
||||
g_tls_error = fs::error::exist;
|
||||
@@ -884,7 +939,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class windows_file final : public file_base, public get_native_handle
|
||||
class windows_file final : public file_base
|
||||
{
|
||||
const HANDLE m_handle;
|
||||
|
||||
@@ -987,7 +1042,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
native_handle get_handle() override
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
@@ -1034,7 +1089,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
::ftruncate(fd, 0);
|
||||
}
|
||||
|
||||
class unix_file final : public file_base, public get_native_handle
|
||||
class unix_file final : public file_base
|
||||
{
|
||||
const int m_fd;
|
||||
|
||||
@@ -1127,10 +1182,21 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return file_info.st_size;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
native_handle get_handle() override
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
u64 write_gather(const iovec_clone* buffers, u64 buf_count) override
|
||||
{
|
||||
static_assert(sizeof(iovec) == sizeof(iovec_clone), "Weird iovec size");
|
||||
static_assert(offsetof(iovec, iov_len) == offsetof(iovec_clone, iov_len), "Weird iovec::iov_len offset");
|
||||
|
||||
const auto result = ::writev(m_fd, (const iovec*)buffers, buf_count);
|
||||
verify("file::write_gather" HERE), result != -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<unix_file>(fd);
|
||||
@@ -1208,9 +1274,9 @@ fs::file::file(const void* ptr, std::size_t size)
|
||||
|
||||
fs::native_handle fs::file::get_handle() const
|
||||
{
|
||||
if (auto getter = dynamic_cast<get_native_handle*>(m_file.get()))
|
||||
if (m_file)
|
||||
{
|
||||
return getter->get();
|
||||
return m_file->get_handle();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1220,6 +1286,15 @@ fs::native_handle fs::file::get_handle() const
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
bool fs::file::set_delete(bool autodelete) const
|
||||
{
|
||||
FILE_DISPOSITION_INFO disp;
|
||||
disp.DeleteFileW = autodelete;
|
||||
return SetFileInformationByHandle(get_handle(), FileDispositionInfo, &disp, sizeof(disp)) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void fs::dir::xnull() const
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("fs::dir is null");
|
||||
@@ -1385,8 +1460,9 @@ const std::string& fs::get_config_dir()
|
||||
|
||||
#ifdef _WIN32
|
||||
wchar_t buf[32768];
|
||||
if (GetEnvironmentVariable(L"RPCS3_CONFIG_DIR", buf, std::size(buf)) - 1 >= std::size(buf) - 1 &&
|
||||
GetModuleFileName(NULL, buf, std::size(buf)) - 1 >= std::size(buf) - 1)
|
||||
constexpr DWORD size = static_cast<DWORD>(std::size(buf));
|
||||
if (GetEnvironmentVariable(L"RPCS3_CONFIG_DIR", buf, size) - 1 >= size - 1 &&
|
||||
GetModuleFileName(NULL, buf, size) - 1 >= size - 1)
|
||||
{
|
||||
MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
|
||||
return dir; // empty
|
||||
@@ -1463,30 +1539,45 @@ const std::string& fs::get_cache_dir()
|
||||
return s_dir;
|
||||
}
|
||||
|
||||
void fs::remove_all(const std::string& path, bool remove_root)
|
||||
bool fs::remove_all(const std::string& path, bool remove_root)
|
||||
{
|
||||
for (const auto& entry : dir(path))
|
||||
if (const auto root_dir = dir(path))
|
||||
{
|
||||
if (entry.name == "." || entry.name == "..")
|
||||
for (const auto& entry : root_dir)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.name == "." || entry.name == "..")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.is_directory == false)
|
||||
{
|
||||
remove_file(path + '/' + entry.name);
|
||||
}
|
||||
if (entry.is_directory == false)
|
||||
{
|
||||
if (!remove_file(path + '/' + entry.name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.is_directory == true)
|
||||
{
|
||||
remove_all(path + '/' + entry.name);
|
||||
if (entry.is_directory == true)
|
||||
{
|
||||
if (!remove_all(path + '/' + entry.name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remove_root)
|
||||
{
|
||||
remove_dir(path);
|
||||
return remove_dir(path);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 fs::get_dir_size(const std::string& path)
|
||||
|
||||
+19
-4
@@ -65,10 +65,11 @@ namespace fs
|
||||
s64 ctime;
|
||||
};
|
||||
|
||||
// Native handle getter
|
||||
struct get_native_handle
|
||||
// Helper, layout is equal to iovec struct
|
||||
struct iovec_clone
|
||||
{
|
||||
virtual native_handle get() = 0;
|
||||
const void* iov_base;
|
||||
std::size_t iov_len;
|
||||
};
|
||||
|
||||
// File handle base
|
||||
@@ -83,6 +84,8 @@ namespace fs
|
||||
virtual u64 write(const void* buffer, u64 size) = 0;
|
||||
virtual u64 seek(s64 offset, seek_mode whence) = 0;
|
||||
virtual u64 size() = 0;
|
||||
virtual native_handle get_handle();
|
||||
virtual u64 write_gather(const iovec_clone* buffers, u64 buf_count);
|
||||
};
|
||||
|
||||
// Directory entry (TODO)
|
||||
@@ -366,6 +369,18 @@ namespace fs
|
||||
|
||||
// Get native handle if available
|
||||
native_handle get_handle() const;
|
||||
|
||||
// Gathered write
|
||||
u64 write_gather(const iovec_clone* buffers, u64 buf_count) const
|
||||
{
|
||||
if (!m_file) xnull();
|
||||
return m_file->write_gather(buffers, buf_count);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows-specific function
|
||||
bool set_delete(bool autodelete = true) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class dir final
|
||||
@@ -488,7 +503,7 @@ namespace fs
|
||||
const std::string& get_cache_dir();
|
||||
|
||||
// Delete directory and all its contents recursively
|
||||
void remove_all(const std::string& path, bool remove_root = true);
|
||||
bool remove_all(const std::string& path, bool remove_root = true);
|
||||
|
||||
// Get size of all files recursively
|
||||
u64 get_dir_size(const std::string& path);
|
||||
|
||||
@@ -354,7 +354,7 @@ std::string GDBDebugServer::get_reg(std::shared_ptr<ppu_thread> thread, u32 rid)
|
||||
case 65:
|
||||
return std::string(16, 'x');
|
||||
case 66:
|
||||
return u32_to_padded_hex(thread->cr_pack());
|
||||
return u32_to_padded_hex(thread->cr.pack());
|
||||
case 67:
|
||||
return u64_to_padded_hex(thread->lr);
|
||||
case 68:
|
||||
@@ -368,7 +368,7 @@ std::string GDBDebugServer::get_reg(std::shared_ptr<ppu_thread> thread, u32 rid)
|
||||
default:
|
||||
if (rid > 70) return "";
|
||||
return (rid > 31)
|
||||
? u64_to_padded_hex(reinterpret_cast<u64&>(thread->fpr[rid - 32])) //fpr
|
||||
? u64_to_padded_hex(std::bit_cast<u64>(thread->fpr[rid - 32])) //fpr
|
||||
: u64_to_padded_hex(thread->gpr[rid]); //gpr
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,7 @@ bool GDBDebugServer::set_reg(std::shared_ptr<ppu_thread> thread, u32 rid, std::s
|
||||
case 65:
|
||||
return true;
|
||||
case 66:
|
||||
thread->cr_unpack(hex_to_u32(value));
|
||||
thread->cr.unpack(hex_to_u32(value));
|
||||
return true;
|
||||
case 67:
|
||||
thread->lr = hex_to_u64(value);
|
||||
@@ -401,7 +401,7 @@ bool GDBDebugServer::set_reg(std::shared_ptr<ppu_thread> thread, u32 rid, std::s
|
||||
if (rid > 70) return false;
|
||||
if (rid > 31) {
|
||||
u64 val = hex_to_u64(value);
|
||||
thread->fpr[rid - 32] = reinterpret_cast<f64&>(val);
|
||||
thread->fpr[rid - 32] = std::bit_cast<f64>(val);
|
||||
} else {
|
||||
thread->gpr[rid] = hex_to_u64(value);
|
||||
}
|
||||
@@ -541,7 +541,7 @@ bool GDBDebugServer::cmd_read_memory(gdb_cmd & cmd)
|
||||
std::string result;
|
||||
result.reserve(len * 2);
|
||||
for (u32 i = 0; i < len; ++i) {
|
||||
if (vm::check_addr(addr, 1, vm::page_allocated | vm::page_readable)) {
|
||||
if (vm::check_addr(addr)) {
|
||||
result += to_hexbyte(vm::read8(addr + i));
|
||||
} else {
|
||||
break;
|
||||
@@ -567,7 +567,7 @@ bool GDBDebugServer::cmd_write_memory(gdb_cmd & cmd)
|
||||
u32 len = hex_to_u32(cmd.data.substr(s + 1, s2 - s - 1));
|
||||
const char* data_ptr = (cmd.data.c_str()) + s2 + 1;
|
||||
for (u32 i = 0; i < len; ++i) {
|
||||
if (vm::check_addr(addr + i, 1, vm::page_allocated | vm::page_writable)) {
|
||||
if (vm::check_addr(addr + i, 1, vm::page_writable)) {
|
||||
u8 val;
|
||||
int res = sscanf_s(data_ptr, "%02hhX", &val);
|
||||
if (!res) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template<typename T1, typename T2> struct range_t
|
||||
{
|
||||
T1 _min; // first value
|
||||
|
||||
+108
-34
@@ -64,6 +64,8 @@ static u8* add_jit_memory(std::size_t size, uint align)
|
||||
|
||||
if (UNLIKELY(_new > 0x40000000))
|
||||
{
|
||||
// Sorry, we failed, and further attempts should fail too.
|
||||
ctr = 0x40000000;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -77,7 +79,7 @@ static u8* add_jit_memory(std::size_t size, uint align)
|
||||
|
||||
if (UNLIKELY(pos == -1))
|
||||
{
|
||||
LOG_FATAL(GENERAL, "JIT: Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
|
||||
LOG_WARNING(GENERAL, "JIT: Out of memory (size=0x%x, align=0x%x, off=0x%x)", size, align, Off);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -181,25 +183,41 @@ void jit_runtime::finalize() noexcept
|
||||
std::memcpy(alloc(s_data_init.size(), 1, false), s_data_init.data(), s_data_init.size());
|
||||
}
|
||||
|
||||
::jit_runtime& asmjit::get_global_runtime()
|
||||
asmjit::JitRuntime& asmjit::get_global_runtime()
|
||||
{
|
||||
// Magic static
|
||||
static ::jit_runtime g_rt;
|
||||
static asmjit::JitRuntime g_rt;
|
||||
return g_rt;
|
||||
}
|
||||
|
||||
asmjit::Label asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::Label fallback)
|
||||
void asmjit::build_transaction_enter(asmjit::X86Assembler& c, asmjit::Label fallback, const asmjit::X86Gp& ctr, uint less_than)
|
||||
{
|
||||
Label fall = c.newLabel();
|
||||
Label begin = c.newLabel();
|
||||
c.jmp(begin);
|
||||
c.bind(fall);
|
||||
c.test(x86::eax, _XABORT_RETRY);
|
||||
c.jz(fallback);
|
||||
|
||||
if (less_than < 65)
|
||||
{
|
||||
c.add(ctr, 1);
|
||||
c.test(x86::eax, _XABORT_RETRY);
|
||||
c.jz(fallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Count an attempt without RETRY flag as 65 normal attempts and continue
|
||||
c.not_(x86::eax);
|
||||
c.and_(x86::eax, _XABORT_RETRY);
|
||||
c.shl(x86::eax, 5);
|
||||
c.add(x86::eax, 1); // eax = RETRY ? 1 : 65
|
||||
c.add(ctr, x86::rax);
|
||||
}
|
||||
|
||||
c.cmp(ctr, less_than);
|
||||
c.jae(fallback);
|
||||
c.align(kAlignCode, 16);
|
||||
c.bind(begin);
|
||||
c.xbegin(fall);
|
||||
return begin;
|
||||
}
|
||||
|
||||
void asmjit::build_transaction_abort(asmjit::X86Assembler& c, unsigned char code)
|
||||
@@ -248,6 +266,7 @@ static void* const s_memory = []() -> void*
|
||||
{
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
llvm::InitializeNativeTargetAsmParser();
|
||||
LLVMLinkInMCJIT();
|
||||
|
||||
#ifdef MAP_32BIT
|
||||
@@ -472,7 +491,7 @@ struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
s_unfire.push_front(std::make_pair(addr, size));
|
||||
#endif
|
||||
|
||||
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
|
||||
return RTDyldMemoryManager::registerEHFramesInProcess(addr, size);
|
||||
}
|
||||
|
||||
void deregisterEHFrames() override
|
||||
@@ -503,6 +522,63 @@ struct MemoryManager2 : llvm::RTDyldMemoryManager
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void registerEHFrames(u8* addr, u64 load_addr, std::size_t size) override
|
||||
{
|
||||
#ifndef _WIN32
|
||||
RTDyldMemoryManager::registerEHFramesInProcess(addr, size);
|
||||
s_unfire.push_front(std::make_pair(addr, size));
|
||||
#endif
|
||||
}
|
||||
|
||||
void deregisterEHFrames() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Simple memory manager. I promise there will be no MemoryManager4.
|
||||
struct MemoryManager3 : llvm::RTDyldMemoryManager
|
||||
{
|
||||
std::vector<std::pair<u8*, std::size_t>> allocs;
|
||||
|
||||
MemoryManager3() = default;
|
||||
|
||||
~MemoryManager3() override
|
||||
{
|
||||
for (auto& a : allocs)
|
||||
{
|
||||
utils::memory_release(a.first, a.second);
|
||||
}
|
||||
}
|
||||
|
||||
u8* allocateCodeSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name) override
|
||||
{
|
||||
u8* r = static_cast<u8*>(utils::memory_reserve(size));
|
||||
utils::memory_commit(r, size, utils::protection::wx);
|
||||
allocs.emplace_back(r, size);
|
||||
return r;
|
||||
}
|
||||
|
||||
u8* allocateDataSection(std::uintptr_t size, uint align, uint sec_id, llvm::StringRef sec_name, bool is_ro) override
|
||||
{
|
||||
u8* r = static_cast<u8*>(utils::memory_reserve(size));
|
||||
utils::memory_commit(r, size);
|
||||
allocs.emplace_back(r, size);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool finalizeMemory(std::string* = nullptr) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void registerEHFrames(u8* addr, u64 load_addr, std::size_t size) override
|
||||
{
|
||||
}
|
||||
|
||||
void deregisterEHFrames() override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Helper class
|
||||
@@ -515,7 +591,7 @@ struct EventListener : llvm::JITEventListener
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyObjectEmitted(const llvm::object::ObjectFile& obj, const llvm::RuntimeDyld::LoadedObjectInfo& inf) override
|
||||
void notifyObjectLoaded(ObjectKey K, const llvm::object::ObjectFile& obj, const llvm::RuntimeDyld::LoadedObjectInfo& inf) override
|
||||
{
|
||||
#ifdef _WIN32
|
||||
for (auto it = obj.section_begin(), end = obj.section_end(); it != end; ++it)
|
||||
@@ -624,8 +700,11 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
m_cpu == "broadwell" ||
|
||||
m_cpu == "skylake" ||
|
||||
m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cascadelake" ||
|
||||
m_cpu == "cannonlake" ||
|
||||
m_cpu == "icelake")
|
||||
m_cpu == "icelake" ||
|
||||
m_cpu == "icelake-client" ||
|
||||
m_cpu == "icelake-server")
|
||||
{
|
||||
// Downgrade if AVX is not supported by some chips
|
||||
if (!utils::has_avx())
|
||||
@@ -635,8 +714,11 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
}
|
||||
|
||||
if (m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cascadelake" ||
|
||||
m_cpu == "cannonlake" ||
|
||||
m_cpu == "icelake")
|
||||
m_cpu == "icelake" ||
|
||||
m_cpu == "icelake-client" ||
|
||||
m_cpu == "icelake-server")
|
||||
{
|
||||
// Downgrade if AVX-512 is disabled or not supported
|
||||
if (!utils::has_512())
|
||||
@@ -649,7 +731,7 @@ std::string jit_compiler::cpu(const std::string& _cpu)
|
||||
return m_cpu;
|
||||
}
|
||||
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, bool large)
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, u32 flags)
|
||||
: m_link(_link)
|
||||
, m_cpu(cpu(_cpu))
|
||||
{
|
||||
@@ -657,13 +739,24 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||
|
||||
if (m_link.empty())
|
||||
{
|
||||
std::unique_ptr<llvm::RTDyldMemoryManager> mem;
|
||||
|
||||
if (flags & 0x1)
|
||||
{
|
||||
mem = std::make_unique<MemoryManager3>();
|
||||
}
|
||||
else
|
||||
{
|
||||
mem = std::make_unique<MemoryManager2>();
|
||||
}
|
||||
|
||||
// Auxiliary JIT (does not use custom memory manager, only writes the objects)
|
||||
m_engine.reset(llvm::EngineBuilder(std::make_unique<llvm::Module>("null_", m_context))
|
||||
.setErrorStr(&result)
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.setMCJITMemoryManager(std::make_unique<MemoryManager2>())
|
||||
.setMCJITMemoryManager(std::move(mem))
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setCodeModel(large ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
.setCodeModel(flags & 0x2 ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
.setMCPU(m_cpu)
|
||||
.create());
|
||||
}
|
||||
@@ -678,7 +771,7 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, co
|
||||
.setEngineKind(llvm::EngineKind::JIT)
|
||||
.setMCJITMemoryManager(std::move(mem))
|
||||
.setOptLevel(llvm::CodeGenOpt::Aggressive)
|
||||
.setCodeModel(large ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
.setCodeModel(flags & 0x2 ? llvm::CodeModel::Large : llvm::CodeModel::Small)
|
||||
.setMCPU(m_cpu)
|
||||
.create());
|
||||
|
||||
@@ -698,25 +791,6 @@ jit_compiler::~jit_compiler()
|
||||
{
|
||||
}
|
||||
|
||||
bool jit_compiler::has_ssse3() const
|
||||
{
|
||||
if (m_cpu == "generic" ||
|
||||
m_cpu == "k8" ||
|
||||
m_cpu == "opteron" ||
|
||||
m_cpu == "athlon64" ||
|
||||
m_cpu == "athlon-fx" ||
|
||||
m_cpu == "k8-sse3" ||
|
||||
m_cpu == "opteron-sse3" ||
|
||||
m_cpu == "athlon64-sse3" ||
|
||||
m_cpu == "amdfam10" ||
|
||||
m_cpu == "barcelona")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string& path)
|
||||
{
|
||||
ObjectCache cache{path};
|
||||
|
||||
+3
-6
@@ -40,10 +40,10 @@ struct jit_runtime final : asmjit::HostRuntime
|
||||
namespace asmjit
|
||||
{
|
||||
// Should only be used to build global functions
|
||||
::jit_runtime& get_global_runtime();
|
||||
asmjit::JitRuntime& get_global_runtime();
|
||||
|
||||
// Emit xbegin and adjacent loop, return label at xbegin
|
||||
Label build_transaction_enter(X86Assembler& c, Label fallback);
|
||||
void build_transaction_enter(X86Assembler& c, Label fallback, const X86Gp& ctr, uint less_than);
|
||||
|
||||
// Emit xabort
|
||||
void build_transaction_abort(X86Assembler& c, unsigned char code);
|
||||
@@ -128,7 +128,7 @@ class jit_compiler final
|
||||
std::string m_cpu;
|
||||
|
||||
public:
|
||||
jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, bool large = false);
|
||||
jit_compiler(const std::unordered_map<std::string, u64>& _link, const std::string& _cpu, u32 flags = 0);
|
||||
~jit_compiler();
|
||||
|
||||
// Get LLVM context
|
||||
@@ -142,9 +142,6 @@ public:
|
||||
return *m_engine;
|
||||
}
|
||||
|
||||
// Test SSSE3 feature
|
||||
bool has_ssse3() const;
|
||||
|
||||
// Add module (path to obj cache dir)
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
|
||||
+18
-8
@@ -387,9 +387,7 @@ logs::file_writer::file_writer(const std::string& name)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Autodelete compressed log file
|
||||
FILE_DISPOSITION_INFO disp;
|
||||
disp.DeleteFileW = TRUE;
|
||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||
m_fout2.set_delete();
|
||||
#endif
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@@ -469,9 +467,7 @@ logs::file_writer::~file_writer()
|
||||
|
||||
#ifdef _WIN32
|
||||
// Cancel compressed log file autodeletion
|
||||
FILE_DISPOSITION_INFO disp;
|
||||
disp.DeleteFileW = FALSE;
|
||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||
m_fout2.set_delete(false);
|
||||
|
||||
UnmapViewOfFile(m_fptr);
|
||||
CloseHandle(m_fmap);
|
||||
@@ -593,16 +589,30 @@ logs::file_listener::file_listener(const std::string& name)
|
||||
// Write UTF-8 BOM
|
||||
file_writer::log(logs::level::always, "\xEF\xBB\xBF", 3);
|
||||
|
||||
const std::string firmware_version = utils::get_firmware_version();
|
||||
const std::string firmware_string = firmware_version.empty() ? "" : (" | Firmware version: " + firmware_version);
|
||||
|
||||
// Write initial message
|
||||
stored_message ver;
|
||||
ver.m.ch = nullptr;
|
||||
ver.m.sev = level::always;
|
||||
ver.stamp = 0;
|
||||
ver.text = fmt::format("RPCS3 v%s | %s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), utils::get_system_info());
|
||||
ver.text = fmt::format("RPCS3 v%s | %s%s\n%s", rpcs3::version.to_string(), rpcs3::get_branch(), firmware_string, utils::get_system_info());
|
||||
|
||||
file_writer::log(logs::level::always, ver.text.data(), ver.text.size());
|
||||
file_writer::log(logs::level::always, "\n", 1);
|
||||
messages.emplace_back(std::move(ver));
|
||||
|
||||
// Write OS version
|
||||
stored_message os;
|
||||
os.m.ch = nullptr;
|
||||
os.m.sev = level::notice;
|
||||
os.stamp = 0;
|
||||
os.text = utils::get_OS_version();
|
||||
|
||||
file_writer::log(logs::level::notice, os.text.data(), os.text.size());
|
||||
file_writer::log(logs::level::notice, "\n", 1);
|
||||
messages.emplace_back(std::move(os));
|
||||
}
|
||||
|
||||
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
|
||||
@@ -630,7 +640,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
const u64 frac = (stamp % 1'000'000);
|
||||
fmt::append(text, "%u:%02u:%02u.%06u ", hours, mins, secs, frac);
|
||||
|
||||
if (prefix.size() > 0)
|
||||
if (!prefix.empty())
|
||||
{
|
||||
text += "{";
|
||||
text += prefix;
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include "StrFmt.h"
|
||||
#include <climits>
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace logs
|
||||
void set_level(const std::string&, level);
|
||||
}
|
||||
|
||||
#define LOG_CHANNEL(ch, ...) ::logs::channel ch(#ch, ##__VA_ARGS__);
|
||||
#define LOG_CHANNEL(ch, ...) ::logs::channel ch(#ch, ##__VA_ARGS__)
|
||||
|
||||
// Legacy:
|
||||
|
||||
|
||||
@@ -177,13 +177,13 @@ void fmt_class_string<ullong>::format(std::string& out, u64 arg)
|
||||
template <>
|
||||
void fmt_class_string<float>::format(std::string& out, u64 arg)
|
||||
{
|
||||
fmt::append(out, "%gf", static_cast<float>(reinterpret_cast<f64&>(arg)));
|
||||
fmt::append(out, "%gf", static_cast<float>(std::bit_cast<f64>(arg)));
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<double>::format(std::string& out, u64 arg)
|
||||
{
|
||||
fmt::append(out, "%g", reinterpret_cast<f64&>(arg));
|
||||
fmt::append(out, "%g", std::bit_cast<f64>(arg));
|
||||
}
|
||||
|
||||
template <>
|
||||
|
||||
+1
-13
@@ -62,7 +62,7 @@ struct fmt_unveil<T, std::enable_if_t<std::is_floating_point<T>::value && sizeof
|
||||
// Convert FP to f64 and reinterpret as u64
|
||||
static inline u64 get(const f64& arg)
|
||||
{
|
||||
return *reinterpret_cast<const u64*>(reinterpret_cast<const u8*>(&arg));
|
||||
return std::bit_cast<u64>(arg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,18 +140,9 @@ struct fmt_class_string
|
||||
// Enum -> string function type
|
||||
using convert_t = const char*(*)(T value);
|
||||
|
||||
// Enum -> string function registered
|
||||
static convert_t convert_enum;
|
||||
|
||||
// Helper function (safely converts arg to enum value)
|
||||
static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, convert_t convert)
|
||||
{
|
||||
// Save convert function
|
||||
if (convert_enum == nullptr)
|
||||
{
|
||||
convert_enum = convert;
|
||||
}
|
||||
|
||||
const auto value = static_cast<std::underlying_type_t<T>>(arg);
|
||||
|
||||
// Check narrowing
|
||||
@@ -203,9 +194,6 @@ struct fmt_class_string
|
||||
static constexpr const char* unknown = nullptr;
|
||||
};
|
||||
|
||||
template <typename T, typename V>
|
||||
const char*(*fmt_class_string<T, V>::convert_enum)(T) = nullptr;
|
||||
|
||||
template <>
|
||||
struct fmt_class_string<const void*, void>
|
||||
{
|
||||
|
||||
+284
-73
@@ -1,7 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_mmapper.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
@@ -28,7 +30,9 @@
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#ifndef __OpenBSD__
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@@ -801,7 +805,7 @@ register_t* freebsd_x64reg(x64_context *context, int reg)
|
||||
|
||||
long* openbsd_x64reg(x64_context *context, int reg)
|
||||
{
|
||||
auto *state = &context->uc_mcontext;
|
||||
auto *state = &context;
|
||||
switch(reg)
|
||||
{
|
||||
case 0: return &state->sc_rax;
|
||||
@@ -1098,6 +1102,11 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
try
|
||||
{
|
||||
if (cpu)
|
||||
{
|
||||
vm::temporary_unlock(*cpu);
|
||||
}
|
||||
|
||||
handled = rsx::g_access_violation_handler(addr, is_writing);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
@@ -1106,7 +1115,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
if (cpu)
|
||||
{
|
||||
vm::temporary_unlock(*cpu);
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
|
||||
if (cpu->test_stopped())
|
||||
@@ -1128,6 +1136,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cpu && cpu->test_stopped())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
auto code = (const u8*)RIP(context);
|
||||
@@ -1148,7 +1160,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
}
|
||||
};
|
||||
|
||||
if ((d_size | d_size + addr) >= 0x100000000ull)
|
||||
if ((d_size | (d_size + addr)) >= 0x100000000ull)
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Invalid d_size (0x%llx)", d_size);
|
||||
report_opcode();
|
||||
@@ -1158,7 +1170,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
// get length of data being accessed
|
||||
size_t a_size = get_x64_access_size(context, op, reg, d_size, i_size);
|
||||
|
||||
if ((a_size | a_size + addr) >= 0x100000000ull)
|
||||
if ((a_size | (a_size + addr)) >= 0x100000000ull)
|
||||
{
|
||||
LOG_ERROR(MEMORY, "Invalid a_size (0x%llx)", a_size);
|
||||
report_opcode();
|
||||
@@ -1261,7 +1273,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size), vm::page_allocated | (is_writing ? vm::page_writable : vm::page_readable)))
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size), is_writing ? vm::page_writable : vm::page_readable))
|
||||
{
|
||||
if (cpu && cpu->test_stopped())
|
||||
{
|
||||
@@ -1273,64 +1285,175 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
|
||||
if (cpu)
|
||||
{
|
||||
// TODO: Only PPU thread page fault notifications are supported
|
||||
if (cpu->id_type() == 1 && fxm::check<page_fault_notification_entries>())
|
||||
u32 pf_port_id = 0;
|
||||
|
||||
if (auto pf_entries = g_fxo->get<page_fault_notification_entries>(); true)
|
||||
{
|
||||
for (const auto& entry : fxm::get<page_fault_notification_entries>()->entries)
|
||||
if (auto mem = vm::get(vm::any, addr))
|
||||
{
|
||||
auto mem = vm::get(vm::any, entry.start_addr);
|
||||
if (!mem)
|
||||
std::shared_lock lock(pf_entries->mutex);
|
||||
|
||||
for (const auto& entry : pf_entries->entries)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.start_addr <= addr && addr <= addr + mem->size - 1)
|
||||
{
|
||||
// Place the page fault event onto table so that other functions [sys_mmapper_free_address and ppu pagefault funcs]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto pf_entries = fxm::get_always<page_fault_event_entries>();
|
||||
if (entry.start_addr == mem->addr)
|
||||
{
|
||||
std::lock_guard pf_lock(pf_entries->pf_mutex);
|
||||
page_fault_event pf_event{ cpu->id, addr };
|
||||
pf_entries->events.emplace_back(pf_event);
|
||||
pf_port_id = entry.port_id;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now, we notify the game that a page fault occurred so it can rectify it.
|
||||
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
|
||||
u64 data1 = addr;
|
||||
u64 data2 = ((u64)SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) + cpu->id;
|
||||
u64 data3 = vm::check_addr(addr, a_size, vm::page_readable) ? SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY : SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;
|
||||
|
||||
LOG_ERROR(MEMORY, "Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
|
||||
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
|
||||
|
||||
error_code sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (sending_error == CELL_EBUSY)
|
||||
{
|
||||
lv2_obj::sleep(*cpu, 1000);
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(entry.port_id, data1, data2, data3);
|
||||
}
|
||||
|
||||
if (sending_error)
|
||||
{
|
||||
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
|
||||
}
|
||||
|
||||
lv2_obj::sleep(*cpu);
|
||||
thread_ctrl::wait();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm::temporary_unlock(*cpu);
|
||||
if (pf_port_id)
|
||||
{
|
||||
// We notify the game that a page fault occurred so it can rectify it.
|
||||
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
|
||||
u64 data1 = addr;
|
||||
u64 data2;
|
||||
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) | cpu->id;
|
||||
}
|
||||
else if (static_cast<spu_thread*>(cpu)->group)
|
||||
{
|
||||
data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_SPU_THREAD << 32) | cpu->id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Index is the correct ID in RawSPU
|
||||
data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_RAW_SPU << 32) | static_cast<spu_thread*>(cpu)->index;
|
||||
}
|
||||
|
||||
u64 data3;
|
||||
{
|
||||
vm::reader_lock rlock;
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size), is_writing ? vm::page_writable : vm::page_readable))
|
||||
{
|
||||
// Memory was allocated inbetween, retry
|
||||
return true;
|
||||
}
|
||||
else if (vm::check_addr(addr, std::max<std::size_t>(1, d_size)))
|
||||
{
|
||||
data3 = SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY; // TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
data3 = SYS_MEMORY_PAGE_FAULT_CAUSE_NON_MAPPED;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, place the page fault event onto table so that other functions [sys_mmapper_free_address and pagefault recovery funcs etc]
|
||||
// know that this thread is page faulted and where.
|
||||
|
||||
auto pf_events = g_fxo->get<page_fault_event_entries>();
|
||||
{
|
||||
std::lock_guard pf_lock(pf_events->pf_mutex);
|
||||
pf_events->events.emplace(static_cast<u32>(data2), addr);
|
||||
}
|
||||
|
||||
LOG_ERROR(MEMORY, "Page_fault %s location 0x%x because of %s memory", is_writing ? "writing" : "reading",
|
||||
addr, data3 == SYS_MEMORY_PAGE_FAULT_CAUSE_READ_ONLY ? "writing read-only" : "using unmapped");
|
||||
|
||||
error_code sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
|
||||
|
||||
// If we fail due to being busy, wait a bit and try again.
|
||||
while (sending_error == CELL_EBUSY)
|
||||
{
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
lv2_obj::sleep(*cpu, 1000);
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(1000);
|
||||
sending_error = sys_event_port_send(pf_port_id, data1, data2, data3);
|
||||
}
|
||||
|
||||
if (sending_error)
|
||||
{
|
||||
fmt::throw_exception("Unknown error %x while trying to pass page fault.", sending_error.value);
|
||||
}
|
||||
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
// Deschedule
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
|
||||
// Wait until the thread is recovered
|
||||
for (std::shared_lock pf_lock(pf_events->pf_mutex);
|
||||
pf_events->events.find(static_cast<u32>(data2)) != pf_events->events.end();)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Timeout in case the emulator is stopping
|
||||
pf_events->cond.wait(pf_lock, 10000);
|
||||
}
|
||||
|
||||
// Reschedule
|
||||
if (cpu->test_stopped())
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
// Hack: allocate memory in case the emulator is stopping
|
||||
vm::falloc(addr & -0x10000, 0x10000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cpu->id_type() != 1)
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
|
||||
// TODO:
|
||||
// RawSPU: Send appropriate interrupt
|
||||
// SPUThread: Send sys_spu exception event
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
if (cpu->check_state())
|
||||
{
|
||||
// Hack: allocate memory in case the emulator is stopping
|
||||
auto area = vm::reserve_map(vm::any, addr & -0x10000, 0x10000);
|
||||
|
||||
if (area->flags & 0x100)
|
||||
{
|
||||
// For 4kb pages
|
||||
utils::memory_protect(vm::base(addr & -0x1000), 0x1000, utils::protection::rw);
|
||||
}
|
||||
else
|
||||
{
|
||||
area->falloc(addr & -0x10000, 0x10000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto last_func = static_cast<ppu_thread*>(cpu)->current_function)
|
||||
{
|
||||
LOG_FATAL(PPU, "Function aborted: %s", last_func);
|
||||
}
|
||||
|
||||
lv2_obj::sleep(*cpu);
|
||||
}
|
||||
}
|
||||
|
||||
Emu.Pause();
|
||||
|
||||
if (cpu)
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "\n%s", cpu->dump());
|
||||
}
|
||||
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
Emu.Pause();
|
||||
|
||||
while (Emu.IsPaused())
|
||||
{
|
||||
@@ -1406,7 +1529,7 @@ static bool is_leaf_function(u64 rip)
|
||||
static LONG exception_handler(PEXCEPTION_POINTERS pExp)
|
||||
{
|
||||
const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::g_base_addr;
|
||||
const u64 exec64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::g_exec_addr;
|
||||
const u64 exec64 = (pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::g_exec_addr) / 2;
|
||||
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
|
||||
|
||||
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000ull)
|
||||
@@ -1541,7 +1664,7 @@ static void signal_handler(int sig, siginfo_t* info, void* uct)
|
||||
#endif
|
||||
|
||||
const u64 addr64 = (u64)info->si_addr - (u64)vm::g_base_addr;
|
||||
const u64 exec64 = (u64)info->si_addr - (u64)vm::g_exec_addr;
|
||||
const u64 exec64 = ((u64)info->si_addr - (u64)vm::g_exec_addr) / 2;
|
||||
const auto cause = is_writing ? "writing" : "reading";
|
||||
|
||||
if (addr64 < 0x100000000ull)
|
||||
@@ -1584,7 +1707,7 @@ const bool s_exception_handler_set = []() -> bool
|
||||
#endif
|
||||
|
||||
// TODO
|
||||
extern atomic_t<u32> g_thread_count(0);
|
||||
atomic_t<u32> g_thread_count(0);
|
||||
|
||||
thread_local DECLARE(thread_ctrl::g_tls_this_thread) = nullptr;
|
||||
|
||||
@@ -1879,13 +2002,13 @@ void thread_ctrl::detect_cpu_layout()
|
||||
}
|
||||
}
|
||||
|
||||
u16 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
{
|
||||
detect_cpu_layout();
|
||||
|
||||
if (const auto thread_count = std::thread::hardware_concurrency())
|
||||
{
|
||||
const u16 all_cores_mask = thread_count < 16 ? (u16)(~(UINT16_MAX << thread_count)): UINT16_MAX;
|
||||
const u64 all_cores_mask = thread_count < 64 ? UINT64_MAX >> (64 - thread_count): UINT64_MAX;
|
||||
|
||||
switch (g_native_core_layout)
|
||||
{
|
||||
@@ -1896,20 +2019,100 @@ u16 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
}
|
||||
case native_core_arrangement::amd_ccx:
|
||||
{
|
||||
u16 spu_mask, ppu_mask, rsx_mask;
|
||||
if (thread_count >= 16)
|
||||
u64 spu_mask, ppu_mask, rsx_mask;
|
||||
const auto system_id = utils::get_system_info();
|
||||
if (thread_count >= 32)
|
||||
{
|
||||
// Threadripper, R7
|
||||
// Assign threads 8-16
|
||||
// It appears some windows code is bound to lower core addresses, binding 8-16 is alot faster than 0-7
|
||||
ppu_mask = spu_mask = 0b1111111100000000;
|
||||
rsx_mask = all_cores_mask;
|
||||
if (system_id.find("3950X") != std::string::npos)
|
||||
{
|
||||
// zen2
|
||||
// Ryzen 9 3950X
|
||||
// Assign threads 9-32
|
||||
ppu_mask = 0b11111111000000000000000000000000;
|
||||
spu_mask = 0b00000000111111110000000000000000;
|
||||
rsx_mask = 0b00000000000000001111111100000000;
|
||||
}
|
||||
else if (system_id.find("2970WX") != std::string::npos)
|
||||
{
|
||||
// zen+
|
||||
// Threadripper 2970WX
|
||||
// Assign threads 9-24
|
||||
ppu_mask = 0b000000111111000000000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b111111000000000000000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// zen(+)
|
||||
// Threadripper 1950X/2950X/2990WX
|
||||
// Assign threads 17-32
|
||||
ppu_mask = 0b00000000111111110000000000000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b11111111000000000000000000000000;
|
||||
}
|
||||
|
||||
}
|
||||
else if (thread_count == 24)
|
||||
{
|
||||
if (system_id.find("3900X") != std::string::npos)
|
||||
{
|
||||
// zen2
|
||||
// Ryzen 9 3900X
|
||||
// Assign threads 7-22
|
||||
ppu_mask = 0b111111000000000000000000;
|
||||
spu_mask = 0b000000111111000000000000;
|
||||
rsx_mask = 0b000000000000111111000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// zen(+)
|
||||
// Threadripper 1920X/2920X
|
||||
// Assign threads 13-24
|
||||
ppu_mask = 0b000000111111000000000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b111111000000000000000000;
|
||||
}
|
||||
}
|
||||
else if (thread_count == 16)
|
||||
{
|
||||
if (system_id.find("3700X") != std::string::npos || system_id.find("3800X") != std::string::npos)
|
||||
{
|
||||
// Ryzen 7 3700/3800 (x)
|
||||
// Assign threads 1-16
|
||||
ppu_mask = 0b0000000011110000;
|
||||
spu_mask = 0b1111111100000000;
|
||||
rsx_mask = 0b0000000000001111;
|
||||
}
|
||||
else
|
||||
{
|
||||
// zen(+)
|
||||
// Ryzen 7, Threadripper
|
||||
// Assign threads 3-16
|
||||
ppu_mask = 0b1111111100000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b0000000000111100;
|
||||
}
|
||||
}
|
||||
else if (thread_count == 12)
|
||||
{
|
||||
// 1600/2600 (x)
|
||||
ppu_mask = spu_mask = 0b111111000000;
|
||||
rsx_mask = all_cores_mask;
|
||||
if (system_id.find("3600") != std::string::npos)
|
||||
{
|
||||
// zen2
|
||||
// R5 3600 (x)
|
||||
// Assign threads 1-12
|
||||
ppu_mask = 0b000000111000;
|
||||
spu_mask = 0b111111000000;
|
||||
rsx_mask = 0b000000000111;
|
||||
}
|
||||
else
|
||||
{
|
||||
// zen(+)
|
||||
// R5 1600/2600 (x)
|
||||
// Assign threads 3-12
|
||||
ppu_mask = 0b111111000000;
|
||||
spu_mask = ppu_mask;
|
||||
rsx_mask = 0b000000111100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1954,7 +2157,7 @@ u16 thread_ctrl::get_affinity_mask(thread_class group)
|
||||
}
|
||||
}
|
||||
|
||||
return UINT16_MAX;
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
void thread_ctrl::set_native_priority(int priority)
|
||||
@@ -1990,25 +2193,33 @@ void thread_ctrl::set_native_priority(int priority)
|
||||
#endif
|
||||
}
|
||||
|
||||
void thread_ctrl::set_thread_affinity_mask(u16 mask)
|
||||
void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
SetThreadAffinityMask(_this_thread, (DWORD_PTR)mask);
|
||||
SetThreadAffinityMask(_this_thread, mask);
|
||||
#elif __APPLE__
|
||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(mask) };
|
||||
// Supports only one core
|
||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(utils::cnttz64(mask)) };
|
||||
thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
|
||||
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1);
|
||||
#elif defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
cpu_set_t cs;
|
||||
CPU_ZERO(&cs);
|
||||
|
||||
for (u32 core = 0; core < 16u; ++core)
|
||||
for (u32 core = 0; core < 64u; ++core)
|
||||
{
|
||||
if ((u32)mask & (1u << core))
|
||||
const u64 shifted = mask >> core;
|
||||
|
||||
if (shifted & 1)
|
||||
{
|
||||
CPU_SET(core, &cs);
|
||||
}
|
||||
|
||||
if (shifted <= 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@@ -258,13 +258,13 @@ public:
|
||||
static void detect_cpu_layout();
|
||||
|
||||
// Returns a core affinity mask. Set whether to generate the high priority set or not
|
||||
static u16 get_affinity_mask(thread_class group);
|
||||
static u64 get_affinity_mask(thread_class group);
|
||||
|
||||
// Sets the native thread priority
|
||||
static void set_native_priority(int priority);
|
||||
|
||||
// Sets the preferred affinity mask for this thread
|
||||
static void set_thread_affinity_mask(u16 mask);
|
||||
static void set_thread_affinity_mask(u64 mask);
|
||||
|
||||
// Spawn a detached named thread
|
||||
template <typename F>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class Timer
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
// Memory protection type
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "types.h"
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "StrFmt.h"
|
||||
#include <vector>
|
||||
|
||||
@@ -58,12 +60,12 @@ namespace utils
|
||||
return (start1 >= start2 && end1 <= end2);
|
||||
}
|
||||
|
||||
address_range(u32 _start, u32 _end) : start(_start), end(_end) {};
|
||||
address_range(u32 _start, u32 _end) : start(_start), end(_end) {}
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
address_range() = default;
|
||||
address_range(const address_range &other) : start(other.start), end(other.end) {};
|
||||
address_range(const address_range &other) : start(other.start), end(other.end) {}
|
||||
|
||||
static inline address_range start_length(u32 _start, u32 _length)
|
||||
{
|
||||
@@ -376,7 +378,7 @@ namespace utils
|
||||
|
||||
// We use index access because we might have to push_back within the loop, which could invalidate the iterators
|
||||
size_type _size = data.size();
|
||||
for (int n = 0; n < _size; ++n)
|
||||
for (size_type n = 0; n < _size; ++n)
|
||||
{
|
||||
address_range &existing = data[n];
|
||||
|
||||
@@ -453,7 +455,7 @@ namespace utils
|
||||
{
|
||||
size_t _size = data.size();
|
||||
|
||||
for (int i = 0; i < _size; ++i)
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
{
|
||||
const auto &r1 = data[i];
|
||||
if (!r1.valid())
|
||||
@@ -461,7 +463,7 @@ namespace utils
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < _size; ++j)
|
||||
for (size_t j = i + 1; j < _size; ++j)
|
||||
{
|
||||
const auto &r2 = data[j];
|
||||
if (!r2.valid())
|
||||
@@ -572,7 +574,7 @@ namespace utils
|
||||
return vec.overlaps(*this);
|
||||
}
|
||||
|
||||
}; // namespace utils
|
||||
} // namespace utils
|
||||
|
||||
|
||||
namespace std {
|
||||
@@ -587,4 +589,4 @@ namespace std {
|
||||
return (size_t{ k.start } << 32) | size_t{ k.end };
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+60
-17
@@ -9,6 +9,8 @@ namespace utils
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanReverse(&res, arg) || nonzero ? res ^ 31 : 32;
|
||||
#elif __LZCNT__
|
||||
return _lzcnt_u32(arg);
|
||||
#else
|
||||
return arg || nonzero ? __builtin_clz(arg) : 32;
|
||||
#endif
|
||||
@@ -19,6 +21,8 @@ namespace utils
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanReverse64(&res, arg) || nonzero ? res ^ 63 : 64;
|
||||
#elif __LZCNT__
|
||||
return _lzcnt_u64(arg);
|
||||
#else
|
||||
return arg || nonzero ? __builtin_clzll(arg) : 64;
|
||||
#endif
|
||||
@@ -29,6 +33,8 @@ namespace utils
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward(&res, arg) || nonzero ? res : 32;
|
||||
#elif __BMI__
|
||||
return _tzcnt_u32(arg);
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctz(arg) : 32;
|
||||
#endif
|
||||
@@ -39,23 +45,28 @@ namespace utils
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
|
||||
#elif __BMI__
|
||||
return _tzcnt_u64(arg);
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctzll(arg) : 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u8 popcnt16(u16 arg)
|
||||
inline u8 popcnt32(u32 arg)
|
||||
{
|
||||
const u32 a1 = arg & 0x5555;
|
||||
const u32 a2 = (arg >> 1) & 0x5555;
|
||||
#ifdef _MSC_VER
|
||||
const u32 a1 = arg & 0x55555555;
|
||||
const u32 a2 = (arg >> 1) & 0x55555555;
|
||||
const u32 a3 = a1 + a2;
|
||||
const u32 b1 = a3 & 0x3333;
|
||||
const u32 b2 = (a3 >> 2) & 0x3333;
|
||||
const u32 b1 = a3 & 0x33333333;
|
||||
const u32 b2 = (a3 >> 2) & 0x33333333;
|
||||
const u32 b3 = b1 + b2;
|
||||
const u32 c1 = b3 & 0x0f0f;
|
||||
const u32 c2 = (b3 >> 4) & 0x0f0f;
|
||||
const u32 c3 = c1 + c2;
|
||||
return static_cast<u8>(c3 + (c3 >> 8));
|
||||
const u32 c3 = (b3 + (b3 >> 4)) & 0x0f0f0f0f;
|
||||
const u32 d3 = c3 + (c3 >> 8);
|
||||
return static_cast<u8>(d3 + (d3 >> 16));
|
||||
#else
|
||||
return __builtin_popcount(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Rotate helpers
|
||||
@@ -63,72 +74,104 @@ namespace utils
|
||||
|
||||
inline u8 rol8(u8 x, u8 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateleft8)
|
||||
return __builtin_rotateleft8(x, n);
|
||||
#else
|
||||
u8 result = x;
|
||||
__asm__("rolb %[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u8 ror8(u8 x, u8 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateright8)
|
||||
return __builtin_rotateright8(x, n);
|
||||
#else
|
||||
u8 result = x;
|
||||
__asm__("rorb %[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u16 rol16(u16 x, u16 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateleft16)
|
||||
return __builtin_rotateleft16(x, n);
|
||||
#else
|
||||
u16 result = x;
|
||||
__asm__("rolw %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u16 ror16(u16 x, u16 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateright16)
|
||||
return __builtin_rotateright16(x, n);
|
||||
#else
|
||||
u16 result = x;
|
||||
__asm__("rorw %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u32 rol32(u32 x, u32 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateleft32)
|
||||
return __builtin_rotateleft32(x, n);
|
||||
#else
|
||||
u32 result = x;
|
||||
__asm__("roll %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u32 ror32(u32 x, u32 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateright32)
|
||||
return __builtin_rotateright32(x, n);
|
||||
#else
|
||||
u32 result = x;
|
||||
__asm__("rorl %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u64 rol64(u64 x, u64 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateleft64)
|
||||
return __builtin_rotateleft64(x, n);
|
||||
#else
|
||||
u64 result = x;
|
||||
__asm__("rolq %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u64 ror64(u64 x, u64 n)
|
||||
{
|
||||
#if __has_builtin(__builtin_rotateright64)
|
||||
return __builtin_rotateright64(x, n);
|
||||
#else
|
||||
u64 result = x;
|
||||
__asm__("rorq %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n));
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u64 umulh64(u64 a, u64 b)
|
||||
constexpr u64 umulh64(u64 a, u64 b)
|
||||
{
|
||||
u64 result;
|
||||
__asm__("mulq %[b]" : "=d"(result) : [a] "a"(a), [b] "rm"(b));
|
||||
return result;
|
||||
const __uint128_t x = a;
|
||||
const __uint128_t y = b;
|
||||
return (x * y) >> 64;
|
||||
}
|
||||
|
||||
inline s64 mulh64(s64 a, s64 b)
|
||||
constexpr s64 mulh64(s64 a, s64 b)
|
||||
{
|
||||
s64 result;
|
||||
__asm__("imulq %[b]" : "=d"(result) : [a] "a"(a), [b] "rm"(b));
|
||||
return result;
|
||||
const __int128_t x = a;
|
||||
const __int128_t y = b;
|
||||
return (x * y) >> 64;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
@@ -86,13 +86,13 @@ void patch_engine::append(const std::string& patch)
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
info.value_as<f32>() = patch[2].as<f32>();
|
||||
info.value = std::bit_cast<u32>(patch[2].as<f32>());
|
||||
break;
|
||||
}
|
||||
case patch_type::bef64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
info.value_as<f64>() = patch[2].as<f64>();
|
||||
info.value = std::bit_cast<u64>(patch[2].as<f64>());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -28,12 +28,6 @@ class patch_engine
|
||||
patch_type type;
|
||||
u32 offset;
|
||||
u64 value;
|
||||
|
||||
template <typename T>
|
||||
T& value_as()
|
||||
{
|
||||
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
|
||||
}
|
||||
};
|
||||
|
||||
// Database
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ Intersection (&) and symmetric difference (^) is also available.
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
template <typename T>
|
||||
class atomic_bs_t;
|
||||
|
||||
+17
-12
@@ -7,6 +7,8 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
static const size_t size_dropped = std::numeric_limits<size_t>::max();
|
||||
|
||||
/*
|
||||
C-style format parser. Appends formatted string to `out`, returns number of characters written.
|
||||
`out`: mutable reference to std::string, std::vector<char> or other compatible container
|
||||
@@ -41,7 +43,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
const auto drop_sequence = [&]
|
||||
{
|
||||
out.insert(out.end(), fmt - ctx.size, fmt);
|
||||
ctx.size = -1;
|
||||
ctx.size = size_dropped;
|
||||
};
|
||||
|
||||
const auto read_decimal = [&](uint result) -> uint
|
||||
@@ -112,7 +114,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
ctx = {0};
|
||||
out.push_back(ch);
|
||||
}
|
||||
else if (ctx.size == -1)
|
||||
else if (ctx.size == size_dropped)
|
||||
{
|
||||
out.push_back(ch);
|
||||
}
|
||||
@@ -410,9 +412,10 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
}
|
||||
|
||||
const u64 mask =
|
||||
ctx.type == 1 ? 0xffull :
|
||||
ctx.type == 2 ? 0xffffull :
|
||||
ctx.type == 4 ? 0xffffffffull : 0xffffffffffffffffull;
|
||||
ctx.type == 1 ? 0xff :
|
||||
ctx.type == 2 ? 0xffff :
|
||||
ctx.type == 4 ? 0xffff'ffffu :
|
||||
0xffff'ffff'ffff'ffffu;
|
||||
|
||||
// Trunc sign-extended signed types
|
||||
const u64 val = src.template get<u64>(ctx.args) & mask;
|
||||
@@ -466,9 +469,10 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
}
|
||||
|
||||
const u64 mask =
|
||||
ctx.type == 1 ? 0xffull :
|
||||
ctx.type == 2 ? 0xffffull :
|
||||
ctx.type == 4 ? 0xffffffffull : 0xffffffffffffffffull;
|
||||
ctx.type == 1 ? 0xff :
|
||||
ctx.type == 2 ? 0xffff :
|
||||
ctx.type == 4 ? 0xffff'ffffu :
|
||||
0xffff'ffff'ffff'ffffu;
|
||||
|
||||
// Trunc sign-extended signed types
|
||||
const u64 val = src.template get<u64>(ctx.args) & mask;
|
||||
@@ -529,9 +533,10 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
}
|
||||
|
||||
const u64 mask =
|
||||
ctx.type == 1 ? 0xffull :
|
||||
ctx.type == 2 ? 0xffffull :
|
||||
ctx.type == 4 ? 0xffffffffull : 0xffffffffffffffffull;
|
||||
ctx.type == 1 ? 0xff :
|
||||
ctx.type == 2 ? 0xffff :
|
||||
ctx.type == 4 ? 0xffff'ffffu :
|
||||
0xffff'ffff'ffff'ffffu;
|
||||
|
||||
// Trunc sign-extended signed types
|
||||
const u64 val = src.template get<u64>(ctx.args) & mask;
|
||||
@@ -626,7 +631,7 @@ std::size_t cfmt_append(Dst& out, const Char* fmt, Src&& src)
|
||||
}
|
||||
|
||||
// Handle unfinished sequence
|
||||
if (ctx.size && ctx.size != -1)
|
||||
if (ctx.size && ctx.size != size_dropped)
|
||||
{
|
||||
fmt--, drop_sequence();
|
||||
}
|
||||
|
||||
+208
-26
@@ -148,7 +148,7 @@ bool notifier::wait(u64 usec_timeout)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool cond_one::imp_wait(u64 _timeout) noexcept
|
||||
bool unique_cond::imp_wait(u64 _timeout) noexcept
|
||||
{
|
||||
// State transition: c_sig -> c_lock \ c_lock -> c_wait
|
||||
const u32 _old = m_value.fetch_sub(1);
|
||||
@@ -173,7 +173,7 @@ bool cond_one::imp_wait(u64 _timeout) noexcept
|
||||
});
|
||||
}
|
||||
|
||||
void cond_one::imp_notify() noexcept
|
||||
void unique_cond::imp_notify() noexcept
|
||||
{
|
||||
auto [old, ok] = m_value.fetch_op([](u32& v)
|
||||
{
|
||||
@@ -196,46 +196,51 @@ void cond_one::imp_notify() noexcept
|
||||
balanced_awaken(m_value, 1);
|
||||
}
|
||||
|
||||
bool cond_x16::imp_wait(u32 slot, u64 _timeout) noexcept
|
||||
bool shared_cond::imp_wait(u32 slot, u64 _timeout) noexcept
|
||||
{
|
||||
const u32 wait_bit = c_wait << slot;
|
||||
const u32 lock_bit = c_lock << slot;
|
||||
if (slot >= 32)
|
||||
{
|
||||
// Invalid argument, assume notified
|
||||
return true;
|
||||
}
|
||||
|
||||
const u64 wait_bit = c_wait << slot;
|
||||
const u64 lock_bit = c_lock << slot;
|
||||
|
||||
// Change state from c_lock to c_wait
|
||||
const u32 old_ = m_cvx16.fetch_op([=](u32& cvx16)
|
||||
const u64 old_ = m_cvx32.fetch_op([=](u64& cvx32)
|
||||
{
|
||||
if (cvx16 & wait_bit)
|
||||
if (cvx32 & wait_bit)
|
||||
{
|
||||
// c_sig -> c_lock
|
||||
cvx16 &= ~wait_bit;
|
||||
// c_lock -> c_wait
|
||||
cvx32 &= ~(lock_bit & ~wait_bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvx16 |= wait_bit;
|
||||
cvx16 &= ~lock_bit;
|
||||
// c_sig -> c_lock
|
||||
cvx32 |= lock_bit;
|
||||
}
|
||||
});
|
||||
|
||||
if (old_ & wait_bit)
|
||||
if ((old_ & wait_bit) == 0)
|
||||
{
|
||||
// Already signaled, return without waiting
|
||||
return true;
|
||||
}
|
||||
|
||||
return balanced_wait_until(m_cvx16, _timeout, [&](u32& cvx16, auto... ret) -> int
|
||||
return balanced_wait_until(m_cvx32, _timeout, [&](u64& cvx32, auto... ret) -> int
|
||||
{
|
||||
if (cvx16 & lock_bit)
|
||||
if ((cvx32 & wait_bit) == 0)
|
||||
{
|
||||
// c_sig -> c_lock
|
||||
cvx16 &= ~wait_bit;
|
||||
cvx32 |= lock_bit;
|
||||
return +1;
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(ret))
|
||||
{
|
||||
// Retire
|
||||
cvx16 |= lock_bit;
|
||||
cvx16 &= ~wait_bit;
|
||||
cvx32 |= lock_bit;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -243,16 +248,14 @@ bool cond_x16::imp_wait(u32 slot, u64 _timeout) noexcept
|
||||
});
|
||||
}
|
||||
|
||||
void cond_x16::imp_notify() noexcept
|
||||
void shared_cond::imp_notify() noexcept
|
||||
{
|
||||
auto [old, ok] = m_cvx16.fetch_op([](u32& v)
|
||||
auto [old, ok] = m_cvx32.fetch_op([](u64& cvx32)
|
||||
{
|
||||
const u32 lock_mask = v >> 16;
|
||||
const u32 wait_mask = v & 0xffff;
|
||||
|
||||
if (const u32 sig_mask = lock_mask ^ wait_mask)
|
||||
if (const u64 sig_mask = cvx32 & 0xffffffff)
|
||||
{
|
||||
v |= sig_mask | sig_mask << 16;
|
||||
cvx32 &= 0xffffffffull << 32;
|
||||
cvx32 |= sig_mask << 32;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -260,18 +263,197 @@ void cond_x16::imp_notify() noexcept
|
||||
});
|
||||
|
||||
// Determine if some waiters need a syscall notification
|
||||
const u32 wait_mask = old & (~old >> 16);
|
||||
const u64 wait_mask = old & (~old >> 32);
|
||||
|
||||
if (UNLIKELY(!ok || !wait_mask))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
balanced_awaken<true>(m_cvx16, utils::popcnt16(wait_mask));
|
||||
balanced_awaken<true>(m_cvx32, utils::popcnt32(wait_mask));
|
||||
}
|
||||
|
||||
void shared_cond::wait_all() noexcept
|
||||
{
|
||||
// Try to acquire waiting state without locking but only if there are other locks
|
||||
const auto [old_, result] = m_cvx32.fetch_op([](u64& cvx32) -> u64
|
||||
{
|
||||
// Check waiting alone
|
||||
if ((cvx32 & 0xffffffff) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Combine used bits and invert to find least significant bit unused
|
||||
const u32 slot = utils::cnttz64(~((cvx32 & 0xffffffff) | (cvx32 >> 32)), true);
|
||||
|
||||
// Set waiting bit (does nothing if all slots are used)
|
||||
cvx32 |= (1ull << slot) & 0xffffffff;
|
||||
return 1ull << slot;
|
||||
});
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (result > 0xffffffffu)
|
||||
{
|
||||
// All slots are used, fallback to spin wait
|
||||
while (m_cvx32 & 0xffffffff)
|
||||
{
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const u64 wait_bit = result;
|
||||
const u64 lock_bit = wait_bit | (wait_bit << 32);
|
||||
|
||||
balanced_wait_until(m_cvx32, -1, [&](u64& cvx32, auto... ret) -> int
|
||||
{
|
||||
if ((cvx32 & wait_bit) == 0)
|
||||
{
|
||||
// Remove signal and unlock at once
|
||||
cvx32 &= ~lock_bit;
|
||||
return +1;
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(ret))
|
||||
{
|
||||
cvx32 &= ~lock_bit;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
bool shared_cond::wait_all(shared_cond::shared_lock& lock) noexcept
|
||||
{
|
||||
AUDIT(lock.m_this == this);
|
||||
|
||||
if (lock.m_slot >= 32)
|
||||
{
|
||||
// Invalid argument, assume notified
|
||||
return true;
|
||||
}
|
||||
|
||||
const u64 wait_bit = c_wait << lock.m_slot;
|
||||
const u64 lock_bit = c_lock << lock.m_slot;
|
||||
|
||||
// Try to acquire waiting state only if there are other locks
|
||||
const auto [old_, not_alone] = m_cvx32.fetch_op([&](u64& cvx32)
|
||||
{
|
||||
// Check locking alone
|
||||
if (((cvx32 >> 32) & cvx32) == (lock_bit >> 32))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// c_lock -> c_wait, c_sig -> unlock
|
||||
cvx32 &= ~(lock_bit & ~wait_bit);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!not_alone)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set invalid slot to acknowledge unlocking
|
||||
lock.m_slot = 33;
|
||||
}
|
||||
|
||||
if ((old_ & wait_bit) == 0)
|
||||
{
|
||||
// Already signaled, return without waiting
|
||||
return true;
|
||||
}
|
||||
|
||||
balanced_wait_until(m_cvx32, -1, [&](u64& cvx32, auto... ret) -> int
|
||||
{
|
||||
if ((cvx32 & wait_bit) == 0)
|
||||
{
|
||||
// Remove signal and unlock at once
|
||||
cvx32 &= ~lock_bit;
|
||||
return +1;
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(ret))
|
||||
{
|
||||
cvx32 &= ~lock_bit;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool shared_cond::notify_all(shared_cond::shared_lock& lock) noexcept
|
||||
{
|
||||
AUDIT(lock.m_this == this);
|
||||
|
||||
if (lock.m_slot >= 32)
|
||||
{
|
||||
// Invalid argument
|
||||
return false;
|
||||
}
|
||||
|
||||
const u64 slot_mask = c_sig << lock.m_slot;
|
||||
|
||||
auto [old, ok] = m_cvx32.fetch_op([&](u64& cvx32)
|
||||
{
|
||||
if (((cvx32 << 32) & cvx32) != slot_mask)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const u64 sig_mask = cvx32 & 0xffffffff)
|
||||
{
|
||||
cvx32 &= (0xffffffffull << 32) & ~slot_mask;
|
||||
cvx32 |= (sig_mask << 32) & ~slot_mask;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
// Not an exclusive reader
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set invalid slot to acknowledge unlocking
|
||||
lock.m_slot = 34;
|
||||
|
||||
// Determine if some waiters need a syscall notification
|
||||
const u64 wait_mask = old & (~old >> 32);
|
||||
|
||||
if (UNLIKELY(!wait_mask))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
balanced_awaken<true>(m_cvx32, utils::popcnt32(wait_mask));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lf_queue_base::wait(u64 _timeout)
|
||||
{
|
||||
auto _old = m_head.compare_and_swap(0, 1);
|
||||
|
||||
if (_old)
|
||||
{
|
||||
verify("lf_queue concurrent wait" HERE), _old != 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return balanced_wait_until(m_head, _timeout, [](std::uintptr_t& head, auto... ret) -> int
|
||||
{
|
||||
if (head != 1)
|
||||
|
||||
+60
-41
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include <shared_mutex>
|
||||
#include "asm.h"
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000;
|
||||
};
|
||||
|
||||
// Pair of a fake shared mutex (only limited shared locking) and a condition variable
|
||||
// Pair of a fake shared mutex (only limited shared locking) and a condition variable. Obsolete.
|
||||
class notifier
|
||||
{
|
||||
atomic_t<u32> m_counter{0};
|
||||
@@ -129,7 +129,8 @@ public:
|
||||
static constexpr u32 max_readers = 0x7f;
|
||||
};
|
||||
|
||||
class cond_one
|
||||
// Condition variable fused with a pseudo-mutex which is never supposed to be locked concurrently.
|
||||
class unique_cond
|
||||
{
|
||||
enum : u32
|
||||
{
|
||||
@@ -144,7 +145,7 @@ class cond_one
|
||||
void imp_notify() noexcept;
|
||||
|
||||
public:
|
||||
constexpr cond_one() = default;
|
||||
constexpr unique_cond() = default;
|
||||
|
||||
void lock() noexcept
|
||||
{
|
||||
@@ -158,7 +159,7 @@ public:
|
||||
m_value = 0;
|
||||
}
|
||||
|
||||
bool wait(std::unique_lock<cond_one>& lock, u64 usec_timeout = -1) noexcept
|
||||
bool wait(std::unique_lock<unique_cond>& lock, u64 usec_timeout = -1) noexcept
|
||||
{
|
||||
AUDIT(lock.owns_lock());
|
||||
AUDIT(lock.mutex() == this);
|
||||
@@ -175,61 +176,67 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Packed version of cond_one, supports up to 16 readers.
|
||||
class cond_x16
|
||||
// Condition variable fused with a pseudo-mutex supporting only reader locks (up to 32 readers).
|
||||
class shared_cond
|
||||
{
|
||||
// For information, shouldn't modify
|
||||
enum : u32
|
||||
enum : u64
|
||||
{
|
||||
// Wait bit is aligned for compatibility with 32-bit futex.
|
||||
c_wait = 1,
|
||||
c_lock = 1 << 16,
|
||||
c_sig = 1 << 16 | 1,
|
||||
c_sig = 1ull << 32,
|
||||
c_lock = 1ull << 32 | 1,
|
||||
};
|
||||
|
||||
// Split in 16-bit parts for convenient bit combining
|
||||
atomic_t<u32> m_cvx16{0};
|
||||
// Split in 32-bit parts for convenient bit combining
|
||||
atomic_t<u64> m_cvx32{0};
|
||||
|
||||
// Effectively unused, only counts readers
|
||||
atomic_t<u32> m_total{0};
|
||||
|
||||
class lock_x16
|
||||
class shared_lock
|
||||
{
|
||||
cond_x16* m_this;
|
||||
shared_cond* m_this;
|
||||
u32 m_slot;
|
||||
|
||||
friend class cond_x16;
|
||||
friend class shared_cond;
|
||||
|
||||
public:
|
||||
lock_x16(cond_x16* _this) noexcept
|
||||
shared_lock(shared_cond* _this) noexcept
|
||||
: m_this(_this)
|
||||
{
|
||||
// Spin if the number of readers exceeds 16
|
||||
while (UNLIKELY(m_this->m_total++ >= 16))
|
||||
m_this->m_total--;
|
||||
|
||||
// Lock and remember obtained slot index
|
||||
m_slot = m_this->m_cvx16.atomic_op([](u32& cvx16)
|
||||
m_slot = m_this->m_cvx32.atomic_op([](u64& cvx32)
|
||||
{
|
||||
// Combine used bits and invert to find least significant bit unused
|
||||
const u32 slot = utils::cnttz32(~((cvx16 & 0xffff) | (cvx16 >> 16)), true);
|
||||
const u32 slot = static_cast<u32>(utils::cnttz64(~((cvx32 & 0xffffffff) | (cvx32 >> 32)), true));
|
||||
|
||||
// Set lock bit
|
||||
cvx16 |= c_lock << slot;
|
||||
|
||||
AUDIT(slot < 16);
|
||||
// Set lock bits (does nothing if all slots are used)
|
||||
const u64 bit = (1ull << slot) & 0xffffffff;
|
||||
cvx32 |= bit | (bit << 32);
|
||||
return slot;
|
||||
});
|
||||
}
|
||||
|
||||
lock_x16(const lock_x16&) = delete;
|
||||
shared_lock(const shared_lock&) = delete;
|
||||
|
||||
lock_x16& operator=(const lock_x16&) = delete;
|
||||
|
||||
~lock_x16()
|
||||
shared_lock(shared_lock&& rhs)
|
||||
: m_this(rhs.m_this)
|
||||
, m_slot(rhs.m_slot)
|
||||
{
|
||||
// Clear the slot
|
||||
m_this->m_cvx16 &= ~((c_wait | c_lock) << m_slot);
|
||||
m_this->m_total -= 1;
|
||||
rhs.m_slot = 32;
|
||||
}
|
||||
|
||||
shared_lock& operator=(const shared_lock&) = delete;
|
||||
|
||||
~shared_lock()
|
||||
{
|
||||
// Clear the slot (does nothing if all slots are used)
|
||||
const u64 bit = (1ull << m_slot) & 0xffffffff;
|
||||
m_this->m_cvx32 &= ~(bit | (bit << 32));
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
// Check success
|
||||
return m_slot < 32;
|
||||
}
|
||||
|
||||
bool wait(u64 usec_timeout = -1) const noexcept
|
||||
@@ -242,24 +249,36 @@ class cond_x16
|
||||
void imp_notify() noexcept;
|
||||
|
||||
public:
|
||||
constexpr cond_x16() = default;
|
||||
constexpr shared_cond() = default;
|
||||
|
||||
lock_x16 lock_one() noexcept
|
||||
shared_lock try_shared_lock() noexcept
|
||||
{
|
||||
return lock_x16(this);
|
||||
return shared_lock(this);
|
||||
}
|
||||
|
||||
bool wait(lock_x16 const& lock, u64 usec_timeout = -1) noexcept
|
||||
u32 count() const noexcept
|
||||
{
|
||||
const u64 cvx32 = m_cvx32;
|
||||
return utils::popcnt32(static_cast<u32>(cvx32 | (cvx32 >> 32)));
|
||||
}
|
||||
|
||||
bool wait(shared_lock const& lock, u64 usec_timeout = -1) noexcept
|
||||
{
|
||||
AUDIT(lock.m_this == this);
|
||||
return imp_wait(lock.m_slot, usec_timeout);
|
||||
}
|
||||
|
||||
void wait_all() noexcept;
|
||||
|
||||
bool wait_all(shared_lock& lock) noexcept;
|
||||
|
||||
void notify_all() noexcept
|
||||
{
|
||||
if (LIKELY(!m_cvx16))
|
||||
if (LIKELY(!m_cvx32))
|
||||
return;
|
||||
|
||||
imp_notify();
|
||||
}
|
||||
|
||||
bool notify_all(shared_lock& lock) noexcept;
|
||||
};
|
||||
|
||||
+13
-1
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
namespace date_time
|
||||
{
|
||||
static inline tm get_time(time_t* _time)
|
||||
@@ -22,11 +25,20 @@ namespace date_time
|
||||
return str;
|
||||
}
|
||||
|
||||
template<char separator = 0>
|
||||
static inline std::string current_time_narrow()
|
||||
{
|
||||
char str[80];
|
||||
tm now = get_time(0);
|
||||
strftime(str, sizeof(str), "%Y%m%d%H%M%S", &now);
|
||||
|
||||
std::string parse_buf;
|
||||
|
||||
if constexpr(separator != 0)
|
||||
parse_buf = std::string("%Y") + separator + "%m" + separator + "%d" + separator + "%H" + separator + "%M" + separator + "%S";
|
||||
else
|
||||
parse_buf = "%Y%m%d%H%M%S";
|
||||
|
||||
strftime(str, sizeof(str), parse_buf.c_str(), &now);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "dynamic_library.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -50,7 +50,7 @@ namespace utils
|
||||
|
||||
bool dynamic_library::loaded() const
|
||||
{
|
||||
return !m_handle;
|
||||
return m_handle != nullptr;
|
||||
}
|
||||
|
||||
dynamic_library::operator bool() const
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
#include <deque>
|
||||
#include <list>
|
||||
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
template <typename T, T Mod = T::__state_enum_max, typename Under = std::underlying_type_t<T>>
|
||||
T operator ++(T& value, int)
|
||||
|
||||
+21
-6
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@@ -673,6 +673,16 @@ struct area_base
|
||||
return{ x1, y1, x2 - x1, y2 - y1 };
|
||||
}
|
||||
|
||||
constexpr T width() const
|
||||
{
|
||||
return (x1 < x2) ? (x2 - x1) : (x1 - x2);
|
||||
}
|
||||
|
||||
constexpr T height() const
|
||||
{
|
||||
return (y1 < y2) ? (y2 - y1) : (y1 - y2);
|
||||
}
|
||||
|
||||
void flip_vertical()
|
||||
{
|
||||
T _y = y1; y1 = y2; y2 = _y;
|
||||
@@ -693,6 +703,11 @@ struct area_base
|
||||
return{ x2, y1, x1, y2 };
|
||||
}
|
||||
|
||||
constexpr bool is_flipped() const
|
||||
{
|
||||
return (x1 > x2 || y1 > y2);
|
||||
}
|
||||
|
||||
constexpr bool operator == (const area_base& rhs) const
|
||||
{
|
||||
return x1 == rhs.x1 && x2 == rhs.x2 && y1 == rhs.y1 && y2 == rhs.y2;
|
||||
@@ -826,7 +841,7 @@ struct color4_base
|
||||
T xyzw[4];
|
||||
};
|
||||
|
||||
color4_base()
|
||||
constexpr color4_base()
|
||||
: x{}
|
||||
, y{}
|
||||
, z{}
|
||||
@@ -834,7 +849,7 @@ struct color4_base
|
||||
{
|
||||
}
|
||||
|
||||
color4_base(T x, T y = {}, T z = {}, T w = {})
|
||||
constexpr color4_base(T x, T y = {}, T z = {}, T w = {})
|
||||
: x(x)
|
||||
, y(y)
|
||||
, z(z)
|
||||
@@ -842,18 +857,18 @@ struct color4_base
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const color4_base& rhs) const
|
||||
constexpr bool operator == (const color4_base& rhs) const
|
||||
{
|
||||
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
|
||||
}
|
||||
|
||||
bool operator != (const color4_base& rhs) const
|
||||
constexpr bool operator != (const color4_base& rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
template<typename NT>
|
||||
operator color4_base<NT>() const
|
||||
constexpr operator color4_base<NT>() const
|
||||
{
|
||||
return{ (NT)x, (NT)y, (NT)z, (NT)w };
|
||||
}
|
||||
|
||||
+6
-6
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Utilities/types.h"
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
@@ -28,24 +29,23 @@ namespace rpcs3
|
||||
template<typename T>
|
||||
static size_t hash_struct(const T& value)
|
||||
{
|
||||
// TODO: use c++17 if constexpr
|
||||
static constexpr auto block_sz = sizeof(T);
|
||||
|
||||
if ((block_sz & 0x7) == 0)
|
||||
if constexpr ((block_sz & 0x7) == 0)
|
||||
{
|
||||
return hash_struct_base<T, u64>(value);
|
||||
}
|
||||
|
||||
if ((block_sz & 0x3) == 0)
|
||||
if constexpr ((block_sz & 0x3) == 0)
|
||||
{
|
||||
return hash_struct_base<T, u32>(value);
|
||||
}
|
||||
|
||||
if ((block_sz & 0x1) == 0)
|
||||
if constexpr ((block_sz & 0x1) == 0)
|
||||
{
|
||||
return hash_struct_base<T, u16>(value);
|
||||
}
|
||||
|
||||
return hash_struct_base<T, u8>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-21
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
//! Simple sizeless array base for concurrent access. Cannot shrink, only growths automatically.
|
||||
//! There is no way to know the current size. The smaller index is, the faster it's accessed.
|
||||
@@ -68,13 +68,13 @@ public:
|
||||
// Get current "push" position
|
||||
u32 size() const
|
||||
{
|
||||
return reinterpret_cast<const atomic_t<u32>&>(m_ctrl).load(); // Hack
|
||||
return m_ctrl.load().push;
|
||||
}
|
||||
|
||||
// Acquire the place for one or more elements.
|
||||
u32 push_begin(u32 count = 1)
|
||||
{
|
||||
return reinterpret_cast<atomic_t<u32>&>(m_ctrl).fetch_add(count); // Hack
|
||||
return std::bit_cast<atomic_t<u64>*>(&m_ctrl)->fetch_add(count); // Hack
|
||||
}
|
||||
|
||||
// Get current "pop" position
|
||||
@@ -358,7 +358,7 @@ public:
|
||||
|
||||
~lf_queue()
|
||||
{
|
||||
delete reinterpret_cast<T*>(m_head.load());
|
||||
delete reinterpret_cast<lf_queue_item<T>*>(m_head.load());
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
@@ -388,27 +388,13 @@ public:
|
||||
|
||||
// Apply func(data) to each element, return the total length
|
||||
template <typename F>
|
||||
std::size_t apply(F&& func)
|
||||
std::size_t apply(F func)
|
||||
{
|
||||
std::size_t count = 0;
|
||||
|
||||
for (auto slice = pop_all(); slice; slice.pop_front())
|
||||
{
|
||||
std::invoke(std::forward<F>(func), *slice);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// apply() overload for callable template argument
|
||||
template <auto F>
|
||||
std::size_t apply()
|
||||
{
|
||||
std::size_t count = 0;
|
||||
|
||||
for (auto slice = pop_all(); slice; slice.pop_front())
|
||||
{
|
||||
std::invoke(F, *slice);
|
||||
std::invoke(func, *slice);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
+109
-11
@@ -1,7 +1,4 @@
|
||||
#include "mutex.h"
|
||||
#include "sync.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
void shared_mutex::imp_lock_shared(u32 val)
|
||||
{
|
||||
@@ -42,26 +39,112 @@ void shared_mutex::imp_unlock_shared(u32 old)
|
||||
}
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock_low(u32 val)
|
||||
{
|
||||
verify("shared_mutex underflow" HERE), val < c_err;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
busy_wait();
|
||||
|
||||
if (try_lock_low())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire writer lock and downgrade
|
||||
const u32 old = m_value.fetch_add(c_one);
|
||||
|
||||
if (old == 0)
|
||||
{
|
||||
lock_downgrade();
|
||||
return;
|
||||
}
|
||||
|
||||
verify("shared_mutex overflow" HERE), (old % c_sig) + c_one < c_sig;
|
||||
imp_wait();
|
||||
lock_downgrade();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_unlock_low(u32 old)
|
||||
{
|
||||
verify("shared_mutex underflow" HERE), old - 1 < c_err;
|
||||
|
||||
// Check reader count, notify the writer if necessary
|
||||
if ((old - 1) % c_vip == 0)
|
||||
{
|
||||
imp_signal();
|
||||
}
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock_vip(u32 val)
|
||||
{
|
||||
verify("shared_mutex underflow" HERE), val < c_err;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
busy_wait();
|
||||
|
||||
if (try_lock_vip())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire writer lock and downgrade
|
||||
const u32 old = m_value.fetch_add(c_one);
|
||||
|
||||
if (old == 0)
|
||||
{
|
||||
lock_downgrade_to_vip();
|
||||
return;
|
||||
}
|
||||
|
||||
verify("shared_mutex overflow" HERE), (old % c_sig) + c_one < c_sig;
|
||||
imp_wait();
|
||||
lock_downgrade_to_vip();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_unlock_vip(u32 old)
|
||||
{
|
||||
verify("shared_mutex underflow" HERE), old - 1 < c_err;
|
||||
|
||||
// Check reader count, notify the writer if necessary
|
||||
if ((old - 1) % c_one / c_vip == 0)
|
||||
{
|
||||
imp_signal();
|
||||
}
|
||||
}
|
||||
|
||||
void shared_mutex::imp_wait()
|
||||
{
|
||||
while (!balanced_wait_until(m_value, -1, [&](u32& value, auto...)
|
||||
while (true)
|
||||
{
|
||||
if (value >= c_sig)
|
||||
const auto [old, ok] = m_value.fetch_op([](u32& value)
|
||||
{
|
||||
value -= c_sig;
|
||||
return true;
|
||||
if (value >= c_sig)
|
||||
{
|
||||
value -= c_sig;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
m_value.wait(old);
|
||||
}
|
||||
}
|
||||
|
||||
void shared_mutex::imp_signal()
|
||||
{
|
||||
m_value += c_sig;
|
||||
balanced_awaken(m_value, 1);
|
||||
m_value.notify_one();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock(u32 val)
|
||||
@@ -158,3 +241,18 @@ void shared_mutex::imp_lock_unlock()
|
||||
imp_wait();
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool shared_mutex::downgrade_unique_vip_lock_to_low_or_unlock()
|
||||
{
|
||||
return m_value.atomic_op([](u32& value)
|
||||
{
|
||||
if (value % c_one / c_vip == 1)
|
||||
{
|
||||
value -= c_vip - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
value -= c_vip;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
+119
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
// Shared mutex with small size (u32).
|
||||
class shared_mutex final
|
||||
@@ -12,12 +12,17 @@ class shared_mutex final
|
||||
c_one = 1u << 14, // Fixed-point 1.0 value (one writer, max_readers = c_one - 1)
|
||||
c_sig = 1u << 30,
|
||||
c_err = 1u << 31,
|
||||
c_vip = 1u << 7,
|
||||
};
|
||||
|
||||
atomic_t<u32> m_value{};
|
||||
|
||||
void imp_lock_shared(u32 val);
|
||||
void imp_unlock_shared(u32 old);
|
||||
void imp_lock_low(u32 val);
|
||||
void imp_unlock_low(u32 old);
|
||||
void imp_lock_vip(u32 val);
|
||||
void imp_unlock_vip(u32 old);
|
||||
void imp_wait();
|
||||
void imp_signal();
|
||||
void imp_lock(u32 val);
|
||||
@@ -83,6 +88,64 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool try_lock_low()
|
||||
{
|
||||
const u32 value = m_value.load();
|
||||
|
||||
// Conditional increment
|
||||
return value < c_vip - 1 && m_value.compare_and_swap_test(value, value + 1);
|
||||
}
|
||||
|
||||
void lock_low()
|
||||
{
|
||||
const u32 value = m_value.load();
|
||||
|
||||
if (UNLIKELY(value >= c_vip - 1 || !m_value.compare_and_swap_test(value, value + 1)))
|
||||
{
|
||||
imp_lock_low(value);
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_low()
|
||||
{
|
||||
// Unconditional decrement (can result in broken state)
|
||||
const u32 value = m_value.fetch_sub(1);
|
||||
|
||||
if (UNLIKELY(value >= c_one))
|
||||
{
|
||||
imp_unlock_low(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool try_lock_vip()
|
||||
{
|
||||
const u32 value = m_value.load();
|
||||
|
||||
// Conditional increment
|
||||
return value < c_one - 1 && (value % c_vip) == 0 && m_value.compare_and_swap_test(value, value + c_vip);
|
||||
}
|
||||
|
||||
void lock_vip()
|
||||
{
|
||||
const u32 value = m_value.load();
|
||||
|
||||
if (UNLIKELY(value >= c_one - 1 || (value % c_vip) || !m_value.compare_and_swap_test(value, value + c_vip)))
|
||||
{
|
||||
imp_lock_vip(value);
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_vip()
|
||||
{
|
||||
// Unconditional decrement (can result in broken state)
|
||||
const u32 value = m_value.fetch_sub(c_vip);
|
||||
|
||||
if (UNLIKELY(value >= c_one))
|
||||
{
|
||||
imp_unlock_vip(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return m_value.compare_and_swap_test(0, c_one);
|
||||
@@ -121,7 +184,7 @@ public:
|
||||
|
||||
void unlock_hle()
|
||||
{
|
||||
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), -c_one);
|
||||
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), 0u - c_one);
|
||||
|
||||
if (UNLIKELY(value != c_one))
|
||||
{
|
||||
@@ -151,6 +214,12 @@ public:
|
||||
m_value -= c_one - 1;
|
||||
}
|
||||
|
||||
void lock_downgrade_to_vip()
|
||||
{
|
||||
// Convert to vip lock (can result in broken state)
|
||||
m_value -= c_one - c_vip;
|
||||
}
|
||||
|
||||
// Optimized wait for lockability without locking, relaxed
|
||||
void lock_unlock()
|
||||
{
|
||||
@@ -171,9 +240,12 @@ public:
|
||||
{
|
||||
return m_value.load() < c_one - 1;
|
||||
}
|
||||
|
||||
// Special purpose logic
|
||||
bool downgrade_unique_vip_lock_to_low_or_unlock();
|
||||
};
|
||||
|
||||
// Simplified shared (reader) lock implementation.
|
||||
// Simplified shared (reader) lock implementation. Mutually incompatible with low_lock and vip_lock.
|
||||
class reader_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
@@ -211,3 +283,47 @@ public:
|
||||
m_upgraded ? m_mutex.unlock() : m_mutex.unlock_shared();
|
||||
}
|
||||
};
|
||||
|
||||
// Special shared (reader) lock, mutually exclusive with vip locks. Mutually incompatible with normal shared (reader) lock.
|
||||
class low_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
|
||||
public:
|
||||
low_lock(const low_lock&) = delete;
|
||||
|
||||
low_lock& operator=(const low_lock&) = delete;
|
||||
|
||||
explicit low_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
{
|
||||
m_mutex.lock_low();
|
||||
}
|
||||
|
||||
~low_lock()
|
||||
{
|
||||
m_mutex.unlock_low();
|
||||
}
|
||||
};
|
||||
|
||||
// Special shared (reader) lock, mutually exclusive with low locks. Mutually incompatible with normal shared (reader) lock.
|
||||
class vip_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
|
||||
public:
|
||||
vip_lock(const vip_lock&) = delete;
|
||||
|
||||
vip_lock& operator=(const vip_lock&) = delete;
|
||||
|
||||
explicit vip_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
{
|
||||
m_mutex.lock_vip();
|
||||
}
|
||||
|
||||
~vip_lock()
|
||||
{
|
||||
m_mutex.unlock_vip();
|
||||
}
|
||||
};
|
||||
|
||||
+3
-17
@@ -1,5 +1,4 @@
|
||||
#include "sema.h"
|
||||
#include "sync.h"
|
||||
|
||||
void semaphore_base::imp_wait()
|
||||
{
|
||||
@@ -15,14 +14,6 @@ void semaphore_base::imp_wait()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
const s32 value = m_value.fetch_sub(1);
|
||||
|
||||
if (value <= 0)
|
||||
{
|
||||
NtWaitForKeyedEvent(nullptr, &m_value, false, nullptr);
|
||||
}
|
||||
#else
|
||||
while (true)
|
||||
{
|
||||
// Try hard way
|
||||
@@ -51,24 +42,19 @@ void semaphore_base::imp_wait()
|
||||
if (value >= 0)
|
||||
{
|
||||
// Signal other waiter to wake up or to restore sign bit
|
||||
futex(&m_value, FUTEX_WAKE_PRIVATE, 1);
|
||||
m_value.notify_one();
|
||||
return;
|
||||
}
|
||||
|
||||
futex(&m_value, FUTEX_WAIT_PRIVATE, value);
|
||||
m_value.wait(value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void semaphore_base::imp_post(s32 _old)
|
||||
{
|
||||
verify("semaphore_base: overflow" HERE), _old < 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
NtReleaseKeyedEvent(nullptr, &m_value, false, nullptr);
|
||||
#else
|
||||
futex(&m_value, FUTEX_WAKE_PRIVATE, 1);
|
||||
#endif
|
||||
m_value.notify_one();
|
||||
}
|
||||
|
||||
bool semaphore_base::try_post(s32 _max)
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
// Lightweight semaphore helper class
|
||||
class semaphore_base
|
||||
|
||||
+17
-3
@@ -3,7 +3,7 @@
|
||||
/* For internal use. Don't include. */
|
||||
|
||||
#include "types.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include "dynamic_library.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -233,9 +233,16 @@ bool balanced_wait_until(atomic_t<T>& var, u64 usec_timeout, Pred&& pred)
|
||||
timeout.tv_sec = usec_timeout / 1000000;
|
||||
timeout.tv_nsec = (usec_timeout % 1000000) * 1000;
|
||||
|
||||
char* ptr = reinterpret_cast<char*>(&var);
|
||||
|
||||
if constexpr (sizeof(T) == 8)
|
||||
{
|
||||
ptr += 4 * IS_BE_MACHINE;
|
||||
}
|
||||
|
||||
while (!test_pred(value))
|
||||
{
|
||||
if (futex(&var, FUTEX_WAIT_PRIVATE, static_cast<u32>(value), is_inf ? nullptr : &timeout) == 0)
|
||||
if (futex(ptr, FUTEX_WAIT_PRIVATE, static_cast<u32>(value), is_inf ? nullptr : &timeout) == 0)
|
||||
{
|
||||
if (!test_pred(value, nullptr))
|
||||
{
|
||||
@@ -284,9 +291,16 @@ void balanced_awaken(atomic_t<T>& var, u32 weight)
|
||||
NtReleaseKeyedEvent(nullptr, &var, false, nullptr);
|
||||
}
|
||||
#else
|
||||
char* ptr = reinterpret_cast<char*>(&var);
|
||||
|
||||
if constexpr (sizeof(T) == 8)
|
||||
{
|
||||
ptr += 4 * IS_BE_MACHINE;
|
||||
}
|
||||
|
||||
if (All || weight)
|
||||
{
|
||||
futex(&var, FUTEX_WAKE_PRIVATE, All ? INT_MAX : std::min<u32>(INT_MAX, weight));
|
||||
futex(ptr, FUTEX_WAKE_PRIVATE, All ? INT_MAX : std::min<u32>(INT_MAX, weight));
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
Regular → Executable
+109
-1
@@ -1,10 +1,17 @@
|
||||
#include "sysinfo.h"
|
||||
#include "sysinfo.h"
|
||||
#include "StrFmt.h"
|
||||
#include "File.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#include "sysinfoapi.h"
|
||||
#include "subauth.h"
|
||||
#include "stringapiset.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
bool utils::has_ssse3()
|
||||
@@ -37,6 +44,12 @@ bool utils::has_rtm()
|
||||
return g_value;
|
||||
}
|
||||
|
||||
bool utils::has_tsx_force_abort()
|
||||
{
|
||||
static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[3] & 0x2000) == 0x2000;
|
||||
return g_value;
|
||||
}
|
||||
|
||||
bool utils::has_mpx()
|
||||
{
|
||||
static const bool g_value = get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4000) == 0x4000;
|
||||
@@ -97,6 +110,15 @@ std::string utils::get_system_info()
|
||||
|
||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||
|
||||
if (const ullong tsc_freq = get_tsc_freq())
|
||||
{
|
||||
fmt::append(result, " | TSC: %.02fGHz", tsc_freq / 1000000000.);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::append(result, " | TSC: Bad");
|
||||
}
|
||||
|
||||
if (has_avx())
|
||||
{
|
||||
result += " | AVX";
|
||||
@@ -120,11 +142,97 @@ std::string utils::get_system_info()
|
||||
if (has_rtm())
|
||||
{
|
||||
result += " | TSX";
|
||||
|
||||
if (has_tsx_force_abort())
|
||||
{
|
||||
result += "-FA";
|
||||
}
|
||||
|
||||
if (!has_mpx())
|
||||
{
|
||||
result += " disabled by default";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string utils::get_firmware_version()
|
||||
{
|
||||
const std::string file_path = g_cfg.vfs.get_dev_flash() + "vsh/etc/version.txt";
|
||||
if (fs::is_file(file_path))
|
||||
{
|
||||
const fs::file version_file = fs::file(file_path);
|
||||
std::string version = version_file.to_string();
|
||||
|
||||
// Extract version
|
||||
const size_t start = version.find_first_of(':') + 1;
|
||||
const size_t end = version.find_first_of(':', start);
|
||||
version = version.substr(start, end - start);
|
||||
|
||||
// Trim version
|
||||
const size_t trim_start = version.find_first_not_of('0');
|
||||
const size_t trim_end = version.find_last_not_of('0');
|
||||
version = version.substr(trim_start, trim_end);
|
||||
|
||||
return version;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string utils::get_OS_version()
|
||||
{
|
||||
std::string output = "";
|
||||
#ifdef _WIN32
|
||||
// GetVersionEx is deprecated, RtlGetVersion is kernel-mode only and AnalyticsInfo is UWP only.
|
||||
// So we're forced to read PEB instead to get Windows version info. It's ugly but works.
|
||||
|
||||
const DWORD peb_offset = 0x60;
|
||||
const INT_PTR peb = __readgsqword(peb_offset);
|
||||
|
||||
const DWORD version_major = *reinterpret_cast<const DWORD*>(peb + 0x118);
|
||||
const DWORD version_minor = *reinterpret_cast<const DWORD*>(peb + 0x11c);
|
||||
const WORD build = *reinterpret_cast<const WORD*>(peb + 0x120);
|
||||
const UNICODE_STRING service_pack = *reinterpret_cast<const UNICODE_STRING*>(peb + 0x02E8);
|
||||
const u64 compatibility_mode = *reinterpret_cast<const u64*>(peb + 0x02C8); // Two DWORDs, major & minor version
|
||||
|
||||
const bool has_sp = service_pack.Length > 0;
|
||||
std::vector<char> holder(service_pack.Length + 1, '\0');
|
||||
if (has_sp)
|
||||
{
|
||||
WideCharToMultiByte(CP_UTF8, NULL, service_pack.Buffer, service_pack.Length,
|
||||
(LPSTR) holder.data(), static_cast<int>(holder.size()), NULL, NULL);
|
||||
}
|
||||
|
||||
fmt::append(output,
|
||||
"Operating system: Windows, Major: %lu, Minor: %lu, Build: %u, Service Pack: %s, Compatibility mode: %llu",
|
||||
version_major, version_minor, build, has_sp ? holder.data() : "none", compatibility_mode);
|
||||
#else
|
||||
struct utsname details = {};
|
||||
|
||||
if (!uname(&details))
|
||||
{
|
||||
fmt::append(output, "Operating system: POSIX, Name: %s, Release: %s, Version: %s",
|
||||
details.sysname, details.release, details.version);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::append(output, "Operating system: POSIX, Unknown version! (Error: %d)", errno);
|
||||
}
|
||||
#endif
|
||||
return output;
|
||||
}
|
||||
|
||||
ullong utils::get_tsc_freq()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER freq;
|
||||
if (!QueryPerformanceFrequency(&freq) || freq.QuadPart > 9'999'999)
|
||||
return 0;
|
||||
return freq.QuadPart * 1024;
|
||||
#else
|
||||
// TODO
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Regular → Executable
+9
-1
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
@@ -37,6 +37,8 @@ namespace utils
|
||||
|
||||
bool has_rtm();
|
||||
|
||||
bool has_tsx_force_abort();
|
||||
|
||||
bool has_mpx();
|
||||
|
||||
bool has_512();
|
||||
@@ -44,4 +46,10 @@ namespace utils
|
||||
bool has_xop();
|
||||
|
||||
std::string get_system_info();
|
||||
|
||||
std::string get_firmware_version();
|
||||
|
||||
std::string get_OS_version();
|
||||
|
||||
ullong get_tsc_freq();
|
||||
}
|
||||
|
||||
+197
-398
@@ -3,7 +3,8 @@
|
||||
#include "types.h"
|
||||
#include "mutex.h"
|
||||
#include "cond.h"
|
||||
#include "Atomic.h"
|
||||
#include "util/atomic.hpp"
|
||||
#include "util/typeindices.hpp"
|
||||
#include "VirtualMemory.h"
|
||||
#include <memory>
|
||||
|
||||
@@ -35,21 +36,6 @@ namespace utils
|
||||
ullong stamp;
|
||||
};
|
||||
|
||||
// Detect shared type: id_share tag type can specify any type
|
||||
template <typename T, typename = void>
|
||||
struct typeinfo_share
|
||||
{
|
||||
static constexpr bool is_shared = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct typeinfo_share<T, std::void_t<typename std::decay_t<T>::id_share>>
|
||||
{
|
||||
using share = std::decay_t<typename std::decay_t<T>::id_share>;
|
||||
|
||||
static constexpr bool is_shared = true;
|
||||
};
|
||||
|
||||
// Detect id transformation trait (multiplier)
|
||||
template <typename T, typename = void>
|
||||
struct typeinfo_step
|
||||
@@ -70,12 +56,6 @@ namespace utils
|
||||
static constexpr uint bias = 0;
|
||||
};
|
||||
|
||||
// template <typename T>
|
||||
// struct typeinfo_bias<T, std::void_t<decltype(std::decay_t<T>::id_bias)>>
|
||||
// {
|
||||
// static constexpr uint bias = uint{std::decay_t<T>::id_bias};
|
||||
// };
|
||||
|
||||
template <typename T>
|
||||
struct typeinfo_bias<T, std::void_t<decltype(std::decay_t<T>::id_base)>>
|
||||
{
|
||||
@@ -92,212 +72,51 @@ namespace utils
|
||||
template <typename T>
|
||||
struct typeinfo_count<T, std::void_t<decltype(std::decay_t<T>::id_count)>>
|
||||
{
|
||||
static constexpr uint get_max()
|
||||
{
|
||||
// Use count of the "shared" tag type, it should be a public base of T in this case
|
||||
if constexpr (typeinfo_share<T>::is_shared)
|
||||
{
|
||||
using shared = typename typeinfo_share<T>::share;
|
||||
|
||||
if constexpr (!std::is_same_v<std::decay_t<T>, shared>)
|
||||
{
|
||||
return typeinfo_count<shared>::max_count;
|
||||
}
|
||||
}
|
||||
|
||||
return uint{std::decay_t<T>::id_count};
|
||||
}
|
||||
|
||||
static constexpr uint max_count = get_max();
|
||||
static constexpr uint max_count = uint{std::decay_t<T>::id_count};
|
||||
|
||||
static_assert(ullong{max_count} * typeinfo_step<T>::step <= 0x1'0000'0000ull);
|
||||
};
|
||||
|
||||
// Detect polymorphic type enablement
|
||||
// Detect operator ->
|
||||
template <typename T, typename = void>
|
||||
struct typeinfo_poly
|
||||
struct typeinfo_pointer
|
||||
{
|
||||
static constexpr bool is_poly = false;
|
||||
static constexpr bool is_ptr = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct typeinfo_poly<T, std::void_t<decltype(std::decay_t<T>::id_poly)>>
|
||||
struct typeinfo_pointer<T, std::void_t<decltype(&std::decay_t<T>::operator->)>>
|
||||
{
|
||||
static constexpr bool is_poly = true;
|
||||
|
||||
static_assert(std::has_virtual_destructor_v<std::decay_t<T>>);
|
||||
static constexpr bool is_ptr = true;
|
||||
};
|
||||
|
||||
// Type information
|
||||
struct typeinfo_base
|
||||
{
|
||||
uint type = 0;
|
||||
uint size = 0;
|
||||
uint align = 0;
|
||||
uint count = 0;
|
||||
void(*clean)(class typemap_block*) = 0;
|
||||
const typeinfo_base* base = 0;
|
||||
|
||||
constexpr typeinfo_base() noexcept = default;
|
||||
|
||||
protected:
|
||||
// Next typeinfo in linked list
|
||||
typeinfo_base* next = 0;
|
||||
template <typename T>
|
||||
static void call_destructor(typemap_block* ptr) noexcept;
|
||||
|
||||
template <typename T>
|
||||
friend struct typeinfo;
|
||||
|
||||
friend class typecounter;
|
||||
|
||||
friend class typemap_block;
|
||||
friend class typemap;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline typeinfo_base g_sh{};
|
||||
|
||||
// Class for automatic type registration
|
||||
class typecounter
|
||||
{
|
||||
// Linked list built at global initialization time
|
||||
typeinfo_base* first = &g_sh<void>;
|
||||
typeinfo_base* next = first;
|
||||
typeinfo_base* last = first;
|
||||
|
||||
template <typename T>
|
||||
friend struct typeinfo;
|
||||
|
||||
friend class typemap_block;
|
||||
friend class typemap;
|
||||
|
||||
public:
|
||||
constexpr typecounter() noexcept = default;
|
||||
|
||||
// Get next type id, or total type count
|
||||
operator uint() const
|
||||
static constexpr typeinfo_base make_typeinfo() noexcept
|
||||
{
|
||||
return last->type + 1;
|
||||
static_assert(alignof(T) < 4096);
|
||||
|
||||
typeinfo_base r;
|
||||
r.size = uint{sizeof(T)};
|
||||
r.align = uint{alignof(T)};
|
||||
r.count = typeinfo_count<T>::max_count;
|
||||
r.clean = &call_destructor<T>;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
// Global typecounter instance
|
||||
inline typecounter g_typecounter{};
|
||||
|
||||
template <typename T>
|
||||
struct typeinfo : typeinfo_base
|
||||
{
|
||||
static void call_destructor(class typemap_block* ptr);
|
||||
|
||||
typeinfo();
|
||||
|
||||
template <typename, typename B>
|
||||
friend struct typepoly;
|
||||
};
|
||||
|
||||
// Type information for each used type
|
||||
template <typename T>
|
||||
inline const typeinfo<T> g_typeinfo{};
|
||||
|
||||
template <typename T, typename B>
|
||||
struct typepoly
|
||||
{
|
||||
uint type = 0;
|
||||
|
||||
typepoly();
|
||||
};
|
||||
|
||||
// Polymorphic type helper
|
||||
template <typename T, typename B>
|
||||
inline const typepoly<T, B> g_typepoly{};
|
||||
|
||||
template <typename T>
|
||||
typeinfo<T>::typeinfo()
|
||||
{
|
||||
static_assert(alignof(T) < 4096);
|
||||
|
||||
this->type = g_typecounter;
|
||||
this->size = uint{sizeof(T)};
|
||||
this->align = uint{alignof(T)};
|
||||
this->count = typeinfo_count<T>::max_count;
|
||||
this->clean = &call_destructor;
|
||||
|
||||
if (this != &g_typeinfo<T>)
|
||||
{
|
||||
// Protect global state against unrelated constructions of typeinfo<> objects
|
||||
this->type = g_typeinfo<T>.type;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update linked list
|
||||
g_typecounter.next->next = this;
|
||||
g_typecounter.next = this;
|
||||
g_typecounter.last = this;
|
||||
}
|
||||
|
||||
if constexpr (typeinfo_share<T>::is_shared)
|
||||
{
|
||||
// Store additional information for shared types
|
||||
using shared = typename typeinfo_share<T>::share;
|
||||
|
||||
// Bind
|
||||
this->base = &g_sh<shared>;
|
||||
|
||||
if (this != &g_typeinfo<T>)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Use smallest type id (void tag can reuse id 0)
|
||||
if (g_sh<shared>.type == 0 && !std::is_void_v<shared>)
|
||||
g_sh<shared>.type = this->type;
|
||||
|
||||
// Update max size and alignment
|
||||
if (g_sh<shared>.size < this->size)
|
||||
g_sh<shared>.size = this->size;
|
||||
if (g_sh<shared>.align < this->align)
|
||||
g_sh<shared>.align = this->align;
|
||||
if (g_sh<shared>.count < this->count)
|
||||
g_sh<shared>.count = this->count;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename B>
|
||||
typepoly<T, B>::typepoly()
|
||||
{
|
||||
static_assert(alignof(T) < 4096);
|
||||
|
||||
if (this != &g_typepoly<T, B>)
|
||||
{
|
||||
// Protect global state against unrelated constructions of typepoly<> objects
|
||||
return;
|
||||
}
|
||||
|
||||
// Set min align 16 to make some space for a pointer
|
||||
const uint size{sizeof(T) < 16 ? 16 : sizeof(T)};
|
||||
const uint align{alignof(T) < 16 ? 16 : alignof(T)};
|
||||
|
||||
typeinfo_base& info = const_cast<typeinfo<B>&>(g_typeinfo<B>);
|
||||
|
||||
this->type = info.type;
|
||||
|
||||
// Update max size and alignment of the base class typeinfo
|
||||
if (info.size < size)
|
||||
info.size = size;
|
||||
if (info.align < align)
|
||||
info.align = align;
|
||||
|
||||
if constexpr (typeinfo_share<B>::is_shared)
|
||||
{
|
||||
typeinfo_base& base = const_cast<typeinfo_base&>(*info.base);
|
||||
|
||||
// Update max size and alignment of the shared type
|
||||
if (base.size < size)
|
||||
base.size = size;
|
||||
if (base.align < align)
|
||||
base.align = align;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal, control block for a particular object
|
||||
class typemap_block
|
||||
{
|
||||
@@ -326,20 +145,126 @@ namespace utils
|
||||
static_assert(sizeof(typemap_block) == 8);
|
||||
|
||||
template <typename T>
|
||||
void typeinfo<T>::call_destructor(typemap_block* ptr)
|
||||
void typeinfo_base::call_destructor(typemap_block* ptr) noexcept
|
||||
{
|
||||
// Choose cleanup routine
|
||||
if constexpr (typeinfo_poly<T>::is_poly)
|
||||
{
|
||||
// Read actual pointer to the base class
|
||||
(*ptr->get_ptr<T*>())->~T();
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->get_ptr<T>()->~T();
|
||||
}
|
||||
ptr->get_ptr<T>()->~T();
|
||||
}
|
||||
|
||||
// An object of type T paired with atomic refcounter
|
||||
template <typename T>
|
||||
class refctr final
|
||||
{
|
||||
atomic_t<std::size_t> m_ref{1};
|
||||
|
||||
public:
|
||||
T object;
|
||||
|
||||
template <typename... Args>
|
||||
refctr(Args&&... args)
|
||||
: object(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
void add_ref() noexcept
|
||||
{
|
||||
m_ref++;
|
||||
}
|
||||
|
||||
std::size_t remove_ref() noexcept
|
||||
{
|
||||
return --m_ref;
|
||||
}
|
||||
};
|
||||
|
||||
// Simplified "shared" ptr making use of refctr<T> class
|
||||
template <typename T>
|
||||
class refptr final
|
||||
{
|
||||
refctr<T>* m_ptr = nullptr;
|
||||
|
||||
void destroy()
|
||||
{
|
||||
if (m_ptr && !m_ptr->remove_ref())
|
||||
delete m_ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr refptr() = default;
|
||||
|
||||
// Construct directly from refctr<T> pointer
|
||||
explicit refptr(refctr<T>* ptr) noexcept
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
refptr(const refptr& rhs) noexcept
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
if (m_ptr)
|
||||
m_ptr->add_ref();
|
||||
}
|
||||
|
||||
refptr(refptr&& rhs) noexcept
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
rhs.m_ptr = nullptr;
|
||||
}
|
||||
|
||||
~refptr()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
refptr& operator =(const refptr& rhs) noexcept
|
||||
{
|
||||
destroy();
|
||||
m_ptr = rhs.m_ptr;
|
||||
if (m_ptr)
|
||||
m_ptr->add_ref();
|
||||
}
|
||||
|
||||
refptr& operator =(refptr&& rhs) noexcept
|
||||
{
|
||||
std::swap(m_ptr, rhs.m_ptr);
|
||||
}
|
||||
|
||||
void reset() noexcept
|
||||
{
|
||||
destroy();
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
|
||||
refctr<T>* release() noexcept
|
||||
{
|
||||
return std::exchange(m_ptr, nullptr);
|
||||
}
|
||||
|
||||
void swap(refptr&& rhs) noexcept
|
||||
{
|
||||
std::swap(m_ptr, rhs.m_ptr);
|
||||
}
|
||||
|
||||
refctr<T>* get() const noexcept
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T& operator *() const noexcept
|
||||
{
|
||||
return m_ptr->object;
|
||||
}
|
||||
|
||||
T* operator ->() const noexcept
|
||||
{
|
||||
return &m_ptr->object;
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return !!m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Internal, typemap control block for a particular type
|
||||
struct alignas(64) typemap_head
|
||||
{
|
||||
@@ -456,20 +381,20 @@ namespace utils
|
||||
auto get() const noexcept
|
||||
{
|
||||
ASSUME(m_block->m_type != 0);
|
||||
|
||||
if constexpr (std::is_lvalue_reference_v<T>)
|
||||
{
|
||||
return static_cast<D*>(*m_block->get_ptr<std::remove_reference_t<T>*>());
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_block->get_ptr<T>();
|
||||
}
|
||||
return m_block->get_ptr<T>();
|
||||
}
|
||||
|
||||
auto operator->() const noexcept
|
||||
{
|
||||
return get();
|
||||
// Invoke object's operator -> if available
|
||||
if constexpr (typeinfo_pointer<T>::is_ptr)
|
||||
{
|
||||
return get()->operator->();
|
||||
}
|
||||
else
|
||||
{
|
||||
return get();
|
||||
}
|
||||
}
|
||||
|
||||
// Release the lock and set invalid state
|
||||
@@ -512,24 +437,12 @@ namespace utils
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (std::is_lvalue_reference_v<T>)
|
||||
{
|
||||
using base = std::remove_reference_t<T>;
|
||||
|
||||
if (m_block->m_type.exchange(g_typepoly<New, base>.type) != 0)
|
||||
{
|
||||
(*m_block->get_ptr<base*>())->~base();
|
||||
m_head->m_destroy_count++;
|
||||
}
|
||||
|
||||
*m_block->get_ptr<base*>() = new (m_block->get_ptr<New, 16>()) New(std::forward<Args>(args)...);
|
||||
}
|
||||
else
|
||||
if constexpr (true)
|
||||
{
|
||||
static_assert(std::is_same_v<New, T>);
|
||||
|
||||
// Set type; zero value shall not be observed in the case of recreation
|
||||
if (m_block->m_type.exchange(type_index()) != 0)
|
||||
if (m_block->m_type.exchange(1) != 0)
|
||||
{
|
||||
// Destroy object if it exists
|
||||
m_block->get_ptr<T>()->~T();
|
||||
@@ -552,16 +465,7 @@ namespace utils
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (std::is_lvalue_reference_v<T>)
|
||||
{
|
||||
using base = std::remove_reference_t<T>;
|
||||
(*m_block->get_ptr<base*>())->~base();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_block->get_ptr<T>()->~T();
|
||||
}
|
||||
|
||||
m_block->get_ptr<T>()->~T();
|
||||
m_head->m_destroy_count++;
|
||||
}
|
||||
|
||||
@@ -582,17 +486,6 @@ namespace utils
|
||||
return static_cast<uint>(quot) * step + bias;
|
||||
}
|
||||
|
||||
// Get current type
|
||||
uint get_type() const
|
||||
{
|
||||
return m_block->m_type;
|
||||
}
|
||||
|
||||
static uint type_index()
|
||||
{
|
||||
return g_typeinfo<std::decay_t<T>>.type;
|
||||
}
|
||||
|
||||
static constexpr bool type_const()
|
||||
{
|
||||
return std::is_const_v<std::remove_reference_t<T>>;
|
||||
@@ -619,16 +512,7 @@ namespace utils
|
||||
template <typename T>
|
||||
typemap_head* get_head() const
|
||||
{
|
||||
using _type = std::decay_t<T>;
|
||||
|
||||
if constexpr (typeinfo_share<T>::is_shared)
|
||||
{
|
||||
return &m_map[g_sh<_type>.type];
|
||||
}
|
||||
else
|
||||
{
|
||||
return &m_map[g_typeinfo<_type>.type];
|
||||
}
|
||||
return &m_map[stx::type_counter<typeinfo_base>::type<std::decay_t<T>>.index()];
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -660,10 +544,7 @@ namespace utils
|
||||
// Recreate, also required if constructed without initialization.
|
||||
void init()
|
||||
{
|
||||
// Kill the ability to register more types (should segfault on attempt)
|
||||
g_typecounter.next = nullptr;
|
||||
|
||||
if (g_typecounter <= 1)
|
||||
if (!stx::typeinfo_v<typeinfo_base>.count())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -671,13 +552,14 @@ namespace utils
|
||||
// Recreate and copy some type information
|
||||
if (m_map == nullptr)
|
||||
{
|
||||
m_map = new typemap_head[g_typecounter]();
|
||||
m_map = new typemap_head[stx::typeinfo_v<typeinfo_base>.count()]();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto type = g_typecounter.first;
|
||||
auto type = stx::typeinfo_v<typeinfo_base>.begin();
|
||||
auto _end = stx::typeinfo_v<typeinfo_base>.end();
|
||||
|
||||
for (uint i = 0; type; i++, type = type->next)
|
||||
for (uint i = 0; type != _end; i++, ++type)
|
||||
{
|
||||
// Delete objects (there shall be no threads accessing them)
|
||||
const uint lim = m_map[i].m_count != 1 ? +m_map[i].m_limit : 1;
|
||||
@@ -686,9 +568,9 @@ namespace utils
|
||||
{
|
||||
const auto block = reinterpret_cast<typemap_block*>(m_map[i].m_ptr + j * m_map[i].m_ssize);
|
||||
|
||||
if (const uint type_id = block->m_type)
|
||||
if (block->m_type)
|
||||
{
|
||||
m_map[type_id].clean(block);
|
||||
m_map[i].clean(block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,26 +587,24 @@ namespace utils
|
||||
if (m_memory == nullptr)
|
||||
{
|
||||
// Determine total size, copy typeinfo
|
||||
auto type = g_typecounter.first;
|
||||
auto type = stx::typeinfo_v<typeinfo_base>.begin();
|
||||
auto _end = stx::typeinfo_v<typeinfo_base>.end();
|
||||
|
||||
for (uint i = 0; type; i++, type = type->next)
|
||||
for (uint i = 0; type != _end; i++, ++type)
|
||||
{
|
||||
// Use base info if provided
|
||||
const auto base = type->base ? type->base : type;
|
||||
|
||||
const uint align = base->align;
|
||||
const uint ssize = ::align<uint>(sizeof(typemap_block), align) + ::align(base->size, align);
|
||||
const auto total = std::size_t{ssize} * base->count;
|
||||
const uint align = type->align;
|
||||
const uint ssize = ::align<uint>(sizeof(typemap_block), align) + ::align(type->size, align);
|
||||
const auto total = std::size_t{ssize} * type->count;
|
||||
const auto start = std::uintptr_t{::align(m_total, align)};
|
||||
|
||||
if (total && type->type == base->type)
|
||||
if (total)
|
||||
{
|
||||
// Move forward hoping there are no usable gaps wasted
|
||||
m_total = start + total;
|
||||
|
||||
// Store storage size and object count
|
||||
m_map[i].m_ssize = ssize;
|
||||
m_map[i].m_count = base->count;
|
||||
m_map[i].m_count = type->count;
|
||||
m_map[i].m_ptr = reinterpret_cast<uchar*>(start);
|
||||
}
|
||||
|
||||
@@ -737,7 +617,7 @@ namespace utils
|
||||
utils::memory_commit(m_memory, m_total);
|
||||
|
||||
// Update pointers
|
||||
for (uint i = 0, n = g_typecounter; i < n; i++)
|
||||
for (uint i = 0, n = stx::typeinfo_v<typeinfo_base>.count(); i < n; i++)
|
||||
{
|
||||
if (m_map[i].m_count)
|
||||
{
|
||||
@@ -769,8 +649,6 @@ namespace utils
|
||||
return {};
|
||||
}
|
||||
|
||||
const uint type_id = g_typeinfo<std::decay_t<Type>>.type;
|
||||
|
||||
using id_tag = std::decay_t<Arg>;
|
||||
|
||||
typemap_head* head = get_head<Type>();
|
||||
@@ -829,14 +707,6 @@ namespace utils
|
||||
block = nullptr;
|
||||
}
|
||||
}
|
||||
else if constexpr (typeinfo_share<Type>::is_shared)
|
||||
{
|
||||
// id_any/id_always allows either null or matching type
|
||||
if (UNLIKELY(block->m_type && block->m_type != type_id))
|
||||
{
|
||||
block = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_invocable_r_v<bool, const Arg&, const Type&>)
|
||||
@@ -846,20 +716,13 @@ namespace utils
|
||||
{
|
||||
block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize);
|
||||
|
||||
if (block->m_type == type_id)
|
||||
if (block->m_type)
|
||||
{
|
||||
std::lock_guard lock(block->m_mutex);
|
||||
|
||||
if (block->m_type == type_id)
|
||||
if (block->m_type)
|
||||
{
|
||||
if constexpr (std::is_lvalue_reference_v<Type>)
|
||||
{
|
||||
if (std::invoke(std::forward<Arg>(id), std::as_const(**block->get_ptr<std::remove_reference_t<Type>*>())))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
|
||||
if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -884,13 +747,6 @@ namespace utils
|
||||
{
|
||||
block = nullptr;
|
||||
}
|
||||
else if constexpr (typeinfo_share<Type>::is_shared)
|
||||
{
|
||||
if (UNLIKELY(block->m_type != type_id))
|
||||
{
|
||||
block = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UNLIKELY(block->m_type == 0))
|
||||
@@ -911,58 +767,24 @@ namespace utils
|
||||
{
|
||||
using id_tag = std::decay_t<Arg>;
|
||||
|
||||
const uint type_id = g_typeinfo<std::decay_t<Type>>.type;
|
||||
|
||||
if constexpr (std::is_same_v<id_tag, id_new_t>)
|
||||
{
|
||||
// No action for id_new
|
||||
return;
|
||||
}
|
||||
else if constexpr (std::is_same_v<id_tag, id_any_t> && !typeinfo_share<Type>::is_shared)
|
||||
{
|
||||
// No action for unshared id_any
|
||||
return;
|
||||
}
|
||||
else if constexpr (std::is_same_v<id_tag, id_any_t>)
|
||||
{
|
||||
// Possibly shared id_any
|
||||
if (LIKELY(!block || block->m_type == type_id || block->m_type == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// No action for id_any
|
||||
return;
|
||||
}
|
||||
else if constexpr (std::is_same_v<id_tag, id_always_t>)
|
||||
{
|
||||
if constexpr (typeinfo_share<Type>::is_shared)
|
||||
{
|
||||
if (!block)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (block->m_type && block->m_type != type_id)
|
||||
{
|
||||
block->m_mutex.unlock();
|
||||
block = nullptr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (block->m_type == 0 && block->m_type.compare_and_swap_test(0, type_id))
|
||||
if (block->m_type == 0 && block->m_type.compare_and_swap_test(0, 1))
|
||||
{
|
||||
// Initialize object if necessary
|
||||
static_assert(!std::is_const_v<std::remove_reference_t<Type>>);
|
||||
static_assert(!std::is_volatile_v<std::remove_reference_t<Type>>);
|
||||
|
||||
if constexpr (std::is_lvalue_reference_v<Type>)
|
||||
{
|
||||
using base = std::remove_reference_t<Type>;
|
||||
*block->get_ptr<base*>() = new (block->get_ptr<base, 16>()) base();
|
||||
}
|
||||
else
|
||||
{
|
||||
new (block->get_ptr<Type>) Type();
|
||||
}
|
||||
new (block->get_ptr<Type>) Type();
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -974,16 +796,9 @@ namespace utils
|
||||
return;
|
||||
}
|
||||
|
||||
if (LIKELY(block->m_type == type_id))
|
||||
if (LIKELY(block->m_type))
|
||||
{
|
||||
if constexpr (std::is_lvalue_reference_v<Type>)
|
||||
{
|
||||
if (std::invoke(std::forward<Arg>(id), std::as_const(**block->get_ptr<std::remove_reference_t<Type>*>())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
|
||||
if (std::invoke(std::forward<Arg>(id), std::as_const(*block->get_ptr<Type>())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -991,19 +806,9 @@ namespace utils
|
||||
}
|
||||
else if (block)
|
||||
{
|
||||
if constexpr (!typeinfo_share<Type>::is_shared)
|
||||
if (LIKELY(block->m_type))
|
||||
{
|
||||
if (LIKELY(block->m_type))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LIKELY(block->m_type == type_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1147,44 +952,48 @@ namespace utils
|
||||
return true;
|
||||
}
|
||||
|
||||
// Transform T&& into refptr<T>, moving const qualifier from T to refptr<T>
|
||||
template <typename T, typename U = std::remove_reference_t<T>>
|
||||
using decode_t = std::conditional_t<!std::is_rvalue_reference_v<T>, T,
|
||||
std::conditional_t<std::is_const_v<U>, const refptr<std::remove_const_t<U>>, refptr<U>>>;
|
||||
|
||||
public:
|
||||
// Lock any objects by their identifiers, special tags id_new/id_any/id_always, or search predicates
|
||||
template <typename... Types, typename... Args, typename = std::enable_if_t<sizeof...(Types) == sizeof...(Args)>>
|
||||
auto lock(Args&&... ids) const
|
||||
{
|
||||
static_assert(((!std::is_lvalue_reference_v<Types> == !typeinfo_poly<Types>::is_poly) && ...));
|
||||
static_assert(((!std::is_rvalue_reference_v<Types>) && ...));
|
||||
static_assert(((!std::is_lvalue_reference_v<Types>) && ...));
|
||||
static_assert(((!std::is_array_v<Types>) && ...));
|
||||
static_assert(((!std::is_void_v<Types>) && ...));
|
||||
|
||||
// Initialize pointers
|
||||
std::array<typeptr_base, sizeof...(Types)> result{this->init_ptr<Types>(std::forward<Args>(ids))...};
|
||||
std::array<typeptr_base, sizeof...(Types)> result{this->init_ptr<decode_t<Types>>(std::forward<Args>(ids))...};
|
||||
|
||||
// Whether requires locking after init_ptr
|
||||
using locks_t = std::integer_sequence<bool, does_need_lock<Types, Args>()...>;
|
||||
using locks_t = std::integer_sequence<bool, does_need_lock<decode_t<Types>, Args>()...>;
|
||||
|
||||
// Array index helper
|
||||
using seq_t = std::index_sequence_for<Types...>;
|
||||
using seq_t = std::index_sequence_for<decode_t<Types>...>;
|
||||
|
||||
// Lock any number of objects in safe manner
|
||||
while (true)
|
||||
{
|
||||
const uint locked = lock_array<Types...>(result, seq_t{}, locks_t{});
|
||||
if (LIKELY(try_lock<0, Types...>(result, locked, locks_t{})))
|
||||
const uint locked = lock_array<decode_t<Types>...>(result, seq_t{}, locks_t{});
|
||||
if (LIKELY(try_lock<0, decode_t<Types>...>(result, locked, locks_t{})))
|
||||
break;
|
||||
}
|
||||
|
||||
// Verify object types
|
||||
check_array<Types...>(result, seq_t{}, std::forward<Args>(ids)...);
|
||||
check_array<decode_t<Types>...>(result, seq_t{}, std::forward<Args>(ids)...);
|
||||
|
||||
// Return tuple of possibly locked pointers, or a single pointer
|
||||
if constexpr (sizeof...(Types) != 1)
|
||||
{
|
||||
return array_to_tuple<Types...>(result, seq_t{});
|
||||
return array_to_tuple<decode_t<Types>...>(result, seq_t{});
|
||||
}
|
||||
else
|
||||
{
|
||||
return typeptr<Types...>(result[0]);
|
||||
return typeptr<decode_t<Types>...>(result[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1192,35 +1001,25 @@ namespace utils
|
||||
template <typename Type, typename... Types, typename F>
|
||||
ullong apply(F&& func)
|
||||
{
|
||||
static_assert(!std::is_lvalue_reference_v<Type> == !typeinfo_poly<Type>::is_poly);
|
||||
static_assert(!std::is_rvalue_reference_v<Type>);
|
||||
static_assert(!std::is_lvalue_reference_v<Type>);
|
||||
static_assert(!std::is_array_v<Type>);
|
||||
static_assert(!std::is_void_v<Type>);
|
||||
|
||||
const uint type_id = g_typeinfo<std::decay_t<Type>>.type;
|
||||
|
||||
typemap_head* head = get_head<Type>();
|
||||
typemap_head* head = get_head<decode_t<Type>>();
|
||||
|
||||
const ullong ix = head->m_create_count;
|
||||
|
||||
for (std::size_t j = 0; j < (typeinfo_count<Type>::max_count != 1 ? +head->m_limit : 1); j++)
|
||||
for (std::size_t j = 0; j < (typeinfo_count<decode_t<Type>>::max_count != 1 ? +head->m_limit : 1); j++)
|
||||
{
|
||||
const auto block = reinterpret_cast<typemap_block*>(head->m_ptr + j * head->m_ssize);
|
||||
|
||||
if (block->m_type == type_id)
|
||||
if (block->m_type)
|
||||
{
|
||||
std::lock_guard lock(block->m_mutex);
|
||||
|
||||
if (block->m_type == type_id)
|
||||
if (block->m_type)
|
||||
{
|
||||
if constexpr (std::is_lvalue_reference_v<Type>)
|
||||
{
|
||||
std::invoke(std::forward<F>(func), **block->get_ptr<std::remove_reference_t<Type>*>());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::invoke(std::forward<F>(func), *block->get_ptr<Type>());
|
||||
}
|
||||
std::invoke(std::forward<F>(func), *block->get_ptr<decode_t<Type>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+104
-11
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
@@ -20,6 +21,10 @@
|
||||
#define IS_LE_MACHINE 1
|
||||
#define IS_BE_MACHINE 0
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define ASSUME(...) __assume(__VA_ARGS__) // MSVC __assume ignores side-effects
|
||||
@@ -28,6 +33,7 @@
|
||||
#define SAFE_BUFFERS __declspec(safebuffers)
|
||||
#define NEVER_INLINE __declspec(noinline)
|
||||
#define FORCE_INLINE __forceinline
|
||||
#define RESTRICT __restrict
|
||||
|
||||
#else // not _MSC_VER
|
||||
|
||||
@@ -47,6 +53,7 @@
|
||||
#define SAFE_BUFFERS
|
||||
#define NEVER_INLINE __attribute__((noinline))
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#define RESTRICT __restrict__
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
@@ -79,6 +86,22 @@
|
||||
#define AUDIT(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L)
|
||||
#include <bit>
|
||||
#else
|
||||
namespace std
|
||||
{
|
||||
template <class To, class From, typename = std::enable_if_t<sizeof(To) == sizeof(From)>>
|
||||
constexpr To bit_cast(const From& from) noexcept
|
||||
{
|
||||
static_assert(sizeof(To) == sizeof(From), "std::bit_cast<>: incompatible type size");
|
||||
|
||||
To result;
|
||||
std::memcpy(&result, &from, sizeof(From));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
using schar = signed char;
|
||||
using uchar = unsigned char;
|
||||
@@ -108,6 +131,46 @@ using steady_clock = std::conditional<
|
||||
std::chrono::high_resolution_clock::is_steady,
|
||||
std::chrono::high_resolution_clock, std::chrono::steady_clock>::type;
|
||||
|
||||
// Get integral type from type size
|
||||
template <std::size_t N>
|
||||
struct get_int_impl
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_impl<sizeof(u8)>
|
||||
{
|
||||
using utype = u8;
|
||||
using stype = s8;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_impl<sizeof(u16)>
|
||||
{
|
||||
using utype = u16;
|
||||
using stype = s16;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_impl<sizeof(u32)>
|
||||
{
|
||||
using utype = u32;
|
||||
using stype = s32;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct get_int_impl<sizeof(u64)>
|
||||
{
|
||||
using utype = u64;
|
||||
using stype = s64;
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
using get_uint_t = typename get_int_impl<N>::utype;
|
||||
|
||||
template <std::size_t N>
|
||||
using get_sint_t = typename get_int_impl<N>::stype;
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
using std::byte;
|
||||
@@ -361,6 +424,9 @@ struct alignas(16) s128
|
||||
CHECK_SIZE_ALIGN(u128, 16, 16);
|
||||
CHECK_SIZE_ALIGN(s128, 16, 16);
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
union alignas(2) f16
|
||||
{
|
||||
u16 _u16;
|
||||
@@ -371,22 +437,20 @@ union alignas(2) f16
|
||||
_u16 = raw;
|
||||
}
|
||||
|
||||
explicit operator float() const
|
||||
explicit operator f32() const
|
||||
{
|
||||
// See http://stackoverflow.com/a/26779139
|
||||
// The conversion doesn't handle NaN/Inf
|
||||
u32 raw = ((_u16 & 0x8000) << 16) | // Sign (just moved)
|
||||
(((_u16 & 0x7c00) + 0x1C000) << 13) | // Exponent ( exp - 15 + 127)
|
||||
((_u16 & 0x03FF) << 13); // Mantissa
|
||||
return (float&)raw;
|
||||
|
||||
return std::bit_cast<f32>(raw);
|
||||
}
|
||||
};
|
||||
|
||||
CHECK_SIZE_ALIGN(f16, 2, 2);
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||
constexpr T align(const T& value, ullong align)
|
||||
{
|
||||
@@ -397,13 +461,11 @@ template <typename T, typename T2>
|
||||
inline u32 offset32(T T2::*const mptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static_assert(sizeof(mptr) == sizeof(u32), "Invalid pointer-to-member size");
|
||||
return reinterpret_cast<const u32&>(mptr);
|
||||
return std::bit_cast<u32>(mptr);
|
||||
#elif __GNUG__
|
||||
static_assert(sizeof(mptr) == sizeof(std::size_t), "Invalid pointer-to-member size");
|
||||
return static_cast<u32>(reinterpret_cast<const std::size_t&>(mptr));
|
||||
return std::bit_cast<std::size_t>(mptr);
|
||||
#else
|
||||
static_assert(sizeof(mptr) == 0, "Invalid pointer-to-member size");
|
||||
static_assert(sizeof(mptr) == 0, "Unsupported pointer-to-member size");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -833,3 +895,34 @@ inline void busy_wait(std::size_t cycles = 3000)
|
||||
const u64 s = __rdtsc();
|
||||
do _mm_pause(); while (__rdtsc() - s < cycles);
|
||||
}
|
||||
|
||||
// TODO: Remove when moving to c++20
|
||||
template <typename T>
|
||||
inline constexpr uintmax_t floor2(T value)
|
||||
{
|
||||
value >>= 1;
|
||||
|
||||
for (uintmax_t i = 0;; i++, value >>= 1)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr uintmax_t ceil2(T value)
|
||||
{
|
||||
const uintmax_t ispow2 = value & (value - 1); // if power of 2 the result is 0
|
||||
|
||||
value >>= 1;
|
||||
|
||||
for (uintmax_t i = 0;; i++, value >>= 1)
|
||||
{
|
||||
if (value == 0)
|
||||
{
|
||||
return i + std::min<uintmax_t>(ispow2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "Skip installation" FORCE)
|
||||
set(ENABLE_SPVREMAPPER OFF CACHE BOOL "Enables building of SPVRemapper" FORCE)
|
||||
set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "Builds glslangValidator and spirv-remap" FORCE)
|
||||
set(ENABLE_OPT OFF CACHE BOOL "Enables spirv-opt capability if present" FORCE)
|
||||
set(ENABLE_HLSL OFF CACHE BOOL "Enables HLSL input support" FORCE)
|
||||
set(ENABLE_AMD_EXTENSIONS ON CACHE BOOL "Enables support of AMD-specific extensions" FORCE)
|
||||
set(ENABLE_NV_EXTENSIONS ON CACHE BOOL "Enables support of Nvidia-specific extensions" FORCE)
|
||||
add_subdirectory(glslang)
|
||||
|
||||
+1
-1
Submodule Vulkan/glslang updated: c99304c5dc...c11e3156af
@@ -13,18 +13,17 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8F85B6CC-250F-4ACA-A617-E820A74E3E3C}</ProjectGuid>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -37,26 +36,28 @@
|
||||
<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 Label="UserMacros" >
|
||||
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeBuildCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeReBuildCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeCleanCommandLine>cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
+13
-10
@@ -1,22 +1,23 @@
|
||||
|
||||
version: '{build}'
|
||||
|
||||
image: Visual Studio 2017
|
||||
image: Visual Studio 2019
|
||||
|
||||
environment:
|
||||
QTDIR: C:\Qt\5.11\msvc2017_64
|
||||
QTDIR: C:\Qt\5.13\msvc2017_64
|
||||
QT_URL: https://cdn.discordapp.com/attachments/442667232489897997/614126952953020416/msvc2017_64.7z
|
||||
LLVMLIBS: https://github.com/RPCS3/llvm/releases/download/continuous-master/llvmlibs.7z
|
||||
GLSLANG: https://drive.google.com/uc?export=download&id=1nJK_NEeRzJ_r_u4zWLySwLmMrV8ZO_wL
|
||||
GLSLANG: https://dl.dropboxusercontent.com/s/ku2qgwmtfptzbvx/glslang.7z
|
||||
COMPATDB: https://rpcs3.net/compatibility?api=v1&export
|
||||
VULKAN_SDK: "C:\\VulkanSDK\\1.1.73.0"
|
||||
VULKAN_SDK_URL: https://sdk.lunarg.com/sdk/download/1.1.73.0/windows/VulkanSDK-1.1.73.0-Installer.exe
|
||||
VULKAN_SDK_MIRROR: https://obk.ee/rpcs3/VulkanSDK-1.1.73.0-Installer.exe
|
||||
VULKAN_SDK_SHA: a5d193f97db4de97e6b4fdd81f00ff6a603f66bb17dc3cf8ac0fe9aec58497c7
|
||||
VULKAN_SDK: "C:\\VulkanSDK\\1.1.106.0"
|
||||
VULKAN_SDK_URL: https://sdk.lunarg.com/sdk/download/1.1.106.0/windows/VulkanSDK-1.1.106.0-Installer.exe
|
||||
VULKAN_SDK_SHA: 24b5c9d415912c0fb07f973f10f671a488b0e33ca991409bcabf1d4bebf0b804
|
||||
|
||||
cache:
|
||||
- glslang.7z -> appveyor.yml
|
||||
- compat_database.dat
|
||||
- vulkan-sdk.exe -> appveyor.yml
|
||||
- msvc2017_64.7z -> appveyor.yml
|
||||
|
||||
install:
|
||||
- ps: | # set env vars for versioning
|
||||
@@ -49,6 +50,7 @@ install:
|
||||
3rdparty/GSL `
|
||||
3rdparty/hidapi `
|
||||
3rdparty/libpng `
|
||||
3rdparty/libusb `
|
||||
3rdparty/pugixml `
|
||||
3rdparty/xxHash `
|
||||
3rdparty/yaml-cpp `
|
||||
@@ -68,14 +70,15 @@ build:
|
||||
before_build:
|
||||
- ps: | # initialize mirror arrays and fetch precompiled build dependencies
|
||||
$VULKAN_SDK_URLS = @(
|
||||
$env:VULKAN_SDK_MIRROR;
|
||||
$env:VULKAN_SDK_URL;
|
||||
"$($env:VULKAN_SDK_URL)?Human=true";
|
||||
)
|
||||
if (!(test-path llvmlibs.7z)) { irm $env:LLVMLIBS -outfile llvmlibs.7z }
|
||||
if (!(test-path glslang.7z)) { irm $env:GLSLANG -outfile glslang.7z }
|
||||
if (!(test-path msvc2017_64.7z)) { irm $env:QT_URL -outfile msvc2017_64.7z }
|
||||
7z x llvmlibs.7z -aos -o"." | out-null
|
||||
7z x glslang.7z -aos -o".\lib\$env:CONFIGURATION-$env:PLATFORM" | out-null
|
||||
7z x msvc2017_64.7z -aos -o"C:\Qt\5.13" | out-null
|
||||
if (!(test-path vulkan-sdk.exe))
|
||||
{
|
||||
foreach ($url in $VULKAN_SDK_URLS) {
|
||||
@@ -106,8 +109,8 @@ after_build:
|
||||
|
||||
- ps: | # package artifacts
|
||||
7z a -m0=LZMA2 -mx9 $env:BUILD .\bin\*
|
||||
7z a -m0=LZMA2 -mx9 openssl_win64.7z C:\OpenSSL-Win64\bin\libeay32.dll `
|
||||
C:\OpenSSL-Win64\bin\ssleay32.dll
|
||||
7z a -m0=LZMA2 -mx9 openssl_win64.7z C:\OpenSSL-v111-Win64\bin\libcrypto-1_1-x64.dll `
|
||||
C:\OpenSSL-v111-Win64\bin\libssl-1_1-x64.dll
|
||||
$env:FILESIZEMB = (Get-Item $env:BUILD).length/1MB
|
||||
|
||||
- ps: | # generate sha256 hashes
|
||||
|
||||
+1
-1
Submodule asmjit updated: 673dcefaa0...fc251c914e
@@ -87,13 +87,13 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{AC40FF01-426E-4838-A317-66354CEFAE88}</ProjectGuid>
|
||||
<RootNamespace>asmjit</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -0,0 +1,630 @@
|
||||
/*
|
||||
Envy theme for RPCS3 by drysalter (https://github.com/drysalter)
|
||||
03/04/2019
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Table of Main Colors:
|
||||
|
||||
Gray: #23262d
|
||||
Lighter Gray: #2d3038
|
||||
Disabled Gray: #4d5058
|
||||
ComboBox Gray: #999999
|
||||
GroupBox Gray: #bdc3c7
|
||||
White: #f8f8f8
|
||||
Green: #8cf944
|
||||
Lighter Green: #b1f184
|
||||
Candy Red: #ff007a
|
||||
Yellow: #f2d571
|
||||
Fuchsia: #ff00ff
|
||||
Orange: #ff6000
|
||||
Cyan: #3498d8
|
||||
|
||||
*/
|
||||
|
||||
/* Main Colouring */
|
||||
QWidget {
|
||||
background-color: #23262d;
|
||||
color: #f8f8f8;
|
||||
alternate-background-color: #23262d;
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
QToolTip {
|
||||
background-color: #2d3038;
|
||||
color: #8cf944;
|
||||
padding: 0.2em;
|
||||
border: 1px #2d3038;
|
||||
}
|
||||
|
||||
/* Table Headers */
|
||||
QHeaderView {
|
||||
border: none;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QHeaderView::section {
|
||||
background-color: #23262d;
|
||||
color: #f8f8f8;
|
||||
padding-top: 3px;
|
||||
padding-left: 3px;
|
||||
height: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QHeaderView::section:first {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
QTabBar::tab {
|
||||
color: #8cf944;
|
||||
padding-left: 1.25em;
|
||||
padding-right: 1.25em;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.75em;
|
||||
border: none;
|
||||
min-width: 65px;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
alignment: center;
|
||||
}
|
||||
|
||||
QTabBar::tab:!selected {
|
||||
color: #f8f8f8;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
color: #8cf944;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
color: #b1f184;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings {
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:!selected {
|
||||
color: #FFF;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:selected {
|
||||
color: #8cf944;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:hover {
|
||||
color: #b1f184;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
/* Log Tabs */
|
||||
QTabWidget#tab_widget_log::tab-bar {
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:!selected {
|
||||
color: #FFF;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:selected {
|
||||
color: #8cf944;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:hover {
|
||||
color: #b1f184;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 0.125em;
|
||||
border-top-right-radius: 0em;
|
||||
border-bottom-left-radius: 0em;
|
||||
border: 1px solid #FFF;
|
||||
width: 0.75em;
|
||||
height: 0.75em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #7fff03;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked:hover {
|
||||
border: 1px solid #7fff03;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:disabled {
|
||||
background-color: #4d5058;
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
QScrollBar {
|
||||
width: 5px;
|
||||
background: #23262d;
|
||||
}
|
||||
|
||||
QTableView QScrollBar {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
QScrollBar::handle {
|
||||
background: #4d5058;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:hover, QScrollBar::handle:pressed {
|
||||
background: #8cf944;
|
||||
}
|
||||
|
||||
QScrollBar::handle:disabled {
|
||||
background: #2d3038;
|
||||
}
|
||||
|
||||
QScrollBar::up-arrow, QScrollBar::down-arrow, QScrollBar::up-button:vertical, QScrollBar::down-button, QScrollBar::sub-line, QScrollBar::add-line, QScrollBar::add-page, QScrollBar::sub-page {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border: 0.0625em solid #FFF;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin-top: 0.0625em;
|
||||
border-radius: 0.45em;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:checked {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1, fx:1, fy:1, stop:0.25 #7fff03, stop:0.3 #000);
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked:hover {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1, fx:1, fy:1, stop:0.25 #b1f184, stop:0.3 #000);
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #4d5058;
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #23262d;
|
||||
color: #f8f8f8;
|
||||
border: 0.0625em solid #999999;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
QComboBox:hover {
|
||||
color: #8cf944;
|
||||
background-color: #2d3038;
|
||||
border: 0.0625em solid #8cf944;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
QComboBox::selected {
|
||||
background-color: #2d3038;
|
||||
color: #FFFFFF;
|
||||
border: 0.0625em solid #8cf944;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
QComboBox::!selected {
|
||||
background-color: #23262d;
|
||||
color: #FFFFFF;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
QComboBox:disabled {
|
||||
background-color: #4d5058;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Sliders */
|
||||
QSlider::groove:horizontal {
|
||||
border: -3px solid transparent;
|
||||
border-radius: 0.45em;
|
||||
height: 8px;
|
||||
background: #8cf944;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal:disabled {
|
||||
background: #4d5058;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #23262d;
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: #23262d;
|
||||
border: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:pressed {
|
||||
background: #30333a;
|
||||
border: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
QProgressBar {
|
||||
border: 0.05em solid #999999;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QProgressBar::chunk {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #b1f184, stop: 0.5 #99f75b, stop: 1 #8cf944);
|
||||
}
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 1em;
|
||||
font-size: 8pt;
|
||||
border: 0.05em solid #bdc3c7;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top;
|
||||
padding: 0.3em 0.5em 0.3em 0.5em;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #23262d, stop: 1 #23262d);
|
||||
border-width: 2px;
|
||||
border: 1px solid #f8f8f8;
|
||||
border-radius: 2px;
|
||||
padding: 2px;
|
||||
color: #f8f8f8;
|
||||
min-width: 82px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #23262d, stop: 1 #23262d);
|
||||
border-width: 2px;
|
||||
border: 1px solid #8cf944;
|
||||
padding: 2px;
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d3038, stop: 1 #2d3038);
|
||||
}
|
||||
|
||||
/* Spinboxes */
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
border: 1px solid #999999;
|
||||
padding: 2px;
|
||||
color: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:hover, QDoubleSpinBox:hover {
|
||||
background-color: transparent;
|
||||
border: 1px solid #8cf944;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:disabled, QDoubleSpinBox:disabled {
|
||||
border: 1px solid #4d5058;
|
||||
color: #4d5058;
|
||||
}
|
||||
|
||||
|
||||
/* Log and Debugger Borders */
|
||||
QTextEdit {
|
||||
border-top: 0.05em solid #8cf944;
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
border: 1px solid #f8f8f8;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
border: 1px solid #8cf944;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* Title Bar Docks */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background-color: #23262d;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
QDockWidget#logger {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
QDockWidget#gamelist {
|
||||
color: #f8f8f8;
|
||||
}
|
||||
|
||||
/* Top Menu Bar */
|
||||
QMenuBar::item:selected {
|
||||
margin-bottom: 0.125em;
|
||||
color: #8cf944;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QMenuBar::item:!selected {
|
||||
border-bottom: 2px solid transparent;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
QMenuBar::item:pressed {
|
||||
color: #8cf944;
|
||||
background: #2d3038;
|
||||
margin-bottom: 0.125em;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
margin-bottom: 0.125em;
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background: #2d3038;
|
||||
color: #8cf944;
|
||||
border-left: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
background-color: #23262d;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Libraries List */
|
||||
QListWidget {
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
QListWidget:disabled {
|
||||
border: 1px solid #4d5058;
|
||||
}
|
||||
|
||||
QListWidget::item:selected {
|
||||
background-color: #30333a;
|
||||
color: #b1f184;
|
||||
border-radius: 0.125em;
|
||||
}
|
||||
|
||||
QListWidget::item:hover {
|
||||
background-color: #30333a;
|
||||
color: #8cf944;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
QListWidget::indicator {
|
||||
border: 1px solid #f8f8f8;
|
||||
background: #000000;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QListWidget::indicator:checked {
|
||||
background: #8cf944;
|
||||
}
|
||||
|
||||
QListWidget::indicator:hover {
|
||||
border: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
QListWidget::indicator:disabled {
|
||||
background: transparent;
|
||||
border: 1px solid #1b1e23;
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
/* Slider on Toolbar */
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::groove:horizontal {
|
||||
border: 0em solid transparent;
|
||||
height: .3em;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::handle:horizontal {
|
||||
width: 1em;
|
||||
margin: -.8em 0;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Seachbar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #ecf0f1;
|
||||
background-color: #2d3038;
|
||||
border: 1px solid #f8f8f8;
|
||||
margin: 15px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
color: #ecf0f1;
|
||||
background-color: #2d3038;
|
||||
border: 1px solid #8cf944;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
QToolBar {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Toolbar Buttons */
|
||||
QLabel#toolbar_icon_color {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
background: transparent;
|
||||
border-radius: 0em;
|
||||
padding: 0.09375em;
|
||||
margin-left: 0.125em;
|
||||
margin-top: 0.125em;
|
||||
margin-bottom: 0.125em;
|
||||
min-width: 0.063em;
|
||||
width: auto;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QToolButton:disabled {
|
||||
background-color: #30333a;
|
||||
color: #f8f8f8;
|
||||
}
|
||||
|
||||
QToolButton:hover {
|
||||
background-color: #2d3038;
|
||||
color: #8cf944;
|
||||
border-bottom: 1px solid #8cf944;
|
||||
}
|
||||
|
||||
/* Game Table */
|
||||
QTableView {
|
||||
selection-background-color: #2d3038;
|
||||
selection-color: #8cf944;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTableView::item:hover {
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
/* Game Icon Background */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #23262d;
|
||||
}
|
||||
|
||||
/* Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #23262d;
|
||||
}
|
||||
|
||||
QLabel#log_level_always {
|
||||
color: #f8f8f8;
|
||||
}
|
||||
|
||||
QLabel#log_level_fatal {
|
||||
color: #ff00ff;
|
||||
}
|
||||
|
||||
QLabel#log_level_error {
|
||||
color: #ff007a;
|
||||
}
|
||||
|
||||
QLabel#log_level_todo {
|
||||
color: #f2d571;
|
||||
}
|
||||
|
||||
QLabel#log_level_success {
|
||||
color: #8cf944;
|
||||
}
|
||||
|
||||
QLabel#log_level_warning {
|
||||
color: #ff6000;
|
||||
}
|
||||
|
||||
QLabel#log_level_notice {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QLabel#log_level_trace {
|
||||
color: #2d3038;
|
||||
}
|
||||
|
||||
QLabel#log_stack {
|
||||
color: #3498d8;
|
||||
}
|
||||
|
||||
/* TTY colors */
|
||||
QTextEdit#tty_frame {
|
||||
background-color: #23262d;
|
||||
}
|
||||
|
||||
QLabel#tty_text {
|
||||
color: #f8f8f8;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
Skyline (Nightfall) theme for RPCS3 by drysalter (https://github.com/drysalter)
|
||||
04/04/2019
|
||||
*/
|
||||
|
||||
/* Color Palette:
|
||||
|
||||
Banner Purple: #370048
|
||||
Banner Blue: #161249
|
||||
Banner Dusk Blue: #00364a
|
||||
Background Gray: #111525
|
||||
Gray: #455971
|
||||
Highlight-blue: #0074e7
|
||||
Light blue: #359aff
|
||||
Button-blue: #0071ec
|
||||
Fatal-error red: #b23345
|
||||
Warning-orange: #e49000
|
||||
Todo-orange: #fbb81b
|
||||
Disable-gray: #999999 & #26293b
|
||||
|
||||
*/
|
||||
|
||||
/* Widget Colors */
|
||||
QWidget {
|
||||
background-color: #111525;
|
||||
color: #FFFFFF;
|
||||
alternate-background-color: #1c273d;
|
||||
}
|
||||
|
||||
/* Top Menu Bar */
|
||||
QMenuBar {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #370048, stop: 0.5 #161249, stop: 1 #00364a);
|
||||
color: #FFFFFF;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
QMenuBar::item:selected {
|
||||
border-bottom: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
QMenuBar::item:!selected {
|
||||
border-bottom: 2px solid transparent;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
QMenuBar::item:pressed {
|
||||
color: #FFFFFF;
|
||||
background: #111525;
|
||||
border-bottom: 2px solid #111525;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
margin-bottom: 0.125em;
|
||||
border-left: 2px solid #111525;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background: #1c273d;
|
||||
color: #0074e7;
|
||||
border-left: 2px solid #0074e7;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
background-color: #111525;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
QToolBar {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #370048, stop: 0.5 #161249, stop: 1 #00364a);
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Toolbar Buttons */
|
||||
QLabel#toolbar_icon_color {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
color: #FFFFFF;
|
||||
background: transparent;
|
||||
border-radius: 0em;
|
||||
padding: 0.09375em;
|
||||
margin-left: 0.125em;
|
||||
margin-top: 0.125em;
|
||||
margin-bottom: 0.125em;
|
||||
min-width: 0.063em;
|
||||
width: auto;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
|
||||
QToolButton:disabled {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
QToolButton:hover {
|
||||
border-bottom: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
/* Searchbar in Main Toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #999999;
|
||||
margin: 15px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
color: #0074e7;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #0071ec;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
|
||||
/* Sliders */
|
||||
QSlider {
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: -3px solid transparent;
|
||||
border-radius: 0.45em;
|
||||
height: 8px;
|
||||
background: #0074e7;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal:disabled {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #51657e, stop:1 #455971);
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #111525;
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: #111525;
|
||||
border: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:pressed {
|
||||
border: 1px solid #0074e7;
|
||||
background: #1c273d;
|
||||
}
|
||||
|
||||
/* Slider on Toolbar */
|
||||
QToolBar#mw_toolbar QSlider {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::groove:horizontal {
|
||||
border: 0em transparent;
|
||||
height: .3em;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::handle:horizontal {
|
||||
width: 1em;
|
||||
margin: -.8em 0;
|
||||
border: 1px solid #161249;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::handle:hover {
|
||||
border: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
QScrollBar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
QTableView QScrollBar {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
QScrollBar::handle {
|
||||
background: #455971;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
QScrollBar::handle:hover, QScrollBar::handle:pressed {
|
||||
background: #0074e7;
|
||||
}
|
||||
|
||||
QScrollBar::handle:disabled {
|
||||
background: #26293b;
|
||||
}
|
||||
|
||||
QTableView QScrollBar::handle {
|
||||
background: #1c273d;
|
||||
}
|
||||
|
||||
QScrollBar::up-arrow, QScrollBar::down-arrow, QScrollBar::up-button:vertical, QScrollBar::down-button, QScrollBar::sub-line, QScrollBar::add-line, QScrollBar::add-page, QScrollBar::sub-page {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border: 0.0625em solid #455971;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin-top: 0.0625em;
|
||||
border-radius: 0.45em;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:checked {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1, fx:1, fy:1, stop:0.25 #0074e7, stop:0.3 #FFFFFF);
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:checked:hover {
|
||||
border: 0.0625em solid #0074e7;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #455971;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border: 1px solid #455971;
|
||||
border-radius: 2px;
|
||||
width: 0.75em;
|
||||
height: 0.75em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #008be7, stop:1 #0074e7);
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked:hover {
|
||||
border: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked:hover {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #3ca3e7, stop:1 #2a89e7);
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:disabled {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #51657e, stop:1 #455971);
|
||||
}
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 1em;
|
||||
font-size: 8pt;
|
||||
border: 0.05em solid #FFFFFF;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top;
|
||||
padding: 0.3em 0.5em 0.3em 0.5em;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
|
||||
/* Tabs */
|
||||
QTabBar::tab {
|
||||
color: #455971;
|
||||
padding-left: 1.25em;
|
||||
padding-right: 1.25em;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.75em;
|
||||
border: none;
|
||||
min-width: 65px;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
alignment: center;
|
||||
}
|
||||
|
||||
QTabBar::tab:!selected {
|
||||
color: #FFFFFF;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
color: #0074e7;
|
||||
border-bottom: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
color: #0074e7;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings {
|
||||
border-bottom: 1px solid #0074e7;
|
||||
width: 5.20em;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:!selected {
|
||||
color: #FFFFFF;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:selected {
|
||||
color: #0074e7;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:hover {
|
||||
color: #177fe7;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
/* Log Tabs */
|
||||
QTabWidget#tab_widget_log::tab-bar {
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:!selected {
|
||||
color: #FFFFFF;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:selected, QTabBar#tab_bar_log::tab:hover {
|
||||
color: #0074e7;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #1c273d;
|
||||
color: #FFFFFF;
|
||||
border: 0.0625em solid #455971;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
QComboBox:hover {
|
||||
color: #FFFFFF;
|
||||
background-color: #1c273d;
|
||||
border: 0.0625em solid #0074e7;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
QComboBox::item:selected {
|
||||
color: #FFFFFF;
|
||||
background-color: #1c273d;
|
||||
border: 0.0625em solid #0074e7;
|
||||
border-radius: 0.10em;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QComboBox::item:!selected {
|
||||
color: #FFFFFF;
|
||||
background-color: #111525;
|
||||
border: 0.0625em solid #0074e7;
|
||||
border-radius: 0.10em;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
QComboBox::indicator{
|
||||
background-color: transparent;
|
||||
selection-background-color: transparent;
|
||||
color: transparent;
|
||||
selection-color: transparent;
|
||||
}
|
||||
|
||||
QComboBox::selected {
|
||||
background-color: #1c273d;
|
||||
color: #FFFFFF;
|
||||
border: 0.0625em solid #0074e7;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
}
|
||||
|
||||
QComboBox:disabled {
|
||||
background-color: #26293b;
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
border: 1px solid #455971;
|
||||
padding: 2px;
|
||||
color: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
background-color: #1c273d;
|
||||
min-width: 82px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: #1c273d;
|
||||
border: 1px solid #0074e7;
|
||||
padding: 2px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: #121d34;
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
border: 1px solid #999999;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Spinboxes */
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
border: 1px solid #455971;
|
||||
padding: 2px;
|
||||
color: #FFFFFF;
|
||||
border-radius: 2px;
|
||||
background-color: #1c273d;
|
||||
}
|
||||
|
||||
QSpinBox:hover, QDoubleSpinBox:hover {
|
||||
background-color: #1c273d;
|
||||
border: 1px solid #0074e7;
|
||||
padding: 2px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:disabled, QDoubleSpinBox:disabled {
|
||||
color: #455971;
|
||||
background: #26293b;
|
||||
border: 1px solid #455971;
|
||||
}
|
||||
|
||||
/* Libraries List */
|
||||
QListWidget {
|
||||
border: 1px solid #FFFFFF;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
QListWidget:disabled {
|
||||
border: 1px solid #455971;
|
||||
}
|
||||
|
||||
QListWidget::item:selected {
|
||||
background-color: #1c273d;
|
||||
color: #0074e7;
|
||||
border-radius: 0.125em;
|
||||
}
|
||||
|
||||
QListWidget::item:hover {
|
||||
background-color: #1c273d;
|
||||
}
|
||||
|
||||
QListWidget:disabled, QListWidget:disabled:hover, QListWidget::item:disabled:hover {
|
||||
background-color: #111525;
|
||||
color: #FFFFFF;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
QListWidget::item:disabled {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Title Bar Docking Buttons */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QDockWidget::title#gamelist {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #370048, stop: 0.5 #161249, stop: 1 #00364a);
|
||||
}
|
||||
|
||||
QDockWidget#gamelist {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Game Table */
|
||||
QTableView {
|
||||
selection-background-color: #0f1d36;
|
||||
selection-color: #2397ff;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QTableView::item:hover {
|
||||
color: #2397ff;
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
QProgressBar {
|
||||
border: 1px solid #455971;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QProgressBar::chunk {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #370048, stop: 0.5 #161249, stop: 1 #00364a);
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #0074e7;
|
||||
}
|
||||
|
||||
/* Game Icon Background */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
/* Table Headers */
|
||||
QHeaderView {
|
||||
border: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #370048, stop: 0.5 #161249, stop: 1 #00364a);
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
QHeaderView::section {
|
||||
background-color: #111525;
|
||||
color: #FFFFFF;
|
||||
padding-top: 3px;
|
||||
padding-left: 3px;
|
||||
height: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QHeaderView::section:first {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
QToolTip {
|
||||
background-color: #111525;
|
||||
color: #FFFFFF;
|
||||
padding: 0.1em;
|
||||
border: none;
|
||||
opacity: 225;
|
||||
}
|
||||
|
||||
/* Log and Debugger Borders */
|
||||
QDockWidget::title#logger {
|
||||
background: #111525;
|
||||
}
|
||||
|
||||
QDockWidget#logger {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
QTextEdit {
|
||||
border-top: 1px solid #0074e7;
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
border: 1px solid #455971;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
border: 1px solid #0074e7;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #111525;
|
||||
}
|
||||
|
||||
QLabel#log_level_always {
|
||||
color: #0074e7;
|
||||
}
|
||||
|
||||
QLabel#log_level_fatal {
|
||||
color: #b23345;
|
||||
}
|
||||
|
||||
QLabel#log_level_error {
|
||||
color: #e85545;
|
||||
}
|
||||
|
||||
QLabel#log_level_todo {
|
||||
color: #fbb81b;
|
||||
}
|
||||
|
||||
QLabel#log_level_success {
|
||||
color: #07c365;
|
||||
}
|
||||
|
||||
QLabel#log_level_warning {
|
||||
color: #e49000;
|
||||
}
|
||||
|
||||
QLabel#log_level_notice {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QLabel#log_level_trace {
|
||||
color: #00364a;
|
||||
}
|
||||
|
||||
QLabel#log_stack {
|
||||
color: #0071ec;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #370048;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,675 @@
|
||||
/*
|
||||
Skyline theme for RPCS3 by drysalter (https://github.com/drysalter)
|
||||
04/04/2019
|
||||
*/
|
||||
|
||||
/* Color Palette:
|
||||
|
||||
Purple: #8500ae
|
||||
Pink Highlight: #f8edfb
|
||||
Blue: #4343c1
|
||||
Light Blue: #009ed0
|
||||
Gray: #455971
|
||||
Toolbar-blue: #4c5ad6
|
||||
Border-blue: #359aff
|
||||
Button-blue: #0071ec
|
||||
Fatal-error red: #b23345
|
||||
Warning-orange: #e49000
|
||||
Todo-orange: #fbb81b
|
||||
Disable-gray: #999999 & #b3b3b3
|
||||
|
||||
*/
|
||||
|
||||
/* Widget Colors */
|
||||
QWidget {
|
||||
background-color: #FFFFFF;
|
||||
color: #455971;
|
||||
alternate-background-color: #f8edfb;
|
||||
}
|
||||
|
||||
/* Top Menu Bar */
|
||||
QMenuBar {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
color: #FFFFFF;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
QMenuBar::item:selected {
|
||||
border-bottom: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
QMenuBar::item:!selected {
|
||||
border-bottom: 2px solid transparent;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
QMenuBar::item:pressed {
|
||||
color: #455971;
|
||||
background: #FFFFFF;
|
||||
border-bottom: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
margin-bottom: 0.125em;
|
||||
border-left: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background: #f8edfb;
|
||||
color: #455971;
|
||||
border-left: 2px solid #8500ae;
|
||||
}
|
||||
|
||||
QMenu::item:disabled {
|
||||
background-color: #FFFFFF;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
QToolBar {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Toolbar Buttons */
|
||||
QLabel#toolbar_icon_color {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
color: #FFFFFF;
|
||||
background: transparent;
|
||||
border-radius: 0em;
|
||||
padding: 0.09375em;
|
||||
margin-left: 0.125em;
|
||||
margin-top: 0.125em;
|
||||
margin-bottom: 0.125em;
|
||||
min-width: 0.063em;
|
||||
width: auto;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
|
||||
QToolButton:disabled {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
QToolButton:hover {
|
||||
border-bottom: 2px solid #FFFFFF;
|
||||
}
|
||||
|
||||
/* Searchbar in Main Toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #999999;
|
||||
margin: 15px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:hover {
|
||||
margin-left: 0.7em;
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #0071ec;
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
QLineEdit#mw_searchbar:focus {
|
||||
border: 1px solid #0071ec;
|
||||
}
|
||||
|
||||
|
||||
/* Sliders */
|
||||
QSlider {
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: -3px solid transparent;
|
||||
border-radius: 0.45em;
|
||||
height: 8px;
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal:disabled {
|
||||
background: #b3b3b3;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #5c5c5c;
|
||||
border-radius: 0.1em;
|
||||
width: 18px;
|
||||
margin: -2px 2;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:disabled {
|
||||
border: 1px solid #b3b3b3;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:pressed {
|
||||
background: #f8edfb;
|
||||
border: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
/* Slider on Toolbar */
|
||||
QToolBar#mw_toolbar QSlider {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::groove:horizontal {
|
||||
border: 0em transparent;
|
||||
height: .3em;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::handle:horizontal {
|
||||
width: 1em;
|
||||
margin: -.8em 0;
|
||||
border: 1px solid #4343c1;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
QSlider#sizeSlider::handle:hover {
|
||||
border: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
/* Scrollbars */
|
||||
QScrollBar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
QScrollArea {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QTableView QScrollBar {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
QScrollBar::handle {
|
||||
background: #999999;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
QTableView QScrollBar::handle {
|
||||
background: #999999;
|
||||
}
|
||||
|
||||
QScrollBar::handle:hover, QScrollBar::handle:pressed {
|
||||
background: #8500ae;
|
||||
}
|
||||
|
||||
QTableView QScrollBar::handle:hover, QTableView QScrollBar::handle:pressed {
|
||||
background: #4343c1;
|
||||
}
|
||||
|
||||
QScrollBar::handle:disabled {
|
||||
background: #b3b3b3;
|
||||
}
|
||||
|
||||
QScrollBar::up-arrow, QScrollBar::down-arrow, QScrollBar::up-button:vertical, QScrollBar::down-button, QScrollBar::sub-line, QScrollBar::add-line, QScrollBar::add-page, QScrollBar::sub-page {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border: 0.0625em solid #455971;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin-top: 0.0625em;
|
||||
border-radius: 0.45em;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:checked {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1, fx:1, fy:1, stop:0.25 #b345d9, stop:0.3 #FFFFFF);
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:checked:hover {
|
||||
border: 0.0625em solid #8500ae;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QRadioButton::indicator:disabled {
|
||||
background-color: #455971;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border: 1px solid #455971;
|
||||
border-radius: 2px;
|
||||
width: 0.75em;
|
||||
height: 0.75em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #c500ff, stop:1 #8500ae);
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked:hover {
|
||||
border: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked:hover {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #da5eff, stop:1 #974cae);
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked:disabled {
|
||||
background-color: qradialgradient(cx:0, cy:0, radius: 1, fx:0.3, fy:0.3, stop:0.8 #b3b3b3, stop:1 #9d9d9d);
|
||||
}
|
||||
|
||||
QCheckBox::indicator:unchecked:disabled {
|
||||
border: 1px solid #b3b3b3;
|
||||
}
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 1em;
|
||||
font-size: 8pt;
|
||||
border: 0.05em solid #455971;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top;
|
||||
padding: 0.3em 0.5em 0.3em 0.5em;
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
|
||||
/* Tabs */
|
||||
QTabBar::tab {
|
||||
color: #455971;
|
||||
padding-left: 1.25em;
|
||||
padding-right: 1.25em;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.75em;
|
||||
border: none;
|
||||
min-width: 65px;
|
||||
border-bottom: 1px solid #455971;
|
||||
}
|
||||
|
||||
QTabWidget::pane {
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
alignment: center;
|
||||
}
|
||||
|
||||
QTabBar::tab:!selected {
|
||||
color: #455971;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
color: #8500ae;
|
||||
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border-bottom: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
QTabBar::tab:hover {
|
||||
color: #8500ae;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings {
|
||||
border-bottom: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
width: 5.20em;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:!selected {
|
||||
color: #455971;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_settings::tab:selected, QTabBar#tab_bar_settings::tab:hover {
|
||||
color: #8500ae;
|
||||
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border-bottom: 1px solid #8500ae;
|
||||
}
|
||||
|
||||
/* Log Tabs */
|
||||
QTabWidget#tab_widget_log::tab-bar {
|
||||
alignment: left;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:!selected {
|
||||
color: #956fa1;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:selected {
|
||||
color: #4343c1;
|
||||
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTabBar#tab_bar_log::tab:hover {
|
||||
color: #8500ae;
|
||||
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #FFFFFF;
|
||||
color: #455971;
|
||||
border: 0.0625em solid #455971;
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
QComboBox:hover {
|
||||
color: #455971;
|
||||
background-color: #FFFFFF;
|
||||
border: 0.0625em solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
QComboBox::item:selected {
|
||||
color: #000000;
|
||||
background-color: #f8edfb;
|
||||
border: 0.0625em solid #455971;
|
||||
border-radius: 0.10em;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
QComboBox::item:!selected {
|
||||
color: #000000;
|
||||
background-color: #FFFFFF;
|
||||
border: 0.0625em solid #455971;
|
||||
border-radius: 0.10em;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
QComboBox::indicator {
|
||||
background-color: transparent;
|
||||
selection-background-color: transparent;
|
||||
color: transparent;
|
||||
selection-color: transparent;
|
||||
}
|
||||
|
||||
QComboBox::selected {
|
||||
background-color: #FFFFFF;
|
||||
color: #455971;
|
||||
border: 0.0625em solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
border-radius: 0.10em;
|
||||
padding-bottom: 0.125em;
|
||||
}
|
||||
|
||||
QComboBox:disabled {
|
||||
background-color: #b3b3b3;
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
border: 1px solid #455971;
|
||||
padding: 2px;
|
||||
color: #455971;
|
||||
border-radius: 2px;
|
||||
background-color: #FFFFFF;
|
||||
text-align: center;
|
||||
min-width: 82px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0, stop: 0.2 #FFF3FF, stop: 1 #FFFFFF);
|
||||
border: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
padding: 2px;
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
QPushButton::pressed {
|
||||
background-color: #f8edfb;
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
border: 1px solid #b3b3b3;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
/* Spinboxes */
|
||||
QSpinBox, QDoubleSpinBox {
|
||||
border: 1px solid #455971;
|
||||
padding: 2px;
|
||||
color: #455971;
|
||||
border-radius: 2px;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QSpinBox:hover, QDoubleSpinBox:hover {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
padding: 2px;
|
||||
color: #455971;
|
||||
}
|
||||
|
||||
QSpinBox::up-button, QSpinBox::down-button, QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QSpinBox:disabled, QDoubleSpinBox:disabled {
|
||||
background-color: #b3b3b3;
|
||||
color: #455971;
|
||||
border: 1px solid #455971;
|
||||
}
|
||||
|
||||
/* Libraries List */
|
||||
QListWidget {
|
||||
border: 1px solid #455971;
|
||||
border-radius: 0.1em;
|
||||
}
|
||||
|
||||
QListWidget:disabled, QListWidget:disabled:hover, QListWidget::item:disabled:hover {
|
||||
border: 1px solid #999999;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
QListWidget::item:selected {
|
||||
background-color: #FFFFFF;
|
||||
color: #4343c1;
|
||||
border-radius: 0.125em;
|
||||
}
|
||||
|
||||
QListWidget::item:hover {
|
||||
background-color: #FFFFFF;
|
||||
color: #8500ae;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
QListWidget::item:disabled {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* Title Bar & Docking Buttons */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QDockWidget::title#gamelist {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
}
|
||||
|
||||
QDockWidget#gamelist {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* Game Table */
|
||||
QTableView {
|
||||
selection-background-color: #4343c1;
|
||||
selection-color: #FFFFFF;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QTableView::item:hover {
|
||||
color: #4343c1;
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
QProgressBar {
|
||||
border: 1px solid #455971;
|
||||
border-radius: 3px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QProgressBar::chunk {
|
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #4343c1;
|
||||
}
|
||||
|
||||
/* Game Icon Background */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
/* Table Headers */
|
||||
QHeaderView {
|
||||
border: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
QHeaderView::section {
|
||||
background-color: #FFFFFF;
|
||||
color: #455971;
|
||||
padding-top: 3px;
|
||||
padding-left: 3px;
|
||||
height: 20px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QHeaderView::section:first {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
QToolTip {
|
||||
background-color: #FFFFFF;
|
||||
color: #8500ae;
|
||||
padding: 0.1em;
|
||||
border: none;
|
||||
opacity: 225;
|
||||
}
|
||||
|
||||
/* Log and Debugger Borders */
|
||||
QDockWidget::title#logger {
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
QDockWidget#logger {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
QTextEdit {
|
||||
border-top: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
}
|
||||
|
||||
QLineEdit {
|
||||
border: 1px solid #455971;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
border: 1px solid qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.25 #8500ae, stop: 0.5 #4343c1, stop: 1 #009ed0);
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
/* Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
QLabel#log_level_always {
|
||||
color: #8500ae;
|
||||
}
|
||||
|
||||
QLabel#log_level_fatal {
|
||||
color: #b23345;
|
||||
}
|
||||
|
||||
QLabel#log_level_error {
|
||||
color: #e85545;
|
||||
}
|
||||
|
||||
QLabel#log_level_todo {
|
||||
color: #fbb81b;
|
||||
}
|
||||
|
||||
QLabel#log_level_success {
|
||||
color: #07c365;
|
||||
}
|
||||
|
||||
QLabel#log_level_warning {
|
||||
color: #e49000;
|
||||
}
|
||||
|
||||
QLabel#log_level_notice {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
QLabel#log_level_trace {
|
||||
color: #009ed0;
|
||||
}
|
||||
|
||||
QLabel#log_stack {
|
||||
color: #0071ec;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #8500ae;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ aea993
|
||||
|
||||
/* Every widget */
|
||||
QWidget {
|
||||
font-family: SCE-PS3 Rodin LATIN, Arial;
|
||||
font-family: SCE-PS3 Rodin LATIN;
|
||||
font-size: 9.00pt;
|
||||
|
||||
color: #292929;
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
<?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 without macros. Import right before Microsoft.Cpp.Default.props -->
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?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" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolSet>$(DefaultPlatformToolset)</PlatformToolSet>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
||||
+1
-1
Submodule llvm updated: 5c906fd169...b860b5e8f4
@@ -14,16 +14,16 @@
|
||||
<ProjectGuid>{8BC303AB-25BE-4276-8E57-73F171B2D672}</ProjectGuid>
|
||||
<Keyword>MakeFileProj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -34,35 +34,37 @@
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Label="UserMacros" >
|
||||
<CmakeGenerator>"Visual Studio $(VisualStudioVersion.Substring(0,2))"</CmakeGenerator>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakePreprocessorDefinitions>
|
||||
</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakePreprocessorDefinitions />
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -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 -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -64,16 +64,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3", "rpcs3\rpcs3.vcxpro
|
||||
{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078} = {FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}
|
||||
{FDC361C5-7734-493B-8CFB-037308B35122} = {FDC361C5-7734-493B-8CFB-037308B35122}
|
||||
{8F85B6CC-250F-4ACA-A617-E820A74E3E3C} = {8F85B6CC-250F-4ACA-A617-E820A74E3E3C}
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {349EE8F9-7D25-4909-AAF5-FF3FADE72187}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hidapi", "hidapi", "{FA1E6C16-CA63-45F8-8D52-E21DF396BE36}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "3rdparty\hidapi\windows\hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hidapi", "3rdparty\hidapi.vcxproj", "{A107C21C-418A-4697-BB10-20C3AA60E2E4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "xxhash", "xxhash", "{D16E245C-CC5A-4B9A-8BAB-1176F02C1631}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxhash", "3rdparty\xxhash.vcxproj", "{939FE206-1182-ABC3-1234-FEAB88E98404}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libusb", "libusb", "{6D8E86F7-84A0-45BA-ACC3-F02FC5545B3B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "3rdparty\libusb_static.vcxproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug - LLVM|x64 = Debug - LLVM|x64
|
||||
@@ -232,6 +237,16 @@ Global
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404}.Release - LLVM|x64.Build.0 = Release|x64
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404}.Release|x64.ActiveCfg = Release|x64
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404}.Release|x64.Build.0 = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug - LLVM|x64.ActiveCfg = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug - LLVM|x64.Build.0 = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug - MemLeak|x64.Build.0 = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release - LLVM|x64.ActiveCfg = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release - LLVM|x64.Build.0 = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -252,6 +267,7 @@ Global
|
||||
{FDC361C5-7734-493B-8CFB-037308B35122} = {DDF904CA-2771-441A-8629-5DF2EB922A79}
|
||||
{A107C21C-418A-4697-BB10-20C3AA60E2E4} = {FA1E6C16-CA63-45F8-8D52-E21DF396BE36}
|
||||
{939FE206-1182-ABC3-1234-FEAB88E98404} = {D16E245C-CC5A-4B9A-8BAB-1176F02C1631}
|
||||
{349EE8F9-7D25-4909-AAF5-FF3FADE72187} = {6D8E86F7-84A0-45BA-ACC3-F02FC5545B3B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {06CC7920-E085-4B81-9582-8DE8AAD42510}
|
||||
|
||||
+24
-14
@@ -1,11 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.8.2)
|
||||
cmake_minimum_required(VERSION 3.8.2)
|
||||
|
||||
include(cotire)
|
||||
|
||||
# Generate git-version.h at build time.
|
||||
add_custom_target(GitVersion ALL
|
||||
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/git-version.cmake)
|
||||
|
||||
# Check for a sufficient compiler and set build options
|
||||
include(ConfigureCompiler)
|
||||
@@ -37,31 +35,43 @@ include(${CMAKE_SOURCE_DIR}/3rdparty/qt5.cmake)
|
||||
add_subdirectory(Emu)
|
||||
add_subdirectory(rpcs3qt)
|
||||
|
||||
file(GLOB RPCS3_SRC "*.cpp")
|
||||
set(RPCS3_SRC
|
||||
basic_keyboard_handler.cpp
|
||||
basic_mouse_handler.cpp
|
||||
ds3_pad_handler.cpp
|
||||
ds4_pad_handler.cpp
|
||||
evdev_joystick_handler.cpp
|
||||
headless_application.cpp
|
||||
keyboard_pad_handler.cpp
|
||||
main.cpp
|
||||
main_application.cpp
|
||||
mm_joystick_handler.cpp
|
||||
pad_thread.cpp
|
||||
rpcs3_version.cpp
|
||||
stb_image.cpp
|
||||
stdafx.cpp
|
||||
xinput_pad_handler.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
add_executable(rpcs3 WIN32 ${RPCS3_SRC})
|
||||
elseif(APPLE)
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME rpcs3)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.rpcs3.rpcs3")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "Open-source Sony PlayStation 3 emulator")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "rpcs3.icns")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "0.0.5")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "0.0.5")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "0.0.5")
|
||||
add_executable(rpcs3 MACOSX_BUNDLE ${RPCS3_SRC} "${RPCS3_SRC_DIR}/rpcs3.icns")
|
||||
set_target_properties(rpcs3
|
||||
PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST "${RPCS3_SRC_DIR}/rpcs3.plist.in")
|
||||
else()
|
||||
add_executable(rpcs3 ${RPCS3_SRC})
|
||||
endif()
|
||||
|
||||
add_dependencies(rpcs3 GitVersion)
|
||||
gen_git_version(${RPCS3_SRC_DIR})
|
||||
set_target_properties(rpcs3
|
||||
PROPERTIES
|
||||
AUTOMOC ON
|
||||
AUTOUIC ON)
|
||||
|
||||
target_link_libraries(rpcs3 rpcs3_emu rpcs3_ui)
|
||||
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi)
|
||||
target_link_libraries(rpcs3 3rdparty::discord-rpc 3rdparty::qt5 3rdparty::hidapi 3rdparty::libusb)
|
||||
target_link_libraries(rpcs3 ${ADDITIONAL_LIBS})
|
||||
|
||||
# Win resource file
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "aes.h"
|
||||
#include "aesni.h"
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
@@ -458,6 +459,9 @@ int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int key
|
||||
|
||||
ctx->rk = RK = ctx->buf;
|
||||
|
||||
if( aesni_supports( POLARSSL_AESNI_AES ) )
|
||||
return( aesni_setkey_enc( (unsigned char *) ctx->rk, key, keysize ) );
|
||||
|
||||
for( i = 0; i < (keysize >> 5); i++ )
|
||||
{
|
||||
GET_UINT32_LE( RK[i], key, i << 2 );
|
||||
@@ -558,6 +562,13 @@ int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int key
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
if( aesni_supports( POLARSSL_AESNI_AES ) )
|
||||
{
|
||||
aesni_inverse_key( (unsigned char *) ctx->rk,
|
||||
(const unsigned char *) cty.rk, ctx->nr );
|
||||
goto done;
|
||||
}
|
||||
|
||||
SK = cty.rk + cty.nr * 4;
|
||||
|
||||
*RK++ = *SK++;
|
||||
@@ -581,6 +592,7 @@ int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int key
|
||||
*RK++ = *SK++;
|
||||
*RK++ = *SK++;
|
||||
|
||||
done:
|
||||
memset( &cty, 0, sizeof( aes_context ) );
|
||||
|
||||
return( 0 );
|
||||
@@ -643,6 +655,9 @@ int aes_crypt_ecb( aes_context *ctx,
|
||||
int i;
|
||||
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
|
||||
|
||||
if( aesni_supports( POLARSSL_AESNI_AES ) )
|
||||
return( aesni_crypt_ecb( ctx, mode, input, output ) );
|
||||
|
||||
RK = ctx->rk;
|
||||
|
||||
GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
|
||||
|
||||
@@ -0,0 +1,682 @@
|
||||
/*
|
||||
* AES-NI support functions
|
||||
*
|
||||
* Copyright (C) 2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
|
||||
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
|
||||
*/
|
||||
|
||||
#include "aesni.h"
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
#define POLARSSL_HAVE_MSVC_X64_INTRINSICS
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* AES-NI support detection routine
|
||||
*/
|
||||
int aesni_supports( unsigned int what )
|
||||
{
|
||||
static int done = 0;
|
||||
static unsigned int c = 0;
|
||||
|
||||
if( ! done )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
int regs[4]; // eax, ebx, ecx, edx
|
||||
__cpuid( regs, 1 );
|
||||
c = regs[2];
|
||||
#else
|
||||
asm( "movl $1, %%eax \n"
|
||||
"cpuid \n"
|
||||
: "=c" (c)
|
||||
:
|
||||
: "eax", "ebx", "edx" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
done = 1;
|
||||
}
|
||||
|
||||
return( ( c & what ) != 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* AES-NI AES-ECB block en(de)cryption
|
||||
*/
|
||||
int aesni_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
__m128i* rk, a;
|
||||
int i;
|
||||
|
||||
rk = (__m128i*)ctx->rk;
|
||||
a = _mm_xor_si128( _mm_loadu_si128( (__m128i*)input ), _mm_loadu_si128( rk++ ) );
|
||||
|
||||
if (mode == AES_ENCRYPT)
|
||||
{
|
||||
for (i = ctx->nr - 1; i; --i)
|
||||
a = _mm_aesenc_si128( a, _mm_loadu_si128( rk++ ) );
|
||||
a = _mm_aesenclast_si128( a, _mm_loadu_si128( rk ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = ctx->nr - 1; i; --i)
|
||||
a = _mm_aesdec_si128( a, _mm_loadu_si128( rk++ ) );
|
||||
a = _mm_aesdeclast_si128( a, _mm_loadu_si128( rk ) );
|
||||
}
|
||||
|
||||
_mm_storeu_si128( (__m128i*)output, a );
|
||||
#else
|
||||
asm( "movdqu (%3), %%xmm0 \n" // load input
|
||||
"movdqu (%1), %%xmm1 \n" // load round key 0
|
||||
"pxor %%xmm1, %%xmm0 \n" // round 0
|
||||
"addq $16, %1 \n" // point to next round key
|
||||
"subl $1, %0 \n" // normal rounds = nr - 1
|
||||
"test %2, %2 \n" // mode?
|
||||
"jz 2f \n" // 0 = decrypt
|
||||
|
||||
"1: \n" // encryption loop
|
||||
"movdqu (%1), %%xmm1 \n" // load round key
|
||||
"aesenc %%xmm1, %%xmm0 \n" // do round
|
||||
"addq $16, %1 \n" // point to next round key
|
||||
"subl $1, %0 \n" // loop
|
||||
"jnz 1b \n"
|
||||
"movdqu (%1), %%xmm1 \n" // load round key
|
||||
"aesenclast %%xmm1, %%xmm0 \n" // last round
|
||||
"jmp 3f \n"
|
||||
|
||||
"2: \n" // decryption loop
|
||||
"movdqu (%1), %%xmm1 \n"
|
||||
"aesdec %%xmm1, %%xmm0 \n"
|
||||
"addq $16, %1 \n"
|
||||
"subl $1, %0 \n"
|
||||
"jnz 2b \n"
|
||||
"movdqu (%1), %%xmm1 \n" // load round key
|
||||
"aesdeclast %%xmm1, %%xmm0 \n" // last round
|
||||
|
||||
"3: \n"
|
||||
"movdqu %%xmm0, (%4) \n" // export output
|
||||
:
|
||||
: "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output)
|
||||
: "memory", "cc", "xmm0", "xmm1" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
static inline void clmul256( __m128i a, __m128i b, __m128i* r0, __m128i* r1 )
|
||||
{
|
||||
__m128i c, d, e, f, ef;
|
||||
c = _mm_clmulepi64_si128( a, b, 0x00 );
|
||||
d = _mm_clmulepi64_si128( a, b, 0x11 );
|
||||
e = _mm_clmulepi64_si128( a, b, 0x10 );
|
||||
f = _mm_clmulepi64_si128( a, b, 0x01 );
|
||||
|
||||
// r0 = f0^e0^c1:c0 = c1:c0 ^ f0^e0:0
|
||||
// r1 = d1:f1^e1^d0 = d1:d0 ^ 0:f1^e1
|
||||
|
||||
ef = _mm_xor_si128( e, f );
|
||||
*r0 = _mm_xor_si128( c, _mm_slli_si128( ef, 8 ) );
|
||||
*r1 = _mm_xor_si128( d, _mm_srli_si128( ef, 8 ) );
|
||||
}
|
||||
|
||||
static inline void sll256( __m128i a0, __m128i a1, __m128i* s0, __m128i* s1 )
|
||||
{
|
||||
__m128i l0, l1, r0, r1;
|
||||
|
||||
l0 = _mm_slli_epi64( a0, 1 );
|
||||
l1 = _mm_slli_epi64( a1, 1 );
|
||||
|
||||
r0 = _mm_srli_epi64( a0, 63 );
|
||||
r1 = _mm_srli_epi64( a1, 63 );
|
||||
|
||||
*s0 = _mm_or_si128( l0, _mm_slli_si128( r0, 8 ) );
|
||||
*s1 = _mm_or_si128( _mm_or_si128( l1, _mm_srli_si128( r0, 8 ) ), _mm_slli_si128( r1, 8 ) );
|
||||
}
|
||||
|
||||
static inline __m128i reducemod128( __m128i x10, __m128i x32 )
|
||||
{
|
||||
__m128i a, b, c, dx0, e, f, g, h;
|
||||
|
||||
// (1) left shift x0 by 63, 62 and 57
|
||||
a = _mm_slli_epi64( x10, 63 );
|
||||
b = _mm_slli_epi64( x10, 62 );
|
||||
c = _mm_slli_epi64( x10, 57 );
|
||||
|
||||
// (2) compute D xor'ing a, b, c and x1
|
||||
// d:x0 = x1:x0 ^ [a^b^c:0]
|
||||
dx0 = _mm_xor_si128( x10, _mm_slli_si128( _mm_xor_si128( _mm_xor_si128( a, b ), c ), 8 ) );
|
||||
|
||||
// (3) right shift [d:x0] by 1, 2, 7
|
||||
e = _mm_or_si128( _mm_srli_epi64( dx0, 1 ), _mm_srli_si128( _mm_slli_epi64( dx0, 63 ), 8 ) );
|
||||
f = _mm_or_si128( _mm_srli_epi64( dx0, 2 ), _mm_srli_si128( _mm_slli_epi64( dx0, 62 ), 8 ) );
|
||||
g = _mm_or_si128( _mm_srli_epi64( dx0, 7 ), _mm_srli_si128( _mm_slli_epi64( dx0, 57 ), 8 ) );
|
||||
|
||||
// (4) compute h = d^e1^f1^g1 : x0^e0^f0^g0
|
||||
h = _mm_xor_si128( dx0, _mm_xor_si128( e, _mm_xor_si128( f, g ) ) );
|
||||
|
||||
// result is x3^h1:x2^h0
|
||||
return _mm_xor_si128( x32, h );
|
||||
}
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
|
||||
/*
|
||||
* GCM multiplication: c = a times b in GF(2^128)
|
||||
* Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5.
|
||||
*/
|
||||
void aesni_gcm_mult( unsigned char c[16],
|
||||
const unsigned char a[16],
|
||||
const unsigned char b[16] )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
__m128i xa, xb, m0, m1, x10, x32, r;
|
||||
|
||||
xa.m128i_u64[1] = _byteswap_uint64( *((unsigned __int64*)a + 0) );
|
||||
xa.m128i_u64[0] = _byteswap_uint64( *((unsigned __int64*)a + 1) );
|
||||
xb.m128i_u64[1] = _byteswap_uint64( *((unsigned __int64*)b + 0) );
|
||||
xb.m128i_u64[0] = _byteswap_uint64( *((unsigned __int64*)b + 1) );
|
||||
|
||||
clmul256( xa, xb, &m0, &m1 );
|
||||
sll256( m0, m1, &x10, &x32 );
|
||||
r = reducemod128( x10, x32 );
|
||||
|
||||
*((unsigned __int64*)c + 0) = _byteswap_uint64( r.m128i_u64[1] );
|
||||
*((unsigned __int64*)c + 1) = _byteswap_uint64( r.m128i_u64[0] );
|
||||
#else
|
||||
unsigned char aa[16], bb[16], cc[16];
|
||||
size_t i;
|
||||
|
||||
/* The inputs are in big-endian order, so byte-reverse them */
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
aa[i] = a[15 - i];
|
||||
bb[i] = b[15 - i];
|
||||
}
|
||||
|
||||
asm( "movdqu (%0), %%xmm0 \n" // a1:a0
|
||||
"movdqu (%1), %%xmm1 \n" // b1:b0
|
||||
|
||||
/*
|
||||
* Caryless multiplication xmm2:xmm1 = xmm0 * xmm1
|
||||
* using [CLMUL-WP] algorithm 1 (p. 13).
|
||||
*/
|
||||
"movdqa %%xmm1, %%xmm2 \n" // copy of b1:b0
|
||||
"movdqa %%xmm1, %%xmm3 \n" // same
|
||||
"movdqa %%xmm1, %%xmm4 \n" // same
|
||||
"pclmulqdq $0x00, %%xmm0, %%xmm1 \n" // a0*b0 = c1:c0
|
||||
"pclmulqdq $0x11, %%xmm0, %%xmm2 \n" // a1*b1 = d1:d0
|
||||
"pclmulqdq $0x10, %%xmm0, %%xmm3 \n" // a0*b1 = e1:e0
|
||||
"pclmulqdq $0x01, %%xmm0, %%xmm4 \n" // a1*b0 = f1:f0
|
||||
"pxor %%xmm3, %%xmm4 \n" // e1+f1:e0+f0
|
||||
"movdqa %%xmm4, %%xmm3 \n" // same
|
||||
"psrldq $8, %%xmm4 \n" // 0:e1+f1
|
||||
"pslldq $8, %%xmm3 \n" // e0+f0:0
|
||||
"pxor %%xmm4, %%xmm2 \n" // d1:d0+e1+f1
|
||||
"pxor %%xmm3, %%xmm1 \n" // c1+e0+f1:c0
|
||||
|
||||
/*
|
||||
* Now shift the result one bit to the left,
|
||||
* taking advantage of [CLMUL-WP] eq 27 (p. 20)
|
||||
*/
|
||||
"movdqa %%xmm1, %%xmm3 \n" // r1:r0
|
||||
"movdqa %%xmm2, %%xmm4 \n" // r3:r2
|
||||
"psllq $1, %%xmm1 \n" // r1<<1:r0<<1
|
||||
"psllq $1, %%xmm2 \n" // r3<<1:r2<<1
|
||||
"psrlq $63, %%xmm3 \n" // r1>>63:r0>>63
|
||||
"psrlq $63, %%xmm4 \n" // r3>>63:r2>>63
|
||||
"movdqa %%xmm3, %%xmm5 \n" // r1>>63:r0>>63
|
||||
"pslldq $8, %%xmm3 \n" // r0>>63:0
|
||||
"pslldq $8, %%xmm4 \n" // r2>>63:0
|
||||
"psrldq $8, %%xmm5 \n" // 0:r1>>63
|
||||
"por %%xmm3, %%xmm1 \n" // r1<<1|r0>>63:r0<<1
|
||||
"por %%xmm4, %%xmm2 \n" // r3<<1|r2>>62:r2<<1
|
||||
"por %%xmm5, %%xmm2 \n" // r3<<1|r2>>62:r2<<1|r1>>63
|
||||
|
||||
/*
|
||||
* Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
|
||||
* using [CLMUL-WP] algorithm 5 (p. 20).
|
||||
* Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted).
|
||||
*/
|
||||
/* Step 2 (1) */
|
||||
"movdqa %%xmm1, %%xmm3 \n" // x1:x0
|
||||
"movdqa %%xmm1, %%xmm4 \n" // same
|
||||
"movdqa %%xmm1, %%xmm5 \n" // same
|
||||
"psllq $63, %%xmm3 \n" // x1<<63:x0<<63 = stuff:a
|
||||
"psllq $62, %%xmm4 \n" // x1<<62:x0<<62 = stuff:b
|
||||
"psllq $57, %%xmm5 \n" // x1<<57:x0<<57 = stuff:c
|
||||
|
||||
/* Step 2 (2) */
|
||||
"pxor %%xmm4, %%xmm3 \n" // stuff:a+b
|
||||
"pxor %%xmm5, %%xmm3 \n" // stuff:a+b+c
|
||||
"pslldq $8, %%xmm3 \n" // a+b+c:0
|
||||
"pxor %%xmm3, %%xmm1 \n" // x1+a+b+c:x0 = d:x0
|
||||
|
||||
/* Steps 3 and 4 */
|
||||
"movdqa %%xmm1,%%xmm0 \n" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n" // same
|
||||
"psrlq $1, %%xmm0 \n" // e1:x0>>1 = e1:e0'
|
||||
"psrlq $2, %%xmm4 \n" // f1:x0>>2 = f1:f0'
|
||||
"psrlq $7, %%xmm5 \n" // g1:x0>>7 = g1:g0'
|
||||
"pxor %%xmm4, %%xmm0 \n" // e1+f1:e0'+f0'
|
||||
"pxor %%xmm5, %%xmm0 \n" // e1+f1+g1:e0'+f0'+g0'
|
||||
// e0'+f0'+g0' is almost e0+f0+g0, except for some missing
|
||||
// bits carried from d. Now get those bits back in.
|
||||
"movdqa %%xmm1,%%xmm3 \n" // d:x0
|
||||
"movdqa %%xmm1,%%xmm4 \n" // same
|
||||
"movdqa %%xmm1,%%xmm5 \n" // same
|
||||
"psllq $63, %%xmm3 \n" // d<<63:stuff
|
||||
"psllq $62, %%xmm4 \n" // d<<62:stuff
|
||||
"psllq $57, %%xmm5 \n" // d<<57:stuff
|
||||
"pxor %%xmm4, %%xmm3 \n" // d<<63+d<<62:stuff
|
||||
"pxor %%xmm5, %%xmm3 \n" // missing bits of d:stuff
|
||||
"psrldq $8, %%xmm3 \n" // 0:missing bits of d
|
||||
"pxor %%xmm3, %%xmm0 \n" // e1+f1+g1:e0+f0+g0
|
||||
"pxor %%xmm1, %%xmm0 \n" // h1:h0
|
||||
"pxor %%xmm2, %%xmm0 \n" // x3+h1:x2+h0
|
||||
|
||||
"movdqu %%xmm0, (%2) \n" // done
|
||||
:
|
||||
: "r" (aa), "r" (bb), "r" (cc)
|
||||
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" );
|
||||
|
||||
/* Now byte-reverse the outputs */
|
||||
for( i = 0; i < 16; i++ )
|
||||
c[i] = cc[15 - i];
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute decryption round keys from encryption round keys
|
||||
*/
|
||||
void aesni_inverse_key( unsigned char *invkey,
|
||||
const unsigned char *fwdkey, int nr )
|
||||
{
|
||||
unsigned char *ik = invkey;
|
||||
const unsigned char *fk = fwdkey + 16 * nr;
|
||||
|
||||
memcpy( ik, fk, 16 );
|
||||
|
||||
for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 )
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
_mm_storeu_si128( (__m128i*)ik, _mm_aesimc_si128( _mm_loadu_si128( (__m128i*)fk) ) );
|
||||
#else
|
||||
asm( "movdqu (%0), %%xmm0 \n"
|
||||
"aesimc %%xmm0, %%xmm0 \n"
|
||||
"movdqu %%xmm0, (%1) \n"
|
||||
:
|
||||
: "r" (fk), "r" (ik)
|
||||
: "memory", "xmm0" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
|
||||
memcpy( ik, fk, 16 );
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
inline static __m128i aes_key_128_assist( __m128i key, __m128i kg )
|
||||
{
|
||||
key = _mm_xor_si128( key, _mm_slli_si128( key, 4 ) );
|
||||
key = _mm_xor_si128( key, _mm_slli_si128( key, 4 ) );
|
||||
key = _mm_xor_si128( key, _mm_slli_si128( key, 4 ) );
|
||||
kg = _mm_shuffle_epi32( kg, _MM_SHUFFLE( 3, 3, 3, 3 ) );
|
||||
return _mm_xor_si128( key, kg );
|
||||
}
|
||||
|
||||
// [AES-WP] Part of Fig. 25 page 32
|
||||
inline static void aes_key_192_assist( __m128i* temp1, __m128i * temp3, __m128i kg )
|
||||
{
|
||||
__m128i temp4;
|
||||
kg = _mm_shuffle_epi32( kg, 0x55 );
|
||||
temp4 = _mm_slli_si128( *temp1, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, kg );
|
||||
kg = _mm_shuffle_epi32( *temp1, 0xff );
|
||||
temp4 = _mm_slli_si128( *temp3, 0x4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, temp4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, kg );
|
||||
}
|
||||
|
||||
// [AES-WP] Part of Fig. 26 page 34
|
||||
inline static void aes_key_256_assist_1( __m128i* temp1, __m128i kg )
|
||||
{
|
||||
__m128i temp4;
|
||||
kg = _mm_shuffle_epi32( kg, 0xff );
|
||||
temp4 = _mm_slli_si128( *temp1, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, temp4 );
|
||||
*temp1 = _mm_xor_si128( *temp1, kg );
|
||||
}
|
||||
|
||||
inline static void aes_key_256_assist_2( __m128i* temp1, __m128i* temp3 )
|
||||
{
|
||||
__m128i temp2, temp4;
|
||||
temp4 = _mm_aeskeygenassist_si128( *temp1, 0x0 );
|
||||
temp2 = _mm_shuffle_epi32( temp4, 0xaa );
|
||||
temp4 = _mm_slli_si128( *temp3, 0x4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, temp4 );
|
||||
temp4 = _mm_slli_si128( temp4, 0x4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, temp4 );
|
||||
*temp3 = _mm_xor_si128( *temp3, temp2 );
|
||||
}
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
|
||||
/*
|
||||
* Key expansion, 128-bit case
|
||||
*/
|
||||
static void aesni_setkey_enc_128( unsigned char *rk,
|
||||
const unsigned char *key )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
__m128i* xrk, k;
|
||||
|
||||
xrk = (__m128i*)rk;
|
||||
|
||||
#define EXPAND_ROUND(k, rcon) \
|
||||
_mm_storeu_si128( xrk++, k ); \
|
||||
k = aes_key_128_assist( k, _mm_aeskeygenassist_si128( k, rcon ) )
|
||||
|
||||
k = _mm_loadu_si128( (__m128i*)key );
|
||||
EXPAND_ROUND( k, 0x01 );
|
||||
EXPAND_ROUND( k, 0x02 );
|
||||
EXPAND_ROUND( k, 0x04 );
|
||||
EXPAND_ROUND( k, 0x08 );
|
||||
EXPAND_ROUND( k, 0x10 );
|
||||
EXPAND_ROUND( k, 0x20 );
|
||||
EXPAND_ROUND( k, 0x40 );
|
||||
EXPAND_ROUND( k, 0x80 );
|
||||
EXPAND_ROUND( k, 0x1b );
|
||||
EXPAND_ROUND( k, 0x36 );
|
||||
_mm_storeu_si128( xrk, k );
|
||||
|
||||
#undef EXPAND_ROUND
|
||||
|
||||
#else
|
||||
asm( "movdqu (%1), %%xmm0 \n" // copy the original key
|
||||
"movdqu %%xmm0, (%0) \n" // as round key 0
|
||||
"jmp 2f \n" // skip auxiliary routine
|
||||
|
||||
/*
|
||||
* Finish generating the next round key.
|
||||
*
|
||||
* On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff
|
||||
* with X = rot( sub( r3 ) ) ^ RCON.
|
||||
*
|
||||
* On exit, xmm0 is r7:r6:r5:r4
|
||||
* with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
|
||||
* and those are written to the round key buffer.
|
||||
*/
|
||||
"1: \n"
|
||||
"pshufd $0xff, %%xmm1, %%xmm1 \n" // X:X:X:X
|
||||
"pxor %%xmm0, %%xmm1 \n" // X+r3:X+r2:X+r1:r4
|
||||
"pslldq $4, %%xmm0 \n" // r2:r1:r0:0
|
||||
"pxor %%xmm0, %%xmm1 \n" // X+r3+r2:X+r2+r1:r5:r4
|
||||
"pslldq $4, %%xmm0 \n" // etc
|
||||
"pxor %%xmm0, %%xmm1 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm1, %%xmm0 \n" // update xmm0 for next time!
|
||||
"add $16, %0 \n" // point to next round key
|
||||
"movdqu %%xmm0, (%0) \n" // write it
|
||||
"ret \n"
|
||||
|
||||
/* Main "loop" */
|
||||
"2: \n"
|
||||
"aeskeygenassist $0x01, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x02, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x04, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x08, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x10, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x20, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x40, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x80, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x1B, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
"aeskeygenassist $0x36, %%xmm0, %%xmm1 \ncall 1b \n"
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
: "memory", "cc", "0" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, 192-bit case
|
||||
*/
|
||||
static void aesni_setkey_enc_192( unsigned char *rk,
|
||||
const unsigned char *key )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
__m128i temp1, temp3;
|
||||
__m128i *key_schedule = (__m128i*)rk;
|
||||
temp1 = _mm_loadu_si128( (__m128i*)key );
|
||||
temp3 = _mm_loadu_si128( (__m128i*)(key + 16) );
|
||||
key_schedule[0] = temp1;
|
||||
key_schedule[1] = temp3;
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128(temp3, 0x1) );
|
||||
key_schedule[1] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( key_schedule[1] ), _mm_castsi128_pd( temp1 ), 0 ) );
|
||||
key_schedule[2] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( temp1 ), _mm_castsi128_pd( temp3 ), 1 ) );
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x2 ) );
|
||||
key_schedule[3] = temp1;
|
||||
key_schedule[4] = temp3;
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x4 ) );
|
||||
key_schedule[4] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( key_schedule[4] ), _mm_castsi128_pd( temp1 ), 0 ) );
|
||||
key_schedule[5] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( temp1 ), _mm_castsi128_pd( temp3 ), 1 ) );
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x8 ) );
|
||||
key_schedule[6] = temp1;
|
||||
key_schedule[7] = temp3;
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x10 ) );
|
||||
key_schedule[7] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( key_schedule[7] ), _mm_castsi128_pd( temp1 ), 0 ) );
|
||||
key_schedule[8] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( temp1 ), _mm_castsi128_pd( temp3 ), 1 ) );
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x20 ) );
|
||||
key_schedule[9] = temp1;
|
||||
key_schedule[10] = temp3;
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x40 ) );
|
||||
key_schedule[10] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( key_schedule[10] ), _mm_castsi128_pd( temp1 ), 0 ) );
|
||||
key_schedule[11] = _mm_castpd_si128( _mm_shuffle_pd( _mm_castsi128_pd( temp1 ), _mm_castsi128_pd( temp3 ), 1 ) );
|
||||
aes_key_192_assist( &temp1, &temp3, _mm_aeskeygenassist_si128( temp3, 0x80 ) );
|
||||
key_schedule[12] = temp1;
|
||||
#else
|
||||
asm( "movdqu (%1), %%xmm0 \n" // copy original round key
|
||||
"movdqu %%xmm0, (%0) \n"
|
||||
"add $16, %0 \n"
|
||||
"movq 16(%1), %%xmm1 \n"
|
||||
"movq %%xmm1, (%0) \n"
|
||||
"add $8, %0 \n"
|
||||
"jmp 2f \n" // skip auxiliary routine
|
||||
|
||||
/*
|
||||
* Finish generating the next 6 quarter-keys.
|
||||
*
|
||||
* On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4
|
||||
* and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON.
|
||||
*
|
||||
* On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10
|
||||
* and those are written to the round key buffer.
|
||||
*/
|
||||
"1: \n"
|
||||
"pshufd $0x55, %%xmm2, %%xmm2 \n" // X:X:X:X
|
||||
"pxor %%xmm0, %%xmm2 \n" // X+r3:X+r2:X+r1:r4
|
||||
"pslldq $4, %%xmm0 \n" // etc
|
||||
"pxor %%xmm0, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm0, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm2, %%xmm0 \n" // update xmm0 = r9:r8:r7:r6
|
||||
"movdqu %%xmm0, (%0) \n"
|
||||
"add $16, %0 \n"
|
||||
"pshufd $0xff, %%xmm0, %%xmm2 \n" // r9:r9:r9:r9
|
||||
"pxor %%xmm1, %%xmm2 \n" // stuff:stuff:r9+r5:r10
|
||||
"pslldq $4, %%xmm1 \n" // r2:r1:r0:0
|
||||
"pxor %%xmm2, %%xmm1 \n" // update xmm1 = stuff:stuff:r11:r10
|
||||
"movq %%xmm1, (%0) \n"
|
||||
"add $8, %0 \n"
|
||||
"ret \n"
|
||||
|
||||
"2: \n"
|
||||
"aeskeygenassist $0x01, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x02, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x04, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x08, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x10, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x20, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x40, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x80, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
: "memory", "cc", "0" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, 256-bit case
|
||||
*/
|
||||
static void aesni_setkey_enc_256( unsigned char *rk,
|
||||
const unsigned char *key )
|
||||
{
|
||||
#if defined(POLARSSL_HAVE_MSVC_X64_INTRINSICS)
|
||||
__m128i temp1, temp3;
|
||||
__m128i *key_schedule = (__m128i*)rk;
|
||||
temp1 = _mm_loadu_si128( (__m128i*)key );
|
||||
temp3 = _mm_loadu_si128( (__m128i*)(key + 16) );
|
||||
key_schedule[0] = temp1;
|
||||
key_schedule[1] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x01 ) );
|
||||
key_schedule[2] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[3] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x02 ) );
|
||||
key_schedule[4] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[5] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x04 ) );
|
||||
key_schedule[6] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[7] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x08 ) );
|
||||
key_schedule[8] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[9] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x10 ) );
|
||||
key_schedule[10] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[11] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x20 ) );
|
||||
key_schedule[12] = temp1;
|
||||
aes_key_256_assist_2( &temp1, &temp3 );
|
||||
key_schedule[13] = temp3;
|
||||
aes_key_256_assist_1( &temp1, _mm_aeskeygenassist_si128( temp3, 0x40 ) );
|
||||
key_schedule[14] = temp1;
|
||||
#else
|
||||
asm( "movdqu (%1), %%xmm0 \n"
|
||||
"movdqu %%xmm0, (%0) \n"
|
||||
"add $16, %0 \n"
|
||||
"movdqu 16(%1), %%xmm1 \n"
|
||||
"movdqu %%xmm1, (%0) \n"
|
||||
"jmp 2f \n" // skip auxiliary routine
|
||||
|
||||
/*
|
||||
* Finish generating the next two round keys.
|
||||
*
|
||||
* On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and
|
||||
* xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
|
||||
*
|
||||
* On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12
|
||||
* and those have been written to the output buffer.
|
||||
*/
|
||||
"1: \n"
|
||||
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
||||
"pxor %%xmm0, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm0, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm0, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm0 \n"
|
||||
"pxor %%xmm2, %%xmm0 \n"
|
||||
"add $16, %0 \n"
|
||||
"movdqu %%xmm0, (%0) \n"
|
||||
|
||||
/* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
|
||||
* and proceed to generate next round key from there */
|
||||
"aeskeygenassist $0, %%xmm0, %%xmm2\n"
|
||||
"pshufd $0xaa, %%xmm2, %%xmm2 \n"
|
||||
"pxor %%xmm1, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm1 \n"
|
||||
"pxor %%xmm1, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm1 \n"
|
||||
"pxor %%xmm1, %%xmm2 \n"
|
||||
"pslldq $4, %%xmm1 \n"
|
||||
"pxor %%xmm2, %%xmm1 \n"
|
||||
"add $16, %0 \n"
|
||||
"movdqu %%xmm1, (%0) \n"
|
||||
"ret \n"
|
||||
|
||||
/*
|
||||
* Main "loop" - Generating one more key than necessary,
|
||||
* see definition of aes_context.buf
|
||||
*/
|
||||
"2: \n"
|
||||
"aeskeygenassist $0x01, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x02, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x04, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x08, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x10, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x20, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
"aeskeygenassist $0x40, %%xmm1, %%xmm2 \ncall 1b \n"
|
||||
:
|
||||
: "r" (rk), "r" (key)
|
||||
: "memory", "cc", "0" );
|
||||
#endif /* POLARSSL_HAVE_MSVC_X64_INTRINSICS */
|
||||
}
|
||||
|
||||
/*
|
||||
* Key expansion, wrapper
|
||||
*/
|
||||
int aesni_setkey_enc( unsigned char *rk,
|
||||
const unsigned char *key,
|
||||
size_t bits )
|
||||
{
|
||||
switch( bits )
|
||||
{
|
||||
case 128: aesni_setkey_enc_128( rk, key ); break;
|
||||
case 192: aesni_setkey_enc_192( rk, key ); break;
|
||||
case 256: aesni_setkey_enc_256( rk, key ); break;
|
||||
default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
#define POLARSSL_HAVE_ASM
|
||||
/**
|
||||
* \file aesni.h
|
||||
*
|
||||
* \brief AES-NI for hardware AES acceleration on some Intel processors
|
||||
*
|
||||
* Copyright (C) 2013, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
#define POLARSSL_AESNI_AES 0x02000000u
|
||||
#define POLARSSL_AESNI_CLMUL 0x00000002u
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief AES-NI features detection routine
|
||||
*
|
||||
* \param what The feature to detect
|
||||
* (POLARSSL_AESNI_AES or POLARSSL_AESNI_CLMUL)
|
||||
*
|
||||
* \return 1 if CPU has support for the feature, 0 otherwise
|
||||
*/
|
||||
int aesni_supports( unsigned int what );
|
||||
|
||||
/**
|
||||
* \brief AES-NI AES-ECB block en(de)cryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 on success (cannot fail)
|
||||
*/
|
||||
int aesni_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
/**
|
||||
* \brief GCM multiplication: c = a * b in GF(2^128)
|
||||
*
|
||||
* \param c Result
|
||||
* \param a First operand
|
||||
* \param b Second operand
|
||||
*
|
||||
* \note Both operands and result are bit strings interpreted as
|
||||
* elements of GF(2^128) as per the GCM spec.
|
||||
*/
|
||||
void aesni_gcm_mult( unsigned char c[16],
|
||||
const unsigned char a[16],
|
||||
const unsigned char b[16] );
|
||||
|
||||
/**
|
||||
* \brief Compute decryption round keys from encryption round keys
|
||||
*
|
||||
* \param invkey Round keys for the equivalent inverse cipher
|
||||
* \param fwdkey Original round keys (for encryption)
|
||||
* \param nr Number of rounds (that is, number of round keys minus one)
|
||||
*/
|
||||
void aesni_inverse_key( unsigned char *invkey,
|
||||
const unsigned char *fwdkey, int nr );
|
||||
|
||||
/**
|
||||
* \brief Perform key expansion (for encryption)
|
||||
*
|
||||
* \param rk Destination buffer where the round keys are written
|
||||
* \param key Encryption key
|
||||
* \param bits Key size in bits (must be 128, 192 or 256)
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aesni_setkey_enc( unsigned char *rk,
|
||||
const unsigned char *key,
|
||||
size_t bits );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <array>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "Utilities/File.h"
|
||||
|
||||
constexpr u32 SDAT_FLAG = 0x01000000;
|
||||
constexpr u32 EDAT_COMPRESSED_FLAG = 0x00000001;
|
||||
constexpr u32 EDAT_FLAG_0x02 = 0x00000002;
|
||||
@@ -14,7 +14,7 @@ constexpr u32 EDAT_FLAG_0x10 = 0x00000010;
|
||||
constexpr u32 EDAT_FLAG_0x20 = 0x00000020;
|
||||
constexpr u32 EDAT_DEBUG_DATA_FLAG = 0x80000000;
|
||||
|
||||
struct LoadedNpdrmKeys_t
|
||||
struct loaded_npdrm_keys
|
||||
{
|
||||
std::array<u8, 0x10> devKlic{};
|
||||
std::array<u8, 0x10> rifKey{};
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
: edata_file(std::move(input)), rif_key(rif_key), dev_key(dev_key) {}
|
||||
|
||||
~EDATADecrypter() override {}
|
||||
// false if invalid
|
||||
// false if invalid
|
||||
bool ReadHeader();
|
||||
u64 ReadData(u64 pos, u8* data, u64 size);
|
||||
|
||||
@@ -92,10 +92,10 @@ public:
|
||||
stats.mtime = -1;
|
||||
return stats;
|
||||
}
|
||||
bool trunc(u64 length) override
|
||||
bool trunc(u64 length) override
|
||||
{
|
||||
return true;
|
||||
};
|
||||
}
|
||||
u64 read(void* buffer, u64 size) override
|
||||
{
|
||||
u64 bytesRead = ReadData(pos, (u8*)buffer, size);
|
||||
|
||||
@@ -201,7 +201,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
|
||||
bool was_null = true;
|
||||
|
||||
// Get full path and create the directory
|
||||
const std::string dir = Emu.GetHddDir() + "game/" + install_id + '/';
|
||||
const std::string dir = Emulator::GetHddDir() + "game/" + install_id + '/';
|
||||
|
||||
if (!fs::create_dir(dir))
|
||||
{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/BEType.h"
|
||||
|
||||
// Constants
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include "key_vault.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "Utilities/Log.h"
|
||||
|
||||
struct AppInfo
|
||||
{
|
||||
u64 authid;
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}</ProjectGuid>
|
||||
<RootNamespace>D3D12GSRender</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="..\common_default_macros.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -96,4 +96,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -128,7 +128,7 @@ bool OpenALBackend::AddData(const void* src, u32 num_samples)
|
||||
// Fail if there are no free buffers remaining
|
||||
if (m_num_unqueued == 0)
|
||||
{
|
||||
LOG_WARNING(GENERAL, "XAudio2Backend : no unqueued buffers remaining");
|
||||
LOG_WARNING(GENERAL, "OpenALBackend : no unqueued buffers remaining");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ public:
|
||||
OpenALBackend();
|
||||
virtual ~OpenALBackend() override;
|
||||
|
||||
virtual const char* GetName() const override { return "OpenAL"; };
|
||||
virtual const char* GetName() const override { return "OpenAL"; }
|
||||
|
||||
static const u32 capabilities = PLAY_PAUSE_FLUSH | IS_PLAYING | GET_NUM_ENQUEUED_SAMPLES | SET_FREQUENCY_RATIO;
|
||||
virtual u32 GetCapabilities() const override { return capabilities; };
|
||||
virtual u32 GetCapabilities() const override { return capabilities; }
|
||||
|
||||
virtual void Open(u32 num_buffers) override;
|
||||
virtual void Close() override;
|
||||
|
||||
@@ -16,10 +16,10 @@ public:
|
||||
ALSABackend();
|
||||
virtual ~ALSABackend() override;
|
||||
|
||||
virtual const char* GetName() const override { return "ALSA"; };
|
||||
virtual const char* GetName() const override { return "ALSA"; }
|
||||
|
||||
static const u32 capabilities = 0;
|
||||
virtual u32 GetCapabilities() const override { return capabilities; };
|
||||
virtual u32 GetCapabilities() const override { return capabilities; }
|
||||
|
||||
virtual void Open(u32) override;
|
||||
virtual void Close() override;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/File.h"
|
||||
|
||||
struct WAVHeader
|
||||
{
|
||||
struct RIFFHeader
|
||||
|
||||
@@ -8,17 +8,17 @@ public:
|
||||
NullAudioBackend() {}
|
||||
virtual ~NullAudioBackend() {}
|
||||
|
||||
virtual const char* GetName() const override { return "Null"; }
|
||||
virtual const char* GetName() const override { return "Null"; }
|
||||
|
||||
static const u32 capabilities = PLAY_PAUSE_FLUSH;
|
||||
virtual u32 GetCapabilities() const override { return capabilities; };
|
||||
virtual u32 GetCapabilities() const override { return capabilities; }
|
||||
|
||||
virtual void Open(u32) override {};
|
||||
virtual void Close() override {};
|
||||
virtual void Open(u32) override {}
|
||||
virtual void Close() override {}
|
||||
|
||||
virtual void Play() override {};
|
||||
virtual void Pause() override {};
|
||||
virtual void Play() override {}
|
||||
virtual void Pause() override {}
|
||||
|
||||
virtual bool AddData(const void*, u32) override { return true; };
|
||||
virtual void Flush() override {};
|
||||
virtual bool AddData(const void*, u32) override { return true; }
|
||||
virtual void Flush() override {}
|
||||
};
|
||||
|
||||
@@ -10,10 +10,10 @@ public:
|
||||
PulseBackend();
|
||||
virtual ~PulseBackend() override;
|
||||
|
||||
virtual const char* GetName() const override { return "Pulse"; };
|
||||
virtual const char* GetName() const override { return "Pulse"; }
|
||||
|
||||
static const u32 capabilities = 0;
|
||||
virtual u32 GetCapabilities() const override { return capabilities; };
|
||||
virtual u32 GetCapabilities() const override { return capabilities; }
|
||||
|
||||
virtual void Open(u32) override;
|
||||
virtual void Close() override;
|
||||
|
||||
+321
-36
@@ -1,6 +1,8 @@
|
||||
file(GLOB SRC_FILES "*.cpp")
|
||||
|
||||
add_library(rpcs3_emu ${SRC_FILES})
|
||||
add_library(rpcs3_emu
|
||||
IdManager.cpp
|
||||
System.cpp
|
||||
VFS.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PRIVATE
|
||||
@@ -15,8 +17,26 @@ target_include_directories(rpcs3_emu
|
||||
|
||||
|
||||
# Utilities
|
||||
file(GLOB UTILITIES_SRC_FILES "../../Utilities/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${UTILITIES_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
../util/atomic.cpp
|
||||
../../Utilities/bin_patch.cpp
|
||||
../../Utilities/cond.cpp
|
||||
../../Utilities/Config.cpp
|
||||
../../Utilities/dynamic_library.cpp
|
||||
../../Utilities/File.cpp
|
||||
../../Utilities/GDBDebugServer.cpp
|
||||
../../Utilities/JIT.cpp
|
||||
../../Utilities/Log.cpp
|
||||
../../Utilities/LUrlParser.cpp
|
||||
../../Utilities/mutex.cpp
|
||||
../../Utilities/rXml.cpp
|
||||
../../Utilities/sema.cpp
|
||||
../../Utilities/StrFmt.cpp
|
||||
../../Utilities/sysinfo.cpp
|
||||
../../Utilities/Thread.cpp
|
||||
../../Utilities/version.cpp
|
||||
../../Utilities/VirtualMemory.cpp
|
||||
)
|
||||
|
||||
target_include_directories(rpcs3_emu PUBLIC "${CMAKE_SOURCE_DIR}")
|
||||
|
||||
@@ -25,21 +45,48 @@ target_link_libraries(rpcs3_emu
|
||||
3rdparty::pugixml
|
||||
3rdparty::gsl)
|
||||
|
||||
set_source_files_properties("../../Utilities/JIT.cpp" PROPERTIES COMPILE_FLAGS -fno-rtti)
|
||||
if (MSVC)
|
||||
set_source_files_properties("../../Utilities/JIT.cpp" PROPERTIES COMPILE_FLAGS /GR-)
|
||||
else()
|
||||
set_source_files_properties("../../Utilities/JIT.cpp" PROPERTIES COMPILE_FLAGS -fno-rtti)
|
||||
endif()
|
||||
|
||||
|
||||
# Crypto
|
||||
file(GLOB CRYPTO_SRC_FILES "../Crypto/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${CRYPTO_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
../Crypto/aes.cpp
|
||||
../Crypto/aesni.cpp
|
||||
../Crypto/ec.cpp
|
||||
../Crypto/key_vault.cpp
|
||||
../Crypto/lz.cpp
|
||||
../Crypto/sha1.cpp
|
||||
../Crypto/unedat.cpp
|
||||
../Crypto/unpkg.cpp
|
||||
../Crypto/unself.cpp
|
||||
../Crypto/utils.cpp
|
||||
)
|
||||
|
||||
# Loader
|
||||
file(GLOB LOADER_SRC_FILES "../Loader/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${LOADER_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
../Loader/ELF.cpp
|
||||
../Loader/PSF.cpp
|
||||
../Loader/PUP.cpp
|
||||
../Loader/TAR.cpp
|
||||
../Loader/TROPUSR.cpp
|
||||
../Loader/TRP.cpp
|
||||
)
|
||||
|
||||
|
||||
# Audio
|
||||
file(GLOB_RECURSE AUDIO_SRC_FILES "Audio/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${AUDIO_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Audio/AudioDumper.cpp
|
||||
Audio/AL/OpenALBackend.cpp
|
||||
Audio/ALSA/ALSABackend.cpp
|
||||
Audio/Pulse/PulseBackend.cpp
|
||||
Audio/XAudio2/XAudio27Backend.cpp
|
||||
Audio/XAudio2/XAudio28Backend.cpp
|
||||
Audio/XAudio2/XAudio2Backend.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
# Slimmed down version of minidx9 for XAudio2_7 only
|
||||
@@ -52,8 +99,180 @@ target_link_libraries(rpcs3_emu
|
||||
|
||||
|
||||
# Cell
|
||||
file(GLOB_RECURSE CELL_SRC_FILES "Cell/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${CELL_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Cell/MFC.cpp
|
||||
Cell/PPUAnalyser.cpp
|
||||
Cell/PPUDisAsm.cpp
|
||||
Cell/PPUFunction.cpp
|
||||
Cell/PPUInterpreter.cpp
|
||||
Cell/PPUModule.cpp
|
||||
Cell/PPUThread.cpp
|
||||
Cell/PPUTranslator.cpp
|
||||
Cell/RawSPUThread.cpp
|
||||
Cell/SPUAnalyser.cpp
|
||||
Cell/SPUASMJITRecompiler.cpp
|
||||
Cell/SPUDisAsm.cpp
|
||||
Cell/SPUInterpreter.cpp
|
||||
Cell/SPURecompiler.cpp
|
||||
Cell/SPUThread.cpp
|
||||
Cell/lv2/lv2.cpp
|
||||
Cell/lv2/sys_cond.cpp
|
||||
Cell/lv2/sys_config.cpp
|
||||
Cell/lv2/sys_dbg.cpp
|
||||
Cell/lv2/sys_event.cpp
|
||||
Cell/lv2/sys_event_flag.cpp
|
||||
Cell/lv2/sys_fs.cpp
|
||||
Cell/lv2/sys_gamepad.cpp
|
||||
Cell/lv2/sys_gpio.cpp
|
||||
Cell/lv2/sys_interrupt.cpp
|
||||
Cell/lv2/sys_lwcond.cpp
|
||||
Cell/lv2/sys_lwmutex.cpp
|
||||
Cell/lv2/sys_memory.cpp
|
||||
Cell/lv2/sys_mmapper.cpp
|
||||
Cell/lv2/sys_mutex.cpp
|
||||
Cell/lv2/sys_net.cpp
|
||||
Cell/lv2/sys_overlay.cpp
|
||||
Cell/lv2/sys_ppu_thread.cpp
|
||||
Cell/lv2/sys_process.cpp
|
||||
Cell/lv2/sys_prx.cpp
|
||||
Cell/lv2/sys_rsx.cpp
|
||||
Cell/lv2/sys_rwlock.cpp
|
||||
Cell/lv2/sys_semaphore.cpp
|
||||
Cell/lv2/sys_spu.cpp
|
||||
Cell/lv2/sys_ss.cpp
|
||||
Cell/lv2/sys_time.cpp
|
||||
Cell/lv2/sys_timer.cpp
|
||||
Cell/lv2/sys_trace.cpp
|
||||
Cell/lv2/sys_tty.cpp
|
||||
Cell/lv2/sys_usbd.cpp
|
||||
Cell/lv2/sys_vm.cpp
|
||||
Cell/Modules/cellAdec.cpp
|
||||
Cell/Modules/cellAtrac.cpp
|
||||
Cell/Modules/cellAtracMulti.cpp
|
||||
Cell/Modules/cellAudio.cpp
|
||||
Cell/Modules/cellAudioOut.cpp
|
||||
Cell/Modules/cellAvconfExt.cpp
|
||||
Cell/Modules/cellBgdl.cpp
|
||||
Cell/Modules/cellCamera.cpp
|
||||
Cell/Modules/cellCelp8Enc.cpp
|
||||
Cell/Modules/cellCelpEnc.cpp
|
||||
Cell/Modules/cellCrossController.cpp
|
||||
Cell/Modules/cellDaisy.cpp
|
||||
Cell/Modules/cellDmux.cpp
|
||||
Cell/Modules/cellDtcpIpUtility.cpp
|
||||
Cell/Modules/cellFiber.cpp
|
||||
Cell/Modules/cellFont.cpp
|
||||
Cell/Modules/cellFontFT.cpp
|
||||
Cell/Modules/cell_FreeType2.cpp
|
||||
Cell/Modules/cellFs.cpp
|
||||
Cell/Modules/cellGame.cpp
|
||||
Cell/Modules/cellGameExec.cpp
|
||||
Cell/Modules/cellGcmSys.cpp
|
||||
Cell/Modules/cellGem.cpp
|
||||
Cell/Modules/cellGifDec.cpp
|
||||
Cell/Modules/cellHttp.cpp
|
||||
Cell/Modules/cellHttpUtil.cpp
|
||||
Cell/Modules/cellImeJp.cpp
|
||||
Cell/Modules/cellJpgDec.cpp
|
||||
Cell/Modules/cellJpgEnc.cpp
|
||||
Cell/Modules/cellKb.cpp
|
||||
Cell/Modules/cellKey2char.cpp
|
||||
Cell/Modules/cellL10n.cpp
|
||||
Cell/Modules/cellLibprof.cpp
|
||||
Cell/Modules/cellMic.cpp
|
||||
Cell/Modules/cellMouse.cpp
|
||||
Cell/Modules/cellMsgDialog.cpp
|
||||
Cell/Modules/cellMusic.cpp
|
||||
Cell/Modules/cellMusicDecode.cpp
|
||||
Cell/Modules/cellMusicExport.cpp
|
||||
Cell/Modules/cellNetAoi.cpp
|
||||
Cell/Modules/cellNetCtl.cpp
|
||||
Cell/Modules/cellOskDialog.cpp
|
||||
Cell/Modules/cellOvis.cpp
|
||||
Cell/Modules/cellPad.cpp
|
||||
Cell/Modules/cellPamf.cpp
|
||||
Cell/Modules/cellPesmUtility.cpp
|
||||
Cell/Modules/cellPhotoDecode.cpp
|
||||
Cell/Modules/cellPhotoExport.cpp
|
||||
Cell/Modules/cellPhotoImport.cpp
|
||||
Cell/Modules/cellPngDec.cpp
|
||||
Cell/Modules/cellPngEnc.cpp
|
||||
Cell/Modules/cellPrint.cpp
|
||||
Cell/Modules/cellRec.cpp
|
||||
Cell/Modules/cellRemotePlay.cpp
|
||||
Cell/Modules/cellResc.cpp
|
||||
Cell/Modules/cellRtcAlarm.cpp
|
||||
Cell/Modules/cellRtc.cpp
|
||||
Cell/Modules/cellRudp.cpp
|
||||
Cell/Modules/cellSail.cpp
|
||||
Cell/Modules/cellSailRec.cpp
|
||||
Cell/Modules/cellSaveData.cpp
|
||||
Cell/Modules/cellScreenshot.cpp
|
||||
Cell/Modules/cellSearch.cpp
|
||||
Cell/Modules/cellSheap.cpp
|
||||
Cell/Modules/cellSpudll.cpp
|
||||
Cell/Modules/cellSpurs.cpp
|
||||
Cell/Modules/cellSpursJq.cpp
|
||||
Cell/Modules/cellSpursSpu.cpp
|
||||
Cell/Modules/cellSsl.cpp
|
||||
Cell/Modules/cellStorage.cpp
|
||||
Cell/Modules/cellSubDisplay.cpp
|
||||
Cell/Modules/cellSync2.cpp
|
||||
Cell/Modules/cellSync.cpp
|
||||
Cell/Modules/cellSysconf.cpp
|
||||
Cell/Modules/cellSysmodule.cpp
|
||||
Cell/Modules/cellSysutilAp.cpp
|
||||
Cell/Modules/cellSysutilAvc2.cpp
|
||||
Cell/Modules/cellSysutilAvc.cpp
|
||||
Cell/Modules/cellSysutilAvcExt.cpp
|
||||
Cell/Modules/cellSysutil.cpp
|
||||
Cell/Modules/cellSysutilMisc.cpp
|
||||
Cell/Modules/cellSysutilNpEula.cpp
|
||||
Cell/Modules/cellUsbd.cpp
|
||||
Cell/Modules/cellUsbpspcm.cpp
|
||||
Cell/Modules/cellUserInfo.cpp
|
||||
Cell/Modules/cellVdec.cpp
|
||||
Cell/Modules/cellVideoExport.cpp
|
||||
Cell/Modules/cellVideoOut.cpp
|
||||
Cell/Modules/cellVideoPlayerUtility.cpp
|
||||
Cell/Modules/cellVideoUpload.cpp
|
||||
Cell/Modules/cellVoice.cpp
|
||||
Cell/Modules/cellVpost.cpp
|
||||
Cell/Modules/cellWebBrowser.cpp
|
||||
Cell/Modules/libad_async.cpp
|
||||
Cell/Modules/libad_core.cpp
|
||||
Cell/Modules/libmedi.cpp
|
||||
Cell/Modules/libmixer.cpp
|
||||
Cell/Modules/libsnd3.cpp
|
||||
Cell/Modules/libsynth2.cpp
|
||||
Cell/Modules/sceNp2.cpp
|
||||
Cell/Modules/sceNpClans.cpp
|
||||
Cell/Modules/sceNpCommerce2.cpp
|
||||
Cell/Modules/sceNp.cpp
|
||||
Cell/Modules/sceNpMatchingInt.cpp
|
||||
Cell/Modules/sceNpSns.cpp
|
||||
Cell/Modules/sceNpTrophy.cpp
|
||||
Cell/Modules/sceNpTus.cpp
|
||||
Cell/Modules/sceNpUtil.cpp
|
||||
Cell/Modules/StaticHLE.cpp
|
||||
Cell/Modules/sys_game.cpp
|
||||
Cell/Modules/sys_heap.cpp
|
||||
Cell/Modules/sys_io.cpp
|
||||
Cell/Modules/sys_libc_.cpp
|
||||
Cell/Modules/sys_libc.cpp
|
||||
Cell/Modules/sys_lv2dbg.cpp
|
||||
Cell/Modules/sys_lwcond_.cpp
|
||||
Cell/Modules/sys_lwmutex_.cpp
|
||||
Cell/Modules/sys_mempool.cpp
|
||||
Cell/Modules/sys_mmapper_.cpp
|
||||
Cell/Modules/sys_net_.cpp
|
||||
Cell/Modules/sys_ppu_thread_.cpp
|
||||
Cell/Modules/sys_prx_.cpp
|
||||
Cell/Modules/sysPrxForUser.cpp
|
||||
Cell/Modules/sys_rsxaudio_.cpp
|
||||
Cell/Modules/sys_spinlock.cpp
|
||||
Cell/Modules/sys_spu_.cpp
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(Cell/PPUTranslator.cpp PROPERTIES COMPILE_FLAGS -fno-rtti)
|
||||
@@ -63,58 +282,124 @@ target_link_libraries(rpcs3_emu
|
||||
PRIVATE
|
||||
3rdparty::stblib 3rdparty::libpng)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7))
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
target_link_libraries(rpcs3_emu PUBLIC -latomic)
|
||||
endif()
|
||||
|
||||
|
||||
# CPU
|
||||
file(GLOB_RECURSE CPU_SRC_FILES "CPU/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${CPU_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
CPU/CPUThread.cpp
|
||||
CPU/CPUTranslator.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PUBLIC 3rdparty::llvm 3rdparty::asmjit)
|
||||
|
||||
|
||||
# Io
|
||||
file(GLOB_RECURSE IO_SRC_FILES "Io/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${IO_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Io/KeyboardHandler.cpp
|
||||
Io/PadHandler.cpp
|
||||
)
|
||||
|
||||
|
||||
# Memory
|
||||
file(GLOB_RECURSE MEMORY_SRC_FILES "Memory/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE ${MEMORY_SRC_FILES})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
Memory/vm.cpp
|
||||
)
|
||||
|
||||
|
||||
# RSX
|
||||
file(GLOB RSX_SRC_FILES
|
||||
"RSX/*.cpp"
|
||||
"RSX/Common/*.cpp"
|
||||
"RSX/Null/*.cpp"
|
||||
"RSX/Overlays/*.cpp"
|
||||
"RSX/Capture/*.cpp"
|
||||
"RSX/GL/*.cpp")
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
RSX/CgBinaryFragmentProgram.cpp
|
||||
RSX/CgBinaryVertexProgram.cpp
|
||||
RSX/gcm_enums.cpp
|
||||
RSX/gcm_printing.cpp
|
||||
RSX/GSRender.cpp
|
||||
RSX/RSXFIFO.cpp
|
||||
RSX/rsx_methods.cpp
|
||||
RSX/RSXOffload.cpp
|
||||
RSX/RSXTexture.cpp
|
||||
RSX/RSXThread.cpp
|
||||
RSX/rsx_utils.cpp
|
||||
RSX/Common/BufferUtils.cpp
|
||||
RSX/Common/FragmentProgramDecompiler.cpp
|
||||
RSX/Common/ProgramStateCache.cpp
|
||||
RSX/Common/ShaderParam.cpp
|
||||
RSX/Common/surface_store.cpp
|
||||
RSX/Common/TextureUtils.cpp
|
||||
RSX/Common/VertexProgramDecompiler.cpp
|
||||
RSX/Null/NullGSRender.cpp
|
||||
RSX/Overlays/overlay_edit_text.cpp
|
||||
RSX/Overlays/overlay_font.cpp
|
||||
RSX/Overlays/overlay_list_view.cpp
|
||||
RSX/Overlays/overlay_message_dialog.cpp
|
||||
RSX/Overlays/overlay_osk.cpp
|
||||
RSX/Overlays/overlay_perf_metrics.cpp
|
||||
RSX/Overlays/overlay_progress_bar.cpp
|
||||
RSX/Overlays/overlay_save_dialog.cpp
|
||||
RSX/Overlays/overlays.cpp
|
||||
RSX/Overlays/overlay_shader_compile_notification.cpp
|
||||
RSX/Overlays/overlay_trophy_notification.cpp
|
||||
RSX/Capture/rsx_capture.cpp
|
||||
RSX/Capture/rsx_replay.cpp
|
||||
RSX/GL/GLCommonDecompiler.cpp
|
||||
RSX/GL/GLFragmentProgram.cpp
|
||||
RSX/GL/GLGSRender.cpp
|
||||
RSX/GL/GLHelpers.cpp
|
||||
RSX/GL/GLRenderTargets.cpp
|
||||
RSX/GL/GLTexture.cpp
|
||||
RSX/GL/GLVertexBuffers.cpp
|
||||
RSX/GL/GLVertexProgram.cpp
|
||||
RSX/GL/OpenGL.cpp
|
||||
)
|
||||
|
||||
if(TARGET 3rdparty_vulkan)
|
||||
file(GLOB VULKAN_SRCS "RSX/VK/*.cpp")
|
||||
list(APPEND RSX_SRC_FILES ${VULKAN_SRCS})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
RSX/VK/VKCommonDecompiler.cpp
|
||||
RSX/VK/VKFormats.cpp
|
||||
RSX/VK/VKFragmentProgram.cpp
|
||||
RSX/VK/VKFramebuffer.cpp
|
||||
RSX/VK/VKGSRender.cpp
|
||||
RSX/VK/VKHelpers.cpp
|
||||
RSX/VK/VKMemAlloc.cpp
|
||||
RSX/VK/VKProgramPipeline.cpp
|
||||
RSX/VK/VKRenderPass.cpp
|
||||
RSX/VK/VKResolveHelper.cpp
|
||||
RSX/VK/VKResourceManager.cpp
|
||||
RSX/VK/VKTexture.cpp
|
||||
RSX/VK/VKVertexBuffers.cpp
|
||||
RSX/VK/VKVertexProgram.cpp
|
||||
RSX/VK/VulkanAPI.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
file(GLOB DX12_SRCS "RSX/D3D12/*.cpp")
|
||||
list(APPEND RSX_SRC_FILES ${DX12_SRCS})
|
||||
target_sources(rpcs3_emu PRIVATE
|
||||
RSX/D3D12/D3D12Buffer.cpp
|
||||
RSX/D3D12/D3D12CommonDecompiler.cpp
|
||||
RSX/D3D12/D3D12Formats.cpp
|
||||
RSX/D3D12/D3D12FragmentProgramDecompiler.cpp
|
||||
RSX/D3D12/D3D12GSRender.cpp
|
||||
RSX/D3D12/D3D12MemoryHelpers.cpp
|
||||
RSX/D3D12/D3D12Overlay.cpp
|
||||
RSX/D3D12/D3D12PipelineState.cpp
|
||||
RSX/D3D12/D3D12RenderTargetSets.cpp
|
||||
RSX/D3D12/D3D12Texture.cpp
|
||||
RSX/D3D12/D3D12Utils.cpp
|
||||
RSX/D3D12/D3D12VertexProgramDecompiler.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(rpcs3_emu PRIVATE ${RSX_SRC_FILES})
|
||||
|
||||
target_link_libraries(rpcs3_emu
|
||||
PUBLIC
|
||||
3rdparty::ffmpeg 3rdparty::cereal
|
||||
3rdparty::opengl 3rdparty::stblib
|
||||
3rdparty::vulkan
|
||||
3rdparty::vulkan 3rdparty::glew
|
||||
PRIVATE
|
||||
3rdparty::gsl 3rdparty::xxhash
|
||||
3rdparty::dx12 3rdparty::glew)
|
||||
3rdparty::dx12)
|
||||
|
||||
|
||||
# Setup cotire
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user