Compare commits
596 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0064976c43 | |||
| 4bdb6674eb | |||
| c7f7d7ef5b | |||
| 2c19fdf092 | |||
| 8fc9862614 | |||
| 55d84414ee | |||
| 8c0bdd71d9 | |||
| 3c9126d91f | |||
| 8b4836a12f | |||
| b2a7eee1ec | |||
| ed21bb309f | |||
| 7b3e4f5e3d | |||
| 30b3af0d12 | |||
| 541cb4062b | |||
| 4e9160104a | |||
| 86fa379c78 | |||
| 8733505d0a | |||
| 242611aa46 | |||
| baa5a261a5 | |||
| 3730b9d1da | |||
| 0d35363ea0 | |||
| 75504b3f5e | |||
| 4ca98e53a6 | |||
| 300a36d3d6 | |||
| 60c7a508a7 | |||
| 1fa18757fc | |||
| fbb7186e66 | |||
| 0961a43997 | |||
| 7037504dcf | |||
| 2385029eab | |||
| eed55a446c | |||
| bbcb6b6851 | |||
| b95630d84a | |||
| af1d3c2aa6 | |||
| ec3e5c547f | |||
| 963a87fed5 | |||
| 173d05b54f | |||
| 865bb47462 | |||
| 3e7ed8a831 | |||
| 3a49a77c07 | |||
| 6782b22637 | |||
| 4600094829 | |||
| daaa83b9ca | |||
| 3288050680 | |||
| b8c29ae957 | |||
| 47bacc0ef0 | |||
| 3d0dced4bd | |||
| 30bba09fed | |||
| 31b07f2c5c | |||
| f7063bb57b | |||
| e4ef85b6e0 | |||
| b7c2088489 | |||
| 59cd0a9c7f | |||
| af107df0b4 | |||
| 0e7e40f2cb | |||
| 0b788f5b43 | |||
| db5c2500c2 | |||
| a1496eb1f1 | |||
| 4aa89132d7 | |||
| 9b8eb089b1 | |||
| c1f08ce58d | |||
| 09a0d046f4 | |||
| 0741698f13 | |||
| c2ac05f734 | |||
| f8f5f9f418 | |||
| 7e6d6b45d4 | |||
| 361e80f7dc | |||
| 395b4bfa45 | |||
| ce2b790d8f | |||
| 1ffc1e82b0 | |||
| 8520ca7ef7 | |||
| 89fba1c385 | |||
| 00a0d37455 | |||
| dbb2251f93 | |||
| 7abf755a57 | |||
| 055f0e2e4a | |||
| 49f4da3016 | |||
| bf234dc668 | |||
| 11bd65c2b5 | |||
| e0d1ac676e | |||
| 494cbac78b | |||
| 0d46a8e786 | |||
| 626b9f93c4 | |||
| 53f9defb07 | |||
| 4bf8d1e41f | |||
| 936c817bd8 | |||
| 9c9495621c | |||
| d53673c6f7 | |||
| 882e949f80 | |||
| e6849a59a2 | |||
| 6918e265ec | |||
| e9f293f522 | |||
| 5fc36d64b6 | |||
| 95e6d78689 | |||
| f4a666345a | |||
| 7a5c88a8d1 | |||
| 0de0dded53 | |||
| 5e58cf6079 | |||
| b0737d1c90 | |||
| 779ed75a19 | |||
| dbf1573e89 | |||
| 96fd8556f2 | |||
| 8f324dfc0a | |||
| 34a6085cc0 | |||
| b3efa75206 | |||
| b90a7dc66a | |||
| 200557c036 | |||
| 472cb3b1c2 | |||
| d8ee6a2edb | |||
| ddcacb8258 | |||
| a8e1754fa4 | |||
| 5db45c3699 | |||
| 89dcafbe41 | |||
| 3d05e61f7e | |||
| 5146f3ec47 | |||
| 170a95f5df | |||
| c661578906 | |||
| f20e0c2898 | |||
| 64b2ae3cd5 | |||
| a11d66f52d | |||
| 304a4a1b61 | |||
| 76b7103fed | |||
| 1572d01c53 | |||
| 86bf61ad35 | |||
| 479aa91368 | |||
| bb398c4a08 | |||
| eab9d06981 | |||
| c63ff05e6e | |||
| 0129c54ab6 | |||
| c570410e06 | |||
| 9af71699a4 | |||
| 58860614e3 | |||
| e8bde583ef | |||
| 5b19908996 | |||
| 19f3bb8cb0 | |||
| ac64792d99 | |||
| efe140bc0c | |||
| df2fc13b7a | |||
| f5d450f24c | |||
| 2e5f8c0786 | |||
| 9bcc298b18 | |||
| 5a03db7d2e | |||
| 91ef202ee7 | |||
| 6d6b281270 | |||
| a3c49bea2c | |||
| 1d375cb13c | |||
| 20ad9a13b8 | |||
| fc0f98b5db | |||
| 3fe37ede97 | |||
| 55df3cdf67 | |||
| 6e8107a5cb | |||
| 7bee4064a6 | |||
| 12ab03b0b5 | |||
| 47202d5839 | |||
| 47b121a700 | |||
| d53b640bcf | |||
| 78ef467138 | |||
| b7f6bd4c91 | |||
| e272acd7c1 | |||
| 93d2ac887d | |||
| a84cc1d3bb | |||
| cc594ad353 | |||
| beab5291bb | |||
| 3907dd0444 | |||
| 3d64b65813 | |||
| ab4e66a0bf | |||
| 144f6809bf | |||
| d296e6021d | |||
| 45a855ef1f | |||
| e5f756205c | |||
| 6335fa8df1 | |||
| b2605206b1 | |||
| 33182650ca | |||
| 0ca1f82059 | |||
| 0c5cb4824b | |||
| cf83b796e1 | |||
| b338c81907 | |||
| 81b3e7e449 | |||
| 425ddd13e5 | |||
| eb8af974dc | |||
| 3067c8bd27 | |||
| 632c8872cd | |||
| 9650218bb8 | |||
| 0b51102167 | |||
| ca36d08893 | |||
| a358384900 | |||
| 77a75305c7 | |||
| 85b9809b39 | |||
| d36de7d54f | |||
| 2b1c757084 | |||
| e7db0c7d99 | |||
| 393e3b702f | |||
| 23ad687e7e | |||
| a04ecdbe0a | |||
| 9ee21af524 | |||
| b74cdcde00 | |||
| 4d83d749a0 | |||
| 8e66e719fa | |||
| c6e6f4afea | |||
| d0148728c6 | |||
| dfc564f837 | |||
| 2b0edf6cde | |||
| daa7520d1d | |||
| 3499d089e7 | |||
| 6b96a2022a | |||
| 3836b40bf7 | |||
| 571dbfb7b1 | |||
| 10e25eb362 | |||
| 45d0e821dc | |||
| e37a2a8f7d | |||
| 07c83f6e44 | |||
| 061824a7ec | |||
| abb56a354d | |||
| 9359b8c170 | |||
| 2d0f1f27a8 | |||
| 73312fc363 | |||
| deb590cb05 | |||
| 2033f3f7dc | |||
| 3e3160d7ac | |||
| dd919c76b8 | |||
| a6a0f13264 | |||
| b9a0c107ab | |||
| 5c93acefd9 | |||
| a428dac71c | |||
| 3901f08fa0 | |||
| 519f21db18 | |||
| 18d472b7e1 | |||
| bc098d6b9c | |||
| 22ff8abd7d | |||
| 871ccfd32c | |||
| 7a79e184c5 | |||
| 0e72cc879f | |||
| 13304bd18b | |||
| a4b824c50a | |||
| ccc87081f3 | |||
| 800ba9d902 | |||
| 015b9fdf8b | |||
| 83f93202d0 | |||
| ae2ea02377 | |||
| 4fe4521881 | |||
| b83575bcbb | |||
| 17175e1c23 | |||
| cc57719856 | |||
| b9b71ccbc1 | |||
| e789b969b0 | |||
| be44024a1a | |||
| c7d4a30646 | |||
| 837c5dddee | |||
| 669b1385cc | |||
| 01ffaab3e0 | |||
| d5fb7180d0 | |||
| b141b43c1c | |||
| cad91e114d | |||
| db51779682 | |||
| c18e71ca29 | |||
| 6a54b3929e | |||
| 07af701afe | |||
| 669d953529 | |||
| 22d8b57027 | |||
| 0e691e2c51 | |||
| ae1e9e78db | |||
| e00aedd1a0 | |||
| 4a10dcc549 | |||
| 553f67d7e3 | |||
| fac8a520f0 | |||
| f0358f85fc | |||
| 4b9fa8ec6d | |||
| 45cdf6af3b | |||
| 47685bef39 | |||
| b11f9e0405 | |||
| 84e7de0a78 | |||
| f39e2b999f | |||
| cd4b28b4d7 | |||
| 2db2114a45 | |||
| 4b11a62b4d | |||
| 0457f23b13 | |||
| a6ba7ed21c | |||
| 5326912bc0 | |||
| be46c82aaa | |||
| 43bae9f9d7 | |||
| 95231c4dee | |||
| a95e01290e | |||
| 0cbbd3a5b1 | |||
| d8f3354ce3 | |||
| e4105f46de | |||
| 9a1ee9e984 | |||
| 7c897d5019 | |||
| bfe2bccc51 | |||
| 11aa0be04a | |||
| d2cae96e8d | |||
| 8e955297ef | |||
| 205f6a9000 | |||
| 4558f93f92 | |||
| 634c411946 | |||
| d4d0d35e05 | |||
| f4f36a3cb1 | |||
| 21d70a75d5 | |||
| 47ed9aa1b9 | |||
| b60ac78c58 | |||
| 83e139cd1a | |||
| b415b0e737 | |||
| 2e510e5ca0 | |||
| 1262263f5c | |||
| 9b9e2bcafb | |||
| cde29aba64 | |||
| 34cf1ff7c7 | |||
| cc880b53aa | |||
| 8ad44dd00f | |||
| 9440e65452 | |||
| 5cb6815bf3 | |||
| caab400258 | |||
| d3f13ab8a3 | |||
| ca6064b109 | |||
| e57caefd09 | |||
| 7e99f6bc5f | |||
| a85caaee1d | |||
| 5b00aaf561 | |||
| 174f11bdbd | |||
| 05442bdb11 | |||
| 9ba3cea2b1 | |||
| 20d48289b8 | |||
| 8f9410ceff | |||
| 3a08dd7dde | |||
| cfb858a51c | |||
| 37d7fdbcae | |||
| 62c14e9437 | |||
| 90b8346312 | |||
| 167d6a08f8 | |||
| 649d68a00f | |||
| 8807cd06b7 | |||
| b533d57717 | |||
| 14a6269243 | |||
| 7b96190e6c | |||
| 010b75251f | |||
| da3f3fd1fb | |||
| 26e13b4f5f | |||
| a771fcb397 | |||
| 64a6fbe39f | |||
| 43b860d267 | |||
| 818df50bb5 | |||
| 2570911283 | |||
| f59a448f3f | |||
| 834712bb58 | |||
| d98f739043 | |||
| aa5dc5455e | |||
| dfc970c926 | |||
| 68ecf340c5 | |||
| 3d626e84ef | |||
| 95abf768a7 | |||
| cb00190c3e | |||
| 8fdf1b23a3 | |||
| 2e9405db4c | |||
| fe5828cb47 | |||
| e56d8db6a3 | |||
| e76b6e3f27 | |||
| 9a7ce2fd29 | |||
| 462b93f62c | |||
| f71f67c4ff | |||
| 8358bda133 | |||
| 85199e200b | |||
| 5681801b85 | |||
| 86ef07b166 | |||
| 00339cb99b | |||
| daf3760cd4 | |||
| c1450ad616 | |||
| 025a09ed87 | |||
| 1716db14ed | |||
| d0e171784c | |||
| a68983b551 | |||
| c7c0139788 | |||
| 37bc2b3bb9 | |||
| c85806c422 | |||
| ee98683538 | |||
| a822d990d2 | |||
| 33d3303bdf | |||
| 8b35df8327 | |||
| 0854ed2b51 | |||
| 713c1a7a86 | |||
| fb816a0eb9 | |||
| fff62df6a2 | |||
| e6a07e80d7 | |||
| 514a98321d | |||
| 36ac35361f | |||
| bc7d728eb3 | |||
| 66a43c35db | |||
| e9f057c91b | |||
| 196cdfafa6 | |||
| 590ca7115f | |||
| 650db9c962 | |||
| 5d7c454e52 | |||
| 4d5f98017f | |||
| 7ecf6cb014 | |||
| 9d1aebce74 | |||
| dc9671c639 | |||
| 93bfe8164c | |||
| d6329eaa1a | |||
| f21a3069a5 | |||
| a8b989b51d | |||
| 142bfb5250 | |||
| 334327df67 | |||
| 2400210144 | |||
| 1b1c300aad | |||
| 531b03e7af | |||
| 650c1c64f1 | |||
| 2fd4726919 | |||
| b86745ee4e | |||
| c04aa05398 | |||
| 3c9bab8563 | |||
| 0dc24799f1 | |||
| 6eb1786635 | |||
| bbf2a97d2e | |||
| 00c6a589a5 | |||
| c7dca1dbef | |||
| 1da732bbf5 | |||
| 00b0311c86 | |||
| 6a707f515e | |||
| c0409a819e | |||
| b2b5f564a1 | |||
| d54c2dd39a | |||
| e668ecd453 | |||
| 0020359b8f | |||
| a0176775ff | |||
| a18fddb831 | |||
| ea462ae7d7 | |||
| 6d14583f28 | |||
| 956117a74f | |||
| 0c1d4e43e4 | |||
| ae156801df | |||
| 844e09c40e | |||
| 81da93a302 | |||
| e0508c6c64 | |||
| db9618ac2f | |||
| a38182b967 | |||
| 474bd7beaf | |||
| d8c449aadf | |||
| 2c611ec0ba | |||
| b44f5e59ac | |||
| 0ad0510624 | |||
| d2fb69cda3 | |||
| 2047cb8d1d | |||
| 24f9f06279 | |||
| b671bb72dc | |||
| af11ad6253 | |||
| 0d9b89fb34 | |||
| 80fee5ac1e | |||
| a909bd6edd | |||
| eeb4d4d4de | |||
| 4c42043940 | |||
| 6136abd0f8 | |||
| 69a5f3d58b | |||
| 98ef419abd | |||
| 77354f0f90 | |||
| 108f87c08f | |||
| 08e2698b9c | |||
| 6e81db7b43 | |||
| e9f12ae30a | |||
| 2f977aae18 | |||
| 0e5a862d8a | |||
| 1e46cd255b | |||
| e5e6af41a6 | |||
| ce437eb8d2 | |||
| 4c019c55d2 | |||
| ae440a92ac | |||
| 54d2e8bfdd | |||
| 3f206981d9 | |||
| fa7407cd42 | |||
| 866b9524b3 | |||
| d1cde4d0a7 | |||
| b01e7e3362 | |||
| e9b020beaa | |||
| 2fcd38c2bc | |||
| 300b34e268 | |||
| ce0e87373d | |||
| 7e1c6a5819 | |||
| 613214cdca | |||
| 009f53a267 | |||
| f3ad922a8f | |||
| 7b27a8e993 | |||
| fcb7072fee | |||
| 7ab1792ef7 | |||
| 40d305b35d | |||
| 2d7e91ba8a | |||
| b05434bc6f | |||
| 7b4c044480 | |||
| c14eb4e54a | |||
| f6c8f46462 | |||
| faf9ed9fec | |||
| 930ce4af60 | |||
| d51a986dd4 | |||
| 02845f546e | |||
| fff34a7f0f | |||
| 21dd715b42 | |||
| d9a693019b | |||
| 607d2486ea | |||
| 77f58326af | |||
| bf14cbdb27 | |||
| 93db420f80 | |||
| a209d0d7fa | |||
| f564a72d03 | |||
| aeb01bd216 | |||
| bc4d73da02 | |||
| f9e996e006 | |||
| 4dbc546e7b | |||
| 9a1a7dd531 | |||
| 7ac96f7526 | |||
| f613901eac | |||
| 4cd5624fa7 | |||
| fc6891a0e3 | |||
| fb7ccbd7b4 | |||
| 17c399d4e8 | |||
| dd19622823 | |||
| 46fa6e47fe | |||
| 7fa42cfaad | |||
| 5d8640109d | |||
| 6f6b23e879 | |||
| d2116a187e | |||
| f58652e51c | |||
| bf53035e3f | |||
| 60c6bb9865 | |||
| 67b71c0f89 | |||
| 5766fb1f31 | |||
| dbd69536ed | |||
| 08f0047529 | |||
| 54a38aa927 | |||
| 173cc13d01 | |||
| 1899f399b6 | |||
| 4c5921a7a4 | |||
| be84dd73a9 | |||
| 9f3f07f3ae | |||
| d260ccfc96 | |||
| 1c3b9754aa | |||
| 37c26b77ee | |||
| ff772dd28b | |||
| 60e2928ec1 | |||
| f8e57147b0 | |||
| 1bef748dc4 | |||
| b2fa0fdf53 | |||
| ab198c0c5f | |||
| f577af452d | |||
| a7802e9377 | |||
| 3b03f9a010 | |||
| cb194e06ce | |||
| a24780fe5e | |||
| a7c28f5827 | |||
| 425821863b | |||
| 8db6555bdb | |||
| 6557bf1b20 | |||
| 6648084c64 | |||
| 5543441618 | |||
| 0508e1e638 | |||
| adf119e960 | |||
| 2bc57fbee3 | |||
| 42b06af577 | |||
| f9a69c449d | |||
| 3f9affd2ad | |||
| 23701248f3 | |||
| c9abab6828 | |||
| 9dc9378bcc | |||
| 5cc152b8dd | |||
| 9bd6d28514 | |||
| 58816e314c | |||
| e93fbc6900 | |||
| f8c2e198c5 | |||
| f69e252c7a | |||
| 96dfa9b526 | |||
| 2b24635ef7 | |||
| fde6099769 | |||
| 7b3693bb29 | |||
| df8fa74e2a | |||
| 9747ab61f9 | |||
| d7e72797a8 | |||
| 0dfd2eadc1 | |||
| 291ec1eeb2 | |||
| b24eb621ae | |||
| 0fa148e65e | |||
| 3f6b24d33a | |||
| 9fee2ebeb5 | |||
| 99828a8f15 | |||
| 2526626646 | |||
| 582913dc31 | |||
| 94c1b74a17 | |||
| cbd1b28d0d | |||
| 05ffb50037 | |||
| 72e13ddeb2 | |||
| 78f09d7645 | |||
| f69121116a | |||
| 0136215ef1 | |||
| ab534ac55d | |||
| 67bbd59924 | |||
| f0b1a587aa | |||
| ae8f858c56 | |||
| 7426eb285f | |||
| f91f2e3e6d | |||
| e39ee10105 | |||
| 2ef2f0f63b | |||
| e875c91121 |
@@ -0,0 +1,24 @@
|
||||
<!---
|
||||
|
||||
THIS IS NOT A SUPPORT FORUM, FOR SUPPORT GO TO:
|
||||
https://forums.rpcs3.net
|
||||
or our discord:
|
||||
https://discord.me/RPCS3
|
||||
|
||||
PLEASE READ THE GUIDELINES BEFORE OPENING AN ISSUE:
|
||||
https://github.com/RPCS3/rpcs3/blob/master/CONTRIBUTING.md
|
||||
|
||||
====================================================
|
||||
|
||||
When submitting an issue, please check the following:
|
||||
|
||||
- You have read the above.
|
||||
- You have provided the version (commit hash) of RPCS3 you are using.
|
||||
- You have provided sufficient detail for the issue to be reproduced.
|
||||
- You have provided system specs.
|
||||
- Please also provide:
|
||||
- For crashes, a backtrace.
|
||||
- For graphical issues, comparison screenshots with real hardware.
|
||||
|
||||
Remember that the GitHub Issue Tracker is not the place to ask for support or to submit Game Compatibility reports. You must use our forums for that.
|
||||
--->
|
||||
@@ -41,6 +41,10 @@
|
||||
/Vulkan/Vulkan-build
|
||||
/Vulkan/glslang-build
|
||||
|
||||
# Themes
|
||||
!/bin/GuiConfigs/
|
||||
/bin/GuiConfigs/*.ini
|
||||
|
||||
/bin/rpcs3.ini
|
||||
/bin/rpcs3.ipdb
|
||||
/bin/rpcs3.iobj
|
||||
@@ -70,6 +74,7 @@ rpcs3/git-version.h
|
||||
!/bin/dev_hdd0/game/
|
||||
/bin/dev_hdd0/game/*
|
||||
!/bin/dev_hdd0/game/TEST12345/
|
||||
/bin/dev_hdd0/disc/*
|
||||
|
||||
# Ignore other system generated files
|
||||
bin/dev_hdd0/*.txt
|
||||
|
||||
+4
-7
@@ -9,9 +9,6 @@
|
||||
path = llvm
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
branch = release_40
|
||||
[submodule "rsx_program_decompiler"]
|
||||
path = rsx_program_decompiler
|
||||
url = https://github.com/RPCS3/rsx_program_decompiler
|
||||
[submodule "GSL"]
|
||||
path = 3rdparty/GSL
|
||||
url = https://github.com/Microsoft/GSL.git
|
||||
@@ -34,13 +31,13 @@
|
||||
[submodule "3rdparty/cereal"]
|
||||
path = 3rdparty/cereal
|
||||
url = https://github.com/USCiLab/cereal.git
|
||||
[submodule "rsx-debugger"]
|
||||
path = rsx-debugger
|
||||
url = https://github.com/RPCS3/rsx-debugger.git
|
||||
[submodule "3rdparty/zlib"]
|
||||
path = 3rdparty/zlib
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "3rdparty/hidapi"]
|
||||
path = 3rdparty/hidapi
|
||||
url = https://github.com/RPCS3/hidapi
|
||||
branch = master
|
||||
branch = master
|
||||
[submodule "3rdparty/Optional"]
|
||||
path = 3rdparty/Optional
|
||||
url = https://github.com/akrzemi1/Optional.git
|
||||
|
||||
+33
-50
@@ -1,6 +1,5 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
os:
|
||||
- linux
|
||||
@@ -17,23 +16,10 @@ cache:
|
||||
directories:
|
||||
- $HOME/hombebrew_cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: BXyNziNYFLqLtY6Q58BDEUpRJr81HUtHpxf2Sr646bDcbG0Rf2rb2utqHZJ1Om926WdH7RqHuoVti4dr2X1lh4nHMkLD7MrIrfIkNN5T9aZdk19uw9IyMtz/cXon7/wqVo24tVqtBI0UghFxKii/GTDJEvRKgfpPp1e1vKSNGa4=
|
||||
# Which Travis environment to run Coverity on
|
||||
- coverity_scan_run_condition='"$TRAVIS_OS_NAME" = linux -a "$CC" = gcc'
|
||||
# Test mode is for testing if it's working with Coverity. Change to true if testing, to avoid reaching the quota.
|
||||
- coverity_scan_script_test_mode=false
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
include:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: WITHOUT_LLVM="yes"
|
||||
|
||||
|
||||
git:
|
||||
submodules: false
|
||||
@@ -44,54 +30,58 @@ before_install:
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
|
||||
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
|
||||
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01';
|
||||
fi;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y;
|
||||
sudo apt-get update;
|
||||
sudo apt-get install qt59base -y --allow-unauthenticated;
|
||||
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run ;
|
||||
chmod a+x ./qt-unified-linux-x64-online.run ;
|
||||
export QT_QPA_PLATFORM=minimal ;
|
||||
./qt-unified-linux-x64-online.run --script qt-installer-noninteractive.qs --no-force-installations ;
|
||||
fi;
|
||||
# Add coverall for C++ so coverall.io could be triggered. Even it should be --coverage and gcov.
|
||||
|
||||
# Install updated libglew-dev since the version provided by trusty is outdated
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
pip install --user cpp-coveralls requests[security];
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew-dev_1.13.0-2_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/main/g/glew/libglew1.13_1.13.0-2_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.21.0+dfsg1-1~16.04.1_amd64.deb libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
sudo dpkg -i libglew1.13_1.13.0-2_amd64.deb libglew-dev_1.13.0-2_amd64.deb libvulkan1_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb libvulkan-dev_1.0.42.0+dfsg1-1ubuntu1~16.04.1_amd64.deb;
|
||||
else
|
||||
brew update; brew update;
|
||||
brew update;
|
||||
brew install ccache glew llvm40;
|
||||
fi;
|
||||
|
||||
before_script:
|
||||
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
- source /opt/qt59/bin/qt59-env.sh
|
||||
- git submodule update --init asmjit 3rdparty/ffmpeg 3rdparty/pugixml 3rdparty/GSL 3rdparty/libpng Utilities/yaml-cpp 3rdparty/cereal 3rdparty/hidapi 3rdparty/Optional Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [ -z "$WITHOUT_LLVM" ]; then
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
|
||||
- export CMAKE_PREFIX_PATH=~/Qt/5.9.2/gcc_64/lib/cmake
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
|
||||
else
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DWITHOUT_LLVM=ON;
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/#$TRAVIS_PULL_REQUEST";
|
||||
fi;
|
||||
- cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
|
||||
- make -j 3
|
||||
- # AppImage generation
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export LD_LIBRARY_PATH=${PWD}/3rdparty/libpng:/opt/qt59/lib/:$LD_LIBRARY_PATH ;
|
||||
- if [ -n "$UPLOAD_URL" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$CC" = "clang-4.0" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export LD_LIBRARY_PATH=~/Qt/5.9.2/gcc_64/lib;
|
||||
make DESTDIR=appdir install ; find appdir/ ;
|
||||
find ../bin ;
|
||||
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" ;
|
||||
chmod a+x linuxdeployqt*.AppImage ;
|
||||
unset QTDIR; unset QT_PLUGIN_PATH ;
|
||||
export PATH=~/Qt/5.9.2/gcc_64/bin/:${PATH} ;
|
||||
./linuxdeployqt*.AppImage --appimage-extract ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage ;
|
||||
mkdir ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
mkdir ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/lib/libQt5Svg.so.5 ./appdir/usr/lib/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/xcbglintegrations/* ./appdir/usr/plugins/xcbglintegrations/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/imageformats/* ./appdir/usr/plugins/imageformats/ ;
|
||||
cp ~/Qt/5.9.2/gcc_64/plugins/platforms/* ./appdir/usr/plugins/platforms/ ;
|
||||
export PATH=${TRAVIS_BUILD_DIR}/build/squashfs-root/usr/bin/:${PATH} ;
|
||||
./squashfs-root/usr/bin/appimagetool ${TRAVIS_BUILD_DIR}/build/appdir ;
|
||||
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
|
||||
zip -r9 rpcs3.zip ./RPCS3*.AppImage;
|
||||
if [ -z "$WITHOUT_LLVM" ]; then
|
||||
export LLVM="-LLVM";
|
||||
fi;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}${LLVM}_linux64 --upload-file rpcs3.zip;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}_linux64 --upload-file ./RPCS3*.AppImage;
|
||||
fi;
|
||||
|
||||
script:
|
||||
@@ -99,14 +89,15 @@ script:
|
||||
#- echo "--Shell Export Lists START--" ; export -p; echo "--Shell Export Lists STOP--";
|
||||
# And to ensure the versions of toolchain
|
||||
- echo "--CXX version?"; "$CXX" --version; echo "--CXX version confirmed";
|
||||
#- if [ "$COVERITY_SCAN_BRANCH" != 1 ]; then make -j 3; fi
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- sourceline: 'ppa:jonathonf/binutils' # We need to update binutils to a newer version to link against the ffmpeg libs on.
|
||||
packages:
|
||||
- binutils
|
||||
- cmake
|
||||
- libasound2-dev
|
||||
- libopenal-dev
|
||||
@@ -124,16 +115,8 @@ addons:
|
||||
- libstdc++-5-dev
|
||||
- lib32stdc++6
|
||||
- zlib1g-dev
|
||||
# We need to install qt 5.8 manually because the version trusty provides is too old.
|
||||
# We need to install qt 5.9.2 manually because the version trusty provides is too old.
|
||||
#- qtbase5-dev
|
||||
- libudev-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: $TRAVIS_REPO_SLUG
|
||||
description: "PS3 emulator/debugger"
|
||||
notification_email: nekotekina@gmail.com
|
||||
build_command: "make -j 3"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
after_success:
|
||||
- if [ "$COVERITY_SCAN_BRANCH" != 1 ] && [ "$TRAVIS_OS_NAME" = linux ]; then coveralls --extension .c --extension .cpp --extension .h; fi
|
||||
- libevdev-dev
|
||||
- libpulse-dev
|
||||
|
||||
+1
Submodule 3rdparty/Optional added at f27e79084a
Vendored
+1
-1
Submodule 3rdparty/ffmpeg updated: 8dd84dc1ea...7b7ae7b067
Vendored
+1
-1
Submodule 3rdparty/hidapi updated: c095a22c53...ca39ce8939
+2
-2
@@ -1,6 +1,6 @@
|
||||
# Getting Started
|
||||
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](http://www.emunewz.net/forum/forumdisplay.php?fid=172).
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](https://forums.rpcs3.net).
|
||||
|
||||
# Issue Reporting
|
||||
|
||||
@@ -13,7 +13,7 @@ Before getting started using the emulator, read the [Quickstart Guide](https://r
|
||||
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message.
|
||||
- While reporting issues, don't forget to include details about your system (OS, CPU, GPU, etc.), as well as the RPCS3.log file.
|
||||
|
||||
Submitting your test results for Commercial Games must be done on our forums' [Commercial Games](http://www.emunewz.net/forum/forumdisplay.php?fid=193) section. If there's already a thread for the game you want to report post in it, otherwise please make a new thread following the [Guidelines for submitting new games](http://www.emunewz.net/forum/showthread.php?tid=174376).
|
||||
Submitting your test results for Commercial Games must be done on our forums. Please read the [Game Compatibility](https://github.com/RPCS3/rpcs3/wiki/Game-Compatibility) wiki page before doing so.
|
||||
|
||||
# Contributing
|
||||
|
||||
|
||||
@@ -3,14 +3,13 @@ RPCS3
|
||||
|
||||
[](https://travis-ci.org/RPCS3/rpcs3)
|
||||
[](https://ci.appveyor.com/project/rpcs3/rpcs3/branch/master)
|
||||
[](https://scan.coverity.com/projects/3960)
|
||||
|
||||
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
|
||||
|
||||
You can find some basic information in our [**website**](https://rpcs3.net/).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](http://www.emunewz.net/forum/forumdisplay.php?fid=172) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
|
||||
[**Support Lead Developer Nekotekina on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
|
||||
|
||||
## Development
|
||||
@@ -21,11 +20,11 @@ If you want to contribute please take a look at the [Coding Style](https://githu
|
||||
## Dependencies
|
||||
|
||||
### Windows
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx)
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/vs/older-downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
|
||||
* [Qt 5.7+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.7\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Qt 5.8+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.8\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
|
||||
|
||||
### Linux
|
||||
@@ -33,12 +32,13 @@ If you want to contribute please take a look at the [Coding Style](https://githu
|
||||
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
|
||||
* Arch: `sudo pacman -S glew openal cmake llvm qt5-base`
|
||||
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel libGLEW`
|
||||
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel glew glew-devel`
|
||||
**If you have a NVIDIA GPU, you may need to install the libglvnd package.**
|
||||
|
||||
### Mac OSX
|
||||
Mac OSX is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
### MacOS
|
||||
MacOS is not supported at this moment because it doesn't meet system requirements (OpenGL 4.3)
|
||||
* Xcode 6+ (tested with Xcode 6.4)
|
||||
* Install with Homebrew: `brew install glew`
|
||||
* Install with Homebrew: `brew install glew llvm qt cmake`
|
||||
|
||||
|
||||
## Building on Windows:
|
||||
@@ -47,10 +47,10 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
### Configuring Qt
|
||||
|
||||
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.7\msvc2015_64\` </br>
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.8\msvc2015_64\` </br>
|
||||
|
||||
*If you wish to use the Visual Studio plugin for Qt:* </br>
|
||||
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.7\msvc2015_64`. </br>
|
||||
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.8\msvc2015_64`. </br>
|
||||
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
### Building the projects
|
||||
@@ -58,27 +58,39 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
2) Press *BUILD* > *Build Solution* or *Rebuild Solution*. </br>
|
||||
|
||||
|
||||
## Building on Linux & Mac OSX:
|
||||
## Building on Linux & Mac OS:
|
||||
|
||||
1) `git clone https://github.com/RPCS3/rpcs3.git` </br>
|
||||
2) `cd rpcs3/` </br>
|
||||
3) `git submodule update --init` </br>
|
||||
4) `cmake CMakeLists.txt && make GitVersion && make` </br>
|
||||
4) `cd ../ && mkdir rpcs3_build && cd rpcs3_build`
|
||||
4) `cmake ../rpcs3/ && make GitVersion && make` </br>
|
||||
5) Run RPCS3 with `./bin/rpcs3` </br>
|
||||
|
||||
If you are on OSX and want to build with llvm don't forget to add `-DLLVM_DIR=...` (or wherever llvm brew was installed) to cmake invocation.
|
||||
If you are on MacOS and want to build with brew llvm and qt don't forget to add the following environment variables
|
||||
|
||||
* `LLVM_DIR=/usr/local/opt/llvm/` (or wherever llvm was installed).
|
||||
* `Qt5_DIR=/usr/local/opt/qt/lib/cmake/Qt5` (or wherever qt was installed).
|
||||
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
|
||||
|
||||
## CMake Build Options (Linux & Mac OSX)
|
||||
## CMake Build Options (Linux & Mac OS)
|
||||
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*) </br>
|
||||
- ```-DUSE_SYSTEM_LIBPNG=ON/OFF``` (default = *OFF*)
|
||||
Build against the shared libpng instead of using the builtin one. libpng 1.6+ highly recommended. Try this option if you get version conflict errors or only see black game icons.
|
||||
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*) </br>
|
||||
- ```-DUSE_SYSTEM_FFMPEG=ON/OFF``` (default = *OFF*)
|
||||
Build against the shared ffmpeg libraries instead of using the builtin patched version. Try this if the builtin version breaks the OpenGL renderer for you.
|
||||
|
||||
- ```-DWITHOUT_LLVM=ON/OFF``` (default = *OFF*)
|
||||
This forces RPCS3 to build without LLVM, not recommended.
|
||||
|
||||
- ```-DWITH_GDB=ON/OFF``` (default = *OFF*)
|
||||
This Builds RPCS3 with support for debugging PS3 games using gdb.
|
||||
|
||||
- ```-DUSE_VULKAN=ON/OFF``` (default = *ON*)
|
||||
This builds RPCS3 with Vulkan support.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+27
-3
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
logs::channel cfg("CFG");
|
||||
@@ -48,6 +50,11 @@ namespace cfg
|
||||
static void decode(const YAML::Node& data, class _base& rhs);
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
{
|
||||
return {std::to_string(min), std::to_string(max)};
|
||||
}
|
||||
|
||||
bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
{
|
||||
// TODO: this could be rewritten without exceptions (but it should be as safe as possible and provide logs)
|
||||
@@ -82,6 +89,8 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
|
||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
|
||||
{
|
||||
u64 max = -1;
|
||||
|
||||
for (u64 i = 0;; i++)
|
||||
{
|
||||
std::string var;
|
||||
@@ -99,6 +108,8 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
max = i;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -108,14 +119,22 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
|
||||
if (pos != value.size())
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): unexpected characters (pos=%zu)", value, pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val > max)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out) *out = val;
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): invalid enum value: %s", value, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -268,14 +287,19 @@ std::string cfg::node::to_string() const
|
||||
YAML::Emitter out;
|
||||
cfg::encode(out, *this);
|
||||
|
||||
return{ out.c_str(), out.size() };
|
||||
return {out.c_str(), out.size()};
|
||||
}
|
||||
|
||||
bool cfg::node::from_string(const std::string& value)
|
||||
bool cfg::node::from_string(const std::string& value) try
|
||||
{
|
||||
cfg::decode(YAML::Load(value), *this);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cfg.fatal("%s thrown: %s", typeid(e).name(), e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
void cfg::node::from_default()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
// Format min and max values
|
||||
std::vector<std::string> make_int_range(s64 min, s64 max);
|
||||
|
||||
// Convert string to signed integer
|
||||
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
|
||||
|
||||
@@ -249,6 +252,11 @@ namespace cfg
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return make_int_range(Min, Max);
|
||||
}
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
|
||||
+79
-23
@@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
@@ -93,6 +94,9 @@ static fs::error to_error(DWORD e)
|
||||
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
||||
case ERROR_DIRECTORY: return fs::error::inval;
|
||||
case ERROR_INVALID_NAME: return fs::error::inval;
|
||||
case ERROR_SHARING_VIOLATION: return fs::error::acces;
|
||||
case ERROR_DIR_NOT_EMPTY: return fs::error::notempty;
|
||||
case ERROR_NOT_READY: return fs::error::noent;
|
||||
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
|
||||
}
|
||||
}
|
||||
@@ -127,6 +131,7 @@ static fs::error to_error(int e)
|
||||
case EEXIST: return fs::error::exist;
|
||||
case EINVAL: return fs::error::inval;
|
||||
case EACCES: return fs::error::acces;
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
default: fmt::throw_exception("Unknown system error: %d.", e);
|
||||
}
|
||||
}
|
||||
@@ -509,7 +514,7 @@ bool fs::remove_dir(const std::string& path)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs::rename(const std::string& from, const std::string& to)
|
||||
bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
|
||||
{
|
||||
const auto device = get_virtual_device(from);
|
||||
|
||||
@@ -524,14 +529,43 @@ bool fs::rename(const std::string& from, const std::string& to)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get()))
|
||||
const auto ws1 = to_wchar(from);
|
||||
const auto ws2 = to_wchar(to);
|
||||
|
||||
if (!MoveFileExW(ws1.get(), ws2.get(), overwrite ? MOVEFILE_REPLACE_EXISTING : 0))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
DWORD error1 = GetLastError();
|
||||
|
||||
if (overwrite && error1 == ERROR_ACCESS_DENIED && is_dir(from) && is_dir(to))
|
||||
{
|
||||
if (RemoveDirectoryW(ws2.get()))
|
||||
{
|
||||
if (MoveFileW(ws1.get(), ws2.get()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
error1 = GetLastError();
|
||||
CreateDirectoryW(ws2.get(), NULL); // TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
error1 = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
g_tls_error = to_error(error1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
if (!overwrite && exists(to))
|
||||
{
|
||||
g_tls_error = fs::error::exist;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::rename(from.c_str(), to.c_str()) != 0)
|
||||
{
|
||||
g_tls_error = to_error(errno);
|
||||
@@ -645,18 +679,17 @@ bool fs::truncate_file(const std::string& path, u64 length)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
LARGE_INTEGER distance;
|
||||
distance.QuadPart = length;
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
|
||||
// Seek and truncate
|
||||
if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle))
|
||||
if (!SetFileInformationByHandle(handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
CloseHandle(handle);
|
||||
@@ -685,7 +718,7 @@ bool fs::utime(const std::string& path, s64 atime, s64 mtime)
|
||||
|
||||
#ifdef _WIN32
|
||||
// Open the file
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
const auto handle = CreateFileW(to_wchar(path).get(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
@@ -764,7 +797,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
||||
}
|
||||
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
DWORD share = FILE_SHARE_READ;
|
||||
if (!test(mode & fs::unshare))
|
||||
{
|
||||
share |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
}
|
||||
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -772,7 +811,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class windows_file final : public file_base
|
||||
class windows_file final : public file_base, public get_native_handle
|
||||
{
|
||||
const HANDLE m_handle;
|
||||
|
||||
@@ -810,23 +849,15 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
bool trunc(u64 length) override
|
||||
{
|
||||
LARGE_INTEGER old, pos;
|
||||
FILE_END_OF_FILE_INFO _eof;
|
||||
_eof.EndOfFile.QuadPart = length;
|
||||
|
||||
pos.QuadPart = 0;
|
||||
if (!SetFilePointerEx(m_handle, pos, &old, FILE_CURRENT)) // get old position
|
||||
if (!SetFileInformationByHandle(m_handle, FileEndOfFileInfo, &_eof, sizeof(_eof)))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
pos.QuadPart = length;
|
||||
if (!SetFilePointerEx(m_handle, pos, NULL, FILE_BEGIN)) // set new position
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
verify("file::trunc" HERE), SetEndOfFile(m_handle), SetFilePointerEx(m_handle, old, NULL, FILE_BEGIN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -879,6 +910,11 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<windows_file>(handle);
|
||||
@@ -902,7 +938,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class unix_file final : public file_base
|
||||
class unix_file final : public file_base, public get_native_handle
|
||||
{
|
||||
const int m_fd;
|
||||
|
||||
@@ -991,6 +1027,11 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return file_info.st_size;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<unix_file>(fd);
|
||||
@@ -1066,6 +1107,20 @@ fs::file::file(const void* ptr, std::size_t size)
|
||||
m_file = std::make_unique<memory_stream>(ptr, size);
|
||||
}
|
||||
|
||||
fs::native_handle fs::file::get_handle() const
|
||||
{
|
||||
if (auto getter = dynamic_cast<get_native_handle*>(m_file.get()))
|
||||
{
|
||||
return getter->get();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fs::dir::xnull() const
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("fs::dir is null");
|
||||
@@ -1398,6 +1453,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::noent: return "Not found";
|
||||
case fs::error::exist: return "Already exists";
|
||||
case fs::error::acces: return "Access violation";
|
||||
case fs::error::notempty: return "Not empty";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
|
||||
+19
-1
@@ -10,6 +10,12 @@
|
||||
|
||||
namespace fs
|
||||
{
|
||||
#ifdef _WIN32
|
||||
using native_handle = void*;
|
||||
#else
|
||||
using native_handle = int;
|
||||
#endif
|
||||
|
||||
// File open mode flags
|
||||
enum class open_mode : u32
|
||||
{
|
||||
@@ -19,6 +25,7 @@ namespace fs
|
||||
create,
|
||||
trunc,
|
||||
excl,
|
||||
unshare,
|
||||
|
||||
__bitset_enum_max
|
||||
};
|
||||
@@ -29,6 +36,7 @@ namespace fs
|
||||
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
|
||||
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
|
||||
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
|
||||
constexpr auto unshare = +open_mode::unshare; // Prevent opening the file twice
|
||||
|
||||
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;
|
||||
|
||||
@@ -55,6 +63,12 @@ namespace fs
|
||||
s64 ctime;
|
||||
};
|
||||
|
||||
// Native handle getter
|
||||
struct get_native_handle
|
||||
{
|
||||
virtual native_handle get() = 0;
|
||||
};
|
||||
|
||||
// File handle base
|
||||
struct file_base
|
||||
{
|
||||
@@ -145,7 +159,7 @@ namespace fs
|
||||
bool create_path(const std::string& path);
|
||||
|
||||
// Rename (move) file or directory
|
||||
bool rename(const std::string& from, const std::string& to);
|
||||
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
||||
|
||||
// Copy file contents
|
||||
bool copy_file(const std::string& from, const std::string& to, bool overwrite);
|
||||
@@ -347,6 +361,9 @@ namespace fs
|
||||
if (seek(0), !read(result)) xfail();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get native handle if available
|
||||
native_handle get_handle() const;
|
||||
};
|
||||
|
||||
class dir final
|
||||
@@ -485,6 +502,7 @@ namespace fs
|
||||
noent,
|
||||
exist,
|
||||
acces,
|
||||
notempty,
|
||||
};
|
||||
|
||||
// Error code returned
|
||||
|
||||
+40
-12
@@ -12,6 +12,7 @@
|
||||
#include "File.h"
|
||||
#include "Log.h"
|
||||
#include "mutex.h"
|
||||
#include "sysinfo.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -89,13 +90,13 @@ extern void jit_finalize()
|
||||
// Helper class
|
||||
struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
{
|
||||
std::unordered_map<std::string, std::uintptr_t>& m_link;
|
||||
std::unordered_map<std::string, u64>& m_link;
|
||||
|
||||
std::array<u8, 16>* m_tramps{};
|
||||
|
||||
u8* m_code_addr{}; // TODO
|
||||
|
||||
MemoryManager(std::unordered_map<std::string, std::uintptr_t>& table)
|
||||
MemoryManager(std::unordered_map<std::string, u64>& table)
|
||||
: m_link(table)
|
||||
{
|
||||
}
|
||||
@@ -343,32 +344,54 @@ public:
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Created module: %s", module->getName().data());
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
|
||||
{
|
||||
std::string name = m_path;
|
||||
name.append(module->getName());
|
||||
|
||||
if (fs::file cached{name, fs::read})
|
||||
if (fs::file cached{path, fs::read})
|
||||
{
|
||||
auto buf = llvm::MemoryBuffer::getNewUninitMemBuffer(cached.size());
|
||||
cached.read(const_cast<char*>(buf->getBufferStart()), buf->getBufferSize());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
std::string path = m_path;
|
||||
path.append(module->getName());
|
||||
|
||||
if (auto buf = load(path))
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Loaded module: %s", module->getName().data());
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, std::uintptr_t>& _link, std::string _cpu)
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, std::string _cpu)
|
||||
: m_link(std::move(_link))
|
||||
, m_cpu(std::move(_cpu))
|
||||
{
|
||||
if (m_cpu.empty())
|
||||
{
|
||||
m_cpu = llvm::sys::getHostCPUName();
|
||||
|
||||
if (m_cpu == "sandybridge" ||
|
||||
m_cpu == "ivybridge" ||
|
||||
m_cpu == "haswell" ||
|
||||
m_cpu == "broadwell" ||
|
||||
m_cpu == "skylake" ||
|
||||
m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cannonlake")
|
||||
{
|
||||
if (!utils::has_avx())
|
||||
{
|
||||
m_cpu = "nehalem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result;
|
||||
@@ -430,6 +453,11 @@ void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void jit_compiler::add(const std::string& path)
|
||||
{
|
||||
m_engine->addObjectFile(std::move(llvm::object::ObjectFile::createObjectFile(*ObjectCache::load(path)).get()));
|
||||
}
|
||||
|
||||
void jit_compiler::fin()
|
||||
{
|
||||
m_engine->finalizeObject();
|
||||
|
||||
+4
-1
@@ -49,9 +49,12 @@ public:
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// Add module
|
||||
// Add module (path to obj cache dir)
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
// Add object (path to obj file)
|
||||
void add(const std::string& path);
|
||||
|
||||
// Finalize
|
||||
void fin();
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "LUrlParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
// check if the scheme name is valid
|
||||
static bool IsSchemeValid( const std::string& SchemeName )
|
||||
{
|
||||
for ( auto c : SchemeName )
|
||||
{
|
||||
if ( !isalpha( c ) && c != '+' && c != '-' && c != '.' ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LUrlParser::clParseURL::GetPort( int* OutPort ) const
|
||||
{
|
||||
if ( !IsValid() ) { return false; }
|
||||
|
||||
int Port = atoi( m_Port.c_str() );
|
||||
|
||||
if ( Port <= 0 || Port > 65535 ) { return false; }
|
||||
|
||||
if ( OutPort ) { *OutPort = Port; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// based on RFC 1738 and RFC 3986
|
||||
LUrlParser::clParseURL LUrlParser::clParseURL::ParseURL( const std::string& URL )
|
||||
{
|
||||
LUrlParser::clParseURL Result;
|
||||
|
||||
const char* CurrentString = URL.c_str();
|
||||
|
||||
/*
|
||||
* <scheme>:<scheme-specific-part>
|
||||
* <scheme> := [a-z\+\-\.]+
|
||||
* For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names
|
||||
*/
|
||||
|
||||
// try to read scheme
|
||||
{
|
||||
const char* LocalString = strchr( CurrentString, ':' );
|
||||
|
||||
if ( !LocalString )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoUrlCharacter );
|
||||
}
|
||||
|
||||
// save the scheme name
|
||||
Result.m_Scheme = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
if ( !IsSchemeValid( Result.m_Scheme ) )
|
||||
{
|
||||
return clParseURL( LUrlParserError_InvalidSchemeName );
|
||||
}
|
||||
|
||||
// scheme should be lowercase
|
||||
std::transform( Result.m_Scheme.begin(), Result.m_Scheme.end(), Result.m_Scheme.begin(), ::tolower );
|
||||
|
||||
// skip ':'
|
||||
CurrentString = LocalString+1;
|
||||
}
|
||||
|
||||
/*
|
||||
* //<user>:<password>@<host>:<port>/<url-path>
|
||||
* any ":", "@" and "/" must be normalized
|
||||
*/
|
||||
|
||||
// skip "//"
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
if ( *CurrentString++ != '/' ) return clParseURL( LUrlParserError_NoDoubleSlash );
|
||||
|
||||
// check if the user name and password are specified
|
||||
bool bHasUserName = false;
|
||||
|
||||
const char* LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( *LocalString == '@' )
|
||||
{
|
||||
// user name and password are specified
|
||||
bHasUserName = true;
|
||||
break;
|
||||
}
|
||||
else if ( *LocalString == '/' )
|
||||
{
|
||||
// end of <host>:<port> specification
|
||||
bHasUserName = false;
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
// user name and password
|
||||
LocalString = CurrentString;
|
||||
|
||||
if ( bHasUserName )
|
||||
{
|
||||
// read user name
|
||||
while ( *LocalString && *LocalString != ':' && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_UserName = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
// proceed with the current pointer
|
||||
CurrentString = LocalString;
|
||||
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
// skip ':'
|
||||
CurrentString++;
|
||||
|
||||
// read password
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '@' ) LocalString++;
|
||||
|
||||
Result.m_Password = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// skip '@'
|
||||
if ( *CurrentString != '@' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoAtSign );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
}
|
||||
|
||||
bool bHasBracket = ( *CurrentString == '[' );
|
||||
|
||||
// go ahead, read the host name
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString )
|
||||
{
|
||||
if ( bHasBracket && *LocalString == ']' )
|
||||
{
|
||||
// end of IPv6 address
|
||||
LocalString++;
|
||||
break;
|
||||
}
|
||||
else if ( !bHasBracket && ( *LocalString == ':' || *LocalString == '/' ) )
|
||||
{
|
||||
// port number is specified
|
||||
break;
|
||||
}
|
||||
|
||||
LocalString++;
|
||||
}
|
||||
|
||||
Result.m_Host = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// is port number specified?
|
||||
if ( *CurrentString == ':' )
|
||||
{
|
||||
CurrentString++;
|
||||
|
||||
// read port number
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '/' ) LocalString++;
|
||||
|
||||
Result.m_Port = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// end of string
|
||||
if ( !*CurrentString )
|
||||
{
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// skip '/'
|
||||
if ( *CurrentString != '/' )
|
||||
{
|
||||
return clParseURL( LUrlParserError_NoSlash );
|
||||
}
|
||||
|
||||
CurrentString++;
|
||||
|
||||
// parse the path
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' && *LocalString != '?' ) LocalString++;
|
||||
|
||||
Result.m_Path = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
|
||||
// check for query
|
||||
if ( *CurrentString == '?' )
|
||||
{
|
||||
// skip '?'
|
||||
CurrentString++;
|
||||
|
||||
// read query
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString && *LocalString != '#' ) LocalString++;
|
||||
|
||||
Result.m_Query = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
// check for fragment
|
||||
if ( *CurrentString == '#' )
|
||||
{
|
||||
// skip '#'
|
||||
CurrentString++;
|
||||
|
||||
// read fragment
|
||||
LocalString = CurrentString;
|
||||
|
||||
while ( *LocalString ) LocalString++;
|
||||
|
||||
Result.m_Fragment = std::string( CurrentString, LocalString - CurrentString );
|
||||
|
||||
CurrentString = LocalString;
|
||||
}
|
||||
|
||||
Result.m_ErrorCode = LUrlParserError_Ok;
|
||||
|
||||
return Result;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Lightweight URL & URI parser (RFC 1738, RFC 3986)
|
||||
* https://github.com/corporateshark/LUrlParser
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace LUrlParser
|
||||
{
|
||||
enum LUrlParserError
|
||||
{
|
||||
LUrlParserError_Ok = 0,
|
||||
LUrlParserError_Uninitialized = 1,
|
||||
LUrlParserError_NoUrlCharacter = 2,
|
||||
LUrlParserError_InvalidSchemeName = 3,
|
||||
LUrlParserError_NoDoubleSlash = 4,
|
||||
LUrlParserError_NoAtSign = 5,
|
||||
LUrlParserError_UnexpectedEndOfLine = 6,
|
||||
LUrlParserError_NoSlash = 7,
|
||||
};
|
||||
|
||||
class clParseURL
|
||||
{
|
||||
public:
|
||||
LUrlParserError m_ErrorCode;
|
||||
std::string m_Scheme;
|
||||
std::string m_Host;
|
||||
std::string m_Port;
|
||||
std::string m_Path;
|
||||
std::string m_Query;
|
||||
std::string m_Fragment;
|
||||
std::string m_UserName;
|
||||
std::string m_Password;
|
||||
|
||||
clParseURL()
|
||||
: m_ErrorCode( LUrlParserError_Uninitialized )
|
||||
{}
|
||||
|
||||
/// return 'true' if the parsing was successful
|
||||
bool IsValid() const { return m_ErrorCode == LUrlParserError_Ok; }
|
||||
|
||||
/// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range)
|
||||
bool GetPort( int* OutPort ) const;
|
||||
|
||||
/// parse the URL
|
||||
static clParseURL ParseURL( const std::string& URL );
|
||||
|
||||
private:
|
||||
explicit clParseURL( LUrlParserError ErrorCode )
|
||||
: m_ErrorCode( ErrorCode )
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace LUrlParser
|
||||
+200
-42
@@ -3,16 +3,21 @@
|
||||
#include "StrFmt.h"
|
||||
#include "sema.h"
|
||||
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "rpcs3_version.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <chrono>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
static std::string empty_string()
|
||||
{
|
||||
return {};
|
||||
@@ -44,32 +49,71 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
|
||||
|
||||
namespace logs
|
||||
{
|
||||
constexpr std::size_t s_log_size = 128 * 1024 * 1024;
|
||||
constexpr std::size_t s_log_size_s = s_log_size / 2;
|
||||
constexpr std::size_t s_log_size_t = s_log_size / 4 + s_log_size_s;
|
||||
constexpr std::size_t s_log_size_e = s_log_size / 8 + s_log_size_t;
|
||||
constexpr std::size_t s_log_size_f = s_log_size / 16 + s_log_size_e;
|
||||
|
||||
class file_writer
|
||||
{
|
||||
// Could be memory-mapped file
|
||||
fs::file m_file;
|
||||
std::string m_name;
|
||||
|
||||
#ifdef _WIN32
|
||||
::HANDLE m_fmap;
|
||||
#endif
|
||||
atomic_t<std::size_t> m_pos{0};
|
||||
std::size_t m_size{0};
|
||||
uchar* m_fptr{};
|
||||
|
||||
public:
|
||||
file_writer(const std::string& name);
|
||||
|
||||
virtual ~file_writer() = default;
|
||||
virtual ~file_writer();
|
||||
|
||||
// Append raw data
|
||||
void log(const char* text, std::size_t size);
|
||||
void log(logs::level sev, const char* text, std::size_t size);
|
||||
};
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct stored_message
|
||||
{
|
||||
message m;
|
||||
u64 stamp;
|
||||
std::string prefix;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct file_listener : public file_writer, public listener
|
||||
{
|
||||
file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
{
|
||||
const std::string& start = fmt::format("\xEF\xBB\xBF" "RPCS3 v%s\n", rpcs3::version.to_string());
|
||||
file_writer::log(start.data(), start.size());
|
||||
}
|
||||
file_listener(const std::string& name);
|
||||
|
||||
virtual ~file_listener() = default;
|
||||
|
||||
// Encode level, current thread name, channel name and write log message
|
||||
virtual void log(u64 stamp, const message& msg, const std::string& prefix, const std::string& text) override;
|
||||
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> channels;
|
||||
|
||||
// Messages for delayed listener initialization
|
||||
std::vector<stored_message> messages;
|
||||
};
|
||||
|
||||
static file_listener* get_logger()
|
||||
@@ -121,33 +165,17 @@ namespace logs
|
||||
channel SPU("SPU");
|
||||
channel ARMv7("ARMv7");
|
||||
|
||||
struct channel_info
|
||||
{
|
||||
channel* pointer = nullptr;
|
||||
level enabled = level::notice;
|
||||
|
||||
void set_level(level value)
|
||||
{
|
||||
enabled = value;
|
||||
|
||||
if (pointer)
|
||||
{
|
||||
pointer->enabled = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Channel registry mutex
|
||||
semaphore<> g_mutex;
|
||||
|
||||
// Channel registry
|
||||
std::unordered_map<std::string, channel_info> g_channels;
|
||||
// Must be set to true in main()
|
||||
atomic_t<bool> g_init{false};
|
||||
|
||||
void reset()
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
for (auto&& pair : g_channels)
|
||||
for (auto&& pair : get_logger()->channels)
|
||||
{
|
||||
pair.second.set_level(level::notice);
|
||||
}
|
||||
@@ -157,7 +185,18 @@ namespace logs
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
g_channels[ch_name].set_level(value);
|
||||
get_logger()->channels[ch_name].set_level(value);
|
||||
}
|
||||
|
||||
// Must be called in main() to stop accumulating messages in g_messages
|
||||
void set_init()
|
||||
{
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
get_logger()->messages.clear();
|
||||
g_init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,11 +209,19 @@ void logs::listener::add(logs::listener* _new)
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
// Install new listener at the end of linked list
|
||||
while (lis->m_next || !lis->m_next.compare_and_swap_test(nullptr, _new))
|
||||
{
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Send initial messages
|
||||
for (const auto& msg : get_logger()->messages)
|
||||
{
|
||||
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
|
||||
}
|
||||
}
|
||||
|
||||
void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||
@@ -187,7 +234,7 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
auto& info = g_channels[ch->name];
|
||||
auto& info = get_logger()->channels[ch->name];
|
||||
|
||||
if (info.pointer && info.pointer != ch)
|
||||
{
|
||||
@@ -207,13 +254,30 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
}
|
||||
|
||||
// Get text
|
||||
std::string text;
|
||||
thread_local std::string text; text.clear();
|
||||
fmt::raw_append(text, fmt, sup, args);
|
||||
std::string prefix = g_tls_log_prefix();
|
||||
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
while (lis)
|
||||
{
|
||||
lis->log(stamp, *this, prefix, text);
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Store message additionally
|
||||
get_logger()->messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
|
||||
}
|
||||
}
|
||||
|
||||
// Send message to all listeners
|
||||
while (lis)
|
||||
{
|
||||
@@ -225,13 +289,30 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
[[noreturn]] extern void catch_all_exceptions();
|
||||
|
||||
logs::file_writer::file_writer(const std::string& name)
|
||||
: m_name(name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!m_file.open(fs::get_config_dir() + name, fs::rewrite + fs::append))
|
||||
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
|
||||
{
|
||||
fmt::throw_exception("Can't create log file %s (error %s)", name, fs::g_tls_error);
|
||||
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
m_fmap = CreateFileMappingW(m_file.get_handle(), 0, PAGE_READWRITE, s_log_size >> 32, s_log_size & 0xffffffff, 0);
|
||||
m_fptr = m_fmap ? (uchar*)MapViewOfFile(m_fmap, FILE_MAP_WRITE, 0, 0, 0) : nullptr;
|
||||
#else
|
||||
m_file.trunc(s_log_size);
|
||||
m_fptr = (uchar*)::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0);
|
||||
#endif
|
||||
|
||||
verify(name.c_str()), m_fptr;
|
||||
std::memset(m_fptr, '\n', s_log_size);
|
||||
|
||||
// Rotate backups (TODO)
|
||||
fs::remove_file(fs::get_config_dir() + name + "1.gz");
|
||||
fs::create_dir(fs::get_config_dir() + "old_logs");
|
||||
fs::rename(fs::get_config_dir() + m_name + ".gz", fs::get_config_dir() + "old_logs/" + m_name + ".gz", true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -239,14 +320,91 @@ logs::file_writer::file_writer(const std::string& name)
|
||||
}
|
||||
}
|
||||
|
||||
void logs::file_writer::log(const char* text, std::size_t size)
|
||||
logs::file_writer::~file_writer()
|
||||
{
|
||||
m_file.write(text, size);
|
||||
if (m_size == 0)
|
||||
{
|
||||
m_size = std::min<std::size_t>(+m_pos, s_log_size);
|
||||
}
|
||||
|
||||
// Compress
|
||||
z_stream zs{};
|
||||
if (deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) == Z_OK)
|
||||
{
|
||||
auto buf = std::make_unique<uchar[]>(s_log_size);
|
||||
zs.avail_in = ::narrow<u32>(m_size);
|
||||
zs.avail_out = s_log_size;
|
||||
zs.next_in = m_fptr;
|
||||
zs.next_out = buf.get();
|
||||
|
||||
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
|
||||
{
|
||||
fs::file(fs::get_config_dir() + m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
|
||||
}
|
||||
|
||||
if (deflateEnd(&zs) != Z_OK)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
UnmapViewOfFile(m_fptr);
|
||||
CloseHandle(m_fmap);
|
||||
#else
|
||||
::munmap(m_fptr, s_log_size);
|
||||
#endif
|
||||
m_file.trunc(m_size);
|
||||
}
|
||||
|
||||
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
{
|
||||
// Adaptive log limit
|
||||
const auto lim =
|
||||
sev >= logs::level::success ? s_log_size_s :
|
||||
sev == logs::level::todo ? s_log_size_t :
|
||||
sev == logs::level::error ? s_log_size_e : s_log_size_f;
|
||||
|
||||
if (m_pos >= lim)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Acquire memory
|
||||
const auto pos = m_pos.fetch_add(size);
|
||||
|
||||
// Write if possible
|
||||
if (pos + size <= s_log_size)
|
||||
{
|
||||
std::memcpy(m_fptr + pos, text, size);
|
||||
}
|
||||
else if (pos <= s_log_size)
|
||||
{
|
||||
m_size = pos;
|
||||
}
|
||||
}
|
||||
|
||||
logs::file_listener::file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
{
|
||||
// Write UTF-8 BOM
|
||||
file_writer::log(logs::level::always, "\xEF\xBB\xBF", 3);
|
||||
|
||||
// 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());
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
|
||||
{
|
||||
std::string text; text.reserve(prefix.size() + _text.size() + 200);
|
||||
thread_local std::string text;
|
||||
|
||||
// Used character: U+00B7 (Middle Dot)
|
||||
switch (msg.sev)
|
||||
@@ -274,8 +432,8 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
text += prefix;
|
||||
text += "} ";
|
||||
}
|
||||
|
||||
if ('\0' != *msg.ch->name)
|
||||
|
||||
if (msg.ch && '\0' != *msg.ch->name)
|
||||
{
|
||||
text += msg.ch->name;
|
||||
text += msg.sev == level::todo ? " TODO: " : ": ";
|
||||
@@ -284,9 +442,9 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
{
|
||||
text += "TODO: ";
|
||||
}
|
||||
|
||||
|
||||
text += _text;
|
||||
text += '\n';
|
||||
|
||||
file_writer::log(text.data(), text.size());
|
||||
file_writer::log(msg.sev, text.data(), text.size());
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class MTProgressDialog : public wxDialog
|
||||
{
|
||||
wxGauge** m_gauge;
|
||||
wxStaticText** m_msg;
|
||||
|
||||
wxArrayLong m_maximum;
|
||||
const u8 m_cores;
|
||||
|
||||
static const uint layout = 16;
|
||||
static const uint maxdial = 65536;
|
||||
wxArrayInt m_lastupdate;
|
||||
|
||||
public:
|
||||
MTProgressDialog(wxWindow* parent, const wxSize& size, const wxString& title,
|
||||
const wxString& msg, const wxArrayLong& maximum, const u8 cores)
|
||||
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition)
|
||||
, m_maximum(maximum)
|
||||
, m_cores(cores)
|
||||
{
|
||||
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_gauge = new wxGauge*[m_cores];
|
||||
m_msg = new wxStaticText*[m_cores];
|
||||
|
||||
m_lastupdate.SetCount(cores);
|
||||
|
||||
for(uint i=0; i<m_cores; ++i)
|
||||
{
|
||||
m_lastupdate[i] = -1;
|
||||
|
||||
m_msg[i] = new wxStaticText(this, wxID_ANY, msg);
|
||||
sizer->Add(m_msg[i], 0, wxLEFT | wxTOP, layout);
|
||||
|
||||
m_gauge[i] = new wxGauge(this, wxID_ANY, maxdial,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxGA_HORIZONTAL );
|
||||
|
||||
sizer->Add(m_gauge[i], 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, layout);
|
||||
m_gauge[i]->SetValue(0);
|
||||
|
||||
sizer->AddSpacer(5);
|
||||
}
|
||||
|
||||
SetSizerAndFit(sizer);
|
||||
if(size != wxDefaultSize)
|
||||
{
|
||||
SetSize(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxSize ws;
|
||||
ws.x = 400;
|
||||
ws.y = GetSize().y + 8;
|
||||
SetSize(ws);
|
||||
}
|
||||
|
||||
m_maximum.SetCount(m_cores);
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
void Update(const u8 thread_id, const u64 value, const wxString& msg)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
|
||||
const int curupdate = (int)(((double)value/(double)m_maximum[thread_id])*1000);
|
||||
if(curupdate == m_lastupdate[thread_id]) return;
|
||||
m_lastupdate[thread_id] = curupdate;
|
||||
|
||||
m_msg[thread_id]->SetLabel(msg);
|
||||
|
||||
if(value >= (u32)m_maximum[thread_id]) return;
|
||||
m_gauge[thread_id]->SetValue(((double)value / (double)m_maximum[thread_id]) * maxdial);
|
||||
}
|
||||
|
||||
const u32 GetMaxValue(const uint thread_id) const
|
||||
{
|
||||
if(thread_id > m_cores) return 0;
|
||||
return m_maximum[thread_id];
|
||||
}
|
||||
|
||||
void SetMaxFor(const uint thread_id, const u64 val)
|
||||
{
|
||||
if(thread_id > m_cores) return;
|
||||
m_maximum[thread_id] = val;
|
||||
m_lastupdate[thread_id] = 0;
|
||||
}
|
||||
|
||||
virtual void Close(bool force = false)
|
||||
{
|
||||
m_lastupdate.Empty();
|
||||
m_maximum.Empty();
|
||||
|
||||
wxDialog::Close(force);
|
||||
}
|
||||
};
|
||||
@@ -257,8 +257,8 @@ struct fmt::cfmt_src
|
||||
|
||||
void skip(std::size_t extra)
|
||||
{
|
||||
++sup += extra;
|
||||
++args += extra;
|
||||
sup += extra + 1;
|
||||
args += extra + 1;
|
||||
}
|
||||
|
||||
std::size_t fmt_string(std::string& out, std::size_t extra) const
|
||||
|
||||
+92
-23
@@ -3,7 +3,10 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_mmapper.h"
|
||||
#include "Emu/Cell/lv2/sys_event.h"
|
||||
#include "Thread.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
@@ -30,13 +33,25 @@ thread_local u64 g_tls_fault_spu = 0;
|
||||
|
||||
static void report_fatal_error(const std::string& msg)
|
||||
{
|
||||
static semaphore<> g_report_only_once;
|
||||
|
||||
g_report_only_once.wait();
|
||||
|
||||
std::string _msg = msg + "\n"
|
||||
"HOW TO REPORT ERRORS: Check the FAQ, README, other sources.\n"
|
||||
"HOW TO REPORT ERRORS: https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support\n"
|
||||
"Please, don't send incorrect reports. Thanks for understanding.\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
_msg += "Press (Ctrl+C) to copy this message.";
|
||||
MessageBoxA(0, _msg.c_str(), "Fatal error", MB_ICONERROR); // TODO: unicode message
|
||||
_msg += "\nPress Yes or Enter to visit the URL above immediately.";
|
||||
const std::size_t buf_size = _msg.size() + 1;
|
||||
const int size = static_cast<int>(buf_size);
|
||||
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size]);
|
||||
MultiByteToWideChar(CP_UTF8, 0, _msg.c_str(), size, buffer.get(), size);
|
||||
|
||||
if (MessageBoxW(0, buffer.get(), L"Fatal error", MB_ICONERROR | MB_YESNO) == IDYES)
|
||||
{
|
||||
ShellExecuteW(0, L"open", L"https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support", 0, 0, SW_SHOWNORMAL);
|
||||
}
|
||||
#else
|
||||
std::printf("Fatal error: \n%s", _msg.c_str());
|
||||
#endif
|
||||
@@ -1236,7 +1251,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)))
|
||||
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 (cpu)
|
||||
{
|
||||
@@ -1246,9 +1261,60 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
|
||||
if (cpu)
|
||||
{
|
||||
if (fxm::check<page_fault_notification_entries>())
|
||||
{
|
||||
for (const auto& entry : fxm::get<page_fault_notification_entries>()->entries)
|
||||
{
|
||||
auto mem = vm::get(vm::any, entry.start_addr);
|
||||
if (!mem)
|
||||
{
|
||||
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>();
|
||||
{
|
||||
semaphore_lock pf_lock(pf_entries->pf_mutex);
|
||||
page_fault_event pf_event{ cpu->id, addr };
|
||||
pf_entries->events.emplace_back(pf_event);
|
||||
}
|
||||
|
||||
// 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.
|
||||
be_t<u64> data1 = addr;
|
||||
be_t<u64> data2 = (SYS_MEMORY_PAGE_FAULT_TYPE_PPU_THREAD << 32) + cpu->id; // TODO: fix hack for now that assumes PPU thread always.
|
||||
be_t<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_FATAL(MEMORY, "Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
cpu->check_state();
|
||||
@@ -1413,13 +1479,6 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
|
||||
|
||||
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
||||
|
||||
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
msg += "\n"
|
||||
"Illegal instruction exception occured.\n"
|
||||
"Note that your CPU must support SSSE3 extension.\n";
|
||||
}
|
||||
|
||||
// TODO: print registers and the callstack
|
||||
|
||||
// Report fatal error
|
||||
@@ -1825,20 +1884,30 @@ void thread_ctrl::set_native_priority(int priority)
|
||||
HANDLE _this_thread = GetCurrentThread();
|
||||
INT native_priority = THREAD_PRIORITY_NORMAL;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (priority > 0)
|
||||
native_priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
||||
break;
|
||||
case -1:
|
||||
if (priority < 0)
|
||||
native_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
SetThreadPriority(_this_thread, native_priority);
|
||||
if (!SetThreadPriority(_this_thread, native_priority))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "SetThreadPriority() failed: 0x%x", GetLastError());
|
||||
}
|
||||
#else
|
||||
int policy;
|
||||
struct sched_param param;
|
||||
|
||||
pthread_getschedparam(pthread_self(), &policy, ¶m);
|
||||
|
||||
if (priority > 0)
|
||||
param.sched_priority = sched_get_priority_max(policy);
|
||||
if (priority < 0)
|
||||
param.sched_priority = sched_get_priority_min(policy);
|
||||
|
||||
if (int err = pthread_setschedparam(pthread_self(), policy, ¶m))
|
||||
{
|
||||
LOG_ERROR(GENERAL, "pthraed_setschedparam() failed: %d", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace utils
|
||||
void memory_decommit(void* pointer, std::size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
verify(HERE), ::VirtualFree(pointer, 0, MEM_DECOMMIT);
|
||||
verify(HERE), ::VirtualFree(pointer, size, MEM_DECOMMIT);
|
||||
#else
|
||||
verify(HERE), ::mmap(pointer, size, PROT_NONE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
||||
+65
-5
@@ -10,13 +10,18 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case patch_type::load: return "load";
|
||||
case patch_type::byte: return "byte";
|
||||
case patch_type::le16: return "le16";
|
||||
case patch_type::le32: return "le32";
|
||||
case patch_type::le64: return "le64";
|
||||
case patch_type::bef32: return "bef32";
|
||||
case patch_type::bef64: return "bef64";
|
||||
case patch_type::be16: return "be16";
|
||||
case patch_type::be32: return "be32";
|
||||
case patch_type::be64: return "be64";
|
||||
case patch_type::lef32: return "lef32";
|
||||
case patch_type::lef64: return "lef64";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@@ -39,23 +44,67 @@ void patch_engine::append(const std::string& patch)
|
||||
u64 type64 = 0;
|
||||
cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar());
|
||||
|
||||
struct patch info;
|
||||
struct patch info{};
|
||||
info.type = static_cast<patch_type>(type64);
|
||||
info.offset = patch[1].as<u32>();
|
||||
info.value = patch[2].as<u64>();
|
||||
info.offset = patch[1].as<u32>(0);
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Special syntax: copy named sequence (must be loaded before)
|
||||
const auto found = m_map.find(patch[1].Scalar());
|
||||
|
||||
if (found != m_map.end())
|
||||
{
|
||||
// Address modifier (optional)
|
||||
const u32 mod = patch[2].as<u32>(0);
|
||||
|
||||
for (const auto& rd : found->second)
|
||||
{
|
||||
info = rd;
|
||||
info.offset += mod;
|
||||
data.emplace_back(info);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: error
|
||||
break;
|
||||
}
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
info.value_as<f32>() = patch[2].as<f32>();
|
||||
break;
|
||||
}
|
||||
case patch_type::bef64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
info.value_as<f64>() = patch[2].as<f64>();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
info.value = patch[2].as<u64>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data.emplace_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
{
|
||||
const auto found = m_map.find(name);
|
||||
|
||||
if (found == m_map.cend())
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Apply modifications sequentially
|
||||
@@ -65,6 +114,11 @@ void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
|
||||
switch (p.type)
|
||||
{
|
||||
case patch_type::load:
|
||||
{
|
||||
// Invalid in this context
|
||||
break;
|
||||
}
|
||||
case patch_type::byte:
|
||||
{
|
||||
*ptr = static_cast<u8>(p.value);
|
||||
@@ -76,11 +130,13 @@ void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::le32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::le64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
@@ -91,15 +147,19 @@ void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::be32:
|
||||
case patch_type::bef32:
|
||||
{
|
||||
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::be64:
|
||||
case patch_type::bef64:
|
||||
{
|
||||
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found->second.size();
|
||||
}
|
||||
|
||||
+13
-2
@@ -7,13 +7,18 @@
|
||||
|
||||
enum class patch_type
|
||||
{
|
||||
load,
|
||||
byte,
|
||||
le16,
|
||||
le32,
|
||||
le64,
|
||||
lef32,
|
||||
lef64,
|
||||
be16,
|
||||
be32,
|
||||
be64,
|
||||
bef32,
|
||||
bef64,
|
||||
};
|
||||
|
||||
class patch_engine
|
||||
@@ -23,6 +28,12 @@ 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
|
||||
@@ -32,6 +43,6 @@ public:
|
||||
// Load from file
|
||||
void append(const std::string& path);
|
||||
|
||||
// Apply patch
|
||||
void apply(const std::string& name, u8* dst) const;
|
||||
// Apply patch (returns the number of entries applied)
|
||||
std::size_t apply(const std::string& name, u8* dst) const;
|
||||
};
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
Copyright (C) 2011-2012 Andrzej Krzemienski
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0
|
||||
(see accompanying file LICENSE_1_0.txt or a copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
The idea and interface is based on Boost.Optional library
|
||||
authored by Fernando Luis Cacciola Carballal
|
||||
|
||||
Home at https://github.com/akrzemi1/Optional
|
||||
@@ -731,9 +731,9 @@ struct area_base
|
||||
{
|
||||
return{ x1 * size.width, y1 * size.height, x2 * size.width, y2 * size.height };
|
||||
}
|
||||
constexpr area_base operator * (const T& value) const
|
||||
constexpr area_base operator * (const f32& value) const
|
||||
{
|
||||
return{ x1 * value, y1 * value, x2 * value, y2 * value };
|
||||
return{ (T)(x1 * value), (T)(y1 * value), (T)(x2 * value), (T)(y2 * value) };
|
||||
}
|
||||
|
||||
template<typename NT>
|
||||
|
||||
@@ -16,6 +16,7 @@ rem // Official git repository and contact information can be found at
|
||||
rem // https://github.com/RPCS3/rpcs3 and http://rpcs3.net/.
|
||||
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
setlocal ENABLEEXTENSIONS
|
||||
|
||||
set GIT_VERSION_FILE=%~p0..\rpcs3\git-version.h
|
||||
if not defined GIT (
|
||||
@@ -47,15 +48,43 @@ if errorlevel 1 (
|
||||
echo // This is a generated file. > "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION "unknown" >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_BRANCH "unknown" >> "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
|
||||
goto done
|
||||
)
|
||||
|
||||
rem // Get commit count from HEAD by default
|
||||
for /F %%I IN ('call %GIT% rev-list HEAD --count') do set GIT_VERSION=%%I
|
||||
|
||||
rem // If we're in AppVeyor and we're building for master: Get commit count from unshallowed upstream
|
||||
if defined APPVEYOR (
|
||||
if not defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
|
||||
call %GIT% remote add upstream https://github.com/RPCS3/RPCS3.git
|
||||
call %GIT% fetch --unshallow upstream
|
||||
for /F %%I IN ('call %GIT% rev-list --count upstream/master') do set GIT_VERSION=%%I
|
||||
)
|
||||
)
|
||||
|
||||
if defined APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH (
|
||||
if "%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"=="master" (
|
||||
for /f "tokens=1* delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set user=%%a
|
||||
set "GIT_BRANCH=!user!/%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%"
|
||||
) else (
|
||||
set GIT_BRANCH=%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%
|
||||
)
|
||||
|
||||
) else (
|
||||
for /F %%I IN ('call %GIT% rev-parse --abbrev-ref HEAD') do set GIT_BRANCH=%%I
|
||||
)
|
||||
|
||||
rem // Get last commit (shortened) and concat after commit count in GIT_VERSION
|
||||
for /F %%I IN ('call %GIT% rev-parse --short HEAD') do set GIT_VERSION=%GIT_VERSION%-%%I
|
||||
|
||||
rem // Echo obtained GIT_VERSION for debug purposes if needed
|
||||
echo %GIT_VERSION%
|
||||
|
||||
rem // Don't modify the file if it already has the current version.
|
||||
if exist "%GIT_VERSION_FILE%" (
|
||||
findstr /C:"%GIT_VERSION%" "%GIT_VERSION_FILE%" > NUL
|
||||
@@ -67,6 +96,7 @@ if exist "%GIT_VERSION_FILE%" (
|
||||
echo // This is a generated file. > "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION "%GIT_VERSION%" >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_BRANCH ^"%GIT_BRANCH%^" >> "%GIT_VERSION_FILE%"
|
||||
echo. >> "%GIT_VERSION_FILE%"
|
||||
echo // If you don't want this file to update/recompile, change to 1. >> "%GIT_VERSION_FILE%"
|
||||
echo #define RPCS3_GIT_VERSION_NO_UPDATE 0 >> "%GIT_VERSION_FILE%"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
template<typename T>
|
||||
static size_t hash_base(T value)
|
||||
{
|
||||
return static_cast<size_t>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static size_t hash_struct(const T& value)
|
||||
{
|
||||
// FNV 64-bit
|
||||
size_t result = 14695981039346656037ull;
|
||||
const unsigned char *bytes = reinterpret_cast<const unsigned char*>(&value);
|
||||
|
||||
for (size_t n = 0; n < sizeof(T); ++n)
|
||||
{
|
||||
result ^= bytes[n];
|
||||
result *= 1099511628211ull;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+83
-1
@@ -1,7 +1,12 @@
|
||||
#include "mutex.h"
|
||||
#include "sync.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// TLS variable for tracking owned mutexes
|
||||
thread_local std::vector<shared_mutex*> g_tls_locks;
|
||||
|
||||
void shared_mutex::imp_lock_shared(s64 _old)
|
||||
{
|
||||
@@ -217,12 +222,14 @@ void shared_mutex::imp_unlock(s64 _old)
|
||||
|
||||
void shared_mutex::imp_lock_upgrade()
|
||||
{
|
||||
// TODO
|
||||
unlock_shared();
|
||||
lock();
|
||||
}
|
||||
|
||||
void shared_mutex::imp_lock_degrade()
|
||||
{
|
||||
// TODO
|
||||
unlock();
|
||||
lock_shared();
|
||||
}
|
||||
@@ -250,3 +257,78 @@ bool shared_mutex::try_lock_degrade()
|
||||
// TODO
|
||||
return m_value.compare_and_swap_test(0, c_one - c_min);
|
||||
}
|
||||
|
||||
safe_reader_lock::safe_reader_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
}
|
||||
|
||||
safe_reader_lock::~safe_reader_lock()
|
||||
{
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
safe_writer_lock::safe_writer_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_is_owned(false)
|
||||
, m_is_upgraded(false)
|
||||
{
|
||||
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||
{
|
||||
m_is_owned = true;
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
g_tls_locks.emplace_back(&m_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
if (m_mutex.is_reading())
|
||||
{
|
||||
m_is_upgraded = true;
|
||||
m_mutex.lock_upgrade();
|
||||
}
|
||||
}
|
||||
|
||||
safe_writer_lock::~safe_writer_lock()
|
||||
{
|
||||
if (m_is_upgraded)
|
||||
{
|
||||
m_mutex.lock_degrade();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_is_owned)
|
||||
{
|
||||
m_mutex.unlock();
|
||||
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: order locks
|
||||
}
|
||||
|
||||
@@ -95,6 +95,11 @@ public:
|
||||
imp_lock_degrade();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_reading() const
|
||||
{
|
||||
return (m_value.load() % c_one) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Simplified shared (reader) lock implementation.
|
||||
@@ -171,3 +176,56 @@ public:
|
||||
unlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Safe reader lock. Can be recursive above other safe locks (reader or writer).
|
||||
class safe_reader_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_reader_lock(const safe_reader_lock&) = delete;
|
||||
|
||||
explicit safe_reader_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_reader_lock();
|
||||
};
|
||||
|
||||
// Safe writer lock. Can be recursive above other safe locks. Performs upgrade and degrade operations above existing reader lock if necessary.
|
||||
class safe_writer_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_is_owned;
|
||||
bool m_is_upgraded;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
safe_writer_lock(const safe_writer_lock&) = delete;
|
||||
|
||||
explicit safe_writer_lock(shared_mutex& mutex);
|
||||
|
||||
~safe_writer_lock();
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2
-3
@@ -61,10 +61,9 @@ rXmlDocument::rXmlDocument() : handle()
|
||||
{
|
||||
}
|
||||
|
||||
void rXmlDocument::Load(const std::string & path)
|
||||
void rXmlDocument::Read(const std::string& data)
|
||||
{
|
||||
// TODO: Unsure of use of c_str.
|
||||
handle.load_file(path.c_str());
|
||||
handle.load_buffer(data.data(), data.size());
|
||||
}
|
||||
|
||||
std::shared_ptr<rXmlNode> rXmlDocument::GetRoot()
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ struct rXmlDocument
|
||||
rXmlDocument();
|
||||
rXmlDocument(const rXmlDocument& other) = delete;
|
||||
rXmlDocument &operator=(const rXmlDocument& other) = delete;
|
||||
void Load(const std::string & path);
|
||||
void Read(const std::string& data);
|
||||
std::shared_ptr<rXmlNode> GetRoot();
|
||||
|
||||
pugi::xml_document handle;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "sysinfo.h"
|
||||
#include "StrFmt.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
std::string utils::get_system_info()
|
||||
{
|
||||
std::string result;
|
||||
std::string brand;
|
||||
|
||||
if (get_cpuid(0x80000000, 0)[0] >= 0x80000004)
|
||||
{
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
brand.append(reinterpret_cast<const char*>(get_cpuid(0x80000002 + i, 0).data()), 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
brand = "Unknown CPU";
|
||||
}
|
||||
|
||||
brand.erase(0, brand.find_first_not_of(' '));
|
||||
brand.erase(brand.find_last_not_of(' ') + 1);
|
||||
|
||||
while (auto found = brand.find(" ") + 1)
|
||||
{
|
||||
brand.erase(brand.begin() + found);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::SYSTEM_INFO sysInfo;
|
||||
::GetNativeSystemInfo(&sysInfo);
|
||||
::MEMORYSTATUSEX memInfo;
|
||||
memInfo.dwLength = sizeof(memInfo);
|
||||
::GlobalMemoryStatusEx(&memInfo);
|
||||
const u32 num_proc = sysInfo.dwNumberOfProcessors;
|
||||
const u64 mem_total = memInfo.ullTotalPhys;
|
||||
#else
|
||||
const u32 num_proc = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||
const u64 mem_total = ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||
|
||||
if (has_avx())
|
||||
{
|
||||
result += " | AVX";
|
||||
}
|
||||
|
||||
if (has_rtm())
|
||||
{
|
||||
result += " | TSX";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::array<u32, 4> get_cpuid(u32 func, u32 subfunc)
|
||||
{
|
||||
int regs[4];
|
||||
#ifdef _MSC_VER
|
||||
__cpuidex(regs, func, subfunc);
|
||||
#else
|
||||
__asm__ volatile("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (func), "c" (subfunc));
|
||||
#endif
|
||||
return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]};
|
||||
}
|
||||
|
||||
inline bool has_ssse3()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x200;
|
||||
}
|
||||
|
||||
inline bool has_avx()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000;
|
||||
}
|
||||
|
||||
inline bool has_rtm()
|
||||
{
|
||||
// Check RTM and MPX extensions in order to filter out TSX on Haswell CPUs
|
||||
return get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4800) == 0x4800;
|
||||
}
|
||||
|
||||
inline bool transaction_enter()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const auto status = _xbegin();
|
||||
|
||||
if (status == _XBEGIN_STARTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(status & _XABORT_RETRY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_system_info();
|
||||
}
|
||||
+31
-5
@@ -32,7 +32,6 @@
|
||||
#define SAFE_BUFFERS
|
||||
#define NEVER_INLINE __attribute__((noinline))
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#define thread_local __thread
|
||||
#endif
|
||||
|
||||
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
||||
@@ -49,7 +48,7 @@
|
||||
#define CONCATENATE_DETAIL(x, y) x ## y
|
||||
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
|
||||
|
||||
#define STRINGIZE_DETAIL(x) #x
|
||||
#define STRINGIZE_DETAIL(x) #x ""
|
||||
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
|
||||
|
||||
#define HERE "\n(in file " __FILE__ ":" STRINGIZE(__LINE__) ")"
|
||||
@@ -535,6 +534,26 @@ inline u64 cntlz64(u64 arg, bool nonzero = false)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u32 cnttz32(u32 arg, bool nonzero = false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward(&res, arg) || nonzero ? res : 32;
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctzll(arg) : 32;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u64 cnttz64(u64 arg, bool nonzero = false)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
ulong res;
|
||||
return _BitScanForward64(&res, arg) || nonzero ? res : 64;
|
||||
#else
|
||||
return arg || nonzero ? __builtin_ctzll(arg) : 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function, used by ""_u16, ""_u32, ""_u64
|
||||
constexpr u8 to_u8(char c)
|
||||
{
|
||||
@@ -919,7 +938,7 @@ struct error_code
|
||||
error_code() = default;
|
||||
|
||||
// Implementation must be provided specially
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg);
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg, const fmt_type_info* sup2, u64 arg2);
|
||||
|
||||
// Helper type
|
||||
enum class not_an_error : s32
|
||||
@@ -940,7 +959,7 @@ struct error_code
|
||||
|
||||
// Not an error constructor
|
||||
template<typename ET, typename = decltype(ET::__not_an_error)>
|
||||
error_code(const ET& value, int = 0)
|
||||
error_code(const ET& value, std::nullptr_t = nullptr)
|
||||
: value(static_cast<s32>(value))
|
||||
{
|
||||
}
|
||||
@@ -948,7 +967,14 @@ struct error_code
|
||||
// Error constructor
|
||||
template<typename ET, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value)))
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), nullptr, 0))
|
||||
{
|
||||
}
|
||||
|
||||
// Error constructor (2 args)
|
||||
template<typename ET, typename T2, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value, const T2& value2)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), fmt::get_type_info<fmt_unveil_t<T2>>(), fmt_unveil<T2>::get(value2)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Submodule Vulkan/Vulkan-LoaderAndValidationLayers updated: 115665a3b5...85926a33d4
+1
-1
Submodule Vulkan/glslang updated: 0e07119ae2...cf571f7310
+72
-31
@@ -1,41 +1,82 @@
|
||||
version: '0.0.2-{build}'
|
||||
#---------------------------------#
|
||||
# general configuration #
|
||||
#---------------------------------#
|
||||
|
||||
os: Visual Studio 2015
|
||||
platform: x64
|
||||
clone_folder: C:\rpcs3
|
||||
clone_depth: 3
|
||||
test: off
|
||||
# version format
|
||||
version: '0.0.4-{build}'
|
||||
|
||||
configuration:
|
||||
# Release
|
||||
- ReleaseLLVM
|
||||
#---------------------------------#
|
||||
# environment configuration #
|
||||
#---------------------------------#
|
||||
|
||||
before_build:
|
||||
- ps: $env:Date="$(git show -s --date=short --format='%ad')"
|
||||
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi
|
||||
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
|
||||
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
# Build worker image (VM template)
|
||||
image: Visual Studio 2015
|
||||
|
||||
build_script:
|
||||
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
# clone directory
|
||||
clone_folder: c:\projects\rpcs3
|
||||
|
||||
install:
|
||||
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
|
||||
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
|
||||
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-HVE3xvheVFX05lRFdnZlh5aUU" -FileName zlib.7z
|
||||
- set QTDIR=C:\Qt\5.8\msvc2015_64
|
||||
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%QTDIR%;%PATH%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
# set clone depth
|
||||
clone_depth: 3 # clone entire repository history if not defined
|
||||
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.2-$(Date)-$(COMMIT_SHA)_win64'
|
||||
type: zip
|
||||
# environment variables
|
||||
environment:
|
||||
QTDIR: C:\Qt\5.9.1\msvc2015_64
|
||||
|
||||
# build cache to preserve files/folders between builds
|
||||
cache:
|
||||
- llvmlibs.7z -> appveyor.yml
|
||||
- vulkan.7z -> appveyor.yml
|
||||
- zlib.7z -> appveyor.yml
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
- git submodule update --init 3rdparty/cereal 3rdparty/ffmpeg 3rdparty/GSL 3rdparty/hidapi 3rdparty/libpng 3rdparty/Optional 3rdparty/pugixml 3rdparty/zlib asmjit Utilities/yaml-cpp Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers
|
||||
|
||||
#---------------------------------#
|
||||
# build configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
|
||||
platform: x64
|
||||
|
||||
# build Configuration, i.e. Debug, Release, etc.
|
||||
configuration: Release - LLVM
|
||||
|
||||
build:
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
project: rpcs3.sln # path to Visual Studio solution or project
|
||||
# MSBuild verbosity level
|
||||
verbosity: normal
|
||||
|
||||
# scripts to run before build
|
||||
before_build:
|
||||
- set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%/#%APPVEYOR_PULL_REQUEST_NUMBER%
|
||||
- if "%APPVEYOR_PULL_REQUEST_NUMBER%"=="" (set BRANCH=%APPVEYOR_REPO_NAME%/%APPVEYOR_REPO_BRANCH%)
|
||||
- set PATH=%PATH%;%QTDIR%
|
||||
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
|
||||
- 7z x llvmlibs.7z -aos -o%APPVEYOR_BUILD_FOLDER% > null
|
||||
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
|
||||
- 7z x vulkan.7z -aos -o"%APPVEYOR_BUILD_FOLDER%\lib\%CONFIGURATION%-%PLATFORM%" > null
|
||||
|
||||
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
||||
before_package:
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.exp
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.lib
|
||||
- rm %APPVEYOR_BUILD_FOLDER%\bin\rpcs3.pdb
|
||||
- set COMMIT_DATE=%APPVEYOR_REPO_COMMIT_TIMESTAMP:~0,10%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
|
||||
#---------------------------------#
|
||||
# tests configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# to disable automatic tests
|
||||
test: off
|
||||
|
||||
#---------------------------------#
|
||||
# artifacts configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# pushing entire folder as a zip archive
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.4-$(COMMIT_DATE)-$(COMMIT_SHA)_win64'
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
Kuroi (Dark) Theme for RPCS3
|
||||
by Ani @ https://github.com/AniLeo
|
||||
r1 (2017.08.15)
|
||||
*/
|
||||
|
||||
/*
|
||||
Color Scheme
|
||||
(Darker to Lighter)
|
||||
|
||||
Black
|
||||
> 292929
|
||||
> 323232
|
||||
> 333333
|
||||
> 3d3d3d
|
||||
> 404040
|
||||
> 444444
|
||||
|
||||
Light Grey
|
||||
> 828790
|
||||
> bdc3c7
|
||||
> ecf0f1
|
||||
|
||||
> b1b1b1
|
||||
> 7f8c8d
|
||||
|
||||
Green
|
||||
> 2ecc71
|
||||
|
||||
Red
|
||||
> e74c3c
|
||||
*/
|
||||
|
||||
/* Every widget */
|
||||
QWidget {
|
||||
background-color: #323232;
|
||||
color: #bdc3c7;
|
||||
alternate-background-color: #3d3d3d;
|
||||
}
|
||||
|
||||
/* Mouse tooltips */
|
||||
QToolTip {
|
||||
border: 0.05em solid #323232;
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Table headers */
|
||||
QHeaderView::section {
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
padding-left: 0.2em;
|
||||
border: 0.05em solid #323232;
|
||||
}
|
||||
|
||||
/* Settings Dialog: Tabs */
|
||||
QTabBar::tab {
|
||||
color: #ecf0f1;
|
||||
border: 0.05em solid #444;
|
||||
border-bottom-style: none;
|
||||
background-color: #333333;
|
||||
padding-left: 0.9em;
|
||||
padding-right: 0.9em;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
margin-right: -0.2em;
|
||||
}
|
||||
QTabBar::tab:last {
|
||||
margin-right: 0em;
|
||||
}
|
||||
QTabBar::tab:!selected {
|
||||
color: #b1b1b1;
|
||||
border-bottom-style: solid;
|
||||
margin-top: 0.15em;
|
||||
background-color: #292929;
|
||||
}
|
||||
QTabBar::tab:hover {
|
||||
background-color: #333333;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 0.1em;
|
||||
border: 0.05em solid #ecf0f1;
|
||||
margin-top: 0.05em;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QCheckBox::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border-radius: 0.4em;
|
||||
border: 0.05em solid;
|
||||
border-color: white;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QRadioButton::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #404040;
|
||||
color: #fff;
|
||||
border: 0.05em solid #1e1e1e;
|
||||
border-radius: 0.15em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left: 0.4em;
|
||||
}
|
||||
QComboBox::disabled {
|
||||
background-color: #828790;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 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: #404040;
|
||||
}
|
||||
QPushButton::disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
QTextEdit {
|
||||
border: 0.05em solid #828790;
|
||||
}
|
||||
|
||||
/* For dock buttons to be visible */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background-color: #bdc3c7;
|
||||
border: 0.05em solid #000;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
/* Disable ugly borders */
|
||||
QTabWidget::pane {
|
||||
border: 0em solid #828790;
|
||||
}
|
||||
|
||||
/* Top menu bar */
|
||||
QMenuBar::item:selected {
|
||||
background: #444444;
|
||||
}
|
||||
QMenu::item {
|
||||
padding-left: 1.5em;
|
||||
padding-right: 0.75em;
|
||||
padding-top: 0.25em;
|
||||
padding-bottom: 0.25em;
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: #444444;
|
||||
border: 0.05em solid #bdc3c7;
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Libraries list */
|
||||
QListWidget::item:selected {
|
||||
background-color: #3d3d3d;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
QListWidget::item:hover {
|
||||
background-color: #4c4b4b;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #bdc3c7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QLabel#gamegrid_font {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Slider on toolbar */
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Seachbar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left: 0.7em;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Uniform colors in Toolbar */
|
||||
QToolButton {
|
||||
background: transparent;
|
||||
color: transparent;
|
||||
}
|
||||
QToolButton::disabled {
|
||||
background-color: #828790;
|
||||
}
|
||||
QToolButton::hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/* Set Theme UI colors */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#gamelist_toolbar_icon_color {
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
|
||||
/* Set Windows Taskbar Thumbnail colors */
|
||||
QLabel#thumbnail_icon_color {
|
||||
color: #444444;
|
||||
}
|
||||
|
||||
/* Set Log colors */
|
||||
QTextEdit#log_frame {
|
||||
background-color: #000000; /* Black */
|
||||
}
|
||||
QLabel#log_level_always {
|
||||
color: #00ffff; /* Cyan */
|
||||
}
|
||||
QLabel#log_level_fatal {
|
||||
color: #ff00ff; /* Fuchsia */
|
||||
}
|
||||
QLabel#log_level_error {
|
||||
color: #ff0000; /* Red */
|
||||
}
|
||||
QLabel#log_level_todo {
|
||||
color: #ff6000; /* Orange */
|
||||
}
|
||||
QLabel#log_level_success {
|
||||
color: #00ff00; /* Green */
|
||||
}
|
||||
QLabel#log_level_warning {
|
||||
color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#log_level_notice {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
QLabel#log_level_trace {
|
||||
color: #808080; /* Gray */
|
||||
}
|
||||
QLabel#log_stack {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
|
||||
/* Set TTY colors */
|
||||
QTextEdit#tty_frame {
|
||||
background-color: #000000; /* Black */
|
||||
}
|
||||
QLabel#tty_text {
|
||||
color: #ffffff; /* White */
|
||||
}
|
||||
|
||||
/* RSX Debugger */
|
||||
QLabel#rsx_debugger_display_buffer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Kernel Explorer */
|
||||
QDialog#kernel_explorer {
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Memory Viewer */
|
||||
QDialog#memory_viewer {
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_address_panel {
|
||||
color: #00cbff; /* Font Color: Blue */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_hex_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#memory_viewer_ascii_panel {
|
||||
color: #bdc3c7; /* Font Color: Grey */
|
||||
background-color: #323232;
|
||||
}
|
||||
|
||||
/* Debugger colors */
|
||||
QLabel#debugger_frame_breakpoint {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #ffff00; /* Yellow */
|
||||
}
|
||||
QLabel#debugger_frame_pc {
|
||||
color: #000000; /* Font Color: Black */
|
||||
background-color: #00ff00; /* Green */
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
|
||||
make_fself compiled.elf EBOOT.BIN
|
||||
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
// http://stackoverflow.com/a/34032216/78204
|
||||
|
||||
function Controller() {
|
||||
installer.autoRejectMessageBoxes();
|
||||
installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes);
|
||||
installer.installationFinished.connect(function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
})
|
||||
}
|
||||
|
||||
Controller.prototype.WelcomePageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.CredentialsPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.IntroductionPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.TargetDirectoryPageCallback = function()
|
||||
{
|
||||
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt");
|
||||
//gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("InstallerDirPath") + "/Qt");
|
||||
//gui.currentPageWidget().TargetDirectoryLineEdit.setText("/scratch/Qt");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
var widget = gui.currentPageWidget();
|
||||
|
||||
widget.deselectAll();
|
||||
widget.selectComponent("qt.592.gcc_64");
|
||||
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.LicenseAgreementPageCallback = function() {
|
||||
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.StartMenuDirectoryPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ReadyForInstallationPageCallback = function()
|
||||
{
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.FinishedPageCallback = function() {
|
||||
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
|
||||
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
|
||||
checkBoxForm.launchQtCreatorCheckBox.checked = false;
|
||||
}
|
||||
gui.clickButton(buttons.FinishButton);
|
||||
}
|
||||
+128
-33
@@ -12,8 +12,14 @@ if (WIN32)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5WinExtras_INCLUDE_DIRS})
|
||||
else()
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets)
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||
find_package(Qt5DBus)
|
||||
if (Qt5DBus_FOUND)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus)
|
||||
add_definitions(-DHAVE_QTDBUS)
|
||||
else()
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets)
|
||||
endif()
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Let's make sure we have Qt before we continue
|
||||
@@ -23,8 +29,8 @@ if (NOT Qt5Widgets_FOUND)
|
||||
if ("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
|
||||
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install an up-to-date qt5 version.
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-xenial
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt59-trusty
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-xenial
|
||||
https://launchpad.net/~beineri/+archive/ubuntu/opt-qt592-trusty
|
||||
just make sure to run
|
||||
source /opt/qt59/bin/qt59-env.sh
|
||||
before re-running cmake")
|
||||
@@ -85,10 +91,12 @@ else()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
if($ENV{CI})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1") # fix for travis gcc OoM crash. Might be fixed with the move to containers.
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
# This hides our LLVM from mesa's LLVM, otherwise we get some unresolvable conflicts.
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--exclude-libs,ALL")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_RC_COMPILER_INIT windres)
|
||||
enable_language(RC)
|
||||
@@ -98,20 +106,27 @@ if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
|
||||
endif()
|
||||
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3)
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3 -mrtm)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
# This fixes 'some' of the st11range issues. See issue #2516
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
|
||||
if(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-image_base,0x10000 -Wl,-pagezero_size,0x10000")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Some distros have the compilers set to use PIE by default, but RPCS3 doesn't work with PIE, so we need to disable it.
|
||||
CHECK_C_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
|
||||
if(HAS_NO_PIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
|
||||
if(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie")
|
||||
else()
|
||||
CHECK_C_COMPILER_FLAG("-nopie" HAS_NO_PIE)
|
||||
CHECK_C_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
|
||||
CHECK_C_COMPILER_FLAG("-nopie" HAS_NOPIE)
|
||||
|
||||
if(HAS_NO_PIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
|
||||
elseif(HAS_NOPIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nopie")
|
||||
endif()
|
||||
endif()
|
||||
@@ -125,15 +140,17 @@ else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS /DYNAMICBASE:NO /BASE:0x10000 /FIXED")
|
||||
endif()
|
||||
|
||||
set(ADDITIONAL_LIBS "")
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
#on some Linux distros shm_unlink and similar functions are in librt only
|
||||
set(ADDITIONAL_LIBS "rt" "X11" "asound")
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "rt")
|
||||
elseif(NOT MSVC AND NOT CMAKE_CXX_FLAGS MATCHES "LIBICONV_PLUG")
|
||||
#it seems like glibc includes the iconv functions we use but other libc
|
||||
#implementations like the one on OSX don't seem implement them
|
||||
set(ADDITIONAL_LIBS "iconv")
|
||||
else()
|
||||
set(ADDITIONAL_LIBS "")
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "iconv")
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} "X11")
|
||||
endif()
|
||||
|
||||
if(NOT RPCS3_SRC_DIR)
|
||||
@@ -149,6 +166,29 @@ find_package(OpenGL REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
if (NOT WITHOUT_LLVM)
|
||||
find_package(LLVM 4.0 CONFIG)
|
||||
if (NOT LLVM_FOUND)
|
||||
message("System LLVM was not found, LLVM will be built from the submodule.")
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD "X86" CACHE INTERNAL "")
|
||||
option(LLVM_BUILD_RUNTIME OFF)
|
||||
option(LLVM_BUILD_TOOLS OFF)
|
||||
option(LLVM_INCLUDE_DOCS OFF)
|
||||
option(LLVM_INCLUDE_EXAMPLES OFF)
|
||||
option(LLVM_INCLUDE_TESTS OFF)
|
||||
option(LLVM_INCLUDE_TOOLS OFF)
|
||||
option(LLVM_INCLUDE_UTILS OFF)
|
||||
option(WITH_POLLY OFF)
|
||||
|
||||
# LLVM needs to be built out-of-tree
|
||||
add_subdirectory(../llvm ../llvm_build)
|
||||
set(LLVM_DIR "${CMAKE_CURRENT_BINARY_DIR}/../llvm_build/lib/cmake/llvm/")
|
||||
|
||||
# now tries to find LLVM again
|
||||
find_package(LLVM 4.0 CONFIG)
|
||||
if (NOT LLVM_FOUND)
|
||||
message(WARNING "Couldn't build LLVM from the submodule. You might need to run `git submodule update --init`")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -158,6 +198,47 @@ elseif(WIN32)
|
||||
set(PLATFORM_ARCH "Windows/x86_64")
|
||||
else()
|
||||
set(PLATFORM_ARCH "linux/x86_64")
|
||||
option(USE_ALSA "ALSA audio backend" ON)
|
||||
option(USE_PULSE "PulseAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
option(USE_VULKAN "Vulkan render backend" ON)
|
||||
endif()
|
||||
|
||||
if(USE_ALSA)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(ALSA alsa)
|
||||
if(ALSA_FOUND)
|
||||
add_definitions(-DHAVE_ALSA)
|
||||
include_directories(SYSTEM ${ALSA_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${ALSA_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(USE_PULSE)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PULSE libpulse-simple)
|
||||
if(PULSE_FOUND)
|
||||
add_definitions(-DHAVE_PULSE)
|
||||
include_directories(SYSTEM ${PULSE_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${PULSE_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(USE_LIBEVDEV)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBEVDEV libevdev)
|
||||
if(LIBEVDEV_FOUND)
|
||||
add_definitions(-DHAVE_LIBEVDEV)
|
||||
include_directories(SYSTEM ${LIBEVDEV_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${LIBEVDEV_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(NOT WIN32 AND USE_VULKAN)
|
||||
find_package(Vulkan)
|
||||
if(VULKAN_FOUND)
|
||||
add_definitions(-DHAVE_VULKAN)
|
||||
list(APPEND ADDITIONAL_LIBS ${VULKAN_LIBRARY})
|
||||
else()
|
||||
message("WARNING! USE_VULKAN was enabled, but libvulkan was not found. RPCS3 will be compiled without Vulkan support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Select the version of libpng to use, default is builtin
|
||||
@@ -201,6 +282,7 @@ ${LLVM_INCLUDE_DIRS}
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/GL"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/stblib"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/cereal/include"
|
||||
"${RPCS3_SRC_DIR}/../3rdparty/Optional"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
@@ -214,16 +296,10 @@ if(NOT LLVM_FOUND)
|
||||
else()
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
add_definitions(-DLLVM_AVAILABLE)
|
||||
|
||||
#Use static linking for windows binary but always dynamic on *nix
|
||||
if (WIN32)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
|
||||
else()
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
endif()
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler)
|
||||
else()
|
||||
set(LLVM_LIBS LLVM)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS core support executionengine object runtimedyld x86desc x86info scalaropts mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
@@ -257,7 +333,7 @@ RPCS3_SRC
|
||||
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit/*.cpp"
|
||||
)
|
||||
|
||||
if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
if (NOT WIN32 AND VULKAN_FOUND)
|
||||
# Compile glslang and SPIRV modules needed for glsl compilation
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
@@ -266,7 +342,6 @@ if (NOT WIN32 AND "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/MachineIndependent/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/glslang/OSDependent/Unix/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/OGLCompilersDLL/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/hlsl/*.cpp"
|
||||
"${RPCS3_SRC_DIR}/../Vulkan/glslang/SPIRV/*.cpp"
|
||||
)
|
||||
|
||||
@@ -275,14 +350,14 @@ endif()
|
||||
|
||||
#File exclusion section
|
||||
|
||||
#Ignore vulkan if not on windows or linux
|
||||
if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
if(NOT WIN32 AND NOT VULKAN_FOUND)
|
||||
set (EXCLUDE_FILES "/RSX/VK/")
|
||||
endif()
|
||||
|
||||
# Ignore autogenerated moc_* files if present
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "moc_")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "rpcs3_automoc")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "qrc_resources.cpp")
|
||||
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
foreach (EXCLUDE_PATH ${EXCLUDE_FILES})
|
||||
@@ -294,7 +369,7 @@ foreach (TMP_PATH ${RPCS3_SRC})
|
||||
endforeach(TMP_PATH)
|
||||
|
||||
# Remove the Qt moc files as part of clean, they are compiled when generating automoc
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp")
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp" "${RPCS3_SRC_DIR}/qrc_resources.cpp")
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TMP_MOC}")
|
||||
|
||||
if (WIN32)
|
||||
@@ -315,11 +390,16 @@ if(WIN32)
|
||||
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
|
||||
else()
|
||||
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(rpcs3 hidapi-hidraw udev vulkan)
|
||||
if(APPLE)
|
||||
target_link_libraries(rpcs3 hidapi-mac "-framework CoreFoundation" "-framework IOKit")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(rpcs3 hidapi-hidraw udev)
|
||||
else()
|
||||
target_link_libraries(rpcs3 hidapi-libusb usb)
|
||||
endif()
|
||||
if(VULKAN_FOUND)
|
||||
target_link_libraries(rpcs3 ${VULKAN_LIBRARIES})
|
||||
endif()
|
||||
target_link_libraries(rpcs3 ${CMAKE_DL_LIBS} -lpthread ${ZLIB_LIBRARIES} ${ADDITIONAL_LIBS})
|
||||
if (USE_SYSTEM_FFMPEG)
|
||||
link_libraries(${FFMPEG_LIBRARY_DIR})
|
||||
@@ -347,6 +427,21 @@ target_link_libraries(rpcs3 ${RPCS3_QT_LIBS})
|
||||
|
||||
set_target_properties(rpcs3 PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${RPCS3_SRC_DIR}/stdafx.h")
|
||||
|
||||
if (MSVC)
|
||||
# Under Windows, some QT DLLs need to be in the same directory of the compiled
|
||||
# RPCS3 binary, so call the windeployqt tool that will take care of copying
|
||||
# them from the local QT installation at the end of the build.
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations --debug ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET rpcs3 POST_BUILD
|
||||
COMMAND $ENV{QTDIR}/bin/windeployqt --no-angle --no-opengl-sw --no-svg --no-translations ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
cotire(rpcs3)
|
||||
|
||||
# Unix installation
|
||||
|
||||
@@ -150,8 +150,8 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np
|
||||
const int metadata_section_size = ((edat->flags & EDAT_COMPRESSED_FLAG) != 0 || (edat->flags & EDAT_FLAG_0x20) != 0) ? 0x20 : 0x10;
|
||||
const int metadata_offset = 0x100;
|
||||
|
||||
std::unique_ptr<u8> enc_data;
|
||||
std::unique_ptr<u8> dec_data;
|
||||
std::unique_ptr<u8[]> enc_data;
|
||||
std::unique_ptr<u8[]> dec_data;
|
||||
u8 hash[0x10] = { 0 };
|
||||
u8 key_result[0x10] = { 0 };
|
||||
u8 hash_result[0x14] = { 0 };
|
||||
@@ -315,7 +315,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
|
||||
{
|
||||
const int total_blocks = (int)((edat->file_size + edat->block_size - 1) / edat->block_size);
|
||||
u64 size_left = (int)edat->file_size;
|
||||
std::unique_ptr<u8> data(new u8[edat->block_size]);
|
||||
std::unique_ptr<u8[]> data(new u8[edat->block_size]);
|
||||
|
||||
for (int i = 0; i < total_blocks; i++)
|
||||
{
|
||||
@@ -427,8 +427,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
|
||||
long bytes_read = 0;
|
||||
long bytes_to_read = metadata_size;
|
||||
std::unique_ptr<u8> metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8> empty_metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8[]> metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8[]> empty_metadata(new u8[metadata_size]);
|
||||
|
||||
while (bytes_to_read > 0)
|
||||
{
|
||||
@@ -487,7 +487,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
if ((edat->flags & EDAT_FLAG_0x20) != 0) //Sony failed again, they used buffer from 0x100 with half size of real metadata.
|
||||
{
|
||||
int metadata_buf_size = block_num * 0x10;
|
||||
std::unique_ptr<u8> metadata_buf(new u8[metadata_buf_size]);
|
||||
std::unique_ptr<u8[]> metadata_buf(new u8[metadata_buf_size]);
|
||||
f->seek(file_offset + metadata_offset);
|
||||
f->read(metadata_buf.get(), metadata_buf_size);
|
||||
sha1(metadata_buf.get(), metadata_buf_size, signature_hash);
|
||||
@@ -516,7 +516,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
{
|
||||
// Setup header signature hash.
|
||||
memset(signature_hash, 0, 20);
|
||||
std::unique_ptr<u8> header_buf(new u8[0xD8]);
|
||||
std::unique_ptr<u8[]> header_buf(new u8[0xD8]);
|
||||
f->seek(file_offset);
|
||||
f->read(header_buf.get(), 0xD8);
|
||||
sha1(header_buf.get(), 0xD8, signature_hash );
|
||||
@@ -577,7 +577,7 @@ int validate_npd_hashes(const char* file_name, const u8* klicensee, NPD_HEADER *
|
||||
int dev_hash_result = 0;
|
||||
|
||||
const int file_name_length = (int) strlen(file_name);
|
||||
std::unique_ptr<u8> buf(new u8[0x30 + file_name_length]);
|
||||
std::unique_ptr<u8[]> buf(new u8[0x30 + file_name_length]);
|
||||
|
||||
// Build the title buffer (content_id + file_name).
|
||||
memcpy(buf.get(), npd->content_id, 0x30);
|
||||
|
||||
+96
-16
@@ -3,19 +3,78 @@
|
||||
#include "aes.h"
|
||||
#include "sha1.h"
|
||||
#include "key_vault.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "Emu/VFS.h"
|
||||
#include "unpkg.h"
|
||||
|
||||
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync)
|
||||
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
|
||||
{
|
||||
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
std::vector<fs::file> filelist;
|
||||
u32 cur_file=0;
|
||||
|
||||
fs::file original_file(pkg_filepath);
|
||||
original_file.seek(pkg_f.pos());
|
||||
|
||||
filelist.push_back(std::move(original_file));
|
||||
|
||||
// Save current file offset (probably zero)
|
||||
const u64 start_offset = pkg_f.pos();
|
||||
u64 cur_offset = start_offset;
|
||||
u64 cur_file_offset = start_offset;
|
||||
|
||||
// Get basic PKG information
|
||||
PKGHeader header;
|
||||
|
||||
if (!pkg_f.read(header))
|
||||
auto archive_seek = [&](const s64 new_offset, const fs::seek_mode damode = fs::seek_set)
|
||||
{
|
||||
if(damode == fs::seek_set) cur_offset = new_offset;
|
||||
else if (damode == fs::seek_cur) cur_offset += new_offset;
|
||||
|
||||
u64 _offset = 0;
|
||||
for (u32 i = 0; i < filelist.size(); i++)
|
||||
{
|
||||
if (cur_offset < (_offset + filelist[i].size()))
|
||||
{
|
||||
cur_file = i;
|
||||
cur_file_offset = cur_offset - _offset;
|
||||
filelist[i].seek(cur_file_offset);
|
||||
break;
|
||||
}
|
||||
_offset += filelist[i].size();
|
||||
}
|
||||
};
|
||||
|
||||
auto archive_read = [&](const void *data_ptr, const u64 num_bytes)
|
||||
{
|
||||
u64 num_bytes_left = filelist[cur_file].size() - cur_file_offset;
|
||||
//check if it continues in another file
|
||||
if (num_bytes > num_bytes_left)
|
||||
{
|
||||
filelist[cur_file].read((u8 *)data_ptr, num_bytes_left);
|
||||
if ((cur_file + 1) < filelist.size()) cur_file++;
|
||||
else
|
||||
{
|
||||
cur_offset += num_bytes_left;
|
||||
cur_file_offset = filelist[cur_file].size();
|
||||
return num_bytes_left;
|
||||
}
|
||||
u64 num_read = filelist[cur_file].read((u8 *)data_ptr + num_bytes_left, num_bytes - num_bytes_left);
|
||||
cur_offset += (num_read + num_bytes_left);
|
||||
cur_file_offset = num_read;
|
||||
return (num_read+num_bytes_left);
|
||||
}
|
||||
|
||||
u64 num_read = filelist[cur_file].read((u8 *)data_ptr, num_bytes);
|
||||
|
||||
cur_offset += num_read;
|
||||
cur_file_offset += num_read;
|
||||
|
||||
return num_read;
|
||||
};
|
||||
|
||||
|
||||
if (archive_read(&header, sizeof(header)) != sizeof(header))
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file is too short!");
|
||||
return false;
|
||||
@@ -51,8 +110,29 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
|
||||
if (header.pkg_size > pkg_f.size())
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
|
||||
return false;
|
||||
//Check if multi-files pkg
|
||||
if (pkg_filepath.length() < 7 || pkg_filepath.substr(pkg_filepath.length() - 7).compare("_00.pkg") != 0)
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name_wo_number = pkg_filepath.substr(0, pkg_filepath.length() - 7);
|
||||
u64 cursize = pkg_f.size();
|
||||
while (cursize != header.pkg_size)
|
||||
{
|
||||
std::string archive_filename = fmt::format("%s_%02d.pkg", name_wo_number, filelist.size());
|
||||
|
||||
fs::file archive_file(archive_filename);
|
||||
if (!archive_file)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Missing part of the multi-files pkg: %s", archive_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
cursize += archive_file.size();
|
||||
filelist.push_back(std::move(archive_file));
|
||||
}
|
||||
}
|
||||
|
||||
if (header.data_size + header.data_offset > header.pkg_size)
|
||||
@@ -64,7 +144,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
be_t<u32> drm_type{0};
|
||||
be_t<u32> content_type{0};
|
||||
|
||||
pkg_f.seek(header.pkg_info_off);
|
||||
archive_seek(header.pkg_info_off);
|
||||
|
||||
for (u32 i = 0; i < header.pkg_info_num; i++)
|
||||
{
|
||||
@@ -74,7 +154,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
be_t<u32> size;
|
||||
} packet;
|
||||
|
||||
pkg_f.read(packet);
|
||||
archive_read(&packet, sizeof(packet));
|
||||
|
||||
// TODO
|
||||
switch (+packet.id)
|
||||
@@ -83,7 +163,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
{
|
||||
if (packet.size == sizeof(drm_type))
|
||||
{
|
||||
pkg_f.read(drm_type);
|
||||
archive_read(&drm_type, sizeof(drm_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -93,7 +173,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
{
|
||||
if (packet.size == sizeof(content_type))
|
||||
{
|
||||
pkg_f.read(content_type);
|
||||
archive_read(&content_type, sizeof(content_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -101,7 +181,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
}
|
||||
}
|
||||
|
||||
pkg_f.seek(packet.size, fs::seek_cur);
|
||||
archive_seek(packet.size, fs::seek_cur);
|
||||
}
|
||||
|
||||
// Allocate buffer with BUF_SIZE size or more if required
|
||||
@@ -110,10 +190,10 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
// Define decryption subfunction (`psp` arg selects the key for specific block)
|
||||
auto decrypt = [&](u64 offset, u64 size, const uchar* key) -> u64
|
||||
{
|
||||
pkg_f.seek(start_offset + header.data_offset + offset);
|
||||
archive_seek(start_offset + header.data_offset + offset);
|
||||
|
||||
// Read the data and set available size
|
||||
const u64 read = pkg_f.read(buf.get(), size);
|
||||
const u64 read = archive_read(buf.get(), size);
|
||||
|
||||
// Get block count
|
||||
const u64 blocks = (read + 15) / 16;
|
||||
@@ -206,7 +286,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
|
||||
decrypt(entry.name_offset, entry.name_size, is_psp ? PKG_AES_KEY2 : dec_key.data());
|
||||
|
||||
const std::string name(reinterpret_cast<char*>(buf.get()), entry.name_size);
|
||||
std::string name{reinterpret_cast<char*>(buf.get()), entry.name_size};
|
||||
|
||||
LOG_NOTICE(LOADER, "Entry 0x%08x: %s", entry.type, name);
|
||||
|
||||
@@ -224,17 +304,17 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
{
|
||||
const std::string path = dir + name;
|
||||
const std::string path = dir + vfs::escape(name);
|
||||
|
||||
const bool did_overwrite = fs::is_file(path);
|
||||
|
||||
if (did_overwrite && (entry.type&PKG_FILE_ENTRY_OVERWRITE) == 0)
|
||||
if (did_overwrite && (entry.type & PKG_FILE_ENTRY_OVERWRITE) == 0)
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Didn't overwrite %s", name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fs::file out{ path, fs::rewrite })
|
||||
if (fs::file out{path, fs::rewrite})
|
||||
{
|
||||
for (u64 pos = 0; pos < entry.file_size; pos += BUF_SIZE)
|
||||
{
|
||||
@@ -279,7 +359,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
case PKG_FILE_ENTRY_FOLDER:
|
||||
case 0x12:
|
||||
{
|
||||
const std::string path = dir + name;
|
||||
const std::string path = dir + vfs::escape(name);
|
||||
|
||||
if (fs::create_dir(path))
|
||||
{
|
||||
|
||||
@@ -57,4 +57,4 @@ struct PKGEntry
|
||||
be_t<u32> pad; // Padding (zeros)
|
||||
};
|
||||
|
||||
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, atomic_t<double>&);
|
||||
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, atomic_t<double>&, const std::string& pkg_filepath);
|
||||
|
||||
@@ -118,7 +118,7 @@ void aesecb128_encrypt(unsigned char *key, unsigned char *in, unsigned char *out
|
||||
|
||||
bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
|
||||
{
|
||||
std::unique_ptr<u8> out(new u8[key_len]);
|
||||
std::unique_ptr<u8[]> out(new u8[key_len]);
|
||||
|
||||
sha1_hmac(key, key_len, in, in_len, out.get());
|
||||
|
||||
@@ -132,7 +132,7 @@ void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_
|
||||
|
||||
bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
|
||||
{
|
||||
std::unique_ptr<u8> out(new u8[key_len]);
|
||||
std::unique_ptr<u8[]> out(new u8[key_len]);
|
||||
|
||||
aes_context ctx;
|
||||
aes_setkey_enc(&ctx, key, 128);
|
||||
|
||||
@@ -50,6 +50,8 @@ OpenALThread::OpenALThread()
|
||||
{
|
||||
m_format = g_cfg.audio.convert_to_u16 ? AL_FORMAT_71CHN16 : AL_FORMAT_71CHN32;
|
||||
}
|
||||
|
||||
m_buffers = std::make_unique<ALuint[]>(g_cfg.audio.frames);
|
||||
}
|
||||
|
||||
OpenALThread::~OpenALThread()
|
||||
@@ -83,7 +85,7 @@ void OpenALThread::Close()
|
||||
if (alIsSource(m_source))
|
||||
alDeleteSources(1, &m_source);
|
||||
|
||||
alDeleteBuffers(g_al_buffers_count, m_buffers);
|
||||
alDeleteBuffers(g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alDeleteBuffers");
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ void OpenALThread::Open(const void* src, int size)
|
||||
alGenSources(1, &m_source);
|
||||
checkForAlError("alGenSources");
|
||||
|
||||
alGenBuffers(g_al_buffers_count, m_buffers);
|
||||
alGenBuffers(g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alGenBuffers");
|
||||
|
||||
alSourcei(m_source, AL_LOOPING, AL_FALSE);
|
||||
@@ -106,13 +108,13 @@ void OpenALThread::Open(const void* src, int size)
|
||||
|
||||
m_buffer_size = size;
|
||||
|
||||
for (uint i = 0; i<g_al_buffers_count; ++i)
|
||||
for (int i = 0; i < g_cfg.audio.frames; ++i)
|
||||
{
|
||||
alBufferData(m_buffers[i], m_format, src, m_buffer_size, 48000);
|
||||
checkForAlError("alBufferData");
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
|
||||
alSourceQueueBuffers(m_source, g_cfg.audio.frames, m_buffers.get());
|
||||
checkForAlError("alSourceQueueBuffers");
|
||||
Play();
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
#include "3rdparty/OpenAL/include/alext.h"
|
||||
#include <memory>
|
||||
|
||||
class OpenALThread : public AudioThread
|
||||
{
|
||||
private:
|
||||
static const uint g_al_buffers_count = 24;
|
||||
|
||||
ALint m_format;
|
||||
ALuint m_source;
|
||||
ALuint m_buffers[g_al_buffers_count];
|
||||
std::unique_ptr<ALuint[]> m_buffers;
|
||||
ALsizei m_buffer_size;
|
||||
|
||||
public:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "ALSAThread.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
@@ -59,7 +59,7 @@ ALSAThread::ALSAThread()
|
||||
if (!check(snd_pcm_hw_params_set_channels(s_tls_handle, hw_params, g_cfg.audio.downmix_to_2ch ? 2 : 8), "snd_pcm_hw_params_set_channels"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, 8 * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
if (!check(snd_pcm_hw_params_set_buffer_size(s_tls_handle, hw_params, g_cfg.audio.frames * 256), "snd_pcm_hw_params_set_buffer_size"))
|
||||
return;
|
||||
|
||||
if (!check(snd_pcm_hw_params_set_period_size(s_tls_handle, hw_params, 256, 0), "snd_pcm_hw_params_set_period_size"))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "Emu/System.h"
|
||||
#include "PulseThread.h"
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
|
||||
PulseThread::PulseThread()
|
||||
{
|
||||
}
|
||||
|
||||
PulseThread::~PulseThread()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void PulseThread::Play()
|
||||
{
|
||||
}
|
||||
|
||||
void PulseThread::Close()
|
||||
{
|
||||
if(this->connection) {
|
||||
pa_simple_free(this->connection);
|
||||
this->connection = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseThread::Stop()
|
||||
{
|
||||
}
|
||||
|
||||
void PulseThread::Open(const void* src, int size)
|
||||
{
|
||||
pa_sample_spec ss;
|
||||
ss.format = g_cfg.audio.convert_to_u16 ? PA_SAMPLE_S16LE : PA_SAMPLE_FLOAT32LE;
|
||||
ss.channels = g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
ss.rate = 48000;
|
||||
|
||||
int err;
|
||||
this->connection = pa_simple_new(NULL, "RPCS3", PA_STREAM_PLAYBACK, NULL, "Game", &ss, NULL, NULL, &err);
|
||||
if(!this->connection) {
|
||||
fprintf(stderr, "PulseAudio: Failed to initialize audio: %s\n", pa_strerror(err));
|
||||
}
|
||||
|
||||
this->AddData(src, size);
|
||||
}
|
||||
|
||||
void PulseThread::AddData(const void* src, int size)
|
||||
{
|
||||
if(this->connection) {
|
||||
int err;
|
||||
if(pa_simple_write(this->connection, src, size, &err) < 0) {
|
||||
fprintf(stderr, "PulseAudio: Failed to write audio stream: %s\n", pa_strerror(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
#include <pulse/simple.h>
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
class PulseThread : public AudioThread
|
||||
{
|
||||
public:
|
||||
PulseThread();
|
||||
virtual ~PulseThread() override;
|
||||
|
||||
virtual void Play() override;
|
||||
virtual void Open(const void* src, int size) override;
|
||||
virtual void Close() override;
|
||||
virtual void Stop() override;
|
||||
virtual void AddData(const void* src, int size) override;
|
||||
|
||||
private:
|
||||
pa_simple *connection = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "CPUThread.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Utilities/GDBDebugServer.h"
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
+22
-4
@@ -1,9 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
#include "MFC.h"
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
template <>
|
||||
void fmt_class_string<MFC>::format(std::string& out, u64 arg)
|
||||
{
|
||||
@@ -145,10 +148,25 @@ void mfc_thread::cpu_task()
|
||||
vm::reservation_acquire(cmd.eal, 128);
|
||||
|
||||
// Store unconditionally
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
_xend();
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
}
|
||||
}
|
||||
else if (cmd.cmd & MFC_LIST_MASK)
|
||||
{
|
||||
|
||||
@@ -195,6 +195,12 @@ s32 cellAtracGetInternalErrorInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<s32>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAtracGetSamplingRate()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAtrac);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellAtrac)("cellAtrac", []()
|
||||
{
|
||||
REG_FUNC(cellAtrac, cellAtracSetDataAndGetMemSize);
|
||||
@@ -227,4 +233,6 @@ DECLARE(ppu_module_manager::cellAtrac)("cellAtrac", []()
|
||||
REG_FUNC(cellAtrac, cellAtracResetPlayPosition);
|
||||
|
||||
REG_FUNC(cellAtrac, cellAtracGetInternalErrorInfo);
|
||||
|
||||
REG_FUNC(cellAtrac, cellAtracGetSamplingRate);
|
||||
});
|
||||
|
||||
@@ -203,6 +203,12 @@ s32 cellAtracMultiGetInternalErrorInfo(vm::ptr<CellAtracMultiHandle> pHandle, vm
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAtracMultiGetSamplingRate()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAtracMulti);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellAtracMulti)("cellAtracMulti", []()
|
||||
{
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiSetDataAndGetMemSize);
|
||||
@@ -236,4 +242,6 @@ DECLARE(ppu_module_manager::cellAtracMulti)("cellAtracMulti", []()
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiResetPlayPosition);
|
||||
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiGetInternalErrorInfo);
|
||||
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiGetSamplingRate);
|
||||
});
|
||||
|
||||
@@ -12,6 +12,34 @@
|
||||
|
||||
logs::channel cellAudio("cellAudio");
|
||||
|
||||
template <>
|
||||
void fmt_class_string<CellAudioError>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](CellAudioError value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
STR_CASE(CELL_AUDIO_ERROR_ALREADY_INIT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM);
|
||||
STR_CASE(CELL_AUDIO_ERROR_NOT_INIT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PARAM);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_FULL);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_ALREADY_RUN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_OPEN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_NOT_RUN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_TRANS_EVENT);
|
||||
STR_CASE(CELL_AUDIO_ERROR_PORT_OPEN);
|
||||
STR_CASE(CELL_AUDIO_ERROR_SHAREDMEMORY);
|
||||
STR_CASE(CELL_AUDIO_ERROR_MUTEX);
|
||||
STR_CASE(CELL_AUDIO_ERROR_EVENT_QUEUE);
|
||||
STR_CASE(CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND);
|
||||
STR_CASE(CELL_AUDIO_ERROR_TAG_NOT_FOUND);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
{
|
||||
m_buffer.set(vm::alloc(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, vm::main));
|
||||
@@ -29,6 +57,8 @@ void audio_config::on_init(const std::shared_ptr<void>& _this)
|
||||
|
||||
void audio_config::on_task()
|
||||
{
|
||||
thread_ctrl::set_native_priority(1);
|
||||
|
||||
AudioDumper m_dump(g_cfg.audio.dump_to_file ? 2 : 0); // Init AudioDumper for 2 channels if enabled
|
||||
|
||||
float buf2ch[2 * BUFFER_SIZE]{}; // intermediate buffer for 2 channels
|
||||
@@ -309,12 +339,12 @@ void audio_config::on_task()
|
||||
case 8: m_dump.WriteData(&buf8ch, sizeof(buf8ch)); break; // write file data (8 ch)
|
||||
}
|
||||
|
||||
cellAudio.trace("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
time_pos, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
cellAudio.trace("Audio perf: (access=%d, AddData=%d, events=%d, dump=%d)",
|
||||
stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3);
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioInit()
|
||||
error_code cellAudioInit()
|
||||
{
|
||||
cellAudio.warning("cellAudioInit()");
|
||||
|
||||
@@ -329,7 +359,7 @@ s32 cellAudioInit()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioQuit()
|
||||
error_code cellAudioQuit()
|
||||
{
|
||||
cellAudio.warning("cellAudioQuit()");
|
||||
|
||||
@@ -344,7 +374,7 @@ s32 cellAudioQuit()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
|
||||
error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum);
|
||||
|
||||
@@ -444,7 +474,7 @@ s32 cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32> portN
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
error_code cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
{
|
||||
cellAudio.warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig);
|
||||
|
||||
@@ -479,7 +509,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr<CellAudioPortConfig> portConfig)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioPortStart(u32 portNum)
|
||||
error_code cellAudioPortStart(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortStart(portNum=%d)", portNum);
|
||||
|
||||
@@ -504,7 +534,7 @@ s32 cellAudioPortStart(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioPortClose(u32 portNum)
|
||||
error_code cellAudioPortClose(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortClose(portNum=%d)", portNum);
|
||||
|
||||
@@ -529,7 +559,7 @@ s32 cellAudioPortClose(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioPortStop(u32 portNum)
|
||||
error_code cellAudioPortStop(u32 portNum)
|
||||
{
|
||||
cellAudio.warning("cellAudioPortStop(portNum=%d)", portNum);
|
||||
|
||||
@@ -554,7 +584,7 @@ s32 cellAudioPortStop(u32 portNum)
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
{
|
||||
cellAudio.trace("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp);
|
||||
|
||||
@@ -584,7 +614,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr<u64> stamp)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
{
|
||||
cellAudio.trace("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag);
|
||||
|
||||
@@ -627,7 +657,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr<u64> tag)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetPortLevel(u32 portNum, float level)
|
||||
error_code cellAudioSetPortLevel(u32 portNum, float level)
|
||||
{
|
||||
cellAudio.trace("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level);
|
||||
|
||||
@@ -662,7 +692,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
error_code cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
{
|
||||
cellAudio.warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key);
|
||||
|
||||
@@ -693,7 +723,7 @@ s32 cellAudioCreateNotifyEventQueue(vm::ptr<u32> id, vm::ptr<u64> key)
|
||||
return CELL_AUDIO_ERROR_EVENT_QUEUE;
|
||||
}
|
||||
|
||||
s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
|
||||
error_code cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags);
|
||||
|
||||
@@ -707,7 +737,7 @@ s32 cellAudioCreateNotifyEventQueueEx(vm::ptr<u32> id, vm::ptr<u64> key, u32 iFl
|
||||
return CELL_AUDIO_ERROR_EVENT_QUEUE;
|
||||
}
|
||||
|
||||
s32 cellAudioSetNotifyEventQueue(u64 key)
|
||||
error_code cellAudioSetNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
@@ -733,7 +763,7 @@ s32 cellAudioSetNotifyEventQueue(u64 key)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
|
||||
@@ -742,7 +772,7 @@ s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
error_code cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
{
|
||||
cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
@@ -768,7 +798,7 @@ s32 cellAudioRemoveNotifyEventQueue(u64 key)
|
||||
return CELL_AUDIO_ERROR_TRANS_EVENT;
|
||||
}
|
||||
|
||||
s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
error_code cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
{
|
||||
cellAudio.todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
|
||||
@@ -777,7 +807,7 @@ s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
error_code cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
|
||||
|
||||
@@ -812,7 +842,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
error_code cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume);
|
||||
|
||||
@@ -881,7 +911,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr<float> src, u32 samples, float volu
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
error_code cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
{
|
||||
cellAudio.trace("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume);
|
||||
|
||||
@@ -935,25 +965,25 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr<float> src, float volume)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
error_code cellAudioMiscSetAccessoryVolume(u32 devNum, float volume)
|
||||
{
|
||||
cellAudio.todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSendAck(u64 data3)
|
||||
error_code cellAudioSendAck(u64 data3)
|
||||
{
|
||||
cellAudio.todo("cellAudioSendAck(data3=0x%llx)", data3);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
|
||||
error_code cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice)
|
||||
{
|
||||
cellAudio.todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream)
|
||||
error_code cellAudioUnsetPersonalDevice(s32 iPersonalStream)
|
||||
{
|
||||
cellAudio.todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream);
|
||||
return CELL_OK;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Error codes
|
||||
enum
|
||||
enum CellAudioError : u32
|
||||
{
|
||||
CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701,
|
||||
CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702,
|
||||
|
||||
@@ -11,39 +11,39 @@ logs::channel cellAvconfExt("cellAvconfExt");
|
||||
|
||||
vm::gvar<f32> g_gamma; // TODO
|
||||
|
||||
s32 cellAudioOutUnregisterDevice()
|
||||
s32 cellAudioOutUnregisterDevice(u32 deviceNumber)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutUnregisterDevice(deviceNumber=0x%x)", deviceNumber);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutGetDeviceInfo2()
|
||||
s32 cellAudioOutGetDeviceInfo2(u32 deviceNumber, u32 deviceIndex, vm::ptr<CellAudioOutDeviceInfo2> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutGetDeviceInfo2(deviceNumber=0x%x, deviceIndex=0x%x, info=*0x%x)", deviceNumber, deviceIndex, info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetXVColor()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetupDisplay()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInGetDeviceInfo()
|
||||
s32 cellAudioInGetDeviceInfo(u32 deviceNumber, u32 deviceIndex, vm::ptr<CellAudioInDeviceInfo> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInGetDeviceInfo(deviceNumber=0x%x, deviceIndex=0x%x, info=*0x%x)", deviceNumber, deviceIndex, info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutConvertCursorColor()
|
||||
s32 cellVideoOutConvertCursorColor(u32 videoOut, s32 displaybuffer_format, f32 gamma, s32 source_buffer_format, vm::ptr<void> src_addr, vm::ptr<u32> dest_addr, s32 num)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellVideoOutConvertCursorColor(videoOut=%d, displaybuffer_format=0x%x, gamma=0x%x, source_buffer_format=0x%x, src_addr=*0x%x, dest_addr=*0x%x, num=0x%x)", videoOut, displaybuffer_format, gamma, source_buffer_format, src_addr, dest_addr, num);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -61,16 +61,16 @@ s32 cellVideoOutGetGamma(u32 videoOut, vm::ptr<f32> gamma)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInGetAvailableDeviceInfo()
|
||||
s32 cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDeviceInfo> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
cellAvconfExt.todo("cellAudioInGetAvailableDeviceInfo(count=0x%x, info=*0x%x)", count, info);
|
||||
return 0; // number of available devices
|
||||
}
|
||||
|
||||
s32 cellAudioOutGetAvailableDeviceInfo()
|
||||
s32 cellAudioOutGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioOutDeviceInfo2> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
cellAvconfExt.todo("cellAudioOutGetAvailableDeviceInfo(count=0x%x, info=*0x%x)", count, info);
|
||||
return 0; // number of available devices
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetGamma(u32 videoOut, f32 gamma)
|
||||
@@ -92,37 +92,37 @@ s32 cellVideoOutSetGamma(u32 videoOut, f32 gamma)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutRegisterDevice()
|
||||
s32 cellAudioOutRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::ptr<CellAudioOutRegistrationOption> option, vm::ptr<CellAudioOutDeviceConfiguration> config)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutRegisterDevice(deviceType=0x%llx, name=%s, option=*0x%x, config=*0x%x)", deviceType, name, option, config);
|
||||
return 0; // device number
|
||||
}
|
||||
|
||||
s32 cellAudioOutSetDeviceMode(u32 deviceMode)
|
||||
{
|
||||
cellAvconfExt.todo("cellAudioOutSetDeviceMode(deviceMode=0x%x)", deviceMode);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutSetDeviceMode()
|
||||
s32 cellAudioInSetDeviceMode(u32 deviceMode)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInSetDeviceMode(deviceMode=0x%x)", deviceMode);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInSetDeviceMode()
|
||||
s32 cellAudioInRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::ptr<CellAudioInRegistrationOption> option, vm::ptr<CellAudioInDeviceConfiguration> config)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInRegisterDevice(deviceType=0x%llx, name=%s, option=*0x%x, config=*0x%x)", deviceType, name, option, config);
|
||||
return 0; // device number
|
||||
}
|
||||
|
||||
s32 cellAudioInUnregisterDevice(u32 deviceNumber)
|
||||
{
|
||||
cellAvconfExt.todo("cellAudioInUnregisterDevice(deviceNumber=0x%x)", deviceNumber);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInRegisterDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInUnregisterDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> screenSize)
|
||||
s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<f32> screenSize)
|
||||
{
|
||||
cellAvconfExt.warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize=*0x%x)", videoOut, screenSize);
|
||||
|
||||
@@ -143,10 +143,16 @@ s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> screenSize)
|
||||
return CELL_VIDEO_OUT_ERROR_VALUE_IS_NOT_SET;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetCopyControl(u32 videoOut, u32 control)
|
||||
{
|
||||
cellAvconfExt.todo("cellVideoOutSetCopyControl(videoOut=%d, control=0x%x)", videoOut, control);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
|
||||
{
|
||||
REG_VNID(cellSysutilAvconfExt, 0x00000000u, g_gamma).init = []
|
||||
REG_VAR(cellSysutilAvconfExt, g_gamma).flag(MFF_HIDDEN).init = []
|
||||
{
|
||||
// Test
|
||||
*g_gamma = 1.0f;
|
||||
@@ -168,4 +174,5 @@ DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
|
||||
REG_FUNC(cellSysutilAvconfExt, cellAudioInRegisterDevice);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellAudioInUnregisterDevice);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellVideoOutGetScreenSize);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellVideoOutSetCopyControl);
|
||||
});
|
||||
|
||||
@@ -2,16 +2,35 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel cellCrossController("cellCrossController");
|
||||
|
||||
s32 cellCrossController_37E1F502() // LittleBigPlanet 2 and 3
|
||||
struct CellCrossControllerParam
|
||||
{
|
||||
cellCrossController.todo("cellCrossController_37E1F502");
|
||||
vm::bcptr<char> pPackageFileName;
|
||||
vm::bcptr<char> pSignatureFileName;
|
||||
vm::bcptr<char> pIconFileName;
|
||||
vm::bptr<void> option;
|
||||
};
|
||||
|
||||
struct CellCrossControllerPackageInfo
|
||||
{
|
||||
vm::bcptr<char> pTitle;
|
||||
vm::bcptr<char> pTitleId;
|
||||
vm::bcptr<char> pAppVer;
|
||||
};
|
||||
|
||||
using CellCrossControllerCallback = void(s32 status, s32 errorCode, vm::ptr<void> option, vm::ptr<void> userdata);
|
||||
|
||||
s32 cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pParam, vm::cptr<CellCrossControllerPackageInfo> pPkgInfo, vm::ptr<CellCrossControllerCallback> cb, vm::ptr<void> userdata) // LittleBigPlanet 2 and 3
|
||||
{
|
||||
cellCrossController.todo("cellCrossControllerInitialize(pParam=*0x%x, pPkgInfo=*0x%x, cb=*0x%x, userdata=*0x%x)", pParam, pPkgInfo, cb, userdata);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellCrossController)("cellCrossController", []()
|
||||
{
|
||||
REG_FNID(cellCrossController, 0x37E1F502, cellCrossController_37E1F502);
|
||||
REG_FUNC(cellCrossController, cellCrossControllerInitialize);
|
||||
});
|
||||
|
||||
@@ -1035,22 +1035,22 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsChangeFileSizeWithoutAllocation);
|
||||
REG_FUNC(sys_fs, cellFsChmod);
|
||||
REG_FUNC(sys_fs, cellFsChown);
|
||||
REG_FUNC(sys_fs, cellFsClose).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsClosedir).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsClose).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsClosedir).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsFcntl);
|
||||
REG_FUNC(sys_fs, cellFsFdatasync);
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsFGetBlockSize2);
|
||||
REG_FUNC(sys_fs, cellFsFstat).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFsync);
|
||||
REG_FUNC(sys_fs, cellFsFtruncate).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsFtruncate).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsGetBlockSize);
|
||||
REG_FUNC(sys_fs, cellFsGetBlockSize2);
|
||||
REG_FUNC(sys_fs, cellFsGetDirectoryEntries);
|
||||
REG_FUNC(sys_fs, cellFsGetFreeSize);
|
||||
REG_FUNC(sys_fs, cellFsGetPath);
|
||||
REG_FUNC(sys_fs, cellFsLink);
|
||||
REG_FUNC(sys_fs, cellFsLseek).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsLseek).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsLsnGetCDA);
|
||||
REG_FUNC(sys_fs, cellFsLsnGetCDASize);
|
||||
REG_FUNC(sys_fs, cellFsLsnLock);
|
||||
@@ -1063,8 +1063,8 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsOpen);
|
||||
REG_FUNC(sys_fs, cellFsOpen2);
|
||||
REG_FUNC(sys_fs, cellFsOpendir);
|
||||
REG_FUNC(sys_fs, cellFsRead).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsReaddir).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsRead).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsReaddir).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsReadWithOffset);
|
||||
REG_FUNC(sys_fs, cellFsRegisterConversionCallback);
|
||||
REG_FUNC(sys_fs, cellFsRename);
|
||||
@@ -1095,6 +1095,6 @@ DECLARE(ppu_module_manager::cellFs)("sys_fs", []()
|
||||
REG_FUNC(sys_fs, cellFsUnlink);
|
||||
REG_FUNC(sys_fs, cellFsUnregisterL10nCallbacks);
|
||||
REG_FUNC(sys_fs, cellFsUtime);
|
||||
REG_FUNC(sys_fs, cellFsWrite).flags = MFF_PERFECT;
|
||||
REG_FUNC(sys_fs, cellFsWrite).flag(MFF_PERFECT);
|
||||
REG_FUNC(sys_fs, cellFsWriteWithOffset);
|
||||
});
|
||||
|
||||
@@ -80,14 +80,13 @@ struct content_permission final
|
||||
// SFO file
|
||||
psf::registry sfo;
|
||||
|
||||
// True if temporary directory is created and must be moved or deleted
|
||||
bool is_temporary = false;
|
||||
// Temporary directory path
|
||||
std::string temp;
|
||||
|
||||
template <typename Dir, typename Sfo>
|
||||
content_permission(Dir&& dir, Sfo&& sfo, bool is_temp = false)
|
||||
content_permission(Dir&& dir, Sfo&& sfo)
|
||||
: dir(std::forward<Dir>(dir))
|
||||
, sfo(std::forward<Sfo>(sfo))
|
||||
, is_temporary(is_temp)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,9 +94,9 @@ struct content_permission final
|
||||
{
|
||||
try
|
||||
{
|
||||
if (is_temporary)
|
||||
if (!temp.empty())
|
||||
{
|
||||
fs::remove_all(vfs::get("/dev_hdd1/game/" + dir));
|
||||
fs::remove_all(temp);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -183,13 +182,14 @@ s32 cellHddGameGetSizeKB(vm::ptr<u32> size)
|
||||
{
|
||||
cellGame.warning("cellHddGameGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const std::string& local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
const std::string local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_HDDGAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -209,16 +209,16 @@ s32 cellGameDataGetSizeKB(vm::ptr<u32> size)
|
||||
{
|
||||
cellGame.warning("cellGameDataGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const std::string& local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
const std::string local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_GAMEDATA_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
|
||||
}
|
||||
|
||||
s32 cellGameDataSetSystemVer()
|
||||
@@ -262,7 +262,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (category == "AP" || category == "AV" || category == "HG")
|
||||
else if (category == "AP" || category == "AV" || category == "HG" || category == "AT" || category == "AM" || category == "SF")
|
||||
{
|
||||
*type = CELL_GAME_GAMETYPE_HDD;
|
||||
*attributes = 0; // TODO
|
||||
@@ -383,7 +383,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
|
||||
const std::string dir = prm->dir.empty() ? "/dev_bdvd/PS3_GAME"s : "/dev_hdd0/game/" + prm->dir;
|
||||
|
||||
if (prm->is_temporary)
|
||||
if (!prm->temp.empty())
|
||||
{
|
||||
// Make temporary directory persistent
|
||||
const auto vdir = vfs::get(dir);
|
||||
@@ -393,7 +393,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
fmt::throw_exception("cellGameContentPermit(): epic fail: directory '%s' already exists", dir);
|
||||
}
|
||||
|
||||
if (fs::rename(vfs::get("/dev_hdd1/game/" + prm->dir), vdir))
|
||||
if (fs::rename(prm->temp, vdir, false))
|
||||
{
|
||||
cellGame.success("cellGameContentPermit(): directory '%s' has been created", dir);
|
||||
}
|
||||
@@ -406,7 +406,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), prm->sfo);
|
||||
|
||||
// Disable deletion
|
||||
prm->is_temporary = false;
|
||||
prm->temp.clear();
|
||||
}
|
||||
|
||||
strcpy_trunc(*contentInfoPath, dir);
|
||||
@@ -570,8 +570,8 @@ error_code cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<c
|
||||
strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo);
|
||||
strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
|
||||
|
||||
prm->temp = vfs::get(tmp_contentInfo);
|
||||
cellGame.success("cellGameCreateGameData(): temporary directory '%s' has been created", tmp_contentInfo);
|
||||
prm->is_temporary = true;
|
||||
|
||||
// Initial PARAM.SFO parameters (overwrite)
|
||||
prm->sfo =
|
||||
@@ -659,6 +659,11 @@ error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize)
|
||||
{
|
||||
cellGame.warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize);
|
||||
|
||||
if (!buf || bufsize == 0)
|
||||
{
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
@@ -685,6 +690,11 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
|
||||
{
|
||||
cellGame.warning("cellGameSetParamString(id=%d, buf=*0x%x)", id, buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
return CELL_GAME_ERROR_PARAM;
|
||||
}
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
@@ -714,9 +724,10 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
error_code cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
{
|
||||
cellGame.warning("cellGameGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
@@ -724,13 +735,14 @@ s32 cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const std::string& local_dir = prm->is_temporary? vfs::get("/dev_hdd1/game/"s + prm->dir) : vfs::get("/dev_hdd0/game/"s + prm->dir); //should we check the temporary folder?
|
||||
const std::string local_dir = !prm->temp.empty() ? prm->temp : vfs::get("/dev_hdd0/game/" + prm->dir);
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
|
||||
logs::channel cellGameExec("cellGameExec");
|
||||
|
||||
s32 cellGameSetExitParam()
|
||||
s32 cellGameSetExitParam(u32 execdata)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellGameExec.todo("cellGameSetExitParam(execdata=0x%x)", execdata);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeDataExportPath(vm::ptr<char> exportPath)
|
||||
{
|
||||
cellGameExec.warning("cellGameGetHomeDataExportPath(exportPath=0x%x)", exportPath);
|
||||
cellGameExec.warning("cellGameGetHomeDataExportPath(exportPath=*0x%x)", exportPath);
|
||||
|
||||
// TODO: PlayStation home is defunct.
|
||||
|
||||
@@ -21,12 +22,17 @@ s32 cellGameGetHomeDataExportPath(vm::ptr<char> exportPath)
|
||||
|
||||
s32 cellGameGetHomePath()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
UNIMPLEMENTED_FUNC(cellGameExec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeDataImportPath()
|
||||
s32 cellGameGetHomeDataImportPath(vm::ptr<char> importPath)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellGameExec.warning("cellGameGetHomeDataImportPath(importPath=*0x%x)", importPath);
|
||||
|
||||
// TODO: PlayStation home is defunct.
|
||||
|
||||
return CELL_GAME_ERROR_NOAPP;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeLaunchOptionPath(vm::ptr<char> commonPath, vm::ptr<char> personalPath)
|
||||
@@ -37,9 +43,9 @@ s32 cellGameGetHomeLaunchOptionPath(vm::ptr<char> commonPath, vm::ptr<char> pers
|
||||
return CELL_GAME_ERROR_NOAPP;
|
||||
}
|
||||
|
||||
s32 cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm::ptr<u32> execData)
|
||||
s32 cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm::ptr<u32> execdata)
|
||||
{
|
||||
cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execData=*0x%x)", type, dirName, execData);
|
||||
cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execdata=*0x%x)", type, dirName, execdata);
|
||||
|
||||
// TODO: Support more boot types
|
||||
*type = CELL_GAME_GAMETYPE_SYS;
|
||||
|
||||
@@ -26,16 +26,19 @@ const u32 tiled_pitches[] = {
|
||||
0x00010000
|
||||
};
|
||||
|
||||
struct CellGcmSysConfig {
|
||||
u32 zculls_addr;
|
||||
vm::ptr<CellGcmDisplayInfo> gcm_buffers{ vm::null };
|
||||
u32 tiles_addr;
|
||||
u32 ctxt_addr;
|
||||
CellGcmConfig current_config;
|
||||
CellGcmContextData current_context;
|
||||
gcmInfo gcm_info;
|
||||
};
|
||||
|
||||
u64 system_mode = 0;
|
||||
u32 local_size = 0;
|
||||
u32 local_addr = 0;
|
||||
u64 system_mode = 0;
|
||||
|
||||
CellGcmConfig current_config;
|
||||
CellGcmContextData current_context;
|
||||
gcmInfo gcm_info;
|
||||
|
||||
u32 map_offset_addr = 0;
|
||||
u32 map_offset_pos = 0;
|
||||
|
||||
// Auxiliary functions
|
||||
|
||||
@@ -82,7 +85,12 @@ void InitOffsetTable()
|
||||
u32 cellGcmGetLabelAddress(u8 index)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetLabelAddress(index=%d)", index);
|
||||
return gcm_info.label_addr + 0x10 * index;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
|
||||
return m_config->gcm_info.label_addr + 0x10 * index;
|
||||
}
|
||||
|
||||
vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 location)
|
||||
@@ -94,7 +102,7 @@ vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 lo
|
||||
cellGcmSys.error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index);
|
||||
return vm::null;
|
||||
}
|
||||
return vm::ptr<CellGcmReportData>::make(0xC0000000 + index * 0x10);
|
||||
return vm::ptr<CellGcmReportData>::make(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
if (location == CELL_GCM_LOCATION_MAIN) {
|
||||
@@ -117,7 +125,7 @@ u64 cellGcmGetTimeStamp(u32 index)
|
||||
cellGcmSys.error("cellGcmGetTimeStamp: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return vm::read64(0xC0000000 + index * 0x10);
|
||||
return vm::read64(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
u32 cellGcmGetCurrentField()
|
||||
@@ -144,7 +152,7 @@ u32 cellGcmGetNotifyDataAddress(u32 index)
|
||||
*/
|
||||
vm::ptr<CellGcmReportData> _cellGcmFunc12()
|
||||
{
|
||||
return vm::ptr<CellGcmReportData>::make(0xC0000000); // TODO
|
||||
return vm::ptr<CellGcmReportData>::make(0x40301400); // TODO
|
||||
}
|
||||
|
||||
u32 cellGcmGetReport(u32 type, u32 index)
|
||||
@@ -172,7 +180,7 @@ u32 cellGcmGetReportDataAddress(u32 index)
|
||||
cellGcmSys.error("cellGcmGetReportDataAddress: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return 0xC0000000 + index * 0x10;
|
||||
return 0x40301400 + index * 0x10;
|
||||
}
|
||||
|
||||
u32 cellGcmGetReportDataLocation(u32 index, u32 location)
|
||||
@@ -192,7 +200,7 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
|
||||
cellGcmSys.error("cellGcmGetTimeStampLocation: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return vm::read64(0xC0000000 + index * 0x10);
|
||||
return vm::read64(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
if (location == CELL_GCM_LOCATION_MAIN) {
|
||||
@@ -214,20 +222,31 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
|
||||
u32 cellGcmGetControlRegister()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetControlRegister()");
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
return gcm_info.control_addr;
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.control_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDefaultCommandWordSize()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetDefaultCommandWordSize()");
|
||||
return gcm_info.command_size;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.command_size;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDefaultSegmentWordSize()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetDefaultSegmentWordSize()");
|
||||
return gcm_info.segment_size;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.segment_size;
|
||||
}
|
||||
|
||||
s32 cellGcmInitDefaultFifoMode(s32 mode)
|
||||
@@ -280,8 +299,10 @@ s32 cellGcmBindZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
void cellGcmGetConfiguration(vm::ptr<CellGcmConfig> config)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetConfiguration(config=*0x%x)", config);
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
*config = current_config;
|
||||
if (m_config)
|
||||
*config = m_config->current_config;
|
||||
}
|
||||
|
||||
u32 cellGcmGetFlipStatus()
|
||||
@@ -297,9 +318,9 @@ u32 cellGcmGetTiledPitchSize(u32 size)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetTiledPitchSize(size=%d)", size);
|
||||
|
||||
for (size_t i=0; i < sizeof(tiled_pitches) / sizeof(tiled_pitches[0]) - 1; i++) {
|
||||
if (tiled_pitches[i] < size && size <= tiled_pitches[i+1]) {
|
||||
return tiled_pitches[i+1];
|
||||
for (size_t i = 0; i < sizeof(tiled_pitches) / sizeof(tiled_pitches[0]) - 1; i++) {
|
||||
if (tiled_pitches[i] < size && size <= tiled_pitches[i + 1]) {
|
||||
return tiled_pitches[i + 1];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -324,8 +345,12 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
{
|
||||
cellGcmSys.warning("_cellGcmInitBody(context=**0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context, cmdSize, ioSize, ioAddress);
|
||||
|
||||
current_config.ioAddress = 0;
|
||||
current_config.localAddress = 0;
|
||||
auto m_config = fxm::make<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
m_config->current_config.ioAddress = 0;
|
||||
m_config->current_config.localAddress = 0;
|
||||
local_size = 0;
|
||||
local_addr = 0;
|
||||
|
||||
@@ -356,33 +381,42 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
map_offset_addr = 0;
|
||||
map_offset_pos = 0;
|
||||
current_config.ioSize = ioSize;
|
||||
current_config.ioAddress = ioAddress;
|
||||
current_config.localSize = local_size;
|
||||
current_config.localAddress = local_addr;
|
||||
current_config.memoryFrequency = 650000000;
|
||||
current_config.coreFrequency = 500000000;
|
||||
m_config->current_config.ioSize = ioSize;
|
||||
m_config->current_config.ioAddress = ioAddress;
|
||||
m_config->current_config.localSize = local_size;
|
||||
m_config->current_config.localAddress = local_addr;
|
||||
m_config->current_config.memoryFrequency = 650000000;
|
||||
m_config->current_config.coreFrequency = 500000000;
|
||||
|
||||
// Create contexts
|
||||
|
||||
u32 addr = vm::falloc(0x40000000, 0x400000);
|
||||
if (addr == 0 || addr != 0x40000000)
|
||||
fmt::throw_exception("Failed to alloc 0x40000000.");
|
||||
|
||||
g_defaultCommandBufferBegin = ioAddress;
|
||||
g_defaultCommandBufferFragmentCount = cmdSize / (32 * 1024);
|
||||
|
||||
gcm_info.context_addr = vm::alloc(0x1000, vm::main);
|
||||
gcm_info.control_addr = vm::alloc(0x1000, vm::main);
|
||||
gcm_info.label_addr = vm::alloc(0x1000, vm::main); // ???
|
||||
m_config->gcm_info.context_addr = 0x40000000;
|
||||
m_config->gcm_info.control_addr = 0x40100000;
|
||||
m_config->gcm_info.label_addr = 0x40300000;
|
||||
|
||||
current_context.begin.set(g_defaultCommandBufferBegin + 4096); // 4 kb reserved at the beginning
|
||||
current_context.end.set(g_defaultCommandBufferBegin + 32 * 1024 - 4); // 4b at the end for jump
|
||||
current_context.current = current_context.begin;
|
||||
current_context.callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(cellGcmCallback));
|
||||
m_config->current_context.begin.set(g_defaultCommandBufferBegin + 4096); // 4 kb reserved at the beginning
|
||||
m_config->current_context.end.set(g_defaultCommandBufferBegin + 32 * 1024 - 4); // 4b at the end for jump
|
||||
m_config->current_context.current = m_config->current_context.begin;
|
||||
m_config->current_context.callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(cellGcmCallback));
|
||||
|
||||
vm::_ref<CellGcmContextData>(gcm_info.context_addr) = current_context;
|
||||
context->set(gcm_info.context_addr);
|
||||
m_config->ctxt_addr = context.addr();
|
||||
m_config->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
|
||||
m_config->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
m_config->tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
|
||||
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(gcm_info.control_addr);
|
||||
vm::_ref<CellGcmContextData>(m_config->gcm_info.context_addr) = m_config->current_context;
|
||||
context->set(m_config->gcm_info.context_addr);
|
||||
|
||||
// 0x40 is to offset CellGcmControl from RsxDmaControl
|
||||
m_config->gcm_info.control_addr += 0x40;
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr);
|
||||
ctrl.put = 0;
|
||||
ctrl.get = 0;
|
||||
ctrl.ref = -1;
|
||||
@@ -390,15 +424,10 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
const auto render = fxm::get<GSRender>();
|
||||
render->intr_thread = idm::make_ptr<ppu_thread>("_gcm_intr_thread", 1, 0x4000);
|
||||
render->intr_thread->run();
|
||||
render->ctxt_addr = context.addr();
|
||||
render->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
|
||||
render->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
render->tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
|
||||
render->gcm_buffers_count = 0;
|
||||
render->gcm_current_buffer = 0;
|
||||
render->main_mem_addr = 0;
|
||||
render->label_addr = gcm_info.label_addr;
|
||||
render->init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr);
|
||||
render->isHLE = true;
|
||||
render->label_addr = m_config->gcm_info.label_addr;
|
||||
render->init(ioAddress, ioSize, m_config->gcm_info.control_addr - 0x40, local_addr);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -431,6 +460,10 @@ s32 cellGcmSetDisplayBuffer(u8 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetDisplayBuffer(id=0x%x, offset=0x%x, pitch=%d, width=%d, height=%d)", id, offset, width ? pitch / width : pitch, width, height);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (id > 7)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetDisplayBuffer: CELL_GCM_ERROR_FAILURE");
|
||||
@@ -439,16 +472,21 @@ s32 cellGcmSetDisplayBuffer(u8 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||
|
||||
const auto render = fxm::get<GSRender>();
|
||||
|
||||
auto buffers = render->gcm_buffers;
|
||||
auto buffers = render->display_buffers;
|
||||
|
||||
buffers[id].offset = offset;
|
||||
buffers[id].pitch = pitch;
|
||||
buffers[id].width = width;
|
||||
buffers[id].height = height;
|
||||
|
||||
if (id + 1 > render->gcm_buffers_count)
|
||||
m_config->gcm_buffers[id].offset = offset;
|
||||
m_config->gcm_buffers[id].pitch = pitch;
|
||||
m_config->gcm_buffers[id].width = width;
|
||||
m_config->gcm_buffers[id].height = height;
|
||||
|
||||
if (id + 1u > render->display_buffers_count)
|
||||
{
|
||||
render->gcm_buffers_count = id + 1;
|
||||
render->display_buffers_count = id + 1;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@@ -465,17 +503,7 @@ void cellGcmSetFlipMode(u32 mode)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetFlipMode(mode=%d)", mode);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case CELL_GCM_DISPLAY_HSYNC:
|
||||
case CELL_GCM_DISPLAY_VSYNC:
|
||||
case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE:
|
||||
fxm::get<GSRender>()->flip_mode = mode;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fxm::get<GSRender>()->requested_vsync.store(mode == CELL_GCM_DISPLAY_VSYNC);
|
||||
}
|
||||
|
||||
void cellGcmSetFlipStatus()
|
||||
@@ -488,6 +516,9 @@ void cellGcmSetFlipStatus()
|
||||
s32 cellGcmSetPrepareFlip(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctxt, u32 id)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetPrepareFlip(ctxt=*0x%x, id=0x%x)", ctxt, id);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (id > 7)
|
||||
{
|
||||
@@ -506,9 +537,9 @@ s32 cellGcmSetPrepareFlip(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctxt, u32
|
||||
|
||||
const u32 cmd_size = rsx::make_command(ctxt->current, GCM_FLIP_COMMAND, { id });
|
||||
|
||||
if (ctxt.addr() == gcm_info.context_addr)
|
||||
if (ctxt.addr() == m_config->gcm_info.context_addr)
|
||||
{
|
||||
vm::_ref<CellGcmControl>(gcm_info.control_addr).put += cmd_size;
|
||||
vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put += cmd_size;
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -535,15 +566,12 @@ void cellGcmSetSecondVFrequency(u32 freq)
|
||||
switch (freq)
|
||||
{
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ:
|
||||
render->frequency_mode = freq;
|
||||
render->fps_limit = 59.94;
|
||||
break;
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT:
|
||||
render->frequency_mode = freq;
|
||||
cellGcmSys.todo("Unimplemented display frequency: Scanout");
|
||||
break;
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_DISABLE:
|
||||
render->frequency_mode = freq;
|
||||
cellGcmSys.todo("Unimplemented display frequency: Disabled");
|
||||
break;
|
||||
default:
|
||||
@@ -557,13 +585,17 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
cellGcmSys.warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||
index, location, offset, size, pitch, comp, base, bank);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (index >= rsx::limits::tiles_count || base >= 2048 || bank >= 4)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_VALUE");
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
@@ -571,7 +603,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
|
||||
if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12)))
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_ENUM");
|
||||
return CELL_GCM_ERROR_INVALID_ENUM;
|
||||
}
|
||||
|
||||
@@ -591,7 +623,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
tile.base = base;
|
||||
tile.bank = bank;
|
||||
|
||||
vm::_ptr<CellGcmTileInfo>(render->tiles_addr)[index] = tile.pack();
|
||||
vm::_ptr<CellGcmTileInfo>(m_config->tiles_addr)[index] = tile.pack();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -624,7 +656,7 @@ void cellGcmSetWaitFlip(vm::ptr<CellGcmContextData> ctxt)
|
||||
s32 cellGcmSetWaitFlipUnsafe()
|
||||
{
|
||||
cellGcmSys.todo("cellGcmSetWaitFlipUnsafe()");
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -633,6 +665,10 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
cellGcmSys.todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)",
|
||||
index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return;
|
||||
|
||||
if (index >= rsx::limits::zculls_count)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetZcull: CELL_GCM_ERROR_INVALID_VALUE");
|
||||
@@ -643,7 +679,7 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
|
||||
auto& zcull = render->zculls[index];
|
||||
zcull.offset = offset;
|
||||
zcull.width = width;
|
||||
zcull.width = width;
|
||||
zcull.height = height;
|
||||
zcull.cullStart = cullStart;
|
||||
zcull.zFormat = zFormat;
|
||||
@@ -654,7 +690,7 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
zcull.sRef = sRef;
|
||||
zcull.sMask = sMask;
|
||||
|
||||
vm::_ptr<CellGcmZcullInfo>(render->zculls_addr)[index] = zcull.pack();
|
||||
vm::_ptr<CellGcmZcullInfo>(m_config->zculls_addr)[index] = zcull.pack();
|
||||
}
|
||||
|
||||
s32 cellGcmUnbindTile(u8 index)
|
||||
@@ -690,26 +726,35 @@ s32 cellGcmUnbindZcull(u8 index)
|
||||
u32 cellGcmGetTileInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetTileInfo()");
|
||||
return fxm::get<GSRender>()->tiles_addr;
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->tiles_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetZcullInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetZcullInfo()");
|
||||
return fxm::get<GSRender>()->zculls_addr;
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->zculls_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDisplayInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetDisplayInfo()");
|
||||
return fxm::get<GSRender>()->gcm_buffers.addr();
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_buffers.addr();
|
||||
}
|
||||
|
||||
s32 cellGcmGetCurrentDisplayBufferId(vm::ptr<u8> id)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetCurrentDisplayBufferId(id=*0x%x)", id);
|
||||
|
||||
if ((*id = fxm::get<GSRender>()->gcm_current_buffer) > UINT8_MAX)
|
||||
if ((*id = fxm::get<GSRender>()->current_display_buffer) > UINT8_MAX)
|
||||
{
|
||||
fmt::throw_exception("Unexpected" HERE);
|
||||
}
|
||||
@@ -876,7 +921,7 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr<u32> address)
|
||||
|
||||
u32 realAddr;
|
||||
|
||||
if (!RSXIOMem.getRealAddr(ioOffset, realAddr))
|
||||
if (!RSXIOMem.getRealAddr(ioOffset, realAddr))
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
*address = realAddr;
|
||||
@@ -898,7 +943,6 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict)
|
||||
{
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (io >> 20) + i;
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (ea >> 20) + i;
|
||||
render->strict_ordering[(io >> 20) + i] = is_strict;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -948,6 +992,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmMapMainMemory(ea=0x%x, size=0x%x, offset=*0x%x)", ea, size, offset);
|
||||
|
||||
if (size == 0) return CELL_OK;
|
||||
if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
u32 io = RSXIOMem.Map(ea, size);
|
||||
@@ -962,7 +1007,6 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
|
||||
{
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (u16)((io >> 20) + i);
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (u16)((ea >> 20) + i);
|
||||
render->strict_ordering[(io >> 20) + i] = false;
|
||||
}
|
||||
|
||||
*offset = io;
|
||||
@@ -1113,23 +1157,27 @@ s32 cellGcmSetCursorImageOffset(u32 offset)
|
||||
void cellGcmSetDefaultCommandBuffer()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetDefaultCommandBuffer()");
|
||||
vm::write32(fxm::get<GSRender>()->ctxt_addr, gcm_info.context_addr);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (m_config)
|
||||
vm::write32(m_config->ctxt_addr, m_config->gcm_info.context_addr);
|
||||
}
|
||||
|
||||
s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segmentSize)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetDefaultCommandBufferAndSegmentWordSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
const auto& put = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put;
|
||||
const auto& get = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).get;
|
||||
|
||||
const auto& put = vm::_ref<CellGcmControl>(gcm_info.control_addr).put;
|
||||
const auto& get = vm::_ref<CellGcmControl>(gcm_info.control_addr).get;
|
||||
|
||||
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2)
|
||||
if (put != 0x1000 || get != 0x1000 || bufferSize < segmentSize * 2 || segmentSize >= 0x80000000)
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
gcm_info.command_size = bufferSize;
|
||||
gcm_info.segment_size = segmentSize;
|
||||
m_config->gcm_info.command_size = bufferSize;
|
||||
m_config->gcm_info.segment_size = segmentSize;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -1148,9 +1196,11 @@ s32 _cellGcmSetFlipCommand(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctx, u32
|
||||
s32 _cellGcmSetFlipCommandWithWaitLabel(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctx, u32 id, u32 label_index, u32 label_value)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetFlipCommandWithWaitLabel(ctx=*0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx, id, label_index, label_value);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
s32 res = cellGcmSetPrepareFlip(ppu, ctx, id);
|
||||
vm::write32(gcm_info.label_addr + 0x10 * label_index, label_value);
|
||||
vm::write32(m_config->gcm_info.label_addr + 0x10 * label_index, label_value);
|
||||
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1159,6 +1209,10 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
cellGcmSys.warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||
index, location, offset, size, pitch, comp, base, bank);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
// Copied form cellGcmSetTileInfo
|
||||
if (index >= rsx::limits::tiles_count || base >= 2048 || bank >= 4)
|
||||
{
|
||||
@@ -1166,7 +1220,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xf)
|
||||
if (offset & 0xffff || size & 0xffff || pitch & 0xff)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTile: CELL_GCM_ERROR_INVALID_ALIGNMENT");
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
@@ -1194,7 +1248,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
tile.base = base;
|
||||
tile.bank = bank;
|
||||
|
||||
vm::_ptr<CellGcmTileInfo>(render->tiles_addr)[index] = tile.pack();
|
||||
vm::_ptr<CellGcmTileInfo>(m_config->tiles_addr)[index] = tile.pack();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1286,8 +1340,11 @@ static bool isInCommandBufferExcept(u32 getPos, u32 bufferBegin, u32 bufferEnd)
|
||||
s32 cellGcmCallback(ppu_thread& ppu, vm::ptr<CellGcmContextData> context, u32 count)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmCallback(context=*0x%x, count=0x%x)", context, count);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(gcm_info.control_addr);
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr);
|
||||
|
||||
// Flush command buffer (ie allow RSX to read up to context->current)
|
||||
ctrl.put.exchange(getOffsetFromAddress(context->current.addr()));
|
||||
@@ -1427,5 +1484,5 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
|
||||
REG_FUNC(cellGcmSys, cellGcmGpadCaptureSnapshot);
|
||||
|
||||
// Special
|
||||
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
|
||||
REG_FUNC(cellGcmSys, cellGcmCallback).flag(MFF_HIDDEN);
|
||||
});
|
||||
|
||||
@@ -65,6 +65,12 @@ s32 cellHttpSetProxy()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpGetCookie()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpGetProxy()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
@@ -701,6 +707,7 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []()
|
||||
REG_FUNC(cellHttp, cellHttpsInit);
|
||||
REG_FUNC(cellHttp, cellHttpsEnd);
|
||||
REG_FUNC(cellHttp, cellHttpSetProxy);
|
||||
REG_FUNC(cellHttp, cellHttpGetCookie);
|
||||
REG_FUNC(cellHttp, cellHttpGetProxy);
|
||||
|
||||
REG_FUNC(cellHttp, cellHttpInitCookie);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Utilities/LUrlParser.h"
|
||||
|
||||
#include "cellHttpUtil.h"
|
||||
|
||||
@@ -14,50 +15,15 @@ logs::channel cellHttpUtil("cellHttpUtil");
|
||||
|
||||
s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
URL_COMPONENTS stUrlComp;
|
||||
|
||||
ZeroMemory(&stUrlComp, sizeof(URL_COMPONENTS));
|
||||
stUrlComp.dwStructSize = sizeof(URL_COMPONENTS);
|
||||
|
||||
wchar_t lpszScheme[MAX_PATH] = { 0 };
|
||||
wchar_t lpszHostName[MAX_PATH] = { 0 };
|
||||
wchar_t lpszPath[MAX_PATH] = { 0 };
|
||||
wchar_t lpszUserName[MAX_PATH] = { 0 };
|
||||
wchar_t lpszPassword[MAX_PATH] = { 0 };
|
||||
|
||||
stUrlComp.lpszScheme = lpszScheme;
|
||||
stUrlComp.dwSchemeLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszHostName = lpszHostName;
|
||||
stUrlComp.dwHostNameLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszUrlPath = lpszPath;
|
||||
stUrlComp.dwUrlPathLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszUserName = lpszUserName;
|
||||
stUrlComp.dwUserNameLength = MAX_PATH;
|
||||
|
||||
stUrlComp.lpszPassword = lpszPassword;
|
||||
stUrlComp.dwPasswordLength = MAX_PATH;
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
|
||||
LPCWSTR stupidTypeUrlString = converter.from_bytes(str.get_ptr()).c_str();
|
||||
if (!::WinHttpCrackUrl(stupidTypeUrlString, (DWORD)(LONG_PTR)wcslen(stupidTypeUrlString), ICU_ESCAPE, &stUrlComp))
|
||||
cellHttpUtil.trace("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
|
||||
LUrlParser::clParseURL URL = LUrlParser::clParseURL::ParseURL(str.get_ptr());
|
||||
if ( URL.IsValid() )
|
||||
{
|
||||
cellHttpUtil.error("Error %u in WinHttpCrackUrl.\n", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
std::string scheme = converter.to_bytes(lpszScheme);
|
||||
std::string host = converter.to_bytes(lpszHostName);
|
||||
std::string path = converter.to_bytes(lpszPath);
|
||||
std::string username = converter.to_bytes(lpszUserName);
|
||||
std::string password = converter.to_bytes(lpszPassword);
|
||||
std::string scheme = URL.m_Scheme;
|
||||
std::string host = URL.m_Host;
|
||||
std::string path = URL.m_Path;
|
||||
std::string username = URL.m_UserName;
|
||||
std::string password = URL.m_Password;
|
||||
|
||||
u32 schemeOffset = 0;
|
||||
u32 hostOffset = scheme.length() + 1;
|
||||
@@ -67,10 +33,13 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
|
||||
u32 totalSize = passwordOffset + password.length() + 1;
|
||||
|
||||
//called twice, first to setup pool, then to populate.
|
||||
if (!uri) {
|
||||
if (!uri)
|
||||
{
|
||||
*required = totalSize;
|
||||
return CELL_OK;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::strncpy((char*)vm::base(pool.addr() + schemeOffset), (char*)scheme.c_str(), scheme.length() + 1);
|
||||
std::strncpy((char*)vm::base(pool.addr() + hostOffset), (char*)host.c_str(), host.length() + 1);
|
||||
std::strncpy((char*)vm::base(pool.addr() + pathOffset), (char*)path.c_str(), path.length() + 1);
|
||||
@@ -82,14 +51,55 @@ s32 cellHttpUtilParseUri(vm::ptr<CellHttpUri> uri, vm::cptr<char> str, vm::ptr<v
|
||||
uri->path.set(pool.addr() + pathOffset);
|
||||
uri->username.set(pool.addr() + usernameOffset);
|
||||
uri->password.set(pool.addr() + passwordOffset);
|
||||
uri->port = stUrlComp.nPort;
|
||||
|
||||
if (URL.m_Port != "")
|
||||
{
|
||||
int port = stoi(URL.m_Port);
|
||||
uri->port = port;
|
||||
}
|
||||
else
|
||||
{
|
||||
uri->port = (u32)80;
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
cellHttpUtil.todo("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required);
|
||||
#endif
|
||||
return CELL_OK;
|
||||
else
|
||||
{
|
||||
std::string parseError;
|
||||
switch(URL.m_ErrorCode)
|
||||
{
|
||||
case LUrlParser::LUrlParserError_Ok:
|
||||
parseError = "No error, URL was parsed fine";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_Uninitialized:
|
||||
parseError = "Error, LUrlParser is uninitialized";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoUrlCharacter:
|
||||
parseError = "Error, the URL has invalid characters";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_InvalidSchemeName:
|
||||
parseError = "Error, the URL has an invalid scheme";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoDoubleSlash:
|
||||
parseError = "Error, the URL did not contain a double slash";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoAtSign:
|
||||
parseError = "Error, the URL did not contain an @ sign";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_UnexpectedEndOfLine:
|
||||
parseError = "Error, unexpectedly got the end of the line";
|
||||
break;
|
||||
case LUrlParser::LUrlParserError_NoSlash:
|
||||
parseError = "Error, URI didn't contain a slash";
|
||||
break;
|
||||
default:
|
||||
parseError = "Error, unkown error #" + std::to_string(static_cast<int>(URL.m_ErrorCode));
|
||||
break;
|
||||
}
|
||||
cellHttpUtil.error("%s, while parsing URI, %s.", parseError, str.get_ptr());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellHttpUtilParseUriPath(vm::ptr<CellHttpUriPath> path, vm::cptr<char> str, vm::ptr<void> pool, u32 size, vm::ptr<u32> required)
|
||||
|
||||
@@ -177,6 +177,9 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
|
||||
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
KbConfig& current_config = handler->GetConfig(port_no);
|
||||
current_config.code_type = type;
|
||||
@@ -197,6 +200,9 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
|
||||
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
KbConfig& current_config = handler->GetConfig(port_no);
|
||||
current_config.read_mode = rmode;
|
||||
@@ -213,6 +219,9 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
|
||||
if (!handler)
|
||||
return CELL_KB_ERROR_UNINITIALIZED;
|
||||
|
||||
if (port_no >= handler->GetKeyboards().size())
|
||||
return CELL_KB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
const KbConfig& current_config = handler->GetConfig(port_no);
|
||||
config->arrange = current_config.arrange;
|
||||
config->read_mode = current_config.read_mode;
|
||||
|
||||
@@ -161,7 +161,7 @@ bool _L10nCodeParse(s32 code, HostCode& retCode)
|
||||
#ifdef _MSC_VER
|
||||
|
||||
// Use code page to transform std::string to std::wstring.
|
||||
s32 _OEM2Wide(HostCode oem_code, const std::string src, std::wstring& dst)
|
||||
s32 _OEM2Wide(HostCode oem_code, const std::string& src, std::wstring& dst)
|
||||
{
|
||||
//Such length returned should include the '\0' character.
|
||||
s32 length = MultiByteToWideChar(oem_code, 0, src.c_str(), -1, NULL, 0);
|
||||
@@ -178,7 +178,7 @@ s32 _OEM2Wide(HostCode oem_code, const std::string src, std::wstring& dst)
|
||||
}
|
||||
|
||||
// Use Code page to transform std::wstring to std::string.
|
||||
s32 _Wide2OEM(HostCode oem_code, const std::wstring src, std::string& dst)
|
||||
s32 _Wide2OEM(HostCode oem_code, const std::wstring& src, std::string& dst)
|
||||
{
|
||||
//Such length returned should include the '\0' character.
|
||||
s32 length = WideCharToMultiByte(oem_code, 0, src.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
@@ -195,7 +195,7 @@ s32 _Wide2OEM(HostCode oem_code, const std::wstring src, std::string& dst)
|
||||
}
|
||||
|
||||
// Convert Codepage to Codepage (all char*)
|
||||
std::string _OemToOem(HostCode src_code, HostCode dst_code, const std::string str)
|
||||
std::string _OemToOem(HostCode src_code, HostCode dst_code, const std::string& str)
|
||||
{
|
||||
std::wstring wide; std::string result;
|
||||
_OEM2Wide(src_code, str, wide);
|
||||
|
||||
@@ -74,7 +74,7 @@ s32 cellMouseGetInfo(vm::ptr<CellMouseInfo> info)
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->vendor_id[i] = current_info.vendor_id[i];
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->product_id[i] = current_info.product_id[i];
|
||||
for (u32 i=0; i<CELL_MAX_MICE; i++) info->status[i] = current_info.status[i];
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ s32 cellMouseInfoTabletMode(u32 port_no, vm::ptr<CellMouseInfoTablet> info)
|
||||
|
||||
info->is_supported = 0; // Unimplemented: (0=Tablet mode is not supported)
|
||||
info->mode = 1; // Unimplemented: (1=Mouse mode)
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
|
||||
{
|
||||
return CELL_MOUSE_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
|
||||
MouseData& current_data = handler->GetData(port_no);
|
||||
data->update = current_data.update;
|
||||
data->buttons = current_data.buttons;
|
||||
@@ -134,22 +134,27 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
|
||||
|
||||
s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
return CELL_OK;
|
||||
sys_io.todo("cellMouseGetDataList(port_no=%d, data=0x%x", port_no, data);
|
||||
if (g_cfg.io.mouse == mouse_handler::null)
|
||||
return CELL_MOUSE_ERROR_NO_DEVICE;
|
||||
else
|
||||
{
|
||||
data->list_num = 0;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
s32 cellMouseSetTabletMode(u32 port_no, u32 mode)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellMouseGetTabletDataList(u32 port_no, u32 data_addr)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sys_io);
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
|
||||
virtual ~MsgDialogBase();
|
||||
virtual void Create(const std::string& msg) = 0;
|
||||
virtual void CreateOsk(const std::string& msg, char16_t* osk_text) = 0;
|
||||
virtual void CreateOsk(const std::string& msg, char16_t* osk_text, u32 charlimit) = 0;
|
||||
virtual void ProgressBarSetMsg(u32 progressBarIndex, const std::string& msg) = 0;
|
||||
virtual void ProgressBarReset(u32 progressBarIndex) = 0;
|
||||
virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0;
|
||||
|
||||
@@ -156,6 +156,10 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr<CellNetCtlInfo> info)
|
||||
{
|
||||
strcpy_trunc(info->netmask, "255.255.255.255");
|
||||
}
|
||||
else if (code == CELL_NET_CTL_INFO_HTTP_PROXY_CONFIG)
|
||||
{
|
||||
info->http_proxy_config = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -202,6 +206,54 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlAddHandlerGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlAddHandlerGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlConnectGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlConnectGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlDelHandlerGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlDelHandlerGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlDisconnectGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlDisconnectGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetInfoGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetInfoGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetScanInfoGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetScanInfoGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetStateGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetStateGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlScanGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlScanGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellGameUpdateInit()
|
||||
{
|
||||
cellNetCtl.todo("cellGameUpdateInit()");
|
||||
@@ -274,6 +326,15 @@ DECLARE(ppu_module_manager::cellNetCtl)("cellNetCtl", []()
|
||||
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetNatInfo);
|
||||
|
||||
REG_FUNC(cellNetCtl, cellNetCtlAddHandlerGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlConnectGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlDelHandlerGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlDisconnectGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetInfoGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetScanInfoGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetStateGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlScanGameInt);
|
||||
|
||||
REG_FUNC(cellNetCtl, cellGameUpdateInit);
|
||||
REG_FUNC(cellNetCtl, cellGameUpdateTerm);
|
||||
|
||||
|
||||
@@ -14,14 +14,21 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
||||
{
|
||||
cellOskDialog.warning("cellOskDialogLoadAsync(container=0x%x, dialogParam=*0x%x, inputFieldInfo=*0x%x)", container, dialogParam, inputFieldInfo);
|
||||
|
||||
u32 maxLength = (inputFieldInfo->limit_length >= 512) ? 511 : (u32)inputFieldInfo->limit_length;
|
||||
|
||||
std::memset(s_osk_text, 0, sizeof(s_osk_text));
|
||||
|
||||
if (inputFieldInfo->init_text.addr() != 0)
|
||||
for (u32 i = 0; (i < maxLength) && (inputFieldInfo->init_text[i] != 0); i++)
|
||||
s_osk_text[i] = inputFieldInfo->init_text[i];
|
||||
|
||||
const auto osk = Emu.GetCallbacks().get_msg_dialog();
|
||||
bool result = false;
|
||||
|
||||
osk->on_close = [&](s32 status)
|
||||
{
|
||||
sysutil_send_system_cmd(status == CELL_MSGDIALOG_BUTTON_OK ? CELL_SYSUTIL_OSKDIALOG_FINISHED : CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
if (status != CELL_MSGDIALOG_BUTTON_OK) sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
result = true;
|
||||
};
|
||||
|
||||
@@ -32,7 +39,7 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
||||
|
||||
Emu.CallAfter([&]()
|
||||
{
|
||||
osk->CreateOsk("On Screen Keyboard", s_osk_text);
|
||||
osk->CreateOsk("On Screen Keyboard", s_osk_text, maxLength);
|
||||
});
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
@@ -141,6 +148,12 @@ s32 cellOskDialogExtRegisterKeyboardEventHookCallback(u16 hookEventMode, vm::ptr
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellOskDialogExtRegisterKeyboardEventHookCallbackEx(u16 hookEventMode, vm::ptr<cellOskDialogHardwareKeyboardEventHookCallback> pCallback)
|
||||
{
|
||||
cellOskDialog.todo("cellOskDialogExtRegisterKeyboardEventHookCallbackEx(hookEventMode=%u, pCallback=*0x%x)", hookEventMode, pCallback);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellOskDialogExtAddJapaneseOptionDictionary(vm::cpptr<char> filePath)
|
||||
{
|
||||
cellOskDialog.todo("cellOskDialogExtAddJapaneseOptionDictionary(filePath=**0x%0x)", filePath);
|
||||
@@ -247,6 +260,7 @@ DECLARE(ppu_module_manager::cellOskDialog)("cellOskExtUtility", []()
|
||||
{
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtInputDeviceUnlock);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtRegisterKeyboardEventHookCallback);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtRegisterKeyboardEventHookCallbackEx);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtAddJapaneseOptionDictionary);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtEnableClipboard);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtSendFinishMessage);
|
||||
|
||||
+180
-145
@@ -3,7 +3,7 @@
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Io/PadHandler.h"
|
||||
#include "pad_thread.h"
|
||||
#include "cellPad.h"
|
||||
|
||||
extern logs::channel sys_io;
|
||||
@@ -12,7 +12,7 @@ s32 cellPadInit(u32 max_connect)
|
||||
{
|
||||
sys_io.warning("cellPadInit(max_connect=%d)", max_connect);
|
||||
|
||||
const auto handler = fxm::import<PadHandlerBase>(Emu.GetCallbacks().get_pad_handler);
|
||||
const auto handler = fxm::import<pad_thread>(Emu.GetCallbacks().get_pad_handler);
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_ALREADY_INITIALIZED;
|
||||
@@ -26,7 +26,7 @@ s32 cellPadEnd()
|
||||
{
|
||||
sys_io.notice("cellPadEnd()");
|
||||
|
||||
if (!fxm::remove<PadHandlerBase>())
|
||||
if (!fxm::remove<pad_thread>())
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
return CELL_OK;
|
||||
@@ -36,7 +36,7 @@ s32 cellPadClearBuf(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadClearBuf(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -51,20 +51,20 @@ s32 cellPadClearBuf(u32 port_no)
|
||||
//Set 'm_buffer_cleared' to force a resend of everything
|
||||
//might as well also reset everything in our pad 'buffer' to nothing as well
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
Pad& pad = pads[port_no];
|
||||
auto& pads = handler->GetPads();
|
||||
auto pad = pads[port_no];
|
||||
|
||||
pad.m_buffer_cleared = true;
|
||||
pad.m_analog_left_x = pad.m_analog_left_y = pad.m_analog_right_x = pad.m_analog_right_y = 128;
|
||||
pad->m_buffer_cleared = true;
|
||||
pad->m_analog_left_x = pad->m_analog_left_y = pad->m_analog_right_x = pad->m_analog_right_y = 128;
|
||||
|
||||
pad.m_digital_1 = pad.m_digital_2 = 0;
|
||||
pad.m_press_right = pad.m_press_left = pad.m_press_up = pad.m_press_down = 0;
|
||||
pad.m_press_triangle = pad.m_press_circle = pad.m_press_cross = pad.m_press_square = 0;
|
||||
pad.m_press_L1 = pad.m_press_L2 = pad.m_press_R1 = pad.m_press_R2 = 0;
|
||||
pad->m_digital_1 = pad->m_digital_2 = 0;
|
||||
pad->m_press_right = pad->m_press_left = pad->m_press_up = pad->m_press_down = 0;
|
||||
pad->m_press_triangle = pad->m_press_circle = pad->m_press_cross = pad->m_press_square = 0;
|
||||
pad->m_press_L1 = pad->m_press_L2 = pad->m_press_R1 = pad->m_press_R2 = 0;
|
||||
|
||||
//~399 on sensor y is a level non moving controller
|
||||
pad.m_sensor_y = 399;
|
||||
pad.m_sensor_x = pad.m_sensor_z = pad.m_sensor_g = 512;
|
||||
pad->m_sensor_y = 399;
|
||||
pad->m_sensor_x = pad->m_sensor_z = pad->m_sensor_g = 512;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -73,12 +73,12 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
{
|
||||
sys_io.trace("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
const PadInfo& rinfo = handler->GetInfo();
|
||||
|
||||
@@ -89,39 +89,39 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
Pad& pad = pads[port_no];
|
||||
auto pad = pads[port_no];
|
||||
|
||||
u16 d1Initial, d2Initial;
|
||||
d1Initial = pad.m_digital_1;
|
||||
d2Initial = pad.m_digital_2;
|
||||
d1Initial = pad->m_digital_1;
|
||||
d2Initial = pad->m_digital_2;
|
||||
bool btnChanged = false;
|
||||
for(Button& button : pad.m_buttons)
|
||||
for(Button& button : pad->m_buttons)
|
||||
{
|
||||
//here we check btns, and set pad accordingly,
|
||||
//if something changed, set btnChanged
|
||||
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
|
||||
{
|
||||
if (button.m_pressed) pad.m_digital_1 |= button.m_outKeyCode;
|
||||
else pad.m_digital_1 &= ~button.m_outKeyCode;
|
||||
if (button.m_pressed) pad->m_digital_1 |= button.m_outKeyCode;
|
||||
else pad->m_digital_1 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_LEFT:
|
||||
if (pad.m_press_left != button.m_value) btnChanged = true;
|
||||
pad.m_press_left = button.m_value;
|
||||
if (pad->m_press_left != button.m_value) btnChanged = true;
|
||||
pad->m_press_left = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_DOWN:
|
||||
if (pad.m_press_down != button.m_value) btnChanged = true;
|
||||
pad.m_press_down = button.m_value;
|
||||
if (pad->m_press_down != button.m_value) btnChanged = true;
|
||||
pad->m_press_down = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_RIGHT:
|
||||
if (pad.m_press_right != button.m_value) btnChanged = true;
|
||||
pad.m_press_right = button.m_value;
|
||||
if (pad->m_press_right != button.m_value) btnChanged = true;
|
||||
pad->m_press_right = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_UP:
|
||||
if (pad.m_press_up != button.m_value) btnChanged = true;
|
||||
pad.m_press_up = button.m_value;
|
||||
if (pad->m_press_up != button.m_value) btnChanged = true;
|
||||
pad->m_press_up = button.m_value;
|
||||
break;
|
||||
//These arent pressure btns
|
||||
case CELL_PAD_CTRL_R3:
|
||||
@@ -133,42 +133,42 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
}
|
||||
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
|
||||
{
|
||||
if (button.m_pressed) pad.m_digital_2 |= button.m_outKeyCode;
|
||||
else pad.m_digital_2 &= ~button.m_outKeyCode;
|
||||
if (button.m_pressed) pad->m_digital_2 |= button.m_outKeyCode;
|
||||
else pad->m_digital_2 &= ~button.m_outKeyCode;
|
||||
|
||||
switch (button.m_outKeyCode)
|
||||
{
|
||||
case CELL_PAD_CTRL_SQUARE:
|
||||
if (pad.m_press_square != button.m_value) btnChanged = true;
|
||||
pad.m_press_square = button.m_value;
|
||||
if (pad->m_press_square != button.m_value) btnChanged = true;
|
||||
pad->m_press_square = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CROSS:
|
||||
if (pad.m_press_cross != button.m_value) btnChanged = true;
|
||||
pad.m_press_cross = button.m_value;
|
||||
if (pad->m_press_cross != button.m_value) btnChanged = true;
|
||||
pad->m_press_cross = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_CIRCLE:
|
||||
if (pad.m_press_circle != button.m_value) btnChanged = true;
|
||||
pad.m_press_circle = button.m_value;
|
||||
if (pad->m_press_circle != button.m_value) btnChanged = true;
|
||||
pad->m_press_circle = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_TRIANGLE:
|
||||
if (pad.m_press_triangle != button.m_value) btnChanged = true;
|
||||
pad.m_press_triangle = button.m_value;
|
||||
if (pad->m_press_triangle != button.m_value) btnChanged = true;
|
||||
pad->m_press_triangle = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R1:
|
||||
if (pad.m_press_R1 != button.m_value) btnChanged = true;
|
||||
pad.m_press_R1 = button.m_value;
|
||||
if (pad->m_press_R1 != button.m_value) btnChanged = true;
|
||||
pad->m_press_R1 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_L1:
|
||||
if (pad.m_press_L1 != button.m_value) btnChanged = true;
|
||||
pad.m_press_L1 = button.m_value;
|
||||
if (pad->m_press_L1 != button.m_value) btnChanged = true;
|
||||
pad->m_press_L1 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_R2:
|
||||
if (pad.m_press_R2 != button.m_value) btnChanged = true;
|
||||
pad.m_press_R2 = button.m_value;
|
||||
if (pad->m_press_R2 != button.m_value) btnChanged = true;
|
||||
pad->m_press_R2 = button.m_value;
|
||||
break;
|
||||
case CELL_PAD_CTRL_L2:
|
||||
if (pad.m_press_L2 != button.m_value) btnChanged = true;
|
||||
pad.m_press_L2 = button.m_value;
|
||||
if (pad->m_press_L2 != button.m_value) btnChanged = true;
|
||||
pad->m_press_L2 = button.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
@@ -182,96 +182,131 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogStick& stick : pad.m_sticks)
|
||||
for (const AnalogStick& stick : pad->m_sticks)
|
||||
{
|
||||
switch (stick.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||
if (pad.m_analog_left_x != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_left_x = stick.m_value;
|
||||
if (pad->m_analog_left_x != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_left_x = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||
if (pad.m_analog_left_y != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_left_y = stick.m_value;
|
||||
if (pad->m_analog_left_y != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_left_y = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||
if (pad.m_analog_right_x != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_right_x = stick.m_value;
|
||||
if (pad->m_analog_right_x != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_right_x = stick.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||
if (pad.m_analog_right_y != stick.m_value) btnChanged = true;
|
||||
pad.m_analog_right_y = stick.m_value;
|
||||
if (pad->m_analog_right_y != stick.m_value) btnChanged = true;
|
||||
pad->m_analog_right_y = stick.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const AnalogSensor& sensor : pad.m_sensors)
|
||||
for (const AnalogSensor& sensor : pad->m_sensors)
|
||||
{
|
||||
switch (sensor.m_offset)
|
||||
{
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_X:
|
||||
if (pad.m_sensor_x != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_x = sensor.m_value;
|
||||
if (pad->m_sensor_x != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_x = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_Y:
|
||||
if (pad.m_sensor_y != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_y = sensor.m_value;
|
||||
if (pad->m_sensor_y != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_y = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_Z:
|
||||
if (pad.m_sensor_z != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_z = sensor.m_value;
|
||||
if (pad->m_sensor_z != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_z = sensor.m_value;
|
||||
break;
|
||||
case CELL_PAD_BTN_OFFSET_SENSOR_G:
|
||||
if (pad.m_sensor_g != sensor.m_value) btnChanged = true;
|
||||
pad.m_sensor_g = sensor.m_value;
|
||||
if (pad->m_sensor_g != sensor.m_value) btnChanged = true;
|
||||
pad->m_sensor_g = sensor.m_value;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d1Initial != pad.m_digital_1 || d2Initial != pad.m_digital_2)
|
||||
if (d1Initial != pad->m_digital_1 || d2Initial != pad->m_digital_2)
|
||||
{
|
||||
btnChanged = true;
|
||||
}
|
||||
|
||||
//not sure if this should officially change with capabilities/portsettings :(
|
||||
data->len = 24;
|
||||
|
||||
// the real hardware only fills the buffer up to "len" elements (16 bit each)
|
||||
if (pad->m_port_setting & CELL_PAD_SETTING_SENSOR_ON)
|
||||
{
|
||||
// report back new data every ~10 ms even if the input doesn't change
|
||||
// this is observed behaviour when using a Dualshock 3 controller
|
||||
static std::chrono::time_point<steady_clock> last_update[CELL_PAD_MAX_PORT_NUM] = { };
|
||||
const std::chrono::time_point<steady_clock> now = steady_clock::now();
|
||||
|
||||
if (pad.m_buffer_cleared)
|
||||
{
|
||||
pad.m_buffer_cleared = false;
|
||||
if (btnChanged || pad->m_buffer_cleared || (std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update[port_no]).count() >= 10))
|
||||
{
|
||||
data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON;
|
||||
last_update[port_no] = now;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->len = CELL_PAD_LEN_NO_CHANGE;
|
||||
}
|
||||
}
|
||||
else if (!btnChanged)
|
||||
else if (btnChanged || pad->m_buffer_cleared)
|
||||
{
|
||||
data->len = 0;
|
||||
// only give back valid data if a controller state changed
|
||||
data->len = (pad->m_port_setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// report no state changes
|
||||
data->len = CELL_PAD_LEN_NO_CHANGE;
|
||||
}
|
||||
|
||||
pad->m_buffer_cleared = false;
|
||||
|
||||
// only update parts of the output struct depending on the controller setting
|
||||
if (data->len > CELL_PAD_LEN_NO_CHANGE)
|
||||
{
|
||||
memset(data->button, 0, sizeof(data->button));
|
||||
|
||||
data->button[0] = 0x0; // always 0
|
||||
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
|
||||
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15);
|
||||
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad->m_digital_1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad->m_digital_2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad->m_analog_right_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad->m_analog_right_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad->m_analog_left_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad->m_analog_left_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad->m_press_right;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad->m_press_left;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad->m_press_up;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad->m_press_down;
|
||||
}
|
||||
|
||||
if (data->len >= CELL_PAD_LEN_CHANGE_PRESS_ON)
|
||||
{
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad->m_press_triangle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad->m_press_circle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad->m_press_cross;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad->m_press_square;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad->m_press_L1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad->m_press_L2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad->m_press_R1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad->m_press_R2;
|
||||
}
|
||||
|
||||
if (data->len == CELL_PAD_LEN_CHANGE_SENSOR_ON)
|
||||
{
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad->m_sensor_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad->m_sensor_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad->m_sensor_z;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad->m_sensor_g;
|
||||
}
|
||||
data->button[0] = 0x0; // always 0
|
||||
// bits 15-8 reserved, 7-4 = 0x7, 3-0: data->len/2;
|
||||
data->button[1] = (0x7 << 4) | std::min(data->len / 2, 15) & 0xF;
|
||||
//lets still send new data anyway, not sure whats expected still
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad.m_digital_1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad.m_digital_2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad.m_analog_right_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y] = pad.m_analog_right_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X] = pad.m_analog_left_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y] = pad.m_analog_left_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT] = pad.m_press_right;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_LEFT] = pad.m_press_left;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_UP] = pad.m_press_up;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_DOWN] = pad.m_press_down;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE] = pad.m_press_triangle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE] = pad.m_press_circle;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_CROSS] = pad.m_press_cross;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE] = pad.m_press_square;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L1] = pad.m_press_L1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_L2] = pad.m_press_L2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R1] = pad.m_press_R1;
|
||||
data->button[CELL_PAD_BTN_OFFSET_PRESS_R2] = pad.m_press_R2;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_X] = pad.m_sensor_x;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Y] = pad.m_sensor_y;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_Z] = pad.m_sensor_z;
|
||||
data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad.m_sensor_g;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -280,7 +315,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadPeriphGetInfo(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -293,7 +328,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
// TODO: Support other types of controllers
|
||||
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; ++i)
|
||||
@@ -301,10 +336,10 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->port_status[i] = pads[i].m_port_status;
|
||||
info->port_setting[i] = pads[i].m_port_setting;
|
||||
info->device_capability[i] = pads[i].m_device_capability;
|
||||
info->device_type[i] = pads[i].m_device_type;
|
||||
info->port_status[i] = pads[i]->m_port_status;
|
||||
info->port_setting[i] = pads[i]->m_port_setting;
|
||||
info->device_capability[i] = pads[i]->m_device_capability;
|
||||
info->device_type[i] = pads[i]->m_device_type;
|
||||
info->pclass_type[i] = CELL_PAD_PCLASS_TYPE_STANDARD;
|
||||
info->pclass_profile[i] = 0x0;
|
||||
}
|
||||
@@ -315,7 +350,7 @@ s32 cellPadPeriphGetInfo(vm::ptr<CellPadPeriphInfo> info)
|
||||
s32 cellPadPeriphGetData(u32 port_no, vm::ptr<CellPadPeriphData> data)
|
||||
{
|
||||
sys_io.trace("cellPadPeriphGetData(port_no=%d, data=*0x%x)", port_no, data);
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -342,7 +377,7 @@ s32 cellPadGetDataExtra(u32 port_no, vm::ptr<u32> device_type, vm::ptr<CellPadDa
|
||||
{
|
||||
sys_io.trace("cellPadGetDataExtra(port_no=%d, device_type=*0x%x, device_type=*0x%x)", port_no, device_type, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -370,7 +405,7 @@ s32 cellPadSetActDirect(u32 port_no, vm::ptr<CellPadActParam> param)
|
||||
{
|
||||
sys_io.trace("cellPadSetActDirect(port_no=%d, param=*0x%x)", port_no, param);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -391,7 +426,7 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetInfo(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -403,15 +438,15 @@ s32 cellPadGetInfo(vm::ptr<CellPadInfo> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
for (u32 i=0; i<CELL_MAX_PADS; ++i)
|
||||
{
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->status[i] = pads[i].m_port_status;
|
||||
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->status[i] = pads[i]->m_port_status;
|
||||
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->product_id[i] = 0x0268;
|
||||
info->vendor_id[i] = 0x054C;
|
||||
}
|
||||
@@ -423,7 +458,7 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetInfo2(info=*0x%x)", info);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -435,18 +470,18 @@ s32 cellPadGetInfo2(vm::ptr<CellPadInfo2> info)
|
||||
info->now_connect = rinfo.now_connect;
|
||||
info->system_info = rinfo.system_info;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
for (u32 i=0; i<CELL_PAD_MAX_PORT_NUM; ++i)
|
||||
{
|
||||
if (i >= pads.size())
|
||||
break;
|
||||
|
||||
info->port_status[i] = pads[i].m_port_status;
|
||||
pads[i].m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->port_setting[i] = pads[i].m_port_setting;
|
||||
info->device_capability[i] = pads[i].m_device_capability;
|
||||
info->device_type[i] = pads[i].m_device_type;
|
||||
info->port_status[i] = pads[i]->m_port_status;
|
||||
pads[i]->m_port_status &= ~CELL_PAD_STATUS_ASSIGN_CHANGES;
|
||||
info->port_setting[i] = pads[i]->m_port_setting;
|
||||
info->device_capability[i] = pads[i]->m_device_capability;
|
||||
info->device_type[i] = pads[i]->m_device_type;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@@ -456,7 +491,7 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
|
||||
{
|
||||
sys_io.trace("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr());
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -468,10 +503,10 @@ s32 cellPadGetCapabilityInfo(u32 port_no, vm::ptr<CellCapabilityInfo> info)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
//Should return the same as device capability mask, psl1ght has it backwards in pad.h
|
||||
info->info[0] = pads[port_no].m_device_capability;
|
||||
//Should return the same as device capability mask, psl1ght has it backwards in pad->h
|
||||
info->info[0] = pads[port_no]->m_device_capability;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -480,7 +515,7 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
|
||||
{
|
||||
sys_io.trace("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -492,8 +527,8 @@ s32 cellPadSetPortSetting(u32 port_no, u32 port_setting)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
pads[port_no].m_port_setting = port_setting;
|
||||
auto& pads = handler->GetPads();
|
||||
pads[port_no]->m_port_setting = port_setting;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -502,7 +537,7 @@ s32 cellPadInfoPressMode(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadInfoPressMode(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -514,16 +549,16 @@ s32 cellPadInfoPressMode(u32 port_no)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
|
||||
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_PRESS_MODE) > 0;
|
||||
}
|
||||
|
||||
s32 cellPadInfoSensorMode(u32 port_no)
|
||||
{
|
||||
sys_io.trace("cellPadInfoSensorMode(port_no=%d)", port_no);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -535,16 +570,16 @@ s32 cellPadInfoSensorMode(u32 port_no)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
const std::vector<Pad>& pads = handler->GetPads();
|
||||
const auto& pads = handler->GetPads();
|
||||
|
||||
return (pads[port_no].m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
|
||||
return (pads[port_no]->m_device_capability & CELL_PAD_CAPABILITY_SENSOR_MODE) > 0;
|
||||
}
|
||||
|
||||
s32 cellPadSetPressMode(u32 port_no, u32 mode)
|
||||
{
|
||||
sys_io.trace("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -559,12 +594,12 @@ s32 cellPadSetPressMode(u32 port_no, u32 mode)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
if (mode)
|
||||
pads[port_no].m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
|
||||
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_PRESS_ON;
|
||||
else
|
||||
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
|
||||
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_PRESS_ON;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -573,7 +608,7 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
|
||||
{
|
||||
sys_io.trace("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -588,12 +623,12 @@ s32 cellPadSetSensorMode(u32 port_no, u32 mode)
|
||||
if (port_no >= rinfo.now_connect)
|
||||
return CELL_PAD_ERROR_NO_DEVICE;
|
||||
|
||||
std::vector<Pad>& pads = handler->GetPads();
|
||||
auto& pads = handler->GetPads();
|
||||
|
||||
if (mode)
|
||||
pads[port_no].m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
|
||||
pads[port_no]->m_port_setting |= CELL_PAD_SETTING_SENSOR_ON;
|
||||
else
|
||||
pads[port_no].m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
|
||||
pads[port_no]->m_port_setting &= ~CELL_PAD_SETTING_SENSOR_ON;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -602,7 +637,7 @@ s32 cellPadLddRegisterController()
|
||||
{
|
||||
sys_io.todo("cellPadLddRegisterController()");
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -614,7 +649,7 @@ s32 cellPadLddDataInsert(s32 handle, vm::ptr<CellPadData> data)
|
||||
{
|
||||
sys_io.todo("cellPadLddDataInsert(handle=%d, data=*0x%x)", handle, data);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -626,7 +661,7 @@ s32 cellPadLddGetPortNo(s32 handle)
|
||||
{
|
||||
sys_io.todo("cellPadLddGetPortNo(handle=%d)", handle);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
@@ -638,7 +673,7 @@ s32 cellPadLddUnregisterController(s32 handle)
|
||||
{
|
||||
sys_io.todo("cellPadLddUnregisterController(handle=%d)", handle);
|
||||
|
||||
const auto handler = fxm::get<PadHandlerBase>();
|
||||
const auto handler = fxm::get<pad_thread>();
|
||||
|
||||
if (!handler)
|
||||
return CELL_PAD_ERROR_UNINITIALIZED;
|
||||
|
||||
@@ -27,6 +27,15 @@ enum
|
||||
CELL_PAD_PCLASS_TYPE_NAVIGATION = 0x05,
|
||||
};
|
||||
|
||||
// Length returned in CellPadData struct
|
||||
enum
|
||||
{
|
||||
CELL_PAD_LEN_NO_CHANGE = 0,
|
||||
CELL_PAD_LEN_CHANGE_DEFAULT = 8,
|
||||
CELL_PAD_LEN_CHANGE_PRESS_ON = 20,
|
||||
CELL_PAD_LEN_CHANGE_SENSOR_ON = 24,
|
||||
};
|
||||
|
||||
struct CellPadData
|
||||
{
|
||||
be_t<s32> len;
|
||||
|
||||
@@ -1,41 +1,90 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel cellRec("cellRec");
|
||||
|
||||
s32 cellRecOpen()
|
||||
struct CellRecSpursParam
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
vm::bptr<struct CellSpurs> pSpurs;
|
||||
be_t<s32> spu_usage_rate;
|
||||
u8 priority[8];
|
||||
};
|
||||
|
||||
struct CellRecOption
|
||||
{
|
||||
be_t<s32> option;
|
||||
union
|
||||
{
|
||||
be_t<s32> ppu_thread_priority;
|
||||
be_t<s32> spu_thread_priority;
|
||||
be_t<s32> capture_priority;
|
||||
be_t<s32> use_system_spu;
|
||||
be_t<s32> fit_to_youtube;
|
||||
be_t<s32> xmb_bgm;
|
||||
be_t<s32> mpeg4_fast_encode;
|
||||
be_t<u32> ring_sec;
|
||||
be_t<s32> video_input;
|
||||
be_t<s32> audio_input;
|
||||
be_t<s32> audio_input_mix_vol;
|
||||
be_t<s32> reduce_memsize;
|
||||
be_t<s32> show_xmb;
|
||||
vm::bptr<char> metadata_filename;
|
||||
vm::bptr<CellRecSpursParam> pSpursParam;
|
||||
be_t<u64> dummy;
|
||||
} value;
|
||||
};
|
||||
|
||||
struct CellRecParam
|
||||
{
|
||||
be_t<s32> videoFmt;
|
||||
be_t<s32> audioFmt;
|
||||
be_t<s32> numOfOpt;
|
||||
vm::bptr<CellRecOption> pOpt;
|
||||
};
|
||||
|
||||
using CellRecCallback = void(s32 recStatus, s32 recError, vm::ptr<void> userdata);
|
||||
|
||||
s32 cellRecOpen(vm::cptr<char> pDirName, vm::cptr<char> pFileName, vm::cptr<CellRecParam> pParam, u32 container, vm::ptr<CellRecCallback> cb, vm::ptr<void> cbUserData)
|
||||
{
|
||||
cellRec.todo("cellRecOpen(pDirName=%s, pFileName=%s, pParam=*0x%x, container=0x%x, cb=*0x%x, cbUserData=*0x%x)", pDirName, pFileName, pParam, container, cb, cbUserData);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecClose()
|
||||
s32 cellRecClose(s32 isDiscard)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecClose(isDiscard=0x%x)", isDiscard);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecGetInfo()
|
||||
void cellRecGetInfo(s32 info, vm::ptr<u64> pValue)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecGetInfo(info=0x%x, pValue=*0x%x)", info, pValue);
|
||||
}
|
||||
|
||||
s32 cellRecStop()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecStop()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecStart()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecStart()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecQueryMemSize()
|
||||
u32 cellRecQueryMemSize(vm::cptr<CellRecParam> pParam)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecQueryMemSize(pParam=*0x%x)", pParam);
|
||||
return 1 * 1024 * 1024; // dummy memory size
|
||||
}
|
||||
|
||||
s32 cellRecSetInfo()
|
||||
s32 cellRecSetInfo(s32 setInfo, u64 value)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecSetInfo(setInfo=0x%x, value=0x%x)", setInfo, value);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -123,8 +123,8 @@ s32 cellRescGetFlipStatus()
|
||||
|
||||
s32 cellRescGetRegisterCount()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc.todo("cellRescGetRegisterCount()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 cellRescGetLastFlipTime()
|
||||
@@ -134,10 +134,9 @@ u64 cellRescGetLastFlipTime()
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 cellRescSetRegisterCount()
|
||||
void cellRescSetRegisterCount(s32 regCount)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc.todo("cellRescSetRegisterCount(regCount=0x%x)", regCount);
|
||||
}
|
||||
|
||||
void cellRescSetVBlankHandler(vm::ptr<void(u32)> handler)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "sys_net.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Return Codes
|
||||
@@ -79,7 +77,9 @@ enum
|
||||
CELL_RUDP_POLL_EV_ERROR = 0x0008,
|
||||
};
|
||||
|
||||
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net::sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
|
||||
struct sys_net_sockaddr;
|
||||
|
||||
using CellRudpEventHandler = s32(s32 event_id, s32 soc, vm::cptr<u8> data, u32 datalen, vm::cptr<sys_net_sockaddr> addr, u32 addrlen, vm::ptr<void> arg);
|
||||
|
||||
using CellRudpAllocatorFuncAlloc = vm::ptr<void>(u32 size);
|
||||
using CellRudpAllocatorFuncFree = void(vm::ptr<void> ptr);
|
||||
|
||||
@@ -248,12 +248,126 @@ s32 cellSailRecorderCancel()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderRegisterComposer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderUnregisterComposer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderDumpImage()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerInitialize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerFinalize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetStreamParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsAudioParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsUserParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsVideoParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerNotifyCallCompleted()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerNotifySessionError()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSailRec)("cellSailRec", []()
|
||||
{
|
||||
static ppu_static_module cellMp4("cellMp4");
|
||||
@@ -301,6 +415,26 @@ DECLARE(ppu_module_manager::cellSailRec)("cellSailRec", []()
|
||||
REG_FUNC(cellSailRec, cellSailRecorderStart);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderStop);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderCancel);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderRegisterComposer);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderUnregisterComposer);
|
||||
|
||||
REG_FUNC(cellSailRec, cellSailRecorderDumpImage);
|
||||
|
||||
REG_FUNC(cellSailRec, cellSailComposerInitialize);
|
||||
REG_FUNC(cellSailRec, cellSailComposerFinalize);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetStreamParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsAudioParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsUserParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsVideoParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerNotifyCallCompleted);
|
||||
REG_FUNC(cellSailRec, cellSailComposerNotifySessionError);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
@@ -103,13 +103,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
|
||||
|
||||
// get the saves matching the supplied prefix
|
||||
for (const auto& entry : fs::dir(base_dir))
|
||||
for (auto&& entry : fs::dir(base_dir))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.name = vfs::unescape(entry.name);
|
||||
|
||||
for (const auto& prefix : prefix_list)
|
||||
{
|
||||
if (entry.name.substr(0, prefix.size()) == prefix)
|
||||
@@ -453,8 +455,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
auto file_list = statGet->fileList.get_ptr();
|
||||
|
||||
for (const auto& entry : fs::dir(dir_path))
|
||||
for (auto&& entry : fs::dir(dir_path))
|
||||
{
|
||||
entry.name = vfs::unescape(entry.name);
|
||||
|
||||
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
|
||||
if (!entry.is_directory && entry.name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax)
|
||||
{
|
||||
@@ -725,7 +729,7 @@ s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<Ce
|
||||
userId = 1u;
|
||||
}
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/%s/", userId, dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
std::string sfo = save_path + "PARAM.SFO";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
@@ -743,20 +747,26 @@ s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<Ce
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
fs::stat_t dir_info{};
|
||||
if (!fs::stat(save_path, dir_info))
|
||||
if (dir)
|
||||
{
|
||||
return CELL_SAVEDATA_ERROR_INTERNAL;
|
||||
fs::stat_t dir_info{};
|
||||
if (!fs::stat(save_path, dir_info))
|
||||
{
|
||||
return CELL_SAVEDATA_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// get file stats, namely directory
|
||||
strcpy_trunc(dir->dirName, dirName.get_ptr());
|
||||
dir->atime = dir_info.atime;
|
||||
dir->ctime = dir_info.ctime;
|
||||
dir->mtime = dir_info.mtime;
|
||||
}
|
||||
|
||||
// get file stats, namely directory
|
||||
strcpy_trunc(dir->dirName, dirName.get_ptr());
|
||||
dir->atime = dir_info.atime;
|
||||
dir->ctime = dir_info.ctime;
|
||||
dir->mtime = dir_info.mtime;
|
||||
|
||||
//TODO: Set bind in accordance to any problems
|
||||
*bind = 0;
|
||||
if (bind)
|
||||
{
|
||||
//TODO: Set bind in accordance to any problems
|
||||
*bind = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -1077,7 +1087,7 @@ s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<Cell
|
||||
|
||||
void cellSysutil_SaveData_init()
|
||||
{
|
||||
REG_VNID(cellSysutil, 0x00000000u, g_savedata_context);
|
||||
REG_VAR(cellSysutil, g_savedata_context).flag(MFF_HIDDEN);
|
||||
|
||||
// libsysutil functions:
|
||||
REG_FUNC(cellSysutil, cellSaveDataEnableOverlay);
|
||||
|
||||
@@ -118,6 +118,12 @@ s32 cellSearchGetContentInfoDeveloperData()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSearchGetContentInfoSharable()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSearch);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSearchCancel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSearch);
|
||||
@@ -150,6 +156,7 @@ DECLARE(ppu_module_manager::cellSearch)("cellSearchUtility", []()
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoPathMovieThumb);
|
||||
REG_FUNC(cellSearchUtility, cellSearchPrepareFile);
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoDeveloperData);
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoSharable);
|
||||
REG_FUNC(cellSearchUtility, cellSearchCancel);
|
||||
REG_FUNC(cellSearchUtility, cellSearchEnd);
|
||||
});
|
||||
|
||||
@@ -66,5 +66,5 @@ error_code cellSpudllHandleConfigSetDefaultValues(vm::ptr<CellSpudllHandleConfig
|
||||
DECLARE(ppu_module_manager::cellSpudll)("cellSpudll", []()
|
||||
{
|
||||
REG_FUNC(cellSpudll, cellSpudllGetImageSize);
|
||||
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flags = MFF_PERFECT;
|
||||
REG_FUNC(cellSpudll, cellSpudllHandleConfigSetDefaultValues).flag(MFF_PERFECT);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
logs::channel cellSpurs("cellSpurs");
|
||||
|
||||
s32 sys_spu_image_close(vm::ptr<sys_spu_image> img);
|
||||
error_code sys_spu_image_close(vm::ptr<sys_spu_image> img);
|
||||
|
||||
// TODO
|
||||
struct cell_error_t
|
||||
@@ -880,7 +880,7 @@ s32 _spurs::stop_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
|
||||
if (sys_event_port_send(ppu, spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
if (sys_event_port_send(spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ s32 cellSpursEventFlagSet(ppu_thread& ppu, vm::ptr<CellSpursEventFlag> eventFlag
|
||||
// Signal the PPU thread to be woken up
|
||||
eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEvents;
|
||||
|
||||
CHECK_SUCCESS(sys_event_port_send(ppu, eventFlag->eventPortId, 0, 0, 0));
|
||||
CHECK_SUCCESS(sys_event_port_send(eventFlag->eventPortId, 0, 0, 0));
|
||||
}
|
||||
|
||||
if (pendingRecv)
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "Emu/VFS.h"
|
||||
|
||||
logs::channel cellSsl("cellSsl");
|
||||
|
||||
s32 cellSslInit()
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
enum SpecialCerts { BaltimoreCert = 6, Class3G2V2Cert = 13, ClassSSV4Cert = 15, EntrustNetCert = 18, GTECyberTrustGlobalCert = 23 };
|
||||
|
||||
s32 cellSslInit(vm::ptr<void> pool, u32 poolSize)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSsl);
|
||||
cellSsl.todo("cellSslInit(pool=0x%x, poolSize=%d)", pool, poolSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -15,9 +25,66 @@ s32 cellSslEnd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSslCertificateLoader()
|
||||
std::string getCert(const std::string certPath, const int certID, const bool isNormalCert)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSsl);
|
||||
int newID = certID;
|
||||
|
||||
// The 'normal' certs have some special rules for loading.
|
||||
if (isNormalCert && certID >= BaltimoreCert && certID <= GTECyberTrustGlobalCert)
|
||||
{
|
||||
if (certID == BaltimoreCert)
|
||||
newID = GTECyberTrustGlobalCert;
|
||||
else if (certID == Class3G2V2Cert)
|
||||
newID = BaltimoreCert;
|
||||
else if (certID == EntrustNetCert)
|
||||
newID = ClassSSV4Cert;
|
||||
else
|
||||
newID = certID - 1;
|
||||
}
|
||||
|
||||
std::string filePath = fmt::format("%sCA%02d.cer", certPath, newID);
|
||||
|
||||
if (!fs::exists(filePath))
|
||||
{
|
||||
cellSsl.error("Can't find certificate file %s, do you have the PS3 firmware installed?", filePath);
|
||||
return "";
|
||||
}
|
||||
return fs::file(filePath).to_string();
|
||||
}
|
||||
|
||||
s32 cellSslCertificateLoader(u64 flag, vm::ptr<char> buffer, u32 size, vm::ptr<u32> required)
|
||||
{
|
||||
cellSsl.trace("cellSslCertificateLoader(flag=%llu, buffer=0x%x, size=%zu, required=0x%x)", flag, buffer, size, required);
|
||||
|
||||
const std::bitset<58> flagBits(flag);
|
||||
const std::string certPath = vfs::get("/dev_flash/") + "data/cert/";
|
||||
|
||||
if (required)
|
||||
{
|
||||
*required = 0;
|
||||
for (int i = 1; i <= flagBits.size(); i++)
|
||||
{
|
||||
if (!flagBits[i-1])
|
||||
continue;
|
||||
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
|
||||
*required += (u32)(getCert(certPath, i, flagBits[BaltimoreCert-1]).size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string final;
|
||||
for (int i = 1; i <= flagBits.size(); i++)
|
||||
{
|
||||
if (!flagBits[i-1])
|
||||
continue;
|
||||
// If we're loading cert 6 (the baltimore cert), then we need set that we're loading the 'normal' set of certs.
|
||||
final.append(getCert(certPath, i, flagBits[BaltimoreCert-1]));
|
||||
}
|
||||
|
||||
memset(buffer.get_ptr(), '\0', size - 1);
|
||||
memcpy(buffer.get_ptr(), final.c_str(), final.size());
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
+38
-29
@@ -1,9 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "cellSubdisplay.h"
|
||||
#include "cellSubDisplay.h"
|
||||
|
||||
logs::channel cellSubdisplay("cellSubdisplay");
|
||||
logs::channel cellSubDisplay("cellSubDisplay");
|
||||
|
||||
template<>
|
||||
void fmt_class_string<CellSubDisplayError>::format(std::string& out, u64 arg)
|
||||
@@ -28,51 +28,51 @@ void fmt_class_string<CellSubDisplayError>::format(std::string& out, u64 arg)
|
||||
|
||||
error_code cellSubDisplayInit(vm::ptr<CellSubDisplayParam> pParam, vm::ptr<CellSubDisplayHandler> func, vm::ptr<void> userdata, u32 container)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayInit(pParam=*0x%x, func=*0x%x, userdata=*0x%x, container=0x%x)", pParam, func, userdata, container);
|
||||
cellSubDisplay.todo("cellSubDisplayInit(pParam=*0x%x, func=*0x%x, userdata=*0x%x, container=0x%x)", pParam, func, userdata, container);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayEnd()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayEnd()");
|
||||
cellSubDisplay.todo("cellSubDisplayEnd()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetRequiredMemory(vm::ptr<CellSubDisplayParam> pParam)
|
||||
{
|
||||
cellSubdisplay.warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam);
|
||||
cellSubDisplay.warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam);
|
||||
|
||||
if (pParam->version == CELL_SUBDISPLAY_VERSION_0002)
|
||||
switch (pParam->version)
|
||||
{
|
||||
return not_an_error(CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return not_an_error(CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0001: return not_an_error(CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0002: return not_an_error(CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0003: return not_an_error(CELL_SUBDISPLAY_0003_MEMORY_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayStart()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayStart()");
|
||||
cellSubDisplay.todo("cellSubDisplayStart()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayStop()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayStop()");
|
||||
cellSubDisplay.todo("cellSubDisplayStop()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetVideoBuffer(s32 groupId, vm::pptr<void> ppVideoBuf, vm::ptr<u32> pSize)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetVideoBuffer(groupId=%d, ppVideoBuf=**0x%x, pSize=*0x%x)", groupId, ppVideoBuf, pSize);
|
||||
cellSubDisplay.todo("cellSubDisplayGetVideoBuffer(groupId=%d, ppVideoBuf=**0x%x, pSize=*0x%x)", groupId, ppVideoBuf, pSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayAudioOutBlocking(s32 groupId, vm::ptr<void> pvData, s32 samples)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayAudioOutBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ error_code cellSubDisplayAudioOutBlocking(s32 groupId, vm::ptr<void> pvData, s32
|
||||
|
||||
error_code cellSubDisplayAudioOutNonBlocking(s32 groupId, vm::ptr<void> pvData, s32 samples)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayAudioOutNonBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutNonBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
@@ -96,34 +96,43 @@ error_code cellSubDisplayAudioOutNonBlocking(s32 groupId, vm::ptr<void> pvData,
|
||||
|
||||
error_code cellSubDisplayGetPeerNum(s32 groupId)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetPeerNum(groupId=%d)", groupId);
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerNum(groupId=%d)", groupId);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetPeerList(s32 groupId, vm::ptr<CellSubDisplayPeerInfo> pInfo, vm::ptr<s32> pNum)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetPeerList(groupId=%d, pInfo=*0x%x, pNum=*0x%x)", groupId, pInfo, pNum);
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerList(groupId=%d, pInfo=*0x%x, pNum=*0x%x)", groupId, pInfo, pNum);
|
||||
|
||||
*pNum = 0;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSubdisplay)("cellSubdisplay", []()
|
||||
error_code cellSubDisplayGetTouchInfo(s32 groupId, vm::ptr<CellSubDisplayTouchInfo> pTouchInfo, vm::ptr<s32> pNumTouchInfo)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetTouchInfo(groupId=%d, pTouchInfo=*0x%x, pNumTouchInfo=*0x%x)", groupId, pTouchInfo, pNumTouchInfo);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSubDisplay)("cellSubDisplay", []()
|
||||
{
|
||||
// Initialization / Termination Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayInit);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayEnd);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetRequiredMemory);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayStart);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayStop);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayInit);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayEnd);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetRequiredMemory);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayStart);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayStop);
|
||||
|
||||
// Data Setting Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetVideoBuffer);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayAudioOutBlocking);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayAudioOutNonBlocking);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetVideoBuffer);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayAudioOutBlocking);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayAudioOutNonBlocking);
|
||||
|
||||
// Peer Status Acquisition Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetPeerNum);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetPeerList);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetPeerNum);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetPeerList);
|
||||
|
||||
//
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetTouchInfo);
|
||||
});
|
||||
@@ -23,9 +23,11 @@ enum
|
||||
CELL_SUBDISPLAY_STATUS_FATALERROR = 3,
|
||||
CELL_SUBDISPLAY_VERSION_0001 = 1,
|
||||
CELL_SUBDISPLAY_VERSION_0002 = 2,
|
||||
CELL_SUBDISPLAY_VERSION_0003 = 3,
|
||||
CELL_SUBDISPLAY_MODE_REMOTEPLAY = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_A8R8G8B8 = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_R8G8B8A8 = 2,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_YUV420 = 3,
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_16_9 = 0,
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_4_3 = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_MODE_SETDATA = 0,
|
||||
@@ -34,6 +36,7 @@ enum
|
||||
CELL_SUBDISPLAY_AUDIO_MODE_CAPTURE = 1,
|
||||
CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE = 8 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0003_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_NICKNAME_LEN = 256,
|
||||
CELL_SUBDISPLAY_PSPID_LEN = 16,
|
||||
};
|
||||
@@ -82,4 +85,12 @@ struct CellSubDisplayPeerInfo
|
||||
CellSubDisplayNickname pspNickname;
|
||||
};
|
||||
|
||||
struct CellSubDisplayTouchInfo
|
||||
{
|
||||
u8 status;
|
||||
u8 force;
|
||||
be_t<u16> x;
|
||||
be_t<u16> y;
|
||||
};
|
||||
|
||||
using CellSubDisplayHandler = void(s32 cbMsg, u64 cbParam, vm::ptr<void> userdata);
|
||||
@@ -251,6 +251,7 @@ static const char* get_module_id(u16 id)
|
||||
case 0xf034: return "CELL_SYSMODULE_SAIL_REC";
|
||||
case 0xf035: return "CELL_SYSMODULE_SYSUTIL_NP_TROPHY";
|
||||
case 0xf044: return "CELL_SYSMODULE_SYSUTIL_NP_EULA";
|
||||
case 0xf053: return "CELL_SYSMODULE_ADEC_AT3MULTI";
|
||||
case 0xf054: return "CELL_SYSMODULE_LIBATRAC3MULTI";
|
||||
case 0xffff: return "CELL_SYSMODULE_INVALID";
|
||||
}
|
||||
|
||||
@@ -100,11 +100,8 @@ void fmt_class_string<CellSysutilLang>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
// For test
|
||||
enum systemparam_id_name : s32 {};
|
||||
|
||||
template <>
|
||||
void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
|
||||
void fmt_class_string<CellSysutilParamId>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto value)
|
||||
{
|
||||
@@ -133,13 +130,13 @@ void fmt_class_string<systemparam_id_name>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
|
||||
s32 cellSysutilGetSystemParamInt(CellSysutilParamId id, vm::ptr<s32> value)
|
||||
{
|
||||
cellSysutil.warning("cellSysutilGetSystemParamInt(id=0x%x(%s), value=*0x%x)", id, id, value);
|
||||
|
||||
// TODO: load this information from config (preferably "sys/" group)
|
||||
|
||||
switch(id)
|
||||
switch (id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG:
|
||||
*value = g_cfg.sys.language;
|
||||
@@ -208,13 +205,13 @@ s32 cellSysutilGetSystemParamInt(systemparam_id_name id, vm::ptr<s32> value)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilGetSystemParamString(systemparam_id_name id, vm::ptr<char> buf, u32 bufsize)
|
||||
s32 cellSysutilGetSystemParamString(CellSysutilParamId id, vm::ptr<char> buf, u32 bufsize)
|
||||
{
|
||||
cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, id, buf, bufsize);
|
||||
|
||||
memset(buf.get_ptr(), 0, bufsize);
|
||||
|
||||
switch(id)
|
||||
switch (id)
|
||||
{
|
||||
case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME:
|
||||
memcpy(buf.get_ptr(), "Unknown", 8); // for example
|
||||
@@ -471,6 +468,12 @@ s32 _ZN4cxml8DocumentD1Ev()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN4cxml8Document5ClearEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -507,6 +510,12 @@ s32 _ZNK4cxml7Element12GetAttributeEPKcPNS_9AttributeE()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZNK4cxml7Element13GetFirstChildEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZNK4cxml7Element14GetNextSiblingEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -537,6 +546,12 @@ s32 _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN8cxmlutil9GetStringERKN4cxml7ElementEPKcPS5_Pj()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -567,6 +582,36 @@ s32 _ZN8cxmlutil7GetFileERKN4cxml7ElementEPKcPNS0_4FileE()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory3EndEi()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory5BeginEi()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory8AllocateEN4cxml14AllocationTypeEPvS3_jPS3_Pj()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil12PacketWriter5WriteEPKvjPv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil12PacketWriterC1EiiRN4cxml8DocumentE()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutil_E1EC7B6A(vm::ptr<u32> unk)
|
||||
{
|
||||
cellSysutil.todo("cellSysutil_E1EC7B6A(unk=*0x%x)", unk);
|
||||
@@ -636,6 +681,7 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8DocumentC1Ev);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8DocumentD1Ev);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document5ClearEv);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document14SetHeaderMagicEPKc);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document16CreateFromBufferEPKvjb);
|
||||
@@ -643,17 +689,25 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
|
||||
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml4File7GetAddrEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element12GetAttributeEPKcPNS_9AttributeE);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element13GetFirstChildEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element14GetNextSiblingEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml9Attribute6GetIntEPi);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml9Attribute7GetFileEPNS_4FileE);
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil6SetIntERKN4cxml7ElementEPKci);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil9GetStringERKN4cxml7ElementEPKcPS5_Pj);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil9SetStringERKN4cxml7ElementEPKcS5_);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil16CheckElementNameERKN4cxml7ElementEPKc);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil16FindChildElementERKN4cxml7ElementEPKcS5_S5_);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil7GetFileERKN4cxml7ElementEPKcPNS0_4FileE);
|
||||
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory3EndEi);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory5BeginEi);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory8AllocateEN4cxml14AllocationTypeEPvS3_jPS3_Pj);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil12PacketWriter5WriteEPKvjPv);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil12PacketWriterC1EiiRN4cxml8DocumentE);
|
||||
|
||||
REG_FNID(cellSysutil, 0xE1EC7B6A, cellSysutil_E1EC7B6A);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ enum
|
||||
};
|
||||
|
||||
// Parameter IDs
|
||||
enum
|
||||
enum CellSysutilParamId: s32
|
||||
{
|
||||
// Integers
|
||||
CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111,
|
||||
|
||||
@@ -7,166 +7,226 @@
|
||||
|
||||
logs::channel cellSysutilAvc2("cellSysutilAvc2");
|
||||
|
||||
s32 cellSysutilAvc2GetPlayerInfo()
|
||||
template<>
|
||||
void fmt_class_string<CellSysutilAvc2Error>::format(std::string& out, u64 arg)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
format_enum(out, arg, [](auto error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
STR_CASE(CELL_AVC2_ERROR_UNKNOWN);
|
||||
STR_CASE(CELL_AVC2_ERROR_NOT_SUPPORTED);
|
||||
STR_CASE(CELL_AVC2_ERROR_NOT_INITIALIZED);
|
||||
STR_CASE(CELL_AVC2_ERROR_ALREADY_INITIALIZED);
|
||||
STR_CASE(CELL_AVC2_ERROR_INVALID_ARGUMENT);
|
||||
STR_CASE(CELL_AVC2_ERROR_OUT_OF_MEMORY);
|
||||
STR_CASE(CELL_AVC2_ERROR_ERROR_BAD_ID);
|
||||
STR_CASE(CELL_AVC2_ERROR_INVALID_STATUS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TIMEOUT);
|
||||
STR_CASE(CELL_AVC2_ERROR_NO_SESSION);
|
||||
STR_CASE(CELL_AVC2_ERROR_WINDOW_ALREADY_EXISTS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TOO_MANY_WINDOWS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TOO_MANY_PEER_WINDOWS);
|
||||
STR_CASE(CELL_AVC2_ERROR_WINDOW_NOT_FOUND);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2JoinChat()
|
||||
error_code cellSysutilAvc2GetPlayerInfo(vm::cptr<SceNpMatching2RoomMemberId> player_id, vm::ptr<CellSysutilAvc2PlayerInfo> player_info)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopStreaming()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ChangeVideoResolution()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ShowScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetVideoMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowAttribute()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopStreaming2()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetVoiceMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartVoiceDetection()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2UnloadAsync()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopVoiceDetection()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetAttribute()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LoadAsync()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetSpeakerVolumeLevel()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowString()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2EstimateMemoryContainerSize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetVideoMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetPlayerVoiceMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetStreamingTarget()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Unload()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2DestroyWindow()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowPosition()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetSpeakerVolumeLevel()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2IsCameraAttached(vm::ptr<u8> status)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsCameraAttached()");
|
||||
|
||||
*status = CELL_AVC2_CAMERA_STATUS_DETACHED;
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetPlayerInfo(player_id=*0x%x, player_info=*0x%x)", player_id, player_info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2MicRead()
|
||||
error_code cellSysutilAvc2JoinChat(vm::cptr<SceNpMatching2RoomId> room_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2JoinChat(room_id=*0x%x)", room_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetPlayerVoiceMuting()
|
||||
error_code cellSysutilAvc2StopStreaming()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopStreaming()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2JoinChatRequest()
|
||||
error_code cellSysutilAvc2ChangeVideoResolution(CellSysutilAvc2VideoResolution resolution)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ChangeVideoResolution(resolution=0x%x)", resolution);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartStreaming()
|
||||
error_code cellSysutilAvc2ShowScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ShowScreen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowAttribute()
|
||||
error_code cellSysutilAvc2GetVideoMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetVideoMuting(muting=*0x%x)", muting);
|
||||
|
||||
*muting = 1;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowShowStatus()
|
||||
error_code cellSysutilAvc2GetWindowAttribute(SceNpMatching2RoomMemberId member_id, vm::ptr<CellSysutilAvc2WindowAttribute> attr)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowAttribute(member_id=0x%x, attr=*0x%x)", member_id, attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> option)
|
||||
error_code cellSysutilAvc2StopStreaming2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopStreaming2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetVoiceMuting(u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetVoiceMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StartVoiceDetection()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartVoiceDetection()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2UnloadAsync()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StopVoiceDetection()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopVoiceDetection()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetAttribute(vm::ptr<CellSysutilAvc2Attribute> attr)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetAttribute(attr=*0x%x)", attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2LoadAsync(SceNpMatching2ContextId ctx_id, u32 container, vm::ptr<CellSysutilAvc2Callback> callback_func, vm::ptr<void> user_data, vm::cptr<CellSysutilAvc2InitParam> init_param)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LoadAsync(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetSpeakerVolumeLevel(f32 level)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerVolumeLevel(level=0x%x)", level);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowString(SceNpMatching2RoomMemberId member_id, vm::cptr<char> string)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowString(member_id=0x%x, string=%s)", member_id, string);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2EstimateMemoryContainerSize(vm::cptr<CellSysutilAvc2InitParam> initparam, vm::ptr<u32> size)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2EstimateMemoryContainerSize(initparam=*0x%x, size=*0x%x)", initparam, size);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetVideoMuting(u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetVideoMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetPlayerVoiceMuting(SceNpMatching2RoomMemberId member_id, u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetPlayerVoiceMuting(member_id=0x%x, muting=0x%x)", member_id, muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetStreamingTarget()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2Unload()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Unload()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2DestroyWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2DestroyWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowPosition(SceNpMatching2RoomMemberId member_id, f32 x, f32 y, f32 z)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowPosition(member_id=0x%x, x=0x%x, y=0x%x, z=0x%x)", member_id, x, y, z);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetSpeakerVolumeLevel(vm::ptr<f32> level)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetSpeakerVolumeLevel(level=*0x%x)", level);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2IsCameraAttached(vm::ptr<u8> status)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsCameraAttached(status=*0x%x)", status);
|
||||
|
||||
*status = CELL_AVC2_CAMERA_STATUS_DETACHED;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2MicRead(vm::ptr<void> ptr, vm::ptr<u32> pSize)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2MicRead(ptr=*0x%x, pSize=*0x%x)", ptr, pSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetPlayerVoiceMuting(SceNpMatching2RoomMemberId member_id, vm::ptr<u8> muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetPlayerVoiceMuting(member_id=0x%x, muting=*0x%x)", member_id, muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2JoinChatRequest(vm::cptr<SceNpMatching2RoomId> room_id)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2JoinChatRequest(room_id=*0x%x)", room_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StartStreaming()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartStreaming()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowAttribute(SceNpMatching2RoomMemberId member_id, vm::cptr<CellSysutilAvc2WindowAttribute> attr)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowAttribute(member_id=0x%x, attr=*0x%x)", member_id, attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetWindowShowStatus(SceNpMatching2RoomMemberId member_id, vm::ptr<u8> visible)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowShowStatus(member_id=0x%x, visible=*0x%x)", member_id, visible);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> option)
|
||||
{
|
||||
cellSysutilAvc2.warning("cellSysutilAvc2InitParam(version=%d, option=*0x%x)", version, option);
|
||||
|
||||
@@ -213,115 +273,142 @@ s32 cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> opti
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowSize()
|
||||
error_code cellSysutilAvc2GetWindowSize(SceNpMatching2RoomMemberId member_id, vm::ptr<f32> width, vm::ptr<f32> height)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowSize(member_id=0x%x, width=*0x%x, height=*0x%x)", member_id, width, height);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetStreamPriority()
|
||||
error_code cellSysutilAvc2SetStreamPriority(u8 priority)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetStreamPriority(priority=0x%x)", priority);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LeaveChatRequest()
|
||||
error_code cellSysutilAvc2LeaveChatRequest()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LeaveChatRequest()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2IsMicAttached()
|
||||
error_code cellSysutilAvc2IsMicAttached(vm::ptr<u8> status)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsMicAttached(status=*0x%x)", status);
|
||||
|
||||
*status = CELL_AVC2_MIC_STATUS_DETACHED;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2CreateWindow()
|
||||
error_code cellSysutilAvc2CreateWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2CreateWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetSpeakerMuting()
|
||||
error_code cellSysutilAvc2GetSpeakerMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetSpeakerMuting(muting=*0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ShowWindow()
|
||||
error_code cellSysutilAvc2ShowWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ShowWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowSize()
|
||||
error_code cellSysutilAvc2SetWindowSize(SceNpMatching2RoomMemberId member_id, f32 width, f32 height)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowSize(member_id=0x%x, width=0x%x, height=0x%x)", member_id, width, height);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2EnumPlayers()
|
||||
error_code cellSysutilAvc2EnumPlayers(vm::ptr<s32> players_num, vm::ptr<SceNpMatching2RoomMemberId> players_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2EnumPlayers(players_num=*0x%x, players_id=*0x%x)", players_num, players_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowString()
|
||||
error_code cellSysutilAvc2GetWindowString(SceNpMatching2RoomMemberId member_id, vm::ptr<char> string, vm::ptr<u8> len)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowString(member_id=0x%x, string=*0x%x, len=*0x%x)", member_id, string, len);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LeaveChat()
|
||||
error_code cellSysutilAvc2LeaveChat()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LeaveChat()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetSpeakerMuting()
|
||||
error_code cellSysutilAvc2SetSpeakerMuting(u8 muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Load()
|
||||
error_code cellSysutilAvc2Load(SceNpMatching2ContextId ctx_id, u32 container, vm::ptr<CellSysutilAvc2Callback> callback_func, vm::ptr<void> user_data, vm::cptr<CellSysutilAvc2InitParam> init_param)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Load(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetAttribute()
|
||||
error_code cellSysutilAvc2SetAttribute(vm::cptr<CellSysutilAvc2Attribute> attr)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetAttribute(attr=*0x%x)", attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2UnloadAsync2()
|
||||
error_code cellSysutilAvc2UnloadAsync2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartStreaming2()
|
||||
error_code cellSysutilAvc2StartStreaming2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartStreaming2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2HideScreen()
|
||||
error_code cellSysutilAvc2HideScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2HideScreen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2HideWindow()
|
||||
error_code cellSysutilAvc2HideWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2HideWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetVoiceMuting()
|
||||
error_code cellSysutilAvc2GetVoiceMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetVoiceMuting(muting=*0x%x)", muting);
|
||||
|
||||
*muting = 1;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetScreenShowStatus()
|
||||
error_code cellSysutilAvc2GetScreenShowStatus(vm::ptr<u8> visible)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetScreenShowStatus(visible=*0x%x)", visible);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Unload2()
|
||||
error_code cellSysutilAvc2Unload2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Unload2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowPosition()
|
||||
error_code cellSysutilAvc2GetWindowPosition(SceNpMatching2RoomMemberId member_id, vm::ptr<f32> x, vm::ptr<f32> y, vm::ptr<f32> z)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowPosition(member_id=0x%x, x=*0x%x, y=*0x%x, z=*0x%x)", member_id, x, y, z);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Error codes
|
||||
enum
|
||||
enum CellSysutilAvc2Error : u32
|
||||
{
|
||||
CELL_AVC2_ERROR_UNKNOWN = 0x8002b701,
|
||||
CELL_AVC2_ERROR_NOT_SUPPORTED = 0x8002b702,
|
||||
@@ -113,6 +113,14 @@ enum
|
||||
CELL_AVC2_CAMERA_STATUS_UNKNOWN = 3,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_AVC2_MIC_STATUS_DETACHED = 0,
|
||||
CELL_AVC2_MIC_STATUS_ATTACHED_OFF = 1,
|
||||
CELL_AVC2_MIC_STATUS_ATTACHED_ON = 2,
|
||||
CELL_AVC2_MIC_STATUS_UNKNOWN = 3,
|
||||
};
|
||||
|
||||
typedef u32 CellSysutilAvc2AttributeId;
|
||||
typedef u32 CellSysutilAvc2WindowAttributeId;
|
||||
|
||||
@@ -143,7 +151,7 @@ struct CellSysutilAvc2VideoInitParam
|
||||
be_t<u16> max_video_windows;
|
||||
be_t<u16> max_video_framerate;
|
||||
be_t<u32> max_video_bitrate;
|
||||
CellSysutilAvc2CoordinatesForm coordinates_form;
|
||||
be_t<CellSysutilAvc2CoordinatesForm> coordinates_form;
|
||||
u8 video_stream_sharing;
|
||||
};
|
||||
|
||||
@@ -166,15 +174,15 @@ struct CellSysutilAvc2InitParam
|
||||
|
||||
struct CellSysutilAvc2RoomMemberList
|
||||
{
|
||||
vm::ptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::bptr<SceNpMatching2RoomMemberId> member_id;
|
||||
u8 member_num;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2MemberIpAndPortList
|
||||
{
|
||||
vm::ptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::ptr<u32> dst_addr; // in_addr
|
||||
vm::ptr<u16> dst_port;
|
||||
vm::bptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::bptr<u32> dst_addr; // in_addr
|
||||
vm::bptr<u16> dst_port; // in_port_t
|
||||
be_t<SceNpMatching2RoomMemberId> my_member_id;
|
||||
u8 member_num;
|
||||
};
|
||||
@@ -183,7 +191,7 @@ union CellSysutilAvc2AttributeParam
|
||||
{
|
||||
be_t<u64> int_param;
|
||||
be_t<f32> float_param;
|
||||
vm::ptr<void> ptr_param;
|
||||
vm::bptr<void> ptr_param;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2Attribute
|
||||
@@ -196,7 +204,7 @@ union CellSysutilAvc2WindowAttributeParam
|
||||
{
|
||||
be_t<s32> int_vector[4];
|
||||
be_t<f32> float_vector[4];
|
||||
vm::ptr<void> ptr_vector[4];
|
||||
vm::bptr<void> ptr_vector[4];
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2WindowAttribute
|
||||
@@ -204,3 +212,12 @@ struct CellSysutilAvc2WindowAttribute
|
||||
be_t<CellSysutilAvc2WindowAttributeId> attr_id;
|
||||
CellSysutilAvc2WindowAttributeParam attr_param;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2PlayerInfo
|
||||
{
|
||||
be_t<SceNpMatching2RoomMemberId> member_id;
|
||||
u8 joined;
|
||||
u8 connected;
|
||||
u8 mic_attached;
|
||||
u8 reserved[11];
|
||||
};
|
||||
|
||||
@@ -43,6 +43,12 @@ s32 cellUsbdRegisterLdd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdRegisterCompositeLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdRegisterExtraLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
@@ -61,6 +67,12 @@ s32 cellUsbdUnregisterLdd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdUnregisterCompositeLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdUnregisterExtraLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
@@ -151,6 +163,13 @@ s32 cellUsbdFreeMemory()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdResetDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
{
|
||||
REG_FUNC(cellUsbd, cellUsbdInit);
|
||||
@@ -161,9 +180,11 @@ DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
REG_FUNC(cellUsbd, cellUsbdGetThreadPriority);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterCompositeLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterExtraLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterExtraLdd2);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterCompositeLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterExtraLdd);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdOpenPipe);
|
||||
@@ -184,4 +205,6 @@ DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdAllocateMemory);
|
||||
REG_FUNC(cellUsbd, cellUsbdFreeMemory);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdResetDevice);
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user