Compare commits
2573 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| afb2d86560 | |||
| d1bed1f9dc | |||
| 0865041adb | |||
| 0dcba3c680 | |||
| 2e3025a07c | |||
| 20e1d81386 | |||
| e1b3711d88 | |||
| 7b38157c6e | |||
| 2528e51d29 | |||
| abdf507c2e | |||
| cb712ef60d | |||
| b3fd84e6c2 | |||
| 6e99ccb07d | |||
| 6ebd36b1aa | |||
| d95a22c873 | |||
| 7f10734457 | |||
| 89786a000c | |||
| cb9a8c12ed | |||
| 3c7931665b | |||
| 7a7e4a0e93 | |||
| 9689a35819 | |||
| 7942f48e75 | |||
| 3ad2328bac | |||
| 7d1f7f23df | |||
| a5a803a83f | |||
| 6422d4ed88 | |||
| f3fcd9ddef | |||
| b47101666a | |||
| 683aaa74cd | |||
| 85317d52a1 | |||
| 6b1aef2c7f | |||
| 5bda82614c | |||
| 6c3527a268 | |||
| 8d9b3c8cd8 | |||
| ab1443ce54 | |||
| a5cfc60e4a | |||
| 61577db82b | |||
| 09cfec8ed0 | |||
| a1d703a7dd | |||
| c3632b1a89 | |||
| 50072ad337 | |||
| ebffde6170 | |||
| b5d98a03fe | |||
| 3cff737064 | |||
| f53a9860c6 | |||
| e8e7a194ca | |||
| cebb6cf0b0 | |||
| 75c5588a76 | |||
| 96f7db2387 | |||
| 6df7d74e2b | |||
| 4cadada18a | |||
| 8df70aab80 | |||
| 2b74737351 | |||
| 47fad215d6 | |||
| 64464f186d | |||
| 0b01a6a664 | |||
| 2f1c75268f | |||
| b0158b3a1e | |||
| b619806d6d | |||
| f6b2f374c4 | |||
| 34c40569bd | |||
| 86178e5788 | |||
| 0eb9b1149d | |||
| b7be159a3b | |||
| 43c0820686 | |||
| a0bd47e39f | |||
| 63b0b477eb | |||
| 7571d806ad | |||
| 6e39214f3b | |||
| f4741c88c5 | |||
| 768f0e0520 | |||
| 71b1d21656 | |||
| 4fcb545ae6 | |||
| a26f484cb4 | |||
| 5b4a2f57b9 | |||
| b51b68de45 | |||
| 61c1455557 | |||
| f3c34ae5bc | |||
| 030c798d5c | |||
| dbaa273b6b | |||
| 16cf07b91f | |||
| 5b5751dea4 | |||
| 56522adddb | |||
| 25753334fc | |||
| 4369ed5e7a | |||
| 4e97a3f1ef | |||
| 8ffe4bbbc5 | |||
| 078a642e1f | |||
| dd1d07cf03 | |||
| 04c7e9c93e | |||
| a0bbadba06 | |||
| 124b2b16ec | |||
| 7b60100d18 | |||
| ea23f27f43 | |||
| 080521625e | |||
| 362a2b51ca | |||
| 06056db521 | |||
| 5d9fae0bc8 | |||
| 6227d8f19e | |||
| 182aea5ef6 | |||
| 04abf6780c | |||
| 78c750445f | |||
| 9e0ee49a73 | |||
| 470617b957 | |||
| 93db93ccee | |||
| a3d00a585d | |||
| b4d7d81bf5 | |||
| 293b497909 | |||
| 28945301c5 | |||
| 67ab6689b1 | |||
| 30086f9ce2 | |||
| 2df77e9b82 | |||
| 4475e7c074 | |||
| 9878630ad3 | |||
| 3a6e18e72c | |||
| 3292b80269 | |||
| be4ad6ef3d | |||
| d0c34e1ca5 | |||
| cda10cc2c4 | |||
| 34e8e95df4 | |||
| dce714556e | |||
| ffb4c5d2e0 | |||
| 863c4559dd | |||
| 47357e074a | |||
| 84be5a77d8 | |||
| df2fba6206 | |||
| 0340c23cb8 | |||
| 501b97098a | |||
| 72e0ce885f | |||
| aae495062c | |||
| 99c3fc1054 | |||
| b1c9fe13a8 | |||
| effd281be1 | |||
| 578b26d4d3 | |||
| ae0baa3d3c | |||
| f42d952020 | |||
| 5f0bcf0835 | |||
| 71e368d8f0 | |||
| b2aa871a0d | |||
| 0b27b371d7 | |||
| 144f71303d | |||
| f6259800d0 | |||
| 84c0382226 | |||
| 3a82c6dedb | |||
| b85d22ecb8 | |||
| a3071a966e | |||
| 2065aea794 | |||
| 73826cdbbf | |||
| 7c0680bc9a | |||
| 138a224675 | |||
| da3dc260bf | |||
| b28a906a42 | |||
| f4dd914139 | |||
| 37b465570b | |||
| 8f3d576ffa | |||
| dc55df76cf | |||
| 816b783225 | |||
| e4e8de72e4 | |||
| a09bfc136f | |||
| 8064fd1d43 | |||
| 9681b80ffc | |||
| c7077989a8 | |||
| 5f9c792cd3 | |||
| 2b83eaac4a | |||
| fe8674ef6b | |||
| 50414472b9 | |||
| df5b5aea39 | |||
| 9cf815ebd6 | |||
| be091818a6 | |||
| 2012225307 | |||
| dca30b1830 | |||
| dcf3101b17 | |||
| 2598946891 | |||
| 3a2e1e5ea2 | |||
| e95ac4639f | |||
| cd7bd6e99c | |||
| ec8f2dba30 | |||
| 6c1fa1953e | |||
| ac927e63f0 | |||
| e9311cde2d | |||
| 11b6a8eab9 | |||
| 1bd2178753 | |||
| 61b241c1b6 | |||
| b54c232e75 | |||
| 3274e5818c | |||
| c17d27fff5 | |||
| 7b400b7cb8 | |||
| e722f2accb | |||
| d59490c309 | |||
| b5b66f903f | |||
| d31275a873 | |||
| 7aa965eb9c | |||
| bd7795d5be | |||
| 6baabd445b | |||
| 033fd635c6 | |||
| c064fa3472 | |||
| fb614956bc | |||
| 71b53f3455 | |||
| cb393ca5e2 | |||
| 8ef5ceac41 | |||
| 5764e73a84 | |||
| 23a395c231 | |||
| b748811487 | |||
| 9642c2f6eb | |||
| 1d5e21e577 | |||
| b400a21c62 | |||
| 9dc49741e6 | |||
| bde2cb3630 | |||
| 6477fa6d8f | |||
| bd553dc9ed | |||
| 3c933fbb1c | |||
| 9ed18d443f | |||
| d4dcca8fcc | |||
| 0b78fb627e | |||
| 9ebd422aa2 | |||
| 8c21f88ac0 | |||
| dc06b9f6bc | |||
| e9072f6b76 | |||
| 74669077d4 | |||
| 895213c01e | |||
| 18fa309d92 | |||
| 82035de603 | |||
| 2bba3bfe71 | |||
| 0bbc64d382 | |||
| 194d226903 | |||
| 3583857225 | |||
| 2a3e8a69d8 | |||
| 09cc92fbea | |||
| 0b19e19ce7 | |||
| 16dea9fd3e | |||
| 7409b8621b | |||
| 0f5dad4dd5 | |||
| 3561c2541a | |||
| 9a5d12edab | |||
| 9e35258da1 | |||
| bdf6af5ae4 | |||
| 4057179aa5 | |||
| 9e39e461cc | |||
| 927ea7538f | |||
| ddfd11cdf3 | |||
| 555f68c2e7 | |||
| 09adccaa1a | |||
| bbc5d2d202 | |||
| 2e9e366dbb | |||
| 80e29f4c49 | |||
| c5ef8bbb23 | |||
| 16384b5d83 | |||
| 45d4007131 | |||
| 7b957f5cf3 | |||
| 21d8cf97ba | |||
| 6707ba4599 | |||
| bed30d333a | |||
| b0f26b4717 | |||
| 52f14b35d9 | |||
| cc077a9088 | |||
| d0192ab2be | |||
| c6bf211ee4 | |||
| 7aa17844d4 | |||
| 69b5a51646 | |||
| a2c98d2fbb | |||
| fa8097cbf2 | |||
| 7c97574595 | |||
| 32e22372f9 | |||
| 040ff45116 | |||
| 9c6f2d7fa1 | |||
| c27889358e | |||
| 7f96884927 | |||
| 8d7b42a966 | |||
| 0f1f091931 | |||
| a234f60ff5 | |||
| 98a6aaa2ba | |||
| 3d7d7e51fb | |||
| 45c303c81a | |||
| a8c4cfded2 | |||
| f62f367e0a | |||
| 084162b4f3 | |||
| eccb7f6424 | |||
| 7d49d0035b | |||
| 2b1909f441 | |||
| 7725731c54 | |||
| 479df8b469 | |||
| 79aa45a7fa | |||
| 6ee22ab229 | |||
| ebac6de662 | |||
| 2780a4b2fe | |||
| e7cf168eef | |||
| 8b2ac12d42 | |||
| f8dac21700 | |||
| 29a552f870 | |||
| 6f45c82c55 | |||
| 627c0282c9 | |||
| 5e7722b766 | |||
| 5780a8fd78 | |||
| 26692b457b | |||
| 2ff56febb8 | |||
| 0b3d9a7c16 | |||
| f813b9923d | |||
| d3e839c8d0 | |||
| a030f215dd | |||
| 6a15e5373f | |||
| 490243eb11 | |||
| 00e28d3c0e | |||
| cf6f0f6f0b | |||
| 75ed73412d | |||
| 677df3c18e | |||
| 25761039f6 | |||
| 23e2c50300 | |||
| 31f1c7761f | |||
| 415544d012 | |||
| fd7f839342 | |||
| d363f957f5 | |||
| 7f7a694799 | |||
| e67cb385be | |||
| f858fa2234 | |||
| 0d7a486630 | |||
| 350acc3cc3 | |||
| 3407f91aa0 | |||
| 1a96655173 | |||
| d35a8bdea3 | |||
| 419da20ca4 | |||
| cad0d48456 | |||
| fb4160e8e8 | |||
| e1d056486f | |||
| 32a7b50318 | |||
| c7896aeecf | |||
| 74b9446a30 | |||
| c3cb7b78fe | |||
| b50a152dd5 | |||
| edec4149cf | |||
| 2f4863241b | |||
| 03835558fc | |||
| 2ed1b6cf7c | |||
| 1d28f31916 | |||
| 19898e3e0a | |||
| 3ecf8448f0 | |||
| ac80681b77 | |||
| 45ebb29de4 | |||
| 874356694c | |||
| 609a2a7d02 | |||
| 8c336d52fa | |||
| ef94cf1dc1 | |||
| 861bb78be5 | |||
| 48070764e0 | |||
| c8676783d1 | |||
| 5233fc85b8 | |||
| 543021a300 | |||
| 9d93d88a66 | |||
| 2ddc047ac8 | |||
| da0fe00c10 | |||
| afb99946b2 | |||
| 4ab9730ed6 | |||
| 8a56cbd577 | |||
| d1ff86d336 | |||
| 73d9d0ec06 | |||
| 04c95d2fdb | |||
| 577eb6224f | |||
| 8dd10103d6 | |||
| 3dbcd436e8 | |||
| b393976879 | |||
| c19e363025 | |||
| 4525087ce9 | |||
| 15ed4f6d56 | |||
| 7064a9fbcc | |||
| 53df20c005 | |||
| bbfa94151f | |||
| fd4b309e0b | |||
| 2823fe9a12 | |||
| 67b145b22e | |||
| 62dcd6ac5e | |||
| 946f66b128 | |||
| f798bbfcc7 | |||
| 713402b572 | |||
| 415cda6fc9 | |||
| 1156aa24d0 | |||
| 3faa7e10d0 | |||
| b97696624f | |||
| ece41bdd75 | |||
| eddce1d770 | |||
| 4387fef301 | |||
| 39e761b76c | |||
| f330ea8a90 | |||
| 34f0ca5e8f | |||
| e954d87b53 | |||
| 1c7a2194e1 | |||
| af0b55f642 | |||
| bfcc0ffddf | |||
| b280886bca | |||
| 8d3ea37309 | |||
| 3ee37466fd | |||
| 26c4927993 | |||
| 1bd8558eeb | |||
| a93ab235be | |||
| 347a6251e3 | |||
| f8afc40198 | |||
| 681bc82185 | |||
| b4d992f490 | |||
| 13b156402f | |||
| fdcee1ca9f | |||
| 02655d055c | |||
| d8a06158b1 | |||
| 62608cdc7d | |||
| 1b00fd2a9d | |||
| 0ea4b9ed9b | |||
| e85ad43821 | |||
| 1257b50bf4 | |||
| aa9fa1dc84 | |||
| 6ed7c30952 | |||
| 31b9f805ea | |||
| 8da83db1e5 | |||
| 9b6ac82ad8 | |||
| 66cd99bf6b | |||
| a2006940db | |||
| 942ae1847d | |||
| 691d3e6e33 | |||
| 55789db088 | |||
| a006abb94b | |||
| a4e92e8821 | |||
| 7b61185287 | |||
| 210cee96d8 | |||
| 4ff75ae87f | |||
| f13bf76699 | |||
| ddb9fac4e1 | |||
| c259dbc6e0 | |||
| 34891142ac | |||
| cc92c8a229 | |||
| e97cdd00a8 | |||
| 95c035ed73 | |||
| 6113494d08 | |||
| e2f126dd27 | |||
| a476ee53aa | |||
| bf5e5874b4 | |||
| 51b3a0c68f | |||
| e65f72476a | |||
| 9df21ceb6e | |||
| d3d5e6f215 | |||
| a13d17e413 | |||
| baf44c321a | |||
| fbcdcabab5 | |||
| 73c1ed4023 | |||
| 2c47883cc2 | |||
| 8a51682190 | |||
| f1c6333d5f | |||
| 92de1313e7 | |||
| ce7cb7f7e9 | |||
| 4f741dfad2 | |||
| f226cde6fe | |||
| 7eb3eb9ec5 | |||
| ffa012eeb6 | |||
| 94f9eb7a35 | |||
| 6a520f18cf | |||
| de8f9ebac9 | |||
| b14f1f29a9 | |||
| 49aac252d7 | |||
| ed91931184 | |||
| ea76998beb | |||
| f3bfde242b | |||
| f60733b561 | |||
| d47c3cedb4 | |||
| ea7ade197e | |||
| bba0e5e00c | |||
| b1cd632bd4 | |||
| 61b82254d0 | |||
| 3c66454953 | |||
| 85ad25e0e8 | |||
| 131078e3a0 | |||
| a77f00d665 | |||
| eaae858a38 | |||
| cdfdcf6d13 | |||
| 298f41fc76 | |||
| cdab8a4d9e | |||
| d6d3bc0159 | |||
| 9ee8f3613f | |||
| 3b8dd447fa | |||
| b6a97318ec | |||
| 989abd017e | |||
| 71fd6dfa47 | |||
| 8d00e1dc8c | |||
| 34e1075582 | |||
| df5722717a | |||
| 71c5132c57 | |||
| b15ac0f2e1 | |||
| 2296cd5faf | |||
| b50826bc74 | |||
| 409036b6ed | |||
| 5ee3825a50 | |||
| c99dc375e8 | |||
| ca63b92e5b | |||
| 70aa7c6ad8 | |||
| 81c33b6432 | |||
| b76a0a8789 | |||
| ed255ce1c3 | |||
| 3b8d177861 | |||
| 00efc0d571 | |||
| 7bc59784b5 | |||
| 3556d7c0e8 | |||
| b5078c5326 | |||
| 89656d8195 | |||
| 69d3e9be0a | |||
| 94bd8a237d | |||
| e10cbed69f | |||
| 12d675a0a7 | |||
| d2697345e1 | |||
| a8707baf57 | |||
| 5eff34ce8a | |||
| 0bb96a7413 | |||
| db1d3fcb32 | |||
| 3f1d09bc68 | |||
| 39db1b6537 | |||
| c408c30bc1 | |||
| 1e6cfc373e | |||
| a611281a01 | |||
| 6110bbce98 | |||
| d507dbb5dd | |||
| f60d3b80be | |||
| e24a736fc9 | |||
| e916c6dc9a | |||
| 3540015132 | |||
| 4909d176ec | |||
| 2001c0d408 | |||
| 1383afb36f | |||
| 9904d6deb0 | |||
| e8d8fc1806 | |||
| 10e6745e21 | |||
| b2713df6bb | |||
| 23aaee9ecf | |||
| 1fec7a7c51 | |||
| 25c02b96f3 | |||
| 8e39de0368 | |||
| 7806382d8e | |||
| 96afa57d84 | |||
| caaba0ab3f | |||
| 5dd365238e | |||
| e6aea64689 | |||
| 86b48d8258 | |||
| 4880497db5 | |||
| d253c3163b | |||
| 961c1d60e0 | |||
| aa5d8c4ba7 | |||
| c80f0da4ac | |||
| 9c7cfe9252 | |||
| a5b44fa877 | |||
| fdedcf4de0 | |||
| 8530cce10a | |||
| c75d873b91 | |||
| cbf60380f2 | |||
| e76d1d0c3d | |||
| d831b0f55e | |||
| 4300e4b022 | |||
| ca3093e07e | |||
| 47cfd7da98 | |||
| 8e66b32c95 | |||
| 1dd3aadbd8 | |||
| ec49fb9e49 | |||
| 4313d23ba7 | |||
| 5a6f3f04e7 | |||
| aa1493cad0 | |||
| dd632969f3 | |||
| c032b30247 | |||
| ec0c82a4bf | |||
| b07547df75 | |||
| 617cc47231 | |||
| fd68286b2f | |||
| daedeed8d7 | |||
| 337e224ad3 | |||
| 8dda878c62 | |||
| eeaab1268e | |||
| 66ffa18dce | |||
| 5dd0ac75bc | |||
| a236b4c59b | |||
| ff82a575f6 | |||
| 86fb88cdee | |||
| 316a2508a5 | |||
| 63476c03f3 | |||
| 60c8b1b2be | |||
| 988c837011 | |||
| 2869d8574d | |||
| d233fa39bd | |||
| a26879dca8 | |||
| 429d55769c | |||
| 9cbd0b9813 | |||
| 71912cfdbd | |||
| 7db74cb017 | |||
| 2eec091ac0 | |||
| cb19949a82 | |||
| 54e0795e51 | |||
| 1492a346d3 | |||
| 968e7233e5 | |||
| 17b4aa2466 | |||
| 6be0c3f4c6 | |||
| c3b23fcc6e | |||
| af88b60c0e | |||
| 793e971460 | |||
| a9e88c272a | |||
| f76c23d7f7 | |||
| c8205c4cff | |||
| ab9b77fa90 | |||
| 80c2bc7242 | |||
| 4d126dd91a | |||
| 8a30c5d951 | |||
| 817994c47e | |||
| e3ea859592 | |||
| 23f53077cf | |||
| 091bf2fdf0 | |||
| 47dbd0dd3e | |||
| 67585a6fa7 | |||
| 0d9aca84a9 | |||
| a0c2f0bf19 | |||
| bd1c9274b3 | |||
| 812ba76e0d | |||
| 60cf6b8058 | |||
| ee4f8bda88 | |||
| f50f2aefc0 | |||
| 0e7e27edbf | |||
| a2d797310a | |||
| 1de4d86661 | |||
| cd7c075b3b | |||
| 6595bcfc3c | |||
| 60423b81ad | |||
| 6898efcc02 | |||
| 7aca3eb5b7 | |||
| 6f116510da | |||
| ad26e4acba | |||
| 169d03ea9c | |||
| 2de9c62083 | |||
| fd9ecc589e | |||
| d74c6acc0b | |||
| 9bdd0c682d | |||
| f135413b6d | |||
| cebe1d0cb7 | |||
| a3ee869ee9 | |||
| f510650a42 | |||
| add297920a | |||
| 8cc61e5a8a | |||
| d58c660822 | |||
| d460f005c6 | |||
| 13c5387dc9 | |||
| 45804b318a | |||
| 9ffcac744a | |||
| 365554980d | |||
| 702a8cb0c3 | |||
| 0a4ca595ed | |||
| 5302254462 | |||
| 41419b4cee | |||
| 8de53f18e6 | |||
| 777fc58578 | |||
| e2977540d9 | |||
| 0073889d93 | |||
| c11a88f108 | |||
| 14a96e17be | |||
| 2c5b54d7f3 | |||
| 3af2b090e5 | |||
| 9796654816 | |||
| a6afbebc94 | |||
| 487c0de90f | |||
| c19b1a65bf | |||
| cd8f006d31 | |||
| 40c5f0432c | |||
| 6c51026357 | |||
| 806715e166 | |||
| 0e1a6bd60b | |||
| 48f804210c | |||
| a87722b078 | |||
| e3f2664440 | |||
| ce77fbd2ff | |||
| 9612d6e347 | |||
| dd4cc710f2 | |||
| db9420e715 | |||
| f2c82a6262 | |||
| d23dd5b430 | |||
| 6d649279c8 | |||
| 2cd4e6acfa | |||
| b8e9d5542d | |||
| 487bf8bce7 | |||
| 535e41d43e | |||
| adbeb30c8b | |||
| fc9ca545ad | |||
| 3680b93d89 | |||
| dba05e9adf | |||
| ce344bc704 | |||
| 1df88dcb5f | |||
| 3665d2afb4 | |||
| ffb6b1a6fd | |||
| a1de19c105 | |||
| 31073fc0a9 | |||
| 5fefc69eb6 | |||
| f0bea027c1 | |||
| 7ce17c56a2 | |||
| e4fc76503c | |||
| d181050706 | |||
| a93692ee59 | |||
| 88c72e0cb9 | |||
| 7379f6064e | |||
| ea898e5122 | |||
| 842b04627a | |||
| a368d74619 | |||
| 899240d2ac | |||
| 526f460cd4 | |||
| 8e7e036591 | |||
| 993e543162 | |||
| 1b3897a425 | |||
| 2f91eba85d | |||
| 25049d041d | |||
| ae1aff6863 | |||
| 9227edac18 | |||
| f5d61306c9 | |||
| 396b5fb270 | |||
| d2c0b0e0f5 | |||
| 8366d6ec2a | |||
| 0eeb197c81 | |||
| 065c5916b7 | |||
| 0e93a43ab5 | |||
| fd3f2eb1e5 | |||
| 46881aff2e | |||
| db276cecbf | |||
| 0c7add8f8e | |||
| 6896381ab2 | |||
| 56d040ee06 | |||
| 462f6244aa | |||
| 54d430f3c5 | |||
| f2d444e2d5 | |||
| 23e2e3743c | |||
| 2d207b528a | |||
| 843f17e56f | |||
| 9915a1fd3a | |||
| 3334e06ec6 | |||
| 78e0a4ff1e | |||
| b5d6761fe4 | |||
| b29352b816 | |||
| a778116b9a | |||
| 1afaded712 | |||
| c7e63f52ce | |||
| 5696165d66 | |||
| 2ef3d72c72 | |||
| 33807621bc | |||
| cfc02f67eb | |||
| 6ec64b227c | |||
| 5ca7cbc91e | |||
| bb51e7c0f6 | |||
| 6ada5d46b0 | |||
| 69bf7b3cd3 | |||
| b386dd23fb | |||
| fd4e03c565 | |||
| 15c5898488 | |||
| a0c1beb61f | |||
| 7979401675 | |||
| 09e6fde327 | |||
| a2518c1156 | |||
| f70dba5e6e | |||
| 99604dccc9 | |||
| 37f96d452a | |||
| 584a4e082e | |||
| d59a853f0c | |||
| 2ad0db2d80 | |||
| 9a66d29b6b | |||
| 2cb53563f2 | |||
| 4f8f00c4e2 | |||
| 697403b841 | |||
| 43add842ae | |||
| b4b6e064f3 | |||
| 44bbcd9c06 | |||
| 1f8ebea10c | |||
| fb4bc0a528 | |||
| 01c37701d9 | |||
| 23c1d39bc4 | |||
| 5b15481138 | |||
| 8f8b809756 | |||
| a13f6f4dd9 | |||
| 29cbeb8782 | |||
| ea55b42bc8 | |||
| 746a2ae528 | |||
| 9c4a81a6ee | |||
| bae00c0e20 | |||
| 1835cb12be | |||
| 9e4a0680ab | |||
| 7b12c99a0b | |||
| 39c5d65f76 | |||
| 5f91426fec | |||
| 3049096b3e | |||
| 910fc28dce | |||
| 2a57b9317c | |||
| 64e79d6a78 | |||
| f79703e7fd | |||
| 73e72be323 | |||
| 16009cfde9 | |||
| 99369facbf | |||
| 85a2a575a3 | |||
| a07f37e99d | |||
| 3d0fd81cc4 | |||
| ec463819fe | |||
| fabee0e675 | |||
| 1b005c83eb | |||
| c7e882e97d | |||
| 0c09c07cd2 | |||
| b02344ffc5 | |||
| 329b753df5 | |||
| 6535ccbdd8 | |||
| 6a7ed83f6a | |||
| a1863b9fed | |||
| 5af04b84f0 | |||
| f11de747de | |||
| e51eae5203 | |||
| a3838e1023 | |||
| fb6790c4f5 | |||
| 93ca928e98 | |||
| 40cd40cebd | |||
| 59f680048b | |||
| 33998c2981 | |||
| 6e756c434a | |||
| b00c4e30d0 | |||
| 0025c01024 | |||
| 05c7fbeb0b | |||
| 84c4b3c1b8 | |||
| d76c693147 | |||
| b331363de1 | |||
| daad94eedb | |||
| 2b604a49ea | |||
| 2415418dca | |||
| 1ffc4b9f7f | |||
| dd5fb2cf88 | |||
| cdb2b2e1a7 | |||
| 14ea97337b | |||
| 533225f106 | |||
| 760b5ad276 | |||
| b5d689f39f | |||
| e5203b6e4a | |||
| a9d787b340 | |||
| 05144f39df | |||
| 6bd38ce13a | |||
| a9716a340d | |||
| 4a88660a3d | |||
| da5af2cac2 | |||
| f7756d7d4d | |||
| a7a6a3d124 | |||
| c905ed0338 | |||
| 455093ca23 | |||
| cbf596e410 | |||
| 78b3c5ec3f | |||
| 236b8991f6 | |||
| c8d9d18537 | |||
| 3d7cca91ff | |||
| 09a391dbf4 | |||
| 9e0d29db1a | |||
| fcf32c82ba | |||
| 3ea835117a | |||
| 90ebc1a8be | |||
| af7183151c | |||
| b8cb379234 | |||
| fdf4d4926f | |||
| 4cccff934f | |||
| 52e3a3fc15 | |||
| 4b7f822848 | |||
| a35ffe16cc | |||
| 3785e24077 | |||
| 82ba845fc7 | |||
| a113154708 | |||
| 11c2440dcd | |||
| 17f686f39c | |||
| f498b54648 | |||
| 06141feb8b | |||
| b74b005215 | |||
| 4c212ae507 | |||
| 1ebd2894c2 | |||
| d3951235bd | |||
| 073e1a8462 | |||
| 4cf257b997 | |||
| 51db756385 | |||
| fc4d70a5e9 | |||
| a73d8bc8f4 | |||
| dc0b5838b1 | |||
| afb0ca384a | |||
| 817f81ebb2 | |||
| 119b367205 | |||
| 975ecd0b9d | |||
| 13c0b4b5f6 | |||
| 25d1cf4455 | |||
| cd456a9a60 | |||
| cae1dd964d | |||
| 16a3bf10c8 | |||
| 5e0f93210d | |||
| 2396a2b2e5 | |||
| 4dfbb9e597 | |||
| 6af5f94f90 | |||
| 4925e756a6 | |||
| 95df593c2f | |||
| 8be6818a6d | |||
| fcc3cd369e | |||
| 87eec92c5d | |||
| d745e14cb5 | |||
| 3355d41642 | |||
| 0832a5c254 | |||
| c7df47703e | |||
| a1ee9f865f | |||
| 1033e9fe96 | |||
| 323b30a14b | |||
| 2a2c0420a7 | |||
| f78704af93 | |||
| 34e61c45c9 | |||
| a1951f9756 | |||
| c96dc403b9 | |||
| 48f05f97b7 | |||
| 3208946017 | |||
| 7052f9504a | |||
| 45d1755e19 | |||
| bf29ebc354 | |||
| e50fc2022f | |||
| a63e0eed4c | |||
| 1218c9fa7d | |||
| e50d10bfe6 | |||
| 18a9758511 | |||
| fcd8f05c3c | |||
| 56afc57b7b | |||
| b3a0befe33 | |||
| 669dfe73a4 | |||
| c4001c8507 | |||
| 269831e0c4 | |||
| b22fa48e90 | |||
| 397388d230 | |||
| f5de319f40 | |||
| 1c2fe7b9a6 | |||
| c545a2f0ed | |||
| 7f1dea6129 | |||
| 96d9ae4776 | |||
| 8ee9199abc | |||
| 3cba3a76a4 | |||
| 84d2a22b18 | |||
| 8f87a07f62 | |||
| fa9e829f5d | |||
| 920faa97d2 | |||
| f018425e12 | |||
| ad0f727880 | |||
| 9696284e1d | |||
| 10d733d312 | |||
| e9c2768cc0 | |||
| 4f7aba9c05 | |||
| 892cece2aa | |||
| 7cb3f43862 | |||
| 04ab98a634 | |||
| 18ff09d52f | |||
| a951292f27 | |||
| 7806c2096d | |||
| b7855cf14d | |||
| dfb4153049 | |||
| 14d5416616 | |||
| 63f6e0c43d | |||
| 8069426b5c | |||
| 59a835b1b3 | |||
| 727da06266 | |||
| 38762fb618 | |||
| aff40dac8d | |||
| e097d88ab2 | |||
| a16e64420e | |||
| 76ee7cdd7f | |||
| 0e0ae3c4d1 | |||
| 76ce186bd4 | |||
| b69f36afe4 | |||
| 716a91fc0c | |||
| 0d7832b208 | |||
| 908adb4d2b | |||
| 7697bcb087 | |||
| 975759284d | |||
| d13e770ac4 | |||
| 04547a9206 | |||
| 7dd32c8878 | |||
| d0ec3e0266 | |||
| 0dbad182e8 | |||
| e63a877ed6 | |||
| 4df64695c7 | |||
| 394bc1689f | |||
| 6839939140 | |||
| 00c7b23d15 | |||
| bc6bfccade | |||
| ed2becce88 | |||
| b39acdf18a | |||
| 149e039cd0 | |||
| f99fadaa20 | |||
| b5fd533362 | |||
| 8e88cfbf9a | |||
| 3969413779 | |||
| eedbf2fbb7 | |||
| fbb358bf71 | |||
| b3602cad87 | |||
| b9387ceeda | |||
| 3aa7452e48 | |||
| cca7180834 | |||
| 104ab8c7f3 | |||
| e4d273aa0e | |||
| df61a1ab4e | |||
| 1dcd8cc419 | |||
| b55b68f191 | |||
| 2c2339e229 | |||
| d7645252bb | |||
| dc89bb1dfc | |||
| 47383fd053 | |||
| f80406c7cb | |||
| 75b382e619 | |||
| 566c616abb | |||
| 59d2ef8aa1 | |||
| 977262232a | |||
| fa5895de39 | |||
| f2fb788eac | |||
| c8c3b79f2d | |||
| 1c7012726a | |||
| e3bbbdcecf | |||
| 4e8867c819 | |||
| cffb5e767f | |||
| 204711d313 | |||
| e43807540e | |||
| eb79d4f774 | |||
| e80b63f66f | |||
| ada0712e1a | |||
| 0a7aece40f | |||
| 63bcb4693d | |||
| dec630efa0 | |||
| 2a0984408f | |||
| 8e5027dcb2 | |||
| f489742c9e | |||
| bcc6e3c67d | |||
| 12ad7b0d9c | |||
| a6044a684d | |||
| 9c27947345 | |||
| c96a30aea0 | |||
| 934578118b | |||
| 81dbebb663 | |||
| afd3103506 | |||
| 8b34c96a2d | |||
| ec2c4302cb | |||
| 23eeccec9c | |||
| 421f16d0dd | |||
| cb73261c60 | |||
| 6bc02fd838 | |||
| a7e4b0b062 | |||
| 4b75c42218 | |||
| 4a187699fa | |||
| b4710f0f0c | |||
| 99c4c4a0ef | |||
| adb9a55719 | |||
| 078748243d | |||
| eaa5c7a7b0 | |||
| 8dafd4680b | |||
| 6c6fc2d7db | |||
| 3eccbc2963 | |||
| d90ac05d6e | |||
| bdf0983642 | |||
| 16f219d6d3 | |||
| ba1073ace6 | |||
| 1d5c06ccd6 | |||
| afeba0d07e | |||
| 4ad2bbdf2c | |||
| 0faee13bc3 | |||
| e74349e36c | |||
| 2c2bbdd912 | |||
| d772cd39ea | |||
| 13f364d96a | |||
| 779b39e237 | |||
| 0f34bf3850 | |||
| f085f11ea8 | |||
| 1c1624b8a6 | |||
| caa9cd3060 | |||
| b8042c9da1 | |||
| 478411bf82 | |||
| 49a63d43b3 | |||
| 5b4dc4ee08 | |||
| 2cf2603155 | |||
| 462e5f05e6 | |||
| 3caf83e920 | |||
| 58df785d70 | |||
| 4c0526ce0c | |||
| 6c2de17229 | |||
| d649420212 | |||
| 7f53f340ad | |||
| c4c5516315 | |||
| 8662de39f5 | |||
| f2cf444a64 | |||
| 1634d81e4a | |||
| 9c74cc215c | |||
| 659f506e5f | |||
| 7df776e7ed | |||
| 5762fd61e9 | |||
| 39ea315c97 | |||
| 6fc40cb7cb | |||
| 0658b2a2c4 | |||
| 6064d3222b | |||
| d13fb8918f | |||
| d11618eb3f | |||
| 3b4f5e0882 | |||
| 01f5c65eb9 | |||
| 94bdeb6929 | |||
| f36615f1e2 | |||
| ab4b159d06 | |||
| 90e58e4a5f | |||
| 7759403f3e | |||
| 18aa849cc7 | |||
| a9c25d1935 | |||
| 7f4daf3f5b | |||
| f7828ad4a3 | |||
| 2631ad00bd | |||
| d4a00dec3b | |||
| 46e8474e77 | |||
| c8dfccc365 | |||
| 2e14773f1a | |||
| 968fbd4c60 | |||
| 37b7b25208 | |||
| a2c6d60782 | |||
| 808e44388a | |||
| f8ff44c78f | |||
| 7e29932072 | |||
| c1b0e9fea3 | |||
| df91e93034 | |||
| fd265eccbb | |||
| 57d53abd6e | |||
| c62e0cc7d1 | |||
| e5b2b8ef64 | |||
| e6542a78d0 | |||
| 084680b5fd | |||
| bdfcc5d181 | |||
| 2d6962d937 | |||
| d8210b832f | |||
| ac22e33cec | |||
| 7f05df2627 | |||
| 9d7dab724b | |||
| b8b67ba864 | |||
| f6309138f6 | |||
| 7ca3f60999 | |||
| f0f3e35bf6 | |||
| c30ff28f85 | |||
| 5a121bfcb8 | |||
| 613b2edf49 | |||
| 8e9d370770 | |||
| 69afa9d0f8 | |||
| 955d5775cb | |||
| 6c7e4b5597 | |||
| ff8f4a3a92 | |||
| 2e248e7bc0 | |||
| f9d5201b0c | |||
| baa3938f06 | |||
| 12a0d6d5bc | |||
| 0f8c868d6b | |||
| 761b0e0cfa | |||
| 5bb759a0e7 | |||
| 1ef1109b5f | |||
| 36789bff3f | |||
| d8f1ad3a82 | |||
| f197aa52ac | |||
| fdec738485 | |||
| e2858dbb03 | |||
| 8d75f9c991 | |||
| 8c6b5717f7 | |||
| 63536b9819 | |||
| 8780339c72 | |||
| 90542b189c | |||
| 83766bc3f6 | |||
| 6a61a911de | |||
| 7b074305af | |||
| 973716fbfa | |||
| b153cdec93 | |||
| c63ad89a8c | |||
| 9a95b47c96 | |||
| b4cf7315a5 | |||
| d775a09095 | |||
| 318d77e863 | |||
| 1962336316 | |||
| 3fed1aa157 | |||
| 176845047d | |||
| 62662159e1 | |||
| c932090ed5 | |||
| 24b8ead576 | |||
| cb2e9be6cd | |||
| 6ff301bf27 | |||
| fe3a7babcc | |||
| f611942f61 | |||
| 979e93c7be | |||
| 83383df4dd | |||
| a54c0a435e | |||
| 3d8f1c4780 | |||
| 64a4f10ec7 | |||
| 380adaad3b | |||
| 69118a96be | |||
| 6a14fe728e | |||
| b58be017f4 | |||
| 408a44110f | |||
| aa527fc6bd | |||
| cbd824eb10 | |||
| a1c0aafc16 | |||
| fd782538d8 | |||
| 710e6ddc4c | |||
| 3ce754137d | |||
| f4ea92d1fc | |||
| 24917a9952 | |||
| f60ea00fb8 | |||
| 851da15bc7 | |||
| f6e7b4e291 | |||
| a502a99768 | |||
| 39386676d8 | |||
| f48d6bba35 | |||
| fcbb23af92 | |||
| 7f7dfeab12 | |||
| 450ba42558 | |||
| 76f27ae452 | |||
| 6bb7ba3795 | |||
| 509df44c4f | |||
| 9cb4b782e1 | |||
| 6f3577c9a5 | |||
| 06f5e408ee | |||
| 0402c37a07 | |||
| 7ae9bfef0f | |||
| 1bfcdb5dfa | |||
| 2983cfc531 | |||
| d80861db37 | |||
| 23ceb830b3 | |||
| 4c5f0ca83c | |||
| 1b370076b6 | |||
| 9415b3086d | |||
| e7fcc71d8e | |||
| 7e21e13ec9 | |||
| 360a521f11 | |||
| 53d4547918 | |||
| 2d0c14c3c0 | |||
| b9fd1b01d1 | |||
| 45213124dd | |||
| 76371d6087 | |||
| 37c0589a27 | |||
| da71f4cbbc | |||
| 093034f9e7 | |||
| a7b9b30108 | |||
| 6a2a730cdc | |||
| 97b777ae4f | |||
| 09f257026e | |||
| e59afb6ec1 | |||
| b7acee5723 | |||
| 2910488a30 | |||
| 67817918f4 | |||
| 390342af78 | |||
| 653273f82e | |||
| b33a88a69f | |||
| 7cd7869d6a | |||
| 9ae429e03b | |||
| 0053412f87 | |||
| 63baa76cba | |||
| bd6bd4deeb | |||
| 5b5c88fb4e | |||
| fdacf83ad0 | |||
| 8e04a6e2e4 | |||
| 5791645877 | |||
| 6cc40c65b2 | |||
| 1bb8aab866 | |||
| 13b566746d | |||
| 4b5bd10aa2 | |||
| 251e83b1a4 | |||
| d4f108a849 | |||
| 19219bf8f8 | |||
| 74db7dafa7 | |||
| 9bc8fc493d | |||
| abe857225a | |||
| 9c46b9afa0 | |||
| a41d2af10d | |||
| 42cbc56880 | |||
| 9ba843d82f | |||
| 81589d22f8 | |||
| 576be96935 | |||
| f487cdd581 | |||
| bf177d6cce | |||
| e16b48db30 | |||
| 8e84724c62 | |||
| 2f7694dee7 | |||
| 019e2aee1b | |||
| 8cb7031cf6 | |||
| a167e9f751 | |||
| 824f39330f | |||
| bf600140d3 | |||
| 871302a1b1 | |||
| 5a8a074f0c | |||
| 0e139fd0d6 | |||
| de00d223c4 | |||
| 8d8fef23c9 | |||
| 51be7b000e | |||
| 87295776ff | |||
| b3e9d8d97d | |||
| 96f1a16744 | |||
| 7d386e7821 | |||
| ee258b8ec8 | |||
| 0641adc5f4 | |||
| 045294d53b | |||
| 169df7130b | |||
| 49e252337e | |||
| 7906107d6c | |||
| e3d881be76 | |||
| bd968bd60f | |||
| 541aa459cf | |||
| c82c7ee5db | |||
| 76e72c8a86 | |||
| 6304f0daf6 | |||
| e00efb1566 | |||
| 258347fbd1 | |||
| 7434e330c8 | |||
| b55070f939 | |||
| a7524ba74d | |||
| 3436273fdf | |||
| 4dcd49a516 | |||
| 2f4ed3b35f | |||
| b814f997f8 | |||
| e37872398e | |||
| 3b7c3fb217 | |||
| e04aa4b3cc | |||
| 1bb6a82cf3 | |||
| 022f7121b4 | |||
| cc19c8027a | |||
| 7dfb5b6a28 | |||
| 397b78fe06 | |||
| 1e2f4d6c0c | |||
| 387cd98efe | |||
| 7eddd662e7 | |||
| 21f61fe498 | |||
| 0437314ae3 | |||
| 21e8551787 | |||
| 129bbe2198 | |||
| cfcac8c51d | |||
| eaeb90dc07 | |||
| ae68dea923 | |||
| 1ae8e40a3f | |||
| 779aecfbee | |||
| 1c62b19f9f | |||
| c00775b2d1 | |||
| b7b7c48d8e | |||
| 76ffd4fcb4 | |||
| 9ad5094909 | |||
| 0fd23d3e61 | |||
| a587f8b825 | |||
| fb1098c16e | |||
| 97ef444648 | |||
| c672d2544b | |||
| 72ca1b021a | |||
| 044b3a706c | |||
| 4c40aec8b3 | |||
| 4226e9cc45 | |||
| f659e98a52 | |||
| 97b2aa804d | |||
| 8e07f9b0f4 | |||
| 656daa75fa | |||
| 547606b44e | |||
| 15a29f3a43 | |||
| ab81838d87 | |||
| 854ce93c07 | |||
| 08ae9ddedb | |||
| 3f5a3995cc | |||
| 2a86918508 | |||
| f50ee3fb39 | |||
| bae44d2812 | |||
| 2e4775b19a | |||
| 655e2f9010 | |||
| a4008a2550 | |||
| 9e39dfa9d7 | |||
| 94ee3c65b3 | |||
| d609d37798 | |||
| d0a57d4c47 | |||
| 726b989f6c | |||
| 5f76e61240 | |||
| 42d66bb2c1 | |||
| e4135a9adb | |||
| fe1146b62c | |||
| 7956bd6bab | |||
| 32142e25ea | |||
| 85bb6ea3a7 | |||
| d5e42992d2 | |||
| fbdcef3733 | |||
| a13c857b53 | |||
| 85863358fb | |||
| b397af1bac | |||
| 0906bdc6d7 | |||
| 77925f6abc | |||
| 0a0893e6cc | |||
| 3d17023bc9 | |||
| fd16151850 | |||
| 2ae0472f76 | |||
| cd23fedb56 | |||
| 1cb0156cd0 | |||
| 4880c029b7 | |||
| c79994d812 | |||
| f462af1b0e | |||
| 8729bbc41b | |||
| 0fc1681d5c | |||
| 69576cb17d | |||
| 1a85956dcb | |||
| 01150497bb | |||
| 0ed7f5a5ad | |||
| ce83cf00e0 | |||
| 8eea072cd1 | |||
| 4d23292ad3 | |||
| 618832974e | |||
| c80fbf2de7 | |||
| 5b69ceff0d | |||
| 3cc3687dcb | |||
| eb7c73668f | |||
| d35d3b5e22 | |||
| 935518f6dd | |||
| 20dcee3a5c | |||
| 5825a2ec2c | |||
| 355f4b5f92 | |||
| 9437d98df9 | |||
| 7a8ca1c675 | |||
| 79d9359e56 | |||
| 006166a25c | |||
| 33cc0861a6 | |||
| d48ab63497 | |||
| bd62281144 | |||
| 50397d0052 | |||
| 460e6aab96 | |||
| 95b0a21cfc | |||
| f7b6d95910 | |||
| 6e0bec9db4 | |||
| 83132ef041 | |||
| c1586b72bb | |||
| ca25696d1a | |||
| 11579d9118 | |||
| 32714fb841 | |||
| 2bc2030f86 | |||
| 93dbdf8680 | |||
| 301e33a271 | |||
| 53bb8bc6c3 | |||
| e2502772cb | |||
| 24de312a30 | |||
| efe53eb034 | |||
| 96ccb4cb3f | |||
| 3f06037e1b | |||
| 38d8f6a326 | |||
| 2bec60517a | |||
| d3b8133ee2 | |||
| 4b2b5a9d37 | |||
| 6edc3b61ff | |||
| f525b1762b | |||
| 4f5f241669 | |||
| 0b25332171 | |||
| 054c87c91e | |||
| e053abfc3e | |||
| 6abd36d628 | |||
| 582546f8ed | |||
| c1e7235375 | |||
| 975023bdc7 | |||
| 4df32f8247 | |||
| 630dec62f5 | |||
| a58a541bb6 | |||
| 0cff67e032 | |||
| 72b1ad085f | |||
| 04bcc70422 | |||
| d5eec9b8dc | |||
| 36afe4127c | |||
| 572463bb0d | |||
| 6f066253f0 | |||
| f3cbc37067 | |||
| 37b0dab9da | |||
| c6d15c6f37 | |||
| 73f4b8f172 | |||
| 3aceed62c9 | |||
| f10bad7abe | |||
| c15922a942 | |||
| c2a6a20fc1 | |||
| 37155363ff | |||
| b0183efaf1 | |||
| 6dd8524ea5 | |||
| 50cb102a34 | |||
| be20e90630 | |||
| c15a86dc19 | |||
| b790a844f1 | |||
| faacf7f9c5 | |||
| f9b7f567c3 | |||
| 591522c25a | |||
| 9193604aff | |||
| 1ad8769fff | |||
| fbc3bac6d3 | |||
| ea5401084c | |||
| 902473fe6f | |||
| bc6ed93b0f | |||
| b5f5e64d95 | |||
| fa951acf40 | |||
| 189b65b724 | |||
| 6e427bca74 | |||
| 0c260ce12d | |||
| 9a93d85ef6 | |||
| 46f0384828 | |||
| 54c1f22312 | |||
| 2b41ba94ff | |||
| 471c38628f | |||
| b0b270963c | |||
| a719c391a1 | |||
| 13e6ae1d08 | |||
| c6148c109c | |||
| 95bc595f50 | |||
| 1d6f2acbc2 | |||
| 5d5c915ea9 | |||
| f795528d21 | |||
| 1d4ec6f73e | |||
| 723b5df4f1 | |||
| f197268ca7 | |||
| c152f983da | |||
| adeb088e93 | |||
| 70c837f9f0 | |||
| 78c5bf1ec2 | |||
| c6a024289f | |||
| fe55889495 | |||
| 111bcad9a7 | |||
| a062efeb21 | |||
| d4ed05c98c | |||
| 39a631d31d | |||
| 0a6518eb30 | |||
| 37a21ffef6 | |||
| 2808b85fce | |||
| 924ecced98 | |||
| 077a651dc3 | |||
| c2ef10724d | |||
| 350c3a6d44 | |||
| de3c503e02 | |||
| 95b31ee147 | |||
| 7779bc51cd | |||
| df0e306458 | |||
| d864a67c3b | |||
| 9c19889309 | |||
| 0a1cacf77c | |||
| eca531d743 | |||
| 3326ff3f61 | |||
| d4c3ff743b | |||
| d04cb84c5b | |||
| 0359cb244e | |||
| 76f3edb50d | |||
| 116d24ec37 | |||
| 87c45beba2 | |||
| db48158956 | |||
| f3d56d31c0 | |||
| ee50096754 | |||
| 629d82fe27 | |||
| 3a8f9adb4d | |||
| 8794f45816 | |||
| b291faf7a7 | |||
| 537fe906ce | |||
| 339592d681 | |||
| 3d7d57df7c | |||
| 0cdff35bd3 | |||
| e7c882e826 | |||
| 7e8cec005b | |||
| e264a06670 | |||
| 57dc0159d6 | |||
| 36bb951314 | |||
| 8d0db05e78 | |||
| 8b61cd56bc | |||
| 5dabe53af4 | |||
| 9c7c8244f4 | |||
| b22e45cf18 | |||
| fa275793ad | |||
| 9d3960f0f5 | |||
| 2aebcb842a | |||
| e2722509f7 | |||
| b17a6d470f | |||
| d1cacc2f0f | |||
| 9ff1dab6b8 | |||
| 369bac9950 | |||
| 4c0dbfcb6c | |||
| 965849ee41 | |||
| 89bfd6dcf4 | |||
| 361b2b707f | |||
| 443d75c0ac | |||
| 3eb39ddac2 | |||
| 6709c55fea | |||
| 10c6c9a1ec | |||
| 19e3fba836 | |||
| 061297e9b5 | |||
| 02c7ef70ea | |||
| 19688ff924 | |||
| c8be6d406d | |||
| c9df941ee6 | |||
| f5ab145d2f | |||
| 627347a48c | |||
| 4086374249 | |||
| aaaaf1a806 | |||
| 6c28efdd4f | |||
| 29018fae9c | |||
| 36a6ba24b8 | |||
| 1d21309935 | |||
| bed9f56b9d | |||
| fc5835a327 | |||
| 2bbb704c3e | |||
| 8c52e57c46 | |||
| 5e55a3f5d3 | |||
| 701125b0ca | |||
| 380024547a | |||
| 259f76e1b5 | |||
| 0fa50df355 | |||
| dcdbff74b0 | |||
| d5560d68f4 | |||
| 98388a7ec8 | |||
| 1f7dd5a5bc | |||
| 64e960adc5 | |||
| d82244adc0 | |||
| 93f6abd81a | |||
| e1dac6e58e | |||
| 7de823f140 | |||
| 1856334e7e | |||
| a7050e4b51 | |||
| 99f1965aa6 | |||
| 3ddd809b2c | |||
| d586b7cd2b | |||
| d68778ec81 | |||
| 919e8eb962 | |||
| 4faf323aed | |||
| 4f6931faab | |||
| dc00757cd7 | |||
| 76f5d029a0 | |||
| 618345a2ef | |||
| 12d231443c | |||
| b81c483be3 | |||
| e0022ac287 | |||
| e48b1fd07d | |||
| dc89d2d630 | |||
| fc376b3603 | |||
| f953087311 | |||
| facbfc7cf8 | |||
| cfcc120183 | |||
| c16256bb8a | |||
| 91a042200b | |||
| 4aa0c1bbe4 | |||
| 52e65179a8 | |||
| 8375304d61 | |||
| 1f1098e270 | |||
| 8ae0bb88fa | |||
| b8e0f26a22 | |||
| 22217e8e22 | |||
| fab3b96815 | |||
| 4ecc41229a | |||
| 1973eaf67c | |||
| eba95dd227 | |||
| 6807a08a7e | |||
| b01de7797c | |||
| 87ef351b03 | |||
| 91b4ff60c6 | |||
| ab737c05f3 | |||
| 0362ddbc94 | |||
| b443d4b60e | |||
| 7628866def | |||
| 87685cf84c | |||
| 99472b4fb3 | |||
| 49d1aafc1b | |||
| 225ca3160e | |||
| 47f029f01c | |||
| b18ae12e08 | |||
| 8a84c215a9 | |||
| 04d506b1e4 | |||
| df8ef1074f | |||
| b965cac481 | |||
| 0020941740 | |||
| 7cb3d27174 | |||
| 13cf25e829 | |||
| c5a09270a6 | |||
| 2fb92e3d23 | |||
| 3de35e5b60 | |||
| 457b271c86 | |||
| 8921f5528b | |||
| ac2a424353 | |||
| 7aae618ff8 | |||
| 97734f2d9a | |||
| c05ea013f6 | |||
| aaad391a4a | |||
| 67ee51b976 | |||
| 59f8ee3283 | |||
| f103c8851f | |||
| 2144bb77e3 | |||
| d04193e62d | |||
| 1cc59f4298 | |||
| a0b3c46c2b | |||
| 0a5732b953 | |||
| c6ba263572 | |||
| 4c42769104 | |||
| 2868c079e6 | |||
| 2c80679eb9 | |||
| 0c37e04bfc | |||
| 03b65b06b6 | |||
| 15a373c1cd | |||
| 1dd30598fd | |||
| acfeb7b47a | |||
| 6c493fddd9 | |||
| 0e906162e1 | |||
| d9c95f97d7 | |||
| cd6eef2cfa | |||
| 2af7751caa | |||
| c3febf3560 | |||
| b4059849e2 | |||
| 45cfcd67ff | |||
| c1da4b9b4f | |||
| 2540e166b0 | |||
| d911d382f2 | |||
| 86fbb071da | |||
| 51cad78030 | |||
| 8e3f86383c | |||
| 8bced60784 | |||
| 2778040497 | |||
| 8563ed8eac | |||
| 80b44444ec | |||
| 4a2bbc665c | |||
| 6f0e58351a | |||
| 481df9ee3d | |||
| 883ab9a937 | |||
| bfb6e855e0 | |||
| d724ec1128 | |||
| 40dae8a8a7 | |||
| 00b2799427 | |||
| 620094e358 | |||
| c9555e510c | |||
| b800642090 | |||
| f1b83e7295 | |||
| 26259f398d | |||
| d8b4f8594d | |||
| 865e04c9ec | |||
| b75fa3b06f | |||
| 9f3898ae1e | |||
| 4d847e6943 | |||
| 7bc557b4eb | |||
| 89e1dfeeff | |||
| 99b01d396c | |||
| 029e12860a | |||
| d7801f4a06 | |||
| cc36f189f2 | |||
| ca6a31016a | |||
| 171e08c2fd | |||
| a1a58ad8f8 | |||
| 3b149a22d1 | |||
| 455fc1f79f | |||
| 7081f924de | |||
| 1910af51b6 | |||
| 86d897b23f | |||
| b866baae65 | |||
| 0857e27665 | |||
| 2c99de86d0 | |||
| f3e951e0fb | |||
| 051a4638f3 | |||
| b12bd7d7be | |||
| 24c0f5008d | |||
| 2fbd1d8955 | |||
| f36d01d560 | |||
| 177acb95e5 | |||
| bb8dd1294f | |||
| a19748dba7 | |||
| ac9b781647 | |||
| 95668a2bcf | |||
| e4c3326c0a | |||
| 299c5924fa | |||
| 3e84e7930c | |||
| 6106d1b228 | |||
| 357ffd0b92 | |||
| 25ea90817a | |||
| 0e97d30363 | |||
| aecd7d15f1 | |||
| ee43d3fb97 | |||
| 53f55f8e1d | |||
| 27b1255584 | |||
| 733cfb3218 | |||
| fe49fb5442 | |||
| e8b04cdee6 | |||
| d44848022c | |||
| b5798e219d | |||
| 7762bac360 | |||
| fb49d1197d | |||
| 03125ccad6 | |||
| f2841bf904 | |||
| 777707db43 | |||
| 5fc685d598 | |||
| a87afcecdb | |||
| 4170acba79 | |||
| 9e268eba89 | |||
| 8cb46f2425 | |||
| 85bdca8d44 | |||
| 5d2220c842 | |||
| d90b1e0640 | |||
| 586567927a | |||
| b96ad42f20 | |||
| b9bb831b7f | |||
| 808d7749c7 | |||
| d5476af719 | |||
| 5e63bbcd83 | |||
| 0af868a852 | |||
| bd954478c6 | |||
| 3542c8b807 | |||
| e80c4c858e | |||
| be61e07939 | |||
| a53db11e1a | |||
| 9511923581 | |||
| 12a5af98b4 | |||
| 70cfbbd646 | |||
| 4d16e8391e | |||
| 3bccefe2fc | |||
| 022b773205 | |||
| 62e0e38635 | |||
| 7bfc13fc3e | |||
| d6fc134e26 | |||
| 100bcd3c2d | |||
| e6fe518ed3 | |||
| 5a46b6ecbd | |||
| ed6a74c2c6 | |||
| dc9129e6f1 | |||
| a60e080ce1 | |||
| c4acbf6054 | |||
| 62bcfb52c0 | |||
| 4e24d0ef7d | |||
| 3a026a80f2 | |||
| 2589e35ad5 | |||
| 25848a83bb | |||
| 343446a86d | |||
| cdf4335d95 | |||
| 7e1c05fcab | |||
| 5309b527a5 | |||
| b28bd82515 | |||
| 559bde6b4a | |||
| 1e0046f9d6 | |||
| dc3a26df1c | |||
| bb5c092d4f | |||
| 65249db838 | |||
| 561501a337 | |||
| ded843b989 | |||
| b0eeeb4dbc | |||
| 08989fb745 | |||
| 7e2271905e | |||
| 93781748c3 | |||
| fcadd48444 | |||
| 32f7e322b2 | |||
| 3bd37bf4e0 | |||
| 38934767c8 | |||
| 17a77114d0 | |||
| b17122acf8 | |||
| c66e45f0f7 | |||
| 839f8ae557 | |||
| 101eb91c8f | |||
| a95626ca9d | |||
| fbd881f8d9 | |||
| b87fddf3e7 | |||
| 503422d2f7 | |||
| 6cb86dd16b | |||
| f83aef4606 | |||
| 2f9d9c1a99 | |||
| b493973d7d | |||
| d594843de2 | |||
| 40ece81de2 | |||
| ebee591990 | |||
| de572b53e4 | |||
| 86d0ac6745 | |||
| fc01f77d49 | |||
| 3dba82622e | |||
| a0aa883743 | |||
| 2b83160284 | |||
| f98f63fa55 | |||
| fb44581496 | |||
| e911922430 | |||
| 00074c508f | |||
| 0c550588bb | |||
| 8775550147 | |||
| c8d0154a9e | |||
| bdd62104c1 | |||
| e7d7f9df95 | |||
| d2415b35db | |||
| 4554f19a4a | |||
| 5790b36589 | |||
| ba21aec79f | |||
| 9c6a543434 | |||
| fe76ecfe02 | |||
| 883154dad6 | |||
| 8ba5af7049 | |||
| c6026e8a0f | |||
| 58971dffea | |||
| 7fb9aad61f | |||
| baa5929671 | |||
| 59d9ec131b | |||
| cab26a6a0f | |||
| dcbfa92b03 | |||
| a45aafff33 | |||
| bbe82db087 | |||
| 5077b10274 | |||
| 00adc318ce | |||
| b05d57fcce | |||
| 11c20a5c2c | |||
| cc8de81128 | |||
| 3e00d016b2 | |||
| 8eadee0719 | |||
| d5e3fabf03 | |||
| 8e73d25f1c | |||
| 06a024e3e9 | |||
| 122104daf5 | |||
| fae095ea18 | |||
| 32dc0dd2a0 | |||
| 673d54cfee | |||
| 7cff468239 | |||
| dfbdcdba85 | |||
| c36d4d0be5 | |||
| cb35a59fc9 | |||
| 5cae3148ea | |||
| fbb6c1308c | |||
| d1547dd32d | |||
| 2fbe5a78d1 | |||
| de68db0905 | |||
| 2a1e5914f5 | |||
| f40e64c2aa | |||
| cc12601a01 | |||
| 2f316b858a | |||
| 16960cb9a0 | |||
| 7d849e1c4c | |||
| 0f90ff0b65 | |||
| 8b1078d081 | |||
| 8102f870fe | |||
| 1202fa84fa | |||
| 764b18d883 | |||
| 8c9f574f92 | |||
| efcfdf171d | |||
| d6d694a36f | |||
| 6a52458e15 | |||
| 4a76c023e6 | |||
| 51d1e6e94a | |||
| 6e2474081f | |||
| b53ec7392c | |||
| 362698484f | |||
| cbe0dc60e6 | |||
| 37b7714aff | |||
| 398c3b1e33 | |||
| de49d155c6 | |||
| 57aafeb062 | |||
| 8f970fdbbf | |||
| 0d05beae80 | |||
| 2f7bf7bcbd | |||
| 6aa8337fc2 | |||
| f686d15354 | |||
| aa19475c90 | |||
| 36928b7b60 | |||
| 6d2ea5c801 | |||
| 17a03e6c18 | |||
| b3f4870da7 | |||
| bf15410bf1 | |||
| 824317c477 | |||
| 821efb3499 | |||
| 6027c519e4 | |||
| 227e412b68 | |||
| a5577da36d | |||
| d60de4466a | |||
| cdb3f48da7 | |||
| 2f0492cec5 | |||
| fb6c9cde6b | |||
| 05129b6785 | |||
| ff7c698371 | |||
| 7c33043ac0 | |||
| be0ef50195 | |||
| 7990973b35 | |||
| 9666a7f649 | |||
| 285b8786b9 | |||
| 7a60714071 | |||
| c21be4845e | |||
| 9bbc595eb1 | |||
| d9d7920c1c | |||
| eea7d503fa | |||
| 293f1e8805 | |||
| 7140eec2df | |||
| 2ffbb4e46c | |||
| 54d1cb8f9a | |||
| 3e9a60b9b7 | |||
| 5144550e4e | |||
| 89680ddf70 | |||
| e94d123404 | |||
| 8cc8b53d63 | |||
| 70e4dbd45b | |||
| 0ee59dc438 | |||
| 3085ba7d91 | |||
| cc205dcc91 | |||
| 0ff8ed35b9 | |||
| 7e0c461740 | |||
| 0a351112dd | |||
| f3521728ef | |||
| 12a8770ad5 | |||
| 212838f12a | |||
| 28ccf7d8ee | |||
| 324544835a | |||
| 905301fc06 | |||
| e59a51e25f | |||
| 3c62cbf200 | |||
| 0d6f5b470b | |||
| 1460620483 | |||
| c707715f3d | |||
| a412992783 | |||
| 83380d288c | |||
| 01a4470e23 | |||
| 1924d28be3 | |||
| 38c7f1c7d3 | |||
| b84398bcc7 | |||
| 173d5aba06 | |||
| badea8e6a8 | |||
| 0e8fba1fe6 | |||
| 61e91a9c32 | |||
| 98357995fa | |||
| cfdd37bbbb | |||
| 125c301c56 | |||
| 9535e80745 | |||
| 8abc2a7179 | |||
| e740a88e13 | |||
| 55ee19b50a | |||
| d29c381c19 | |||
| 56dc2f94ce | |||
| 61d27ebd75 | |||
| 2bca437e55 | |||
| c67fdcfd6e | |||
| 992c4c4822 | |||
| 4d4a7471f3 | |||
| 979de6bfa2 | |||
| 99b9de271c | |||
| e0113e9bb9 | |||
| 19213c8013 | |||
| 0de4d9e7ad | |||
| 22a9ec286a | |||
| 5623760c3e | |||
| 263c07ace1 | |||
| f7543e3220 | |||
| bedaa505a2 | |||
| 81e042971c | |||
| 616eb9206d | |||
| 2b9badf728 | |||
| a65aa3d6c7 | |||
| d6b84371a9 | |||
| 05ca719522 | |||
| dcf9870b3a | |||
| 985dff2af7 | |||
| 2e12b6401f | |||
| 85306a0d91 | |||
| d9bac83532 | |||
| 0bdf935fc1 | |||
| f4f07d3c0c | |||
| 3944f30d06 | |||
| 4fd42e0e3d | |||
| d520dac7ba | |||
| b06864f286 | |||
| 79ab38af8a | |||
| e70a857459 | |||
| 070d24ef66 | |||
| f2b283c585 | |||
| 58382d8aca | |||
| dc51a95029 | |||
| 707b000111 | |||
| 651f7b3f93 | |||
| 1642732e8f | |||
| e7f258ee45 | |||
| 95e59d931e | |||
| 01a1b74028 | |||
| 4f988babbf | |||
| 1f788723f9 | |||
| 54742fcad9 | |||
| 91c00d0728 | |||
| a05f20a829 | |||
| 865ec6eca3 | |||
| 52b68c9ea2 | |||
| 51f186597c | |||
| bf549ace10 | |||
| e49bbfe91f | |||
| 0e65aad1a8 | |||
| af34a1568f | |||
| c7e0bf23ad | |||
| 82dce3ee60 | |||
| 3b58ee8d3c | |||
| 0586c8fb05 | |||
| 51c5eba087 | |||
| 540c56d8ab | |||
| fa5e5d670b | |||
| 0933a258e3 | |||
| 1d9c9a6cdb | |||
| b77332e75a | |||
| bdf3d17652 | |||
| 406a568c2c | |||
| 659f9e0556 | |||
| f8c6b20a35 | |||
| 803dc7d853 | |||
| afe3d4a1e9 | |||
| 2a0a75a178 | |||
| b931b0c85c | |||
| eb4508e12d | |||
| bcdc4fef88 | |||
| ebdc73a421 | |||
| 5bf7a6c28d | |||
| 1d3b6721c6 | |||
| 1eead1504c | |||
| 1666fd7355 | |||
| 5e00436b79 | |||
| e204031ef6 | |||
| fd01376f1e | |||
| 625babc55e | |||
| 8f74388ae1 | |||
| e90bd0fd70 | |||
| 06b0694f03 | |||
| d1ef22ee47 | |||
| b0de35f57d | |||
| df835da07d | |||
| 74c03f0d4e | |||
| d9981b25d9 | |||
| bab5fc339e | |||
| 1b43d8993e | |||
| ca7d82fc5b | |||
| 226877ec1e | |||
| cdc739a663 | |||
| 7343ad0de5 | |||
| 7da9aa811a | |||
| 1d42d329cf | |||
| a2a88ae8d2 | |||
| 6b80e6572b | |||
| 2b56ea70df | |||
| 86ee899905 | |||
| d52f89674c | |||
| 880216c544 | |||
| eb3da74331 | |||
| aabbc375a3 | |||
| 2fdf621b2f | |||
| fa0cc546e4 | |||
| 66fb949c82 | |||
| bce42bb25c | |||
| d4d3d51a9d | |||
| e99e47aeac | |||
| 00ab6e2294 | |||
| ad8df76c37 | |||
| a2e37c5dbc | |||
| 143f5ce05e | |||
| 5d5dc67605 | |||
| 28006d26a9 | |||
| 1182f80e64 | |||
| d6d91b5798 | |||
| a7e7050af3 | |||
| d35736732b | |||
| e2a18d3fdc | |||
| 6e7eb99763 | |||
| 0c7c77706d | |||
| 822083300e | |||
| 1f46295c68 | |||
| 71a354c1a0 | |||
| 2dd220e1b9 | |||
| fbe11119b8 | |||
| 6f325886a1 | |||
| 82d6b96f8b | |||
| 7b5dfd7de5 | |||
| 4f47c13efc | |||
| 4233e71954 | |||
| a4d899844e | |||
| aecf53b3e1 | |||
| 29c43d9e33 | |||
| c3238ee38c | |||
| 6325c3d40f | |||
| 86b85aabc5 | |||
| 98b695c284 | |||
| a747d99ec4 | |||
| 74a7ae3134 | |||
| 985541db50 | |||
| e3cb1fe91b | |||
| a743068fdc | |||
| fe85290a18 | |||
| f99cba75d1 | |||
| 85f3e3510e | |||
| ec56d2dbdb | |||
| dd77670007 | |||
| 3f4502d970 | |||
| 0c255572ec | |||
| 59f3e1aea8 | |||
| 886f9661fd | |||
| 8326c867be | |||
| d37eb70b42 | |||
| 5a5cf7cf33 | |||
| 9a6e64e67b | |||
| 5c83d03134 | |||
| 01c4ddb8e3 | |||
| 2b01481151 | |||
| 300b8ece4e | |||
| 119f3ef88c | |||
| 3cd139b906 | |||
| e4848200a0 | |||
| 75cbe0f984 | |||
| 9a43a6ebb7 | |||
| 35e199b579 | |||
| 862ff2f80d | |||
| 1512266eac | |||
| 8cd581f770 | |||
| 440ca771df | |||
| c23ac292b7 | |||
| 9b3cd8eeff | |||
| 705823a9a6 | |||
| 1d192d9fd2 | |||
| 9229a08625 | |||
| bf0bdcb280 | |||
| f244cacfd3 | |||
| a0ee52bb44 | |||
| c5ae06c163 | |||
| a5e8994028 | |||
| 9f0f79469a | |||
| 781ce1ea34 | |||
| 90cb917c24 | |||
| 702cd56aae | |||
| d59fc2999b | |||
| f497c1169a | |||
| 5b37b00e17 | |||
| c0a6f3f9e3 | |||
| 6cd031d2cc | |||
| 9ab415dadb | |||
| 7ee85da0cf | |||
| d052caf65a | |||
| 92553b6589 | |||
| ae383cd6a4 | |||
| 510e2ea450 | |||
| 3c47da2b39 | |||
| 7a8f8d611e | |||
| ee1f6e5bdc | |||
| 8854cf9e87 | |||
| 0ca0785912 | |||
| d82ec0fe9c | |||
| d5e4f7b6e9 | |||
| b0f5b646af | |||
| 5f9737fc70 | |||
| 9590b5f00e | |||
| 343d6daf86 | |||
| 9983ff9851 | |||
| 324addba2c | |||
| bda86d6e6a | |||
| 380b42c57f | |||
| a2dd222c9c | |||
| a3bff8cf61 | |||
| 03bb622456 | |||
| a6bdf58619 | |||
| 4b84cd27b2 | |||
| 34fa612f07 | |||
| aade6933ea | |||
| ecb5416057 | |||
| d42fc6c471 | |||
| f5e1b01cd3 | |||
| 2763567122 | |||
| 286ef8bdc1 | |||
| 51cb501510 | |||
| b93b0a6500 | |||
| 2d0a8a9611 | |||
| 147d042747 | |||
| 10914c741c | |||
| 908138d81a | |||
| a35d6b6a05 | |||
| a083342cda | |||
| e14d04b57d | |||
| 796f0b75ff | |||
| 32581568d3 | |||
| 6c006c3e2c | |||
| d59fdc07c4 | |||
| 9582f76f91 | |||
| a09565fcd6 | |||
| c4582b45bb | |||
| cf10ab5f20 | |||
| e6e9d8eca1 | |||
| ced1dc83b0 | |||
| a0a460087f | |||
| 905cb497d8 | |||
| 18f5ea37f5 | |||
| 916d7038f7 | |||
| c0fa5734ab | |||
| 9fb6f7b5f5 | |||
| 00447e5fe6 | |||
| 4eac2e58a0 | |||
| b95eaa147f | |||
| 295f7f3a9f | |||
| 60524f77f0 | |||
| fb27acf286 | |||
| 4dda2c64d3 | |||
| 83b81b4bb9 | |||
| 878c1bb80b | |||
| d2a4ca1d12 | |||
| 89504963a5 | |||
| e1815b576f | |||
| 55ede8541b | |||
| 8e77430cb1 | |||
| 06e7e258e8 | |||
| 10fe5530f9 | |||
| a46acf09e3 | |||
| b2878e6ea6 | |||
| 26a35ebcee | |||
| 6b57f7afa7 | |||
| bfb5e9b8a6 | |||
| fd33cc9d2b | |||
| dccfb03b67 | |||
| 7b2d8b1f0a | |||
| 5869b81e9c | |||
| c0837a59a6 | |||
| d58244ebde | |||
| 35571ad4d1 | |||
| 23ee9d1d6b | |||
| 95598e5de0 | |||
| a315f6702b | |||
| fd127e1ec2 | |||
| 80085cc76c | |||
| a8940ede63 | |||
| b06d14b4c7 | |||
| 189c49f725 | |||
| 345ea0f3e8 | |||
| 3b3b528bbf | |||
| 08148e2e33 | |||
| 19789c115c | |||
| a67135d139 | |||
| 6b5d2039dc | |||
| 3e952be074 | |||
| 2fcab1e8c5 | |||
| 00b23a4210 | |||
| 0318d63bf8 | |||
| f01f588ad2 | |||
| c52e9be3d5 | |||
| d2144001d1 | |||
| dfc81cecad | |||
| b22bd1f315 | |||
| 45a8cd94e7 | |||
| a50d69c3b2 | |||
| 5ba14734cb | |||
| a332f7a872 | |||
| 450430f22e | |||
| 0fe85834ab | |||
| 54a9393588 | |||
| 2974af5018 | |||
| c3f0b01307 | |||
| 8a9f541753 | |||
| 74df9778bb | |||
| 8408c1017d | |||
| bbcd5c9336 | |||
| 798f5e6826 | |||
| ff2fdacfb2 | |||
| 258b8adfb9 | |||
| c043c377a7 | |||
| 37ea272bd4 | |||
| 6378c97b33 | |||
| 024b07a384 | |||
| 88f8ea0e14 | |||
| 8626c0728c | |||
| 1a9a23c420 | |||
| ae01156598 | |||
| 2e65e745ee | |||
| 0b0059908c | |||
| 92dde79dec | |||
| d218b33609 | |||
| 0eba5c4c9c | |||
| 4825ffe2f3 | |||
| cff0b33f4b | |||
| 4f24088719 | |||
| e580927fc1 | |||
| 73a7027eb9 | |||
| ae47b1a4d1 | |||
| 566b6f1dfa | |||
| 3ad33410b1 | |||
| f8d5a7763a | |||
| 17ebe560f6 | |||
| 978867d509 | |||
| 186634cc08 | |||
| a57298fc8f | |||
| e13dd6490d | |||
| c4ad38670f | |||
| f4b54ea332 | |||
| 81e9fe5201 | |||
| 93d7e134b0 | |||
| e730bf1968 | |||
| e8f043921f | |||
| d4b6ebd2fe | |||
| ad8cd2546e | |||
| ba824537d4 | |||
| 3db86b2276 | |||
| 71bb6de3dd | |||
| d2f688c7d9 | |||
| 2b1c8ee783 | |||
| 774bd48b47 | |||
| ed07dd76ef | |||
| 44133b595d | |||
| a19f4c78bf | |||
| 9f67c0c49b | |||
| 9a02e0b6b3 | |||
| 236d3149ee | |||
| 72bffae7fd | |||
| 25a91076d6 | |||
| 85f7a09b9c | |||
| b56a65cc1a | |||
| 4513cf89f2 | |||
| eb24bbacbb | |||
| 407cc432f2 | |||
| b85dcb9f85 | |||
| 1aa6d113ee | |||
| 325af01421 | |||
| 6bec8cef5a | |||
| f12ce22ade | |||
| a21d3e6f2e | |||
| 543a1d14e8 | |||
| 4082a320b8 | |||
| 278e71d6f9 | |||
| b56b7d06cb | |||
| c055e93247 | |||
| c592fed9f1 | |||
| bcf7b48359 | |||
| b8e5d60fca | |||
| 41dc15f765 | |||
| b2bf90be34 | |||
| cd2204893e | |||
| 3ef83348b1 | |||
| 2b61f674bb | |||
| 52c4ab4c75 | |||
| adb4b122bb | |||
| 26d2de18c2 | |||
| 504bb7a98c | |||
| 8de57dc1a3 | |||
| 7e02981c52 | |||
| b50fca5849 | |||
| 5ca9280627 | |||
| 253208d20e | |||
| b1d9011dae | |||
| c30d99a7e3 | |||
| 0c26cd0723 | |||
| 628c7150df | |||
| 233ce403de | |||
| 2ff1a075b2 | |||
| 10f3d1c4b7 | |||
| 0d74148d70 | |||
| e5a5a6319f | |||
| 85273d07c1 | |||
| ed2a232bda | |||
| 515c122521 | |||
| f0608f4837 | |||
| 7e8bebfaac | |||
| fcdab1ff4e | |||
| e7281c957c | |||
| 2dd8b8702f | |||
| 1e4470a007 | |||
| 8c1231869e | |||
| 7509146a8f | |||
| c4a1dc4c70 | |||
| 88e1740422 | |||
| c240042207 | |||
| 0110578bfe | |||
| 3d9e2357c0 | |||
| c41455aac4 | |||
| 7c6dd36ee1 | |||
| def3ba9d66 | |||
| e7f6d321dd | |||
| f3c2a4db93 | |||
| 5157a9f33c | |||
| 5864834661 | |||
| c766d44bbd | |||
| 850f41df42 | |||
| b8985b9d19 | |||
| 29e618146c | |||
| 2a8629c670 | |||
| 689587c2e0 | |||
| b95deeee9f | |||
| 33608b3eb2 | |||
| 069576515d | |||
| 670a832985 | |||
| 435346ce3a | |||
| 88177572fc | |||
| f00d5d9417 | |||
| 013a5c06e6 | |||
| ad8394cbd3 | |||
| b1332c6494 | |||
| fa174a8279 | |||
| f03837f45d | |||
| 444d552d5a | |||
| 3b10c28b66 | |||
| 3fddb28c4f | |||
| ac85678616 | |||
| 2ab636b9ed | |||
| f4e5d27b6c | |||
| 562f33e224 | |||
| e82ff230a5 | |||
| 0a5b357bab | |||
| 9b6217e1c3 | |||
| d12015e91d | |||
| f675506bc6 | |||
| 3107bbb88b | |||
| 91cea45a43 | |||
| 9a40902c9d | |||
| 7bfb213687 | |||
| 6c38dcc885 | |||
| 04ead96133 | |||
| 5254f0cc7b | |||
| 980f8c52e8 | |||
| 298716189e | |||
| 7635f9d91e | |||
| 64748a6339 | |||
| 8f54e3188e | |||
| de67a9c215 | |||
| 584c9b592c | |||
| 5f80f9b246 | |||
| 740356c4c2 | |||
| 576c148b9c | |||
| 8bafdb1725 | |||
| bbb2fe2dbc | |||
| b4f957a166 | |||
| 856cddbc84 | |||
| edee15b21d | |||
| dbd47737cb | |||
| c3a07675e4 | |||
| 2b32abe467 | |||
| 4a88d3477d | |||
| acebc53470 | |||
| d44f98d677 | |||
| 4d44eb97f5 | |||
| 1684256ed2 | |||
| d84fd993c9 | |||
| 0f217b3507 | |||
| 8a31c1d555 | |||
| 038c997b8f | |||
| cb08d37369 | |||
| 0076dd99e0 | |||
| e229c8f8e7 | |||
| 6ddb9e414f | |||
| 183b24086a | |||
| 4d03db1c49 | |||
| c15b35fff2 | |||
| de479fe6fc | |||
| 0d12832d30 | |||
| 5590feac0f | |||
| 8e3a228fc9 | |||
| 8899d70e08 | |||
| 3653b06ad9 | |||
| 60dc0cc68c | |||
| c9b590465c | |||
| 3b5e5ebfa3 | |||
| 35ebe455c0 | |||
| 294611c457 | |||
| df7882e14f | |||
| 19fd1f2556 | |||
| 95fc89ec67 | |||
| 42cdf71b8d | |||
| 77010ee7e3 | |||
| 6769dab121 | |||
| c0cc4e250e | |||
| a61c206c38 | |||
| de3db6eec0 | |||
| 753b12f886 | |||
| 833d6a6b27 | |||
| 4343bd9826 | |||
| 15f62be1db | |||
| 610762a89d | |||
| f131c79b87 | |||
| 3156dd3040 | |||
| f2218fa44d | |||
| a5e8deabac | |||
| 250bcde474 | |||
| 1ac835d420 | |||
| db326b6723 | |||
| 9d94f26ed6 | |||
| 5dd46afaac | |||
| cc2c2b094e | |||
| c16317609f | |||
| 17adab3177 | |||
| 209f8d646c | |||
| fd138cf22a | |||
| d178982ec5 | |||
| 9a525f453b | |||
| 04651784b5 | |||
| 7100eb990e | |||
| 3d1a35c41f | |||
| 7be125ee4d | |||
| 75fe828e21 | |||
| ba74f3e61c | |||
| 61e6e63856 | |||
| 874483ba55 | |||
| bbadf9064a | |||
| 37df6f1968 | |||
| f9a5c99f29 | |||
| d8a00c3f3d | |||
| 2463a077b6 | |||
| 712be64016 | |||
| b1cf4da7bb | |||
| aecf70158e | |||
| 3763552f4a | |||
| 061e163a62 | |||
| 6225c048ef | |||
| 07c4563764 | |||
| 7bb5ece2c6 | |||
| 580e4e71eb | |||
| 64b7369a51 | |||
| c089be96f5 | |||
| 6ea6c2c8f1 | |||
| 76def1195f | |||
| d30c7cc97d | |||
| bf43aa839e | |||
| e1a60b801a | |||
| 9639be152d | |||
| 7e296db599 |
@@ -0,0 +1,69 @@
|
||||
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference
|
||||
version: 2.1
|
||||
|
||||
# Define a job to be invoked later in a workflow.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
|
||||
jobs:
|
||||
build-elrsv2:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=NO LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO PCBI6_ELRSV2=YES" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-elrsv2-<< pipeline.git.tag >>.bin
|
||||
build-gvars:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=YES LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-gvars-<< pipeline.git.tag >>.bin
|
||||
build-heli:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: docker run -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=YES GVARS=YES LUA_COMPILER=NO MULTIMODULE=NO DEBUG=NO" -v $PWD:/opentx vitass/opentx-fw-build
|
||||
- store_artifacts:
|
||||
path: opentx-i6x-2.3.0.bin
|
||||
destination: ./artifacts/opentx-i6x-heli-<< pipeline.git.tag >>.bin
|
||||
publish-github-release:
|
||||
docker:
|
||||
- image: cibuilds/github:0.13
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: ./artifacts
|
||||
- run:
|
||||
name: "Publish Release on GitHub"
|
||||
command: |
|
||||
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete latest ./artifacts/
|
||||
# Invoke jobs via workflows
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
|
||||
workflows:
|
||||
openi6x-workflow:
|
||||
jobs:
|
||||
- build-elrsv2
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- build-gvars
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- build-heli
|
||||
# filters:
|
||||
# branches:
|
||||
# ignore: /.*/
|
||||
# tags:
|
||||
# only: /.*-release$/
|
||||
- publish-github-release:
|
||||
requires:
|
||||
- build-elrsv2
|
||||
- build-gvars
|
||||
- build-heli
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
# Handle line endings automatically for files detected as text
|
||||
# and leave all files detected as binary untouched.
|
||||
* text=auto
|
||||
|
||||
#
|
||||
# The above will handle all files NOT found below
|
||||
#
|
||||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
|
||||
# Source files
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx text
|
||||
*.cpp text
|
||||
*.c++ text
|
||||
*.hpp text
|
||||
*.h text
|
||||
*.h++ text
|
||||
*.hh text
|
||||
*.lua text
|
||||
*.pxd text
|
||||
*.py text
|
||||
*.py3 text
|
||||
*.pyw text
|
||||
*.pyx text
|
||||
*.pl text
|
||||
*.pm text
|
||||
*.sln text eol=crlf
|
||||
*.csproj text eol=crlf
|
||||
*.vbproj text eol=crlf
|
||||
*.vcxproj text eol=crlf
|
||||
*.vcproj text eol=crlf
|
||||
*.dbproj text eol=crlf
|
||||
*.fsproj text eol=crlf
|
||||
*.lsproj text eol=crlf
|
||||
*.wixproj text eol=crlf
|
||||
*.modelproj text eol=crlf
|
||||
*.sqlproj text eol=crlf
|
||||
*.wmaproj text eol=crlf
|
||||
*.xproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.filters text eol=crlf
|
||||
*.vcxitems text eol=crlf
|
||||
*.sh eol=lf
|
||||
|
||||
# Compiled Object files
|
||||
*.slo binary
|
||||
*.lo binary
|
||||
*.o binary
|
||||
*.obj binary
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch binary
|
||||
*.pch binary
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so binary
|
||||
*.dylib binary
|
||||
*.dll binary
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai binary
|
||||
*.la binary
|
||||
*.a binary
|
||||
*.lib binary
|
||||
|
||||
# Executables
|
||||
*.exe binary
|
||||
*.out binary
|
||||
*.app binary
|
||||
|
||||
# Binary files
|
||||
*.db binary
|
||||
*.p binary
|
||||
*.pkl binary
|
||||
*.pyc binary
|
||||
*.pyd binary
|
||||
*.pyo binary
|
||||
|
||||
# Documents
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
*.md text
|
||||
*.adoc text
|
||||
*.textile text
|
||||
*.mustache text
|
||||
*.csv text
|
||||
*.tab text
|
||||
*.tsv text
|
||||
*.sql text
|
||||
|
||||
# Graphics
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.ico binary
|
||||
# SVG treated as an asset (binary) by default. If you want to treat it as text,
|
||||
# comment-out the following line and uncomment the line after.
|
||||
*.svg binary
|
||||
#*.svg text
|
||||
*.eps binary
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help the OpenTX team to improve OpenTX
|
||||
|
||||
---
|
||||
*Before submitting, search the open issue if there is already a report of the bug*
|
||||
|
||||
Also often minor bugs are already fixed in nightly builds, often it is
|
||||
a good idea to test (in a controlled environment like a bench setup)
|
||||
with a nightly firmware to see if the bug still exists.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**General information**
|
||||
- OpenTX version (e.g. 2.1.23 or N123)
|
||||
- Hardware (e.g. Frsky X9D+ or 9X Pro)
|
||||
- OpenTX Companion (e.g. 2.1.23 on Ubuntu 16.04)
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Help
|
||||
about: Problems or question of using OpenTX
|
||||
|
||||
---
|
||||
|
||||
The issue tracker here is for devlopment of OpenTX. This is not a
|
||||
support site, only a bug tracking system. Please use support groups
|
||||
like [rcgroups](https://rcgroups.com/) or
|
||||
[openrcforum](https://www.openrcforums.com/forum/). See also our
|
||||
[manual](https://opentx.gitbooks.io/manual-for-opentx-2-2/).
|
||||
|
||||
For quick questions you can also join our general chat.
|
||||
|
||||
Issues that fall into the category of asking for help, will be
|
||||
generally closed as invalid without an answer.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project to make OpenTX even better
|
||||
|
||||
---
|
||||
*Before suggesting a new feature here, please search the open issue if there is already a request for the feature*
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
+17
-8
@@ -2,12 +2,21 @@
|
||||
/.*project
|
||||
/.settings
|
||||
/.autotools
|
||||
radio/src/bootloader/.dep/
|
||||
radio/src/bootloader/bootloader_ramBoot*
|
||||
*.lbm
|
||||
*.o
|
||||
/doc/
|
||||
*.stamp
|
||||
radio/src/lua/lua_fields_*.txt
|
||||
radio/src/lua/lua_exports_*.txt
|
||||
/*.user
|
||||
/*.user.*
|
||||
build*/
|
||||
cmake-build-*/
|
||||
/debian/
|
||||
/CMakeFiles/*
|
||||
radio/src/CmakeFiles/*
|
||||
/.vscode/
|
||||
*.cmake
|
||||
*.make
|
||||
*.marks
|
||||
/nbproject/
|
||||
*.bin
|
||||
/radio/src/CMakeFiles/firmware.dir/link.txt
|
||||
.push.settings.jsonc
|
||||
build.sh
|
||||
firm.sh
|
||||
flash.sh
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "radio/src/thirdparty/GCS_MAVLink/include_v1.0"]
|
||||
path = radio/src/thirdparty/GCS_MAVLink/include_v1.0
|
||||
url = https://github.com/mavlink/c_library_v1.git
|
||||
+47
-14
@@ -1,27 +1,60 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: python
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
|
||||
virtualenv:
|
||||
system_site_packages: true
|
||||
|
||||
python:
|
||||
- 3.4
|
||||
env:
|
||||
global:
|
||||
# - QT_BASE=53
|
||||
# - QT_BASE=54
|
||||
# - QT_BASE=55
|
||||
# - QT_BASE=56
|
||||
- QT_BASE=57
|
||||
# - GCC_ARM=/opt/gcc-arm-none-eabi/bin
|
||||
- PYTHONPATH=${PYTHONPATH}:/usr/lib/python3/dist-packages
|
||||
matrix:
|
||||
#
|
||||
# ALL will build every individual board & DEFAULT, sequentially.
|
||||
# DEFAULT is "make all" (including Companion & Simulator), with default settings
|
||||
#
|
||||
# - FLAVOR=ALL
|
||||
- FLAVOR=DEFAULT
|
||||
- FLAVOR=ARM9X
|
||||
# - FLAVOR=AR9X
|
||||
# - FLAVOR=SKY9X
|
||||
# - FLAVOR=9XRPRO
|
||||
- FLAVOR=X7
|
||||
- FLAVOR=XLITE
|
||||
- FLAVOR=X9
|
||||
# - FLAVOR=X9D
|
||||
# - FLAVOR=X9D+
|
||||
# - FLAVOR=X9E
|
||||
- FLAVOR=HORUS
|
||||
# - FLAVOR=X10
|
||||
# - FLAVOR=X12Sr10
|
||||
# - FLAVOR=X12S
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository ppa:ubuntu-sdk-team/ppa --yes
|
||||
- sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded --yes
|
||||
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test --yes
|
||||
- if [ "$QT_BASE" = "53" ]; then sudo add-apt-repository ppa:beineri/opt-qt532-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "54" ]; then sudo add-apt-repository ppa:beineri/opt-qt542-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "55" ]; then sudo add-apt-repository ppa:beineri/opt-qt551-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "56" ]; then sudo add-apt-repository ppa:beineri/opt-qt562-trusty -y; fi
|
||||
- if [ "$QT_BASE" = "57" ]; then sudo add-apt-repository ppa:beineri/opt-qt571-trusty -y; fi
|
||||
- sudo apt-get update -qq
|
||||
- pyenv uninstall -f 2.7.6 && pyenv install 3.5.4 && pyenv global 3.5.4
|
||||
- pip install pillow
|
||||
|
||||
install:
|
||||
- sudo apt-get --yes --force-yes install qtbase5-dev qtmultimedia5-dev qttools5-dev qttools5-dev-tools python3-pyqt5 curl gcc-arm-none-eabi libfox-1.6-dev libgtest-dev
|
||||
- wget --quiet http://firmware.ardupilot.org/Tools/Travis/gcc-avr_1%253a4.8-2.1_amd64.deb
|
||||
- wget --quiet http://firmware.ardupilot.org/Tools/Travis/libmpfr4_3.1.2-1_amd64.deb
|
||||
- wget --quiet http://firmware.ardupilot.org/Tools/Travis/avr-libc_1%253a1.8.0-4.1_all.deb
|
||||
- wget --quiet http://firmware.ardupilot.org/Tools/Travis/binutils-avr_2.23.1-2.1_amd64.deb
|
||||
- wget --quiet http://firmware.ardupilot.org/Tools/Travis/libmpc3_1.0.1-1ubuntu1_amd64.deb
|
||||
- sudo dpkg --install gcc-avr_1%3a4.8-2.1_amd64.deb avr-libc_1%3a1.8.0-4.1_all.deb libmpfr4_3.1.2-1_amd64.deb binutils-avr_2.23.1-2.1_amd64.deb libmpc3_1.0.1-1ubuntu1_amd64.deb
|
||||
- sudo apt-get --yes --force-yes install curl libmpfr4 libmpc3 libfox-1.6-dev libgtest-dev
|
||||
- sudo apt-get --yes --force-yes install gcc-arm-none-eabi
|
||||
# Trying to build with gcc-arm 4.7 isn't working because it can't find the compiler, despite adding to PATH (in commit-tests.sh) by defining GCC_ARM above
|
||||
# - wget --quiet https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q3-update/+download/gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2
|
||||
# - tar xjf gcc-arm-none-eabi-4_7-2013q3-20130916-linux.tar.bz2
|
||||
# - mv gcc-arm-none-eabi-4_7-2013q3 /opt/gcc-arm-none-eabi
|
||||
- sudo apt-get install --yes --force-yes -qq qt${QT_BASE}base qt${QT_BASE}multimedia qt${QT_BASE}svg qt${QT_BASE}tools; source /opt/qt${QT_BASE}/bin/qt${QT_BASE}-env.sh
|
||||
|
||||
script:
|
||||
- ./tools/commit-tests.sh .
|
||||
- ./tools/commit-tests.sh
|
||||
|
||||
+162
-23
@@ -1,57 +1,196 @@
|
||||
project(OpenTX)
|
||||
|
||||
set(VERSION_MAJOR "2")
|
||||
set(VERSION_MINOR "2")
|
||||
set(VERSION_MINOR "3")
|
||||
set(VERSION_REVISION "0")
|
||||
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
|
||||
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
|
||||
message(STATUS "OpenTX ${VERSION}")
|
||||
set(SDCARD_REVISION "0018")
|
||||
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_policy(SET CMP0020 NEW)
|
||||
cmake_policy(SET CMP0023 OLD)
|
||||
if(POLICY CMP0042)
|
||||
cmake_policy(SET CMP0042 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0043)
|
||||
cmake_policy(SET CMP0043 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0054)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
endif()
|
||||
if(POLICY CMP0058)
|
||||
cmake_policy(SET CMP0058 NEW) # for ninja
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(RADIO_DIRECTORY ${PROJECT_SOURCE_DIR}/radio)
|
||||
set(RADIO_SRC_DIRECTORY ${RADIO_DIRECTORY}/src)
|
||||
set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src)
|
||||
set(SIMU_SRC_DIRECTORY ${COMPANION_SRC_DIRECTORY}/simulation)
|
||||
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
find_package(Qt5LinguistTools)
|
||||
find_package(Qt5PrintSupport)
|
||||
find_package(Qt5Multimedia)
|
||||
|
||||
message(STATUS "Looking for SDL ")
|
||||
find_package(Sdl)
|
||||
if(SDL_FOUND)
|
||||
message("SDL Include Path: " ${SDL_INCLUDE_DIR})
|
||||
else()
|
||||
message("SDL not found! Joysticks support will be disabled. Simulator audio will not work.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Looking for FOX ")
|
||||
find_package(Fox)
|
||||
if ((NOT FOX_FOUND) AND (NOT WIN32))
|
||||
message("Libfox not found, simu target will not be available")
|
||||
endif()
|
||||
|
||||
include(Macros)
|
||||
today(DATE)
|
||||
now(TIME)
|
||||
git_id(GIT_STR)
|
||||
|
||||
message(STATUS "OpenTX ${VERSION} @${GIT_STR}")
|
||||
|
||||
# options shared by all targets
|
||||
|
||||
option(APP_CUSTOM_DBG_HANDLER "Use custom message handler for debug output in all Qt apps." ON)
|
||||
set(APP_CUSTOM_DBG_LEVEL "0" CACHE STRING
|
||||
"Debug output level: 0=debug+; 1=info+; 2=warn+; 3=critical+; 4=fatal only.")
|
||||
set(APP_CUSTOM_DBG_SHOW_FILE "DEFAULT" CACHE STRING
|
||||
"Show source file names in debug output. 1/0/DEFAULT (default is ON with DEBUG builds).")
|
||||
|
||||
option(VERBOSE_CMAKELISTS "Show extra information while processing CMakeLists.txt files." OFF)
|
||||
option(WARNINGS_AS_ERRORS "Treat any compiler warning as an error (adds -Werror flag)." OFF)
|
||||
|
||||
if(WIN32)
|
||||
set(WIN_EXTRA_LIBS_PATH "C:/Programs" CACHE PATH
|
||||
"Base path to extra libs/headers on Windows (SDL & pthreads folders should be in here).")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/SDL") # hints for FindSDL
|
||||
endif()
|
||||
|
||||
# Python check
|
||||
find_package("PythonInterp")
|
||||
if(PYTHONINTERP_FOUND)
|
||||
message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
|
||||
get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY)
|
||||
else()
|
||||
message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
|
||||
set(LUA NO)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # regular Clang or AppleClang
|
||||
set(CLANG TRUE)
|
||||
endif()
|
||||
|
||||
option(DISABLE_COMPANION "Disable building companion and simulators" OFF)
|
||||
|
||||
if(NOT DISABLE_COMPANION) # FIXME cosmetics/style
|
||||
find_package(Qt5Core)
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
find_package(Qt5LinguistTools)
|
||||
find_package(Qt5PrintSupport)
|
||||
find_package(Qt5Multimedia)
|
||||
find_package(Qt5Svg)
|
||||
|
||||
if(Qt5Core_FOUND)
|
||||
message(STATUS "Qt Version: ${Qt5Core_VERSION}")
|
||||
|
||||
### Get locations of Qt binary executables & libs (libs are for distros, not for linking)
|
||||
# first set up some hints
|
||||
get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
|
||||
get_filename_component(qt_core_path ${QtCore_LOCATION} PATH)
|
||||
if(APPLE)
|
||||
get_filename_component(qt_core_path "${qt_core_path}/.." ABSOLUTE)
|
||||
endif()
|
||||
|
||||
set(QT_LIB_DIR ${qt_core_path} CACHE PATH "Path to Qt libraries (.dll|.framework|.so).")
|
||||
find_path(QT_BIN_DIR NAMES "qmake" "qmake.exe" HINTS "${CMAKE_PREFIX_PATH}/bin" "${qt_core_path}/../bin" "${qt_core_path}" DOC "Path to Qt binaries (qmake, lupdate, etc.).")
|
||||
find_program(QT_QMAKE_EXECUTABLE qmake HINTS "${QT_BIN_DIR}" DOC "Location of qmake program.")
|
||||
find_program(QT_LUPDATE_EXECUTABLE lupdate HINTS "${QT_BIN_DIR}" DOC "Location of Qt's 'lupdate' program for updating translation files.")
|
||||
|
||||
# Try to find Qt translations
|
||||
if(QT_QMAKE_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
|
||||
OUTPUT_VARIABLE qt_translations_hint
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
find_path(QT_TRANSLATIONS_DIR NAMES "qt_en.qm" HINTS "${qt_translations_hint}" DOC "Path to prebuilt Qt translations (qt_*.qm).")
|
||||
|
||||
### Common definitions for the Qt-based apps
|
||||
list(APPEND APP_COMMON_DEFINES -DSIMU)
|
||||
list(APPEND APP_COMMON_DEFINES -DQXT_STATIC)
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_USE_QSTRINGBUILDER) # more efficient QString construction using % operator
|
||||
|
||||
if(MSVC)
|
||||
list(APPEND APP_COMMON_DEFINES -D__STDC_LIMIT_MACROS)
|
||||
endif()
|
||||
if(APP_CUSTOM_DBG_HANDLER)
|
||||
# provide full qDebug log context to our custom handler. This may also affect libsimulator, which is why it is here
|
||||
list(APPEND APP_COMMON_DEFINES -DQT_MESSAGELOGCONTEXT)
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=1)
|
||||
if(APP_CUSTOM_DBG_LEVEL GREATER -1 AND APP_CUSTOM_DBG_LEVEL LESS 5)
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_DEFAULT_LEVEL=${APP_CUSTOM_DBG_LEVEL})
|
||||
endif()
|
||||
if(NOT APP_CUSTOM_DBG_SHOW_FILE STREQUAL "DEFAULT" AND (APP_CUSTOM_DBG_SHOW_FILE STREQUAL "1" OR APP_CUSTOM_DBG_SHOW_FILE STREQUAL "0"))
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_SHOW_SRC_PATH=${APP_CUSTOM_DBG_SHOW_FILE})
|
||||
endif()
|
||||
else()
|
||||
list(APPEND APP_COMMON_DEFINES -DAPP_DBG_HANDLER_ENABLE=0)
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(WARNING "Qt not found! Companion and Simulator builds disabled.")
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package(Fox QUIET) # QUIET not working on WIN32?
|
||||
if (FOX_FOUND)
|
||||
message(STATUS "Foxlib found at ${FOX_LIBRARY}")
|
||||
else() # if(NOT WIN32)
|
||||
message("Libfox not found, simu target will not be available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5Core_FOUND OR FOX_FOUND)
|
||||
set(SDL_BUILDING_LIBRARY YES) # this prevents FindSDL from appending SDLmain lib to the results, which we don't want
|
||||
find_package("SDL")
|
||||
if(SDL_FOUND)
|
||||
message(STATUS "SDL Lib: ${SDL_LIBRARY}; Headers: ${SDL_INCLUDE_DIR}; Version: ${SDL_VERSION_STRING}")
|
||||
if (NOT ${SDL_VERSION_STRING} VERSION_LESS "2.0")
|
||||
message(FATAL_ERROR "OpenTX requires SDL 1.x, not 2.x")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.")
|
||||
endif()
|
||||
endif()
|
||||
endif(NOT DISABLE_COMPANION)
|
||||
|
||||
# Check for a file that is typically left from a OpenTX 2.1 build and abort if found
|
||||
if (EXISTS ${RADIO_SRC_DIRECTORY}/stamp.h OR EXISTS ${RADIO_SRC_DIRECTORY}/translations/en.h)
|
||||
message(FATAL_ERROR "Source directory contains files leftover from a OpenTX 2.1 build. Please run `git clean -f` in source directory (Careful: Will remove any extra files) or do a new clean git checkout")
|
||||
endif()
|
||||
|
||||
# Windows-specific includes and libs shared by sub-projects
|
||||
if(WIN32)
|
||||
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/dirent")
|
||||
if(MSVC)
|
||||
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIRECTORY}/thirdparty/windows/msinttypes")
|
||||
set(WIN_PTHREAD_BASE_PATH "${WIN_EXTRA_LIBS_PATH}/pthreads/Pre-built.2" CACHE PATH "Where to find pthreads include and lib folders.")
|
||||
list(APPEND WIN_INCLUDE_DIRS "${WIN_PTHREAD_BASE_PATH}/include")
|
||||
find_file(WIN_PTHREAD_LIB pthreadVC2.lib PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib NO_DEFAULT_PATH)
|
||||
find_file(WIN_PTHREAD_DLL pthreadVC2.dll PATHS "${WIN_PTHREAD_BASE_PATH}" PATH_SUFFIXES lib/x86 lib dll/x86 dll NO_DEFAULT_PATH)
|
||||
if(WIN_PTHREAD_LIB)
|
||||
list(APPEND WIN_LINK_LIBRARIES "${WIN_PTHREAD_LIB}")
|
||||
else()
|
||||
message(SEND_ERROR "pthreadVC2.lib not found!")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(${RADIO_SRC_DIRECTORY})
|
||||
|
||||
if(Qt5Widgets_FOUND)
|
||||
if(Qt5Core_FOUND AND NOT DISABLE_COMPANION)
|
||||
add_subdirectory(${COMPANION_SRC_DIRECTORY})
|
||||
endif()
|
||||
|
||||
+1474
-1
File diff suppressed because it is too large
Load Diff
-852
@@ -1,852 +0,0 @@
|
||||
<a href="http://frsky-rc.com">FrSky (monthly)</a>
|
||||
<a href="http://alofthobbies.com">Aloft Hobbies</a>
|
||||
<a href="http://jonathan.it">Jonathan Modellismo</a>
|
||||
<a href="http://wstech.de">WsTech</a>
|
||||
<a href="http://aviomotive.com">Aviomotive</a>
|
||||
<a href="http://boltrc.com">BoltRC</a>
|
||||
<a href="http://aerialtechhobbies.com">Aerial Tech Hobbies</a>
|
||||
<a href="http://litepilots.com">LitePilots</a>
|
||||
<a href="http://openpilot.com">David Ankers (OpenPilot)</a>
|
||||
<a href="http://3drobotics.com">3D Robotics</a>
|
||||
<a href="http://rcstudio.cz">RC Studio (monthly)</a>
|
||||
|
||||
Mario Sette
|
||||
Felice Baratto
|
||||
Alessandro Mari
|
||||
Gianpiero Spontina
|
||||
Ingo Kuzniak
|
||||
Hans-Åke Rahm
|
||||
Tamas Varga
|
||||
Thomas Gregg
|
||||
Didier Christien
|
||||
Alain Pinard
|
||||
Sergio Melas
|
||||
Paul Montenot
|
||||
Chris Guy
|
||||
Adrien Gravouille
|
||||
Thomas Black
|
||||
Marc Lucht
|
||||
Zdenek Trojanek
|
||||
Martin Hotar
|
||||
Stefan Grundevik
|
||||
Fabio Eboli
|
||||
Federico Zotti
|
||||
Albin Esbjörnsson
|
||||
Kilian Hüttenhofer
|
||||
Stephen Stough
|
||||
Adilson Oliveira
|
||||
Robert Saint Marie
|
||||
Tad Leake
|
||||
Andreas Weitl
|
||||
Chan Lofland
|
||||
Dirk Kasten
|
||||
Denisov Alexander
|
||||
Timo Varppee
|
||||
Ondrej Hatapka
|
||||
Valérie Billon
|
||||
R. Scott Page
|
||||
Johan Cronje
|
||||
Renato Aranghelovici
|
||||
Jeffrey Irvin
|
||||
John Rodgers
|
||||
Kenneth Crump
|
||||
Damjan Adamic
|
||||
Martin Wilson
|
||||
Joe Street
|
||||
John Holdsworth
|
||||
Daniel Schwartz
|
||||
Dean Church (monthly)
|
||||
Michael Halse
|
||||
David Mark
|
||||
Ted Moss
|
||||
Jim Wagner
|
||||
Nicola Porzi
|
||||
Michael Halse
|
||||
Chewytm
|
||||
Espen Solbu
|
||||
Mike Frizell
|
||||
Bruce Jones
|
||||
Stefano Airaghi
|
||||
Dan Eeckhout
|
||||
Alex Calderhead
|
||||
Leonard MacKey
|
||||
Heung Jin Choi
|
||||
Mike Retterer
|
||||
Keith Wood
|
||||
Viljo Liukku
|
||||
Eric Beier
|
||||
Burt Pickard-Richardson
|
||||
Helmut Renz
|
||||
Rick Harms
|
||||
Vincenzo Vavala
|
||||
Patricia Martin
|
||||
Harald Klein
|
||||
Carl Petersen
|
||||
Douglas Burkett
|
||||
Clifford Evans
|
||||
Teodor Yantchev
|
||||
Jarad Berkman
|
||||
Christian Schulz
|
||||
Gregory J Shepherd
|
||||
Michael Shellim
|
||||
Ming Wang
|
||||
Bernard Lukaschek
|
||||
Nigel Chippindale
|
||||
Mike Perkins
|
||||
Ted Hammond
|
||||
David Beanland
|
||||
Bernd Koehler
|
||||
Frédéric Duflos
|
||||
Dave Fasken
|
||||
Heinrich Illig
|
||||
Michael Collins
|
||||
Michael Manning
|
||||
Craig Lorentz
|
||||
André Lasseret
|
||||
Felipe Alexandre de Oliveira
|
||||
Brian Harris
|
||||
Philippe Herbots
|
||||
Rainer Nelte
|
||||
Franck Bernhard
|
||||
Erhard Werner
|
||||
Stig Jøran Moen
|
||||
Keith Hertzog
|
||||
Christophe Dauvergne
|
||||
Tauno Rautakorpi
|
||||
Sven Assmus
|
||||
Paul Dittman
|
||||
Mike Matheny
|
||||
Cheryl Wynne
|
||||
Emay Toha
|
||||
Don Nolder
|
||||
André Lasseret
|
||||
Filip Lowette
|
||||
Arnaldo Gabella
|
||||
Fiorenzo Agnelli
|
||||
Michele Villa
|
||||
Christophe Rodriguez
|
||||
Larisa Filocamo
|
||||
Hartmut Sahm
|
||||
Åke Brodin
|
||||
Ted Moss
|
||||
Filippos Tigarakis
|
||||
Chewytm
|
||||
Eric Burdis
|
||||
Nigel Chippindale
|
||||
Michael Deasy
|
||||
Stephen Stough
|
||||
Kenneth Lilja (monthly)
|
||||
Robert Jero
|
||||
Gary Bancroft
|
||||
Robert Cotsford
|
||||
NorthSide
|
||||
George Constandinides
|
||||
Robert Schonk Jr
|
||||
Kevin Berkefeld
|
||||
Peter Webster
|
||||
Mike Matheny
|
||||
Martin Sniedze
|
||||
Fernando Rimoldi
|
||||
Sidney Fisher
|
||||
Bruce Anderson
|
||||
John Rodgers
|
||||
Ed Pare
|
||||
Thomas Kilduff
|
||||
Robert Ferguson
|
||||
Bryan Green
|
||||
Kevin Berkefeld
|
||||
Julien Michel
|
||||
Krittikun Chiraphanda
|
||||
Douglas Law
|
||||
Alberto Scotti
|
||||
Oliver Kunkel
|
||||
D. Joseph Frazier
|
||||
Heiko Polig
|
||||
Andrew Fernie
|
||||
Marco Lange
|
||||
Nick McMillan
|
||||
Michel Baily (monthly)
|
||||
Patrick Mullen
|
||||
Scott Campbell
|
||||
Erich Roeder
|
||||
Wayne Davy
|
||||
Michael Fontenot
|
||||
Willie Swanepoel
|
||||
Satoru Sasaki
|
||||
Tyler Darby
|
||||
Nicholas Crego
|
||||
Johan Moelich
|
||||
Timo Esser
|
||||
Brian Paddock
|
||||
Jean Pierre Parisy
|
||||
Norbert Martsch
|
||||
Jean-Marie Guitard
|
||||
Tilman Baumann
|
||||
Fred Larssen
|
||||
Ari Aalto
|
||||
Robert Sams
|
||||
Kirk Robertson
|
||||
John Koontz
|
||||
Jeffery Golias
|
||||
Paul Robinson
|
||||
Dave Matison
|
||||
Mike Matheny
|
||||
Pino Agostino
|
||||
Graham Boucher
|
||||
Nelson Noura
|
||||
Joel Allamy
|
||||
Philip David Martin
|
||||
Sean Stephen
|
||||
Bruce Mackay
|
||||
Blake Spilman
|
||||
Timothy Pelletier
|
||||
Glen Roe (ShowMaster)
|
||||
Jan Van Ooteghem
|
||||
Lawrence Christensen
|
||||
Leo Duflou
|
||||
Bruce Wood
|
||||
Arnd Feige
|
||||
Tauno Rautakorpi
|
||||
Steve Coley
|
||||
Stefan Kiendl
|
||||
Gregory Nuspel
|
||||
Mitchell Brenner
|
||||
Ronnnie DePrez
|
||||
Ferenc Koller
|
||||
Robert Sessler
|
||||
Didier Lanot
|
||||
Rodney Hunt
|
||||
Steve Bernard
|
||||
Paul Nazaroff
|
||||
Gordon Ernenputsch
|
||||
Ksamak
|
||||
Marc Gittelman
|
||||
David Poole
|
||||
Ralph Sauer
|
||||
Karl-Heinz Gansel
|
||||
Michels Bernhard
|
||||
Thomas Demmelbauer
|
||||
Felice Baratto
|
||||
Michael Halse
|
||||
Horst Kampen
|
||||
Ian Gough
|
||||
Matthew Brett
|
||||
Lexington S Morley
|
||||
Clemens Drews
|
||||
Axel Stöckle
|
||||
Roberto Orsello
|
||||
Richard Ruck
|
||||
Hugh Caldwell
|
||||
Christian Marauli
|
||||
Albin Esbjörnsson
|
||||
Per Esbjörnsson
|
||||
Bernd Hohmann
|
||||
Sławomir Juszczak
|
||||
Stephen Henderson
|
||||
David Morgan
|
||||
Aloft Hobbies
|
||||
Netanel Hobara
|
||||
Cameron Galipo
|
||||
Doug Schafer
|
||||
Pietro Rossin
|
||||
Earl Killingsworth
|
||||
Victor B Wright
|
||||
Terry McKinley
|
||||
Марков Алексей
|
||||
Offer Shmuely
|
||||
Ian Lobley
|
||||
Stéphane Fortas
|
||||
Peter Mitrik
|
||||
Thomas Majewski
|
||||
ANF King
|
||||
Henrik Hammarström
|
||||
Kenneth Lilja
|
||||
R Wells
|
||||
Uwe Jordt
|
||||
Harald Wilczak
|
||||
Bernhard Lohmann
|
||||
Ferenc Koller
|
||||
Robert Ferguson
|
||||
Daniel Byers
|
||||
Tyler Darby
|
||||
Miguel Villalpando
|
||||
Kim Dong Hoon
|
||||
Terry McKinley
|
||||
Walter Bell
|
||||
Clinton Linck
|
||||
Josep Clodas Sola
|
||||
Thierry Martin
|
||||
Peter Mauro
|
||||
Mitchell Brenner
|
||||
Yak
|
||||
Lluis Bullich Rañe
|
||||
Steffen Rohr
|
||||
Eric Jacquin
|
||||
Harvest Lane
|
||||
Ville Kuvaja
|
||||
DK-System
|
||||
Heinz Vogel
|
||||
Heung Jin Choi
|
||||
MMJS van der Helm
|
||||
Dan Neelands
|
||||
Yashiro Masayuki
|
||||
Isaac Sloan
|
||||
Harold Baird
|
||||
Roy Bender
|
||||
Bradley Murchie
|
||||
Maximilian Süß
|
||||
Dean Jansa
|
||||
Ronald Donker
|
||||
Paul Oldenkamp
|
||||
Dietmar Drees
|
||||
Bradley Murchie
|
||||
Richard Fahie
|
||||
James Kaufman
|
||||
Henry Deucker
|
||||
Christian Fuchs
|
||||
Arold Reinders
|
||||
Robert Miller
|
||||
Mark Gaskievicz
|
||||
Roland Müller
|
||||
Frank Gewalt
|
||||
Remi Viard
|
||||
Reginald H Millsom
|
||||
Pierluigi Sommaruga
|
||||
A Harris
|
||||
Stefan Grunenberg
|
||||
Francisco Gutierrez Muñoz
|
||||
Steve Coley
|
||||
Sean Cull
|
||||
Roberto Orsello
|
||||
David Finger
|
||||
Jean-Marie Oddo
|
||||
Mike Matheny
|
||||
Glen Roe (Showmaster)
|
||||
Arron Bates
|
||||
Tim Spurr
|
||||
Daniel Morgan
|
||||
Trent Ready
|
||||
Mark Maskiell
|
||||
Robert Crockford
|
||||
Mark Illum
|
||||
David McGuire
|
||||
Martyn Coles
|
||||
Jose Sobral
|
||||
Heung Jin Choi
|
||||
Tomasz Janiak
|
||||
Fabien Gagné
|
||||
Joe Street
|
||||
Micha Ronen
|
||||
Albert Blondin
|
||||
Klaus Schuebel
|
||||
Evening Shade Pottery
|
||||
Thomas Kilduff
|
||||
Sven Assmus
|
||||
Markus Eberl
|
||||
Nicholas Field
|
||||
Harald Wilczak
|
||||
John Grepps
|
||||
Anthony Burbidge
|
||||
Sherba Baine
|
||||
Gordon Evans
|
||||
Fred Figge
|
||||
Uwe Kuehn
|
||||
David Beatty
|
||||
Aaron Stringer
|
||||
Alan J Wasserman
|
||||
Wolfgang Rauser
|
||||
Samuel Cook
|
||||
Friedrich Ipolt
|
||||
Barrington Cole
|
||||
Charles Lakins
|
||||
Thos. O'Meara Photography
|
||||
Adam Chevalier
|
||||
Mike Mulligan
|
||||
Serge Michaux
|
||||
Robert Young
|
||||
Wilco Hijink
|
||||
Roy Nixon
|
||||
Lexington S Morley
|
||||
Daryl Dacko
|
||||
Beat Zurflueh
|
||||
Piotr Kundu
|
||||
Kevin Berkefeld
|
||||
Tomasz Klys
|
||||
Mirco Didone'
|
||||
Christoph Schroeter
|
||||
Zdenek Trojanek
|
||||
Bryan Anderson
|
||||
Kamco Enterprises
|
||||
Robert Bates
|
||||
Robert Brown
|
||||
Dennis Marinus
|
||||
Ronald Van Putte
|
||||
Thomas Kvitle Jenssen
|
||||
Patrick Tuxbury
|
||||
Istvan Magi
|
||||
Sasaki Satoru
|
||||
David Laburthe
|
||||
Vit Jelinek
|
||||
Pablo Gomez Martinez
|
||||
Alan Thoren
|
||||
Jack Clodfelter
|
||||
William Simon
|
||||
James Houck
|
||||
Peter Fithern
|
||||
Thomas Svedman
|
||||
TechFixPros
|
||||
Rafael Eric Suarez Nordlow
|
||||
Colin Rycroft
|
||||
Emanuel Stassar
|
||||
Michael Gregory
|
||||
Robert Russell
|
||||
Felix Kaiser
|
||||
Joshua Bardwell
|
||||
Davd Goodall
|
||||
Leonard MacKey
|
||||
Miles Kelly
|
||||
Sergio Robledo
|
||||
Mikael Wallbäck
|
||||
Daniel Malcman
|
||||
Paul Dittman
|
||||
Attilio Rausse
|
||||
Sidney Gates
|
||||
Andrea Montefusco
|
||||
Paul Luby
|
||||
Donald L Webster
|
||||
Kenneth Frehafer
|
||||
Matthias Hase
|
||||
Markus Wolf
|
||||
Andrew Fazio
|
||||
Stefan Künst
|
||||
Stephen Adams
|
||||
Tauno Rautakorpi
|
||||
Frank Houvenaghel
|
||||
George Neusse
|
||||
Andreja Rusjakovski
|
||||
Axel Stöckle
|
||||
Erwin Störrle
|
||||
Rodger Hopper
|
||||
Fernando Cesar
|
||||
Jonathan Gillis
|
||||
DK-System
|
||||
Lexington S Morley
|
||||
Bernd Koehler
|
||||
Davis RC
|
||||
Pete Johnson
|
||||
Patricia Martin
|
||||
Florian Tschacher
|
||||
Brian Spearing
|
||||
Craig Hall
|
||||
Joseph Case
|
||||
Harald Klein
|
||||
Robert Crockford
|
||||
Chris Boultinghouse
|
||||
Kitsew
|
||||
Georgios Papadopoulos
|
||||
Fourmost Products
|
||||
Dennis Miller
|
||||
Dave Matison
|
||||
Maximilian Radig
|
||||
Juan Rodriguez
|
||||
Robert Sessler
|
||||
John Murray
|
||||
Martin Sniedze
|
||||
David Poole
|
||||
Manfred Delakowitz
|
||||
Martijn Kruissen
|
||||
Jörgen Norman
|
||||
Nathan Kinney
|
||||
John Godden
|
||||
Larry Roper
|
||||
Mike Frizell
|
||||
Daniel Pospolita
|
||||
Peter Herz
|
||||
Don Mondrik
|
||||
Paul Fram
|
||||
Charles Knight
|
||||
Matthew Adams
|
||||
Kenneth Reed
|
||||
Gary Wild
|
||||
Christof Ramm
|
||||
Bruno Bedard
|
||||
Salih Samim Aydin
|
||||
Alexander Pils
|
||||
Andrew Scerbina
|
||||
Donovan Bodishbaugh
|
||||
Ray Dunn
|
||||
Burt Pickard-Richardson
|
||||
Robert Ferguson
|
||||
CY Enterprise
|
||||
Michel Stathakis Neto
|
||||
Beat Zurflueh
|
||||
Portstate Pty Ltd
|
||||
Jens Hoffmann
|
||||
Ricardo Santos
|
||||
Jean-Francois Le Breton
|
||||
Michael Deasy
|
||||
Anindya Mukerjee
|
||||
Emay Toha
|
||||
Kamco Enterprises
|
||||
Peter Mueller
|
||||
Giovanni Trentini
|
||||
Cecil Porter
|
||||
Robert Canavan
|
||||
Greg Higginbottom
|
||||
Tim Walker
|
||||
Spis Ltd/TurboNote
|
||||
Patricia Cox
|
||||
Matthew Lukes
|
||||
Sabine Witte
|
||||
Phillip Perry
|
||||
Beat Zurflueh
|
||||
Russell Stutzman
|
||||
Dietmar Drees
|
||||
Kenneth Ward
|
||||
Jens Lochmüller
|
||||
Anthony Witham
|
||||
Peter Hauke
|
||||
Arizona Action Photos
|
||||
Francis F Dale
|
||||
Willie Swanepoel
|
||||
Edward Hauser
|
||||
Adilson Oliveira
|
||||
Joseph Ordille
|
||||
Michael Shellim
|
||||
Teddie Holmes
|
||||
Alexandre Rault
|
||||
Eric Albin
|
||||
Lukas Kliment
|
||||
Bernard Philippe
|
||||
Bernard Delpy
|
||||
Didier Klein
|
||||
Arnaldo Guedes
|
||||
Cyberauto Systems
|
||||
John Alsbrooks
|
||||
John Kearney
|
||||
Christopher Borden
|
||||
Marc Virgilio Ricci
|
||||
Frederick Davie
|
||||
Jürgen Enders
|
||||
Terrence Pitts
|
||||
Thomas Sandner
|
||||
Marco Coltorti
|
||||
Harald Wilczak
|
||||
Rodney Lorimor
|
||||
Richard Davis
|
||||
Stephen Palmer
|
||||
Michael Napolitan
|
||||
Joshua Bardwell
|
||||
Fred Dawson
|
||||
Jim Wagner
|
||||
Peter Johnson
|
||||
Fredrik Lewerth
|
||||
Arvin Stenersen
|
||||
Daniel Morgan
|
||||
Roy Nixon
|
||||
Joachim Blunck
|
||||
Karl-Heinz Gansel
|
||||
Monrovia Mountain Enterprises
|
||||
Alessandro Villa
|
||||
Jan-Åke Nilsson
|
||||
Matthias Rei
|
||||
DVR Solutions BV
|
||||
Bertrand Condevaux Lanloy
|
||||
Henri Mirra
|
||||
Aurélien Planiol
|
||||
Kevin Caldwell
|
||||
Andrew Garello
|
||||
Tomasz Maziarz
|
||||
Russell Flack
|
||||
Fernando Rimoldi
|
||||
Greg Reid
|
||||
Dietmar Drees
|
||||
Holger Landwehr
|
||||
Arno Loehdorf
|
||||
Boon Sripattha
|
||||
Patrik Åkerfeldt
|
||||
Alonzo Fretwell
|
||||
Renjith Chandrasekharan
|
||||
Ruben Gomez Hernandez
|
||||
Michael Gardner
|
||||
Judith Green
|
||||
Timo Ruppell
|
||||
John Lipscomb
|
||||
Norbert Wenke
|
||||
Erik Frieberg
|
||||
Raimo Ruotsalainen
|
||||
Brian Harris
|
||||
Sebastian Blüml
|
||||
Efisio Maxia
|
||||
Jeff Theobald
|
||||
Anthony Rizzo
|
||||
Rodney Huddleston
|
||||
Dietmar Drees
|
||||
Jürgen Monden
|
||||
David Morgan
|
||||
Andrew Fernie
|
||||
Donald Burke
|
||||
Ronald Donker
|
||||
Fredie Singh
|
||||
Patrizio Simoncini
|
||||
Harald Gabler
|
||||
Michael Brown
|
||||
Julien Gérard
|
||||
Alexandre d'Alton
|
||||
Peter Mergaerts
|
||||
Jan Houwers
|
||||
Christian Grandjean
|
||||
Roger Bergevin
|
||||
NorthSide
|
||||
Sigmund Martinsen
|
||||
Lionel Lafraise
|
||||
Gisli Ofeigsson
|
||||
The Gruvin9x Project
|
||||
Manuel McLure
|
||||
Fernando Rimoldi
|
||||
Hiltenkamp Stephan
|
||||
Sandeep Kishore Jain
|
||||
Greg Parker
|
||||
Norman Maaß
|
||||
Adriano Del Ben
|
||||
Justin Poole
|
||||
Kenneth Harrison
|
||||
Eugene LaFaille
|
||||
John O'Shaughnessy
|
||||
Uwe Jordt
|
||||
Stuart Olson
|
||||
Frédéric Devillard
|
||||
Cheung Leo
|
||||
Peter Webster
|
||||
Jean-Claude Bachetta
|
||||
Delfin Perena
|
||||
Sae-wook Yoon
|
||||
Focus on Excellence
|
||||
Jeffery Golias
|
||||
Nick Milton
|
||||
Paul Zasso
|
||||
Reidar Johannes Lillebotn
|
||||
Handley William
|
||||
Luke Williams
|
||||
Michael Shellim
|
||||
Brian Spearing
|
||||
Derek Foster
|
||||
Pasi Pitkänen
|
||||
Lexington S Morley
|
||||
Jeff Roberson
|
||||
Volkov Victor
|
||||
Bryan Anderson
|
||||
Daniel Garber
|
||||
Pavel Stein
|
||||
Ravi Gupta
|
||||
Patrick Tuxbury
|
||||
Mark Deverell
|
||||
John Capell
|
||||
Neil McVean
|
||||
Matthew Elyash
|
||||
Kerry Cochrell
|
||||
Willem Aandewiel
|
||||
Reg Bell
|
||||
Jean Chenoz
|
||||
Philippe Grand
|
||||
Tauno Rautakorpi
|
||||
Jeff Dillingham
|
||||
Brad Kelley
|
||||
Shaun Currier
|
||||
Danilo Schiara
|
||||
John Hennig
|
||||
RK Custom Homes
|
||||
James Houck
|
||||
Piet Teekens
|
||||
Tommy Widenflycht
|
||||
Johan Petrus Theophilus
|
||||
Maria van Melis
|
||||
Ralph Gustafson
|
||||
Paul Luby
|
||||
Andrew Duncan
|
||||
Stephen Crowther
|
||||
Edward Glover
|
||||
Kelly Byrd
|
||||
Brad Curtis
|
||||
Wolfgang Kuhl
|
||||
John Beidl
|
||||
Roy Nixon
|
||||
Glen Roe
|
||||
CY Enterprise
|
||||
Evening Shade Pottery
|
||||
Gilles Dando
|
||||
Patrick Richard
|
||||
Justin Altemeier
|
||||
Constant Dupuis
|
||||
Tony Kenward
|
||||
Pierre Rondel
|
||||
Ernest Luguera Sanchez
|
||||
Adam Brackney
|
||||
Joe Baker
|
||||
单 雷平
|
||||
Ben Fay
|
||||
Chris Monk
|
||||
Stan von Miller
|
||||
Christian Krebs
|
||||
Michel Motte
|
||||
Graziano Rampinelli
|
||||
Joe Baker
|
||||
Jean-Philippe Laurent
|
||||
Romain Rouzaud
|
||||
Michel Garbarino
|
||||
Henri Mirra
|
||||
Otto Fröhlich
|
||||
Thomas Cramer
|
||||
Anthony Trombetta
|
||||
Fernando Rimoldi
|
||||
Dietmar Drees
|
||||
Michal Kowalski
|
||||
Ivan Correa
|
||||
Modellbau
|
||||
Massimo Luigi Stara
|
||||
Graham Baldwin
|
||||
Tomasz Rejman
|
||||
Wolfgang Lang
|
||||
John Greenwood
|
||||
Till von Reumont
|
||||
Paul Pereira Brunner
|
||||
Donald L Singer
|
||||
Junsun Lee
|
||||
Guy Lamaison
|
||||
Erwin Dulken
|
||||
Mike H Dailey
|
||||
Jon Cammarata
|
||||
Martin Krueger
|
||||
Adolfo Perogio
|
||||
Sylvain Techer
|
||||
Wes Warner
|
||||
Kevin Caldwell
|
||||
Ali Ersan Gur
|
||||
Hans-Rudolf Riniker
|
||||
Sébastien Boutard
|
||||
Jean Chessé
|
||||
Mike H Dailey
|
||||
Don Polk
|
||||
Roberto Orsello
|
||||
Borovikov Dmitriy
|
||||
John Lipscomb
|
||||
Peter Glassey
|
||||
Joseph Kramer
|
||||
F.Javier Martinez Velasco
|
||||
Claudio Piccinini
|
||||
John Jackson
|
||||
John Beech
|
||||
Rene TraaJohn Jackson
|
||||
Sebastien Charpentier (monthly)
|
||||
Nigel Hendriks
|
||||
Frédéric Devillard
|
||||
Albert Herzog
|
||||
Anindya Mukerjee
|
||||
Kenny Stanberry
|
||||
Tauno Rautakorpi
|
||||
Mathias Krapp
|
||||
Fernando Rimoldi
|
||||
Wolfgang Rauser
|
||||
Richard Shagam
|
||||
Stephen Bailey
|
||||
DK-System
|
||||
Casa Kuxtal
|
||||
Christopher Potts
|
||||
Douglas George
|
||||
Michael Banks
|
||||
Jon Wiltshire
|
||||
David Green
|
||||
Guy Willems
|
||||
Xavier Mestelan Pinon
|
||||
Maik Gottschalk
|
||||
Scott Sparks
|
||||
John Dunning
|
||||
RAD51
|
||||
Ron Powell
|
||||
Alain Labonne
|
||||
Carol Sills
|
||||
Franck Aßmann
|
||||
Larry Anderson
|
||||
Mikael Wallbäck
|
||||
Wes Warner
|
||||
Christoffer H Henni
|
||||
Donna Bayer
|
||||
Garry Ogilvie
|
||||
Karlheinz Sirsch
|
||||
Fred Larssen
|
||||
Rob Coppock
|
||||
Franz Josef Hahn
|
||||
Serge Ribault
|
||||
Tanguy Le Moign
|
||||
Barrett Powell
|
||||
Patrice Lafeuille
|
||||
Martin Blume
|
||||
Marek Kopyto
|
||||
Marco Lange
|
||||
Gary Nix
|
||||
Jack Oliphant
|
||||
John Lever
|
||||
Adolphe Montefiore
|
||||
Steven De Weerdt
|
||||
Håkan Berggen
|
||||
Ayelet Egosi
|
||||
Jean-Frederic Gaudreault
|
||||
Jim Wagner
|
||||
Lee Scott
|
||||
Roger Keatley
|
||||
Sherman Lovell
|
||||
Hugh Caldwell
|
||||
JB Fisher Company
|
||||
Michels Bernhard
|
||||
Pietro Rossin
|
||||
Carsten Wache
|
||||
Brock White
|
||||
Steven Poretz
|
||||
David Huelster
|
||||
Gordon Stahl (monthly)
|
||||
John Mathison
|
||||
Richard Duczmal
|
||||
Gregory Barron
|
||||
Marcel Fischer
|
||||
Klas Mälman
|
||||
Viljo Liukku
|
||||
Eric Smith
|
||||
Sven Assmus
|
||||
Luke Mole
|
||||
NorthSide
|
||||
Hannes Mössler
|
||||
James Kaufman
|
||||
Ravi Gupta
|
||||
Lexington S Morley
|
||||
Ralph Segar
|
||||
Frédéric Devillard
|
||||
Cory Theurer
|
||||
Valentinos Zachariou
|
||||
Garrett Paquette
|
||||
Heung Jin Choi
|
||||
Kerry Cochrell
|
||||
Doug Miller
|
||||
Andrzej Weydmann
|
||||
Chair-man.nl
|
||||
Eric Beier
|
||||
Jay Warren
|
||||
Marian Matej
|
||||
Alastair Smith
|
||||
Timothy Senecal
|
||||
Dietmar Drees
|
||||
Bruce Jones
|
||||
Adil Busaidy
|
||||
Herman Hofman
|
||||
Jean Paul Michel
|
||||
Peter McHenry
|
||||
Julien lecoquierre
|
||||
Jean-Marie Clay
|
||||
Robert Nicoll
|
||||
Dan Nixon
|
||||
Ewald Moehring
|
||||
Giovanni Carnesecchi
|
||||
Paul Dumsday
|
||||
Tadeusz Adamowski
|
||||
Andrew Newton
|
||||
Neil Horne
|
||||
Kerstin Appelqvist
|
||||
@@ -1,9 +1,52 @@
|
||||
##OpenTX 2.2 Branch
|
||||
# FlySky i6x port of OpenTX
|
||||
|
||||
[](https://travis-ci.org/opentx/opentx)
|
||||
[](https://opentx.rocket.chat)
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DJ9MASSKVW8WN)
|
||||
This is a port of OpenTX for the venerable Flysky I6X RC radio transmitter. You can find the latest build and some instructions and videos contributed by fellow early adopters in the [RCGroups thread](https://www.rcgroups.com/forums/showthread.php?3916435-FlySky-I6X-port-of-OpenTX)
|
||||
|
||||
The ongoing development on 2.2.x is done in this branch.
|
||||
## Implemented features
|
||||
|
||||
Refer to the opentx.wiki for information about setting up the tool chains for building OpenTX and OpenTX Companion as well as other development related issues.
|
||||
* AFHDS2A protocol
|
||||
* PPM out
|
||||
* CRSF working with ExpressLRS and Crossfire modules at rates from 115k to 3.75M bauds, CRSFshot enabled
|
||||
* Telemetry
|
||||
* Audio tones, alarms and vario custom implementation (Janek)
|
||||
* USB (To enable on standard cable: General Settings > USB Detect set to "Once") (Janek)
|
||||
* Joystick mode (Janek)
|
||||
* Mass Storage to backup/restore eeprom (Janek)
|
||||
* ExpressLRS V1.x configuration in model setup
|
||||
|
||||
## Users Telegram group
|
||||
|
||||
https://t.me/otx_flysky_i6x
|
||||
|
||||
## Navigation:
|
||||
|
||||
| Key | Function |
|
||||
| --- | --- |
|
||||
| UP | Hold for stats |
|
||||
| DOWN | Hold for telemetry |
|
||||
| OK | Hold for Model menu |
|
||||
| CANCEL | EXIT. Hold for graceful shutdown (Needed to save timers) |
|
||||
| BIND | Go RIGHT. Go to next PAGE. Hold for general menu. |
|
||||
| RIGHT POT | Scroll right or left |
|
||||
|
||||
## ST-Link pinout
|
||||
|
||||

|
||||
|
||||
## Linux instructions
|
||||
### Compile
|
||||
`docker run --rm -it -e "BOARD_NAME=I6X" -e "CMAKE_FLAGS=PCB=I6X HELI=NO GVARS=NO LUA_COMPILER=NO MULTIMODULE=NO DEBUG=YES" -v $PWD:/opentx vitass/opentx-fw-build`
|
||||
|
||||
### Flash
|
||||
`sudo st-flash write <file_to_flash>.bin 0x08000000`
|
||||
|
||||
### Debug tty:
|
||||
`sudo cat /dev/ttyUSB0 115200`
|
||||
|
||||
## Contributors
|
||||
|
||||
* Janek (@ajjjjjjjj) ongoing collaboration.
|
||||
* All the RF code was taken from the great KotelloRC's erfly6: Er9X for i6 and i6x. You can find his project here: https://bitbucket.org/KotelloRC/erfly6/src/master/
|
||||
* ADC code taken from OpenGround: https://github.com/fishpepper/OpenGround
|
||||
* This work is based on Jakub's (qba667) work and is forked from his repo.
|
||||
* All the contributors of OpenTX.
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@ macro(add_bitmaps_target targetname filter width format)
|
||||
set(target ${target}.lbm)
|
||||
add_custom_command(
|
||||
OUTPUT ${target}
|
||||
COMMAND python ${RADIO_DIRECTORY}/util/img2lbm.py ${bitmap} ${target} ${width} ${format} ${ARGN}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/img2lbm.py ${bitmap} ${target} ${width} ${format} ${ARGN}
|
||||
DEPENDS ${bitmap}
|
||||
)
|
||||
list(APPEND bitmaps_files ${target})
|
||||
@@ -14,11 +14,11 @@ macro(add_bitmaps_target targetname filter width format)
|
||||
add_custom_target(${targetname} DEPENDS ${bitmaps_files})
|
||||
endmacro(add_bitmaps_target)
|
||||
|
||||
macro(add_truetype_font_target radio name font size bold)
|
||||
macro(add_truetype_font_target radio name font size offset)
|
||||
set(target ${RADIO_SRC_DIRECTORY}/fonts/${radio}/font_${name})
|
||||
add_custom_target(ttf_${radio}_${name}
|
||||
COMMAND ${RADIO_DIRECTORY}/util/font2png.py ${font} ${size} ${bold} ${target}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/font2png.py ${font} ${size} ${offset} ${target}
|
||||
WORKING_DIRECTORY ${RADIO_SRC_DIRECTORY}
|
||||
)
|
||||
set(ttf_${radio}_fonts_targets ${ttf_${radio}_fonts_targets} ttf_${radio}_${name})
|
||||
endmacro(add_truetype_font_target)
|
||||
endmacro(add_truetype_font_target)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# Locate lupdate binary from QT
|
||||
|
||||
# This module defines
|
||||
# LUPDATE_EXECUTABLE, where is QT lupdate
|
||||
# LUPDATE_FOUND, if false, don't try to use lupdate
|
||||
|
||||
FIND_PROGRAM( LUPDATE_EXECUTABLE
|
||||
NAMES
|
||||
lupdate lupdate-qt4
|
||||
)
|
||||
|
||||
MESSAGE( STATUS ${LUPDATE_EXECUTABLE} )
|
||||
|
||||
# if the program is found then we have it
|
||||
IF( LUPDATE_EXECUTABLE )
|
||||
SET( LUPDATE_FOUND "YES" )
|
||||
ENDIF( LUPDATE_EXECUTABLE )
|
||||
|
||||
MARK_AS_ADVANCED( LUPDATE_EXECUTABLE )
|
||||
@@ -0,0 +1,256 @@
|
||||
#.rst:
|
||||
# FindSDL
|
||||
# -------
|
||||
#
|
||||
# Locate SDL library
|
||||
#
|
||||
# This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDL_FOUND, if false, do not try to link to SDL
|
||||
# SDL_LIBRARY, the name(s) of the library(ies) to link against
|
||||
# SDL_LIBSDL, the full path and name of libSDL (or SDL.[lib|dll].
|
||||
# SDL_LIBSDLMAIN, full path and name of libSDLmain (or SDLmain.lib).
|
||||
# SDL_LIBRARY_PATH, the full path to the found libSDL
|
||||
# SDL_INCLUDE_DIR, where to find SDL.h
|
||||
# SDL_VERSION_STRING, human-readable string containing the version of SDL
|
||||
#
|
||||
#
|
||||
#
|
||||
# This module responds to the flag:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# SDL_BUILDING_LIBRARY
|
||||
# If this is defined, then no SDL_main will be linked in because
|
||||
# only applications need main().
|
||||
# Otherwise, it is assumed you are building an application and this
|
||||
# module will attempt to locate and set the proper link flags
|
||||
# as part of the returned SDL_LIBRARY variable.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDLmain which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
#
|
||||
#
|
||||
#
|
||||
# Additional Note: If you see an empty SDL_LIBSDL in your
|
||||
# configuration and no SDL_LIBRARY, it means CMake did not find your SDL
|
||||
# library (SDL.dll, libsdl.so, SDL.framework, etc). Set
|
||||
# SDL_LIBSDL to point to your SDL library, and configure again.
|
||||
# Similarly, if you see an empty SDL_LIBSDLMAIN, you should set this
|
||||
# value as appropriate. These values are used to generate the final
|
||||
# SDL_LIBRARY variable, but when these values are unset, SDL_LIBRARY
|
||||
# does not get created.
|
||||
#
|
||||
#
|
||||
#
|
||||
# $SDLDIR is an environment variable that would correspond to the
|
||||
# ./configure --prefix=$SDLDIR used in building SDL. l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing. Added code to assist with automated building
|
||||
# by using environmental variables and providing a more
|
||||
# controlled/consistent search behavior. Added new modifications to
|
||||
# recognize OS X frameworks and additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL
|
||||
# guidelines. Added a search for SDLmain which is needed by some
|
||||
# platforms. Added a search for threads which is needed by some
|
||||
# platforms. Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of SDL_LIBRARY to
|
||||
# override this selection or set the CMake environment
|
||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
||||
#
|
||||
# Note that the header path has changed from SDL/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention is #include
|
||||
# "SDL.h", not <SDL/SDL.h>. This is done for portability reasons
|
||||
# because not all systems place things in SDL/ (see FreeBSD).
|
||||
|
||||
#
|
||||
# Modified for OpenTx by Maxim Paperno 19-Dec-2016
|
||||
# Added SDL_LIBSDL, SDL_LIBSDLMAIN & SDL_LIBRARY_PATH, removed SDLMAIN_LIBRARY,
|
||||
# SDL_LIBRARY_TEMP, and fixed bug with recursive appending of supporting
|
||||
# libraries to cached SDL_LIBRARY_TEMP variable.
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
#CMake - Cross Platform Makefile Generator
|
||||
#Copyright 2000-2015 Kitware, Inc.
|
||||
#Copyright 2000-2011 Insight Software Consortium
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions
|
||||
#are met:
|
||||
#
|
||||
#* Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#* Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
#The above copyright and license notice applies to distributions of
|
||||
#CMake in source and binary form. Some source files contain additional
|
||||
#notices of original copyright by their contributors; see each source
|
||||
#for details. Third-party software packages supplied with CMake under
|
||||
#compatible licenses provide their own copyright notices documented in
|
||||
#corresponding subdirectories.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
#CMake was initially developed by Kitware with the following sponsorship:
|
||||
#
|
||||
# * National Library of Medicine at the National Institutes of Health
|
||||
# as part of the Insight Segmentation and Registration Toolkit (ITK).
|
||||
#
|
||||
# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
|
||||
# Visualization Initiative.
|
||||
#
|
||||
# * National Alliance for Medical Image Computing (NAMIC) is funded by the
|
||||
# National Institutes of Health through the NIH Roadmap for Medical Research,
|
||||
# Grant U54 EB005149.
|
||||
#
|
||||
# * Kitware, Inc.
|
||||
#=============================================================================
|
||||
|
||||
|
||||
find_path(SDL_INCLUDE_DIR SDL.h
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES SDL SDL12 SDL11
|
||||
# path suffixes to search inside ENV{SDLDIR}
|
||||
include/SDL include/SDL12 include/SDL11 include
|
||||
)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(VC_LIB_PATH_SUFFIX lib/x64)
|
||||
else()
|
||||
set(VC_LIB_PATH_SUFFIX lib/x86)
|
||||
endif()
|
||||
|
||||
# SDL-1.1 is the name used by FreeBSD ports...
|
||||
# don't confuse it for the version number.
|
||||
find_library(SDL_LIBSDL
|
||||
NAMES SDL SDL-1.1
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
)
|
||||
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||
# seem to provide SDLmain for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
find_library(SDL_LIBSDLMAIN
|
||||
NAMES SDLmain SDLmain-1.1
|
||||
HINTS
|
||||
ENV SDLDIR
|
||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
||||
PATHS
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
# SDL may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
if(NOT APPLE)
|
||||
find_package(Threads)
|
||||
endif()
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL
|
||||
if(MINGW)
|
||||
set(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
endif()
|
||||
|
||||
if(SDL_LIBSDL)
|
||||
# For SDLmain
|
||||
if(SDL_LIBSDLMAIN AND NOT SDL_BUILDING_LIBRARY AND NOT SDL_INCLUDE_DIR MATCHES ".framework")
|
||||
list(FIND SDL_LIBSDL "${SDL_LIBSDLMAIN}" _SDL_MAIN_INDEX)
|
||||
if(_SDL_MAIN_INDEX EQUAL -1)
|
||||
list(APPEND _SDL_LIBRARY_TEMP "${SDL_LIBSDLMAIN}")
|
||||
endif()
|
||||
unset(_SDL_MAIN_INDEX)
|
||||
endif()
|
||||
|
||||
list(APPEND _SDL_LIBRARY_TEMP "${SDL_LIBSDL}")
|
||||
|
||||
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there if I modify a pre-used variable.
|
||||
# I think it has something to do with the CACHE STRING.
|
||||
# So I use a temporary variable until the end so I can set the
|
||||
# "real" variable in one-shot.
|
||||
if(APPLE)
|
||||
list(APPEND _SDL_LIBRARY_TEMP "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
if(Threads_FOUND)
|
||||
list(APPEND _SDL_LIBRARY_TEMP ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL
|
||||
if(MINGW)
|
||||
list(INSERT 0 _SDL_LIBRARY_TEMP mingw32)
|
||||
endif()
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
set(SDL_LIBRARY ${_SDL_LIBRARY_TEMP} CACHE STRING "Full list of required SDL & supporting libraries.")
|
||||
unset(_SDL_LIBRARY_TEMP)
|
||||
|
||||
get_filename_component(_SDL_LIBRARY_TEMP ${SDL_LIBSDL} PATH)
|
||||
set(SDL_LIBRARY_PATH ${_SDL_LIBRARY_TEMP} CACHE PATH "Path to SDL library.")
|
||||
unset(_SDL_LIBRARY_TEMP)
|
||||
endif()
|
||||
|
||||
if(SDL_INCLUDE_DIR AND EXISTS "${SDL_INCLUDE_DIR}/SDL_version.h")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
|
||||
file(STRINGS "${SDL_INCLUDE_DIR}/SDL_version.h" SDL_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}")
|
||||
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}")
|
||||
set(SDL_VERSION_STRING ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH})
|
||||
unset(SDL_VERSION_MAJOR_LINE)
|
||||
unset(SDL_VERSION_MINOR_LINE)
|
||||
unset(SDL_VERSION_PATCH_LINE)
|
||||
unset(SDL_VERSION_MAJOR)
|
||||
unset(SDL_VERSION_MINOR)
|
||||
unset(SDL_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
|
||||
REQUIRED_VARS SDL_LIBRARY SDL_LIBRARY_PATH SDL_INCLUDE_DIR
|
||||
VERSION_VAR SDL_VERSION_STRING)
|
||||
@@ -1,159 +0,0 @@
|
||||
# - Locate the SDL library
|
||||
# This module defines
|
||||
# SDL_LIBRARY, the library to link against
|
||||
# SDL_FOUND, if false, do not try to link to SDL
|
||||
# SDL_INCLUDE_DIR, where to find SDL.h
|
||||
#
|
||||
# Don't forget to include SDLmain.h and SDLmain.m your project for the
|
||||
# OS X framework based version. (Other versions link to -lSDLmain which
|
||||
# this module will try to find on your behalf.) Also for OS X, this
|
||||
# module will automatically add the -framework Cocoa on your behalf.
|
||||
# $SDLDIR is an environment variable that would
|
||||
# correspond to the ./configure --prefix=$SDLDIR
|
||||
# used in building SDL.
|
||||
# l.e.galup 9-20-02
|
||||
#
|
||||
# Modified by Eric Wing.
|
||||
# Added new modifications to recognize OS X frameworks and
|
||||
# additional Unix paths (FreeBSD, etc).
|
||||
# Also corrected the header search path to follow "proper" SDL guidelines.
|
||||
# Added a search for SDLmain which is needed by some platforms.
|
||||
# Added a search for threads which is needed by some platforms.
|
||||
# Added needed compile switches for MinGW.
|
||||
#
|
||||
# On OSX, this will prefer the Framework version (if found) over others.
|
||||
# People will have to manually change the cache values of
|
||||
# SDL_LIBRARY to override this selection.
|
||||
#
|
||||
# Note that the header path has changed from SDL/SDL.h to just SDL.h
|
||||
# This needed to change because "proper" SDL convention
|
||||
# is #include "SDL.h", not <SDL/SDL.h>. This is done for portability
|
||||
# reasons because not all systems place things in SDL/ (see FreeBSD).
|
||||
FIND_PATH(SDL_INCLUDE_DIR SDL.h
|
||||
$ENV{SDLDIR}/include
|
||||
~/Library/Frameworks/SDL.framework/Headers
|
||||
/Library/Frameworks/SDL.framework/Headers
|
||||
/usr/local/include/SDL
|
||||
/usr/include/SDL
|
||||
/usr/local/include/SDL12
|
||||
/usr/local/include/SDL11 # FreeBSD ports
|
||||
/usr/include/SDL12
|
||||
/usr/include/SDL11
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/sw/include/SDL # Fink
|
||||
/sw/include
|
||||
/opt/local/include/SDL # DarwinPorts
|
||||
/opt/local/include
|
||||
/opt/csw/include/SDL # Blastwave
|
||||
/opt/csw/include
|
||||
/opt/include/SDL
|
||||
/opt/include
|
||||
C:/Programs/SDL/include
|
||||
)
|
||||
# I'm not sure if I should do a special casing for Apple. It is
|
||||
# unlikely that other Unix systems will find the framework path.
|
||||
# But if they do ([Next|Open|GNU]Step?),
|
||||
# do they want the -framework option also?
|
||||
IF(${SDL_INCLUDE_DIR} MATCHES ".framework")
|
||||
# The Cocoa framework must be linked into SDL because SDL is Cocoa based.
|
||||
# Remember that the OS X framework version expects you to drop in
|
||||
# SDLmain.h and SDLmain.m directly into your project.
|
||||
# (Cocoa link moved to bottom of this script.)
|
||||
# SET (SDL_LIBRARY "-framework SDL -framework Cocoa" CACHE STRING "SDL framework for OSX")
|
||||
# SET(SDL_LIBRARY "-framework SDL" CACHE STRING "SDL framework for OSX")
|
||||
# Extract the path the framework resides in so we can use it for the -F flag
|
||||
STRING(REGEX REPLACE "(.*)/.*\\.framework/.*" "\\1" SDL_FRAMEWORK_PATH_TEMP ${SDL_INCLUDE_DIR})
|
||||
IF("${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/Library/Frameworks"
|
||||
OR "${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/System/Library/Frameworks"
|
||||
)
|
||||
# String is in default search path, don't need to use -F
|
||||
SET(SDL_LIBRARY_TEMP "-framework SDL")
|
||||
ELSE("${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/Library/Frameworks"
|
||||
OR "${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/System/Library/Frameworks"
|
||||
)
|
||||
# String is not /Library/Frameworks, need to use -F
|
||||
SET(SDL_LIBRARY_TEMP "-F${SDL_FRAMEWORK_PATH_TEMP} -framework SDL")
|
||||
ENDIF("${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/Library/Frameworks"
|
||||
OR "${SDL_FRAMEWORK_PATH_TEMP}" STREQUAL "/System/Library/Frameworks"
|
||||
)
|
||||
# Clear the temp variable so nobody can see it
|
||||
SET(SDL_FRAMEWORK_PATH_TEMP "" CACHE INTERNAL "")
|
||||
|
||||
ELSE(${SDL_INCLUDE_DIR} MATCHES ".framework")
|
||||
# SDL-1.1 is the name used by FreeBSD ports...
|
||||
# don't confuse it for the version number.
|
||||
FIND_LIBRARY(SDL_LIBRARY_TEMP
|
||||
NAMES SDL SDL-1.1
|
||||
PATHS
|
||||
$ENV{SDLDIR}/lib
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
C:/Programs/SDL/lib/x86
|
||||
)
|
||||
# Non-OS X framework versions expect you to also dynamically link to
|
||||
# SDLmain. This is mainly for Windows and OS X. Other platforms
|
||||
# seem to provide SDLmain for compatibility even though they don't
|
||||
# necessarily need it.
|
||||
FIND_LIBRARY(SDLMAIN_LIBRARY
|
||||
NAMES SDLmain SDLmain-1.1
|
||||
PATHS
|
||||
$ENV{SDLDIR}/lib
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
/opt/csw/lib
|
||||
/opt/lib
|
||||
)
|
||||
ENDIF(${SDL_INCLUDE_DIR} MATCHES ".framework")
|
||||
|
||||
# SDL may require threads on your system.
|
||||
# The Apple build may not need an explicit flag because one of the
|
||||
# frameworks may already provide it.
|
||||
# But for non-OSX systems, I will use the CMake Threads package.
|
||||
IF(NOT APPLE)
|
||||
FIND_PACKAGE(Threads)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# MinGW needs an additional library, mwindows
|
||||
# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -lmwindows
|
||||
# (Actually on second look, I think it only needs one of the m* libraries.)
|
||||
IF(MINGW)
|
||||
SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
|
||||
ENDIF(MINGW)
|
||||
|
||||
SET(SDL_FOUND "NO")
|
||||
IF(SDL_LIBRARY_TEMP)
|
||||
# For SDLmain
|
||||
IF(SDLMAIN_LIBRARY)
|
||||
SET(SDL_LIBRARY_TEMP ${SDLMAIN_LIBRARY} ${SDL_LIBRARY_TEMP})
|
||||
ENDIF(SDLMAIN_LIBRARY)
|
||||
|
||||
# For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
|
||||
# CMake doesn't display the -framework Cocoa string in the UI even
|
||||
# though it actually is there. I think it has something to do
|
||||
# with the CACHE STRING. Maybe somebody else knows how to fix this.
|
||||
# The problem is mainly cosmetic, and not a functional issue.
|
||||
IF(APPLE)
|
||||
SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} "-framework Cocoa")
|
||||
ENDIF(APPLE)
|
||||
|
||||
# For threads, as mentioned Apple doesn't need this.
|
||||
# In fact, there seems to be a problem if Find the threads package
|
||||
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||
IF(NOT APPLE)
|
||||
SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
# Set the final string here so the GUI reflects the final state.
|
||||
SET(SDL_LIBRARY ${SDL_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
|
||||
|
||||
SET(SDL_FOUND "YES")
|
||||
ENDIF(SDL_LIBRARY_TEMP)
|
||||
|
||||
MARK_AS_ADVANCED(SDL_LIBRARY_TEMP)
|
||||
+67
-67
@@ -1,68 +1,68 @@
|
||||
# Find Xerces-C
|
||||
# The following setings are defined
|
||||
# XERCESC_ROOT_DIR, the root of the include and lib directory
|
||||
# XERCESC_INCLUDE_DIR, the full path of the include dir (ADVANCED)
|
||||
# XERCESC_LIBRARIES, the name of the xerces-c library (ADVANCED)
|
||||
|
||||
# Look for a root installation
|
||||
IF( MSVC )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces-vc )
|
||||
ELSE( )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PATH(XERCESC_ROOT_DIR include/xercesc/parsers/SAXParser.hpp
|
||||
${XERCES_WINDIR}
|
||||
"C:/mingw/msys/1.0/local"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2"
|
||||
/usr
|
||||
/usr/local
|
||||
"C:/MinGW"
|
||||
$ENV{CODESYNTH}
|
||||
DOC "The root of an installed xerces-c installation"
|
||||
)
|
||||
|
||||
# try to find the header
|
||||
FIND_PATH(XERCESC_INCLUDE_DIR xercesc/parsers/SAXParser.hpp
|
||||
${XERCESC_ROOT_DIR}/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Find the library
|
||||
FIND_LIBRARY(XERCESC_LIBRARY
|
||||
NAMES xerces-c xerces-c_3
|
||||
PATHS
|
||||
${XERCESC_ROOT_DIR}/lib
|
||||
${XERCESC_ROOT_DIR}/lib/vc-9.0
|
||||
${XERCESC_ROOT_DIR}/lib64/vc-9.0
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
DOC "The name of the xerces-c library"
|
||||
)
|
||||
|
||||
IF (XERCESC_ROOT_DIR)
|
||||
IF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
SET (XERCESC_FOUND TRUE)
|
||||
SET (XERCESC_LIBRARIES "${XERCESC_LIBRARY}")
|
||||
# FIXME: There should be a better way of handling this?
|
||||
# FIXME: How can we test to see if the lib dir isn't
|
||||
# FIXME: one of the default dirs?
|
||||
LINK_DIRECTORIES(${XERCESC_ROOT_DIR}/lib)
|
||||
ENDIF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
ENDIF (XERCESC_ROOT_DIR)
|
||||
|
||||
IF (XERCESC_FOUND)
|
||||
IF (NOT XERCESC_FIND_QUIETLY)
|
||||
MESSAGE (STATUS " found xerces-c: ${XERCESC_LIBRARY}")
|
||||
ENDIF (NOT XERCESC_FIND_QUIETLY)
|
||||
ELSE (XERCESC_FOUND)
|
||||
IF (XERCESC_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Xerces-C")
|
||||
ENDIF (XERCESC_FIND_REQUIRED)
|
||||
ENDIF (XERCESC_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XERCESC_INCLUDE_DIR
|
||||
XERCESC_LIBRARY
|
||||
# Find Xerces-C
|
||||
# The following setings are defined
|
||||
# XERCESC_ROOT_DIR, the root of the include and lib directory
|
||||
# XERCESC_INCLUDE_DIR, the full path of the include dir (ADVANCED)
|
||||
# XERCESC_LIBRARIES, the name of the xerces-c library (ADVANCED)
|
||||
|
||||
# Look for a root installation
|
||||
IF( MSVC )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces-vc )
|
||||
ELSE( )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PATH(XERCESC_ROOT_DIR include/xercesc/parsers/SAXParser.hpp
|
||||
${XERCES_WINDIR}
|
||||
"C:/mingw/msys/1.0/local"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2"
|
||||
/usr
|
||||
/usr/local
|
||||
"C:/MinGW"
|
||||
$ENV{CODESYNTH}
|
||||
DOC "The root of an installed xerces-c installation"
|
||||
)
|
||||
|
||||
# try to find the header
|
||||
FIND_PATH(XERCESC_INCLUDE_DIR xercesc/parsers/SAXParser.hpp
|
||||
${XERCESC_ROOT_DIR}/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Find the library
|
||||
FIND_LIBRARY(XERCESC_LIBRARY
|
||||
NAMES xerces-c xerces-c_3
|
||||
PATHS
|
||||
${XERCESC_ROOT_DIR}/lib
|
||||
${XERCESC_ROOT_DIR}/lib/vc-9.0
|
||||
${XERCESC_ROOT_DIR}/lib64/vc-9.0
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
DOC "The name of the xerces-c library"
|
||||
)
|
||||
|
||||
IF (XERCESC_ROOT_DIR)
|
||||
IF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
SET (XERCESC_FOUND TRUE)
|
||||
SET (XERCESC_LIBRARIES "${XERCESC_LIBRARY}")
|
||||
# FIXME: There should be a better way of handling this?
|
||||
# FIXME: How can we test to see if the lib dir isn't
|
||||
# FIXME: one of the default dirs?
|
||||
LINK_DIRECTORIES(${XERCESC_ROOT_DIR}/lib)
|
||||
ENDIF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
ENDIF (XERCESC_ROOT_DIR)
|
||||
|
||||
IF (XERCESC_FOUND)
|
||||
IF (NOT XERCESC_FIND_QUIETLY)
|
||||
MESSAGE (STATUS " found xerces-c: ${XERCESC_LIBRARY}")
|
||||
ENDIF (NOT XERCESC_FIND_QUIETLY)
|
||||
ELSE (XERCESC_FOUND)
|
||||
IF (XERCESC_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Xerces-C")
|
||||
ENDIF (XERCESC_FIND_REQUIRED)
|
||||
ENDIF (XERCESC_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XERCESC_INCLUDE_DIR
|
||||
XERCESC_LIBRARY
|
||||
)
|
||||
+51
-15
@@ -1,14 +1,13 @@
|
||||
macro(today RESULT)
|
||||
if(WIN32)
|
||||
execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..)/(..)/(....).*" "\\1.\\2.\\3" ${RESULT} ${${RESULT}})
|
||||
string(SUBSTRING ${${RESULT}} 0 10 ${RESULT})
|
||||
string(REGEX REPLACE "[^0-9]*([0-9]+)[^0-9]([0-9]+)[^0-9]([0-9]+).*" "\\1-\\2-\\3" ${RESULT} ${${RESULT}})
|
||||
elseif(UNIX)
|
||||
execute_process(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(....)-(..)-(..).*" "\\1-\\2-\\3" ${RESULT} ${${RESULT}})
|
||||
else(WIN32)
|
||||
message(SEND_ERROR "date not implemented")
|
||||
set(${RESULT} 00.00.0000)
|
||||
message(WARNING "date not implemented")
|
||||
set(${RESULT} 00-00-0000)
|
||||
endif(WIN32)
|
||||
endmacro(today)
|
||||
|
||||
@@ -20,20 +19,57 @@ macro(now RESULT)
|
||||
execute_process(COMMAND "date" "+%H:%M:%S" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(..):(..):(..).*" "\\1:\\2:\\3" ${RESULT} ${${RESULT}})
|
||||
else(WIN32)
|
||||
message(SEND_ERROR "time not implemented")
|
||||
message(WARNING "time not implemented")
|
||||
set(${RESULT} 00:00:00)
|
||||
endif(WIN32)
|
||||
endmacro(now)
|
||||
|
||||
find_package(Git)
|
||||
|
||||
macro(git_id RESULT)
|
||||
if(WIN32)
|
||||
execute_process(COMMAND "cmd" " /C git --git-dir=${PROJECT_SOURCE_DIR}/.git rev-parse HEAD" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}})
|
||||
elseif(UNIX)
|
||||
execute_process(COMMAND "git" "--git-dir=${PROJECT_SOURCE_DIR}/.git" "rev-parse" "HEAD" OUTPUT_VARIABLE ${RESULT})
|
||||
string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${${RESULT}})
|
||||
else(WIN32)
|
||||
message(SEND_ERROR "Git ID implemented")
|
||||
set(${RESULT} 0)
|
||||
endif(WIN32)
|
||||
set(${RESULT} 0)
|
||||
if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" "--git-dir=${PROJECT_SOURCE_DIR}/.git" "rev-parse" "--short=8" "HEAD" OUTPUT_VARIABLE proc_out ERROR_VARIABLE proc_err)
|
||||
if(proc_err)
|
||||
message(WARNING "Git failed with error: ${proc_err}")
|
||||
else()
|
||||
string(REGEX REPLACE "(.*)\n" "\\1" ${RESULT} ${proc_out})
|
||||
endif()
|
||||
elseif(NOT GIT_FOUND)
|
||||
message(WARNING "Git executable not found, revision number not available.")
|
||||
else()
|
||||
message(STATUS "Git repository not found, revision number not available.")
|
||||
endif()
|
||||
endmacro(git_id)
|
||||
|
||||
macro(use_cxx11)
|
||||
if (CMAKE_VERSION VERSION_LESS "3.1" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")
|
||||
endif ()
|
||||
endmacro(use_cxx11)
|
||||
|
||||
macro(PrintTargetReport targetName)
|
||||
if(CMAKE_CXX_COMPILER MATCHES "/(clang-)?cl\\.exe$")
|
||||
set(cpp_version ${CMAKE_CXX_COMPILER_VERSION})
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE cpp_version)
|
||||
endif()
|
||||
if(cpp_version)
|
||||
string(STRIP "v${cpp_version}" cpp_version)
|
||||
else()
|
||||
set(cpp_version "WARNING: COMPILER NOT FOUND!")
|
||||
endif()
|
||||
message("TARGET ${targetName}: cpp compiler ${CMAKE_CXX_COMPILER} ${cpp_version}")
|
||||
|
||||
if(VERBOSE_CMAKELISTS)
|
||||
get_directory_property(DirOpts COMPILE_OPTIONS)
|
||||
get_directory_property(DirDefs COMPILE_DEFINITIONS)
|
||||
string(REPLACE ";" " " DirOpts "${DirOpts}")
|
||||
string(REPLACE ";" "; " DirDefs "${DirDefs}")
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
|
||||
message("\twith cpp flags: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${build_type}} ${DirOpts}")
|
||||
message("\twith link flags: ${CMAKE_EXE_LINKER_FLAGS}")
|
||||
message("\twith defs: ${DirDefs}")
|
||||
message("--------------")
|
||||
endif()
|
||||
endmacro(PrintTargetReport)
|
||||
|
||||
@@ -1,5 +1,78 @@
|
||||
<h2>Version 2.2.1 / 2017-12-17</h2>
|
||||
|
||||
Please see <a href=http://www.open-tx.org/2017/12/16/opentx-2.2.1>this page</a> for details.
|
||||
|
||||
<h2>Version 2.2.0 / 2017-05-30</h2>
|
||||
|
||||
Major release! Please see <a href=http://www.open-tx.org/2017/05/30/opentx-2.2.0>this page</a> for details.
|
||||
|
||||
<h2>Version 2.1.9 / 2016-09-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>SD sync fixes (<a href=https://github.com/opentx/opentx/issues/3351>#3351</a>)</li>
|
||||
<li>Fixed: Telemetry mode "FrSky D (cable)" choice was missing for Taranis (<a href=https://github.com/opentx/opentx/issues/3372>#3372</a>)</li>
|
||||
<li>Show persistent option only for calculated sensors (<a href=https://github.com/opentx/opentx/issues/3454>#3454</a>)</li>
|
||||
<li>Fixed Flight mode clear command (<a href=https://github.com/opentx/opentx/issues/3214>#3214</a>)</li>
|
||||
<li>Fixed a problem with Rotary encoders linked to flight mode (could freeze Companion) (<a href=https://github.com/opentx/opentx/issues/3459>#3459</a>, <a href=https://github.com/opentx/opentx/issues/3470>#3470</a>)</li>
|
||||
<li>Telemetry simulator improvements: added fuel quantity sensor, increased RPM range (<a href=https://github.com/opentx/opentx/issues/3505>#3505</a>, <a href=https://github.com/opentx/opentx/issues/3506>#3506</a>)</li>
|
||||
<li>Implemented minimal support for the DYI Multimodule (<a href=https://github.com/opentx/opentx/issues/3526>#3526</a>)</li>
|
||||
<li>Fixed: GVar combo-box not being refreshed when GV check-box (re-)selected (<a href=https://github.com/opentx/opentx/issues/3518>#3518</a>)</li>
|
||||
<li>Fixed: Heli inversion not correctly shown/saved from Companion on Radios without virtual inputs (<a href=https://github.com/opentx/opentx/issues/3510>#3510</a>)</li>
|
||||
<li>Implemented print functions for the Heli setup screen (<a href=https://github.com/opentx/opentx/issues/3554>#3554</a>)</li>
|
||||
<li>Fixed: Flight modes linked trims display value (<a href=https://github.com/opentx/opentx/issues/3547>#3547</a>, <a href=https://github.com/opentx/opentx/issues/3568>#3568</a>)</li>
|
||||
<li>Fixed: New model global variables and rotary encoders initialisation (<a href=https://github.com/opentx/opentx/issues/3473>#3473</a>)</li>
|
||||
<li>Fixed: Prevent circular linked global variables and rotary encoders (<a href=https://github.com/opentx/opentx/issues/3472>#3472</a>)</li>
|
||||
<li>Fixed wrong log replay speed issue in Telemetry simulator (<a href=https://github.com/opentx/opentx/issues/3708>#3708</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.8 / 2016-04-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>Telemetry Simulator sensor instance number fixed (<a href=https://github.com/opentx/opentx/issues/3207>#3207</a>)</li>
|
||||
<li>Fixed: Throttle Source combo-box was populated multiple times (<a href=https://github.com/opentx/opentx/issues/3222>#3222</a>)</li>
|
||||
<li>RTC option tool-tip corrected (<a href=https://github.com/opentx/opentx/issues/3225>#3225</a>)</li>
|
||||
<li>Fixed: Companion was looking for custom scripts at the wrong place (<a href=https://github.com/opentx/opentx/issues/3237>#3237</a>)</li>
|
||||
<li>Offset displayed in inputs screen (<a href=https://github.com/opentx/opentx/issues/3248>#3248</a>)</li>
|
||||
<li>Import/export handling was broken for Average formula telemetry sensors (<a href=https://github.com/opentx/opentx/issues/3262>#3262</a>)</li>
|
||||
<li>Fixed: Hardware Setup control types and names were not stored in profile (<a href=https://github.com/opentx/opentx/issues/3260>#3260</a>)</li>
|
||||
<li>Fixed voice language list (<a href=https://github.com/opentx/opentx/issues/3338>#3338</a>)</li>
|
||||
<li>Fixed data overflow in Special Functions Override Channel (<a href=https://github.com/opentx/opentx/issues/3347>#3347</a>)</li>
|
||||
<li>Fixed: Sync dialog new line problem (only present for some UI languages) (<a href=https://github.com/opentx/opentx/issues/3350>#3350</a>)</li>
|
||||
<li>Removed a few legacy timer limitations, fix non-working limit (<a href=https://github.com/opentx/opentx/issues/3301>#3301</a>)</li>
|
||||
<li>Default AVR fuse settings changed to disable JTAG interface (<a href=https://github.com/opentx/opentx/issues/3379>#3379</a>)</li>
|
||||
<li>Channel range fix (Start, Channels) in Model Settings, Setup page, int/ext module settings</li>
|
||||
<li>Use friendly GVAR names in dialogs (if available) (<a href=https://github.com/opentx/opentx/issues/3353>#3353</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.7 / 2016-01-04</h2>
|
||||
|
||||
<ul>
|
||||
<li>Lua 'execute' failed in non-root directory (in Simulator) (<a href=https://github.com/opentx/opentx/issues/3024>#3024</a>)</li>
|
||||
<!-- this is disabled until the speed problem is fixed <li>Header line always visible in Outputs, Logical Switches and Special Functions (<a href=https://github.com/opentx/opentx/issues/2861>#2861</a>)</li> -->
|
||||
<li>LR12 changes: removed option for remote failsafe configuration, added in EU firmware variant</li>
|
||||
<li>Added Clear option to the flight mode context menu (right click on the Name label) (<a href=https://github.com/opentx/opentx/issues/3026>#3026</a>)</li>
|
||||
<li>New features for Telemetry Simulator: log replay, user friendly sensor values (<a href=https://github.com/opentx/opentx/issues/3124>#3124</a>)</li>
|
||||
<li>Added F7 key to reload LUA permanent scripts in radio simulator (<a href=https://github.com/opentx/opentx/issues/3141>#3141</a>)</li>
|
||||
<li>AR9X firmware flashing fall-back was wrong</li>
|
||||
<li>Command line options support added to standalone simulator (try "./simulator21 --help" on Linux and "simulator.exe /help" on Windows for usage) (<a href=https://github.com/opentx/opentx/issues/3160>#3160</a>)</li>
|
||||
<li>Various rounding problem fixed: Telemetry sensor Ratio parameter (<a href=https://github.com/opentx/opentx/issues/3117>#3117</a>),
|
||||
Outputs Sub-trim, Min and Max values (<a href=https://github.com/opentx/opentx/issues/3156>#3156</a>)</li>
|
||||
<li>Fixed: telemetry sensors Ratio and Offset value increment/decrement step (<a href=https://github.com/opentx/opentx/issues/3121>#3121</a>)</li>
|
||||
<li>Hardware/Calibration tab split int two tabs (<a href=https://github.com/opentx/opentx/issues/2974>#2974</a>)</li>
|
||||
<li>Fixed Fahrenheit temperature conversion error (if PREC was not 0) (<a href=https://github.com/opentx/opentx/issues/3146>#3146</a>)</li>
|
||||
<li>Application Setting 'Enable automatic backup before writing firmware' was not saved (<a href=https://github.com/opentx/opentx/issues/3040>#3040</a>)</li>
|
||||
<li>Fixed RPM package problem on Fedora (<a href=https://github.com/opentx/opentx/issues/3130>#3130</a>)</li>
|
||||
<li>Fixed conversion errors when loading 2.0.x EEPE (<a href=https://github.com/opentx/opentx/issues/3177>#3177</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.6 / 2015-11-11</h2>
|
||||
[Taranis]
|
||||
|
||||
<ul>
|
||||
<li>Telemetry custom screen changes didn't emit modified signal (<a href=https://github.com/opentx/opentx/issues/3029>#3029</a>)</li>
|
||||
<li>Hide D8/LR12 when eu firmware option is selected</li>
|
||||
@@ -22,10 +95,10 @@ Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrS
|
||||
<li>Fixed a problem with updates path on Windows (<a href=https://github.com/opentx/opentx/issues/2876>#2876</a>)</li>
|
||||
<li>Edge representation unified (changed from "no release" to "instant") (<a href=https://github.com/opentx/opentx/issues/2837>#2837</a>)</li>
|
||||
<li>Added channel names on failsafe sliders (<a href=https://github.com/opentx/opentx/issues/3021>#3021</a>)</li>
|
||||
<li>Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
|
||||
<li>Corrected failsafe mapping when using Custom failsafe mode, D16 protocol and channel range different from from 1-8.
|
||||
Users with such setups are advised to re-check their failsafe settings (<a href=https://github.com/opentx/opentx/issues/2975>#2975</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Various small bug-fixes: <a href=https://github.com/opentx/opentx/issues/2994>#2994</a>,
|
||||
<li>Various small bug-fixes: <a href=https://github.com/opentx/opentx/issues/2994>#2994</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/3016>#3016</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/3012>#3012</a>
|
||||
</li>
|
||||
@@ -43,8 +116,8 @@ Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrS
|
||||
|
||||
<ul>
|
||||
<li>Fixed: Lua model scripts outputs not working in a simulator (<a href=https://github.com/opentx/opentx/issues/2684>#2684</a>)</li>
|
||||
<li>Fixed a problem of Companion 2.1 trying to install into 2.0 path.
|
||||
The effect will only be visible for the users that did not install any of the previous 2.1.x versions.
|
||||
<li>Fixed a problem of Companion 2.1 trying to install into 2.0 path.
|
||||
The effect will only be visible for the users that did not install any of the previous 2.1.x versions.
|
||||
(<a href=https://github.com/opentx/opentx/issues/2645>#2645</a>)</li>
|
||||
<li>Added missing SDL libraries to MAC package (<a href=https://github.com/opentx/opentx/issues/2678>#2678</a>)</li>
|
||||
<li>Added used channels check/warning in Wizard (<a href=https://github.com/opentx/opentx/issues/2091>#2091</a>)</li>
|
||||
@@ -125,7 +198,7 @@ Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrS
|
||||
<li>Added Battery meter range setting (<a href=https://github.com/opentx/opentx/issues/2195>#2195</a>)</li>
|
||||
<li>Improvements in Print and Compare dialogs (<a href=https://github.com/opentx/opentx/issues/2219>#2219</a>)</li>
|
||||
<li>Reset pots to the middle by right double clicking them in Simulator (<a href=https://github.com/opentx/opentx/issues/1939>#1939</a>)</li>
|
||||
<li>Minor fixes: <a href=https://github.com/opentx/opentx/issues/2153>#2153</a>,
|
||||
<li>Minor fixes: <a href=https://github.com/opentx/opentx/issues/2153>#2153</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2138>#2138</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2090>#2090</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2122>#2122</a>
|
||||
@@ -228,13 +301,13 @@ Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrS
|
||||
<ul>
|
||||
<li>Sound should be ok on all platforms</li>
|
||||
<li>Min/Max reviewed in Logical switches (for the whole telemetry)</li>
|
||||
<li>Various bug fixes</li>
|
||||
<li>Various bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.3</h2>
|
||||
<ul>
|
||||
<li>EEPROM import bug on AdjustGVAR function</li>
|
||||
<li>Timers correctly displayed in logical switches tab</li>
|
||||
<li>Timers correctly displayed in logical switches tab</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.2</h2>
|
||||
|
||||
+397
-230
@@ -1,118 +1,231 @@
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(SIMULATOR_INSTALL_PREFIX "" CACHE STRING "Alternative simulator library search path")
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "(Linux|FreeBSD)")
|
||||
set(C9X_NAME_SUFFIX ${VERSION_MAJOR}${VERSION_MINOR})
|
||||
set(COMPANION_NAME "companion${C9X_NAME_SUFFIX}")
|
||||
set(SIMULATOR_NAME "simulator${C9X_NAME_SUFFIX}")
|
||||
set(SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
else(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
if (NOT ${SIMULATOR_INSTALL_PREFIX} STREQUAL "")
|
||||
set(SIMULATOR_LIB_PATH ${SIMULATOR_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
else()
|
||||
set(SIMULATOR_LIB_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
endif()
|
||||
message(STATUS "Simulators library search path: " ${SIMULATOR_LIB_PATH})
|
||||
set(SIMULATOR_LIB_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/lib/companion${C9X_NAME_SUFFIX})
|
||||
else()
|
||||
set(COMPANION_NAME "companion")
|
||||
set(SIMULATOR_NAME "simulator")
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
endif()
|
||||
|
||||
# This the name that the user will see in the generated DMG and what the application
|
||||
# will be called under /Applications. We include the version string to make installing
|
||||
# different versions for different eeproms easier, i.e. without manually renaming
|
||||
set(COMPANION_OSX_APP_BUNDLE_NAME "OpenTX Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
|
||||
# On OS X we copy dfu-util to the application bundle. This the path from which we copy
|
||||
# the binary (default homebrew path)
|
||||
set(DFU_UTIL_PATH "/usr/local/bin/dfu-util")
|
||||
set(AVRDUDE_PATH "/usr/local/bin/avrdude")
|
||||
set(AVRDUDE_CONF "/usr/local/etc/avrdude.conf")
|
||||
|
||||
option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default
|
||||
if(ALLOW_NIGHTLY_BUILDS)
|
||||
add_definitions(-DALLOW_NIGHTLY_BUILDS)
|
||||
endif(ALLOW_NIGHTLY_BUILDS)
|
||||
|
||||
option(DEBUG_IMPORT "Turn on debug output for EEPROM import") # Disabled by default
|
||||
if(DEBUG_IMPORT)
|
||||
add_definitions(-DDEBUG_MODEL_IMPORT)
|
||||
message(STATUS "EEPROM import debugging enabled")
|
||||
endif(DEBUG_IMPORT)
|
||||
option(DEBUG_STORAGE_IMPORT "Turn on debug output for storage import") # Disabled by default
|
||||
if(DEBUG_STORAGE_IMPORT)
|
||||
add_definitions(-DDEBUG_STORAGE_IMPORT)
|
||||
message(STATUS "Storage import debugging enabled")
|
||||
endif()
|
||||
if(DEBUG)
|
||||
add_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
option(TABLE_LAYOUT "Use QTableWidget for grid layouts") # Disabled by default
|
||||
if(TABLE_LAYOUT)
|
||||
add_definitions(-DTABLE_LAYOUT)
|
||||
message(STATUS "Using QTableWidget")
|
||||
endif(TABLE_LAYOUT)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(WIN_DO_FULL_INSTALL "'install' target will perform a full installation into CMAKE_INSTALL_PREFIX path, otherwise only supporting DLLs are copied to binaries folder (default)" OFF)
|
||||
option(WIN_USE_CONSOLE "Open a Windows command console for Simulator debug output." OFF)
|
||||
if(WIN_USE_CONSOLE)
|
||||
add_definitions(-DWIN_USE_CONSOLE_STDIO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL_FOUND)
|
||||
include_directories(${SDL_INCLUDE_DIR})
|
||||
add_definitions(-DSIMU_AUDIO)
|
||||
add_definitions(-DJOYSTICKS)
|
||||
endif()
|
||||
|
||||
message(STATUS "Looking for QT lupdate ")
|
||||
find_package(Lupdate)
|
||||
if(LUPDATE_FOUND)
|
||||
message("QT lupdate: " ${LUPDATE_EXECUTABLE})
|
||||
add_definitions(${APP_COMMON_DEFINES}) # set in top-level CMakeLists
|
||||
|
||||
if(NOT MSVC)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Wall")
|
||||
if(WARNINGS_AS_ERRORS)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror")
|
||||
endif()
|
||||
else()
|
||||
message("QT lupdate not found!")
|
||||
# silence lots of warnings regarding "insecure" use of functions (sprintf, strcpy, etc)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
|
||||
if(WARNINGS_AS_ERRORS)
|
||||
set(WARNING_FLAGS "${WARNING_FLAGS} /WX")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(-DQXT_STATIC)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "/EHsc /LD")
|
||||
include_directories(${PROJECT_SOURCE_DIR}/winbuild C:/Programs/pthreads/Pre-built.2/include C:/Programs/msinttypes C:/Programs/dirent/include)
|
||||
link_directories(C:/Programs/pthreads/Pre-built.2/lib/)
|
||||
set(PTHREAD_LIBRARY pthreadVC2.lib)
|
||||
if(WIN32)
|
||||
include_directories(SYSTEM ${WIN_INCLUDE_DIRS})
|
||||
if(NOT WIN_USE_CONSOLE)
|
||||
set(WIN_EXECUTABLE_TYPE WIN32) # GUI (WinMain) app
|
||||
endif()
|
||||
if(MSVC)
|
||||
if(NOT CLANG)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /LD /MP")
|
||||
endif()
|
||||
if(NOT WIN_USE_CONSOLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,5.01") # is this even needed?
|
||||
endif()
|
||||
elseif(MINGW)
|
||||
get_filename_component(MINGW_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
|
||||
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields")
|
||||
endif()
|
||||
else()
|
||||
set(PTHREAD_LIBRARY pthread)
|
||||
add_definitions(-Wall)
|
||||
link_directories(/usr/local/lib)
|
||||
endif()
|
||||
|
||||
set(RADIO_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/radio/src)
|
||||
set(SIMU_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src/simulation)
|
||||
set(COMPANION_SRC_DIRECTORY ${PROJECT_SOURCE_DIR}/companion/src)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
|
||||
use_cxx11() # ensure gnu++11 in CXX_FLAGS with CMake < 3.1
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${COMPANION_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/shared
|
||||
${SIMU_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/qxtcommandoptions
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/qcustomplot
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/miniz
|
||||
${COMPANION_SRC_DIRECTORY}/storage
|
||||
)
|
||||
|
||||
############# Do macro replacements on input files #############
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY)
|
||||
|
||||
############# Translations ###############
|
||||
|
||||
### Generate .qm files and assemble resource (qrc) file.
|
||||
|
||||
# available Companion translations (src/translations/*.ts)
|
||||
set(LANGUAGES cs de en es fi fr it pl sv zh_CN)
|
||||
foreach(language ${LANGUAGES})
|
||||
list(APPEND companion_TS translations/companion_${language}.ts)
|
||||
endforeach(language)
|
||||
# .ts -> .qm
|
||||
qt5_add_translation(companion_QM ${companion_TS})
|
||||
|
||||
# add Qt translations if found
|
||||
if(QT_TRANSLATIONS_DIR)
|
||||
# Some languages have all translations in one qt_*.qm file and others break them up into modules, in which case we need qt_base_*.qm
|
||||
file(GLOB qtbase_QM "${QT_TRANSLATIONS_DIR}/qtbase_*.qm")
|
||||
file(GLOB qt_QM "${QT_TRANSLATIONS_DIR}/qt_??.qm") # don't want to match "qt_help_*.qm"
|
||||
list(APPEND qt_QM "${QT_TRANSLATIONS_DIR}/qt_zh_CN.qm" "${QT_TRANSLATIONS_DIR}/qt_zh_TW.qm") # exceptions not matched by the GLOB
|
||||
else()
|
||||
message(STATUS "QT_TRANSLATIONS_DIR not found, unable to package pre-built Qt translations with application.")
|
||||
endif()
|
||||
|
||||
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/translations.qrc")
|
||||
|
||||
# Dynamically create translations.qrc file (XML) from all collected translation files.
|
||||
foreach(qm_file ${companion_QM} ${qt_QM} ${qtbase_QM})
|
||||
get_filename_component(qm_file_name ${qm_file} NAME)
|
||||
# Add file with full path and file name (w/out path) as alias to be used in actual code
|
||||
set(TRANSLATION_FILES_LIST "${TRANSLATION_FILES_LIST} <file alias=\"${qm_file_name}\">${qm_file}</file>\n")
|
||||
endforeach()
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${TRANSLATIONS_QRC} @ONLY)
|
||||
|
||||
### Add optional "translations" target for updating .ts files
|
||||
if(QT_LUPDATE_EXECUTABLE)
|
||||
add_custom_target(translations
|
||||
WORKING_DIRECTORY ${COMPANION_SRC_DIRECTORY}
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS}
|
||||
)
|
||||
else()
|
||||
message(STATUS "Qt lupdate not found, 'translations' target will not be availabe.")
|
||||
endif()
|
||||
|
||||
############# Common lib ###############
|
||||
|
||||
set(common_SRCS
|
||||
appdebugmessagehandler.cpp
|
||||
customdebug.cpp
|
||||
helpers.cpp
|
||||
translations.cpp
|
||||
modeledit/node.cpp # used in simulator
|
||||
modeledit/edge.cpp # used by node
|
||||
)
|
||||
|
||||
set(common_MOC_HDRS
|
||||
appdebugmessagehandler.h
|
||||
helpers.h
|
||||
modeledit/node.h
|
||||
)
|
||||
|
||||
set(common_RESOURCES
|
||||
companion.qrc
|
||||
${TRANSLATIONS_QRC}
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS ${common_MOC_HDRS})
|
||||
qt5_add_resources(common_RCC ${common_RESOURCES})
|
||||
|
||||
add_library(common ${common_SRCS} ${common_RCC})
|
||||
|
||||
target_link_libraries(common
|
||||
firmwares
|
||||
storage
|
||||
simulation
|
||||
maxLibQtWidgets
|
||||
Qt5::Core
|
||||
Qt5::Xml
|
||||
Qt5::Widgets
|
||||
${PTHREAD_LIBRARY}
|
||||
${SDL_LIBRARY}
|
||||
${WIN_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
set(CPN_COMMON_LIB common)
|
||||
|
||||
############# Supporting libraries ###############
|
||||
|
||||
add_subdirectory(datamodels)
|
||||
add_subdirectory(firmwares)
|
||||
add_subdirectory(shared)
|
||||
add_subdirectory(modeledit)
|
||||
add_subdirectory(generaledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(qcustomplot)
|
||||
add_subdirectory(qxtcommandoptions)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(thirdparty/qcustomplot)
|
||||
add_subdirectory(thirdparty/maxlibqt/src/widgets)
|
||||
|
||||
set(common_SRCS
|
||||
eeprominterface.cpp
|
||||
firmwares/th9x/th9xeeprom.cpp # TODO not needed
|
||||
firmwares/th9x/th9xinterface.cpp
|
||||
firmwares/er9x/er9xeeprom.cpp
|
||||
firmwares/er9x/er9xinterface.cpp
|
||||
firmwares/gruvin9x/gruvin9xeeprom.cpp
|
||||
firmwares/gruvin9x/gruvin9xinterface.cpp
|
||||
firmwares/ersky9x/ersky9xeeprom.cpp
|
||||
firmwares/ersky9x/ersky9xinterface.cpp
|
||||
firmwares/opentx/opentxeeprom.cpp
|
||||
firmwares/opentx/open9xStockeeprom.cpp
|
||||
firmwares/opentx/open9xGruvin9xeeprom.cpp
|
||||
firmwares/opentx/open9xSky9xeeprom.cpp
|
||||
firmwares/opentx/opentxinterface.cpp
|
||||
file.cpp
|
||||
appdata.cpp
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(common_SRCS)
|
||||
|
||||
add_library(common ${common_SRCS})
|
||||
qt5_use_modules(common Core Xml Widgets)
|
||||
############# Companion ###############
|
||||
|
||||
set(companion_SRCS
|
||||
hexinterface.cpp
|
||||
firmwareinterface.cpp
|
||||
converteeprom.cpp
|
||||
# xmlinterface.cpp
|
||||
# ${PROJECT_BINARY_DIR}/radio.cxx
|
||||
helpers.cpp
|
||||
helpers_html.cpp
|
||||
mdichild.cpp
|
||||
modelslist.cpp
|
||||
mountlist.cpp
|
||||
apppreferencesdialog.cpp
|
||||
fwpreferencesdialog.cpp
|
||||
burnconfigdialog.cpp
|
||||
multimodelprinter.cpp
|
||||
comparedialog.cpp
|
||||
contributorsdialog.cpp
|
||||
creditsdialog.cpp
|
||||
releasenotesdialog.cpp
|
||||
releasenotesfirmwaredialog.cpp
|
||||
customizesplashdialog.cpp
|
||||
@@ -135,6 +248,8 @@ set(companion_SRCS
|
||||
radionotfound.cpp
|
||||
wizarddata.cpp
|
||||
wizarddialog.cpp
|
||||
styleeditdialog.cpp
|
||||
dialogs/filesyncdialog.cpp # TODO move to own lib with other dialogs
|
||||
)
|
||||
|
||||
set(companion_MOC_HDRS
|
||||
@@ -145,7 +260,7 @@ set(companion_MOC_HDRS
|
||||
printdialog.h
|
||||
fusesdialog.h
|
||||
logsdialog.h
|
||||
contributorsdialog.h
|
||||
creditsdialog.h
|
||||
releasenotesdialog.h
|
||||
releasenotesfirmwaredialog.h
|
||||
customizesplashdialog.h
|
||||
@@ -159,14 +274,16 @@ set(companion_MOC_HDRS
|
||||
flashfirmwaredialog.h
|
||||
flasheepromdialog.h
|
||||
downloaddialog.h
|
||||
modelslist.h
|
||||
mdichild.h
|
||||
mainwindow.h
|
||||
radionotfound.h
|
||||
helpers.h
|
||||
wizarddialog.h
|
||||
modelprinter.h
|
||||
multimodelprinter.h
|
||||
modelslist.h
|
||||
styleeditdialog.h
|
||||
helpers_html.h
|
||||
dialogs/filesyncdialog.h
|
||||
)
|
||||
|
||||
set(companion_UIS
|
||||
@@ -187,213 +304,254 @@ set(companion_UIS
|
||||
flashfirmwaredialog.ui
|
||||
flasheepromdialog.ui
|
||||
radionotfound.ui
|
||||
styleeditdialog.ui
|
||||
)
|
||||
|
||||
set(companion_RESOURCES
|
||||
companion.qrc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/translations.qrc
|
||||
)
|
||||
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/companion.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop @ONLY)
|
||||
configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop @ONLY)
|
||||
|
||||
if(WIN32)
|
||||
set(companion_SRCS ${companion_SRCS} icon.rc)
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_EXE_LINKER_FLAGS -mwindows)
|
||||
endif()
|
||||
set(icon_RC images/winicons/icon.rc)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
include_directories(${CMAKE_SOURCE_DIR})
|
||||
|
||||
set(LANGUAGES he pl pt ru de fr es it sv cs fi nl)
|
||||
foreach(language ${LANGUAGES})
|
||||
set(companion_TS ${companion_TS} translations/companion_${language}.ts)
|
||||
endforeach(language)
|
||||
|
||||
qt5_wrap_ui(companion_SRCS ${companion_UIS})
|
||||
qt5_wrap_cpp(companion_SRCS ${companion_MOC_HDRS})
|
||||
qt5_add_translation(companion_QM ${companion_TS})
|
||||
qt5_add_resources(companion_RCC ${companion_RESOURCES})
|
||||
add_custom_target(gen_qrc DEPENDS ${companion_RCC})
|
||||
|
||||
add_definitions(-DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}")
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${companion_SRCS} ${icon_RC})
|
||||
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit qcustomplot shared ${CPN_COMMON_LIB})
|
||||
|
||||
if(APPLE)
|
||||
add_executable(${COMPANION_NAME} MACOSX_BUNDLE ${companion_SRCS} ${companion_RCC} ${companion_QM})
|
||||
# OS X compiler no longer automatically includes /Library/Frameworks in search path
|
||||
set(CMAKE_EXE_LINKER_FLAGS -F/Library/Frameworks)
|
||||
else()
|
||||
add_executable(${COMPANION_NAME} WIN32 ${companion_SRCS} ${companion_RCC} ${companion_QM})
|
||||
PrintTargetReport("${COMPANION_NAME}")
|
||||
|
||||
############# Standalone simulator ###############
|
||||
|
||||
set(simu_SRCS simulator.cpp )
|
||||
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE ${CPN_COMMON_LIB})
|
||||
|
||||
############# Install ####################
|
||||
|
||||
# Generate list of simulator plugins, used by all platforms
|
||||
file(GLOB simulator_plugins "${CMAKE_BINARY_DIR}/*opentx-*simulator${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
# the current flavour is not automatically added if build in the current cmake iteration, so always
|
||||
# add its library name to be sure
|
||||
string(TOLOWER ${PCB} FLAVOUR)
|
||||
if(POLICY CMP0026)
|
||||
cmake_policy(SET CMP0026 OLD) # https://cmake.org/cmake/help/v3.0/policy/CMP0026.html
|
||||
endif()
|
||||
if(SIMU_TARGET)
|
||||
get_property(current_plugin TARGET opentx-${FLAVOUR}-simulator PROPERTY LOCATION)
|
||||
list(APPEND simulator_plugins "${current_plugin}")
|
||||
endif()
|
||||
|
||||
add_dependencies(${COMPANION_NAME} gen_qrc)
|
||||
qt5_use_modules(${COMPANION_NAME} Core Widgets Network)
|
||||
target_link_libraries(${COMPANION_NAME} PRIVATE generaledit modeledit simulation common qcustomplot shared ${PTHREAD_LIBRARY} ${SDL_LIBRARY})
|
||||
|
||||
############# Standalone simu ###############
|
||||
|
||||
set(simu_SRCS
|
||||
modeledit/node.cpp
|
||||
modeledit/edge.cpp # TODO not needed
|
||||
simulator.cpp
|
||||
)
|
||||
|
||||
set(simu_MOC_HDRS
|
||||
modeledit/node.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(simu_SRCS ${simu_MOC_HDRS} )
|
||||
|
||||
if(WIN32)
|
||||
set(simu_SRCS ${simu_SRCS} icon.rc)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${simu_SRCS} ${companion_RCC})
|
||||
else()
|
||||
add_executable(${SIMULATOR_NAME} WIN32 ${simu_SRCS} ${companion_RCC})
|
||||
endif()
|
||||
|
||||
add_dependencies(${SIMULATOR_NAME} gen_qrc)
|
||||
# TODO not the same link command than companion?
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation common qxtcommandoptions ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${OPENTX_SIMULATOR_LIBS})
|
||||
|
||||
############# Packaging ####################
|
||||
message(STATUS ${CMAKE_BINARY_DIR} ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
message(STATUS "install " ${CMAKE_BINARY_DIR} " to " ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(TARGETS ${COMPANION_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/ DESTINATION ${SIMULATOR_LIB_PATH} USE_SOURCE_PERMISSIONS
|
||||
FILES_MATCHING PATTERN "libopentx-*.so"
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "_CPack_Packages" EXCLUDE
|
||||
PATTERN "companion" EXCLUDE
|
||||
PATTERN "radio" EXCLUDE
|
||||
)
|
||||
install(FILES ${simulator_plugins} DESTINATION "${SIMULATOR_LIB_INSTALL_PATH}")
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/companion.desktop DESTINATION share/applications RENAME companion${C9X_NAME_SUFFIX}.desktop)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/simulator.desktop DESTINATION share/applications RENAME simulator${C9X_NAME_SUFFIX}.desktop)
|
||||
if(${CMAKE_INSTALL_PREFIX} MATCHES "/usr/local")
|
||||
install(FILES images/linuxicons/16x16/companion.png DESTINATION /usr/share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/22x22/companion.png DESTINATION /usr/share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/24x24/companion.png DESTINATION /usr/share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/32x32/companion.png DESTINATION /usr/share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/48x48/companion.png DESTINATION /usr/share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/128x128/companion.png DESTINATION /usr/share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/256x256/companion.png DESTINATION /usr/share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/512x512/companion.png DESTINATION /usr/share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/scalable/companion.svg DESTINATION /usr/share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg)
|
||||
install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION /lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules)
|
||||
else()
|
||||
install(FILES images/linuxicons/16x16/companion.png DESTINATION share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/22x22/companion.png DESTINATION share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/24x24/companion.png DESTINATION share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/32x32/companion.png DESTINATION share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/48x48/companion.png DESTINATION share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/128x128/companion.png DESTINATION share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/256x256/companion.png DESTINATION share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/512x512/companion.png DESTINATION share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/scalable/companion.svg DESTINATION share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg)
|
||||
install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules)
|
||||
set(INSTALL_TEMP_SHR_PFX "/usr/")
|
||||
set(INSTALL_TEMP_LIB_PFX "/")
|
||||
endif()
|
||||
install(FILES images/linuxicons/16x16/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/16x16/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/22x22/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/22x22/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/24x24/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/24x24/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/32x32/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/32x32/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/48x48/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/48x48/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/128x128/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/128x128/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/256x256/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/256x256/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/512x512/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/scalable/companion.svg DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg)
|
||||
install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules)
|
||||
install(FILES ../targets/linux/45-usbasp.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-usbasp.rules)
|
||||
# Linux specific code
|
||||
set(OperatingSystem "Linux")
|
||||
elseif(WIN32)
|
||||
get_target_property(QtCore_LOCATION Qt5::Core LOCATION)
|
||||
get_filename_component(QT_DLL_DIR ${QtCore_LOCATION} PATH)
|
||||
get_filename_component(SDL_DIR ${SDL_LIBRARY} PATH)
|
||||
install(FILES ${QT_DLL_DIR}/icudt54.dll ${QT_DLL_DIR}/icuin54.dll ${QT_DLL_DIR}/icuuc54.dll ${QT_DLL_DIR}/Qt5Core.dll ${QT_DLL_DIR}/Qt5Gui.dll ${QT_DLL_DIR}/Qt5Widgets.dll ${QT_DLL_DIR}/Qt5Xml.dll ${QT_DLL_DIR}/Qt5Network.dll ${QT_DLL_DIR}/Qt5PrintSupport.dll ${QT_DLL_DIR}/Qt5Multimedia.dll ${SDL_DIR}/SDL.dll DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>)
|
||||
install(FILES ${QT_DLL_DIR}/icudt54.dll ${QT_DLL_DIR}/icuin54.dll ${QT_DLL_DIR}/icuuc54.dll ${QT_DLL_DIR}/Qt5Cored.dll ${QT_DLL_DIR}/Qt5Guid.dll ${QT_DLL_DIR}/Qt5Widgetsd.dll ${QT_DLL_DIR}/Qt5Xmld.dll ${QT_DLL_DIR}/Qt5Networkd.dll ${QT_DLL_DIR}/Qt5PrintSupportd.dll ${QT_DLL_DIR}/Qt5Multimediad.dll ${SDL_DIR}/SDL.dll DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(MSVC)
|
||||
set(COMPANION_NSI_IN_FILE companion-vs.nsi.in)
|
||||
set(SIMULATOR_NSI_IN_FILE simulator-vs.nsi.in)
|
||||
elseif(WIN32)
|
||||
|
||||
if(NOT WIN_DO_FULL_INSTALL)
|
||||
# Just copy supporting DLLs to build folder
|
||||
set(INSTALL_DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
message(STATUS "Partial install to " ${INSTALL_DESTINATION})
|
||||
else()
|
||||
set(COMPANION_NSI_IN_FILE companion-msys.nsi.in)
|
||||
set(SIMULATOR_NSI_IN_FILE simulator-msys.nsi.in)
|
||||
# Full Windows installation with all supporting files
|
||||
set(INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}")
|
||||
message(STATUS "Full install to " ${INSTALL_DESTINATION})
|
||||
# companion & simulator binaries
|
||||
install(TARGETS ${COMPANION_NAME} DESTINATION ${INSTALL_DESTINATION})
|
||||
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION})
|
||||
install(FILES ${simulator_plugins} DESTINATION "${INSTALL_DESTINATION}")
|
||||
# supporting utilities
|
||||
set(INSTALL_TEMP_FILES avrdude.exe avrdude.conf dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
|
||||
foreach(tmpfile ${INSTALL_TEMP_FILES})
|
||||
install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/${tmpfile}" DESTINATION ${INSTALL_DESTINATION})
|
||||
endforeach()
|
||||
endif() # WIN_DO_FULL_INSTALL
|
||||
|
||||
# Qt dlls (using windeployqt)
|
||||
## Qt translations are already packaged into our custom qrc. Also don't need software rendering engines.
|
||||
set(wdqtopts --no-translations --no-opengl-sw --no-system-d3d-compiler --no-angle)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(wdqtopts ${wdqtopts} --release) # release builds aren't always properly detected with mingw
|
||||
endif()
|
||||
if(MSVC)
|
||||
set(wdqtopts ${wdqtopts} --no-compiler-runtime) # --compiler-runtime includes vcredist_x86, but we just copy the required DLLs manually
|
||||
endif()
|
||||
set(wdqtopts ${wdqtopts} -dir "${INSTALL_DESTINATION}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${COMPANION_NAME}.exe" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${SIMULATOR_NAME}.exe")
|
||||
# Add installer command to execute windeployqt
|
||||
install(CODE "execute_process(COMMAND \"${QT_BIN_DIR}/windeployqt.exe\" ${wdqtopts})")
|
||||
|
||||
# SDL dll
|
||||
if(SDL_FOUND AND EXISTS "${SDL_LIBRARY_PATH}/SDL.dll")
|
||||
set(SDL_DIR ${SDL_LIBRARY_PATH}) # this is also used by NSIS installer script
|
||||
install(FILES ${SDL_DIR}/SDL.dll DESTINATION ${INSTALL_DESTINATION})
|
||||
elseif(SDL_FOUND)
|
||||
message(WARNING "Installer: SDL.dll not found, set SDL_LIBRARY_PATH manually.")
|
||||
endif()
|
||||
|
||||
set(SYSDIR "$ENV{windir}/system32")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${COMPANION_NSI_IN_FILE} ${PROJECT_BINARY_DIR}/companion/companion.nsi @ONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${SIMULATOR_NSI_IN_FILE} ${PROJECT_BINARY_DIR}/companion/simulator.nsi @ONLY)
|
||||
# libeay (SSL) dlls (used by QtNetwork) -- not strictly required but avoids possible issues with downloads and Qt warnings.
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" WIN_PROGRAM_FILES)
|
||||
find_path(EAY_LIB_DIR libeay32.dll HINTS
|
||||
"${WIN_PROGRAM_FILES}/OpenSSL" "${WIN_PROGRAM_FILES}/OpenSSL-Win32"
|
||||
"C:/OpenSSL/" "C:/OpenSSL-Win32/"
|
||||
"${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/OpenSSL" "${WIN_EXTRA_LIBS_PATH}/OpenSSL-Win32"
|
||||
"${MINGW_DIR}/../opt/bin"
|
||||
"${PYTHON_DIRECTORY}/lib/site-packages/PyQt4"
|
||||
PATH_SUFFIXES bin
|
||||
DOC "Path to libeay32.dll and ssleay32.dll (OpenSSL)"
|
||||
)
|
||||
if (EAY_LIB_DIR)
|
||||
install(FILES "${EAY_LIB_DIR}/libeay32.dll" "${EAY_LIB_DIR}/ssleay32.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
|
||||
else()
|
||||
message(WARNING "Installer: SSL libs not found, set EAY_LIB_DIR manually.")
|
||||
endif()
|
||||
|
||||
# C++/system dlls, depends on compiler
|
||||
if(MSVC)
|
||||
file(TO_CMAKE_PATH "$ENV{windir}/SysWOW64" WIN_SYSDIR) # This would be "system32" for a 64-bit build or on x86... but how to tell?
|
||||
if (NOT EXISTS "${WIN_SYSDIR}")
|
||||
file(TO_CMAKE_PATH "$ENV{windir}/system32" WIN_SYSDIR) # Must be 32-bit Windows.
|
||||
endif()
|
||||
install(FILES "${WIN_SYSDIR}/msvcp140.dll" "${WIN_SYSDIR}/vcruntime140.dll" DESTINATION ${INSTALL_DESTINATION} OPTIONAL)
|
||||
if(WIN_PTHREAD_DLL)
|
||||
install(FILES "${WIN_PTHREAD_DLL}" DESTINATION ${INSTALL_DESTINATION})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif() # WIN32 install
|
||||
|
||||
############# Packaging ####################
|
||||
|
||||
# Create Windows installer with NSIS
|
||||
if(WIN32)
|
||||
|
||||
find_program(NSIS_EXE makensis.exe PATHS
|
||||
"C:/Program Files/NSIS"
|
||||
"C:/Program Files (x86)/NSIS"
|
||||
"C:/Programs/NSIS"
|
||||
"${WIN_EXTRA_LIBS_PATH}/NSIS"
|
||||
)
|
||||
|
||||
if (NSIS_EXE)
|
||||
file(TO_NATIVE_PATH "${INSTALL_DESTINATION}" NSIS_DISTRO) # all files in here will be included in installer
|
||||
set(NSI_FILE "${PROJECT_BINARY_DIR}/companion/companion.nsi")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/companion.nsi.in" "${NSI_FILE}" @ONLY)
|
||||
|
||||
add_custom_target(installer
|
||||
# The 'install' target prepares all the distro files, make sure it has been executed first.
|
||||
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target install
|
||||
COMMAND "${NSIS_EXE}" "${NSI_FILE}"
|
||||
DEPENDS "${NSI_FILE}"
|
||||
COMMENT "Building Windows NSIS installer..."
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/companion/companion-windows.exe
|
||||
COMMAND "${NSIS_EXE}" ARGS ${PROJECT_BINARY_DIR}/companion/companion.nsi
|
||||
DEPENDS companion simulator opentx-simulators ${PROJECT_BINARY_DIR}/companion/companion.nsi
|
||||
COMMENT "Companion Windows NSIS Installer")
|
||||
|
||||
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/companion/simulator-install.exe
|
||||
COMMAND "${NSIS_EXE}" ARGS ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
DEPENDS simulator ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
COMMENT "Simulator Windows NSIS Installer")
|
||||
|
||||
add_custom_target(installer
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/companion/companion-windows.exe
|
||||
DEPENDS ${PROJECT_BINARY_DIR}/companion/simulator-windows.exe
|
||||
SOURCES ${PROJECT_BINARY_DIR}/companion/companion.nsi
|
||||
SOURCES ${PROJECT_BINARY_DIR}/companion/simulator.nsi
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE iconmac.icns)
|
||||
if(CMAKE_GENERATOR STREQUAL Xcode)
|
||||
set(WORK_DIR ${CMAKE_BINARY_DIR}/Debug)
|
||||
else()
|
||||
set(WORK_DIR ${PROJECT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
add_custom_target(addframeworks
|
||||
COMMAND mkdir -p companion.app/Contents/Frameworks
|
||||
COMMAND mkdir -p companion.app/Contents/Resources
|
||||
COMMAND mkdir -p companion.app/Contents/translations
|
||||
COMMAND rsync ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} companion.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE} # Copy the icon files
|
||||
COMMAND rsync -r --exclude=.svn ${PROJECT_SOURCE_DIR}/../targets/mac/qt_menu.nib companion.app/Contents/Resources/
|
||||
COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations
|
||||
COMMAND rsync ${PROJECT_BINARY_DIR}/*.qm companion.app/Contents/translations
|
||||
COMMAND rsync -r /Library/Frameworks/SDL.framework companion.app/Contents/Frameworks/
|
||||
COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app
|
||||
COMMAND install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL companion.app/Contents/MacOS/companion
|
||||
WORKING_DIRECTORY ${WORK_DIR}
|
||||
DEPENDS ${COMPANION_NAME})
|
||||
|
||||
add_custom_target(makedmg
|
||||
COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app -dmg -no-plugins
|
||||
WORKING_DIRECTORY ${WORK_DIR}
|
||||
DEPENDS addframeworks opentx-simulators-bundle)
|
||||
endif()
|
||||
|
||||
if(LUPDATE_FOUND)
|
||||
add_custom_target(translations
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR} -no-obsolete -ts ${companion_TS}
|
||||
)
|
||||
else()
|
||||
add_custom_target(translations
|
||||
COMMAND echo "Sorry, QT lupdate was not found."
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_NAME "companion${C9X_NAME_SUFFIX}")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTx open source firmware")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Models and settings editor for the OpenTX open source firmware")
|
||||
string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_PACKAGE_NAME_LOWERCASE)
|
||||
|
||||
# The file stripping is deliberately disabled, with the stripped file we get
|
||||
# very poor trace-backs from the users when they report Companion crash
|
||||
set(CPACK_STRIP_FILES FALSE)
|
||||
|
||||
# Qt5 + Cmake + Mac is poorly documented. A lot of this is guesswork
|
||||
# and trial and error. Do not hesitate to fix it for the better
|
||||
IF(APPLE)
|
||||
set(plugin_dest_dir ${COMPANION_NAME}.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir ${COMPANION_NAME}.app/Contents/Resources)
|
||||
set(APPS "\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app")
|
||||
set(companion_res_dir ${COMPANION_NAME}.app/Contents/Resources)
|
||||
|
||||
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Companion ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simulator ${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||
|
||||
# Use a non standard Info.plist that adds Retina support flags
|
||||
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
|
||||
INSTALL(TARGETS ${COMPANION_NAME}
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
RUNTIME DESTINATION bin COMPONENT Runtime
|
||||
)
|
||||
|
||||
install(FILES ${simulator_plugins} DESTINATION "${companion_res_dir}" COMPONENT Runtime)
|
||||
|
||||
# Write qt.conf to tell qt where to find it plugins
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||
"[Paths]\nPlugins = Plugins\n")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||
DESTINATION "${companion_res_dir}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
# menu file
|
||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/companion/targets/mac/qt_menu.nib DESTINATION "${companion_res_dir}" COMPONENT Runtime)
|
||||
|
||||
# manually add the required plugins
|
||||
foreach (plugin ${Qt5Multimedia_PLUGINS} ${Qt5PrintSupport_PLUGINS} ${Qt5Gui_PLUGINS} ${Qt5Svg_PLUGINS})
|
||||
get_target_property(QPA_PLUGIN ${plugin} LOCATION)
|
||||
get_filename_component(QPA_PLUGIN_FILENAME ${QPA_PLUGIN} NAME)
|
||||
# Todo is there a nicer way to get the QT Plugin directory name?!
|
||||
get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN} DIRECTORY)
|
||||
get_filename_component(QPA_PLUGIN_DIRECTORY ${QPA_PLUGIN_DIRECTORY} NAME)
|
||||
|
||||
install(FILES ${QPA_PLUGIN} DESTINATION "${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/" COMPONENT Runtime)
|
||||
|
||||
list(APPEND bundle_qt_libs "\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/${QPA_PLUGIN_DIRECTORY}/${QPA_PLUGIN_FILENAME}")
|
||||
endforeach()
|
||||
|
||||
# Add icon
|
||||
set(MACOSX_BUNDLE_ICON_FILE iconmac.icns)
|
||||
set(MAC_ICON_FILE ${COMPANION_SRC_DIRECTORY}/images/${MACOSX_BUNDLE_ICON_FILE})
|
||||
SET_SOURCE_FILES_PROPERTIES(${MAC_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
|
||||
install(FILES ${MAC_ICON_FILE} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
|
||||
# Copy dfu-util and avrdude, resolve symlink first
|
||||
get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDE_ABSOLUTE_PATH ${AVRDUDE_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDECONF_ABSOLUTE_PATH ${AVRDUDE_CONF} REALPATH)
|
||||
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
install(FILES ${AVRDUDECONF_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
|
||||
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")
|
||||
|
||||
|
||||
# Include depencies (adding frameworks, fixing the embbeded libraries)
|
||||
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
|
||||
# technically a hack (that is already is in the Bundle library ...)
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
file(GLOB bundle_simulator_libs \"\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/libopentx-*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS on)
|
||||
fixup_bundle(\"${APPS}\" \"\${bundle_simulator_libs};${bundle_qt_libs};${bundle_tools_path}\" \"${QT_LIB_DIR}\")
|
||||
file(RENAME \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_NAME}.app\" \"\${CMAKE_INSTALL_PREFIX}/${COMPANION_OSX_APP_BUNDLE_NAME}.app\")
|
||||
" COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
||||
|
||||
if(DPKG_PROGRAM)
|
||||
set(CPACK_GENERATOR "DEB")
|
||||
execute_process(
|
||||
@@ -407,13 +565,22 @@ if(DPKG_PROGRAM)
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||
set(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR))
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
elseif(APPLE)
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
# set(CPACK_GENERATOR "TGZ") # for quick testing
|
||||
set(CPACK_BINARY_DRAGNDROP ON)
|
||||
set(CPACK_DMG_BACKGROUND_IMAGE ${COMPANION_SRC_DIRECTORY}/images/splash22_3_dmg.png)
|
||||
set(CPACK_DMG_VOLUME_NAME "OpenTX Companion")
|
||||
set(CPACK_DMG_DS_STORE ${PROJECT_SOURCE_DIR}/companion/targets/mac/DS_Store)
|
||||
set(CPACK_PACKAGE_FILE_NAME "opentx-${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}")
|
||||
else(DPKG_PROGRAM)
|
||||
set(CPACK_GENERATOR "RPM")
|
||||
set(CPACK_RPM_PACKAGE_VERSION ${VERSION})
|
||||
set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${VERSION}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib /lib/udev /lib/udev/rules.d")
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib /lib/udev /lib/udev/rules.d")
|
||||
endif(DPKG_PROGRAM)
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -1,800 +0,0 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "appdata.h"
|
||||
|
||||
// Global data and storage object
|
||||
AppData g;
|
||||
|
||||
// ** CompStoreObj class********************
|
||||
void CompStoreObj::clear (const QString tag1, const QString tag2, const QString tag3)
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (tag2.isEmpty())
|
||||
{
|
||||
settings.remove(tag1);
|
||||
}
|
||||
else if (tag3.isEmpty())
|
||||
{
|
||||
settings.beginGroup(tag1);
|
||||
settings.remove(tag2);
|
||||
settings.endGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.beginGroup(tag1);
|
||||
settings.beginGroup(tag2);
|
||||
settings.remove(tag3);
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
void CompStoreObj::store(const QByteArray newArray, QByteArray &array, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
settings.setValue(tag, newArray);
|
||||
array = newArray;
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::store(const QStringList newSList, QStringList &stringList, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
settings.setValue(tag, newSList);
|
||||
stringList = newSList;
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::store(const QString newString, QString &string, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
settings.setValue(tag, newString);
|
||||
string = newString;
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::store(const bool newTruth, bool &truth, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
settings.setValue(tag, newTruth);
|
||||
truth = newTruth;
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::store(const int newNumber, int &number, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
settings.setValue(tag, newNumber);
|
||||
number = newNumber;
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
// Retrieval functions
|
||||
void CompStoreObj::retrieve( QByteArray &array, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
array = settings.value(tag, def).toByteArray();
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::retrieve( QStringList &stringList, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
stringList = settings.value(tag, def).toStringList();
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::retrieve( QString &string, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
string = settings.value(tag, def).toString();
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::retrieve( bool &truth, const QString tag, const bool def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
truth = settings.value(tag, def).toBool();
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
void CompStoreObj::retrieve( int &number, const QString tag, const int def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
number = settings.value(tag, def).toInt();
|
||||
|
||||
if (!group1.isEmpty()) settings.endGroup();
|
||||
if (!group2.isEmpty()) settings.endGroup();
|
||||
}
|
||||
|
||||
// Retrieve and Store functions
|
||||
void CompStoreObj::getset( QByteArray &array, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
retrieve( array, tag, def, group1, group2);
|
||||
store(array, array, tag, group1, group2);
|
||||
}
|
||||
|
||||
void CompStoreObj::getset( QStringList &stringList, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
retrieve( stringList, tag, def, group1, group2);
|
||||
store(stringList, stringList, tag, group1, group2);
|
||||
}
|
||||
|
||||
void CompStoreObj::getset( QString &string, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
retrieve( string, tag, def, group1, group2);
|
||||
store(string, string, tag, group1, group2);
|
||||
}
|
||||
|
||||
void CompStoreObj::getset( bool &truth, const QString tag, const bool def, const QString group1, const QString group2 )
|
||||
{
|
||||
retrieve( truth, tag, def, group1, group2);
|
||||
store(truth, truth, tag, group1, group2);
|
||||
}
|
||||
|
||||
void CompStoreObj::getset( int &number, const QString tag, const int def, const QString group1, const QString group2 )
|
||||
{
|
||||
retrieve( number, tag, def, group1, group2);
|
||||
store(number, number, tag, group1, group2);
|
||||
}
|
||||
|
||||
// ** FwRevision class********************
|
||||
int FwRevision::get( const QString fwType )
|
||||
{
|
||||
QString result;
|
||||
retrieve( result, fwType, "", "FwRevisions" );
|
||||
return result.toInt();
|
||||
}
|
||||
|
||||
void FwRevision::set( const QString fwType, const int fwRevision )
|
||||
{
|
||||
QString tempString = QString("%1").arg(fwRevision);
|
||||
store( tempString, tempString, fwType, "FwRevisions" );
|
||||
}
|
||||
|
||||
void FwRevision::remove( const QString tag )
|
||||
{
|
||||
clear( "FwRevisions", tag );
|
||||
}
|
||||
|
||||
// ** JStickData class********************
|
||||
// Get declarations
|
||||
int JStickData::stick_axe() { return _stickAxe; }
|
||||
int JStickData::stick_min() { return _stickMin; }
|
||||
int JStickData::stick_med() { return _stickMed; }
|
||||
int JStickData::stick_max() { return _stickMax; }
|
||||
int JStickData::stick_inv() { return _stickInv; }
|
||||
|
||||
// Set declarations
|
||||
void JStickData::stick_axe(const int it) { store( it, _stickAxe, QString("stick%1_axe").arg(index), "JsCalibration" );}
|
||||
void JStickData::stick_min(const int it) { store( it, _stickMin, QString("stick%1_min").arg(index), "JsCalibration" );}
|
||||
void JStickData::stick_med(const int it) { store( it, _stickMed, QString("stick%1_med").arg(index), "JsCalibration" );}
|
||||
void JStickData::stick_max(const int it) { store( it, _stickMax, QString("stick%1_max").arg(index), "JsCalibration" );}
|
||||
void JStickData::stick_inv(const int it) { store( it, _stickInv, QString("stick%1_inv").arg(index), "JsCalibration" );}
|
||||
|
||||
// Constructor
|
||||
JStickData::JStickData()
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
|
||||
void JStickData::remove()
|
||||
{
|
||||
// Remove all JStickData values from settings file
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup( "JsCalibration" );
|
||||
settings.remove( QString( "stick%1_axe").arg(index) );
|
||||
settings.remove( QString( "stick%1_min").arg(index) );
|
||||
settings.remove( QString( "stick%1_med").arg(index) );
|
||||
settings.remove( QString( "stick%1_max").arg(index) );
|
||||
settings.remove( QString( "stick%1_inv").arg(index) );
|
||||
settings.endGroup();
|
||||
|
||||
// Reset all JStickData variables to initial values
|
||||
init(index);
|
||||
}
|
||||
|
||||
bool JStickData::existsOnDisk()
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("JsCalibration");
|
||||
int axe = settings.value( QString("stick%1_axe").arg(index), -1 ).toInt();
|
||||
settings.endGroup();
|
||||
|
||||
return (axe > -1);
|
||||
}
|
||||
|
||||
void JStickData::init(int newIndex)
|
||||
{
|
||||
index = newIndex;
|
||||
_stickAxe = -1;
|
||||
_stickMin = -32767;
|
||||
_stickMed = 0;
|
||||
_stickMax = 0;
|
||||
_stickInv = 0;
|
||||
|
||||
// Do not write empty joystick calibrations to disk.
|
||||
if ( !existsOnDisk() )
|
||||
return;
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
void JStickData::flush()
|
||||
{
|
||||
getset( _stickAxe, QString("stick%1_axe").arg(index), -1, "JsCalibration" );
|
||||
getset( _stickMin, QString("stick%1_min").arg(index), -32767, "JsCalibration" );
|
||||
getset( _stickMed, QString("stick%1_med").arg(index), 0, "JsCalibration" );
|
||||
getset( _stickMax, QString("stick%1_max").arg(index), 0, "JsCalibration" );
|
||||
getset( _stickInv, QString("stick%1_inv").arg(index), 0, "JsCalibration" );
|
||||
}
|
||||
|
||||
// ** Profile class********************
|
||||
// Get declarations
|
||||
QString Profile::fwName() const { return _fwName; }
|
||||
QString Profile::fwType() const { return _fwType; }
|
||||
QString Profile::name() const { return _name; }
|
||||
QString Profile::sdPath() const { return _sdPath; }
|
||||
int Profile::volumeGain() const { return _volumeGain; }
|
||||
QString Profile::pBackupDir() const { return _pBackupDir; }
|
||||
QString Profile::splashFile() const { return _splashFile; }
|
||||
bool Profile::burnFirmware() const { return _burnFirmware; }
|
||||
bool Profile::penableBackup() const { return _penableBackup; }
|
||||
bool Profile::renameFwFiles() const { return _renameFwFiles; }
|
||||
int Profile::channelOrder() const { return _channelOrder; }
|
||||
int Profile::defaultMode() const { return _defaultMode; }
|
||||
|
||||
QString Profile::beeper() const { return _beeper; }
|
||||
QString Profile::countryCode() const { return _countryCode; }
|
||||
QString Profile::display() const { return _display; }
|
||||
QString Profile::haptic() const { return _haptic; }
|
||||
QString Profile::speaker() const { return _speaker; }
|
||||
QString Profile::stickPotCalib() const { return _stickPotCalib; }
|
||||
QString Profile::timeStamp() const { return _timeStamp; }
|
||||
QString Profile::trainerCalib() const { return _trainerCalib; }
|
||||
QString Profile::controlTypes() const { return _controlTypes; }
|
||||
QString Profile::controlNames() const { return _controlNames; }
|
||||
int Profile::txCurrentCalibration() const { return _txCurrentCalibration; }
|
||||
int Profile::gsStickMode() const { return _gsStickMode; }
|
||||
int Profile::ppmMultiplier() const { return _ppmMultiplier; }
|
||||
int Profile::txVoltageCalibration() const { return _txVoltageCalibration; }
|
||||
int Profile::vBatWarn() const { return _vBatWarn; }
|
||||
int Profile::vBatMin() const { return _vBatMin; }
|
||||
int Profile::vBatMax() const { return _vBatMax; }
|
||||
|
||||
// Set declarations
|
||||
void Profile::name (const QString x) { store(x, _name, "Name" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::fwName (const QString x) { store(x, _fwName, "fwName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::fwType (const QString x) { store(x, _fwType, "fwType" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::sdPath (const QString x) { store(x, _sdPath, "sdPath" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::volumeGain (const int x) { store(x, _volumeGain, "volumeGain" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::pBackupDir (const QString x) { store(x, _pBackupDir, "pBackupDir" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::splashFile (const QString x) { store(x, _splashFile, "SplashFileName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::burnFirmware (const bool x) { store(x, _burnFirmware, "burnFirmware" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::renameFwFiles (const bool x) { store(x, _renameFwFiles, "rename_firmware_files" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::penableBackup (const bool x) { store(x, _penableBackup, "penableBackup" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::channelOrder (const int x) { store(x, _channelOrder, "default_channel_order" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::defaultMode (const int x) { store(x, _defaultMode, "default_mode" ,"Profiles", QString("profile%1").arg(index));}
|
||||
|
||||
void Profile::beeper (const QString x) { store(x, _beeper, "Beeper" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::countryCode (const QString x) { store(x, _countryCode, "countryCode" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::display (const QString x) { store(x, _display, "Display" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::haptic (const QString x) { store(x, _haptic, "Haptic" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::speaker (const QString x) { store(x, _speaker, "Speaker" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::stickPotCalib (const QString x) { store(x, _stickPotCalib, "StickPotCalib" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::timeStamp (const QString x) { store(x, _timeStamp, "TimeStamp" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::trainerCalib (const QString x) { store(x, _trainerCalib, "TrainerCalib" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::controlTypes (const QString x) { store(x, _controlTypes, "ControlTypes" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::controlNames (const QString x) { store(x, _controlNames, "ControlNames" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::txCurrentCalibration (const int x) { store(x, _txCurrentCalibration, "currentCalib","Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::gsStickMode (const int x) { store(x, _gsStickMode, "GSStickMode" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::ppmMultiplier (const int x) { store(x, _ppmMultiplier, "PPM_Multiplier" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::txVoltageCalibration (const int x) { store(x, _txVoltageCalibration, "VbatCalib","Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatWarn (const int x) { store(x, _vBatWarn, "vBatWarn" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatMin (const int x) { store(x, _vBatMin, "VbatMin" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatMax (const int x) { store(x, _vBatMax, "VbatMax" ,"Profiles", QString("profile%1").arg(index));}
|
||||
|
||||
// Constructor
|
||||
Profile::Profile()
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
|
||||
// The default copy operator can not be used since the index variable would be destroyed
|
||||
Profile& Profile::operator=(const Profile& rhs)
|
||||
{
|
||||
name ( rhs.name() );
|
||||
fwName ( rhs.fwName() );
|
||||
fwType ( rhs.fwType() );
|
||||
sdPath ( rhs.sdPath() );
|
||||
volumeGain ( rhs.volumeGain() );
|
||||
pBackupDir ( rhs.pBackupDir() );
|
||||
splashFile ( rhs.splashFile() );
|
||||
burnFirmware ( rhs.burnFirmware() );
|
||||
renameFwFiles( rhs.renameFwFiles() );
|
||||
penableBackup( rhs.penableBackup() );
|
||||
channelOrder ( rhs.channelOrder() );
|
||||
defaultMode ( rhs.defaultMode() );
|
||||
beeper ( rhs.beeper() );
|
||||
countryCode ( rhs.countryCode() );
|
||||
display ( rhs.display() );
|
||||
haptic ( rhs.haptic() );
|
||||
speaker ( rhs.speaker() );
|
||||
stickPotCalib( rhs.stickPotCalib() );
|
||||
trainerCalib ( rhs.trainerCalib() );
|
||||
controlTypes ( rhs.controlTypes() );
|
||||
controlNames ( rhs.controlNames() );
|
||||
txCurrentCalibration ( rhs.txCurrentCalibration() );
|
||||
gsStickMode ( rhs.gsStickMode() );
|
||||
ppmMultiplier( rhs.ppmMultiplier() );
|
||||
txVoltageCalibration ( rhs.txVoltageCalibration() );
|
||||
vBatWarn ( rhs.vBatWarn() );
|
||||
vBatMin ( rhs.vBatMin() );
|
||||
vBatMax ( rhs.vBatMax() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Profile::remove()
|
||||
{
|
||||
// Remove all profile values from settings file
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("Profiles");
|
||||
settings.remove(QString("profile%1").arg(index));
|
||||
settings.endGroup();
|
||||
|
||||
// Reset all profile variables to initial values
|
||||
init(index);
|
||||
}
|
||||
|
||||
bool Profile::existsOnDisk()
|
||||
{
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("Profiles");
|
||||
settings.beginGroup(QString("profile%1").arg(index));
|
||||
QStringList keyList = settings.allKeys();
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
return (keyList.length() > 0);
|
||||
}
|
||||
|
||||
void Profile::initFwVariables()
|
||||
{
|
||||
_beeper = "";
|
||||
_countryCode = "";
|
||||
_display = "";
|
||||
_haptic = "";
|
||||
_speaker = "";
|
||||
_stickPotCalib = "";
|
||||
_timeStamp = "";
|
||||
_trainerCalib = "";
|
||||
_controlTypes = "";
|
||||
_controlNames = "";
|
||||
|
||||
_txCurrentCalibration = 0;
|
||||
_gsStickMode = 0;
|
||||
_ppmMultiplier = 0;
|
||||
_txVoltageCalibration = 0;
|
||||
_vBatWarn = 0;
|
||||
_vBatMin = 0;
|
||||
_vBatMax = 0;
|
||||
}
|
||||
|
||||
void Profile::init(int newIndex)
|
||||
{
|
||||
index = newIndex;
|
||||
|
||||
_fwName = "";
|
||||
_fwType = "";
|
||||
_name = "";
|
||||
_sdPath = "";
|
||||
_volumeGain = 10;
|
||||
_pBackupDir = "";
|
||||
_splashFile = "";
|
||||
_burnFirmware = false;
|
||||
_renameFwFiles = false;
|
||||
_penableBackup = false;
|
||||
_channelOrder = 0;
|
||||
_defaultMode = 1;
|
||||
|
||||
initFwVariables();
|
||||
|
||||
// Do not write empty profiles to disk except the default (0) profile.
|
||||
if ( index > 0 && !existsOnDisk())
|
||||
return;
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
void Profile::flush()
|
||||
{
|
||||
// Load and store all variables. Use default values if setting values are missing
|
||||
getset( _fwName, "fwName" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _fwType, "fwType" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _name, "Name" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _sdPath, "sdPath" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _volumeGain, "volumeGain" ,10 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _pBackupDir, "pBackupDir" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _splashFile, "SplashFileName" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _burnFirmware, "burnFirmware" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _penableBackup, "penableBackup" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _renameFwFiles, "rename_firmware_files" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _channelOrder, "default_channel_order" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _defaultMode, "default_mode" ,1 ,"Profiles", QString("profile%1").arg(index));
|
||||
|
||||
getset( _beeper, "Beeper" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _countryCode, "countryCode" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _display, "Display" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _haptic, "Haptic" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _speaker, "Speaker" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _stickPotCalib, "StickPotCalib" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _timeStamp, "TimeStamp" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _trainerCalib, "TrainerCalib" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _controlTypes, "ControlTypes" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _controlNames, "ControlNames" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _txCurrentCalibration, "currentCalib" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _gsStickMode, "GSStickMode" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _ppmMultiplier, "PPM_Multiplier" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _txVoltageCalibration, "VbatCalib" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatWarn, "vBatWarn" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatMin, "VbatMin" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatMax, "VbatMax" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
}
|
||||
|
||||
|
||||
// ** AppData class********************
|
||||
|
||||
// Get declarations
|
||||
QStringList AppData::recentFiles() { return _recentFiles; }
|
||||
QByteArray AppData::mainWinGeo() { return _mainWinGeo; }
|
||||
QByteArray AppData::mainWinState() { return _mainWinState; }
|
||||
QByteArray AppData::modelEditGeo() { return _modelEditGeo; }
|
||||
|
||||
QString AppData::armMcu() { return _armMcu; }
|
||||
QString AppData::avrArguments() { return _avrArguments; }
|
||||
QString AppData::avrPort() { return _avrPort; }
|
||||
QString AppData::avrdudeLocation() { return _avrdudeLocation; }
|
||||
QString AppData::dfuArguments() { return _dfuArguments; }
|
||||
QString AppData::dfuLocation() { return _dfuLocation; }
|
||||
QString AppData::locale() { return _locale; }
|
||||
QString AppData::mcu() { return _mcu; }
|
||||
QString AppData::programmer() { return _programmer; }
|
||||
QString AppData::sambaLocation() { return _sambaLocation; }
|
||||
QString AppData::sambaPort() { return _sambaPort; }
|
||||
QString AppData::lastSimulator() { return _lastSimulator; }
|
||||
|
||||
QString AppData::backupDir() { return _backupDir; }
|
||||
QString AppData::gePath() { return _gePath; }
|
||||
QString AppData::eepromDir() { return _eepromDir; }
|
||||
QString AppData::flashDir() { return _flashDir; }
|
||||
QString AppData::imagesDir() { return _imagesDir; }
|
||||
QString AppData::logDir() { return _logDir; }
|
||||
QString AppData::libDir() { return _libDir; }
|
||||
QString AppData::snapshotDir() { return _snapshotDir; }
|
||||
QString AppData::updatesDir() { return _updatesDir; }
|
||||
|
||||
bool AppData::jsSupport() { return _jsSupport; }
|
||||
bool AppData::maximized() { return _maximized; }
|
||||
bool AppData::showSplash() { return _showSplash; }
|
||||
bool AppData::snapToClpbrd() { return _snapToClpbrd; }
|
||||
bool AppData::autoCheckApp() { return _autoCheckApp; }
|
||||
bool AppData::autoCheckFw() { return _autoCheckFw; }
|
||||
bool AppData::simuSW() { return _simuSW; }
|
||||
bool AppData::useWizard() { return _useWizard; }
|
||||
|
||||
int AppData::backLight() { return _backLight; }
|
||||
int AppData::embedSplashes() { return _embedSplashes; }
|
||||
int AppData::fwServerFails() { return _fwServerFails; }
|
||||
int AppData::generalEditTab() { return _generalEditTab; }
|
||||
int AppData::iconSize() { return _iconSize; }
|
||||
int AppData::historySize() { return _historySize; }
|
||||
int AppData::jsCtrl() { return _jsCtrl; }
|
||||
int AppData::id() { return _id; }
|
||||
int AppData::theme() { return _theme; }
|
||||
int AppData::warningId() { return _warningId; }
|
||||
|
||||
// Set declarations
|
||||
void AppData::recentFiles (const QStringList x) { store(x, _recentFiles, "recentFileList" );}
|
||||
void AppData::mainWinGeo (const QByteArray x) { store(x, _mainWinGeo, "mainWindowGeometry" );}
|
||||
void AppData::mainWinState (const QByteArray x) { store(x, _mainWinState, "mainWindowState" );}
|
||||
void AppData::modelEditGeo (const QByteArray x) { store(x, _modelEditGeo, "modelEditGeometry" );}
|
||||
|
||||
void AppData::armMcu (const QString x) { store(x, _armMcu, "arm_mcu" );}
|
||||
void AppData::avrArguments (const QString x) { store(x, _avrArguments, "avr_arguments" );}
|
||||
void AppData::avrPort (const QString x) { store(x, _avrPort, "avr_port" );}
|
||||
void AppData::avrdudeLocation (const QString x) { store(x, _avrdudeLocation, "avrdudeLocation" );}
|
||||
void AppData::dfuArguments (const QString x) { store(x, _dfuArguments, "dfu_arguments" );}
|
||||
void AppData::dfuLocation (const QString x) { store(x, _dfuLocation, "dfu_location" );}
|
||||
void AppData::locale (const QString x) { store(x, _locale, "locale" );}
|
||||
void AppData::mcu (const QString x) { store(x, _mcu, "mcu" );}
|
||||
void AppData::programmer (const QString x) { store(x, _programmer, "programmer" );}
|
||||
void AppData::sambaLocation (const QString x) { store(x, _sambaLocation, "samba_location" );}
|
||||
void AppData::sambaPort (const QString x) { store(x, _sambaPort, "samba_port" );}
|
||||
void AppData::lastSimulator (const QString x) { store(x, _lastSimulator, "last_simulator" );}
|
||||
|
||||
void AppData::backupDir (const QString x) { store(x, _backupDir, "backupPath" );}
|
||||
void AppData::gePath (const QString x) { store(x, _gePath, "gePath" );}
|
||||
void AppData::eepromDir (const QString x) { store(x, _eepromDir, "lastDir" );}
|
||||
void AppData::flashDir (const QString x) { store(x, _flashDir, "lastFlashDir" );}
|
||||
void AppData::imagesDir (const QString x) { store(x, _imagesDir, "lastImagesDir" );}
|
||||
void AppData::logDir (const QString x) { store(x, _logDir, "lastLogDir" );}
|
||||
void AppData::libDir (const QString x) { store(x, _libDir, "libraryPath" );}
|
||||
void AppData::snapshotDir (const QString x) { store(x, _snapshotDir, "snapshotpath" );}
|
||||
void AppData::updatesDir (const QString x) { store(x, _updatesDir, "lastUpdatesDir" );}
|
||||
|
||||
void AppData::maximized (const bool x) { store(x, _maximized, "maximized" );}
|
||||
void AppData::jsSupport (const bool x) { store(x, _jsSupport, "js_support" );}
|
||||
void AppData::showSplash (const bool x) { store(x, _showSplash, "show_splash" );}
|
||||
void AppData::snapToClpbrd (const bool x) { store(x, _snapToClpbrd, "snapshot_to_clipboard" );}
|
||||
void AppData::autoCheckApp (const bool x) { store(x, _autoCheckApp, "startup_check_companion" );}
|
||||
void AppData::autoCheckFw (const bool x) { store(x, _autoCheckFw, "startup_check_fw" );}
|
||||
void AppData::simuSW (const bool x) { store(x, _simuSW, "simuSW" );}
|
||||
void AppData::useWizard (const bool x) { store(x, _useWizard, "useWizard" );}
|
||||
|
||||
void AppData::backLight (const int x) { store(x, _backLight, "backLight" );}
|
||||
void AppData::embedSplashes (const int x) { store(x, _embedSplashes, "embedded_splashes" );}
|
||||
void AppData::fwServerFails (const int x) { store(x, _fwServerFails, "fwserver" );}
|
||||
void AppData::generalEditTab (const int x) { store(x, _generalEditTab, "generalEditTab" );}
|
||||
void AppData::iconSize (const int x) { store(x, _iconSize, "icon_size" );}
|
||||
void AppData::historySize (const int x) { store(x, _historySize, "history_size" );}
|
||||
void AppData::jsCtrl (const int x) { store(x, _jsCtrl, "js_ctrl" );}
|
||||
void AppData::id (const int x) { store(x, _id, "profileId" );}
|
||||
void AppData::theme (const int x) { store(x, _theme, "theme" );}
|
||||
void AppData::warningId (const int x) { store(x, _warningId, "warningId" );}
|
||||
|
||||
// Constructor
|
||||
AppData::AppData()
|
||||
{
|
||||
}
|
||||
|
||||
void AppData::init()
|
||||
{
|
||||
//Initialize the profiles
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
profile[i].init( i );
|
||||
|
||||
//Initialize the joysticks
|
||||
for (int i=0; i<MAX_JOYSTICKS; i++)
|
||||
joystick[i].init( i );
|
||||
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
|
||||
// Copy existing 2.1 settings if present
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings settings21("OpenTX", "Companion 2.1");
|
||||
|
||||
QStringList keys = settings21.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
{
|
||||
if (settings21.value(*i) != QString("") && settings21.value(*i) != QString("Start Menu Folder"))
|
||||
{
|
||||
settings.setValue(*i, settings21.value(*i));
|
||||
}
|
||||
}
|
||||
|
||||
//Reload profiles
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
profile[i].init( i );
|
||||
}
|
||||
|
||||
// Copy existing 2.0 settings if present
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings settings20("OpenTX", "Companion 2.0");
|
||||
|
||||
QStringList keys = settings20.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
{
|
||||
if (settings20.value(*i) != QString("") && settings20.value(*i) != QString("Start Menu Folder"))
|
||||
{
|
||||
settings.setValue(*i, settings20.value(*i));
|
||||
}
|
||||
}
|
||||
|
||||
//Reload profiles
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
profile[i].init( i );
|
||||
}
|
||||
|
||||
// Else copy existing <2.0.16 settings if present
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings pre2016settings("OpenTX", "OpenTX Companion");
|
||||
|
||||
QStringList keys = pre2016settings.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
{
|
||||
if (pre2016settings.value(*i) != QString("") && pre2016settings.value(*i) != QString("Start Menu Folder"))
|
||||
{
|
||||
settings.setValue(*i, pre2016settings.value(*i));
|
||||
}
|
||||
}
|
||||
|
||||
//Reload profiles
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
profile[i].init( i );
|
||||
}
|
||||
|
||||
// Else import settings from companion9x if present
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings c9x_settings("companion9x", "companion9x");
|
||||
// Copy all settings from companion9x to companion
|
||||
QStringList keys = c9x_settings.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
{
|
||||
settings.setValue(*i, c9x_settings.value(*i));
|
||||
}
|
||||
|
||||
// Store old values in new locations
|
||||
autoCheckApp(settings.value("startup_check_companion9x", true).toBool());
|
||||
useWizard(settings.value("wizardEnable", true).toBool());
|
||||
|
||||
// Convert and store the firmware type
|
||||
QString fwType = settings.value("firmware", "").toString();
|
||||
fwType.replace("open9x","opentx");
|
||||
fwType.replace("x9da","taranis");
|
||||
profile[0].fwType( fwType );
|
||||
|
||||
// Move the Companion9x profile settings to profile0, the new default profile
|
||||
profile[0].name( settings.value( "Name", "" ).toString());
|
||||
profile[0].sdPath( settings.value( "sdPath", "" ).toString());
|
||||
profile[0].splashFile( settings.value( "SplashFileName", "" ).toString());
|
||||
profile[0].burnFirmware( settings.value( "burnFirmware", false ).toBool());
|
||||
profile[0].renameFwFiles( settings.value( "rename_firmware_files", false ).toBool());
|
||||
profile[0].channelOrder( settings.value( "default_channel_order", "0" ).toInt());
|
||||
profile[0].defaultMode( settings.value( "default_mode", "1" ).toInt());
|
||||
|
||||
// Ensure that the default profile has a name
|
||||
if ( profile[0].name().isEmpty() )
|
||||
profile[0].name("My Radio");
|
||||
|
||||
// Delete obsolete settings fields from companion9x
|
||||
settings.remove("ActiveProfile");
|
||||
settings.remove("burnFirmware");
|
||||
settings.remove("custom_id");
|
||||
settings.remove("default_channel_order");
|
||||
settings.remove("default_mode");
|
||||
settings.remove("firmware");
|
||||
settings.remove("lastFw");
|
||||
settings.remove("modelEditTab");
|
||||
settings.remove("Name");
|
||||
settings.remove("patchImage");
|
||||
settings.remove("rename_firmware_files");
|
||||
settings.remove("sdPath");
|
||||
settings.remove("SplashFileName");
|
||||
settings.remove("startup_check_companion9x");
|
||||
settings.remove("wizardEnable");
|
||||
|
||||
// Delete settings that we do not want to carry over from 1.52
|
||||
settings.remove("dfu_location");
|
||||
|
||||
// Select the new default profile as current profile
|
||||
id( 0 );
|
||||
}
|
||||
|
||||
// Remove settings that have been made obsolete during companion2.0 development
|
||||
settings.remove("compilation-server");
|
||||
|
||||
// Load and store all variables. Use default values if setting values are missing
|
||||
QString _tempString; // Do not touch. Do not change the settings version before a new verson update!
|
||||
getset( _tempString, "settings_version" ,"220" ); // This is a version marker. Will be used to upgrade the settings later on.
|
||||
|
||||
getset( _recentFiles, "recentFileList" ,"" );
|
||||
getset( _mainWinGeo, "mainWindowGeometry" ,"" );
|
||||
getset( _mainWinState, "mainWindowState" ,"" );
|
||||
getset( _modelEditGeo, "modelEditGeometry" ,"" );
|
||||
|
||||
getset( _armMcu, "arm_mcu" ,"at91sam3s4-9x" );
|
||||
getset( _avrArguments, "avr_arguments" ,"" );
|
||||
getset( _avrPort, "avr_port" ,"" );
|
||||
getset( _avrdudeLocation, "avrdudeLocation" ,"" );
|
||||
getset( _dfuArguments, "dfu_arguments" ,"-a 0" );
|
||||
getset( _dfuLocation, "dfu_location" ,"" );
|
||||
getset( _locale, "locale" ,"" );
|
||||
getset( _mcu, "mcu" ,"m64" );
|
||||
getset( _programmer, "programmer" ,"usbasp" );
|
||||
getset( _sambaLocation, "samba_location" ,"" );
|
||||
getset( _sambaPort, "samba_port" ,"\\USBserial\\COM23" );
|
||||
getset( _lastSimulator, "last_simulator" ,"" );
|
||||
|
||||
getset( _backupDir, "backupPath" ,"" );
|
||||
getset( _gePath, "gePath" ,"" );
|
||||
getset( _eepromDir, "lastDir" ,"" );
|
||||
getset( _flashDir, "lastFlashDir" ,"" );
|
||||
getset( _imagesDir, "lastImagesDir" ,"" );
|
||||
getset( _logDir, "lastLogDir" ,"" );
|
||||
getset( _libDir, "libraryPath" ,"" );
|
||||
getset( _snapshotDir, "snapshotpath" ,"" );
|
||||
getset( _updatesDir, "lastUpdatesDir" ,"" );
|
||||
|
||||
getset( _outputDisplayDetails, "outputDisplayDetails" ,false );
|
||||
getset( _enableBackup, "enableBackup" ,false );
|
||||
getset( _backupOnFlash, "backupOnFlash" ,true );
|
||||
getset( _checkHardwareCompatibility, "checkHardwareCompatibility" ,true );
|
||||
|
||||
getset( _useCompanionNightlyBuilds, "useCompanionNightlyBuilds" ,false );
|
||||
getset( _useFirmwareNightlyBuilds, "useFirmwareNightlyBuilds" ,false );
|
||||
|
||||
getset( _jsSupport, "js_support" ,false );
|
||||
getset( _maximized, "maximized" ,false );
|
||||
getset( _showSplash, "show_splash" ,true );
|
||||
getset( _snapToClpbrd, "snapshot_to_clipboard" ,false );
|
||||
getset( _autoCheckApp, "startup_check_companion" ,true );
|
||||
getset( _autoCheckFw, "startup_check_fw" ,true );
|
||||
getset( _simuSW, "simuSW" ,false );
|
||||
getset( _useWizard, "useWizard" ,true );
|
||||
|
||||
getset( _backLight, "backLight" ,0 );
|
||||
getset( _embedSplashes, "embedded_splashes" ,0 );
|
||||
getset( _fwServerFails, "fwserver" ,0 );
|
||||
getset( _generalEditTab, "generalEditTab" ,0 );
|
||||
getset( _iconSize, "icon_size" ,2 );
|
||||
getset( _jsCtrl, "js_ctrl" ,0 );
|
||||
getset( _historySize, "history_size" ,10 );
|
||||
getset( _id, "profileId" ,0 );
|
||||
getset( _theme, "theme" ,1 );
|
||||
getset( _warningId, "warningId" ,0 );
|
||||
}
|
||||
@@ -1,392 +0,0 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
// All temporary and permanent global variables are defined here to make
|
||||
// initialization and storage safe and visible.
|
||||
// Do not access variables in QSettings directly, it is not type safe!
|
||||
|
||||
|
||||
#ifndef COMPANION_APPDATA_H
|
||||
#define COMPANION_APPDATA_H
|
||||
#include <QByteArray>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
|
||||
#define COMPANY "OpenTX"
|
||||
#define PRODUCT "Companion 2.2"
|
||||
|
||||
#define MAX_PROFILES 15
|
||||
#define MAX_JOYSTICKS 8
|
||||
|
||||
class CompStoreObj
|
||||
{
|
||||
public:
|
||||
void clear (const QString tag1="", const QString tag2="", const QString tag3="");
|
||||
void store(const QByteArray newArray, QByteArray &array, const QString tag, const QString group1="", const QString group2="" );
|
||||
void store(const QStringList newSList, QStringList &stringList, const QString tag, const QString group1="", const QString group2="" );
|
||||
void store(const QString newString, QString &string, const QString tag, const QString group1="", const QString group2="" );
|
||||
void store(const bool newTruth, bool &truth, const QString tag, const QString group1="", const QString group2="" );
|
||||
void store(const int newNumber, int &number, const QString tag, const QString group1="", const QString group2="" );
|
||||
|
||||
// Retrieval functions
|
||||
void retrieve( QByteArray &array, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void retrieve( QStringList &stringList, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void retrieve( QString &string, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void retrieve( bool &truth, const QString tag, const bool def, const QString group1="", const QString group2="" );
|
||||
void retrieve( int &number, const QString tag, const int def, const QString group1="", const QString group2="" );
|
||||
|
||||
// Retrieve and Store functions
|
||||
void getset( QByteArray &array, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void getset( QStringList &stringList, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void getset( QString &string, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void getset( bool &truth, const QString tag, const bool def, const QString group1="", const QString group2="" );
|
||||
void getset( int &number, const QString tag, const int def, const QString group1="", const QString group2="" );
|
||||
};
|
||||
|
||||
class FwRevision: protected CompStoreObj
|
||||
{
|
||||
public:
|
||||
int get( const QString);
|
||||
void set( const QString, const int );
|
||||
void remove( const QString );
|
||||
};
|
||||
|
||||
class JStickData: protected CompStoreObj
|
||||
{
|
||||
private:
|
||||
int index;
|
||||
|
||||
int _stickAxe;
|
||||
int _stickMin;
|
||||
int _stickMed;
|
||||
int _stickMax;
|
||||
int _stickInv;
|
||||
|
||||
public:
|
||||
// All the get definitions
|
||||
int stick_axe();
|
||||
int stick_min();
|
||||
int stick_med();
|
||||
int stick_max();
|
||||
int stick_inv();
|
||||
|
||||
// All the set definitions
|
||||
void stick_axe(const int);
|
||||
void stick_min(const int);
|
||||
void stick_med(const int);
|
||||
void stick_max(const int);
|
||||
void stick_inv(const int);
|
||||
|
||||
JStickData();
|
||||
void remove();
|
||||
bool existsOnDisk();
|
||||
void init(int index);
|
||||
void flush();
|
||||
};
|
||||
|
||||
class Profile: protected CompStoreObj
|
||||
{
|
||||
private:
|
||||
// Class Internal Variable
|
||||
int index;
|
||||
|
||||
// Application Variables
|
||||
QString _fwName;
|
||||
QString _fwType;
|
||||
QString _name;
|
||||
QString _sdPath;
|
||||
int _volumeGain;
|
||||
QString _pBackupDir;
|
||||
QString _splashFile;
|
||||
bool _burnFirmware;
|
||||
bool _penableBackup;
|
||||
bool _renameFwFiles;
|
||||
int _channelOrder;
|
||||
int _defaultMode;
|
||||
|
||||
// Firmware Variables
|
||||
QString _beeper;
|
||||
QString _countryCode;
|
||||
QString _display;
|
||||
QString _haptic;
|
||||
QString _speaker;
|
||||
QString _stickPotCalib;
|
||||
QString _timeStamp;
|
||||
QString _trainerCalib;
|
||||
QString _controlTypes;
|
||||
QString _controlNames;
|
||||
int _txCurrentCalibration;
|
||||
int _gsStickMode;
|
||||
int _ppmMultiplier;
|
||||
int _txVoltageCalibration;
|
||||
int _vBatWarn;
|
||||
int _vBatMin;
|
||||
int _vBatMax;
|
||||
|
||||
public:
|
||||
// All the get definitions
|
||||
QString fwName() const;
|
||||
QString fwType() const;
|
||||
QString name() const;
|
||||
QString sdPath() const;
|
||||
int volumeGain() const;
|
||||
QString pBackupDir() const;
|
||||
QString splashFile() const;
|
||||
bool burnFirmware() const;
|
||||
bool renameFwFiles() const;
|
||||
bool penableBackup() const;
|
||||
int channelOrder() const;
|
||||
int defaultMode() const;
|
||||
|
||||
QString beeper() const;
|
||||
QString countryCode() const;
|
||||
QString display() const;
|
||||
QString haptic() const;
|
||||
QString speaker() const;
|
||||
QString stickPotCalib() const;
|
||||
QString timeStamp() const;
|
||||
QString trainerCalib() const;
|
||||
QString controlTypes() const;
|
||||
QString controlNames() const;
|
||||
int txCurrentCalibration() const;
|
||||
int gsStickMode() const;
|
||||
int ppmMultiplier() const;
|
||||
int txVoltageCalibration() const;
|
||||
int vBatWarn() const;
|
||||
int vBatMin() const;
|
||||
int vBatMax() const;
|
||||
|
||||
// All the set definitions
|
||||
void name (const QString);
|
||||
void fwName (const QString);
|
||||
void fwType (const QString);
|
||||
void volumeGain (const int);
|
||||
void sdPath (const QString);
|
||||
void pBackupDir (const QString);
|
||||
void splashFile (const QString);
|
||||
void burnFirmware (const bool);
|
||||
void renameFwFiles (const bool);
|
||||
void penableBackup (const bool);
|
||||
void channelOrder (const int);
|
||||
void defaultMode (const int);
|
||||
|
||||
void beeper (const QString);
|
||||
void countryCode (const QString);
|
||||
void display (const QString);
|
||||
void haptic (const QString);
|
||||
void speaker (const QString);
|
||||
void stickPotCalib (const QString);
|
||||
void timeStamp (const QString);
|
||||
void trainerCalib (const QString);
|
||||
void controlTypes (const QString);
|
||||
void controlNames (const QString);
|
||||
void txCurrentCalibration (const int);
|
||||
void gsStickMode (const int);
|
||||
void ppmMultiplier (const int);
|
||||
void txVoltageCalibration (const int);
|
||||
void vBatWarn (const int);
|
||||
void vBatMin (const int);
|
||||
void vBatMax (const int);
|
||||
|
||||
Profile();
|
||||
Profile& operator=(const Profile&);
|
||||
void remove();
|
||||
bool existsOnDisk();
|
||||
void init(int newIndex);
|
||||
void initFwVariables();
|
||||
void flush();
|
||||
};
|
||||
|
||||
#define BOOL_PROPERTY(name, dflt) \
|
||||
public: \
|
||||
inline bool name() { return _ ## name; } \
|
||||
void name(const bool val) { store(val, _ ## name, # name); } \
|
||||
private: \
|
||||
bool _ ## name;
|
||||
|
||||
class AppData: protected CompStoreObj
|
||||
{
|
||||
BOOL_PROPERTY(enableBackup, false)
|
||||
BOOL_PROPERTY(outputDisplayDetails, false)
|
||||
BOOL_PROPERTY(backupOnFlash, true)
|
||||
BOOL_PROPERTY(checkHardwareCompatibility, true)
|
||||
BOOL_PROPERTY(useCompanionNightlyBuilds, false)
|
||||
BOOL_PROPERTY(useFirmwareNightlyBuilds, false)
|
||||
|
||||
// All the global variables
|
||||
public:
|
||||
Profile profile[MAX_PROFILES];
|
||||
JStickData joystick[MAX_JOYSTICKS];
|
||||
FwRevision fwRev;
|
||||
|
||||
private:
|
||||
QStringList _recentFiles;
|
||||
QByteArray _mainWinGeo;
|
||||
QByteArray _mainWinState;
|
||||
QByteArray _modelEditGeo;
|
||||
|
||||
QString _armMcu;
|
||||
QString _avrArguments;
|
||||
QString _avrPort;
|
||||
QString _avrdudeLocation;
|
||||
QString _dfuArguments;
|
||||
QString _dfuLocation;
|
||||
QString _locale;
|
||||
QString _mcu;
|
||||
QString _programmer;
|
||||
QString _sambaLocation;
|
||||
QString _sambaPort;
|
||||
QString _lastSimulator;
|
||||
|
||||
QString _backupDir;
|
||||
QString _gePath;
|
||||
QString _eepromDir;
|
||||
QString _flashDir;
|
||||
QString _imagesDir;
|
||||
QString _logDir;
|
||||
QString _libDir;
|
||||
QString _snapshotDir;
|
||||
QString _updatesDir;
|
||||
|
||||
bool _maximized;
|
||||
bool _jsSupport;
|
||||
bool _showSplash;
|
||||
bool _snapToClpbrd;
|
||||
bool _autoCheckApp;
|
||||
bool _autoCheckFw;
|
||||
bool _simuSW;
|
||||
bool _useWizard;
|
||||
|
||||
int _backLight;
|
||||
int _embedSplashes;
|
||||
int _fwServerFails;
|
||||
int _generalEditTab;
|
||||
int _iconSize;
|
||||
int _jsCtrl;
|
||||
int _historySize;
|
||||
int _id;
|
||||
int _theme;
|
||||
int _warningId;
|
||||
|
||||
public:
|
||||
// All the get definitions
|
||||
QStringList recentFiles();
|
||||
QByteArray mainWinGeo();
|
||||
QByteArray mainWinState();
|
||||
QByteArray modelEditGeo();
|
||||
|
||||
QString armMcu();
|
||||
QString avrArguments();
|
||||
QString avrPort();
|
||||
QString avrdudeLocation();
|
||||
QString dfuArguments();
|
||||
QString dfuLocation();
|
||||
QString lastFw();
|
||||
QString locale();
|
||||
QString mcu();
|
||||
QString programmer();
|
||||
QString sambaLocation();
|
||||
QString sambaPort();
|
||||
QString lastSimulator();
|
||||
|
||||
QString backupDir();
|
||||
QString gePath();
|
||||
QString eepromDir();
|
||||
QString flashDir();
|
||||
QString imagesDir();
|
||||
QString logDir();
|
||||
QString libDir();
|
||||
QString snapshotDir();
|
||||
QString updatesDir();
|
||||
|
||||
bool jsSupport();
|
||||
bool maximized();
|
||||
bool showSplash();
|
||||
bool snapToClpbrd();
|
||||
bool autoCheckApp();
|
||||
bool autoCheckFw();
|
||||
bool simuSW();
|
||||
bool useWizard();
|
||||
|
||||
int backLight();
|
||||
int embedSplashes();
|
||||
int fwServerFails();
|
||||
int generalEditTab();
|
||||
int iconSize();
|
||||
int historySize();
|
||||
int jsCtrl();
|
||||
int id();
|
||||
int theme();
|
||||
int warningId();
|
||||
|
||||
// All the set definitions
|
||||
void recentFiles (const QStringList x);
|
||||
void mainWinGeo (const QByteArray);
|
||||
void mainWinState (const QByteArray);
|
||||
void modelEditGeo (const QByteArray);
|
||||
|
||||
void armMcu (const QString);
|
||||
void avrArguments (const QString);
|
||||
void avrPort (const QString);
|
||||
void avrdudeLocation (const QString);
|
||||
void dfuArguments (const QString);
|
||||
void dfuLocation (const QString);
|
||||
void lastFw (const QString);
|
||||
void locale (const QString);
|
||||
void mcu (const QString);
|
||||
void programmer (const QString);
|
||||
void sambaLocation (const QString);
|
||||
void sambaPort (const QString);
|
||||
void lastSimulator (const QString);
|
||||
|
||||
void backupDir (const QString);
|
||||
void gePath (const QString);
|
||||
void eepromDir (const QString);
|
||||
void flashDir (const QString);
|
||||
void imagesDir (const QString);
|
||||
void logDir (const QString);
|
||||
void libDir (const QString);
|
||||
void snapshotDir (const QString);
|
||||
void updatesDir (const QString);
|
||||
|
||||
void maximized (const bool);
|
||||
void jsSupport (const bool);
|
||||
void showSplash (const bool);
|
||||
void snapToClpbrd (const bool);
|
||||
void autoCheckApp (const bool);
|
||||
void autoCheckFw (const bool);
|
||||
void simuSW (const bool);
|
||||
void useWizard (const bool);
|
||||
|
||||
void backLight (const int);
|
||||
void embedSplashes (const int);
|
||||
void fwServerFails (const int);
|
||||
void generalEditTab (const int);
|
||||
void iconSize (const int);
|
||||
void historySize (const int);
|
||||
void jsCtrl (const int);
|
||||
void modelEditTab (const int);
|
||||
void id (const int);
|
||||
void theme (const int);
|
||||
void warningId (const int);
|
||||
|
||||
// Constructor
|
||||
AppData();
|
||||
void init();
|
||||
};
|
||||
|
||||
extern AppData g;
|
||||
|
||||
#endif // COMPANION_APPDATA_H
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
|
||||
#include <QFileDevice>
|
||||
|
||||
AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) :
|
||||
QObject(parent),
|
||||
m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL),
|
||||
m_showSourcePath(APP_DBG_HANDLER_SHOW_SRC_PATH),
|
||||
m_showFunctionDeclarations(APP_DBG_HANDLER_SHOW_FUNCTION_DECL)
|
||||
{
|
||||
m_srcPathFilter = QRegularExpression("^" APP_DBG_HANDLER_SRC_PATH "[\\\\\\/](.*?)$", QRegularExpression::InvertedGreedinessOption);
|
||||
m_functionFilter = QRegularExpression("^.+?(\\w+\\().+$");
|
||||
}
|
||||
|
||||
AppDebugMessageHandler * AppDebugMessageHandler::instance()
|
||||
{
|
||||
static AppDebugMessageHandler * _instance = NULL;
|
||||
#if APP_DBG_HANDLER_ENABLE
|
||||
if(_instance == NULL && !qApp->closingDown())
|
||||
_instance = new AppDebugMessageHandler(qApp); // Ensure this object is cleaned up when the QApplication exits.
|
||||
#endif
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setAppDebugOutputLevel(const quint8 & appDebugOutputLevel)
|
||||
{
|
||||
m_appDebugOutputLevel = appDebugOutputLevel;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setShowSourcePath(bool showSourcePath)
|
||||
{
|
||||
m_showSourcePath = showSourcePath;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclarations)
|
||||
{
|
||||
m_showFunctionDeclarations = showFunctionDeclarations;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::addOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device && !m_outputDevices.contains(device))
|
||||
m_outputDevices.append(device);
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::removeOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device) {
|
||||
// no QVector::removeAll() in Qt < 5.4
|
||||
int i = 0;
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d == device)
|
||||
m_outputDevices.remove(i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::installAppMessageHandler()
|
||||
{
|
||||
m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler);
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg)
|
||||
{
|
||||
static const char symbols[] = { 'D', 'W', 'E', 'X', 'I' }; // correspond to QtMsgType enum
|
||||
// normalize types, QtDebugMsg stays 0, QtInfoMsg becomes 1, rest are QtMsgType + 1
|
||||
quint8 lvl = type;
|
||||
if (type == QtInfoMsg)
|
||||
lvl = 1;
|
||||
else if (type > QtDebugMsg)
|
||||
++lvl;
|
||||
|
||||
if (lvl < m_appDebugOutputLevel && type != QtFatalMsg)
|
||||
return;
|
||||
|
||||
#if defined(Q_OS_LINUX) && (QT_VERSION < QT_VERSION_CHECK(5, 3, 0))
|
||||
// Filter out lots of QPainter warnings from undocked QDockWidgets... hackish but effective (only workaround found so far)
|
||||
if (lvl == 2 && QString(context.function).contains("QPainter::"))
|
||||
return;
|
||||
#endif
|
||||
|
||||
QString msgPattern = QString("[%1] ").arg(symbols[type]);
|
||||
|
||||
if (m_showSourcePath) {
|
||||
QString file = QString("%1::").arg(context.file);
|
||||
file.replace(m_srcPathFilter, "\\1");
|
||||
msgPattern.append(file);
|
||||
}
|
||||
if (m_showFunctionDeclarations)
|
||||
msgPattern.append(context.function);
|
||||
else
|
||||
msgPattern.append("%{function}()");
|
||||
|
||||
msgPattern.append(":%{line} -%{if-category} [%{category}]%{endif} %{message}");
|
||||
|
||||
if (type == QtFatalMsg)
|
||||
msgPattern.append("\nBACKTRACE:\n%{backtrace depth=12 separator=\"\n\"}");
|
||||
|
||||
qSetMessagePattern(msgPattern);
|
||||
|
||||
if (!m_defaultHandler || m_outputDevices.size() || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
|
||||
msgPattern = qFormatLogMessage(type, context, msg);
|
||||
#else
|
||||
msgPattern.replace("%{line}", QString::number(context.line));
|
||||
msgPattern.replace("%{if-category} [%{category}]%{endif}", QString(context.category));
|
||||
msgPattern.replace("%{message}", msg);
|
||||
if (!m_showFunctionDeclarations) {
|
||||
QString func = context.function;
|
||||
msgPattern.replace("%{function}", func.replace(m_functionFilter, "\\1)"));
|
||||
}
|
||||
#endif
|
||||
|
||||
emit messageOutput(lvl, msgPattern);
|
||||
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d && d->isWritable() && (!d->property("level").isValid() || d->property("level").toInt() <= lvl)) {
|
||||
d->write(qPrintable(msgPattern % "\n"));
|
||||
if (QFileDevice * fd = qobject_cast<QFileDevice *>(d))
|
||||
fd->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (QThread::currentThread() == qApp->thread()) // gui thread
|
||||
|
||||
if (m_defaultHandler) {
|
||||
m_defaultHandler(type, context, msg);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s", qPrintable(msgPattern));
|
||||
if (type == QtFatalMsg)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
|
||||
void g_appDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->messageHandler(type, context, msg);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef APPDEBUGMESSAGEHANDLER_H
|
||||
#define APPDEBUGMESSAGEHANDLER_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QIODevice>
|
||||
#include <QMessageLogContext>
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
|
||||
/*
|
||||
* Custom debug/message handler class to work in conjunction with qDebug() family of functions.
|
||||
* Formats all stderr output generated by the application in a consistent manner.
|
||||
* It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
|
||||
*
|
||||
* Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
|
||||
*
|
||||
* Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
|
||||
* see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
|
||||
*
|
||||
* This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
|
||||
* For example, at start of application:
|
||||
*
|
||||
* QApplication app(argc, argv);
|
||||
* AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
*
|
||||
* To connect to a signal:
|
||||
*
|
||||
* connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
|
||||
*
|
||||
* This singleton will self-destruct upon QApplication termination.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(QT_DEBUG) || defined(DEBUG)
|
||||
#define APP_DBG_HANDLER_IS_DBG_BUILD 1
|
||||
#else
|
||||
#define APP_DBG_HANDLER_IS_DBG_BUILD 0
|
||||
#endif
|
||||
|
||||
// Enable/disable this custom handler handler entirely
|
||||
#ifndef APP_DBG_HANDLER_ENABLE
|
||||
#define APP_DBG_HANDLER_ENABLE 1
|
||||
#endif
|
||||
|
||||
// Default log level (can also be set with setAppDebugOutputLevel()):
|
||||
// 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
|
||||
#ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
|
||||
#define APP_DBG_HANDLER_DEFAULT_LEVEL 0
|
||||
#endif
|
||||
|
||||
// Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
|
||||
#ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
|
||||
#define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
|
||||
#endif
|
||||
|
||||
// Show just the function Class::name vs. full declaration with return and param types
|
||||
#ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
|
||||
#define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
|
||||
#endif
|
||||
|
||||
// base path for source file name filter, everything after this is kept; RegEx, non-greedy
|
||||
#ifndef APP_DBG_HANDLER_SRC_PATH
|
||||
#define APP_DBG_HANDLER_SRC_PATH ".*src"
|
||||
#endif
|
||||
|
||||
// Make sure to include this header if using qInfo()
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
|
||||
#if defined(QT_NO_INFO_OUTPUT)
|
||||
#define qInfo QT_NO_QDEBUG_MACRO
|
||||
#else
|
||||
#define qInfo qDebug
|
||||
#endif
|
||||
#define QtInfoMsg QtMsgType(4)
|
||||
#endif
|
||||
|
||||
class AppDebugMessageHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// This class implements the singleton design pattern and is therefore publicly accessible only through instance().
|
||||
static AppDebugMessageHandler * instance();
|
||||
AppDebugMessageHandler(AppDebugMessageHandler const &) = delete;
|
||||
void operator = (AppDebugMessageHandler const &) = delete;
|
||||
|
||||
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
|
||||
void setShowSourcePath(bool showSourcePath);
|
||||
void setShowFunctionDeclarations(bool showFunctionDeclarations);
|
||||
void addOutputDevice(QIODevice * device);
|
||||
void removeOutputDevice(QIODevice * device);
|
||||
|
||||
void installAppMessageHandler();
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
|
||||
|
||||
private:
|
||||
// This class implements the singleton design pattern and therefore has only a private constructor.
|
||||
explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR);
|
||||
~AppDebugMessageHandler() { }
|
||||
|
||||
QtMessageHandler m_defaultHandler;
|
||||
QRegularExpression m_srcPathFilter;
|
||||
QRegularExpression m_functionFilter;
|
||||
quint8 m_appDebugOutputLevel;
|
||||
QVector<QIODevice *> m_outputDevices;
|
||||
bool m_showSourcePath;
|
||||
bool m_showFunctionDeclarations;
|
||||
|
||||
signals:
|
||||
void messageOutput(quint8 level, const QString & msg);
|
||||
};
|
||||
|
||||
// Message handler which is installed using qInstallMessageHandler. This needs to be global.
|
||||
// Use AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
// instead of installing this function directly (it will verify this handler is enabled, etc).
|
||||
void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
|
||||
|
||||
#endif // APPDEBUGMESSAGEHANDLER_H
|
||||
@@ -1,29 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "apppreferencesdialog.h"
|
||||
#include "ui_apppreferencesdialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "firmwareinterface.h"
|
||||
#ifdef JOYSTICKS
|
||||
#include "storage.h"
|
||||
#if defined(JOYSTICKS)
|
||||
#include "joystick.h"
|
||||
#include "joystickdialog.h"
|
||||
#endif
|
||||
#include <QDesktopServices>
|
||||
#include <QtGui>
|
||||
|
||||
AppPreferencesDialog::AppPreferencesDialog(QWidget *parent) :
|
||||
AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AppPreferencesDialog)
|
||||
ui(new Ui::AppPreferencesDialog),
|
||||
updateLock(false),
|
||||
mainWinHasDirtyChild(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
updateLock=false;
|
||||
setWindowIcon(CompanionIcon("apppreferences.png"));
|
||||
|
||||
initSettings();
|
||||
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(baseFirmwareChanged()));
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(writeValues()));
|
||||
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(onBaseFirmwareChanged()));
|
||||
connect(ui->opt_appDebugLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
connect(ui->opt_fwTraceLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
|
||||
#ifndef JOYSTICKS
|
||||
#if !defined(JOYSTICKS)
|
||||
ui->joystickCB->hide();
|
||||
ui->joystickCB->setDisabled(true);
|
||||
ui->joystickcalButton->hide();
|
||||
@@ -39,59 +59,98 @@ AppPreferencesDialog::~AppPreferencesDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::writeValues()
|
||||
void AppPreferencesDialog::setMainWinHasDirtyChild(bool value)
|
||||
{
|
||||
g.useCompanionNightlyBuilds(ui->useCompanionNightlyBuilds->isChecked());
|
||||
mainWinHasDirtyChild = value;
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::accept()
|
||||
{
|
||||
Profile & profile = g.currentProfile();
|
||||
|
||||
g.autoCheckApp(ui->autoCheckCompanion->isChecked());
|
||||
g.useFirmwareNightlyBuilds(ui->useFirmwareNightlyBuilds->isChecked());
|
||||
g.OpenTxBranch(AppData::DownloadBranchType(ui->OpenTxBranch->currentIndex()));
|
||||
g.autoCheckFw(ui->autoCheckFirmware->isChecked());
|
||||
g.showSplash(ui->showSplash->isChecked());
|
||||
g.simuSW(ui->simuSW->isChecked());
|
||||
g.useWizard(ui->modelWizard_CB->isChecked());
|
||||
g.removeModelSlots(ui->opt_removeBlankSlots->isChecked());
|
||||
g.newModelAction(ui->opt_newMdl_useWizard->isChecked() ? AppData::MODEL_ACT_WIZARD : ui->opt_newMdl_useEditor->isChecked() ? AppData::MODEL_ACT_EDITOR : AppData::MODEL_ACT_NONE);
|
||||
g.historySize(ui->historySize->value());
|
||||
g.backLight(ui->backLightColor->currentIndex());
|
||||
g.profile[g.id()].volumeGain(round(ui->volumeGain->value() * 10.0));
|
||||
profile.volumeGain(round(ui->volumeGain->value() * 10.0));
|
||||
g.libDir(ui->libraryPath->text());
|
||||
g.gePath(ui->ge_lineedit->text());
|
||||
g.embedSplashes(ui->splashincludeCB->currentIndex());
|
||||
g.enableBackup(ui->backupEnable->isChecked());
|
||||
|
||||
g.appDebugLog(ui->opt_appDebugLog->isChecked());
|
||||
g.fwTraceLog(ui->opt_fwTraceLog->isChecked());
|
||||
g.appLogsDir(ui->appLogsDir->text());
|
||||
|
||||
if (ui->joystickChkB ->isChecked() && ui->joystickCB->isEnabled()) {
|
||||
g.jsSupport(ui->joystickChkB ->isChecked());
|
||||
g.jsSupport(ui->joystickChkB ->isChecked());
|
||||
g.jsCtrl(ui->joystickCB ->currentIndex());
|
||||
}
|
||||
else {
|
||||
g.jsSupport(false);
|
||||
g.jsCtrl(0);
|
||||
}
|
||||
g.profile[g.id()].channelOrder(ui->channelorderCB->currentIndex());
|
||||
g.profile[g.id()].defaultMode(ui->stickmodeCB->currentIndex());
|
||||
g.profile[g.id()].renameFwFiles(ui->renameFirmware->isChecked());
|
||||
g.profile[g.id()].burnFirmware(ui->burnFirmware->isChecked());
|
||||
g.profile[g.id()].sdPath(ui->sdPath->text());
|
||||
g.profile[g.id()].pBackupDir(ui->profilebackupPath->text());
|
||||
g.profile[g.id()].penableBackup(ui->pbackupEnable->isChecked());
|
||||
g.profile[g.id()].splashFile(ui->SplashFileName->text());
|
||||
profile.channelOrder(ui->channelorderCB->currentIndex());
|
||||
profile.defaultMode(ui->stickmodeCB->currentIndex());
|
||||
profile.renameFwFiles(ui->renameFirmware->isChecked());
|
||||
profile.burnFirmware(ui->burnFirmware->isChecked());
|
||||
profile.sdPath(ui->sdPath->text());
|
||||
profile.pBackupDir(ui->profilebackupPath->text());
|
||||
profile.penableBackup(ui->pbackupEnable->isChecked());
|
||||
profile.splashFile(ui->SplashFileName->text());
|
||||
|
||||
// The profile name may NEVER be empty
|
||||
if (ui->profileNameLE->text().isEmpty())
|
||||
g.profile[g.id()].name(tr("My Radio"));
|
||||
profile.name(tr("My Radio"));
|
||||
else
|
||||
g.profile[g.id()].name(ui->profileNameLE->text());
|
||||
profile.name(ui->profileNameLE->text());
|
||||
|
||||
bool fwchange = false;
|
||||
Firmware * newFw = getFirmwareVariant(); // always !null
|
||||
// If a new fw type has been choosen, several things need to reset
|
||||
current_firmware_variant = getFirmwareVariant();
|
||||
QString id = current_firmware_variant->getId();
|
||||
if (g.profile[g.id()].fwType() != id) {
|
||||
g.profile[g.id()].fwName("");
|
||||
g.profile[g.id()].initFwVariables();
|
||||
g.profile[g.id()].fwType(id);
|
||||
if (Firmware::getCurrentVariant()->getId() != newFw->getId()) {
|
||||
// check if we're going to be converting to a new radio type and there are unsaved files in the main window
|
||||
if (mainWinHasDirtyChild && !Boards::isBoardCompatible(Firmware::getCurrentVariant()->getBoard(), newFw->getBoard())) {
|
||||
QString q = tr("<p><b>You cannot switch Radio Type or change Build Options while there are unsaved file changes. What do you wish to do?</b></p> <ul>" \
|
||||
"<li><i>Save All</i> - Save any open file(s) before saving Settings.<li>" \
|
||||
"<li><i>Reset</i> - Revert to the previous Radio Type and Build Options before saving Settings.</li>" \
|
||||
"<li><i>Cancel</i> - Return to the Settings editor dialog.</li></ul>");
|
||||
int resp = QMessageBox::question(this, windowTitle(), q, (QMessageBox::SaveAll | QMessageBox::Reset | QMessageBox::Cancel), QMessageBox::Cancel);
|
||||
if (resp == QMessageBox::SaveAll) {
|
||||
// signal main window to save files, need to do this before the fw actually changes
|
||||
emit firmwareProfileAboutToChange();
|
||||
}
|
||||
else if (resp == QMessageBox::Reset) {
|
||||
// bail out early before saving the radio type & firmware options
|
||||
QDialog::accept();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// we do not accept the dialog close
|
||||
return;
|
||||
}
|
||||
}
|
||||
Firmware::setCurrentVariant(newFw);
|
||||
profile.fwName("");
|
||||
profile.resetFwVariables();
|
||||
profile.fwType(newFw->getId());
|
||||
fwchange = true;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
|
||||
if (fwchange)
|
||||
emit firmwareProfileChanged(); // important to do this after the accepted() signal
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_snapshotPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your snapshot folder"), g.snapshotDir());
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select your snapshot folder"), g.snapshotDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
g.snapshotDir(fileName);
|
||||
g.snapToClpbrd(false);
|
||||
@@ -101,34 +160,43 @@ void AppPreferencesDialog::on_snapshotPathButton_clicked()
|
||||
|
||||
void AppPreferencesDialog::initSettings()
|
||||
{
|
||||
const Profile & profile = g.currentProfile();
|
||||
|
||||
ui->snapshotClipboardCKB->setChecked(g.snapToClpbrd());
|
||||
ui->burnFirmware->setChecked(g.profile[g.id()].burnFirmware());
|
||||
ui->burnFirmware->setChecked(profile.burnFirmware());
|
||||
ui->snapshotPath->setText(g.snapshotDir());
|
||||
ui->snapshotPath->setReadOnly(true);
|
||||
if (ui->snapshotClipboardCKB->isChecked()) {
|
||||
ui->snapshotPath->setDisabled(true);
|
||||
ui->snapshotPathButton->setDisabled(true);
|
||||
}
|
||||
#if defined(ALLOW_NIGHTLY_BUILDS)
|
||||
ui->useCompanionNightlyBuilds->setChecked(g.useCompanionNightlyBuilds());
|
||||
ui->useFirmwareNightlyBuilds->setChecked(g.useFirmwareNightlyBuilds());
|
||||
#else
|
||||
ui->useCompanionNightlyBuilds->hide();
|
||||
ui->useFirmwareNightlyBuilds->hide();
|
||||
|
||||
#if !defined(ALLOW_NIGHTLY_BUILDS)
|
||||
// remove nightly version option entirely unless it's the current one (because user might have nightly version also installed)
|
||||
if (g.OpenTxBranch() != AppData::BRANCH_NIGHTLY_UNSTABLE)
|
||||
ui->OpenTxBranch->removeItem(2);
|
||||
// if it's already selected, add a warning message
|
||||
else
|
||||
ui->updatesLayout->addWidget(new QLabel("<font color='red'>" % tr("Note: Nightly builds are not available in this version, Release/RC update channel will be used.") % "</font>", this));
|
||||
#endif
|
||||
ui->OpenTxBranch->setCurrentIndex(g.OpenTxBranch());
|
||||
|
||||
ui->autoCheckCompanion->setChecked(g.autoCheckApp());
|
||||
ui->autoCheckFirmware->setChecked(g.autoCheckFw());
|
||||
ui->showSplash->setChecked(g.showSplash());
|
||||
ui->historySize->setValue(g.historySize());
|
||||
ui->backLightColor->setCurrentIndex(g.backLight());
|
||||
ui->volumeGain->setValue(g.profile[g.id()].volumeGain() / 10.0);
|
||||
ui->volumeGain->setValue(profile.volumeGain() / 10.0);
|
||||
|
||||
if (IS_TARANIS(GetCurrentFirmware()->getBoard())) {
|
||||
if (IS_TARANIS(getCurrentBoard())) {
|
||||
ui->backLightColor->setEnabled(false);
|
||||
}
|
||||
|
||||
ui->simuSW->setChecked(g.simuSW());
|
||||
ui->modelWizard_CB->setChecked(g.useWizard());
|
||||
ui->opt_removeBlankSlots->setChecked(g.removeModelSlots());
|
||||
ui->opt_newMdl_useNone->setChecked(g.newModelAction() == AppData::MODEL_ACT_NONE);
|
||||
ui->opt_newMdl_useWizard->setChecked(g.newModelAction() == AppData::MODEL_ACT_WIZARD);
|
||||
ui->opt_newMdl_useEditor->setChecked(g.newModelAction() == AppData::MODEL_ACT_EDITOR);
|
||||
ui->libraryPath->setText(g.libDir());
|
||||
ui->ge_lineedit->setText(g.gePath());
|
||||
|
||||
@@ -137,15 +205,22 @@ void AppPreferencesDialog::initSettings()
|
||||
ui->backupPath->setText(g.backupDir());
|
||||
ui->backupEnable->setEnabled(true);
|
||||
ui->backupEnable->setChecked(g.enableBackup());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
} else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
ui->splashincludeCB->setCurrentIndex(g.embedSplashes());
|
||||
|
||||
#ifdef JOYSTICKS
|
||||
ui->opt_appDebugLog->setChecked(g.appDebugLog());
|
||||
ui->opt_fwTraceLog->setChecked(g.fwTraceLog());
|
||||
ui->appLogsDir->setText(g.appLogsDir());
|
||||
toggleAppLogSettings();
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
ui->joystickChkB->setChecked(g.jsSupport());
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
@@ -171,35 +246,33 @@ void AppPreferencesDialog::initSettings()
|
||||
ui->joystickCB->setDisabled(true);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
}
|
||||
#endif
|
||||
// Profile Tab Inits
|
||||
ui->channelorderCB->setCurrentIndex(g.profile[g.id()].channelOrder());
|
||||
ui->stickmodeCB->setCurrentIndex(g.profile[g.id()].defaultMode());
|
||||
ui->renameFirmware->setChecked(g.profile[g.id()].renameFwFiles());
|
||||
ui->sdPath->setText(g.profile[g.id()].sdPath());
|
||||
if (!g.profile[g.id()].pBackupDir().isEmpty()) {
|
||||
if (QDir(g.profile[g.id()].pBackupDir()).exists()) {
|
||||
ui->profilebackupPath->setText(g.profile[g.id()].pBackupDir());
|
||||
#endif
|
||||
// Profile Tab Inits
|
||||
ui->channelorderCB->setCurrentIndex(profile.channelOrder());
|
||||
ui->stickmodeCB->setCurrentIndex(profile.defaultMode());
|
||||
ui->renameFirmware->setChecked(profile.renameFwFiles());
|
||||
ui->sdPath->setText(profile.sdPath());
|
||||
if (!profile.pBackupDir().isEmpty()) {
|
||||
if (QDir(profile.pBackupDir()).exists()) {
|
||||
ui->profilebackupPath->setText(profile.pBackupDir());
|
||||
ui->pbackupEnable->setEnabled(true);
|
||||
ui->pbackupEnable->setChecked(g.profile[g.id()].penableBackup());
|
||||
ui->pbackupEnable->setChecked(profile.penableBackup());
|
||||
} else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
|
||||
ui->profileNameLE->setText(g.profile[g.id()].name());
|
||||
ui->SplashFileName->setText(g.profile[g.id()].splashFile());
|
||||
|
||||
displayImage( g.profile[g.id()].splashFile() );
|
||||
ui->profileNameLE->setText(profile.name());
|
||||
|
||||
QString hwSettings;
|
||||
if (g.profile[g.id()].stickPotCalib() == "" ) {
|
||||
if (profile.stickPotCalib() == "" ) {
|
||||
hwSettings = tr("EMPTY: No radio settings stored in profile");
|
||||
}
|
||||
else {
|
||||
QString str = g.profile[g.id()].timeStamp();
|
||||
QString str = profile.timeStamp();
|
||||
if (str.isEmpty())
|
||||
hwSettings = tr("AVAILABLE: Radio settings of unknown age");
|
||||
else
|
||||
@@ -207,16 +280,15 @@ void AppPreferencesDialog::initSettings()
|
||||
}
|
||||
ui->lblGeneralSettings->setText(hwSettings);
|
||||
|
||||
Firmware * current_firmware = GetCurrentFirmware();
|
||||
|
||||
foreach(Firmware * firmware, firmwares) {
|
||||
QString currType = QStringList(profile.fwType().split('-').mid(0, 2)).join('-');
|
||||
foreach(Firmware * firmware, Firmware::getRegisteredFirmwares()) {
|
||||
ui->downloadVerCB->addItem(firmware->getName(), firmware->getId());
|
||||
if (current_firmware->getFirmwareBase() == firmware) {
|
||||
if (currType == firmware->getId()) {
|
||||
ui->downloadVerCB->setCurrentIndex(ui->downloadVerCB->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
baseFirmwareChanged();
|
||||
|
||||
onBaseFirmwareChanged();
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_libraryPathButton_clicked()
|
||||
@@ -262,6 +334,15 @@ void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppPreferencesDialog::on_btn_appLogsDir_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select a folder for application logs"), ui->appLogsDir->text());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->appLogsDir->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ge_pathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Google Earth executable"),ui->ge_lineedit->text());
|
||||
@@ -269,8 +350,8 @@ void AppPreferencesDialog::on_ge_pathButton_clicked()
|
||||
ui->ge_lineedit->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JOYSTICKS
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
void AppPreferencesDialog::on_joystickChkB_clicked() {
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
@@ -307,41 +388,26 @@ void AppPreferencesDialog::on_joystickcalButton_clicked() {
|
||||
|
||||
void AppPreferencesDialog::on_sdPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select the folder replicating your SD structure"), g.profile[g.id()].sdPath());
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select the folder replicating your SD structure"), g.currentProfile().sdPath());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->sdPath->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_removeProfileButton_clicked()
|
||||
bool AppPreferencesDialog::displayImage(const QString & fileName)
|
||||
{
|
||||
if ( g.id() == 0 ) {
|
||||
QMessageBox::information(this, tr("Not possible to remove profile"), tr("The default profile can not be removed."));
|
||||
}
|
||||
else {
|
||||
g.profile[g.id()].remove();
|
||||
g.id( 0 );
|
||||
initSettings();
|
||||
}
|
||||
}
|
||||
// Start by clearing the label
|
||||
ui->imageLabel->clear();
|
||||
|
||||
|
||||
bool AppPreferencesDialog::displayImage( QString fileName )
|
||||
{
|
||||
// Start by clearing the pixmap
|
||||
ui->imageLabel->setPixmap(QPixmap());
|
||||
|
||||
QImage image(fileName);
|
||||
if (image.isNull())
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
|
||||
// Use the firmware name to determine splash width
|
||||
int width = SPLASH_WIDTH;
|
||||
if (g.profile[g.id()].fwType().contains("taranis"))
|
||||
width = SPLASHX9D_WIDTH;
|
||||
|
||||
ui->imageLabel->setPixmap( makePixMap( image, g.profile[g.id()].fwType()));
|
||||
ui->imageLabel->setFixedSize(width, SPLASH_HEIGHT);
|
||||
QImage image(fileName);
|
||||
if (image.isNull())
|
||||
return false;
|
||||
|
||||
ui->imageLabel->setPixmap(makePixMap(image));
|
||||
ui->imageLabel->setFixedSize(getCurrentFirmware()->getCapability(LcdWidth), getCurrentFirmware()->getCapability(LcdHeight));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -357,7 +423,7 @@ void AppPreferencesDialog::on_SplashSelect_clicked()
|
||||
|
||||
if (!fileName.isEmpty()){
|
||||
g.imagesDir(QFileInfo(fileName).dir().absolutePath());
|
||||
|
||||
|
||||
displayImage(fileName);
|
||||
ui->SplashFileName->setText(fileName);
|
||||
}
|
||||
@@ -369,154 +435,126 @@ void AppPreferencesDialog::on_clearImageButton_clicked()
|
||||
ui->SplashFileName->clear();
|
||||
}
|
||||
|
||||
|
||||
void AppPreferencesDialog::showVoice(bool show)
|
||||
void AppPreferencesDialog::onBaseFirmwareChanged()
|
||||
{
|
||||
ui->voiceLabel->setVisible(show);
|
||||
ui->voiceCombo->setVisible(show);
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
populateFirmwareOptions(getBaseFirmware());
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::baseFirmwareChanged()
|
||||
Firmware *AppPreferencesDialog::getBaseFirmware() const
|
||||
{
|
||||
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
|
||||
|
||||
foreach(Firmware * firmware, firmwares) {
|
||||
if (firmware->getId() == selected_firmware) {
|
||||
populateFirmwareOptions(firmware);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Firmware::getFirmwareForId(ui->downloadVerCB->currentData().toString());
|
||||
}
|
||||
|
||||
Firmware * AppPreferencesDialog::getFirmwareVariant()
|
||||
Firmware * AppPreferencesDialog::getFirmwareVariant() const
|
||||
{
|
||||
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
|
||||
QString id = ui->downloadVerCB->currentData().toString();
|
||||
|
||||
foreach(Firmware * firmware, firmwares) {
|
||||
QString id = firmware->getId();
|
||||
if (id == selected_firmware) {
|
||||
foreach(QCheckBox *cb, optionsCheckBoxes) {
|
||||
if (cb->isChecked()) {
|
||||
id += QString("-") + cb->text();
|
||||
}
|
||||
}
|
||||
|
||||
if (voice && voice->isChecked()) {
|
||||
id += QString("-tts") + ui->voiceCombo->currentText();
|
||||
}
|
||||
|
||||
if (ui->langCombo->count()) {
|
||||
id += QString("-") + ui->langCombo->currentText();
|
||||
}
|
||||
|
||||
return GetFirmware(id);
|
||||
}
|
||||
foreach(QCheckBox *cb, optionsCheckBoxes.values()) {
|
||||
if (cb->isChecked())
|
||||
id += "-" + cb->text();
|
||||
}
|
||||
|
||||
// Should never occur...
|
||||
return default_firmware_variant;
|
||||
if (ui->langCombo->count())
|
||||
id += "-" + ui->langCombo->currentText();
|
||||
|
||||
return Firmware::getFirmwareForId(id);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::firmwareOptionChanged(bool state)
|
||||
void AppPreferencesDialog::onFirmwareOptionChanged(bool state)
|
||||
{
|
||||
QCheckBox *cb = qobject_cast<QCheckBox*>(sender());
|
||||
if (cb == voice) {
|
||||
showVoice(voice->isChecked());
|
||||
}
|
||||
Firmware * firmware=NULL;
|
||||
if (cb && state) {
|
||||
QVariant selected_firmware = ui->downloadVerCB->itemData(ui->downloadVerCB->currentIndex());
|
||||
foreach(firmware, firmwares) {
|
||||
if (firmware->getId() == selected_firmware) {
|
||||
foreach(QList<Option> opts, firmware->opts) {
|
||||
foreach(Option opt, opts) {
|
||||
if (cb->text() == opt.name) {
|
||||
foreach(Option other, opts) {
|
||||
if (other.name != opt.name) {
|
||||
foreach(QCheckBox *ocb, optionsCheckBoxes) {
|
||||
if (ocb->text() == other.name) {
|
||||
ocb->setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(cb && state))
|
||||
return;
|
||||
|
||||
// This de-selects any mutually exlusive options (that is, members of the same QList<Option> list).
|
||||
const Firmware::OptionsList & fwOpts = getBaseFirmware()->optionGroups();
|
||||
for (const Firmware::OptionsGroup & optGrp : fwOpts) {
|
||||
for (const Firmware::Option & opt : optGrp) {
|
||||
if (cb->text() == opt.name) {
|
||||
QCheckBox *ocb = nullptr;
|
||||
foreach(const Firmware::Option & other, optGrp)
|
||||
if (other.name != opt.name && (ocb = optionsCheckBoxes.value(other.name, nullptr)))
|
||||
ocb->setChecked(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::toggleAppLogSettings()
|
||||
{
|
||||
bool vis = (ui->opt_appDebugLog->isChecked() || ui->opt_fwTraceLog->isChecked());
|
||||
ui->appLogsDir->setVisible(vis);
|
||||
ui->lbl_appLogsDir->setVisible(vis);
|
||||
ui->btn_appLogsDir->setVisible(vis);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
|
||||
{
|
||||
const Firmware * parent = firmware->getFirmwareBase();
|
||||
const Firmware * baseFw = firmware->getFirmwareBase();
|
||||
QStringList currVariant = Firmware::getCurrentVariant()->getId().split('-');
|
||||
const QString currLang = ui->langCombo->count() ? ui->langCombo->currentText() : currVariant.last();
|
||||
|
||||
updateLock = true;
|
||||
|
||||
QString id = current_firmware_variant->getId();
|
||||
ui->langCombo->clear();
|
||||
foreach(const char *lang, parent->languages) {
|
||||
for (const char *lang : baseFw->languageList()) {
|
||||
ui->langCombo->addItem(lang);
|
||||
if (id.endsWith(lang)) {
|
||||
if (currLang == lang) {
|
||||
ui->langCombo->setCurrentIndex(ui->langCombo->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
voice = NULL; // we will search for a voice checkbox
|
||||
if (optionsCheckBoxes.size()) {
|
||||
currVariant.clear();
|
||||
QMutableMapIterator<QString, QCheckBox *> it(optionsCheckBoxes);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QCheckBox * cb = it.value();
|
||||
if (cb->isChecked())
|
||||
currVariant.append(it.key()); // keep previous selections
|
||||
ui->optionsLayout->removeWidget(cb);
|
||||
cb->deleteLater();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
QWidget * prevFocus = ui->voiceCombo;
|
||||
foreach(QList<Option> opts, parent->opts) {
|
||||
foreach(Option opt, opts) {
|
||||
if (index >= optionsCheckBoxes.size()) {
|
||||
QCheckBox * checkbox = new QCheckBox(ui->profileTab);
|
||||
ui->optionsLayout->addWidget(checkbox, optionsCheckBoxes.count()/5, optionsCheckBoxes.count()%5, 1, 1);
|
||||
optionsCheckBoxes.push_back(checkbox);
|
||||
connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(firmwareOptionChanged(bool)));
|
||||
if (prevFocus) {
|
||||
QWidget::setTabOrder(prevFocus, checkbox);
|
||||
}
|
||||
}
|
||||
|
||||
QCheckBox *cb = optionsCheckBoxes.at(index++);
|
||||
if (cb) {
|
||||
cb->show();
|
||||
cb->setText(opt.name);
|
||||
cb->setToolTip(opt.tooltip);
|
||||
cb->setCheckState(id.contains(opt.name) ? Qt::Checked : Qt::Unchecked);
|
||||
if (opt.name == QString("voice")) {
|
||||
voice = cb;
|
||||
}
|
||||
prevFocus = cb;
|
||||
}
|
||||
QWidget * prevFocus = ui->langCombo;
|
||||
for (const Firmware::OptionsGroup &optGrp : baseFw->optionGroups()) {
|
||||
for (const Firmware::Option &opt : optGrp) {
|
||||
QCheckBox * cb = new QCheckBox(ui->profileTab);
|
||||
cb->setText(opt.name);
|
||||
cb->setToolTip(opt.tooltip);
|
||||
cb->setChecked(currVariant.contains(opt.name));
|
||||
ui->optionsLayout->addWidget(cb, index / 4, index % 4);
|
||||
QWidget::setTabOrder(prevFocus, cb);
|
||||
// connect to duplicates check handler if this option is part of a group
|
||||
if (optGrp.size() > 1)
|
||||
connect(cb, &QCheckBox::toggled, this, &AppPreferencesDialog::onFirmwareOptionChanged);
|
||||
optionsCheckBoxes.insert(opt.name, cb);
|
||||
prevFocus = cb;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
for (; index<optionsCheckBoxes.size(); index++) {
|
||||
QCheckBox *cb = optionsCheckBoxes.at(index);
|
||||
cb->hide();
|
||||
cb->setCheckState(Qt::Unchecked);
|
||||
// TODO: Remove once splash replacement supported on Horus
|
||||
// NOTE: 480x272 image causes issues on screens <800px high, needs a solution like scrolling once reinstated
|
||||
if (IS_HORUS(baseFw->getBoard())) {
|
||||
ui->widget_splashImage->hide();
|
||||
ui->SplashFileName->setText("");
|
||||
}
|
||||
|
||||
ui->voiceCombo->clear();
|
||||
foreach(const char *lang, parent->ttslanguages) {
|
||||
ui->voiceCombo->addItem(lang);
|
||||
if (id.contains(QString("-tts%1").arg(lang))) {
|
||||
ui->voiceCombo->setCurrentIndex(ui->voiceCombo->count() - 1);
|
||||
}
|
||||
else {
|
||||
ui->widget_splashImage->show();
|
||||
ui->SplashFileName->setText(g.currentProfile().splashFile());
|
||||
displayImage(g.currentProfile().splashFile());
|
||||
}
|
||||
|
||||
showVoice(voice && voice->isChecked());
|
||||
|
||||
updateLock = false;
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
QTimer::singleShot(50, this, &AppPreferencesDialog::shrink);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::shrink()
|
||||
{
|
||||
resize(0,0);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
#ifndef APPPREFERENCESDIALOG_H
|
||||
#define APPPREFERENCESDIALOG_H
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _APPPREFERENCESDIALOG_H_
|
||||
#define _APPPREFERENCESDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
@@ -16,49 +36,53 @@ class AppPreferencesDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AppPreferencesDialog(QWidget *parent = 0);
|
||||
explicit AppPreferencesDialog(QWidget * parent = 0);
|
||||
~AppPreferencesDialog();
|
||||
Joystick *joystick;
|
||||
|
||||
private:
|
||||
QList<QCheckBox *> optionsCheckBoxes;
|
||||
bool updateLock;
|
||||
void showVoice(bool);
|
||||
void showVoice();
|
||||
void hideVoice();
|
||||
void populateLocale();
|
||||
void populateFirmwareOptions(const Firmware *);
|
||||
Firmware * getFirmwareVariant();
|
||||
QCheckBox * voice;
|
||||
Joystick * joystick;
|
||||
|
||||
Ui::AppPreferencesDialog *ui;
|
||||
void initSettings();
|
||||
bool displayImage( QString fileName );
|
||||
void loadProfileString(QString profile, QString label);
|
||||
void loadFromProfile();
|
||||
public slots:
|
||||
void accept() Q_DECL_OVERRIDE;
|
||||
void setMainWinHasDirtyChild(bool value);
|
||||
|
||||
signals:
|
||||
void firmwareProfileChanged();
|
||||
void firmwareProfileAboutToChange(bool saveFiles = true);
|
||||
|
||||
protected slots:
|
||||
void shrink();
|
||||
void baseFirmwareChanged();
|
||||
void firmwareOptionChanged(bool state);
|
||||
void shrink();
|
||||
void onBaseFirmwareChanged();
|
||||
void onFirmwareOptionChanged(bool state);
|
||||
void toggleAppLogSettings();
|
||||
|
||||
void writeValues();
|
||||
void on_libraryPathButton_clicked();
|
||||
void on_snapshotPathButton_clicked();
|
||||
void on_snapshotClipboardCKB_clicked();
|
||||
void on_backupPathButton_clicked();
|
||||
void on_ProfilebackupPathButton_clicked();
|
||||
void on_ge_pathButton_clicked();
|
||||
|
||||
|
||||
void on_sdPathButton_clicked();
|
||||
void on_removeProfileButton_clicked();
|
||||
void on_SplashSelect_clicked();
|
||||
void on_clearImageButton_clicked();
|
||||
void on_btn_appLogsDir_clicked();
|
||||
|
||||
#ifdef JOYSTICKS
|
||||
#if defined(JOYSTICKS)
|
||||
void on_joystickChkB_clicked();
|
||||
void on_joystickcalButton_clicked();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void initSettings();
|
||||
void populateFirmwareOptions(const Firmware *);
|
||||
Firmware * getBaseFirmware() const;
|
||||
Firmware * getFirmwareVariant() const;
|
||||
bool displayImage(const QString & fileName);
|
||||
|
||||
Ui::AppPreferencesDialog *ui;
|
||||
QMap<QString, QCheckBox *> optionsCheckBoxes;
|
||||
bool updateLock;
|
||||
bool mainWinHasDirtyChild;
|
||||
};
|
||||
|
||||
#endif // APPPREFERENCESDIALOG_H
|
||||
#endif // _APPPREFERENCESDIALOG_H_
|
||||
|
||||
+1021
-720
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "burnconfigdialog.h"
|
||||
#include "ui_burnconfigdialog.h"
|
||||
#include "eeprominterface.h"
|
||||
@@ -6,7 +26,7 @@
|
||||
#include "progressdialog.h"
|
||||
#include "process_flash.h"
|
||||
|
||||
#if !defined WIN32 && defined __GNUC__
|
||||
#if !defined _MSC_VER && defined __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
@@ -20,8 +40,8 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) :
|
||||
|
||||
getSettings();
|
||||
populateProgrammers();
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
if (IS_STM32(eepromInterface->getBoard())) {
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (IS_STM32(board)) {
|
||||
setWindowTitle(tr("DFU-UTIL Configuration"));
|
||||
ui->avrArgs->hide();
|
||||
ui->avrdude_location->hide();
|
||||
@@ -37,10 +57,10 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) :
|
||||
ui->label_sb1->hide();
|
||||
ui->label_sb3->hide();
|
||||
ui->samba_location->hide();
|
||||
ui->samba_port->hide();
|
||||
ui->samba_port->hide();
|
||||
ui->sb_browse->hide();
|
||||
}
|
||||
else if (IS_SKY9X(eepromInterface->getBoard())) {
|
||||
else if (IS_SKY9X(board)) {
|
||||
setWindowTitle(tr("SAM-BA Configuration"));
|
||||
ui->avrArgs->hide();
|
||||
ui->avrdude_location->hide();
|
||||
@@ -77,7 +97,7 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) :
|
||||
ui->dfuArgs->hide();
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(shrink()));
|
||||
connect(this,SIGNAL(accepted()),this,SLOT(putSettings()));
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(putSettings()));
|
||||
}
|
||||
|
||||
burnConfigDialog::~burnConfigDialog()
|
||||
@@ -85,6 +105,18 @@ burnConfigDialog::~burnConfigDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QStringList burnConfigDialog::getAvrdudeArgs()
|
||||
{
|
||||
QStringList args = avrArgs;
|
||||
if (!avrPort.isEmpty())
|
||||
args << "-P" << avrPort;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
args << "-C" << QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude.conf").absoluteFilePath();
|
||||
#endif
|
||||
return args;
|
||||
}
|
||||
|
||||
void burnConfigDialog::getSettings()
|
||||
{
|
||||
avrLoc = g.avrdudeLocation();
|
||||
@@ -100,11 +132,16 @@ void burnConfigDialog::getSettings()
|
||||
dfuLoc = QFileInfo("dfu-util.exe").absoluteFilePath();
|
||||
#elif defined __APPLE__
|
||||
if ( avrLoc.isEmpty())
|
||||
avrLoc = "/usr/local/bin/avrdude";
|
||||
avrLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude").absoluteFilePath();
|
||||
if ( sambaLoc.isEmpty())
|
||||
sambaLoc = "/usr/local/bin/sam-ba";
|
||||
if ( dfuLoc.isEmpty())
|
||||
dfuLoc = QFileInfo("/opt/local/bin/dfu-util").absoluteFilePath();
|
||||
dfuLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/dfu-util").absoluteFilePath();
|
||||
#elif defined __FreeBSD__
|
||||
if (avrLoc.isEmpty())
|
||||
avrLoc = "/usr/local/bin/avrdude";
|
||||
if (dfuLoc.isEmpty())
|
||||
dfuLoc = "/usr/local/bin/dfu-util";
|
||||
#else
|
||||
if ( avrLoc.isEmpty())
|
||||
avrLoc = "/usr/bin/avrdude";
|
||||
@@ -144,7 +181,7 @@ void burnConfigDialog::getSettings()
|
||||
ui->pushButton_3->setEnabled(true);
|
||||
} else {
|
||||
ui->pushButton_3->setDisabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void burnConfigDialog::putSettings()
|
||||
@@ -308,30 +345,30 @@ void burnConfigDialog::on_pushButton_4_clicked()
|
||||
|
||||
void burnConfigDialog::on_advCtrChkB_toggled(bool checked)
|
||||
{
|
||||
EEPROMInterface *eepromInterface = GetEepromInterface();
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (checked) {
|
||||
if (IS_STM32(eepromInterface->getBoard())) {
|
||||
if (IS_STM32(board)) {
|
||||
ui->label_dfu2->show();
|
||||
ui->dfuArgs->show();
|
||||
}
|
||||
else if (IS_SKY9X(eepromInterface->getBoard())) {
|
||||
else if (IS_SKY9X(board)) {
|
||||
ui->label_sb2->show();
|
||||
ui->arm_mcu->show();
|
||||
}
|
||||
else {
|
||||
ui->label_av3->show();
|
||||
ui->avrdude_mcu->show();
|
||||
QMessageBox::warning(this, tr("Companion"),
|
||||
QMessageBox::warning(this, CPN_STR_APP_NAME,
|
||||
tr("<b><u>WARNING!</u></b><br>Normally CPU type is automatically selected according to the chosen firmware.<br>If you change the CPU type the resulting eeprom could be inconsistent."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (IS_STM32(eepromInterface->getBoard())) {
|
||||
if (IS_STM32(board)) {
|
||||
ui->label_dfu2->hide();
|
||||
ui->dfuArgs->hide();
|
||||
}
|
||||
else if (IS_SKY9X(eepromInterface->getBoard())) {
|
||||
else if (IS_SKY9X(board)) {
|
||||
ui->label_sb2->hide();
|
||||
ui->arm_mcu->hide();
|
||||
}
|
||||
@@ -346,7 +383,7 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked)
|
||||
|
||||
void burnConfigDialog::shrink()
|
||||
{
|
||||
resize(0,0);
|
||||
resize(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
#ifndef BURNCONFIGDIALOG_H_
|
||||
#define BURNCONFIGDIALOG_H_
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BURNCONFIGDIALOG_H_
|
||||
#define _BURNCONFIGDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
@@ -22,7 +42,7 @@ public:
|
||||
QString getAVRDUDE() {return avrLoc;}
|
||||
QString getSAMBA() {return sambaLoc;}
|
||||
QString getDFU() {return dfuLoc;}
|
||||
QStringList getAvrdudeArgs() { QStringList args = avrArgs; if (!avrPort.isEmpty()) args << "-P" << avrPort; return args; }
|
||||
QStringList getAvrdudeArgs();
|
||||
QStringList getDFUArgs() {return dfuArgs;}
|
||||
QString getProgrammer() {return avrProgrammer;}
|
||||
QString getMCU() {return avrMCU;}
|
||||
@@ -70,4 +90,4 @@ private slots:
|
||||
void putSettings();
|
||||
};
|
||||
|
||||
#endif // BURNCONFIGDIALOG_H_
|
||||
#endif // _BURNCONFIGDIALOG_H_
|
||||
|
||||
+285
-168
@@ -1,168 +1,285 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QSplashScreen>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
#endif
|
||||
#include "mainwindow.h"
|
||||
#include "version.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "appdata.h"
|
||||
|
||||
#if defined WIN32 || !defined __GNUC__
|
||||
#include <windows.h>
|
||||
#define sleep(x) Sleep(x*1000)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QProxyStyle>
|
||||
|
||||
class MyProxyStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
void polish ( QWidget * w ) {
|
||||
QMenu* mn = dynamic_cast<QMenu*>(w);
|
||||
QPushButton* pb = dynamic_cast<QPushButton*>(w);
|
||||
if(!(mn || pb) && !w->testAttribute(Qt::WA_MacNormalSize))
|
||||
w->setAttribute(Qt::WA_MacSmallSize);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Q_INIT_RESOURCE(companion);
|
||||
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("OpenTX Companion");
|
||||
app.setOrganizationName("OpenTX");
|
||||
app.setOrganizationDomain("open-tx.org");
|
||||
app.setAttribute(Qt::AA_DontShowIconsInMenus, false);
|
||||
|
||||
g.init();
|
||||
|
||||
QStringList strl = QApplication::arguments();
|
||||
if (strl.contains("--version")) {
|
||||
printf("%s\n", VERSION);
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
app.setStyle(new MyProxyStyle);
|
||||
#endif
|
||||
|
||||
QTranslator companionTranslator;
|
||||
companionTranslator.load(":/companion_" + g.locale());
|
||||
QTranslator qtTranslator;
|
||||
qtTranslator.load((QString)"qt_" + g.locale().left(2), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
app.installTranslator(&companionTranslator);
|
||||
app.installTranslator(&qtTranslator);
|
||||
|
||||
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
sdlFlags |= SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
#ifdef SIMU_AUDIO
|
||||
sdlFlags |= SDL_INIT_AUDIO;
|
||||
#endif
|
||||
if (SDL_Init(sdlFlags) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
registerEEpromInterfaces();
|
||||
registerOpenTxFirmwares();
|
||||
registerSimulators();
|
||||
|
||||
if (g.profile[g.id()].fwType().isEmpty()){
|
||||
g.profile[g.id()].fwType(default_firmware_variant->getId());
|
||||
g.profile[g.id()].fwName("");
|
||||
}
|
||||
|
||||
QString splashScreen;
|
||||
splashScreen = ":/images/splash.png";
|
||||
|
||||
QPixmap pixmap = QPixmap(splashScreen);
|
||||
QSplashScreen *splash = new QSplashScreen(pixmap);
|
||||
|
||||
current_firmware_variant = GetFirmware(g.profile[g.id()].fwType());
|
||||
|
||||
MainWindow *mainWin = new MainWindow();
|
||||
if (g.showSplash()) {
|
||||
splash->show();
|
||||
QTimer::singleShot(1000*SPLASH_TIME, splash, SLOT(close()));
|
||||
QTimer::singleShot(1000*SPLASH_TIME, mainWin, SLOT(show()));
|
||||
}
|
||||
else {
|
||||
mainWin->show();
|
||||
}
|
||||
|
||||
int result = app.exec();
|
||||
|
||||
delete splash;
|
||||
delete mainWin;
|
||||
|
||||
unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterEEpromInterfaces();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QSplashScreen>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
#include "customdebug.h"
|
||||
#include "mainwindow.h"
|
||||
#include "version.h"
|
||||
#include "appdata.h"
|
||||
#include "simulatorinterface.h"
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <QProxyStyle>
|
||||
|
||||
class MyProxyStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
void polish ( QWidget * w ) {
|
||||
QMenu* mn = dynamic_cast<QMenu*>(w);
|
||||
QPushButton* pb = dynamic_cast<QPushButton*>(w);
|
||||
if(!(mn || pb) && !w->testAttribute(Qt::WA_MacNormalSize))
|
||||
w->setAttribute(Qt::WA_MacSmallSize);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
void importError()
|
||||
{
|
||||
QMessageBox::critical(nullptr, CPN_STR_APP_NAME, QCoreApplication::translate("Companion", "The saved settings could not be imported, please try again or continue with current settings."), QMessageBox::Ok, 0);
|
||||
}
|
||||
|
||||
void checkSettingsImport(bool force = false)
|
||||
{
|
||||
QString previousVersion;
|
||||
bool found;
|
||||
if (!(found = g.findPreviousVersionSettings(&previousVersion))) {
|
||||
found = QDir(CPN_SETTINGS_BACKUP_DIR).entryList(QStringList({"*.ini"}), QDir::Files).size() > 0;
|
||||
}
|
||||
if (!found && !force)
|
||||
return;
|
||||
|
||||
const QString impFileBtn = QCoreApplication::translate("Companion", "Import from File");
|
||||
const QString impPrevBtn = QCoreApplication::translate("Companion", "Import from v%1").arg(previousVersion);
|
||||
const QString impNoneBtn = QCoreApplication::translate("Companion", "Do not import");
|
||||
|
||||
QString msg;
|
||||
if (previousVersion.isEmpty()) {
|
||||
if (found)
|
||||
msg = QCoreApplication::translate("Companion", "We have found possible Companion settings backup file(s).\nDo you want to import settings from a file?");
|
||||
else
|
||||
msg = QCoreApplication::translate("Companion", "Import settings from a file, or start with current values.");
|
||||
}
|
||||
else {
|
||||
msg = QCoreApplication::translate("Companion", "We have found existing settings for Companion version: %1.\nDo you want to import them?\n\n" \
|
||||
"If you have a settings backup file, you may import that instead.").arg(previousVersion);
|
||||
}
|
||||
|
||||
const int ret = QMessageBox::question(nullptr, CPN_STR_APP_NAME, msg, impNoneBtn, impFileBtn, (previousVersion.isEmpty() ? QString() : impPrevBtn), 0, 0);
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
// Import from previous version
|
||||
if (ret == 2) {
|
||||
if (!g.importSettings(previousVersion)) {
|
||||
// very unlikely, but just in case of unexpected error, restart the import
|
||||
importError();
|
||||
checkSettingsImport();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Import from file
|
||||
bool err = false;
|
||||
QString impFile = CPN_SETTINGS_BACKUP_DIR;
|
||||
impFile = QFileDialog::getOpenFileName(nullptr, QCoreApplication::translate("Companion", "Select %1:").arg(CPN_STR_APP_SETTINGS_FILES), impFile, CPN_STR_APP_SETTINGS_FILTER);
|
||||
|
||||
if (!impFile.isEmpty() && QFileInfo(impFile).isReadable()) {
|
||||
QSettings fromSettings(impFile, QSettings::IniFormat);
|
||||
if (g.importSettings(&fromSettings)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
importError();
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
// Restart the import prompt if user cancelled the file select dialog but we do have previous settings, or if we had a file import error.
|
||||
if (err || !previousVersion.isEmpty())
|
||||
checkSettingsImport();
|
||||
}
|
||||
|
||||
void printHelpText()
|
||||
{
|
||||
printf(qPrintable(QString(APP_COMPANION % " v%s\n\n")), VERSION);
|
||||
const char tmpl[] = " %s \t %s\n";
|
||||
printf(tmpl, "--export", QCoreApplication::translate("Companion", "Save application settings to file...").toUtf8().constData());
|
||||
printf(tmpl, "--import", QCoreApplication::translate("Companion", "Load application settings from file or previous version...").toUtf8().constData());
|
||||
printf(tmpl, "--defaults", QCoreApplication::translate("Companion", "Reset ALL application settings to default and remove radio profiles...").toUtf8().constData());
|
||||
printf(tmpl, "--quit ", QCoreApplication::translate("Companion", "Exit before settings initialization and application startup.").toUtf8().constData());
|
||||
printf(tmpl, "--version", QCoreApplication::translate("Companion", "Print version number and exit.").toUtf8().constData());
|
||||
printf(tmpl, "--help|-h", QCoreApplication::translate("Companion", "Print this help text.").toUtf8().constData());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||||
/* From doc: This attribute must be set before Q(Gui)Application is constructed. */
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName(APP_COMPANION);
|
||||
app.setOrganizationName(COMPANY);
|
||||
app.setOrganizationDomain(COMPANY_DOMAIN);
|
||||
app.setAttribute(Qt::AA_DontShowIconsInMenus, false);
|
||||
|
||||
const QStringList args(QApplication::arguments());
|
||||
|
||||
if (args.contains("--help") || args.contains("-h") || args.contains("/?")) {
|
||||
printHelpText();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (args.contains("--version")) {
|
||||
printf("%s\n", VERSION);
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Q_INIT_RESOURCE(companion);
|
||||
|
||||
if (AppDebugMessageHandler::instance())
|
||||
AppDebugMessageHandler::instance()->installAppMessageHandler();
|
||||
|
||||
CustomDebug::setFilterRules();
|
||||
|
||||
// handle settings export/import/reset via CLI
|
||||
|
||||
bool doExport = args.contains("--export");
|
||||
bool doImport = args.contains("--import");
|
||||
bool doReset = args.contains("--defaults");
|
||||
|
||||
if (doExport)
|
||||
Helpers::exportAppSettings();
|
||||
|
||||
if (doReset) {
|
||||
char ok;
|
||||
printf("%s [Y/N] ", QCoreApplication::translate("Companion", "Reset ALL application settings to default values and remove radio profiles, are you sure?").toUtf8().constData());
|
||||
std::cin >> ok;
|
||||
if (ok != 'Y' && ok != 'y')
|
||||
exit(0);
|
||||
if (!doExport) {
|
||||
printf("%s [Y/N] ", QCoreApplication::translate("Companion", "Would you like to perform a backup first?").toUtf8().constData());
|
||||
std::cin >> ok;
|
||||
if (ok == 'Y' || ok == 'y')
|
||||
Helpers::exportAppSettings();
|
||||
}
|
||||
g.resetAllSettings();
|
||||
g.storeAllSettings();
|
||||
std::cout << QCoreApplication::translate("Companion", "Application settings were reset and saved.").toUtf8().constData() << std::endl;
|
||||
}
|
||||
|
||||
if (doImport)
|
||||
checkSettingsImport(true);
|
||||
|
||||
// give option to quit before settings init
|
||||
if (args.contains("--quit"))
|
||||
exit(0);
|
||||
|
||||
// end CLI handling
|
||||
|
||||
if (!doImport && g.isFirstUse())
|
||||
checkSettingsImport(false);
|
||||
|
||||
g.init();
|
||||
|
||||
QFile dbgLog;
|
||||
if (AppDebugMessageHandler::instance() && g.appDebugLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
|
||||
QString fn = g.appLogsDir() % "/CompanionDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
|
||||
dbgLog.setFileName(fn);
|
||||
if (dbgLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
AppDebugMessageHandler::instance()->addOutputDevice(&dbgLog);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
app.setStyle(new MyProxyStyle);
|
||||
#endif
|
||||
|
||||
Translations::installTranslators();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
sdlFlags |= SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
#ifdef SIMU_AUDIO
|
||||
sdlFlags |= SDL_INIT_AUDIO;
|
||||
#endif
|
||||
if (SDL_Init(sdlFlags) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
registerStorageFactories();
|
||||
registerOpenTxFirmwares();
|
||||
SimulatorLoader::registerSimulators();
|
||||
|
||||
Profile & profile = g.currentProfile();
|
||||
if (profile.fwType().isEmpty()){
|
||||
profile.fwType(Firmware::getDefaultVariant()->getId());
|
||||
profile.fwName("");
|
||||
}
|
||||
|
||||
QString splashScreen;
|
||||
splashScreen = ":/images/splash.png";
|
||||
|
||||
QPixmap pixmap = QPixmap(splashScreen);
|
||||
QSplashScreen *splash = new QSplashScreen(pixmap);
|
||||
|
||||
Firmware::setCurrentVariant(Firmware::getFirmwareForId(g.profile[g.id()].fwType()));
|
||||
|
||||
MainWindow *mainWin = new MainWindow();
|
||||
if (g.showSplash()) {
|
||||
splash->show();
|
||||
QTimer::singleShot(1000*SPLASH_TIME, splash, SLOT(close()));
|
||||
QTimer::singleShot(1000*SPLASH_TIME, mainWin, SLOT(show()));
|
||||
}
|
||||
else {
|
||||
mainWin->show();
|
||||
}
|
||||
|
||||
int result = app.exec();
|
||||
|
||||
delete splash;
|
||||
delete mainWin;
|
||||
|
||||
SimulatorLoader::unregisterSimulators();
|
||||
unregisterOpenTxFirmwares();
|
||||
unregisterStorageFactories();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
qDebug() << "COMPANION EXIT" << result;
|
||||
|
||||
if (dbgLog.isOpen()) {
|
||||
AppDebugMessageHandler::instance()->removeOutputDevice(&dbgLog);
|
||||
dbgLog.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+111
-24
@@ -1,25 +1,78 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>images/customize.png</file>
|
||||
<file>icon.png</file>
|
||||
<file alias="icon.png">images/icon.png</file>
|
||||
<file>../../CREDITS.txt</file>
|
||||
<file>../../DONATIONS.txt</file>
|
||||
<file>../releasenotes.txt</file>
|
||||
<file>images/simulator/Horus/middle.png</file>
|
||||
<file>images/simulator/Horus/left.png</file>
|
||||
<file>images/simulator/Horus/right.png</file>
|
||||
<file>images/simulator/Horus/top.png</file>
|
||||
<file>images/simulator/Horus/bottom.png</file>
|
||||
<file>images/simulator/Horus/led.png</file>
|
||||
<file>images/simulator/Horus/border-right.png</file>
|
||||
<file>images/simulator/Horus/left_btn1.png</file>
|
||||
<file>images/simulator/Horus/left_btn2.png</file>
|
||||
<file>images/simulator/Horus/left_scrnsht.png</file>
|
||||
<file>images/simulator/Horus/right_btnU.png</file>
|
||||
<file>images/simulator/Horus/right_btnL.png</file>
|
||||
<file>images/simulator/Horus/right_btnD.png</file>
|
||||
<file>images/simulator/Horus/right_btnR.png</file>
|
||||
<file>images/simulator/Horus/right_ent.png</file>
|
||||
<file>images/screenshot.png</file>
|
||||
<file>images/splash.png</file>
|
||||
<file>images/companion-title.png</file>
|
||||
<file>images/maps.png</file>
|
||||
<file>images/track.png</file>
|
||||
<file>images/track0.png</file>
|
||||
<file>images/taranison.png</file>
|
||||
<file>images/simulator/icons/svg/arrow_click.svg</file>
|
||||
<file>images/simulator/icons/svg/camera.svg</file>
|
||||
<file>images/simulator/icons/svg/camera-active.svg</file>
|
||||
<file>images/simulator/icons/svg/console.svg</file>
|
||||
<file>images/simulator/icons/svg/console-active.svg</file>
|
||||
<file>images/simulator/icons/svg/eraser.svg</file>
|
||||
<file>images/simulator/icons/svg/eraser-active.svg</file>
|
||||
<file>images/simulator/icons/svg/fixed_x.svg</file>
|
||||
<file>images/simulator/icons/svg/fixed_x-on.svg</file>
|
||||
<file>images/simulator/icons/svg/fixed_y.svg</file>
|
||||
<file>images/simulator/icons/svg/fixed_y-on.svg</file>
|
||||
<file>images/simulator/icons/svg/folder_open.svg</file>
|
||||
<file>images/simulator/icons/svg/hold_x.svg</file>
|
||||
<file>images/simulator/icons/svg/hold_x-on.svg</file>
|
||||
<file>images/simulator/icons/svg/hold_y.svg</file>
|
||||
<file>images/simulator/icons/svg/hold_y-on.svg</file>
|
||||
<file>images/simulator/icons/svg/info.svg</file>
|
||||
<file>images/simulator/icons/svg/info-active.svg</file>
|
||||
<file>images/simulator/icons/svg/joystick_settings.svg</file>
|
||||
<file>images/simulator/icons/svg/joystick_settings-active.svg</file>
|
||||
<file>images/simulator/icons/svg/line_horiz.svg</file>
|
||||
<file>images/simulator/icons/svg/mouse.svg</file>
|
||||
<file>images/simulator/icons/svg/toggle_lock.svg</file>
|
||||
<file>images/simulator/icons/svg/toggle_lock-on.svg</file>
|
||||
<file>images/simulator/icons/svg/radio_outputs.svg</file>
|
||||
<file>images/simulator/icons/svg/radio_outputs-active.svg</file>
|
||||
<file>images/simulator/icons/svg/reload_script.svg</file>
|
||||
<file>images/simulator/icons/svg/reload_script-active.svg</file>
|
||||
<file>images/simulator/icons/svg/restart.svg</file>
|
||||
<file>images/simulator/icons/svg/restart-active.svg</file>
|
||||
<file>images/simulator/icons/svg/telemetry.svg</file>
|
||||
<file>images/simulator/icons/svg/telemetry-active.svg</file>
|
||||
<file>images/simulator/icons/svg/trainer.svg</file>
|
||||
<file>images/simulator/icons/svg/trainer-active.svg</file>
|
||||
<file>images/simulator/icons/svg/word_wrap.svg</file>
|
||||
<file>images/simulator/icons/svg/word_wrap-on.svg</file>
|
||||
<file>images/simulator/X12/middle.png</file>
|
||||
<file>images/simulator/X12/left.png</file>
|
||||
<file>images/simulator/X12/right.png</file>
|
||||
<file>images/simulator/X12/top.png</file>
|
||||
<file>images/simulator/X12/bottom.png</file>
|
||||
<file>images/simulator/X12/led.png</file>
|
||||
<file>images/simulator/X12/border-right.png</file>
|
||||
<file>images/simulator/X12/left_btn1.png</file>
|
||||
<file>images/simulator/X12/left_btn2.png</file>
|
||||
<file>images/simulator/X12/left_scrnsht.png</file>
|
||||
<file>images/simulator/X12/right_btnU.png</file>
|
||||
<file>images/simulator/X12/right_btnL.png</file>
|
||||
<file>images/simulator/X12/right_btnD.png</file>
|
||||
<file>images/simulator/X12/right_btnR.png</file>
|
||||
<file>images/simulator/X12/right_ent.png</file>
|
||||
<file>images/simulator/X10/left.png</file>
|
||||
<file>images/simulator/X10/right.png</file>
|
||||
<file>images/simulator/X10/top.png</file>
|
||||
<file>images/simulator/X10/bottom.png</file>
|
||||
<file>images/simulator/X10/left_mdl.png</file>
|
||||
<file>images/simulator/X10/left_page.png</file>
|
||||
<file>images/simulator/X10/left_scrnsht.png</file>
|
||||
<file>images/simulator/X10/left_rtn.png</file>
|
||||
<file>images/simulator/X10/left_sys.png</file>
|
||||
<file>images/simulator/X10/left_tele.png</file>
|
||||
<file>images/simulator/X10/right_ent.png</file>
|
||||
<file>images/simulator/9X/9xdb.png</file>
|
||||
<file>images/simulator/9X/9xdl.png</file>
|
||||
<file>images/simulator/9X/9xdr.png</file>
|
||||
@@ -53,12 +106,6 @@
|
||||
<file>images/simulator/9X/9xcursmin.png</file>
|
||||
<file>images/simulator/9X/9xcursdown.png</file>
|
||||
<file>images/simulator/9X/9xcursphoto.png</file>
|
||||
<file>images/screenshot.png</file>
|
||||
<file>images/splash.png</file>
|
||||
<file>images/companion-title.png</file>
|
||||
<file>images/maps.png</file>
|
||||
<file>images/track.png</file>
|
||||
<file>images/track0.png</file>
|
||||
<file>images/simulator/Taranis/x9b0.png</file>
|
||||
<file>images/simulator/Taranis/x9l0.png</file>
|
||||
<file>images/simulator/Taranis/x9l1.png</file>
|
||||
@@ -71,7 +118,36 @@
|
||||
<file>images/simulator/Taranis/x9r3.png</file>
|
||||
<file>images/simulator/Taranis/x9s0.png</file>
|
||||
<file>images/simulator/Taranis/x9t0.png</file>
|
||||
<file>images/taranison.png</file>
|
||||
<file>images/simulator/X7/bottom.png</file>
|
||||
<file>images/simulator/X7/left.png</file>
|
||||
<file>images/simulator/X7/left_exit.png</file>
|
||||
<file>images/simulator/X7/left_menu.png</file>
|
||||
<file>images/simulator/X7/left_page.png</file>
|
||||
<file>images/simulator/X7/left_scrnshot.png</file>
|
||||
<file>images/simulator/X7/right.png</file>
|
||||
<file>images/simulator/X7/right_ent.png</file>
|
||||
<file>images/simulator/X7/top.png</file>
|
||||
<file>images/simulator/X9E/bottom.png</file>
|
||||
<file>images/simulator/X9E/left.png</file>
|
||||
<file>images/simulator/X9E/left_exit.png</file>
|
||||
<file>images/simulator/X9E/left_menu.png</file>
|
||||
<file>images/simulator/X9E/left_page.png</file>
|
||||
<file>images/simulator/X9E/left_scrnshot.png</file>
|
||||
<file>images/simulator/X9E/right.png</file>
|
||||
<file>images/simulator/X9E/right_enter.png</file>
|
||||
<file>images/simulator/X9E/top.png</file>
|
||||
<file>images/simulator/XLITE/bottom.png</file>
|
||||
<file>images/simulator/XLITE/left.png</file>
|
||||
<file>images/simulator/XLITE/left_scrnshot.png</file>
|
||||
<file>images/simulator/XLITE/right.png</file>
|
||||
<file>images/simulator/XLITE/right_ent.png</file>
|
||||
<file>images/simulator/XLITE/top.png</file>
|
||||
<file>images/simulator/XLITE/right_exit.png</file>
|
||||
<file>images/simulator/XLITE/right_shift.png</file>
|
||||
<file>images/simulator/XLITE/right_right.png</file>
|
||||
<file>images/simulator/XLITE/right_left.png</file>
|
||||
<file>images/simulator/XLITE/right_up.png</file>
|
||||
<file>images/simulator/XLITE/right_down.png</file>
|
||||
<file>images/wizard/ailerons.png</file>
|
||||
<file>images/wizard/airbrakes.png</file>
|
||||
<file>images/wizard/elevons.png</file>
|
||||
@@ -169,6 +245,9 @@
|
||||
<file>images/library/10702.png</file>
|
||||
<file>images/library/10801.png</file>
|
||||
<file>images/library/10802.png</file>
|
||||
<file>themes/default/style.css</file>
|
||||
<file>themes/default/style-osx.css</file>
|
||||
<file>themes/default/modelprt.css</file>
|
||||
<file>themes/monochrome/16/paintbrush.png</file>
|
||||
<file>themes/monochrome/16/open.png</file>
|
||||
<file>themes/monochrome/16/edit.png</file>
|
||||
@@ -564,6 +643,7 @@
|
||||
<file>themes/monoblue/16/contributors.png</file>
|
||||
<file>themes/monoblue/16/stop.png</file>
|
||||
<file>themes/monoblue/16/write_eeprom.png</file>
|
||||
<file>themes/monoblue/16/sdsync.png</file>
|
||||
<file>themes/monoblue/24/paintbrush.png</file>
|
||||
<file>themes/monoblue/24/open.png</file>
|
||||
<file>themes/monoblue/24/edit.png</file>
|
||||
@@ -607,6 +687,7 @@
|
||||
<file>themes/monoblue/24/contributors.png</file>
|
||||
<file>themes/monoblue/24/stop.png</file>
|
||||
<file>themes/monoblue/24/write_eeprom.png</file>
|
||||
<file>themes/monoblue/24/sdsync.png</file>
|
||||
<file>themes/monoblue/32/paintbrush.png</file>
|
||||
<file>themes/monoblue/32/open.png</file>
|
||||
<file>themes/monoblue/32/edit.png</file>
|
||||
@@ -650,6 +731,7 @@
|
||||
<file>themes/monoblue/32/contributors.png</file>
|
||||
<file>themes/monoblue/32/stop.png</file>
|
||||
<file>themes/monoblue/32/write_eeprom.png</file>
|
||||
<file>themes/monoblue/32/sdsync.png</file>
|
||||
<file>themes/monoblue/48/paintbrush.png</file>
|
||||
<file>themes/monoblue/48/open.png</file>
|
||||
<file>themes/monoblue/48/edit.png</file>
|
||||
@@ -693,6 +775,7 @@
|
||||
<file>themes/monoblue/48/contributors.png</file>
|
||||
<file>themes/monoblue/48/stop.png</file>
|
||||
<file>themes/monoblue/48/write_eeprom.png</file>
|
||||
<file>themes/monoblue/48/sdsync.png</file>
|
||||
<file>themes/monowhite/16/paintbrush.png</file>
|
||||
<file>themes/monowhite/16/open.png</file>
|
||||
<file>themes/monowhite/16/edit.png</file>
|
||||
@@ -736,6 +819,7 @@
|
||||
<file>themes/monowhite/16/contributors.png</file>
|
||||
<file>themes/monowhite/16/stop.png</file>
|
||||
<file>themes/monowhite/16/write_eeprom.png</file>
|
||||
<file>themes/monowhite/16/sdsync.png</file>
|
||||
<file>themes/monowhite/24/paintbrush.png</file>
|
||||
<file>themes/monowhite/24/open.png</file>
|
||||
<file>themes/monowhite/24/edit.png</file>
|
||||
@@ -779,6 +863,7 @@
|
||||
<file>themes/monowhite/24/contributors.png</file>
|
||||
<file>themes/monowhite/24/stop.png</file>
|
||||
<file>themes/monowhite/24/write_eeprom.png</file>
|
||||
<file>themes/monowhite/24/sdsync.png</file>
|
||||
<file>themes/monowhite/32/paintbrush.png</file>
|
||||
<file>themes/monowhite/32/open.png</file>
|
||||
<file>themes/monowhite/32/edit.png</file>
|
||||
@@ -822,6 +907,7 @@
|
||||
<file>themes/monowhite/32/contributors.png</file>
|
||||
<file>themes/monowhite/32/stop.png</file>
|
||||
<file>themes/monowhite/32/write_eeprom.png</file>
|
||||
<file>themes/monowhite/32/sdsync.png</file>
|
||||
<file>themes/monowhite/48/paintbrush.png</file>
|
||||
<file>themes/monowhite/48/open.png</file>
|
||||
<file>themes/monowhite/48/edit.png</file>
|
||||
@@ -865,6 +951,7 @@
|
||||
<file>themes/monowhite/48/contributors.png</file>
|
||||
<file>themes/monowhite/48/stop.png</file>
|
||||
<file>themes/monowhite/48/write_eeprom.png</file>
|
||||
<file>themes/monowhite/48/sdsync.png</file>
|
||||
<file>themes/yerico/16/paintbrush.png</file>
|
||||
<file>themes/yerico/16/open.png</file>
|
||||
<file>themes/yerico/16/edit.png</file>
|
||||
|
||||
+119
-62
@@ -1,45 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "comparedialog.h"
|
||||
#include "ui_comparedialog.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "modelslist.h"
|
||||
#include "styleeditdialog.h"
|
||||
#include <QPrinter>
|
||||
#include <QPrintDialog>
|
||||
|
||||
// #if !defined WIN32 && defined __GNUC__
|
||||
// #include <unistd.h>
|
||||
// #endif
|
||||
|
||||
class DragDropHeader {
|
||||
public:
|
||||
DragDropHeader():
|
||||
general_settings(false),
|
||||
models_count(0)
|
||||
{
|
||||
}
|
||||
bool general_settings;
|
||||
uint8_t models_count;
|
||||
uint8_t models[C9X_MAX_MODELS];
|
||||
};
|
||||
//class DragDropHeader {
|
||||
// public:
|
||||
// DragDropHeader():
|
||||
// general_settings(false),
|
||||
// models_count(0)
|
||||
// {
|
||||
// }
|
||||
// bool general_settings;
|
||||
// uint8_t models_count;
|
||||
// uint8_t models[CPN_MAX_MODELS];
|
||||
//};
|
||||
|
||||
CompareDialog::CompareDialog(QWidget * parent, Firmware * firmware):
|
||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
multimodelprinter(firmware),
|
||||
model1Valid(false),
|
||||
model2Valid(false),
|
||||
QDialog(parent, Qt::Window),
|
||||
multimodelprinter(new MultiModelPrinter(firmware)),
|
||||
ui(new Ui::CompareDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowIcon(CompanionIcon("compare.png"));
|
||||
setAcceptDrops(true);
|
||||
if (!g.compareWinGeo().isEmpty()) {
|
||||
restoreGeometry(g.compareWinGeo());
|
||||
}
|
||||
}
|
||||
|
||||
//setDragDropOverwriteMode(true);
|
||||
//setDropIndicatorShown(true);
|
||||
// TODO scroll to top ... ui->textEdit->scrollToAnchor("1");
|
||||
CompareDialog::~CompareDialog()
|
||||
{
|
||||
delete multimodelprinter;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void CompareDialog::dragMoveEvent(QDragMoveEvent * event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat("application/x-companion")) {
|
||||
if (event->mimeData()->hasFormat("application/x-companion-modeldata")) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else {
|
||||
@@ -49,8 +70,7 @@ void CompareDialog::dragMoveEvent(QDragMoveEvent * event)
|
||||
|
||||
void CompareDialog::dragEnterEvent(QDragEnterEvent * event)
|
||||
{
|
||||
// accept just text/uri-list mime format
|
||||
if (event->mimeData()->hasFormat("application/x-companion")) {
|
||||
if (event->mimeData()->hasFormat("application/x-companion-modeldata")) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
else {
|
||||
@@ -63,55 +83,85 @@ void CompareDialog::dragLeaveEvent(QDragLeaveEvent * event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
bool CompareDialog::handleDroppedModel(const QMimeData * mimeData, ModelData & model, QLabel * label)
|
||||
bool CompareDialog::handleMimeData(const QMimeData * mimeData)
|
||||
{
|
||||
if (mimeData->hasFormat("application/x-companion")) {
|
||||
QByteArray gmData = mimeData->data("application/x-companion");
|
||||
DragDropHeader * header = (DragDropHeader *)gmData.data();
|
||||
if (!header->general_settings) {
|
||||
char * gData = gmData.data() + sizeof(DragDropHeader);
|
||||
if (gData[0] == 'M') {
|
||||
ModelData * modeltemp = (ModelData *)(gData + 1);
|
||||
if (modeltemp->used) {
|
||||
memcpy(&model, modeltemp, sizeof(ModelData));
|
||||
QString name(model.name);
|
||||
if (!name.isEmpty())
|
||||
label->setText(name);
|
||||
else
|
||||
label->setText(tr("No name"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
QVector<ModelData> mList;
|
||||
GeneralSettings gs;
|
||||
if (!TreeModel::decodeMimeData(mimeData, &mList, &gs) || mList.isEmpty())
|
||||
return false;
|
||||
for (int i=0; i < mList.size(); ++i) {
|
||||
GMData data;
|
||||
data.model = mList[i];
|
||||
data.gs = gs;
|
||||
modelsList.append(data);
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompareDialog::closeEvent(QCloseEvent * event)
|
||||
{
|
||||
g.compareWinGeo(saveGeometry());
|
||||
}
|
||||
|
||||
void CompareDialog::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QLabel * child = qobject_cast<QLabel*>(childAt(event->pos()));
|
||||
if (!child) return;
|
||||
if (child->objectName().contains("label_1")) {
|
||||
model1Valid = handleDroppedModel(event->mimeData(), model1, ui->label_1);
|
||||
}
|
||||
else if (child->objectName().contains("label_2")) {
|
||||
model2Valid = handleDroppedModel(event->mimeData(), model2, ui->label_2);
|
||||
}
|
||||
event->accept();
|
||||
if (model1Valid && model2Valid) {
|
||||
multimodelprinter.setModel(0, model1);
|
||||
multimodelprinter.setModel(1, model2);
|
||||
ui->textEdit->setHtml(multimodelprinter.print(ui->textEdit->document()));
|
||||
if (handleMimeData(event->mimeData())) {
|
||||
event->accept();
|
||||
compare();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::closeEvent(QCloseEvent *event)
|
||||
void CompareDialog::compare()
|
||||
{
|
||||
QLayoutItem *child;
|
||||
while ((child = ui->layout_modelNames->takeAt(0))) {
|
||||
if (child->widget())
|
||||
delete child->widget();
|
||||
delete child;
|
||||
}
|
||||
|
||||
multimodelprinter->clearModels();
|
||||
ui->textEdit->clear();
|
||||
|
||||
for (int i=0; i < modelsList.size(); ++i) {
|
||||
multimodelprinter->setModel(i, &modelsList[i].model, &modelsList[i].gs);
|
||||
QString name(modelsList.at(i).model.name);
|
||||
if (name.isEmpty())
|
||||
name = tr("Unnamed Model %1").arg(i+1);
|
||||
|
||||
QWidget * hdr = new QWidget(this);
|
||||
hdr->setLayout(new QHBoxLayout());
|
||||
hdr->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
hdr->layout()->setSpacing(2);
|
||||
QToolButton * btn = new QToolButton(hdr);
|
||||
btn->setIcon(CompanionIcon("clear.png"));
|
||||
btn->setProperty("index", i);
|
||||
btn->setFixedSize(18, 18);
|
||||
btn->setToolTip(tr("Click to remove this model."));
|
||||
hdr->layout()->addWidget(btn);
|
||||
QLabel * lbl = new QLabel(name, this);
|
||||
lbl->setStyleSheet("font-weight: bold;");
|
||||
hdr->layout()->addWidget(lbl);
|
||||
connect(btn, &QToolButton::clicked, this, &CompareDialog::removeModelBtnClicked);
|
||||
|
||||
ui->layout_modelNames->addWidget(hdr);
|
||||
}
|
||||
if (modelsList.size())
|
||||
ui->textEdit->setHtml(multimodelprinter->print(ui->textEdit->document()));
|
||||
}
|
||||
|
||||
CompareDialog::~CompareDialog()
|
||||
void CompareDialog::removeModel(int idx)
|
||||
{
|
||||
delete ui;
|
||||
if (idx < modelsList.size()) {
|
||||
modelsList.remove(idx);
|
||||
compare();
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::removeModelBtnClicked()
|
||||
{
|
||||
if (sender() && sender()->property("index").isValid())
|
||||
removeModel(sender()->property("index").toInt());
|
||||
}
|
||||
|
||||
void CompareDialog::on_printButton_clicked()
|
||||
@@ -140,3 +190,10 @@ void CompareDialog::on_printFileButton_clicked()
|
||||
ui->textEdit->print(&printer);
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::on_styleButton_clicked()
|
||||
{
|
||||
StyleEditDialog *g = new StyleEditDialog(this, MODEL_PRINT_CSS);
|
||||
if (g->exec() == QDialog::Accepted)
|
||||
compare();
|
||||
}
|
||||
|
||||
@@ -1,41 +1,67 @@
|
||||
#ifndef _COMPAREDIALOG_H
|
||||
#define _COMPAREDIALOG_H
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "multimodelprinter.h"
|
||||
|
||||
namespace Ui {
|
||||
class CompareDialog;
|
||||
}
|
||||
|
||||
class CompareDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CompareDialog(QWidget *parent, Firmware * firmware);
|
||||
~CompareDialog();
|
||||
|
||||
protected:
|
||||
MultiModelPrinter multimodelprinter;
|
||||
ModelData model1;
|
||||
ModelData model2;
|
||||
bool model1Valid;
|
||||
bool model2Valid;
|
||||
Ui::CompareDialog * ui;
|
||||
|
||||
protected slots:
|
||||
void on_printButton_clicked();
|
||||
void on_printFileButton_clicked();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent * event);
|
||||
bool handleDroppedModel(const QMimeData * mimeData, ModelData & model, QLabel * label);
|
||||
void dropEvent(QDropEvent *event);
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
void printDiff();
|
||||
};
|
||||
|
||||
#endif // _COMPAREDIALOG_H
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _COMPAREDIALOG_H_
|
||||
#define _COMPAREDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "multimodelprinter.h"
|
||||
|
||||
namespace Ui {
|
||||
class CompareDialog;
|
||||
}
|
||||
|
||||
class CompareDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CompareDialog(QWidget *parent, Firmware * firmware);
|
||||
~CompareDialog();
|
||||
|
||||
protected:
|
||||
struct GMData {
|
||||
ModelData model;
|
||||
GeneralSettings gs;
|
||||
};
|
||||
|
||||
MultiModelPrinter * multimodelprinter;
|
||||
QVector<GMData> modelsList;
|
||||
QMap<int, GMData> modelsMap;
|
||||
Ui::CompareDialog * ui;
|
||||
|
||||
protected slots:
|
||||
void removeModelBtnClicked();
|
||||
void on_printButton_clicked();
|
||||
void on_printFileButton_clicked();
|
||||
void on_styleButton_clicked();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent * event);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *event);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *event);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *event);
|
||||
virtual void dropEvent(QDropEvent *event);
|
||||
bool handleMimeData(const QMimeData * mimeData);
|
||||
void compare();
|
||||
void removeModel(int idx);
|
||||
};
|
||||
|
||||
#endif // _COMPAREDIALOG_H_
|
||||
|
||||
@@ -29,63 +29,25 @@
|
||||
<string>Compare Models</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:green;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Drag first model here</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Drag second model here</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>To compare models, drag and drop them anywhere in this window.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -106,6 +68,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="styleButton">
|
||||
<property name="text">
|
||||
<string>Style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="printButton">
|
||||
<property name="text">
|
||||
@@ -122,11 +91,28 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="layout_modelNames">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="companion.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
|
||||
+80
-38
@@ -1,41 +1,83 @@
|
||||
#ifndef _constants_h_
|
||||
#define _constants_h_
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
enum BoardEnum {
|
||||
BOARD_STOCK,
|
||||
BOARD_M128,
|
||||
BOARD_MEGA2560,
|
||||
BOARD_GRUVIN9X,
|
||||
BOARD_SKY9X,
|
||||
BOARD_9XRPRO,
|
||||
BOARD_AR9X,
|
||||
BOARD_TARANIS,
|
||||
BOARD_TARANIS_PLUS,
|
||||
BOARD_TARANIS_X9E,
|
||||
BOARD_FLAMENCO,
|
||||
BOARD_HORUS
|
||||
};
|
||||
#ifndef _CONSTANTS_H_
|
||||
#define _CONSTANTS_H_
|
||||
|
||||
#define C9X_MAX_MODELS 60
|
||||
#define C9X_MAX_TIMERS 3
|
||||
#define C9X_MAX_FLIGHT_MODES 9
|
||||
#define C9X_MAX_MIXERS 64
|
||||
#define C9X_MAX_INPUTS 32
|
||||
#define C9X_MAX_EXPOS 64
|
||||
#define C9X_MAX_CURVES 32
|
||||
#define C9X_MAX_POINTS 17
|
||||
#define C9X_MAX_GVARS 9
|
||||
#define C9X_MAX_ENCODERS 2
|
||||
#define C9X_NUM_CHNOUT 32 // number of real output channels
|
||||
#define C9X_NUM_CSW 64 // number of custom switches
|
||||
#define C9X_MAX_CUSTOM_FUNCTIONS 64 // number of functions assigned to switches
|
||||
#define C9X_NUM_MODULES 2
|
||||
#define NUM_STICKS 4
|
||||
#define BOARD_9X_NUM_POTS 3
|
||||
#define C9X_NUM_POTS 8
|
||||
#define NUM_CAL_PPM 4
|
||||
#define NUM_CYC 3
|
||||
#define C9X_NUM_SWITCHES 32
|
||||
#define C9X_NUM_KEYS 32
|
||||
#include <QCoreApplication>
|
||||
|
||||
#endif
|
||||
#define CPN_MAX_MODELS 60
|
||||
#define CPN_MAX_TIMERS 3
|
||||
#define CPN_MAX_FLIGHT_MODES 9
|
||||
#define CPN_MAX_MIXERS 64
|
||||
#define CPN_MAX_INPUTS 32
|
||||
#define CPN_MAX_EXPOS 64
|
||||
#define CPN_MAX_CURVES 32
|
||||
#define CPN_MAX_POINTS 17
|
||||
#define CPN_MAX_GVARS 9
|
||||
#define CPN_MAX_ENCODERS 2 // rotary encoders
|
||||
#define CPN_MAX_CHNOUT 32 // number of real output channels
|
||||
#define CPN_MAX_LOGICAL_SWITCHES 64 // number of custom switches
|
||||
#define CPN_MAX_SPECIAL_FUNCTIONS 64 // number of functions assigned to switches
|
||||
#define CPN_MAX_MODULES 2
|
||||
#define CPN_MAX_STICKS Board::STICK_AXIS_COUNT
|
||||
#define CPN_MAX_TRIMS Board::TRIM_AXIS_COUNT
|
||||
#define CPN_MAX_TRIM_SW Board::TRIM_SW_COUNT
|
||||
#define CPN_MAX_KNOBS 4
|
||||
#define CPN_MAX_SLIDERS 4
|
||||
#define CPN_MAX_POTS (CPN_MAX_KNOBS + CPN_MAX_SLIDERS)
|
||||
#define CPN_MAX_CYC 3
|
||||
#define CPN_MAX_SWITCHES 32
|
||||
#define CPN_MAX_KEYS 32
|
||||
#define CPN_MAX_MOUSE_ANALOGS 2
|
||||
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_MOUSE_ANALOGS)
|
||||
|
||||
#define CPN_STR_APP_NAME QCoreApplication::translate("Companion", "OpenTX Companion")
|
||||
#define CPN_STR_TTL_INFO QCoreApplication::translate("Companion", "Information") // shared Title Case words, eg. for a window title or section heading
|
||||
#define CPN_STR_TTL_WARNING QCoreApplication::translate("Companion", "Warning")
|
||||
#define CPN_STR_TTL_ERROR QCoreApplication::translate("Companion", "Error")
|
||||
#define CPN_STR_TTL_CONFIRM QCoreApplication::translate("Companion", "Please Confirm")
|
||||
|
||||
#define CPN_STR_FILES QCoreApplication::translate("Companion", "files")
|
||||
#define CPN_STR_RAD_MOD_SETTINGS QCoreApplication::translate("Companion", "Radio and Models settings")
|
||||
#define HEX_FILES_FILTER "HEX " % CPN_STR_FILES % " (*.hex);;"
|
||||
#define BIN_FILES_FILTER "BIN " % CPN_STR_FILES % " (*.bin);;"
|
||||
#define DFU_FILES_FILTER "DFU " % CPN_STR_FILES % " (*.dfu);;"
|
||||
#define EEPE_FILES_FILTER "EEPE " % CPN_STR_FILES % " (*.eepe);;"
|
||||
#define OTX_FILES_FILTER "OpenTX " % CPN_STR_FILES % " (*.otx);;"
|
||||
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.otx *.eepe *.bin *.hex);;" % OTX_FILES_FILTER % EEPE_FILES_FILTER % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define FLASH_FILES_FILTER "FLASH " % CPN_STR_FILES % " (*.bin *.hex *.dfu);;" % BIN_FILES_FILTER % HEX_FILES_FILTER % DFU_FILES_FILTER
|
||||
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " % CPN_STR_FILES % " (*.bin *.hex);;" % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
|
||||
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
|
||||
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
|
||||
|
||||
#define CPN_STR_APP_SETTINGS QCoreApplication::translate("Companion", "Application Settings")
|
||||
#define CPN_STR_APP_SETTINGS_FILES CPN_STR_APP_SETTINGS % " " % CPN_STR_FILES
|
||||
#define CPN_STR_APP_SETTINGS_FILTER CPN_STR_APP_SETTINGS_FILES % " (*.ini)"
|
||||
|
||||
#define CPN_STR_UNKNOWN_ITEM "???"
|
||||
|
||||
#define CPN_STR_SW_INDICATOR_UP QCoreApplication::translate("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_DN QCoreApplication::translate("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_NEUT QCoreApplication::translate("RawSwitch", "-") // Switch neutral (middle) position indicator.
|
||||
#define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
|
||||
|
||||
#endif // _CONSTANTS_H_
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef CONTRIBUTORSDIALOG_H
|
||||
#define CONTRIBUTORSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class HtmlDialog;
|
||||
}
|
||||
|
||||
class ContributorsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ContributorsDialog(QWidget * parent = 0);
|
||||
~ContributorsDialog();
|
||||
|
||||
private:
|
||||
Ui::HtmlDialog * ui;
|
||||
QString formatTable(const QString & title, const QStringList & names, int colums);
|
||||
};
|
||||
|
||||
#endif // CONTRIBUTORSDIALOG_H
|
||||
@@ -1,45 +0,0 @@
|
||||
#include "converteeprom.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "firmwareinterface.h"
|
||||
#include <QFile>
|
||||
|
||||
bool convertEEprom(const QString &sourceEEprom, const QString &destinationEEprom, const QString &firmwareFilename)
|
||||
{
|
||||
Firmware *currentFirmware = GetCurrentFirmware();
|
||||
FirmwareInterface firmware(firmwareFilename);
|
||||
if (!firmware.isValid())
|
||||
return false;
|
||||
|
||||
unsigned int version = firmware.getEEpromVersion();
|
||||
unsigned int variant = firmware.getEEpromVariant();
|
||||
|
||||
QFile sourceFile(sourceEEprom);
|
||||
int eeprom_size = sourceFile.size();
|
||||
if (!eeprom_size)
|
||||
return false;
|
||||
|
||||
if (!sourceFile.open(QIODevice::ReadOnly))
|
||||
return false;
|
||||
|
||||
QByteArray eeprom(eeprom_size, 0);
|
||||
long result = sourceFile.read(eeprom.data(), eeprom_size);
|
||||
sourceFile.close();
|
||||
|
||||
QSharedPointer<RadioData> radioData = QSharedPointer<RadioData>(new RadioData());
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)LoadEeprom(*radioData, (uint8_t *)eeprom.data(), eeprom_size));
|
||||
if (!errors.test(ALL_OK)
|
||||
|| !currentFirmware->saveEEPROM((uint8_t *)eeprom.data(), *radioData, variant, version)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile destinationFile(destinationEEprom);
|
||||
if (!destinationFile.open(QIODevice::WriteOnly))
|
||||
return false;
|
||||
|
||||
result = destinationFile.write(eeprom.constData(), eeprom_size);
|
||||
destinationFile.close();
|
||||
if (result != eeprom_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef CONVERTHEADER_H_
|
||||
#define CONVERTHEADER_H_
|
||||
|
||||
#include <QString>
|
||||
|
||||
bool convertEEprom(const QString &sourceEEprom, const QString &destinationEEprom, const QString &firmware);
|
||||
|
||||
#endif /* CONVERTHEADER_H_ */
|
||||
@@ -1,8 +1,29 @@
|
||||
#include "contributorsdialog.h"
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "creditsdialog.h"
|
||||
#include "ui_htmldialog.h"
|
||||
#include "helpers.h"
|
||||
#include <QFile>
|
||||
|
||||
ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
CreditsDialog::CreditsDialog(QWidget * parent):
|
||||
QDialog(parent),
|
||||
ui(new Ui::HtmlDialog)
|
||||
{
|
||||
@@ -21,42 +42,8 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
"</head>"
|
||||
"<body class=\"normal\">";
|
||||
|
||||
QFile credits(":/CREDITS.txt");
|
||||
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine();
|
||||
if (line.trimmed() == "")
|
||||
break;
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Main Developers"), names, 3));
|
||||
|
||||
names.clear();
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine();
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Other contributors"), names, 3));
|
||||
}
|
||||
|
||||
QFile donations(":/DONATIONS.txt");
|
||||
if (donations.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
while (!donations.atEnd()) {
|
||||
QByteArray line = donations.readLine();
|
||||
if (line.trimmed() == "")
|
||||
break;
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Companies and projects who have donated to OpenTX"), names, 3));
|
||||
|
||||
names.clear();
|
||||
while (!donations.atEnd()) {
|
||||
QByteArray line = donations.readLine();
|
||||
names.append(line);
|
||||
}
|
||||
str.append(formatTable(tr("People who have donated to OpenTX"), names, 6));
|
||||
foreach(CreditsSection section, readCredits()) {
|
||||
str.append(formatTable(sectionTitle(section.title), section.names, 3));
|
||||
}
|
||||
|
||||
str.append("<table><tr><td class=\"normal\"> </td></tr>" \
|
||||
@@ -66,9 +53,9 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
#if 0
|
||||
QFile blacklist(":/BLACKLIST.txt");
|
||||
if (blacklist.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
names << blacklist.readAll();
|
||||
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
|
||||
QStringList names;
|
||||
names << blacklist.readAll();
|
||||
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -78,12 +65,45 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
ui->textEditor->setOpenExternalLinks(true);
|
||||
}
|
||||
|
||||
ContributorsDialog::~ContributorsDialog()
|
||||
CreditsDialog::~CreditsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString ContributorsDialog::formatTable(const QString & title, const QStringList & names, int columns)
|
||||
QList<CreditsDialog::CreditsSection> CreditsDialog::readCredits()
|
||||
{
|
||||
QFile credits(":/CREDITS.txt");
|
||||
QList<CreditsSection> result;
|
||||
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine().trimmed();
|
||||
if (line.size() >= 2) {
|
||||
if (line.startsWith("[") && line.endsWith("]")) {
|
||||
result.push_back(CreditsSection(line.mid(1, line.size() - 2)));
|
||||
} else {
|
||||
result.back().addName(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CreditsDialog::sectionTitle(const QString & title)
|
||||
{
|
||||
if (title == "Main developers")
|
||||
return tr("Main developers");
|
||||
else if (title == "Translators")
|
||||
return tr("Translators");
|
||||
else if (title == "Companies and projects who have donated to OpenTX")
|
||||
return tr("Companies and projects who have donated to OpenTX");
|
||||
else if (title == "People who have donated to OpenTX")
|
||||
return tr("People who have donated to OpenTX");
|
||||
else
|
||||
return tr("Other contributors");
|
||||
}
|
||||
|
||||
QString CreditsDialog::formatTable(const QString & title, const QStringList & names, int columns)
|
||||
{
|
||||
const float cwidth = 100.0 / columns;
|
||||
QString str = "<table width=\"100%\" border=0 cellspacing=0 cellpadding=2>" \
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CREDITSDIALOG_H_
|
||||
#define _CREDITSDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class HtmlDialog;
|
||||
}
|
||||
|
||||
class CreditsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class CreditsSection
|
||||
{
|
||||
public:
|
||||
CreditsSection(const QString & title):
|
||||
title(title)
|
||||
{
|
||||
}
|
||||
|
||||
void addName(const QString & name)
|
||||
{
|
||||
names.push_back(name);
|
||||
}
|
||||
|
||||
QString title;
|
||||
QStringList names;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit CreditsDialog(QWidget * parent = 0);
|
||||
~CreditsDialog();
|
||||
|
||||
private:
|
||||
Ui::HtmlDialog * ui;
|
||||
QList<CreditsSection> readCredits();
|
||||
QString sectionTitle(const QString & title);
|
||||
QString formatTable(const QString & title, const QStringList & names, int colums);
|
||||
};
|
||||
|
||||
#endif // _CREDITSDIALOG_H_
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customdebug.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(eepromImport, "eeprom.import")
|
||||
|
||||
Q_LOGGING_CATEGORY(simulatorInterfaceLoader, "simulator.interface.loader")
|
||||
|
||||
void CustomDebug::setFilterRules()
|
||||
{
|
||||
QString rules;
|
||||
rules.append("eeprom.import=");
|
||||
#if defined(DEBUG_STORAGE_IMPORT)
|
||||
rules.append("true\n");
|
||||
#else
|
||||
rules.append("false\n");
|
||||
#endif
|
||||
|
||||
rules.append("simulator.interface.*=true\n");
|
||||
|
||||
QLoggingCategory::setFilterRules(rules);
|
||||
}
|
||||
+32
-10
@@ -1,16 +1,38 @@
|
||||
#ifndef customdebug_h
|
||||
#define customdebug_h
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#ifndef _CUSTOMDEBUG_H_
|
||||
#define _CUSTOMDEBUG_H_
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
// Controls the generation of debug output for EEPROM import
|
||||
#if defined(DEBUG_MODEL_IMPORT)
|
||||
inline QDebug eepromImportDebug() { return QDebug(QtDebugMsg); }
|
||||
#else
|
||||
#undef eepromImportDebug
|
||||
inline QNoDebug eepromImportDebug() { return QNoDebug(); }
|
||||
#endif
|
||||
Q_DECLARE_LOGGING_CATEGORY(eepromImport) // "eeprom.import"
|
||||
|
||||
// Controls the generation of debug output of SimulatorLoader class
|
||||
Q_DECLARE_LOGGING_CATEGORY(simulatorInterfaceLoader) // "simulator.interface.loader"
|
||||
|
||||
#endif
|
||||
class CustomDebug
|
||||
{
|
||||
public:
|
||||
static void setFilterRules();
|
||||
};
|
||||
|
||||
#endif // _CUSTOMDEBUG_H_
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customizesplashdialog.h"
|
||||
#include "ui_customizesplashdialog.h"
|
||||
#include "flashfirmwaredialog.h"
|
||||
@@ -29,11 +49,11 @@ void Side::markSourceButton()
|
||||
|
||||
void Side::copyImage( Side side )
|
||||
{
|
||||
if ((*source!=UNDEFINED) && (*side.source!=UNDEFINED))
|
||||
if ((*source!=UNDEFINED) && (*side.source!=UNDEFINED))
|
||||
imageLabel->setPixmap(*side.imageLabel->pixmap());
|
||||
}
|
||||
|
||||
bool Side::displayImage( QString fileName, Source pictSource )
|
||||
bool Side::displayImage(QString fileName, Source pictSource)
|
||||
{
|
||||
QImage image;
|
||||
|
||||
@@ -41,7 +61,7 @@ bool Side::displayImage( QString fileName, Source pictSource )
|
||||
return false;
|
||||
|
||||
// Determine which picture format to use
|
||||
if (pictSource == FW ){
|
||||
if (pictSource == FW) {
|
||||
FirmwareInterface firmware(fileName);
|
||||
if (!firmware.hasSplash())
|
||||
return false;
|
||||
@@ -54,39 +74,36 @@ bool Side::displayImage( QString fileName, Source pictSource )
|
||||
if (pictSource== PICT)
|
||||
*format = image.width()>WIDTH_9X ? LCDTARANIS : LCD9X;
|
||||
else if (pictSource == PROFILE)
|
||||
*format = (g.profile[g.id()].fwType().contains("taranis")) ? LCDTARANIS : LCD9X;
|
||||
*format = (g.profile[g.id()].fwType().contains("x9")) ? LCDTARANIS : LCD9X;
|
||||
}
|
||||
|
||||
if (image.isNull()) {
|
||||
return false;
|
||||
}
|
||||
// Load image
|
||||
if (*format==LCDTARANIS) {
|
||||
imageLabel->setPixmap( makePixMap( image, "taranis" ));
|
||||
imageLabel->setFixedSize(WIDTH_TARANIS*2, HEIGHT_TARANIS*2);
|
||||
}
|
||||
else {
|
||||
imageLabel->setPixmap( makePixMap( image, "9x" ));
|
||||
imageLabel->setFixedSize(WIDTH_9X*2, HEIGHT_9X*2);
|
||||
}
|
||||
|
||||
switch (pictSource){
|
||||
case FW:
|
||||
fileNameEdit->setText(QObject::tr("FW: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source=FW;
|
||||
break;
|
||||
case PICT:
|
||||
fileNameEdit->setText(QObject::tr("Pict: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source=PICT;
|
||||
break;
|
||||
case PROFILE:
|
||||
fileNameEdit->setText(QObject::tr("Profile image"));
|
||||
*saveToFileName = fileName;
|
||||
*source=PROFILE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// Load image
|
||||
QPixmap pixmap = makePixMap(image);
|
||||
imageLabel->setPixmap(pixmap);
|
||||
imageLabel->setFixedSize(pixmap.width()*2, pixmap.height()*2);
|
||||
|
||||
switch (pictSource) {
|
||||
case FW:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("FW: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source = FW;
|
||||
break;
|
||||
case PICT:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("Pict: %1").arg(fileName));
|
||||
*saveToFileName = fileName;
|
||||
*source = PICT;
|
||||
break;
|
||||
case PROFILE:
|
||||
fileNameEdit->setText(CustomizeSplashDialog::tr("Profile image"));
|
||||
*saveToFileName = fileName;
|
||||
*source = PROFILE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
saveButton->setEnabled(true);
|
||||
libraryButton->setEnabled(true);
|
||||
@@ -133,17 +150,15 @@ bool Side::saveImage()
|
||||
return true;
|
||||
}
|
||||
|
||||
//*** customizeSplashDialog Class ***
|
||||
|
||||
customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
|
||||
CustomizeSplashDialog::CustomizeSplashDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::customizeSplashDialog)
|
||||
ui(new Ui::CustomizeSplashDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("paintbrush.png"));
|
||||
ui->leftLibraryButton->setIcon(CompanionIcon("library.png"));
|
||||
ui->rightLibraryButton->setIcon(CompanionIcon("library.png"));
|
||||
|
||||
|
||||
left.imageLabel = ui->leftImageLabel;
|
||||
right.imageLabel = ui->rightImageLabel;
|
||||
left.fileNameEdit = ui->leftFileNameEdit;
|
||||
@@ -154,7 +169,7 @@ customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
|
||||
right.libraryButton = ui->rightLibraryButton;
|
||||
left.invertButton = ui->leftInvertButton;
|
||||
right.invertButton = ui->rightInvertButton;
|
||||
|
||||
|
||||
left.loadFwButton = ui->leftLoadFwButton;
|
||||
right.loadFwButton = ui->rightLoadFwButton;
|
||||
left.loadPictButton = ui->leftLoadPictButton;
|
||||
@@ -168,36 +183,36 @@ customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
|
||||
resize(0,0);
|
||||
}
|
||||
|
||||
customizeSplashDialog::~customizeSplashDialog()
|
||||
CustomizeSplashDialog::~CustomizeSplashDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_copyRightToLeftButton_clicked() {
|
||||
void CustomizeSplashDialog::on_copyRightToLeftButton_clicked() {
|
||||
left.copyImage(right);
|
||||
}
|
||||
void customizeSplashDialog::on_copyLeftToRightButton_clicked() {
|
||||
void CustomizeSplashDialog::on_copyLeftToRightButton_clicked() {
|
||||
right.copyImage(left);
|
||||
}
|
||||
|
||||
|
||||
void customizeSplashDialog::on_leftLoadFwButton_clicked() {loadFirmware(left);}
|
||||
void customizeSplashDialog::on_rightLoadFwButton_clicked() {loadFirmware(right);}
|
||||
void customizeSplashDialog::loadFirmware(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadFwButton_clicked() {loadFirmware(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadFwButton_clicked() {loadFirmware(right);}
|
||||
void CustomizeSplashDialog::loadFirmware(Side side)
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Firmware File"), g.flashDir(), FLASH_FILES_FILTER);
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, FW ))
|
||||
QMessageBox::critical(this, tr("Error"), tr("Can not load embedded image from firmware file %1.").arg(fileName));
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Can not load embedded image from firmware file %1.").arg(fileName));
|
||||
else
|
||||
g.flashDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLoadPictButton_clicked() {loadPicture(left);}
|
||||
void customizeSplashDialog::on_rightLoadPictButton_clicked() {loadPicture(right);}
|
||||
void customizeSplashDialog::loadPicture(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadPictButton_clicked() {loadPicture(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadPictButton_clicked() {loadPicture(right);}
|
||||
void CustomizeSplashDialog::loadPicture(Side side)
|
||||
{
|
||||
QString supportedImageFormats;
|
||||
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
|
||||
@@ -208,42 +223,42 @@ void customizeSplashDialog::loadPicture(Side side)
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, PICT ))
|
||||
QMessageBox::critical(this, tr("Error"), tr("Cannot load the image file %1.").arg(fileName));
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load the image file %1.").arg(fileName));
|
||||
else
|
||||
g.imagesDir( QFileInfo(fileName).dir().absolutePath() );
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
|
||||
void customizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
|
||||
void customizeSplashDialog::loadProfile(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
|
||||
void CustomizeSplashDialog::loadProfile(Side side)
|
||||
{
|
||||
QString fileName=g.profile[g.id()].splashFile();
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, PROFILE ))
|
||||
QMessageBox::critical(this, tr("Error"), tr("Cannot load profile image %1.").arg(fileName));
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load profile image %1.").arg(fileName));
|
||||
}
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicked(right);}
|
||||
void customizeSplashDialog::libraryButton_clicked( Side side )
|
||||
void CustomizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicked(right);}
|
||||
void CustomizeSplashDialog::libraryButton_clicked( Side side )
|
||||
{
|
||||
QString fileName;
|
||||
SplashLibraryDialog *ld = new SplashLibraryDialog(this,&fileName);
|
||||
ld->exec();
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!side.displayImage( fileName, UNDEFINED ))
|
||||
QMessageBox::critical(this, tr("Error"), tr("Cannot load the library image %1.").arg(fileName));
|
||||
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Cannot load the library image %1.").arg(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
|
||||
void customizeSplashDialog::saveButton_clicked( Side side )
|
||||
void CustomizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
|
||||
void CustomizeSplashDialog::saveButton_clicked( Side side )
|
||||
{
|
||||
if (side.saveImage()){
|
||||
QMessageBox::information(this, tr("File Saved"), tr("The image was saved to the file %1").arg(*side.saveToFileName));
|
||||
@@ -255,9 +270,9 @@ void customizeSplashDialog::saveButton_clicked( Side side )
|
||||
QMessageBox::critical(this, tr("File Save Error"), tr("Failed to write image to %1").arg(*side.saveToFileName));
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightInvertButton_clicked(){invertButton_clicked(right);}
|
||||
void customizeSplashDialog::invertButton_clicked(Side side)
|
||||
void CustomizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightInvertButton_clicked(){invertButton_clicked(right);}
|
||||
void CustomizeSplashDialog::invertButton_clicked(Side side)
|
||||
{
|
||||
QImage image = side.imageLabel->pixmap()->toImage();
|
||||
image.invertPixels();
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
#ifndef CUSTOMIZESPLASHDIALOG_H
|
||||
#define CUSTOMIZESPLASHDIALOG_H
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CUSTOMIZESPLASHDIALOG_H_
|
||||
#define _CUSTOMIZESPLASHDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include "firmwareinterface.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class customizeSplashDialog;
|
||||
class CustomizeSplashDialog;
|
||||
}
|
||||
|
||||
const int WIDTH_TARANIS = 212;
|
||||
@@ -43,15 +63,15 @@ private:
|
||||
LCDFormat *format;
|
||||
};
|
||||
|
||||
class customizeSplashDialog : public QDialog
|
||||
class CustomizeSplashDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Side left;
|
||||
Side right;
|
||||
|
||||
public:
|
||||
explicit customizeSplashDialog(QWidget *parent = 0);
|
||||
~customizeSplashDialog();
|
||||
explicit CustomizeSplashDialog(QWidget *parent = 0);
|
||||
~CustomizeSplashDialog();
|
||||
|
||||
private slots:
|
||||
void on_leftLoadFwButton_clicked();
|
||||
@@ -79,8 +99,8 @@ private:
|
||||
void saveButton_clicked( Side );
|
||||
void invertButton_clicked( Side );
|
||||
|
||||
Ui::customizeSplashDialog *ui;
|
||||
Ui::CustomizeSplashDialog *ui;
|
||||
enum sideEnum { LEFT, RIGHT };
|
||||
};
|
||||
|
||||
#endif // CUSTOMIZESPLASHDIALOG_H
|
||||
#endif // _CUSTOMIZESPLASHDIALOG_H_
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>customizeSplashDialog</class>
|
||||
<widget class="QDialog" name="customizeSplashDialog">
|
||||
<class>CustomizeSplashDialog</class>
|
||||
<widget class="QDialog" name="CustomizeSplashDialog">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
set(datamodels_SRCS
|
||||
rawitemdatamodels.cpp
|
||||
rawitemfilteredmodel.cpp
|
||||
)
|
||||
|
||||
set(datamodels_HDRS
|
||||
rawitemdatamodels.h
|
||||
rawitemfilteredmodel.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(datamodels_SRCS ${datamodels_HDRS})
|
||||
|
||||
add_library(datamodels ${datamodels_SRCS} ${datamodels_HDRS})
|
||||
target_link_libraries(datamodels PRIVATE ${CPN_COMMON_LIB})
|
||||
|
||||
target_include_directories(datamodels
|
||||
PRIVATE
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${COMPANION_SRC_DIRECTORY}"
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
)
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemdatamodels.h"
|
||||
#include "generalsettings.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
const int anasCount = CPN_MAX_STICKS + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + board.getCapability(Board::MouseAnalogs);
|
||||
|
||||
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
|
||||
for (int i=0; i < fw->getCapability(LuaScripts); i++)
|
||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
|
||||
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, anasCount);
|
||||
addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->getCapability(RotaryEncoders));
|
||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board.getCapability(Board::NumTrims));
|
||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board.getCapability(Board::Switches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
|
||||
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
|
||||
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
|
||||
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3);
|
||||
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
|
||||
}
|
||||
|
||||
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
item->setText(src.toString(modelData, generalSettings, board));
|
||||
item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
|
||||
{
|
||||
for (int i = start; i < start + count; i++) {
|
||||
const RawSource src = RawSource(type, i);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(src.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(group, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, src);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSourceItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// RawSwitchItemModel
|
||||
//
|
||||
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, -fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_TRIM, -board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board.getCapability(Board::SwitchPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_TIMER_MODE, 5);
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board.getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
||||
addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_ON, 1);
|
||||
addItems(SWITCH_TYPE_ONE, 1);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
|
||||
{
|
||||
const Board::Type board = getCurrentBoard();
|
||||
item->setText(rsw.toString(board, generalSettings, modelData));
|
||||
item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
// handle exceptions in RawSwitch() index values
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
// determine cotext flags
|
||||
int context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
context &= ~RawSwitch::MixesContext;
|
||||
// fallthrough
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
context &= ~RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
context = RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
context &= ~RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
case SWITCH_TYPE_ONE:
|
||||
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(rs.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(context, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, rs);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMDATAMODELS_H
|
||||
#define RAWITEMDATAMODELS_H
|
||||
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
|
||||
class AbstractRawItemDataModel: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
|
||||
Q_ENUM(DataRoles)
|
||||
|
||||
explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
QStandardItemModel(parent),
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData)
|
||||
{}
|
||||
|
||||
public slots:
|
||||
virtual void update() const = 0;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
};
|
||||
|
||||
|
||||
class RawSourceItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
|
||||
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
|
||||
};
|
||||
|
||||
|
||||
class RawSwitchItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
|
||||
void addItems(const RawSwitchType & type, int count);
|
||||
};
|
||||
|
||||
|
||||
#endif // RAWITEMDATAMODELS_H
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemfilteredmodel.h"
|
||||
#include "rawitemdatamodels.h"
|
||||
|
||||
RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
|
||||
QSortFilterProxyModel(parent),
|
||||
filterFlags(0)
|
||||
{
|
||||
setFilterRole(AbstractRawItemDataModel::IsAvailableRole);
|
||||
setFilterKeyColumn(0);
|
||||
setFilterFlags(flags);
|
||||
setDynamicSortFilter(true);
|
||||
setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::setFilterFlags(int flags)
|
||||
{
|
||||
if (filterFlags != flags) {
|
||||
filterFlags = flags;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
||||
{
|
||||
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
|
||||
return false;
|
||||
|
||||
if (!filterFlags)
|
||||
return true;
|
||||
|
||||
bool ok;
|
||||
const int flags = sourceModel()->data(srcIdx, AbstractRawItemDataModel::ItemFlagsRole).toInt(&ok);
|
||||
return (ok && (!flags || (filterFlags & flags)));
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::update() const
|
||||
{
|
||||
AbstractRawItemDataModel * model = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
|
||||
if (model)
|
||||
model->update();
|
||||
}
|
||||
|
||||
|
||||
RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMFILTEREDMODEL_H
|
||||
#define RAWITEMFILTEREDMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
class RawSourceItemModel;
|
||||
class RawSwitchItemModel;
|
||||
|
||||
class RawItemFilteredModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
|
||||
|
||||
public slots:
|
||||
void setFilterFlags(int flags);
|
||||
void update() const;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
|
||||
|
||||
int filterFlags;
|
||||
};
|
||||
|
||||
|
||||
// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established.
|
||||
// These proxy classes will automatically create a source model of the corresponding type.
|
||||
|
||||
class RawSwitchFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class RawSourceFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr);
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {}
|
||||
};
|
||||
|
||||
#endif // RAWITEMFILTEREDMODEL_H
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "filesyncdialog.h"
|
||||
|
||||
#include "autobitsetcheckbox.h"
|
||||
#include "autocheckbox.h"
|
||||
#include "autocombobox.h"
|
||||
#include "autolineedit.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "progresswidget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QCompleter>
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QFileSystemModel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QSpinBox>
|
||||
|
||||
FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) :
|
||||
QDialog(parent),
|
||||
m_syncOptions(syncOptions),
|
||||
m_running(false)
|
||||
{
|
||||
setWindowTitle(tr("Synchronize Files"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setSizeGripEnabled(true);
|
||||
|
||||
setupUi();
|
||||
toggleExtraOptions(false);
|
||||
validate();
|
||||
updateRunningState();
|
||||
}
|
||||
|
||||
void FileSyncDialog::reject()
|
||||
{
|
||||
// override close event via window system close or esc. key
|
||||
if (m_running) {
|
||||
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Are you sure you wish to abort the sync?")) == QMessageBox::No)
|
||||
return;
|
||||
emit stopSync();
|
||||
// Force termination if the sync hasn't finished within 5s
|
||||
QElapsedTimer tim;
|
||||
tim.start();
|
||||
while (!tim.hasExpired(5000) && m_running)
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 10);
|
||||
if (m_running)
|
||||
qWarning() << "Terminating thread while Sync process was still running.";
|
||||
}
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
// Create a widget with a line edit and folder select button and handles all interactions. Features autosuggest
|
||||
// path hints while typing, invalid paths shown in red.
|
||||
// This should probably be moved some place more reusable, esp. the QFileSystemModel.
|
||||
static QWidget * folderSelectorWidget(QLineEdit * le, QWidget * parent)
|
||||
{
|
||||
static QFileSystemModel fileModel;
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
init = true;
|
||||
fileModel.setFilter(QDir::Dirs);
|
||||
fileModel.setRootPath("/");
|
||||
}
|
||||
|
||||
QWidget * fsw = new QWidget(parent);
|
||||
//le = new QLineEdit(parent);
|
||||
QCompleter * fsc = new QCompleter(fsw);
|
||||
fsc->setModel(&fileModel);
|
||||
//fsc->setCompletionMode(QCompleter::InlineCompletion);
|
||||
le->setCompleter(fsc);
|
||||
|
||||
QToolButton * btn = new QToolButton(fsw);
|
||||
btn->setIcon(CompanionIcon("open.png"));
|
||||
QHBoxLayout * l = new QHBoxLayout(fsw);
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
l->setSpacing(3);
|
||||
l->addWidget(le);
|
||||
l->addWidget(btn);
|
||||
|
||||
QObject::connect(btn, &QToolButton::clicked, [=]() {
|
||||
QString dir = QFileDialog::getExistingDirectory(parent, fsw->property("fileDialogTitle").toString(), le->text(), 0);
|
||||
if (!dir.isEmpty()) {
|
||||
le->setText(QDir::toNativeSeparators(dir));
|
||||
le->setFocus();
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(le, &QLineEdit::textChanged, [=](const QString & text) {
|
||||
if (QFile::exists(text))
|
||||
le->setStyleSheet("");
|
||||
else
|
||||
le->setStyleSheet("QLineEdit {color: red;}");
|
||||
});
|
||||
|
||||
return fsw;
|
||||
}
|
||||
|
||||
void FileSyncDialog::setupUi()
|
||||
{
|
||||
const QString srcArw = CPN_STR_SW_INDICATOR_UP % " ";
|
||||
const QString dstArw = CPN_STR_SW_INDICATOR_DN % " ";
|
||||
int row = 0;
|
||||
|
||||
CompanionIcon playIcon("play.png");
|
||||
playIcon.addImage("stop.png", QIcon::Normal, QIcon::On);
|
||||
|
||||
QLabel * lblSrc = new QLabel(tr("Source Folder:"), this);
|
||||
AutoLineEdit * leSrc = new AutoLineEdit(this, true);
|
||||
leSrc->setField(m_syncOptions.folderA);
|
||||
leSrc->setText(QDir::toNativeSeparators(m_syncOptions.folderA));
|
||||
QWidget * wdgSrc = folderSelectorWidget(leSrc, this);
|
||||
|
||||
QLabel * lblDst = new QLabel(tr("Destination Folder:"), this);
|
||||
AutoLineEdit * leDst = new AutoLineEdit(this, true);
|
||||
leDst->setField(m_syncOptions.folderB);
|
||||
leDst->setText(QDir::toNativeSeparators(m_syncOptions.folderB));
|
||||
QWidget * wdgDst = folderSelectorWidget(leDst, this);
|
||||
|
||||
AutoComboBox * syncDir = new AutoComboBox(this);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to destination folder first").arg(dstArw, srcArw), SyncProcess::SYNC_A2B_B2A);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to source folder first").arg(srcArw, dstArw), SyncProcess::SYNC_B2A_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from source folder to destination folder").arg(dstArw), SyncProcess::SYNC_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from destination folder to source folder").arg(srcArw), SyncProcess::SYNC_B2A);
|
||||
syncDir->setCurrentIndex(-1); // we set the default option later
|
||||
|
||||
AutoComboBox * copyMode = new AutoComboBox(this);
|
||||
copyMode->setToolTip(tr("How to handle overwriting files which already exist in the destination folder."));
|
||||
copyMode->addItem(tr("Copy only if newer and different (compare contents)"), SyncProcess::OVERWR_NEWER_IF_DIFF);
|
||||
copyMode->addItem(tr("Copy only if newer (do not compare contents)"), SyncProcess::OVERWR_NEWER_ALWAYS);
|
||||
copyMode->addItem(tr("Copy only if different (ignore file time stamps)"), SyncProcess::OVERWR_IF_DIFF);
|
||||
copyMode->addItem(tr("Always copy (force overwite existing files)"), SyncProcess::OVERWR_ALWAYS);
|
||||
copyMode->setField(m_syncOptions.compareType);
|
||||
|
||||
QSpinBox * maxSize = new QSpinBox(this);
|
||||
maxSize->setRange(0, 100 * 1024);
|
||||
maxSize->setAccelerated(true);
|
||||
maxSize->setSpecialValueText(tr("Any size"));
|
||||
maxSize->setToolTip(tr("Skip files larger than this size. Enter zero for unlimited."));
|
||||
maxSize->setGroupSeparatorShown(true);
|
||||
maxSize->setValue(0); // we set the real default value later
|
||||
|
||||
AutoComboBox * logLevel = new AutoComboBox(this);
|
||||
logLevel->setToolTip(tr("Minimum reporting level. Events of this type and of higher importance are shown.\n" \
|
||||
"WARNING: High log rates may make the user interface temporarily unresponsive."));
|
||||
logLevel->addItem(tr("Skipped"), QtDebugMsg);
|
||||
logLevel->addItem(tr("Created"), QtInfoMsg);
|
||||
logLevel->addItem(tr("Updated"), QtWarningMsg);
|
||||
//logLevel->addItem(tr("Item Deleted"), QtCriticalMsg); // unused
|
||||
logLevel->addItem(tr("Errors Only"), QtFatalMsg);
|
||||
logLevel->setField(m_syncOptions.logLevel);
|
||||
|
||||
AutoBitsetCheckBox * testRun = new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_DRY_RUN, tr("Test-run only"), this);
|
||||
testRun->setToolTip(tr("Run as normal but do not actually copy anything. Useful for verifying results before real sync."));
|
||||
|
||||
// layout to hold size spinbox and checkbox option(s)
|
||||
QHBoxLayout * hlay1 = new QHBoxLayout();
|
||||
hlay1->addWidget(maxSize, 1);
|
||||
hlay1->addWidget(testRun);
|
||||
hlay1->addWidget(new QLabel(tr("Log Level:"), this));
|
||||
hlay1->addWidget(logLevel);
|
||||
|
||||
// "extra" options
|
||||
|
||||
QLabel * lbFilter = new QLabel(tr("Filters:"), this);
|
||||
lbFilter->setToolTip(tr("The \"Include\" filter will only copy files which match the pattern(s).\n" \
|
||||
"The \"Exclude\" filter will skip files matching the filter pattern(s).\n" \
|
||||
"The Include filter is evaluated first."));
|
||||
|
||||
AutoLineEdit * leFiltExc = new AutoLineEdit(this, true);
|
||||
leFiltExc->setField(m_syncOptions.excludeFilter);
|
||||
leFiltExc->setToolTip(tr("One or more file pattern(s) to exclude, separated by commas.\n" "Blank means exclude none. ?, *, and [...] wildcards accepted."));
|
||||
|
||||
AutoLineEdit * leFiltInc = new AutoLineEdit(this, true);
|
||||
leFiltInc->setField(m_syncOptions.includeFilter);
|
||||
leFiltInc->setToolTip(tr("One or more file pattern(s) to include, separated by commas.\n" "Blank means include all. ?, *, and [...] wildcards accepted."));
|
||||
|
||||
// layout to hold filter options
|
||||
QHBoxLayout * filtLo = new QHBoxLayout();
|
||||
filtLo->addWidget(new QLabel(tr("Include:"), this));
|
||||
filtLo->addWidget(leFiltInc, 1);
|
||||
filtLo->addWidget(new QLabel(tr("Exclude:"), this));
|
||||
filtLo->addWidget(leFiltExc, 1);
|
||||
|
||||
// file options
|
||||
QHBoxLayout * filOptsLo = new QHBoxLayout();
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::CaseSensitive, tr("Case sensitive"), this));
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::NoSymLinks, true, tr("Follow links"), this));
|
||||
filOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::Hidden, tr("Include hidden"), this));
|
||||
|
||||
// folder options
|
||||
QHBoxLayout * dirOptsLo = new QHBoxLayout();
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_RECURSIVE, tr("Recursive"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.flags, SyncProcess::OPT_SKIP_DIR_LINKS, true, tr("Follow links"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::Dirs, true, tr("Skip empty"), this));
|
||||
dirOptsLo->addWidget(new AutoBitsetCheckBox(m_syncOptions.dirFilterFlags, QDir::AllDirs, true, tr("Apply filters"), this));
|
||||
|
||||
// extra options container widget and layout
|
||||
ui_extraOptions = new QWidget(this);
|
||||
ui_extraOptions->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
||||
|
||||
QGridLayout * xOptsLay = new QGridLayout(ui_extraOptions);
|
||||
xOptsLay->setContentsMargins(0, 0, 0, 0);
|
||||
xOptsLay->addWidget(lbFilter, row, 0);
|
||||
xOptsLay->addLayout(filtLo, row++, 1);
|
||||
xOptsLay->addWidget(new QLabel(tr("Filter Options:"), this), row, 0);
|
||||
xOptsLay->addLayout(filOptsLo, row++, 1);
|
||||
xOptsLay->addWidget(new QLabel(tr("Folder Options:"), this), row, 0);
|
||||
xOptsLay->addLayout(dirOptsLo, row++, 1);
|
||||
|
||||
// status label
|
||||
ui_statusLabel = new QLabel(this);
|
||||
// progress widget
|
||||
ui_progress = new ProgressWidget(this);
|
||||
ui_progress->setMinimumWidth(0);
|
||||
ui_progress->setVisible(false);
|
||||
|
||||
// dialog buttons & menu
|
||||
|
||||
QMenu * optionsMenu = new QMenu(tr("Options"));
|
||||
QAction * xtrasAct = optionsMenu->addAction(CompanionIcon("fuses.png"), tr("Show extra options"), this, &FileSyncDialog::toggleExtraOptions);
|
||||
xtrasAct->setCheckable(true);
|
||||
connect(this, &FileSyncDialog::extraOptionsToggled, xtrasAct, &QAction::setChecked);
|
||||
optionsMenu->addAction(CompanionIcon("paintbrush.png"), tr("Reset to defaults"), this, &FileSyncDialog::resetOptions);
|
||||
|
||||
QToolButton * btnOpts = new QToolButton(this);
|
||||
btnOpts->setDefaultAction(xtrasAct);
|
||||
btnOpts->setMenu(optionsMenu);
|
||||
btnOpts->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
btnOpts->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
btnOpts->setToolTip(xtrasAct->text());
|
||||
|
||||
ui_btnStartStop = new QToolButton(this);
|
||||
ui_btnStartStop->setCheckable(true);
|
||||
ui_btnStartStop->setIcon(playIcon);
|
||||
ui_btnStartStop->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
|
||||
ui_btnClose = new QToolButton(this);
|
||||
ui_btnClose->setText(tr("Close"));
|
||||
ui_btnClose->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
ui_btnClose->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
|
||||
ui_buttonBox = new QDialogButtonBox(this);
|
||||
ui_buttonBox->addButton(btnOpts, QDialogButtonBox::ActionRole);
|
||||
ui_buttonBox->addButton(ui_btnStartStop, QDialogButtonBox::ActionRole);
|
||||
ui_buttonBox->addButton(ui_btnClose, QDialogButtonBox::RejectRole);
|
||||
|
||||
// The options group box.
|
||||
ui_optionsPanel = new QGroupBox(tr("Options"), this);
|
||||
QGridLayout * optsLay = new QGridLayout(ui_optionsPanel);
|
||||
row = 0;
|
||||
optsLay->addWidget(lblSrc, row, 0);
|
||||
optsLay->addWidget(wdgSrc, row++, 1);
|
||||
optsLay->addWidget(lblDst, row, 0);
|
||||
optsLay->addWidget(wdgDst, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Sync. Direction:"), this), row, 0);
|
||||
optsLay->addWidget(syncDir, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Existing Files:"), this), row, 0);
|
||||
optsLay->addWidget(copyMode, row++, 1);
|
||||
optsLay->addWidget(new QLabel(tr("Max. File Size:"), this), row, 0);
|
||||
optsLay->addLayout(hlay1, row++, 1);
|
||||
optsLay->addWidget(ui_extraOptions, row, 0, 1, 2);
|
||||
|
||||
// layout to hold warning label and button box
|
||||
QHBoxLayout * hlay2 = new QHBoxLayout();
|
||||
hlay2->addWidget(ui_statusLabel, 1);
|
||||
hlay2->addWidget(ui_buttonBox);
|
||||
|
||||
// Create main layout and add options, progress, buttons.
|
||||
QVBoxLayout * dlgL = new QVBoxLayout(this);
|
||||
dlgL->addWidget(ui_optionsPanel, 0, Qt::AlignTop);
|
||||
dlgL->addLayout(hlay2);
|
||||
dlgL->addWidget(ui_progress, 1);
|
||||
|
||||
// Connect all signal handlers
|
||||
|
||||
// source path
|
||||
connect(leSrc, &AutoLineEdit::textChanged, this, &FileSyncDialog::validate);
|
||||
// destination path
|
||||
connect(leDst, &AutoLineEdit::textChanged, this, &FileSyncDialog::validate);
|
||||
|
||||
// function to dis/enable the OVERWR_ALWAYS option depending on sync direction
|
||||
connect(syncDir, &AutoComboBox::currentDataChanged, [=](int dir) {
|
||||
int idx = copyMode->findData(SyncProcess::OVERWR_ALWAYS);
|
||||
int flg = (dir == SyncProcess::SYNC_A2B || dir == SyncProcess::SYNC_B2A) ? 33 : 0;
|
||||
if (!flg && idx == copyMode->currentIndex())
|
||||
copyMode->setCurrentIndex(copyMode->findData(SyncProcess::OVERWR_NEWER_IF_DIFF));
|
||||
copyMode->setItemData(idx, flg, Qt::UserRole - 1);
|
||||
});
|
||||
|
||||
// function to set magnitude of file size spinbox, KB or MB
|
||||
connect(maxSize, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
const QSignalBlocker blocker(maxSize);
|
||||
int multi = maxSize->property("multi").isValid() ? maxSize->property("multi").toInt() : 0;
|
||||
if (value >= 10 * 1024 && multi != 1024 * 1024) {
|
||||
// KB -> MB
|
||||
multi = 1024 * 1024;
|
||||
maxSize->setValue(value / 1024);
|
||||
maxSize->setMaximum(100);
|
||||
maxSize->setSingleStep(1);
|
||||
maxSize->setSuffix(tr(" MB"));
|
||||
}
|
||||
else if ((value < 10 && multi != 1024) || !multi) {
|
||||
// MB -> KB
|
||||
if (multi)
|
||||
value *= 1024;
|
||||
multi = 1024;
|
||||
if (value == 9 * 1024)
|
||||
value += 1024 - 32; // avoid large jump when stepping from 10MB to 10,208KB
|
||||
maxSize->setMaximum(100 * 1024);
|
||||
maxSize->setValue(value);
|
||||
maxSize->setSingleStep(32);
|
||||
maxSize->setSuffix(tr(" KB"));
|
||||
}
|
||||
maxSize->setProperty("multi", multi);
|
||||
m_syncOptions.maxFileSize = value * multi;
|
||||
});
|
||||
|
||||
// we set these after connections are made because we want the signal processors to run
|
||||
syncDir->setField(m_syncOptions.direction);
|
||||
maxSize->setValue(m_syncOptions.maxFileSize / 1024);
|
||||
|
||||
// connect Reset action to all fields
|
||||
for (AutoLineEdit * a : ui_optionsPanel->findChildren<AutoLineEdit *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoLineEdit::updateValue);
|
||||
for (AutoComboBox * a : ui_optionsPanel->findChildren<AutoComboBox *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoComboBox::updateValue);
|
||||
for (AutoBitsetCheckBox * a : ui_optionsPanel->findChildren<AutoBitsetCheckBox *>())
|
||||
connect(this, &FileSyncDialog::optionsWereReset, a, &AutoBitsetCheckBox::updateValue);
|
||||
connect(this, &FileSyncDialog::optionsWereReset, [=]() { maxSize->setValue(m_syncOptions.maxFileSize / 1024); });
|
||||
|
||||
// React to name changes for source and destination path labels
|
||||
connect(this, &FileSyncDialog::folderNameAChanged, [=](const QString &text) {
|
||||
lblSrc->setText(text % ":");
|
||||
wdgSrc->setProperty("fileDialogTitle", text);
|
||||
});
|
||||
connect(this, &FileSyncDialog::folderNameBChanged, [=](const QString &text) {
|
||||
lblDst->setText(text % ":");
|
||||
wdgDst->setProperty("fileDialogTitle", text);
|
||||
});
|
||||
|
||||
// button actions
|
||||
connect(ui_btnStartStop, &QPushButton::clicked, this, &FileSyncDialog::toggleSync);
|
||||
connect(ui_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
connect(ui_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(ui_progress, &ProgressWidget::detailsToggled, this, &FileSyncDialog::adjustSizeDelayed);
|
||||
}
|
||||
|
||||
void FileSyncDialog::toggleSync(bool)
|
||||
{
|
||||
if (m_running) {
|
||||
setCursor(Qt::WaitCursor);
|
||||
emit stopSync();
|
||||
return;
|
||||
}
|
||||
|
||||
ui_progress->clearDetails();
|
||||
ui_progress->setInfo("");
|
||||
SyncProcess * syncProcess = new SyncProcess(m_syncOptions);
|
||||
|
||||
// move sync process to separate thread, we only use signals/slots from here on...
|
||||
QThread * syncThread = new QThread(this);
|
||||
syncProcess->moveToThread(syncThread);
|
||||
|
||||
// ...and quite a few of them!
|
||||
connect(this, &FileSyncDialog::startSync, syncProcess, &SyncProcess::run);
|
||||
connect(this, &FileSyncDialog::stopSync, syncProcess, &SyncProcess::stop);
|
||||
connect(syncProcess, &SyncProcess::started, this, &FileSyncDialog::onSyncStarted);
|
||||
connect(syncProcess, &SyncProcess::finished, this, &FileSyncDialog::onSyncFinished);
|
||||
connect(syncProcess, &SyncProcess::statusMessage, this, &FileSyncDialog::setStatusText);
|
||||
connect(syncProcess, &SyncProcess::statusUpdate, this, &FileSyncDialog::onStatusUpdate);
|
||||
connect(syncProcess, &SyncProcess::fileCountChanged, ui_progress, &ProgressWidget::setMaximum);
|
||||
connect(syncProcess, &SyncProcess::progressMessage, ui_progress, &ProgressWidget::addMessage);
|
||||
connect(syncProcess, &SyncProcess::finished, syncThread, &QThread::quit);
|
||||
connect(syncThread, &QThread::finished, syncThread, &QThread::deleteLater);
|
||||
connect(syncThread, &QThread::destroyed, syncProcess, &SyncProcess::deleteLater);
|
||||
|
||||
// go
|
||||
syncThread->start(QThread::LowPriority);
|
||||
emit startSync();
|
||||
}
|
||||
|
||||
void FileSyncDialog::onSyncStarted()
|
||||
{
|
||||
m_running = true;
|
||||
updateRunningState();
|
||||
}
|
||||
|
||||
void FileSyncDialog::onSyncFinished()
|
||||
{
|
||||
m_running = false;
|
||||
updateRunningState();
|
||||
if (parentWidget())
|
||||
QApplication::alert(parentWidget());
|
||||
}
|
||||
|
||||
void FileSyncDialog::updateRunningState()
|
||||
{
|
||||
ui_btnStartStop->setChecked(m_running);
|
||||
ui_optionsPanel->setEnabled(!m_running);
|
||||
ui_btnClose->setEnabled(!m_running);
|
||||
ui_btnStartStop->setText(m_running ? tr("Abort") : tr("Start"));
|
||||
if (m_running) {
|
||||
ui_progress->setVisible(true); // don't hide after run
|
||||
}
|
||||
else {
|
||||
setCursor(Qt::ArrowCursor); // in case we set a wait cursor upon abort request
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::onStatusUpdate(const SyncProcess::SyncStatus & stat)
|
||||
{
|
||||
static const QString reportTemplate = tr("Total: <b>%1</b>; Created: <b>%2</b>; Updated: <b>%3</b>; Skipped: <b>%4</b>; Errors: <font color=%6><b>%5</b></font>;");
|
||||
ui_progress->setInfo((stat.index < stat.count ? tr("Current: <b>%1</b> of ").arg(stat.index) : "") % reportTemplate.arg(stat.count).arg(stat.created).arg(stat.updated).arg(stat.skipped).arg(stat.errored).arg(stat.errored ? "red" : "black"));
|
||||
ui_progress->setValue(stat.index);
|
||||
}
|
||||
|
||||
void FileSyncDialog::setSyncOptions(const SyncProcess::SyncOptions & syncOptions)
|
||||
{
|
||||
m_syncOptions = syncOptions;
|
||||
emit optionsWereReset();
|
||||
}
|
||||
|
||||
void FileSyncDialog::resetOptions()
|
||||
{
|
||||
m_syncOptions.reset();
|
||||
emit optionsWereReset();
|
||||
}
|
||||
|
||||
void FileSyncDialog::toggleExtraOptions(bool show)
|
||||
{
|
||||
ui_extraOptions->setVisible(show);
|
||||
if (!ui_progress->detailsVisible())
|
||||
adjustSizeDelayed();
|
||||
m_extraOptionsVisible = show;
|
||||
emit extraOptionsToggled(show);
|
||||
}
|
||||
|
||||
void FileSyncDialog::setFolderNameA(const QString & name)
|
||||
{
|
||||
if (m_folderNameA != name) {
|
||||
m_folderNameA = name;
|
||||
emit folderNameAChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::setFolderNameB(const QString & name)
|
||||
{
|
||||
if (m_folderNameB != name) {
|
||||
m_folderNameB = name;
|
||||
emit folderNameBChanged(name);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSyncDialog::setStatusText(const QString & text, int type)
|
||||
{
|
||||
ui_statusLabel->setText(text);
|
||||
ui_statusLabel->setStyleSheet(type != QtInfoMsg && type >= QtWarningMsg ? "QLabel { color: red; }:" : "");
|
||||
}
|
||||
|
||||
bool FileSyncDialog::validate()
|
||||
{
|
||||
QString msg;
|
||||
if (m_syncOptions.folderA.isEmpty() || !QFileInfo(m_syncOptions.folderA).exists())
|
||||
msg = tr("Source folder not found.");
|
||||
else if (m_syncOptions.folderB.isEmpty() || !QFileInfo(m_syncOptions.folderB).exists())
|
||||
msg = tr("Destination folder not found.");
|
||||
else if (QFileInfo(m_syncOptions.folderA).canonicalFilePath() == QFileInfo(m_syncOptions.folderB).canonicalFilePath())
|
||||
msg = tr("Source and destination folders are the same.");
|
||||
|
||||
setStatusText(msg, QtCriticalMsg);
|
||||
ui_btnStartStop->setEnabled(msg.isEmpty());
|
||||
return msg.isEmpty();
|
||||
}
|
||||
|
||||
void FileSyncDialog::adjustSizeDelayed()
|
||||
{
|
||||
QTimer::singleShot(0, [=]() { adjustSize(); });
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef FILESYNCDIALOG_H
|
||||
#define FILESYNCDIALOG_H
|
||||
|
||||
#include "process_sync.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
|
||||
class ProgressWidget;
|
||||
|
||||
class FileSyncDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(SyncProcess::SyncOptions syncOptions READ syncOptions WRITE setSyncOptions RESET resetOptions NOTIFY optionsWereReset)
|
||||
Q_PROPERTY(bool extraOptionsVisible READ extraOptionsVisible WRITE toggleExtraOptions NOTIFY extraOptionsToggled)
|
||||
Q_PROPERTY(QString folderNameA READ folderNameA WRITE setFolderNameA NOTIFY folderNameAChanged)
|
||||
Q_PROPERTY(QString folderNameB READ folderNameB WRITE setFolderNameB NOTIFY folderNameBChanged)
|
||||
|
||||
public:
|
||||
FileSyncDialog(QWidget * parent = nullptr, const SyncProcess::SyncOptions & syncOptions = SyncProcess::SyncOptions());
|
||||
|
||||
inline SyncProcess::SyncOptions syncOptions() const { return m_syncOptions; }
|
||||
void setSyncOptions(const SyncProcess::SyncOptions & syncOptions);
|
||||
void resetOptions();
|
||||
|
||||
inline bool extraOptionsVisible() const { return m_extraOptionsVisible; }
|
||||
void toggleExtraOptions(bool show);
|
||||
|
||||
inline QString folderNameA() const { return m_folderNameA; }
|
||||
void setFolderNameA(const QString & name);
|
||||
|
||||
inline QString folderNameB() const { return m_folderNameB; }
|
||||
void setFolderNameB(const QString & name);
|
||||
|
||||
public slots:
|
||||
virtual void reject() override;
|
||||
void setStatusText(const QString & text, int type = QtWarningMsg);
|
||||
bool validate();
|
||||
|
||||
signals:
|
||||
void startSync();
|
||||
void stopSync();
|
||||
void folderNameAChanged(const QString & name);
|
||||
void folderNameBChanged(const QString & name);
|
||||
void extraOptionsToggled(bool show);
|
||||
void optionsWereReset();
|
||||
|
||||
private slots:
|
||||
void setupUi();
|
||||
void toggleSync(bool);
|
||||
void onSyncStarted();
|
||||
void onSyncFinished();
|
||||
void updateRunningState();
|
||||
void onStatusUpdate(const SyncProcess::SyncStatus & stat);
|
||||
void adjustSizeDelayed();
|
||||
|
||||
private:
|
||||
SyncProcess::SyncOptions m_syncOptions;
|
||||
QString m_folderNameA;
|
||||
QString m_folderNameB;
|
||||
bool m_running;
|
||||
bool m_extraOptionsVisible;
|
||||
|
||||
QGroupBox * ui_optionsPanel;
|
||||
QWidget * ui_extraOptions;
|
||||
ProgressWidget * ui_progress;
|
||||
QDialogButtonBox * ui_buttonBox;
|
||||
QToolButton * ui_btnStartStop;
|
||||
QToolButton * ui_btnClose;
|
||||
QLabel * ui_statusLabel;
|
||||
};
|
||||
|
||||
#endif // FILESYNCDIALOG_H
|
||||
@@ -1,12 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "downloaddialog.h"
|
||||
#include "ui_downloaddialog.h"
|
||||
#include <QTime>
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
downloadDialog::downloadDialog(QWidget *parent, QString src, QString tgt):
|
||||
QDialog(parent),
|
||||
ui(new Ui::downloadDialog),
|
||||
file(NULL)
|
||||
reply(nullptr),
|
||||
file(nullptr),
|
||||
aborted(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("fwpreferences.png"));
|
||||
@@ -21,7 +45,7 @@ downloadDialog::downloadDialog(QWidget *parent, QString src, QString tgt):
|
||||
|
||||
file = new QFile(tgt);
|
||||
if (!file->open(QIODevice::WriteOnly)) {
|
||||
QMessageBox::critical(this, "Companion",
|
||||
QMessageBox::critical(this, CPN_STR_APP_NAME,
|
||||
tr("Unable to save the file %1: %2.")
|
||||
.arg(tgt).arg(file->errorString()));
|
||||
QTimer::singleShot(0, this, SLOT(fileError()));
|
||||
@@ -40,29 +64,38 @@ downloadDialog::~downloadDialog()
|
||||
delete file;
|
||||
}
|
||||
|
||||
void downloadDialog::reject()
|
||||
{
|
||||
if (reply && reply->isRunning()) {
|
||||
aborted = true;
|
||||
reply->abort(); // this will call QNetworkReply::finished()
|
||||
return;
|
||||
}
|
||||
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void downloadDialog::httpFinished()
|
||||
{
|
||||
file->flush();
|
||||
file->close();
|
||||
file->flush();
|
||||
file->close();
|
||||
|
||||
bool ok = true;
|
||||
if (reply->error()) {
|
||||
file->remove();
|
||||
QMessageBox::information(this, tr("Companion"),
|
||||
tr("Download failed: %1.")
|
||||
.arg(reply->errorString()));
|
||||
ok = false;
|
||||
}
|
||||
const bool ok = !(reply->error() || aborted);
|
||||
if (!ok) {
|
||||
file->remove();
|
||||
if (!aborted)
|
||||
QMessageBox::information(this, CPN_STR_APP_NAME, tr("Download failed: %1.").arg(reply->errorString()));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
reply = 0;
|
||||
delete file;
|
||||
file = NULL;
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
file->deleteLater();
|
||||
file = nullptr;
|
||||
|
||||
if (ok)
|
||||
accept();
|
||||
else
|
||||
reject();
|
||||
if (ok)
|
||||
accept();
|
||||
else
|
||||
reject();
|
||||
}
|
||||
|
||||
void downloadDialog::httpReadyRead()
|
||||
@@ -91,7 +124,7 @@ void downloadDialog::closeEvent( QCloseEvent * event)
|
||||
// Delay closing 2 seconds to avoid unpleasant flashing download dialogs
|
||||
QTime closeTime= QTime::currentTime().addSecs(2);
|
||||
while( QTime::currentTime() < closeTime )
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
#ifndef DOWNLOADDIALOG_H
|
||||
#define DOWNLOADDIALOG_H
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DOWNLOADDIALOG_H_
|
||||
#define _DOWNLOADDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QNetworkAccessManager>
|
||||
@@ -19,6 +39,9 @@ public:
|
||||
explicit downloadDialog(QWidget *parent = 0, QString src = "", QString tgt = "");
|
||||
~downloadDialog();
|
||||
|
||||
public slots:
|
||||
virtual void reject() override;
|
||||
|
||||
private slots:
|
||||
void fileError();
|
||||
void httpFinished();
|
||||
@@ -34,7 +57,7 @@ private:
|
||||
QNetworkAccessManager qnam;
|
||||
QNetworkReply *reply;
|
||||
QFile *file;
|
||||
|
||||
bool aborted;
|
||||
};
|
||||
|
||||
#endif // DOWNLOADDIALOG_H
|
||||
#endif // _DOWNLOADDIALOG_H_
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
|
||||
set(firmwares_SRCS
|
||||
boards.cpp
|
||||
curvereference.cpp
|
||||
customfunctiondata.cpp
|
||||
eeprominterface.cpp
|
||||
generalsettings.cpp
|
||||
gvardata.cpp
|
||||
io_data.cpp
|
||||
logicalswitchdata.cpp
|
||||
modeldata.cpp
|
||||
moduledata.cpp
|
||||
multiprotocols.cpp
|
||||
radiodata.cpp
|
||||
radiodataconversionstate.cpp
|
||||
rawsource.cpp
|
||||
rawswitch.cpp
|
||||
sensordata.cpp
|
||||
telem_data.cpp
|
||||
er9x/er9xeeprom.cpp
|
||||
er9x/er9xinterface.cpp
|
||||
ersky9x/ersky9xeeprom.cpp
|
||||
ersky9x/ersky9xinterface.cpp
|
||||
opentx/opentxeeprom.cpp
|
||||
opentx/opentxinterface.cpp
|
||||
)
|
||||
|
||||
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
||||
|
||||
list(APPEND firmwares_HDRS
|
||||
eepromimportexport.h
|
||||
moduledata.h
|
||||
)
|
||||
|
||||
add_library(firmwares ${firmwares_SRCS} ${firmwares_HDRS})
|
||||
target_link_libraries(firmwares ${CPN_COMMON_LIB} Qt5::Core Qt5::Xml Qt5::Widgets)
|
||||
target_include_directories(firmwares
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/er9x"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ersky9x"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/opentx"
|
||||
)
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "boards.h"
|
||||
#include "macros.h"
|
||||
|
||||
// TODO remove all those constants
|
||||
// Update: These are now all only used within this class.
|
||||
// External access is only via getEEpromSize() and getFlashSize()
|
||||
|
||||
#define EESIZE_STOCK 2048
|
||||
#define EESIZE_M128 4096
|
||||
#define EESIZE_GRUVIN9X 4096
|
||||
#define EESIZE_TARANIS (32*1024)
|
||||
#define EESIZE_SKY9X (128*4096)
|
||||
#define EESIZE_9XRPRO (128*4096)
|
||||
#define EESIZE_MAX EESIZE_9XRPRO
|
||||
|
||||
// getFlashSize() (and these macros) is only used by radiointerface::getDfuArgs (perhaps can find a better way?)
|
||||
#define FSIZE_STOCK (64*1024)
|
||||
#define FSIZE_M128 (128*1024)
|
||||
#define FSIZE_GRUVIN9X (256*1024)
|
||||
#define FSIZE_TARANIS (512*1024)
|
||||
#define FSIZE_SKY9X (256*1024)
|
||||
#define FSIZE_9XRPRO (512*1024)
|
||||
#define FSIZE_HORUS (2048*1024)
|
||||
#define FSIZE_MAX FSIZE_HORUS
|
||||
|
||||
using namespace Board;
|
||||
|
||||
void Boards::setBoardType(const Type & board)
|
||||
{
|
||||
if (board >= BOARD_UNKNOWN && board < BOARD_ENUM_COUNT)
|
||||
m_boardType = board;
|
||||
else
|
||||
m_boardType = BOARD_UNKNOWN;
|
||||
}
|
||||
|
||||
uint32_t Boards::getFourCC(Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_X12S:
|
||||
return 0x3478746F;
|
||||
case BOARD_X10:
|
||||
return 0x3778746F;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
return 0x3978746F;
|
||||
case BOARD_TARANIS_X7:
|
||||
return 0x3678746F;
|
||||
case BOARD_TARANIS_X9E:
|
||||
return 0x3578746F;
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
return 0x3378746F;
|
||||
case BOARD_SKY9X:
|
||||
case BOARD_AR9X:
|
||||
case BOARD_9XRPRO:
|
||||
return 0x3278746F;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return 0x3178746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const int Boards::getEEpromSize(Board::Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return EESIZE_STOCK;
|
||||
case BOARD_M128:
|
||||
return EESIZE_M128;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return EESIZE_GRUVIN9X;
|
||||
case BOARD_SKY9X:
|
||||
return EESIZE_SKY9X;
|
||||
case BOARD_9XRPRO:
|
||||
case BOARD_AR9X:
|
||||
return EESIZE_9XRPRO;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
case BOARD_TARANIS_X7:
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
case BOARD_TARANIS_X9E:
|
||||
return EESIZE_TARANIS;
|
||||
case BOARD_UNKNOWN:
|
||||
return EESIZE_MAX;
|
||||
default:
|
||||
return 0; // unlimited
|
||||
}
|
||||
}
|
||||
|
||||
const int Boards::getFlashSize(Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return FSIZE_STOCK;
|
||||
case BOARD_M128:
|
||||
return FSIZE_M128;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return FSIZE_GRUVIN9X;
|
||||
case BOARD_SKY9X:
|
||||
return FSIZE_SKY9X;
|
||||
case BOARD_9XRPRO:
|
||||
case BOARD_AR9X:
|
||||
return FSIZE_9XRPRO;
|
||||
case BOARD_TARANIS_XLITE:
|
||||
case BOARD_TARANIS_X7:
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
case BOARD_TARANIS_X9E:
|
||||
return FSIZE_TARANIS;
|
||||
case BOARD_X12S:
|
||||
case BOARD_X10:
|
||||
return FSIZE_HORUS;
|
||||
case BOARD_UNKNOWN:
|
||||
return FSIZE_MAX;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
|
||||
|
||||
if (IS_TARANIS_XLITE(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_2POS, "SC"},
|
||||
{SWITCH_2POS, "SD"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
if (IS_TARANIS_X7(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_TOGGLE, "SH"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_HORUS_OR_TARANIS(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_3POS, "SE"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_3POS, "SG"},
|
||||
{SWITCH_TOGGLE, "SH"},
|
||||
{SWITCH_3POS, "SI"},
|
||||
{SWITCH_3POS, "SJ"},
|
||||
{SWITCH_3POS, "SK"},
|
||||
{SWITCH_3POS, "SL"},
|
||||
{SWITCH_3POS, "SM"},
|
||||
{SWITCH_3POS, "SN"},
|
||||
{SWITCH_3POS, "SO"},
|
||||
{SWITCH_3POS, "SP"},
|
||||
{SWITCH_3POS, "SQ"},
|
||||
{SWITCH_3POS, "SR"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "3POS"},
|
||||
{SWITCH_2POS, "THR"},
|
||||
{SWITCH_2POS, "RUD"},
|
||||
{SWITCH_2POS, "ELE"},
|
||||
{SWITCH_2POS, "AIL"},
|
||||
{SWITCH_2POS, "GEA"},
|
||||
{SWITCH_TOGGLE, "TRN"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
|
||||
return {SWITCH_NOT_AVAILABLE, CPN_STR_UNKNOWN_ITEM};
|
||||
}
|
||||
|
||||
const int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Sticks:
|
||||
return 4;
|
||||
|
||||
case Pots:
|
||||
if (IS_TARANIS_SMALL(board))
|
||||
return 2;
|
||||
else if (IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else
|
||||
return 3;
|
||||
|
||||
case FactoryInstalledPots:
|
||||
if (IS_TARANIS_X9(board))
|
||||
return 2;
|
||||
else
|
||||
return getCapability(board, Pots);
|
||||
|
||||
case Sliders:
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case MouseAnalogs:
|
||||
if (IS_HORUS_X12S(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case MaxAnalogs:
|
||||
return getCapability(board, Board::Sticks) + getCapability(board, Board::Pots) + getCapability(board, Board::Sliders) + getCapability(board, Board::MouseAnalogs);
|
||||
|
||||
case MultiposPots:
|
||||
return IS_HORUS_OR_TARANIS(board) ? 3 : 0;
|
||||
|
||||
case MultiposPotsPositions:
|
||||
return IS_HORUS_OR_TARANIS(board) ? 6 : 0;
|
||||
|
||||
case Switches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 18;
|
||||
else if (IS_TARANIS_X7(board))
|
||||
return 6;
|
||||
else if (IS_TARANIS_XLITE(board))
|
||||
return 4;
|
||||
else if (IS_HORUS_OR_TARANIS(board))
|
||||
return 8;
|
||||
else
|
||||
return 7;
|
||||
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
else
|
||||
return getCapability(board, Switches);
|
||||
|
||||
case SwitchPositions:
|
||||
if (IS_HORUS_OR_TARANIS(board))
|
||||
return getCapability(board, Switches) * 3;
|
||||
else
|
||||
return 9;
|
||||
|
||||
case NumTrims:
|
||||
if (IS_HORUS(board))
|
||||
return 6;
|
||||
else
|
||||
return 4;
|
||||
|
||||
case NumTrimSwitches:
|
||||
return getCapability(board, NumTrims) * 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QString Boards::getAxisName(int index)
|
||||
{
|
||||
const QString axes[] = {
|
||||
tr("Left Horizontal"),
|
||||
tr("Left Vertical"),
|
||||
tr("Right Vertical"),
|
||||
tr("Right Horizontal"),
|
||||
tr("Aux. 1"),
|
||||
tr("Aux. 2"),
|
||||
};
|
||||
if (index < (int)DIM(axes))
|
||||
return axes[index];
|
||||
else
|
||||
return tr("Unknown");
|
||||
}
|
||||
|
||||
const QString Boards::getAnalogInputName(Board::Type board, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
|
||||
if (index < getBoardCapability(board, Board::Sticks)) {
|
||||
const QString sticks[] = {
|
||||
tr("Rud"),
|
||||
tr("Ele"),
|
||||
tr("Thr"),
|
||||
tr("Ail")
|
||||
};
|
||||
return sticks[index];
|
||||
}
|
||||
|
||||
index -= getCapability(board, Board::Sticks);
|
||||
|
||||
if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) {
|
||||
const QString pots[] = {
|
||||
"P1",
|
||||
"P2",
|
||||
"P3"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_TARANIS_X9E(board)) {
|
||||
const QString pots[] = {
|
||||
"F1",
|
||||
"F2",
|
||||
"F3",
|
||||
"F4",
|
||||
"S1",
|
||||
"S2",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"S2",
|
||||
"S3",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_HORUS_X12S(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"6P",
|
||||
"S2",
|
||||
"L1",
|
||||
"L2",
|
||||
"LS",
|
||||
"RS",
|
||||
"JSx",
|
||||
"JSy"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
else if (IS_HORUS_X10(board)) {
|
||||
const QString pots[] = {
|
||||
"S1",
|
||||
"6P",
|
||||
"S2",
|
||||
"LS",
|
||||
"RS"
|
||||
};
|
||||
if (index < DIM(pots))
|
||||
return pots[index];
|
||||
}
|
||||
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
const bool Boards::isBoardCompatible(Type board1, Type board2)
|
||||
{
|
||||
return (getFourCC(board1) == getFourCC(board2));
|
||||
}
|
||||
|
||||
const QString Boards::getBoardName(Board::Type board)
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_STOCK:
|
||||
return "9X";
|
||||
case BOARD_M128:
|
||||
return "9X128";
|
||||
case BOARD_GRUVIN9X:
|
||||
return "Gruvin9x";
|
||||
case BOARD_MEGA2560:
|
||||
return "MEGA2560";
|
||||
case BOARD_TARANIS_X7:
|
||||
return "Taranis X7/X7S";
|
||||
case BOARD_TARANIS_XLITE:
|
||||
return "Taranis X-Lite";
|
||||
case BOARD_TARANIS_X9D:
|
||||
return "Taranis X9D";
|
||||
case BOARD_TARANIS_X9DP:
|
||||
return "Taranis X9D+";
|
||||
case BOARD_TARANIS_X9E:
|
||||
return "Taranis X9E";
|
||||
case BOARD_SKY9X:
|
||||
return "Sky9x";
|
||||
case BOARD_9XRPRO:
|
||||
return "9XR-PRO";
|
||||
case BOARD_AR9X:
|
||||
return "AR9X";
|
||||
case BOARD_X12S:
|
||||
return "Horus X12S";
|
||||
case BOARD_X10:
|
||||
return "Horus X10/X10S";
|
||||
default:
|
||||
return tr("Unknown");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BOARDS_H_
|
||||
#define _BOARDS_H_
|
||||
|
||||
#include <QtCore>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
// TODO create a Board class with all these functions
|
||||
|
||||
namespace Board {
|
||||
|
||||
enum Type
|
||||
{
|
||||
BOARD_UNKNOWN = -1,
|
||||
BOARD_STOCK = 0,
|
||||
BOARD_M128,
|
||||
BOARD_MEGA2560,
|
||||
BOARD_GRUVIN9X,
|
||||
BOARD_SKY9X,
|
||||
BOARD_9XRPRO,
|
||||
BOARD_AR9X,
|
||||
BOARD_TARANIS_X7,
|
||||
BOARD_TARANIS_X9D,
|
||||
BOARD_TARANIS_X9DP,
|
||||
BOARD_TARANIS_X9E,
|
||||
BOARD_X12S,
|
||||
BOARD_X10,
|
||||
BOARD_TARANIS_XLITE,
|
||||
BOARD_ENUM_COUNT
|
||||
};
|
||||
|
||||
enum PotType
|
||||
{
|
||||
POT_NONE,
|
||||
POT_WITH_DETENT,
|
||||
POT_MULTIPOS_SWITCH,
|
||||
POT_WITHOUT_DETENT
|
||||
};
|
||||
|
||||
enum SliderType
|
||||
{
|
||||
SLIDER_NONE,
|
||||
SLIDER_WITH_DETENT
|
||||
};
|
||||
|
||||
enum SwitchType
|
||||
{
|
||||
SWITCH_NOT_AVAILABLE,
|
||||
SWITCH_TOGGLE,
|
||||
SWITCH_2POS,
|
||||
SWITCH_3POS
|
||||
};
|
||||
|
||||
enum StickAxes {
|
||||
STICK_AXIS_LH = 0,
|
||||
STICK_AXIS_LV,
|
||||
STICK_AXIS_RV,
|
||||
STICK_AXIS_RH,
|
||||
STICK_AXIS_COUNT
|
||||
};
|
||||
|
||||
enum TrimAxes {
|
||||
TRIM_AXIS_LH = 0,
|
||||
TRIM_AXIS_LV,
|
||||
TRIM_AXIS_RV,
|
||||
TRIM_AXIS_RH,
|
||||
TRIM_AXIS_T5,
|
||||
TRIM_AXIS_T6,
|
||||
TRIM_AXIS_COUNT
|
||||
};
|
||||
|
||||
enum TrimSwitches
|
||||
{
|
||||
TRIM_SW_LH_DEC,
|
||||
TRIM_SW_LH_INC,
|
||||
TRIM_SW_LV_DEC,
|
||||
TRIM_SW_LV_INC,
|
||||
TRIM_SW_RV_DEC,
|
||||
TRIM_SW_RV_INC,
|
||||
TRIM_SW_RH_DEC,
|
||||
TRIM_SW_RH_INC,
|
||||
TRIM_SW_T5_DEC,
|
||||
TRIM_SW_T5_INC,
|
||||
TRIM_SW_T6_DEC,
|
||||
TRIM_SW_T6_INC,
|
||||
TRIM_SW_COUNT
|
||||
};
|
||||
|
||||
enum Capability {
|
||||
Sticks,
|
||||
Pots,
|
||||
FactoryInstalledPots,
|
||||
Sliders,
|
||||
MouseAnalogs,
|
||||
MaxAnalogs,
|
||||
MultiposPots,
|
||||
MultiposPotsPositions,
|
||||
Switches,
|
||||
SwitchPositions,
|
||||
FactoryInstalledSwitches,
|
||||
NumTrims,
|
||||
NumTrimSwitches
|
||||
};
|
||||
|
||||
struct SwitchInfo
|
||||
{
|
||||
SwitchType config;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct SwitchPosition {
|
||||
SwitchPosition(unsigned int index, unsigned int position):
|
||||
index(index),
|
||||
position(position)
|
||||
{
|
||||
}
|
||||
unsigned int index;
|
||||
unsigned int position;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class Boards
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Boards)
|
||||
|
||||
public:
|
||||
|
||||
Boards(Board::Type board)
|
||||
{
|
||||
setBoardType(board);
|
||||
}
|
||||
|
||||
void setBoardType(const Board::Type & board);
|
||||
Board::Type getBoardType() const { return m_boardType; }
|
||||
|
||||
const uint32_t getFourCC() const { return getFourCC(m_boardType); }
|
||||
const int getEEpromSize() const { return getEEpromSize(m_boardType); }
|
||||
const int getFlashSize() const { return getFlashSize(m_boardType); }
|
||||
const Board::SwitchInfo getSwitchInfo(int index) const { return getSwitchInfo(m_boardType, index); }
|
||||
const int getCapability(Board::Capability capability) const { return getCapability(m_boardType, capability); }
|
||||
const QString getAnalogInputName(int index) const { return getAnalogInputName(m_boardType, index); }
|
||||
const bool isBoardCompatible(Board::Type board2) const { return isBoardCompatible(m_boardType, board2); }
|
||||
|
||||
static uint32_t getFourCC(Board::Type board);
|
||||
static const int getEEpromSize(Board::Type board);
|
||||
static const int getFlashSize(Board::Type board);
|
||||
static const Board::SwitchInfo getSwitchInfo(Board::Type board, int index);
|
||||
static const int getCapability(Board::Type board, Board::Capability capability);
|
||||
static const QString getAxisName(int index);
|
||||
static const QString getAnalogInputName(Board::Type board, int index);
|
||||
static const bool isBoardCompatible(Board::Type board1, Board::Type board2);
|
||||
static const QString getBoardName(Board::Type board);
|
||||
|
||||
protected:
|
||||
|
||||
Board::Type m_boardType;
|
||||
};
|
||||
|
||||
// temporary aliases for transition period, use Boards class instead.
|
||||
#define getBoardCapability(b__, c__) Boards::getCapability(b__, c__)
|
||||
|
||||
#define IS_9X(board) (board==Board::BOARD_STOCK || board==Board::BOARD_M128)
|
||||
#define IS_STOCK(board) (board==Board::BOARD_STOCK)
|
||||
#define IS_M128(board) (board==Board::BOARD_M128)
|
||||
#define IS_2560(board) (board==Board::BOARD_GRUVIN9X || board==Board::BOARD_MEGA2560)
|
||||
#define IS_SKY9X(board) (board==Board::BOARD_SKY9X || board==Board::BOARD_9XRPRO || board==Board::BOARD_AR9X)
|
||||
#define IS_9XRPRO(board) (board==Board::BOARD_9XRPRO)
|
||||
#define IS_TARANIS_XLITE(board) (board==Board::BOARD_TARANIS_XLITE)
|
||||
#define IS_TARANIS_X7(board) (board==Board::BOARD_TARANIS_X7)
|
||||
#define IS_TARANIS_X9(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS_X9D(board) (board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP)
|
||||
#define IS_TARANIS_PLUS(board) (board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS_X9E(board) (board==Board::BOARD_TARANIS_X9E)
|
||||
#define IS_TARANIS(board) (IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board))
|
||||
#define IS_TARANIS_SMALL(board) (board==Board::BOARD_TARANIS_X7 || board==Board::BOARD_TARANIS_XLITE)
|
||||
#define IS_TARANIS_NOT_X9E(board) (IS_TARANIS(board) && !IS_TARANIS_X9E(board))
|
||||
#define IS_HORUS_X12S(board) (board==Board::BOARD_X12S)
|
||||
#define IS_HORUS_X10(board) (board==Board::BOARD_X10)
|
||||
#define IS_HORUS(board) (IS_HORUS_X12S(board) || IS_HORUS_X10(board))
|
||||
#define IS_HORUS_OR_TARANIS(board) (IS_HORUS(board) || IS_TARANIS(board))
|
||||
#define IS_STM32(board) (IS_TARANIS(board) || IS_HORUS(board))
|
||||
#define IS_ARM(board) (IS_STM32(board) || IS_SKY9X(board))
|
||||
#define HAS_LARGE_LCD(board) (IS_HORUS(board) || IS_TARANIS_X9(board))
|
||||
|
||||
#endif // _BOARDS_H_
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "curvereference.h"
|
||||
|
||||
#include "helpers.h" // for Helpers::getAdjustmentString()
|
||||
#include "radiodata.h" // for ModelData
|
||||
|
||||
QString CurveReference::toString(const ModelData * model, bool verbose) const
|
||||
{
|
||||
if (value == 0) {
|
||||
return "----";
|
||||
}
|
||||
|
||||
QString ret;
|
||||
unsigned idx = abs(value) - 1;
|
||||
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
ret = tr("Diff(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_EXPO:
|
||||
ret = tr("Expo(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_FUNC:
|
||||
ret = QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3);
|
||||
if (verbose)
|
||||
ret = tr("Function(%1)").arg(ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (model)
|
||||
ret = model->curves[idx].nameToString(idx);
|
||||
else
|
||||
ret = CurveData().nameToString(idx);
|
||||
if (verbose)
|
||||
ret = tr("Curve(%1)").arg(ret);
|
||||
if (value < 0)
|
||||
ret.prepend(CPN_STR_SW_INDICATOR_REV);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef CURVEREFERENCE_H
|
||||
#define CURVEREFERENCE_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class ModelData;
|
||||
|
||||
class CurveReference {
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveReference)
|
||||
|
||||
public:
|
||||
enum CurveRefType {
|
||||
CURVE_REF_DIFF,
|
||||
CURVE_REF_EXPO,
|
||||
CURVE_REF_FUNC,
|
||||
CURVE_REF_CUSTOM
|
||||
};
|
||||
|
||||
CurveReference() { clear(); }
|
||||
|
||||
CurveReference(CurveRefType type, int value):
|
||||
type(type),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
|
||||
void clear() { memset(this, 0, sizeof(CurveReference)); }
|
||||
|
||||
CurveRefType type;
|
||||
int value;
|
||||
|
||||
QString toString(const ModelData * model = NULL, bool verbose = true) const;
|
||||
};
|
||||
|
||||
#endif // CURVEREFERENCE_H
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "customfunctiondata.h"
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void CustomFunctionData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(CustomFunctionData));
|
||||
if (!getCurrentFirmware()->getCapability(SafetyChannelCustomFunction)) {
|
||||
func = FuncTrainer;
|
||||
}
|
||||
}
|
||||
|
||||
bool CustomFunctionData::isEmpty() const
|
||||
{
|
||||
return (swtch.type == SWITCH_TYPE_NONE);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::nameToString(int index, bool globalContext) const
|
||||
{
|
||||
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index+1, 0, true);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
{
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
|
||||
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return tr("Trainer");
|
||||
else if (func == FuncTrainerRUD)
|
||||
return tr("Trainer RUD");
|
||||
else if (func == FuncTrainerELE)
|
||||
return tr("Trainer ELE");
|
||||
else if (func == FuncTrainerTHR)
|
||||
return tr("Trainer THR");
|
||||
else if (func == FuncTrainerAIL)
|
||||
return tr("Trainer AIL");
|
||||
else if (func == FuncInstantTrim)
|
||||
return tr("Instant Trim");
|
||||
else if (func == FuncPlaySound)
|
||||
return tr("Play Sound");
|
||||
else if (func == FuncPlayHaptic)
|
||||
return tr("Haptic");
|
||||
else if (func == FuncReset)
|
||||
return tr("Reset");
|
||||
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3)
|
||||
return tr("Set Timer %1").arg(func-FuncSetTimer1+1);
|
||||
else if (func == FuncVario)
|
||||
return tr("Vario");
|
||||
else if (func == FuncPlayPrompt)
|
||||
return tr("Play Track");
|
||||
else if (func == FuncPlayBoth)
|
||||
return tr("Play Both");
|
||||
else if (func == FuncPlayValue)
|
||||
return tr("Play Value");
|
||||
else if (func == FuncPlayScript)
|
||||
return tr("Play Script");
|
||||
else if (func == FuncLogs)
|
||||
return tr("SD Logs");
|
||||
else if (func == FuncVolume)
|
||||
return tr("Volume");
|
||||
else if (func == FuncBacklight)
|
||||
return tr("Backlight");
|
||||
else if (func == FuncScreenshot)
|
||||
return tr("Screenshot");
|
||||
else if (func == FuncBackgroundMusic)
|
||||
return tr("Background Music");
|
||||
else if (func == FuncBackgroundMusicPause)
|
||||
return tr("Background Music Pause");
|
||||
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
|
||||
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model));
|
||||
else if (func == FuncSetFailsafeInternalModule)
|
||||
return tr("SetFailsafe Int. Module");
|
||||
else if (func == FuncSetFailsafeExternalModule)
|
||||
return tr("SetFailsafe Ext. Module");
|
||||
else if (func == FuncRangeCheckInternalModule)
|
||||
return tr("RangeCheck Int. Module");
|
||||
else if (func == FuncRangeCheckExternalModule)
|
||||
return tr("RangeCheck Ext. Module");
|
||||
else if (func == FuncBindInternalModule)
|
||||
return tr("Bind Int. Module");
|
||||
else if (func == FuncBindExternalModule)
|
||||
return tr("Bind Ext. Module");
|
||||
else {
|
||||
return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is)
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox * b, unsigned int value = 0)
|
||||
{
|
||||
int val = 0;
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
b->addItem(tr("Timer1"), val++);
|
||||
b->addItem(tr("Timer2"), val++);
|
||||
if (IS_ARM(board)) {
|
||||
b->addItem( tr("Timer3"), val++);
|
||||
}
|
||||
b->addItem(tr("Flight"), val++);
|
||||
b->addItem(tr("Telemetry"), val++);
|
||||
int reCount = firmware->getCapability(RotaryEncoders);
|
||||
if (reCount == 1) {
|
||||
b->addItem(tr("Rotary Encoder"), val++);
|
||||
}
|
||||
else if (reCount == 2) {
|
||||
b->addItem(tr("REa"), val++);
|
||||
b->addItem(tr("REb"), val++);
|
||||
}
|
||||
if ((int)value < b->count()) {
|
||||
b->setCurrentIndex(value);
|
||||
}
|
||||
if (model && IS_ARM(board)) {
|
||||
for (int i=0; i<CPN_MAX_SENSORS; ++i) {
|
||||
if (model->sensorData[i].isAvailable()) {
|
||||
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i);
|
||||
b->addItem(item.toString(model), val+i);
|
||||
if ((int)value == val+i) {
|
||||
b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populatePlaySoundParams(QStringList & qs)
|
||||
{
|
||||
qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ;
|
||||
qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ;
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateHapticParams(QStringList & qs)
|
||||
{
|
||||
qs << "0" << "1" << "2" << "3";
|
||||
}
|
||||
|
||||
QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||
{
|
||||
QStringList qs;
|
||||
if (func <= FuncInstantTrim) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
else if (func==FuncLogs) {
|
||||
return QString("%1").arg(param/10.0) + tr("s");
|
||||
}
|
||||
else if (func==FuncPlaySound) {
|
||||
CustomFunctionData::populatePlaySoundParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if (func==FuncPlayHaptic) {
|
||||
CustomFunctionData::populateHapticParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if (func==FuncReset) {
|
||||
QComboBox cb;
|
||||
CustomFunctionData::populateResetParams(model, &cb);
|
||||
int pos = cb.findData(param);
|
||||
if (pos >= 0)
|
||||
return cb.itemText(pos);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
}
|
||||
else if ((func==FuncVolume)|| (func==FuncPlayValue)) {
|
||||
RawSource item(param);
|
||||
return item.toString(model);
|
||||
}
|
||||
else if ((func==FuncPlayPrompt) || (func==FuncPlayBoth)) {
|
||||
if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
else {
|
||||
return paramarm;
|
||||
}
|
||||
}
|
||||
else if ((func>=FuncAdjustGV1) && (func<FuncCount)) {
|
||||
switch (adjustMode) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
return tr("Value ")+QString("%1").arg(param);
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
return RawSource(param).toString();
|
||||
case FUNC_ADJUST_GVAR_INCDEC:
|
||||
if (param==0) return tr("Decr:") + " -1";
|
||||
else return tr("Incr:") + " +1";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString CustomFunctionData::repeatToString() const
|
||||
{
|
||||
if (repeatParam == -1) {
|
||||
return tr("played once, not during startup");
|
||||
}
|
||||
else if (repeatParam == 0) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
unsigned int step = IS_ARM(getCurrentBoard()) ? 1 : 10;
|
||||
return tr("repeat(%1s)").arg(step*repeatParam);
|
||||
}
|
||||
}
|
||||
|
||||
QString CustomFunctionData::enabledToString() const
|
||||
{
|
||||
if ((func>=FuncOverrideCH1 && func<=FuncOverrideCH32) ||
|
||||
(func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) ||
|
||||
(func==FuncReset) ||
|
||||
(func>=FuncSetTimer1 && func<=FuncSetTimer2) ||
|
||||
(func==FuncVolume) ||
|
||||
(func <= FuncInstantTrim)) {
|
||||
if (!enabled) {
|
||||
return tr("DISABLED");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("CFN"), 8);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
||||
swtch.convert(cstate);
|
||||
if (func == FuncVolume || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
||||
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOMFUNCTIONDATA_H
|
||||
#define CUSTOMFUNCTIONDATA_H
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QComboBox>
|
||||
|
||||
class Firmware;
|
||||
class ModelData;
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum AssignFunc {
|
||||
FuncOverrideCH1 = 0,
|
||||
FuncOverrideCH32 = FuncOverrideCH1+CPN_MAX_CHNOUT-1,
|
||||
FuncTrainer,
|
||||
FuncTrainerRUD,
|
||||
FuncTrainerELE,
|
||||
FuncTrainerTHR,
|
||||
FuncTrainerAIL,
|
||||
FuncInstantTrim,
|
||||
FuncPlaySound,
|
||||
FuncPlayHaptic,
|
||||
FuncReset,
|
||||
FuncSetTimer1,
|
||||
FuncSetTimer2,
|
||||
FuncSetTimer3,
|
||||
FuncVario,
|
||||
FuncPlayPrompt,
|
||||
FuncPlayBoth,
|
||||
FuncPlayValue,
|
||||
FuncPlayScript,
|
||||
FuncLogs,
|
||||
FuncVolume,
|
||||
FuncBacklight,
|
||||
FuncScreenshot,
|
||||
FuncBackgroundMusic,
|
||||
FuncBackgroundMusicPause,
|
||||
FuncAdjustGV1,
|
||||
FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1,
|
||||
FuncSetFailsafeInternalModule,
|
||||
FuncSetFailsafeExternalModule,
|
||||
FuncRangeCheckInternalModule,
|
||||
FuncRangeCheckExternalModule,
|
||||
FuncBindInternalModule,
|
||||
FuncBindExternalModule,
|
||||
FuncCount,
|
||||
FuncReserve = -1
|
||||
};
|
||||
|
||||
enum GVarAdjustModes
|
||||
{
|
||||
FUNC_ADJUST_GVAR_CONSTANT,
|
||||
FUNC_ADJUST_GVAR_SOURCE,
|
||||
FUNC_ADJUST_GVAR_GVAR,
|
||||
FUNC_ADJUST_GVAR_INCDEC
|
||||
};
|
||||
|
||||
class CustomFunctionData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CustomFunctionData)
|
||||
|
||||
public:
|
||||
CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
|
||||
RawSwitch swtch;
|
||||
AssignFunc func;
|
||||
int param;
|
||||
char paramarm[10];
|
||||
unsigned int enabled; // TODO perhaps not any more the right name
|
||||
unsigned int adjustMode;
|
||||
int repeatParam;
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
QString nameToString(int index, bool globalContext = false) const;
|
||||
QString funcToString(const ModelData * model = NULL) const;
|
||||
QString paramToString(const ModelData * model) const;
|
||||
QString repeatToString() const;
|
||||
QString enabledToString() const;
|
||||
|
||||
static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value);
|
||||
static void populatePlaySoundParams(QStringList & qs);
|
||||
static void populateHapticParams(QStringList & qs);
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // CUSTOMFUNCTIONDATA_H
|
||||
+805
-745
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "firmwares/opentx/opentxeeprom.h"
|
||||
#include "firmwareinterface.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QMessageBox>
|
||||
#include <bitset>
|
||||
|
||||
float ValToTim(int value)
|
||||
{
|
||||
return ((value < -109 ? 129+value : (value < 7 ? (113+value)*5 : (53+value)*10))/10.0);
|
||||
}
|
||||
|
||||
int TimToVal(float value)
|
||||
{
|
||||
int temp;
|
||||
if (value>60) {
|
||||
temp=136+round((value-60));
|
||||
}
|
||||
else if (value>2) {
|
||||
temp=20+round((value-2.0)*2.0);
|
||||
}
|
||||
else {
|
||||
temp=round(value*10.0);
|
||||
}
|
||||
return (temp-129);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EEpromInterface globals
|
||||
*/
|
||||
|
||||
// TODO: No globals
|
||||
|
||||
QList<EEPROMInterface *> eepromInterfaces;
|
||||
|
||||
void unregisterEEpromInterfaces()
|
||||
{
|
||||
foreach(EEPROMInterface * intf, eepromInterfaces) {
|
||||
// qDebug() << "UnregisterEepromInterfaces(): deleting " << QString::number( reinterpret_cast<uint64_t>(intf), 16 );
|
||||
delete intf;
|
||||
}
|
||||
OpenTxEepromCleanup();
|
||||
}
|
||||
|
||||
#if 0 // TODO: remove if unused, currently commented out in mdiChild.cpp
|
||||
// TODO: No GUI here, e.g. return string list instead
|
||||
void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList errorsList;
|
||||
|
||||
errorsList << tr("Possible causes for this:");
|
||||
|
||||
if (errors.test(UNSUPPORTED_NEWER_VERSION)) { errorsList << tr("- Eeprom is from a newer version of OpenTX"); }
|
||||
if (errors.test(NOT_OPENTX)) { errorsList << tr("- Eeprom is not from OpenTX"); }
|
||||
if (errors.test(NOT_TH9X)) { errorsList << tr("- Eeprom is not from Th9X"); }
|
||||
if (errors.test(NOT_GRUVIN9X)) { errorsList << tr("- Eeprom is not from Gruvin9X"); }
|
||||
if (errors.test(NOT_ERSKY9X)) { errorsList << tr("- Eeprom is not from ErSky9X"); }
|
||||
if (errors.test(NOT_ER9X)) { errorsList << tr("- Eeprom is not from Er9X"); }
|
||||
if (errors.test(WRONG_SIZE)) { errorsList << tr("- Eeprom size is invalid"); }
|
||||
if (errors.test(WRONG_FILE_SYSTEM)) { errorsList << tr("- Eeprom file system is invalid"); }
|
||||
if (errors.test(UNKNOWN_BOARD)) { errorsList << tr("- Eeprom is from a unknown board"); }
|
||||
if (errors.test(WRONG_BOARD)) { errorsList << tr("- Eeprom is from the wrong board"); }
|
||||
if (errors.test(BACKUP_NOT_SUPPORTED)) { errorsList << tr("- Eeprom backup not supported"); }
|
||||
|
||||
if (errors.test(UNKNOWN_ERROR)) { errorsList << tr("- Something that couldn't be guessed, sorry"); }
|
||||
|
||||
if (errors.test(HAS_WARNINGS)) {
|
||||
errorsList << tr("Warning:");
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { errorsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
}
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(mainMessage);
|
||||
msgBox.setInformativeText(errorsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: No GUI here, e.g. return string list instead
|
||||
void EEPROMInterface::showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList warningsList;
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << tr("- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
if (errors.test(OLD_VERSION)) { warningsList << tr("- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); }
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setText(tr("Warnings!"));
|
||||
msgBox.setInformativeText(warningsList.join("\n"));
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Firmware
|
||||
*/
|
||||
|
||||
// static
|
||||
QVector<Firmware *> Firmware::registeredFirmwares;
|
||||
Firmware * Firmware::defaultVariant = NULL;
|
||||
Firmware * Firmware::currentVariant = NULL;
|
||||
|
||||
// static
|
||||
Firmware * Firmware::getFirmwareForId(const QString & id)
|
||||
{
|
||||
foreach(Firmware * firmware, registeredFirmwares) {
|
||||
Firmware * result = firmware->getFirmwareVariant(id);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultVariant;
|
||||
}
|
||||
|
||||
unsigned int Firmware::getVariantNumber()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
const Firmware * base = getFirmwareBase();
|
||||
QStringList options = id.mid(base->getId().length()+1).split("-", QString::SkipEmptyParts);
|
||||
foreach(QString option, options) {
|
||||
foreach(OptionsGroup group, base->opts) {
|
||||
foreach(Option opt, group) {
|
||||
if (opt.name == option) {
|
||||
result += opt.variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Firmware::addLanguage(const char * lang)
|
||||
{
|
||||
languages.push_back(lang);
|
||||
}
|
||||
|
||||
//void Firmware::addTTSLanguage(const char * lang)
|
||||
//{
|
||||
// ttslanguages.push_back(lang);
|
||||
//}
|
||||
|
||||
void Firmware::addOption(const char * option, const QString & tooltip, unsigned variant)
|
||||
{
|
||||
addOption(Option(option, tooltip, variant));
|
||||
}
|
||||
|
||||
void Firmware::addOption(const Option & option)
|
||||
{
|
||||
addOptionsGroup({option});
|
||||
}
|
||||
|
||||
void Firmware::addOptionsGroup(const OptionsGroup & options)
|
||||
{
|
||||
this->opts.append(options);
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _EEPROMINTERFACE_H_
|
||||
#define _EEPROMINTERFACE_H_
|
||||
|
||||
#include "boards.h"
|
||||
#include "macros.h"
|
||||
#include "radiodata.h"
|
||||
#include "../../radio/src/definitions.h"
|
||||
#include "simulatorinterface.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QStringList>
|
||||
#include <QList>
|
||||
#include <QDebug>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
const uint8_t modn12x3[4][4]= {
|
||||
{1, 2, 3, 4},
|
||||
{1, 3, 2, 4},
|
||||
{4, 2, 3, 1},
|
||||
{4, 3, 2, 1} };
|
||||
|
||||
enum Capability {
|
||||
Models,
|
||||
ModelName,
|
||||
FlightModes,
|
||||
FlightModesName,
|
||||
FlightModesHaveFades,
|
||||
Imperial,
|
||||
Mixes,
|
||||
Timers,
|
||||
TimersName,
|
||||
VoicesAsNumbers,
|
||||
VoicesMaxLength,
|
||||
MultiLangVoice,
|
||||
ModelImage,
|
||||
CustomFunctions,
|
||||
SafetyChannelCustomFunction,
|
||||
LogicalSwitches,
|
||||
CustomAndSwitches,
|
||||
HasNegAndSwitches,
|
||||
LogicalSwitchesExt,
|
||||
RotaryEncoders,
|
||||
Outputs,
|
||||
ChannelsName,
|
||||
ExtraInputs,
|
||||
TrimsRange,
|
||||
ExtendedTrimsRange,
|
||||
NumCurves,
|
||||
NumCurvePoints,
|
||||
OffsetWeight,
|
||||
Simulation,
|
||||
SoundMod,
|
||||
SoundPitch,
|
||||
MaxVolume,
|
||||
MaxContrast,
|
||||
MinContrast,
|
||||
Haptic,
|
||||
HasBeeper,
|
||||
ModelTrainerEnable,
|
||||
HasExpoNames,
|
||||
HasNoExpo,
|
||||
HasMixerNames,
|
||||
HasCvNames,
|
||||
HasPxxCountry,
|
||||
HasPPMStart,
|
||||
HasGeneralUnits,
|
||||
HasFAIMode,
|
||||
OptrexDisplay,
|
||||
PPMExtCtrl,
|
||||
PPMFrameLength,
|
||||
Telemetry,
|
||||
TelemetryUnits,
|
||||
TelemetryBars,
|
||||
Heli,
|
||||
Gvars,
|
||||
GvarsInCS,
|
||||
GvarsAreNamed,
|
||||
GvarsFlightModes,
|
||||
GvarsName,
|
||||
NoTelemetryProtocol,
|
||||
TelemetryCustomScreens,
|
||||
TelemetryCustomScreensFieldsPerLine,
|
||||
TelemetryMaxMultiplier,
|
||||
HasVario,
|
||||
HasVarioSink,
|
||||
HasFailsafe,
|
||||
HasSoundMixer,
|
||||
NumModules,
|
||||
HasModuleR9MFlex,
|
||||
HasModuleR9MMini,
|
||||
PPMCenter,
|
||||
PPMUnitMicroseconds,
|
||||
SYMLimits,
|
||||
HastxCurrentCalibration,
|
||||
HasVolume,
|
||||
HasBrightness,
|
||||
PerModelTimers,
|
||||
SlowScale,
|
||||
SlowRange,
|
||||
PermTimers,
|
||||
HasSDLogs,
|
||||
CSFunc,
|
||||
LcdWidth,
|
||||
LcdHeight,
|
||||
LcdDepth,
|
||||
GetThrSwitch,
|
||||
HasDisplayText,
|
||||
HasTopLcd,
|
||||
GlobalFunctions,
|
||||
VirtualInputs,
|
||||
InputsLength,
|
||||
TrainerInputs,
|
||||
RtcTime,
|
||||
SportTelemetry,
|
||||
LuaScripts,
|
||||
LuaInputsPerScript,
|
||||
LuaOutputsPerScript,
|
||||
LimitsPer1000,
|
||||
EnhancedCurves,
|
||||
HasFasOffset,
|
||||
HasMahPersistent,
|
||||
SimulatorVariant,
|
||||
MavlinkTelemetry,
|
||||
HasInputDiff,
|
||||
HasMixerExpo,
|
||||
HasBatMeterRange,
|
||||
DangerousFunctions,
|
||||
HasModelCategories
|
||||
};
|
||||
|
||||
class EEPROMInterface
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(EEPROMInterface)
|
||||
|
||||
public:
|
||||
|
||||
EEPROMInterface(Board::Type board):
|
||||
board(board)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~EEPROMInterface() {}
|
||||
|
||||
inline Board::Type getBoard() { return board; }
|
||||
|
||||
virtual unsigned long load(RadioData &radioData, const uint8_t * eeprom, int size) = 0;
|
||||
|
||||
virtual unsigned long loadBackup(RadioData & radioData, const uint8_t * eeprom, int esize, int index) = 0;
|
||||
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0) = 0;
|
||||
|
||||
virtual int getSize(const ModelData &) = 0;
|
||||
|
||||
virtual int getSize(const GeneralSettings &) = 0;
|
||||
|
||||
//static void showEepromErrors(QWidget *parent, const QString &title, const QString &mainMessage, unsigned long errorsFound);
|
||||
static void showEepromWarnings(QWidget *parent, const QString &title, unsigned long errorsFound);
|
||||
|
||||
protected:
|
||||
|
||||
Board::Type board;
|
||||
|
||||
private:
|
||||
|
||||
EEPROMInterface();
|
||||
|
||||
};
|
||||
|
||||
/* EEPROM string conversion function (used only by er9xeeprom and ersky9xeeprom) */
|
||||
inline void getEEPROMString(char *dst, const char *src, int size)
|
||||
{
|
||||
memcpy(dst, src, size);
|
||||
dst[size] = '\0';
|
||||
for (int i=size-1; i>=0; i--) {
|
||||
if (dst[i] == ' ')
|
||||
dst[i] = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// (used only by er9xeeprom and ersky9xeeprom)
|
||||
inline int applyStickMode(int stick, unsigned int mode)
|
||||
{
|
||||
if (mode == 0 || mode > 4) {
|
||||
std::cerr << "Incorrect stick mode" << mode;
|
||||
return stick;
|
||||
}
|
||||
|
||||
if (stick >= 1 && stick <= 4)
|
||||
return modn12x3[mode-1][stick-1];
|
||||
else
|
||||
return stick;
|
||||
}
|
||||
|
||||
float ValToTim(int value);
|
||||
int TimToVal(float value);
|
||||
|
||||
void registerEEpromInterfaces();
|
||||
void unregisterEEpromInterfaces();
|
||||
void registerOpenTxFirmwares();
|
||||
void unregisterOpenTxFirmwares();
|
||||
|
||||
enum EepromLoadErrors {
|
||||
ALL_OK,
|
||||
UNKNOWN_ERROR,
|
||||
UNSUPPORTED_NEWER_VERSION,
|
||||
WRONG_SIZE,
|
||||
WRONG_FILE_SYSTEM,
|
||||
NOT_OPENTX,
|
||||
NOT_TH9X,
|
||||
NOT_GRUVIN9X,
|
||||
NOT_ERSKY9X,
|
||||
NOT_ER9X,
|
||||
UNKNOWN_BOARD,
|
||||
WRONG_BOARD,
|
||||
BACKUP_NOT_SUPPORTED,
|
||||
|
||||
HAS_WARNINGS,
|
||||
OLD_VERSION,
|
||||
WARNING_WRONG_FIRMWARE,
|
||||
|
||||
NUM_ERRORS
|
||||
};
|
||||
|
||||
class Firmware
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Firmware)
|
||||
|
||||
public:
|
||||
struct Option {
|
||||
const char * name = nullptr;
|
||||
QString tooltip;
|
||||
unsigned variant = 0;
|
||||
|
||||
explicit Option(const char * name, const QString & description, unsigned variant = 0) :
|
||||
name(name), tooltip(description), variant(variant) { }
|
||||
};
|
||||
typedef QList<Option> OptionsGroup;
|
||||
typedef QList<OptionsGroup> OptionsList;
|
||||
|
||||
|
||||
explicit Firmware(const QString & id, const QString & name, Board::Type board) :
|
||||
Firmware(nullptr, id, name, board)
|
||||
{ }
|
||||
|
||||
explicit Firmware(Firmware * base, const QString & id, const QString & name, Board::Type board) :
|
||||
id(id),
|
||||
name(name),
|
||||
board(board),
|
||||
variantBase(0),
|
||||
base(base),
|
||||
eepromInterface(nullptr)
|
||||
{ }
|
||||
|
||||
virtual ~Firmware() { }
|
||||
|
||||
inline const Firmware * getFirmwareBase() const
|
||||
{
|
||||
return base ? base : this;
|
||||
}
|
||||
|
||||
virtual Firmware * getFirmwareVariant(const QString & id) { return NULL; }
|
||||
|
||||
unsigned int getVariantNumber();
|
||||
|
||||
virtual void addLanguage(const char * lang);
|
||||
|
||||
//virtual void addTTSLanguage(const char * lang);
|
||||
|
||||
virtual void addOption(const char * option, const QString & tooltip = QString(), unsigned variant = 0);
|
||||
|
||||
virtual void addOption(const Option & option);
|
||||
|
||||
virtual void addOptionsGroup(const OptionsGroup & options);
|
||||
|
||||
virtual QString getStampUrl() = 0;
|
||||
|
||||
virtual QString getReleaseNotesUrl() = 0;
|
||||
|
||||
virtual QString getFirmwareUrl() = 0;
|
||||
|
||||
Board::Type getBoard() const
|
||||
{
|
||||
return board;
|
||||
}
|
||||
|
||||
void setEEpromInterface(EEPROMInterface * eeprom)
|
||||
{
|
||||
eepromInterface = eeprom;
|
||||
}
|
||||
|
||||
EEPROMInterface * getEEpromInterface()
|
||||
{
|
||||
return eepromInterface;
|
||||
}
|
||||
|
||||
QString getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
QString getId() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
QList<const char *> languageList() const
|
||||
{
|
||||
return languages;
|
||||
}
|
||||
|
||||
OptionsList optionGroups() const
|
||||
{
|
||||
return opts;
|
||||
}
|
||||
|
||||
virtual int getCapability(Capability) = 0;
|
||||
|
||||
virtual QString getAnalogInputName(unsigned int index) = 0;
|
||||
|
||||
virtual QTime getMaxTimerStart() = 0;
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0) = 0;
|
||||
|
||||
const int getFlashSize();
|
||||
|
||||
static Firmware * getFirmwareForId(const QString & id);
|
||||
|
||||
static QVector<Firmware *> getRegisteredFirmwares()
|
||||
{
|
||||
return registeredFirmwares;
|
||||
}
|
||||
|
||||
static void addRegisteredFirmware(Firmware * fw)
|
||||
{
|
||||
registeredFirmwares.append(fw);
|
||||
}
|
||||
|
||||
static Firmware * getDefaultVariant()
|
||||
{
|
||||
return defaultVariant;
|
||||
}
|
||||
static void setDefaultVariant(Firmware * value)
|
||||
{
|
||||
defaultVariant = value;
|
||||
}
|
||||
|
||||
static Firmware * getCurrentVariant()
|
||||
{
|
||||
return currentVariant;
|
||||
}
|
||||
|
||||
static void setCurrentVariant(Firmware * value)
|
||||
{
|
||||
currentVariant = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
QString id;
|
||||
QString name;
|
||||
Board::Type board;
|
||||
unsigned int variantBase;
|
||||
Firmware * base;
|
||||
EEPROMInterface * eepromInterface;
|
||||
QList<const char *> languages;
|
||||
//QList<const char *> ttslanguages;
|
||||
OptionsList opts;
|
||||
|
||||
static QVector<Firmware *> registeredFirmwares;
|
||||
static Firmware * defaultVariant;
|
||||
static Firmware * currentVariant;
|
||||
};
|
||||
|
||||
inline Firmware * getCurrentFirmware()
|
||||
{
|
||||
return Firmware::getCurrentVariant();
|
||||
}
|
||||
|
||||
inline EEPROMInterface * getCurrentEEpromInterface()
|
||||
{
|
||||
return Firmware::getCurrentVariant()->getEEpromInterface();
|
||||
}
|
||||
|
||||
inline Board::Type getCurrentBoard()
|
||||
{
|
||||
return Firmware::getCurrentVariant()->getBoard();
|
||||
}
|
||||
|
||||
inline int divRoundClosest(const int n, const int d)
|
||||
{
|
||||
return ((n < 0) ^ (d < 0)) ? ((n - d/2)/d) : ((n + d/2)/d);
|
||||
}
|
||||
|
||||
inline int calcRESXto100(int x)
|
||||
{
|
||||
return divRoundClosest(x*100, 1024);
|
||||
}
|
||||
|
||||
extern QList<EEPROMInterface *> eepromInterfaces;
|
||||
|
||||
|
||||
#endif // _EEPROMINTERFACE_H_
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "er9xeeprom.h"
|
||||
#include "helpers.h"
|
||||
@@ -45,7 +65,7 @@ t_Er9xTrainerData::t_Er9xTrainerData()
|
||||
t_Er9xTrainerData::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++) {
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
@@ -61,26 +81,20 @@ Er9xGeneral::operator GeneralSettings ()
|
||||
{
|
||||
GeneralSettings result;
|
||||
result.version = myVers;
|
||||
for (int i=0; i<NUM_STICKSnPOTS; i++) {
|
||||
for (int i=0; i<CPN_MAX_STICKSnPOTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
result.trainer = trainer;
|
||||
result.blightinv=blightinv;
|
||||
result.stickScroll=stickScroll;
|
||||
result.crosstrim=crosstrim;
|
||||
result.hideNameOnSplash=hideNameOnSplash;
|
||||
result.enablePpmsim=enablePpmsim;
|
||||
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = disableSwitchWarning ? 0 : -1;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
@@ -103,9 +117,6 @@ Er9xGeneral::operator GeneralSettings ()
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
result.disablePotScroll=(disablePotScroll==1);
|
||||
result.disableBG=(disableBG==1);
|
||||
result.frskyinternalalarm = frskyinternalalarm;
|
||||
|
||||
result.backlightMode = 0;
|
||||
if (lightSw == 22) {
|
||||
@@ -126,7 +137,6 @@ Er9xGeneral::operator GeneralSettings ()
|
||||
result.speakerPitch = speakerPitch;
|
||||
result.hapticStrength = hapticStrength - 3;
|
||||
result.speakerMode = speakerMode;
|
||||
result.switchWarningStates =switchWarningStates;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -402,8 +412,8 @@ t_Er9xModelData::operator ModelData ()
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < C9X_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < C9X_MAX_EXPOS; dr++, pos++) {
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
@@ -426,7 +436,7 @@ t_Er9xModelData::operator ModelData ()
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < C9X_MAX_EXPOS - 1) {
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
@@ -440,7 +450,7 @@ t_Er9xModelData::operator ModelData ()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ER9X_MAX_CURVE5; i++) {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,10 +16,10 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef er9xeeprom_h
|
||||
#define er9xeeprom_h
|
||||
|
||||
#ifndef _ER9XEEPROM_H_
|
||||
#define _ER9XEEPROM_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eeprominterface.h"
|
||||
@@ -29,7 +34,7 @@
|
||||
|
||||
#define ER9X_NUM_CHNOUT 16 //number of real outputchannels CH1-CH8
|
||||
#define ER9X_NUM_CSW 12 //number of custom switches
|
||||
#define NUM_STICKSnPOTS 7 //number of sticks and pots
|
||||
#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots
|
||||
#define ER9X_MAX_GVARS 7
|
||||
|
||||
#define ER9X_MAX_MODES 4
|
||||
@@ -54,9 +59,9 @@ PACK(typedef struct t_Er9xTrainerData {
|
||||
|
||||
PACK(typedef struct t_Er9xGeneral {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[NUM_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[NUM_STICKSnPOTS];
|
||||
int16_t calibSpanPos[NUM_STICKSnPOTS];
|
||||
int16_t calibMid[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanPos[CPN_MAX_STICKSnPOTS];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
@@ -131,7 +136,7 @@ PACK(typedef struct t_Er9xLimitData {
|
||||
#define MLTPX_REP 2
|
||||
|
||||
PACK(typedef struct t_Er9xMixData {
|
||||
uint8_t destCh; // 1..C9X_NUM_CHNOUT
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
@@ -257,4 +262,4 @@ PACK(typedef struct t_Er9xModelData {
|
||||
t_Er9xModelData() { memset(this, 0, sizeof(t_Er9xModelData)); }
|
||||
}) Er9xModelData;
|
||||
|
||||
#endif
|
||||
#endif // _ER9XEEPROM_H_
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,15 +16,14 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "er9xinterface.h"
|
||||
#include "er9xeeprom.h"
|
||||
#include "simulator/er9xsimulator.h"
|
||||
#include "file.h"
|
||||
#include "appdata.h"
|
||||
#include "rlefile.h"
|
||||
// #include "appdata.h"
|
||||
// #include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
@@ -28,8 +32,8 @@
|
||||
#define FILE_MODEL(n) (1+n)
|
||||
|
||||
Er9xInterface::Er9xInterface():
|
||||
EEPROMInterface(BOARD_STOCK),
|
||||
efile(new RleFile())
|
||||
EEPROMInterface(Board::BOARD_STOCK),
|
||||
efile(new RleFile())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,20 +47,6 @@ const char * Er9xInterface::getName()
|
||||
return "Er9x";
|
||||
}
|
||||
|
||||
const int Er9xInterface::getEEpromSize()
|
||||
{
|
||||
QString avrMCU = g.mcu();
|
||||
if (avrMCU==QString("m128")) {
|
||||
return 2*EESIZE_STOCK;
|
||||
}
|
||||
return EESIZE_STOCK;
|
||||
}
|
||||
|
||||
const int Er9xInterface::getMaxModels()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
@@ -89,23 +79,26 @@ inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying er9x xml import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Er9xGeneral er9xGeneral;
|
||||
memset(&er9xGeneral,0,sizeof(er9xGeneral));
|
||||
if(!loadGeneralDataXML(&doc, &er9xGeneral)) {
|
||||
if (!loadRadioSettingsDataXML(&doc, &er9xGeneral)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
} else {
|
||||
radioData.generalSettings=er9xGeneral;
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
}
|
||||
for(int i=0; i<getMaxModels(); i++)
|
||||
{
|
||||
else {
|
||||
radioData.generalSettings=er9xGeneral;
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
}
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
memset(&er9xModel,0,sizeof(er9xModel));
|
||||
if(loadModelDataXML(&doc, &er9xModel, i)) {
|
||||
@@ -113,43 +106,46 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying er9x import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != getEEpromSize()) {
|
||||
std::cout << "wrong size\n";
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_STOCK)) {
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_STOCK)) {
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Er9xGeneral er9xGeneral;
|
||||
|
||||
if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
|
||||
switch(er9xGeneral.myVers) {
|
||||
case 3:
|
||||
std::cout << "(old gruvin9x) ";
|
||||
dbg << "(old gruvin9x) ";
|
||||
case 4:
|
||||
// case 5:
|
||||
case 6:
|
||||
@@ -159,21 +155,21 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
|
||||
case 10:
|
||||
break;
|
||||
default:
|
||||
std::cout << "not er9x\n";
|
||||
dbg << "not er9x";
|
||||
errors.set(NOT_ER9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
|
||||
}
|
||||
radioData.generalSettings = er9xGeneral;
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
if (!efile->readRlc1((uint8_t*)&er9xModel, sizeof(Er9xModelData))) {
|
||||
@@ -182,29 +178,21 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
|
||||
else {
|
||||
applyStickModeToModel(er9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long Er9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Er9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Er9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
{
|
||||
std::cout << "NO!\n";
|
||||
// TODO an error
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Er9xInterface::getSize(const ModelData &model)
|
||||
{
|
||||
return 0;
|
||||
@@ -230,11 +218,11 @@ int Er9xInterface::isAvailable(PulsesProtocol prot, int port)
|
||||
|
||||
void Er9xInterface::appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value)
|
||||
{
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(value);
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
QDomElement e = qdoc->createElement(name);
|
||||
QDomText t = qdoc->createTextNode(name);
|
||||
t.setNodeValue(value);
|
||||
e.appendChild(t);
|
||||
pe->appendChild(e);
|
||||
}
|
||||
|
||||
void Er9xInterface::appendNumberElement(QDomDocument * qdoc, QDomElement * pe,QString name, int value, bool forceZeroWrite)
|
||||
@@ -276,15 +264,15 @@ QDomElement Er9xInterface::getModelDataXML(QDomDocument * qdoc, Er9xModelData *
|
||||
return md;
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen)
|
||||
bool Er9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen)
|
||||
{
|
||||
//look for "GENERAL_DATA" tag
|
||||
// look for "GENERAL_DATA" tag
|
||||
QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement();
|
||||
|
||||
if(gde.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
//load cdata into tgen
|
||||
// load cdata into tgen
|
||||
QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
@@ -296,17 +284,17 @@ bool Er9xInterface::loadGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen)
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
//check version?
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Er9xInterface::loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum)
|
||||
{
|
||||
//look for MODEL_DATA with modelNum attribute.
|
||||
//if modelNum = -1 then just pick the first one
|
||||
// look for MODEL_DATA with modelNum attribute.
|
||||
// if modelNum = -1 then just pick the first one
|
||||
QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA");
|
||||
|
||||
//cycle through nodes to find correct model number
|
||||
// cycle through nodes to find correct model number
|
||||
QDomNode k = ndl.at(0);
|
||||
if(modelNum>=0) {
|
||||
while(!k.isNull()) {
|
||||
@@ -317,11 +305,11 @@ bool Er9xInterface::loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod,
|
||||
}
|
||||
}
|
||||
|
||||
if(k.isNull()) // couldn't find
|
||||
if (k.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
|
||||
//load cdata into tgen
|
||||
// load cdata into tgen
|
||||
QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
@@ -333,6 +321,16 @@ bool Er9xInterface::loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod,
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
//check version?
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
int Er9xInterface::getCapability(Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Models:
|
||||
return 16;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,13 +16,15 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef er9x_interface_h
|
||||
#define er9x_interface_h
|
||||
|
||||
#ifndef _ER9XINTERFACE_H_
|
||||
#define _ER9XINTERFACE_H_
|
||||
|
||||
#include <QtXml>
|
||||
#include "eeprominterface.h"
|
||||
#include "er9xeeprom.h"
|
||||
|
||||
class RleFile;
|
||||
|
||||
class Er9xInterface : public EEPROMInterface
|
||||
@@ -30,27 +37,28 @@ class Er9xInterface : public EEPROMInterface
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t * eeprom, RadioData & radioData, uint32_t variant=0, uint8_t version=0);
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getSize(const ModelData &);
|
||||
|
||||
virtual int getSize(const GeneralSettings &settings);
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0);
|
||||
|
||||
virtual int getCapability(Capability capability);
|
||||
|
||||
protected:
|
||||
|
||||
RleFile *efile;
|
||||
RleFile * efile;
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
@@ -63,10 +71,10 @@ class Er9xInterface : public EEPROMInterface
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
bool loadGeneralDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); // get data from XML
|
||||
bool loadRadioSettingsDataXML(QDomDocument * qdoc, Er9xGeneral * tgen); // get data from XML
|
||||
|
||||
bool loadModelDataXML(QDomDocument * qdoc, Er9xModelData * tmod, int modelNum = -1); // get data from XML
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // _ER9XINTERFACE_H_
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
set(ER9X_CHECKOUT_DIRECTORY ${PROJECT_BINARY_DIR}/firmwares/er9x)
|
||||
add_custom_command(
|
||||
OUTPUT ${ER9X_CHECKOUT_DIRECTORY}/er9xsimulator.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${ER9X_CHECKOUT_DIRECTORY}
|
||||
COMMAND cd ${ER9X_CHECKOUT_DIRECTORY} && svn checkout http://er9x.googlecode.com/svn/trunk/src@790 .
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/er9x/er9xsimulator.cpp ${ER9X_CHECKOUT_DIRECTORY}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/er9x/er9xsimulator.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_library(er9x-simulator er9xsimulator.cpp)
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firmwares/er9x/er9xsimulator.h"
|
||||
#include "firmwares/er9x/er9xinterface.h"
|
||||
|
||||
#define SIMU
|
||||
#define SIMU_EXCEPTIONS
|
||||
#define TELEMETRY_FRSKY
|
||||
#define PHASES
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#define NUM_POTS 3
|
||||
#define NUM_SLIDERS 0
|
||||
#define SWSRC_SW1 DSW_SW1
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace Er9x {
|
||||
|
||||
#include "simpgmspace.h"
|
||||
#include "er9x.cpp"
|
||||
#include "stamp.cpp"
|
||||
#include "menus.cpp"
|
||||
#include "pers.cpp"
|
||||
#include "file.cpp"
|
||||
#include "lcd.cpp"
|
||||
#include "drivers.cpp"
|
||||
#include "simpgmspace.cpp"
|
||||
#include "templates.cpp"
|
||||
#include "frsky.cpp"
|
||||
#include "audio.cpp"
|
||||
|
||||
uint8_t pxxFlag = 0;
|
||||
int16_t g_anas[7];
|
||||
|
||||
#define isBacklightEnabled() (PORTB & (1<<OUT_B_LIGHT))
|
||||
|
||||
uint16_t anaIn(uint8_t chan)
|
||||
{
|
||||
if (chan == 7)
|
||||
return 1500;
|
||||
else
|
||||
return g_anas[chan];
|
||||
}
|
||||
|
||||
bool hasExtendedTrims()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setTrim(uint8_t idx, int8_t value)
|
||||
{
|
||||
g_model.trim[idx] = value;
|
||||
}
|
||||
|
||||
void getTrims(int16_t values[4])
|
||||
{
|
||||
for (int i=0; i<4; i++)
|
||||
values[i] = g_model.trim[i];
|
||||
}
|
||||
|
||||
#define TRIMS_GPIO_REG_LHL pind
|
||||
#define TRIMS_GPIO_REG_LVD pind
|
||||
#define TRIMS_GPIO_REG_RVU pind
|
||||
#define TRIMS_GPIO_REG_RHL pind
|
||||
#define TRIMS_GPIO_REG_LHR pind
|
||||
#define TRIMS_GPIO_REG_LVU pind
|
||||
#define TRIMS_GPIO_REG_RVD pind
|
||||
#define TRIMS_GPIO_REG_RHR pind
|
||||
#define PIN_TRIM_LH_L (1<<INP_D_TRM_LH_DWN)
|
||||
#define PIN_TRIM_LV_DN (1<<INP_D_TRM_LV_DWN)
|
||||
#define PIN_TRIM_RV_UP (1<<INP_D_TRM_RV_UP)
|
||||
#define PIN_TRIM_RH_L (1<<INP_D_TRM_RH_DWN)
|
||||
#define PIN_TRIM_LH_R (1<<INP_D_TRM_LH_UP)
|
||||
#define PIN_TRIM_LV_UP (1<<INP_D_TRM_LV_UP)
|
||||
#define PIN_TRIM_RV_DN (1<<INP_D_TRM_RV_DWN)
|
||||
#define PIN_TRIM_RH_R (1<<INP_D_TRM_RH_UP)
|
||||
|
||||
#define TRIM_CASE(key, pin, mask) \
|
||||
case key: \
|
||||
if (state) pin |= mask; else pin &= ~mask;\
|
||||
break;
|
||||
|
||||
void simuSetTrim(uint8_t trim, bool state)
|
||||
{
|
||||
switch (trim) {
|
||||
TRIM_CASE(0, TRIMS_GPIO_REG_LHL, PIN_TRIM_LH_L)
|
||||
TRIM_CASE(1, TRIMS_GPIO_REG_LHR, PIN_TRIM_LH_R)
|
||||
TRIM_CASE(2, TRIMS_GPIO_REG_LVD, PIN_TRIM_LV_DN)
|
||||
TRIM_CASE(3, TRIMS_GPIO_REG_LVU, PIN_TRIM_LV_UP)
|
||||
TRIM_CASE(4, TRIMS_GPIO_REG_RVD, PIN_TRIM_RV_DN)
|
||||
TRIM_CASE(5, TRIMS_GPIO_REG_RVU, PIN_TRIM_RV_UP)
|
||||
TRIM_CASE(6, TRIMS_GPIO_REG_RHL, PIN_TRIM_RH_L)
|
||||
TRIM_CASE(7, TRIMS_GPIO_REG_RHR, PIN_TRIM_RH_R)
|
||||
}
|
||||
}
|
||||
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
case swtch: \
|
||||
if (state) pin &= ~(mask); else pin |= (mask); \
|
||||
break;
|
||||
#define SWITCH_3_CASE(swtch, pin1, pin2, mask1, mask2) \
|
||||
case swtch: \
|
||||
if (state >= 0) pin1 &= ~(mask1); else pin1 |= (mask1); \
|
||||
if (state <= 0) pin2 &= ~(mask2); else pin2 |= (mask2); \
|
||||
break;
|
||||
|
||||
void simuSetSwitch(uint8_t swtch, int8_t state)
|
||||
{
|
||||
switch (swtch) {
|
||||
SWITCH_CASE(0, pinc, 1<<INP_C_ThrCt)
|
||||
SWITCH_CASE(4, pinc, 1<<INP_C_AileDR)
|
||||
SWITCH_3_CASE(3, ping, pine, (1<<INP_G_ID1), (1<<INP_E_ID2))
|
||||
SWITCH_CASE(1, ping, 1<<INP_G_RuddDR)
|
||||
SWITCH_CASE(2, pine, 1<<INP_E_ElevDR)
|
||||
SWITCH_CASE(5, pine, 1<<INP_E_Gear)
|
||||
SWITCH_CASE(6, pine, 1<<INP_E_Trainer)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define KEY_CASE(key, pin, mask) \
|
||||
case key: \
|
||||
if (state) pin |= mask; else pin &= ~mask;\
|
||||
break;
|
||||
|
||||
void simuSetKey(uint8_t key, bool state)
|
||||
{
|
||||
switch (key) {
|
||||
KEY_CASE(KEY_MENU, pinb, (1<<INP_B_KEY_MEN))
|
||||
KEY_CASE(KEY_EXIT, pinb, (1<<INP_B_KEY_EXT))
|
||||
KEY_CASE(KEY_RIGHT, pinb, (1<<INP_B_KEY_RGT))
|
||||
KEY_CASE(KEY_LEFT, pinb, (1<<INP_B_KEY_LFT))
|
||||
KEY_CASE(KEY_UP, pinb, (1<<INP_B_KEY_UP))
|
||||
KEY_CASE(KEY_DOWN, pinb, (1<<INP_B_KEY_DWN))
|
||||
}
|
||||
}
|
||||
|
||||
#define isBacklightEnabled() (PORTB & (1<<OUT_B_LIGHT))
|
||||
|
||||
}
|
||||
|
||||
using namespace Er9x;
|
||||
|
||||
Er9xSimulator::Er9xSimulator(Er9xInterface * er9xInterface):
|
||||
er9xInterface(er9xInterface)
|
||||
{
|
||||
}
|
||||
|
||||
bool Er9xSimulator::timer10ms()
|
||||
{
|
||||
AUDIO_DRIVER(); // the tone generator
|
||||
AUDIO_HEARTBEAT(); // the queue processing
|
||||
#define TIMER10MS_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
uint8_t * Er9xSimulator::getLcd()
|
||||
{
|
||||
return (::uint8_t *)simuLcdBuf;
|
||||
}
|
||||
|
||||
bool Er9xSimulator::lcdChanged(bool & lightEnable)
|
||||
{
|
||||
#define LCDCHANGED_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Er9xSimulator::start(RadioData &radioData, bool tests)
|
||||
{
|
||||
er9xInterface->save(&eeprom[0], radioData);
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void Er9xSimulator::stop()
|
||||
{
|
||||
StopMainThread();
|
||||
}
|
||||
|
||||
void Er9xSimulator::getValues(TxOutputs &outputs)
|
||||
{
|
||||
#define GETVALUES_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
outputs.beep = audio.busy();
|
||||
}
|
||||
|
||||
void Er9xSimulator::setValues(TxInputs &inputs)
|
||||
{
|
||||
#define SETVALUES_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Er9xSimulator::setTrim(unsigned int idx, int value)
|
||||
{
|
||||
Er9x::setTrim(idx, value);
|
||||
}
|
||||
|
||||
void Er9xSimulator::getTrims(Trims & trims)
|
||||
{
|
||||
trims.extended = false;
|
||||
Er9x::getTrims(trims.values);
|
||||
}
|
||||
|
||||
const char * Er9xSimulator::getError()
|
||||
{
|
||||
#define GETERROR_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef er9x_simulator_h
|
||||
#define er9x_simulator_h
|
||||
|
||||
#include "simulatorinterface.h"
|
||||
|
||||
class RadioData;
|
||||
class Er9xInterface;
|
||||
|
||||
class Er9xSimulator : public SimulatorInterface {
|
||||
|
||||
public:
|
||||
|
||||
Er9xSimulator(Er9xInterface *);
|
||||
|
||||
virtual void start(RadioData & radioData, bool tests);
|
||||
|
||||
virtual void stop();
|
||||
|
||||
virtual bool timer10ms();
|
||||
|
||||
virtual uint8_t * getLcd();
|
||||
|
||||
virtual bool lcdChanged(bool & lightEnable);
|
||||
|
||||
virtual void setValues(TxInputs &inputs);
|
||||
|
||||
virtual void getValues(TxOutputs &outputs);
|
||||
|
||||
virtual void setTrim(unsigned int idx, int value);
|
||||
|
||||
virtual void getTrims(Trims & trims);
|
||||
|
||||
virtual unsigned int getPhase() { return 0; }
|
||||
|
||||
virtual const char * getPhaseName(unsigned int phase) { return 0; }
|
||||
|
||||
virtual const char * getError();
|
||||
|
||||
virtual void sendTelemetry(uint8_t * data, unsigned int len) {};
|
||||
|
||||
virtual uint8_t getSensorInstance(uint16_t id, uint8_t defaultValue = 0) { return 0; };
|
||||
|
||||
virtual uint16_t getSensorRatio(uint16_t id) { return 0; };
|
||||
|
||||
virtual void setTrainerInput(unsigned int inputNumber, int16_t value) {};
|
||||
|
||||
virtual void setLuaStateReloadPermanentScripts() {};
|
||||
|
||||
protected:
|
||||
|
||||
Er9xInterface * er9xInterface;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "helpers.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
@@ -55,7 +75,7 @@ t_Ersky9xTrainerData::t_Ersky9xTrainerData()
|
||||
t_Ersky9xTrainerData::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++) {
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
@@ -73,13 +93,13 @@ Ersky9xGeneral::operator GeneralSettings ()
|
||||
|
||||
result.version = myVers;
|
||||
|
||||
for (int i=0; i<NUM_STICKSnPOTS; i++) {
|
||||
for (int i=0; i<CPN_MAX_STICKSnPOTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.currModelIndex = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
@@ -100,7 +120,6 @@ Ersky9xGeneral::operator GeneralSettings ()
|
||||
result.trainer = trainer;
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = disableSwitchWarning ? 0 : -1;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
@@ -123,8 +142,6 @@ Ersky9xGeneral::operator GeneralSettings ()
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
result.disablePotScroll=(disablePotScroll==1);
|
||||
result.disableBG=(disableBG==1);
|
||||
result.templateSetup = templateSetup;
|
||||
result.PPM_Multiplier = PPM_Multiplier;
|
||||
getEEPROMString(result.ownerName, ownerName, sizeof(ownerName));
|
||||
@@ -132,7 +149,6 @@ Ersky9xGeneral::operator GeneralSettings ()
|
||||
result.speakerPitch = speakerPitch;
|
||||
result.hapticStrength = hapticStrength - 3;
|
||||
result.speakerMode = speakerMode;
|
||||
result.switchWarningStates = switchWarningStates;
|
||||
result.speakerVolume = volume;
|
||||
result.backlightBright = bright ;
|
||||
result.txCurrentCalibration = current_calib;
|
||||
@@ -530,8 +546,8 @@ t_Ersky9xModelData_v10::operator ModelData ()
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < C9X_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < C9X_MAX_EXPOS; dr++, pos++) {
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
@@ -554,7 +570,7 @@ t_Ersky9xModelData_v10::operator ModelData ()
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < C9X_MAX_EXPOS - 1) {
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
@@ -568,7 +584,7 @@ t_Ersky9xModelData_v10::operator ModelData ()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE5; i++) {
|
||||
@@ -645,8 +661,8 @@ t_Ersky9xModelData_v11::operator ModelData ()
|
||||
|
||||
// expoData
|
||||
int e = 0;
|
||||
for (int ch = 0; ch < 4 && e < C9X_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < C9X_MAX_EXPOS; dr++, pos++) {
|
||||
for (int ch = 0; ch < 4 && e < CPN_MAX_EXPOS; ch++) {
|
||||
for (int dr = 0, pos = 0; dr < 3 && e < CPN_MAX_EXPOS; dr++, pos++) {
|
||||
if ((dr == 0 && !expoData[ch].drSw1) || (dr == 1 && !expoData[ch].drSw2))
|
||||
dr = 2;
|
||||
if (dr == 2 && !expoData[ch].expo[0][0][0] && !expoData[ch].expo[0][0][1] && !expoData[ch].expo[0][1][0] && !expoData[ch].expo[0][1][1])
|
||||
@@ -669,7 +685,7 @@ t_Ersky9xModelData_v11::operator ModelData ()
|
||||
}
|
||||
else {
|
||||
c9x.expoData[e].mode = 2;
|
||||
if (e < C9X_MAX_EXPOS - 1) {
|
||||
if (e < CPN_MAX_EXPOS - 1) {
|
||||
c9x.expoData[e + 1].swtch = c9x.expoData[e].swtch;
|
||||
c9x.expoData[++e].chn = ch;
|
||||
c9x.expoData[e].mode = 1;
|
||||
@@ -683,7 +699,7 @@ t_Ersky9xModelData_v11::operator ModelData ()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
c9x.flightModeData[0].trim[i] = trim[i];
|
||||
|
||||
for (int i=0; i<ERSKY9X_MAX_CURVE5; i++) {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,10 +16,10 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef ersky9xeeprom_h
|
||||
#define ersky9xeeprom_h
|
||||
|
||||
#ifndef _ERSKY9XEEPROM_H_
|
||||
#define _ERSKY9XEEPROM_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eeprominterface.h"
|
||||
@@ -40,7 +45,7 @@ extern RawSwitch getEr9xTimerMode(int mode);
|
||||
#define ERSKY9X_NUM_VOICE 8
|
||||
#define ERSKY9X_MAX_GVARS 7
|
||||
|
||||
#define NUM_STICKSnPOTS 7 //number of sticks and pots
|
||||
#define CPN_MAX_STICKSnPOTS 7 //number of sticks and pots
|
||||
|
||||
PACK(typedef struct t_Ersky9xTrainerMix {
|
||||
uint8_t srcChn:3; //0-7 = ch1-8
|
||||
@@ -62,9 +67,9 @@ PACK(typedef struct t_Ersky9xTrainerData {
|
||||
|
||||
PACK(typedef struct t_Ersky9xGeneral {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[NUM_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[NUM_STICKSnPOTS];
|
||||
int16_t calibSpanPos[NUM_STICKSnPOTS];
|
||||
int16_t calibMid[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanNeg[CPN_MAX_STICKSnPOTS];
|
||||
int16_t calibSpanPos[CPN_MAX_STICKSnPOTS];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
@@ -143,7 +148,7 @@ PACK(typedef struct t_Ersky9xLimitData {
|
||||
#define MLTPX_REP 2
|
||||
|
||||
PACK(typedef struct t_Ersky9xMixData_v10 {
|
||||
uint8_t destCh; // 1..C9X_NUM_CHNOUT
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
@@ -165,7 +170,7 @@ PACK(typedef struct t_Ersky9xMixData_v10 {
|
||||
}) Ersky9xMixData_v10;
|
||||
|
||||
PACK(typedef struct t_Ersky9xMixData_v11 {
|
||||
uint8_t destCh; // 1..C9X_NUM_CHNOUT
|
||||
uint8_t destCh; // 1..CPN_MAX_CHNOUT
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
@@ -428,4 +433,4 @@ PACK(typedef struct t_Ersky9xModelData_v11 {
|
||||
t_Ersky9xModelData_v11() { memset(this, 0, sizeof(t_Ersky9xModelData_v11)); }
|
||||
}) Ersky9xModelData_v11;
|
||||
|
||||
#endif
|
||||
#endif // _ERSKY9XEEPROM_H_
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,14 +16,13 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "ersky9xinterface.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
#include "simulator/ersky9xsimulator.h"
|
||||
#include "file.h"
|
||||
#include "rlefile.h"
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
@@ -30,7 +34,7 @@
|
||||
#define FILE_TMP (1+16)
|
||||
|
||||
Ersky9xInterface::Ersky9xInterface():
|
||||
EEPROMInterface(BOARD_SKY9X),
|
||||
EEPROMInterface(Board::BOARD_SKY9X),
|
||||
efile(new RleFile())
|
||||
{
|
||||
}
|
||||
@@ -45,16 +49,6 @@ const char * Ersky9xInterface::getName()
|
||||
return "Ersky9x";
|
||||
}
|
||||
|
||||
const int Ersky9xInterface::getEEpromSize()
|
||||
{
|
||||
return EESIZE_SKY9X;
|
||||
}
|
||||
|
||||
const int Ersky9xInterface::getMaxModels()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
inline void applyStickModeToModel(Ersky9xModelData_v10 & model, unsigned int mode)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
@@ -119,71 +113,77 @@ inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mod
|
||||
model.swashCollectiveSource = applyStickMode(model.swashCollectiveSource, mode);
|
||||
}
|
||||
|
||||
#if 0
|
||||
unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying ersky9x xml import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
memset(&ersky9xGeneral,0,sizeof(ersky9xGeneral));
|
||||
if(!loadGeneralDataXML(&doc, &ersky9xGeneral)) {
|
||||
if(!loadRadioSettingsDataXML(&doc, &ersky9xGeneral)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=ersky9xGeneral;
|
||||
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
}
|
||||
for(int i=0; i<getMaxModels(); i++) {
|
||||
for(int i=0; i<getCapability(Models); i++) {
|
||||
if (ersky9xGeneral.myVers == 10) {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v10>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v11>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying ersky9x import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != EESIZE_SKY9X) {
|
||||
std::cout << "wrong size\n";
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_SKY9X)) {
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_SKY9X)) {
|
||||
std::cout << "wrong file system\n";
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_SKY9X)) {
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
|
||||
if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
|
||||
switch(ersky9xGeneral.myVers) {
|
||||
case 10:
|
||||
@@ -191,26 +191,26 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
|
||||
case 11:
|
||||
break;
|
||||
default:
|
||||
std::cout << "not ersky9x\n";
|
||||
dbg << "not ersky9x";
|
||||
errors.set(NOT_ERSKY9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
radioData.generalSettings = ersky9xGeneral;
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
uint8_t buffer[4096];
|
||||
uint size;
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
|
||||
|
||||
// if (!efile->readRlc2((uint8_t*)&ersky9xModel, sizeof(Ersky9xModelData))) {
|
||||
size=efile->readRlc2(buffer, 4096);
|
||||
size = efile->readRlc2(buffer, 4096);
|
||||
if (!size) {
|
||||
radioData.models[i].clear();
|
||||
}
|
||||
@@ -226,29 +226,21 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
|
||||
applyStickModeToModel(ersky9xModel, radioData.generalSettings.stickMode+1);
|
||||
radioData.models[i] = ersky9xModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long Ersky9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
unsigned long Ersky9xInterface::loadBackup(RadioData &radioData, const uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Ersky9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
{
|
||||
std::cout << "NO!\n";
|
||||
// TODO an error
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Ersky9xInterface::getSize(const ModelData & model)
|
||||
{
|
||||
return 0;
|
||||
@@ -320,15 +312,15 @@ QDomElement Ersky9xInterface::getModelDataXML(QDomDocument * qdoc, Ersky9xModelD
|
||||
return md;
|
||||
}
|
||||
|
||||
bool Ersky9xInterface::loadGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen)
|
||||
bool Ersky9xInterface::loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen)
|
||||
{
|
||||
//look for "GENERAL_DATA" tag
|
||||
// look for "GENERAL_DATA" tag
|
||||
QDomElement gde = qdoc->elementsByTagName("GENERAL_DATA").at(0).toElement();
|
||||
|
||||
if(gde.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
//load cdata into tgen
|
||||
// load cdata into tgen
|
||||
QDomNode n = gde.elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
@@ -340,7 +332,7 @@ bool Ersky9xInterface::loadGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral *
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
//check version?
|
||||
// check version?
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -350,11 +342,11 @@ bool Ersky9xInterface::loadModelDataXML(QDomDocument * qdoc, ModelData *model, i
|
||||
T ersky9xModel;
|
||||
memset(&ersky9xModel, 0, sizeof(ersky9xModel));
|
||||
|
||||
//look for MODEL_DATA with modelNum attribute.
|
||||
// look for MODEL_DATA with modelNum attribute.
|
||||
//if modelNum = -1 then just pick the first one
|
||||
QDomNodeList ndl = qdoc->elementsByTagName("MODEL_DATA");
|
||||
|
||||
//cycle through nodes to find correct model number
|
||||
// cycle through nodes to find correct model number
|
||||
QDomNode k = ndl.at(0);
|
||||
if (modelNum>=0) {
|
||||
while(!k.isNull()) {
|
||||
@@ -368,7 +360,7 @@ bool Ersky9xInterface::loadModelDataXML(QDomDocument * qdoc, ModelData *model, i
|
||||
if (k.isNull()) // couldn't find
|
||||
return false;
|
||||
|
||||
//load cdata into tgen
|
||||
// load cdata into tgen
|
||||
QDomNode n = k.toElement().elementsByTagName("Data").at(0).firstChild();// get all children in Data
|
||||
while (!n.isNull()) {
|
||||
if (n.isCDATASection()) {
|
||||
@@ -385,3 +377,13 @@ bool Ersky9xInterface::loadModelDataXML(QDomDocument * qdoc, ModelData *model, i
|
||||
*model = ersky9xModel;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Ersky9xInterface::getCapability(Capability capability)
|
||||
{
|
||||
switch (capability) {
|
||||
case Models:
|
||||
return 20;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -11,13 +16,15 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef ersky9x_interface_h
|
||||
#define ersky9x_interface_h
|
||||
|
||||
#ifndef _ERSKY9XINTERFACE_H_
|
||||
#define _ERSKY9XINTERFACE_H_
|
||||
|
||||
#include <QtXml>
|
||||
#include "eeprominterface.h"
|
||||
#include "ersky9xeeprom.h"
|
||||
|
||||
class RleFile;
|
||||
|
||||
class Ersky9xInterface : public EEPROMInterface
|
||||
@@ -30,27 +37,27 @@ class Ersky9xInterface : public EEPROMInterface
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
|
||||
virtual unsigned long load(RadioData &, const uint8_t * eeprom, int size);
|
||||
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t * eeprom, RadioData & radioData, uint32_t variant=0, uint8_t version=0);
|
||||
virtual unsigned long loadBackup(RadioData &, const uint8_t * eeprom, int esize, int index);
|
||||
|
||||
virtual int save(uint8_t * eeprom, const RadioData & radioData, uint8_t version=0, uint32_t variant=0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int getSize(const ModelData &);
|
||||
|
||||
virtual int getSize(const GeneralSettings & settings);
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0);
|
||||
|
||||
virtual int getCapability(Capability capability);
|
||||
|
||||
protected:
|
||||
|
||||
RleFile *efile;
|
||||
RleFile * efile;
|
||||
|
||||
private:
|
||||
void appendTextElement(QDomDocument * qdoc, QDomElement * pe, QString name, QString value);
|
||||
@@ -63,11 +70,11 @@ class Ersky9xInterface : public EEPROMInterface
|
||||
|
||||
QDomElement getModelDataXML(QDomDocument * qdoc, Ersky9xModelData_v11 * tmod, int modelNum, int mdver); //parse out data to XML format
|
||||
|
||||
bool loadGeneralDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); // get data from XML
|
||||
bool loadRadioSettingsDataXML(QDomDocument * qdoc, Ersky9xGeneral * tgen); // get data from XML
|
||||
|
||||
template <class T>
|
||||
bool loadModelDataXML(QDomDocument * qdoc, ModelData * model, int modelNum, int stickMode); // get data from XML
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // _ERSKY9XINTERFACE_H_
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
set(ERSKY9X_CHECKOUT_DIRECTORY ${PROJECT_BINARY_DIR}/firmwares/ersky9x)
|
||||
add_custom_command(
|
||||
OUTPUT ${ERSKY9X_CHECKOUT_DIRECTORY}/ersky9xsimulator.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${ERSKY9X_CHECKOUT_DIRECTORY}
|
||||
COMMAND cd ${ERSKY9X_CHECKOUT_DIRECTORY} && svn checkout http://ersky9x.googlecode.com/svn/trunk/src@170 .
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/ersky9x/ersky9xsimulator.cpp ${ERSKY9X_CHECKOUT_DIRECTORY}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/firmwares/ersky9x/ersky9xsimulator.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
add_library(ersky9x-simulator ersky9xsimulator.cpp)
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "firmwares/ersky9x/ersky9xsimulator.h"
|
||||
#include "firmwares/ersky9x/ersky9xinterface.h"
|
||||
|
||||
#define SIMU
|
||||
#define SIMU_EXCEPTIONS
|
||||
#define PCBSKY9X
|
||||
#define PCBSKY
|
||||
#define STAMP
|
||||
#define TELEMETRY_FRSKY
|
||||
#define FRSKY_HUB
|
||||
#define WS_HOW_HIGH
|
||||
#define TEMPLATES
|
||||
#define HELI
|
||||
#define HAPTIC
|
||||
#define AUDIO
|
||||
#define REVB
|
||||
|
||||
#define NUM_POTS 3
|
||||
#define NUM_SLIDERS 0
|
||||
#define SWSRC_SW1 DSW_SW1
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace Ersky9x {
|
||||
|
||||
#include "../ersky9x/timers.h"
|
||||
#include "../ersky9x/ersky9x.cpp"
|
||||
#include "../ersky9x/stamp.cpp"
|
||||
#include "../ersky9x/menus.cpp"
|
||||
#include "../ersky9x/pers.cpp"
|
||||
#include "../ersky9x/file.cpp"
|
||||
#include "../ersky9x/lcd.cpp"
|
||||
#include "../ersky9x/drivers.cpp"
|
||||
#include "../ersky9x/logicio.cpp"
|
||||
#include "../ersky9x/timers.cpp"
|
||||
#include "../ersky9x/simpgmspace.cpp"
|
||||
#include "../ersky9x/templates.cpp"
|
||||
#include "../ersky9x/frsky.cpp"
|
||||
#include "../ersky9x/audio.cpp"
|
||||
#include "../ersky9x/sound.cpp"
|
||||
#include "../ersky9x/diskio.cpp"
|
||||
|
||||
#define isBacklightEnabled() (PWM->PWM_CH_NUM[0].PWM_CDTY != 100)
|
||||
|
||||
//uint8_t pxxFlag = 0;
|
||||
int16_t g_anas[7];
|
||||
|
||||
uint16_t anaIn(uint8_t chan)
|
||||
{
|
||||
if (chan == 7)
|
||||
return 1500;
|
||||
else
|
||||
return g_anas[chan];
|
||||
}
|
||||
|
||||
bool hasExtendedTrims()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setTrim(uint8_t idx, int8_t value)
|
||||
{
|
||||
g_model.trim[idx] = value;
|
||||
}
|
||||
|
||||
void getTrims(int16_t values[4])
|
||||
{
|
||||
for (int i=0; i<4; i++)
|
||||
values[i] = g_model.trim[i];
|
||||
}
|
||||
|
||||
#define SWITCH_CASE(swtch, pin, mask) \
|
||||
case swtch: \
|
||||
if (state) pin |= (mask); else pin &= ~(mask); \
|
||||
break;
|
||||
#define SWITCH_3_CASE(swtch, pin1, pin2, mask1, mask2) \
|
||||
case swtch: \
|
||||
if (state < 0) pin1 &= ~(mask1); else pin1 |= (mask1); \
|
||||
if (state > 0) pin2 &= ~(mask2); else pin2 |= (mask2); \
|
||||
break;
|
||||
|
||||
void simuSetSwitch(uint8_t swtch, int8_t state)
|
||||
{
|
||||
// printf("swtch=%d state=%d\n", swtch, state); fflush(stdout);
|
||||
switch (swtch) {
|
||||
SWITCH_CASE(0, PIOC->PIO_PDSR, 1<<20)
|
||||
SWITCH_CASE(1, PIOA->PIO_PDSR, 1<<15)
|
||||
SWITCH_CASE(2, PIOC->PIO_PDSR, 1<<31)
|
||||
SWITCH_3_CASE(3, PIOC->PIO_PDSR, PIOC->PIO_PDSR, 0x00004000, 0x00000800)
|
||||
SWITCH_CASE(4, PIOA->PIO_PDSR, 1<<2)
|
||||
SWITCH_CASE(5, PIOC->PIO_PDSR, 1<<16)
|
||||
SWITCH_CASE(6, PIOC->PIO_PDSR, 1<<8)
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define KEYS_GPIO_REG_MENU PIOB->PIO_PDSR
|
||||
#define KEYS_GPIO_REG_EXIT PIOC->PIO_PDSR
|
||||
#define KEYS_GPIO_REG_UP PIOC->PIO_PDSR
|
||||
#define KEYS_GPIO_REG_DOWN PIOC->PIO_PDSR
|
||||
#define KEYS_GPIO_REG_RIGHT PIOC->PIO_PDSR
|
||||
#define KEYS_GPIO_REG_LEFT PIOC->PIO_PDSR
|
||||
#define KEYS_GPIO_PIN_MENU 0x00000020
|
||||
#define KEYS_GPIO_PIN_EXIT 0x01000000
|
||||
#define KEYS_GPIO_PIN_UP 0x00000002
|
||||
#define KEYS_GPIO_PIN_DOWN 0x00000020
|
||||
#define KEYS_GPIO_PIN_RIGHT 0x00000010
|
||||
#define KEYS_GPIO_PIN_LEFT 0x00000008
|
||||
|
||||
#define KEY_CASE(key, pin, mask) \
|
||||
case key: \
|
||||
if (state) pin &= ~mask; else pin |= mask;\
|
||||
break;
|
||||
|
||||
void simuSetKey(uint8_t key, bool state)
|
||||
{
|
||||
switch (key) {
|
||||
KEY_CASE(KEY_MENU, KEYS_GPIO_REG_MENU, KEYS_GPIO_PIN_MENU)
|
||||
KEY_CASE(KEY_EXIT, KEYS_GPIO_REG_EXIT, KEYS_GPIO_PIN_EXIT)
|
||||
KEY_CASE(KEY_RIGHT, KEYS_GPIO_REG_RIGHT, KEYS_GPIO_PIN_RIGHT)
|
||||
KEY_CASE(KEY_LEFT, KEYS_GPIO_REG_LEFT, KEYS_GPIO_PIN_LEFT)
|
||||
KEY_CASE(KEY_UP, KEYS_GPIO_REG_UP, KEYS_GPIO_PIN_UP)
|
||||
KEY_CASE(KEY_DOWN, KEYS_GPIO_REG_DOWN, KEYS_GPIO_PIN_DOWN)
|
||||
}
|
||||
}
|
||||
|
||||
#define TRIMS_GPIO_REG_LHL PIOA->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_LVD PIOA->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_RVU PIOA->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_RHL PIOA->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_LHR PIOB->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_LVU PIOC->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_RVD PIOC->PIO_PDSR
|
||||
#define TRIMS_GPIO_REG_RHR PIOC->PIO_PDSR
|
||||
#define PIN_TRIM_LH_L 0x00800000
|
||||
#define PIN_TRIM_LV_DN 0x01000000
|
||||
#define PIN_TRIM_RV_UP 0x00000002
|
||||
#define PIN_TRIM_RH_L 0x00000001
|
||||
#define PIN_TRIM_LH_R 0x00000010
|
||||
#define PIN_TRIM_LV_UP 0x10000000
|
||||
#define PIN_TRIM_RV_DN 0x00000400
|
||||
#define PIN_TRIM_RH_R 0x00000200
|
||||
|
||||
#define TRIM_CASE KEY_CASE
|
||||
|
||||
void simuSetTrim(uint8_t trim, bool state)
|
||||
{
|
||||
switch (trim) {
|
||||
TRIM_CASE(0, TRIMS_GPIO_REG_LHL, PIN_TRIM_LH_L)
|
||||
TRIM_CASE(1, TRIMS_GPIO_REG_LHR, PIN_TRIM_LH_R)
|
||||
TRIM_CASE(2, TRIMS_GPIO_REG_LVD, PIN_TRIM_LV_DN)
|
||||
TRIM_CASE(3, TRIMS_GPIO_REG_LVU, PIN_TRIM_LV_UP)
|
||||
TRIM_CASE(4, TRIMS_GPIO_REG_RVD, PIN_TRIM_RV_DN)
|
||||
TRIM_CASE(5, TRIMS_GPIO_REG_RVU, PIN_TRIM_RV_UP)
|
||||
TRIM_CASE(6, TRIMS_GPIO_REG_RHL, PIN_TRIM_RH_L)
|
||||
TRIM_CASE(7, TRIMS_GPIO_REG_RHR, PIN_TRIM_RH_R)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace Ersky9x;
|
||||
|
||||
Ersky9xSimulator::Ersky9xSimulator(Ersky9xInterface * ersky9xInterface):
|
||||
ersky9xInterface(ersky9xInterface)
|
||||
{
|
||||
}
|
||||
|
||||
bool Ersky9xSimulator::timer10ms()
|
||||
{
|
||||
#define TIMER10MS_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
uint8_t * Ersky9xSimulator::getLcd()
|
||||
{
|
||||
return (::uint8_t *)simuLcdBuf;
|
||||
}
|
||||
|
||||
bool Ersky9xSimulator::lcdChanged(bool & lightEnable)
|
||||
{
|
||||
#define LCDCHANGED_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::start(RadioData &radioData, bool tests)
|
||||
{
|
||||
ersky9xInterface->save(Ersky9x::eeprom, radioData);
|
||||
StartEepromThread(NULL);
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::stop()
|
||||
{
|
||||
StopMainThread();
|
||||
StopEepromThread();
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::getValues(TxOutputs &outputs)
|
||||
{
|
||||
#define GETVALUES_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::setValues(TxInputs &inputs)
|
||||
{
|
||||
#define SETVALUES_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::setTrim(unsigned int idx, int value)
|
||||
{
|
||||
Ersky9x::setTrim(idx, value);
|
||||
}
|
||||
|
||||
void Ersky9xSimulator::getTrims(Trims & trims)
|
||||
{
|
||||
trims.extended = false;
|
||||
Ersky9x::getTrims(trims.values);
|
||||
}
|
||||
|
||||
const char * Ersky9xSimulator::getError()
|
||||
{
|
||||
#define GETERROR_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ersky9x_simulator_h
|
||||
#define ersky9x_simulator_h
|
||||
|
||||
#include "simulatorinterface.h"
|
||||
|
||||
class RadioData;
|
||||
class Ersky9xInterface;
|
||||
|
||||
class Ersky9xSimulator : public SimulatorInterface {
|
||||
|
||||
public:
|
||||
|
||||
Ersky9xSimulator(Ersky9xInterface *);
|
||||
|
||||
virtual void start(RadioData & radioData, bool tests);
|
||||
|
||||
virtual void stop();
|
||||
|
||||
virtual bool timer10ms();
|
||||
|
||||
virtual uint8_t * getLcd();
|
||||
|
||||
virtual bool lcdChanged(bool & lightEnable);
|
||||
|
||||
virtual void setValues(TxInputs &inputs);
|
||||
|
||||
virtual void getValues(TxOutputs &outputs);
|
||||
|
||||
virtual void setTrim(unsigned int idx, int value);
|
||||
|
||||
virtual void getTrims(Trims & trims);
|
||||
|
||||
virtual unsigned int getPhase() { return 0; }
|
||||
|
||||
virtual const char * getPhaseName(unsigned int phase) { return 0; }
|
||||
|
||||
virtual const char * getError();
|
||||
|
||||
virtual void sendTelemetry(uint8_t * data, unsigned int len) {};
|
||||
|
||||
virtual uint8_t getSensorInstance(uint16_t id, uint8_t defaultValue = 0) { return 0; };
|
||||
|
||||
virtual uint16_t getSensorRatio(uint16_t id) { return 0; };
|
||||
|
||||
virtual void setTrainerInput(unsigned int inputNumber, int16_t value) {};
|
||||
|
||||
virtual void setLuaStateReloadPermanentScripts() {};
|
||||
|
||||
protected:
|
||||
|
||||
Ersky9xInterface * ersky9xInterface;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "generalsettings.h"
|
||||
|
||||
#include "appdata.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
const uint8_t chout_ar[] = { // First number is 0..23 -> template setup, Second is relevant channel out
|
||||
1,2,3,4 , 1,2,4,3 , 1,3,2,4 , 1,3,4,2 , 1,4,2,3 , 1,4,3,2,
|
||||
2,1,3,4 , 2,1,4,3 , 2,3,1,4 , 2,3,4,1 , 2,4,1,3 , 2,4,3,1,
|
||||
3,1,2,4 , 3,1,4,2 , 3,2,1,4 , 3,2,4,1 , 3,4,1,2 , 3,4,2,1,
|
||||
4,1,2,3 , 4,1,3,2 , 4,2,1,3 , 4,2,3,1 , 4,3,1,2 , 4,3,2,1
|
||||
};
|
||||
|
||||
bool GeneralSettings::switchPositionAllowedTaranis(int index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return true;
|
||||
|
||||
div_t qr = div(abs(index)-1, 3);
|
||||
|
||||
if (index < 0 && switchConfig[qr.quot] != Board::SWITCH_3POS)
|
||||
return false;
|
||||
else if (qr.rem == 1)
|
||||
return switchConfig[qr.quot] == Board::SWITCH_3POS;
|
||||
else
|
||||
return switchConfig[qr.quot] != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::switchSourceAllowedTaranis(int index) const
|
||||
{
|
||||
return switchConfig[index] != Board::SWITCH_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isPotAvailable(int index) const
|
||||
{
|
||||
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Pots)) return false;
|
||||
return potConfig[index] != Board::POT_NONE;
|
||||
}
|
||||
|
||||
bool GeneralSettings::isSliderAvailable(int index) const
|
||||
{
|
||||
if (index<0 || index>getBoardCapability(getCurrentBoard(), Board::Sliders)) return false;
|
||||
return sliderConfig[index] != Board::SLIDER_NONE;
|
||||
}
|
||||
|
||||
GeneralSettings::GeneralSettings()
|
||||
{
|
||||
memset(this, 0, sizeof(GeneralSettings));
|
||||
|
||||
contrast = 25;
|
||||
|
||||
for (int i=0; i < CPN_MAX_ANALOGS; ++i) {
|
||||
calibMid[i] = 0x200;
|
||||
calibSpanNeg[i] = 0x180;
|
||||
calibSpanPos[i] = 0x180;
|
||||
}
|
||||
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
// vBatWarn is voltage in 100mV, vBatMin is in 100mV but with -9V offset, vBatMax has a -12V offset
|
||||
vBatWarn = 90;
|
||||
if (IS_TARANIS_X9E(board) || IS_HORUS_X12S(board)) {
|
||||
// NI-MH 9.6V
|
||||
vBatWarn = 87;
|
||||
vBatMin = -5; //8,5V
|
||||
vBatMax = -5; //11,5V
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board)) {
|
||||
// Lipo 2S
|
||||
vBatWarn = 66;
|
||||
vBatMin = -23; // 6.7V
|
||||
vBatMax = -37; // 8.3V
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
// NI-MH 7.2V, X9D, X9D+ and X7
|
||||
vBatWarn = 65;
|
||||
vBatMin = -30; //6V
|
||||
vBatMax = -40; //8V
|
||||
}
|
||||
|
||||
setDefaultControlTypes(board);
|
||||
|
||||
backlightMode = 3; // keys and sticks
|
||||
// backlightBright = 0; // 0 = 100%
|
||||
|
||||
if (IS_HORUS(board)) {
|
||||
backlightOffBright = 20;
|
||||
}
|
||||
|
||||
if (IS_ARM(board)) {
|
||||
speakerVolume = 12;
|
||||
}
|
||||
|
||||
if (IS_HORUS(board)) {
|
||||
strcpy(bluetoothName, "Horus");
|
||||
}
|
||||
else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board)) {
|
||||
strcpy(bluetoothName, "Taranis");
|
||||
}
|
||||
|
||||
templateSetup = g.profile[g.sessionId()].channelOrder();
|
||||
stickMode = g.profile[g.sessionId()].defaultMode();
|
||||
|
||||
QString t_calib = g.profile[g.sessionId()].stickPotCalib();
|
||||
int potsnum = getBoardCapability(getCurrentBoard(), Board::Pots);
|
||||
if (!t_calib.isEmpty()) {
|
||||
QString t_trainercalib=g.profile[g.sessionId()].trainerCalib();
|
||||
int8_t t_txVoltageCalibration=(int8_t)g.profile[g.sessionId()].txVoltageCalibration();
|
||||
int8_t t_txCurrentCalibration=(int8_t)g.profile[g.sessionId()].txCurrentCalibration();
|
||||
int8_t t_PPM_Multiplier=(int8_t)g.profile[g.sessionId()].ppmMultiplier();
|
||||
uint8_t t_stickMode=(uint8_t)g.profile[g.sessionId()].gsStickMode();
|
||||
uint8_t t_vBatWarn=(uint8_t)g.profile[g.sessionId()].vBatWarn();
|
||||
QString t_DisplaySet=g.profile[g.sessionId()].display();
|
||||
QString t_BeeperSet=g.profile[g.sessionId()].beeper();
|
||||
QString t_HapticSet=g.profile[g.sessionId()].haptic();
|
||||
QString t_SpeakerSet=g.profile[g.sessionId()].speaker();
|
||||
QString t_CountrySet=g.profile[g.sessionId()].countryCode();
|
||||
|
||||
if ((t_calib.length()==(CPN_MAX_STICKS+potsnum)*12) && (t_trainercalib.length()==16)) {
|
||||
QString Byte;
|
||||
int16_t byte16;
|
||||
bool ok;
|
||||
for (int i=0; i<(CPN_MAX_STICKS+potsnum); i++) {
|
||||
Byte=t_calib.mid(i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibMid[i]=byte16;
|
||||
Byte=t_calib.mid(4+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanNeg[i]=byte16;
|
||||
Byte=t_calib.mid(8+i*12,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
calibSpanPos[i]=byte16;
|
||||
}
|
||||
for (int i=0; i<4; i++) {
|
||||
Byte=t_trainercalib.mid(i*4,4);
|
||||
byte16=(int16_t)Byte.toInt(&ok,16);
|
||||
if (ok)
|
||||
trainer.calib[i]=byte16;
|
||||
}
|
||||
txCurrentCalibration=t_txCurrentCalibration;
|
||||
txVoltageCalibration=t_txVoltageCalibration;
|
||||
vBatWarn=t_vBatWarn;
|
||||
PPM_Multiplier=t_PPM_Multiplier;
|
||||
stickMode = t_stickMode;
|
||||
}
|
||||
if ((t_DisplaySet.length()==6) && (t_BeeperSet.length()==4) && (t_HapticSet.length()==6) && (t_SpeakerSet.length()==6)) {
|
||||
uint8_t byte8u;
|
||||
int8_t byte8;
|
||||
bool ok;
|
||||
byte8=(int8_t)t_DisplaySet.mid(0,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
optrexDisplay=(byte8==1 ? true : false);
|
||||
byte8u=(uint8_t)t_DisplaySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
contrast=byte8u;
|
||||
byte8u=(uint8_t)t_DisplaySet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
backlightBright=byte8u;
|
||||
byte8=(int8_t)t_BeeperSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
beeperMode=(BeeperMode)byte8;
|
||||
byte8=(int8_t)t_BeeperSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
beeperLength=byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
hapticMode=(BeeperMode)byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(2,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
hapticStrength=byte8;
|
||||
byte8=(int8_t)t_HapticSet.mid(4,2).toInt(&ok,16);
|
||||
if (ok)
|
||||
hapticLength=byte8;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerMode=byte8u;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerPitch=byte8u;
|
||||
byte8u=(uint8_t)t_SpeakerSet.mid(4,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
speakerVolume=byte8u;
|
||||
if (t_CountrySet.length()==6) {
|
||||
byte8u=(uint8_t)t_CountrySet.mid(0,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
countryCode=byte8u;
|
||||
byte8u=(uint8_t)t_CountrySet.mid(2,2).toUInt(&ok,16);
|
||||
if (ok)
|
||||
imperial=byte8u;
|
||||
QString chars = t_CountrySet.mid(4, 2);
|
||||
ttsLanguage[0] = chars[0].toLatin1();
|
||||
ttsLanguage[1] = chars[1].toLatin1();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(themeName, "default");
|
||||
ThemeOptionData option1 = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 };
|
||||
memcpy(&themeOptionValue[0], option1, sizeof(ThemeOptionData));
|
||||
ThemeOptionData option2 = { 0x03, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 };
|
||||
memcpy(&themeOptionValue[1], option2, sizeof(ThemeOptionData));
|
||||
}
|
||||
|
||||
void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
||||
{
|
||||
for (int i=0; i<getBoardCapability(board, Board::FactoryInstalledSwitches); i++) {
|
||||
switchConfig[i] = Boards::getSwitchInfo(board, i).config;
|
||||
}
|
||||
|
||||
// TODO: move to Boards, like with switches
|
||||
if (IS_HORUS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_MULTIPOS_SWITCH;
|
||||
potConfig[2] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X7(board)) {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else {
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[2] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[3] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
}
|
||||
|
||||
int GeneralSettings::getDefaultStick(unsigned int channel) const
|
||||
{
|
||||
if (channel >= CPN_MAX_STICKS)
|
||||
return -1;
|
||||
else
|
||||
return chout_ar[4*templateSetup + channel] - 1;
|
||||
}
|
||||
|
||||
RawSource GeneralSettings::getDefaultSource(unsigned int channel) const
|
||||
{
|
||||
int stick = getDefaultStick(channel);
|
||||
if (stick >= 0)
|
||||
return RawSource(SOURCE_TYPE_STICK, stick);
|
||||
else
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
|
||||
int GeneralSettings::getDefaultChannel(unsigned int stick) const
|
||||
{
|
||||
for (int i=0; i<4; i++){
|
||||
if (getDefaultStick(i) == (int)stick)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void GeneralSettings::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
// Here we can add explicit conversions when moving from one board to another
|
||||
|
||||
cstate.setOrigin(tr("Radio Settings"));
|
||||
|
||||
setDefaultControlTypes(cstate.toType); // start with default switches/pots/sliders
|
||||
|
||||
// Try to intelligently copy any custom control names
|
||||
|
||||
// SE and SG are skipped on X7 board
|
||||
if (IS_TARANIS_X7(cstate.toType)) {
|
||||
if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) {
|
||||
strncpy(switchName[4], switchName[5], sizeof(switchName[4]));
|
||||
strncpy(switchName[5], switchName[7], sizeof(switchName[5]));
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS_X7(cstate.fromType)) {
|
||||
if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) {
|
||||
strncpy(switchName[5], switchName[4], sizeof(switchName[5]));
|
||||
strncpy(switchName[7], switchName[5], sizeof(switchName[7]));
|
||||
}
|
||||
}
|
||||
|
||||
// LS and RS sliders are after 2 aux sliders on X12 and X9E
|
||||
if ((IS_HORUS_X12S(cstate.toType) || IS_TARANIS_X9E(cstate.toType)) && !IS_HORUS_X12S(cstate.fromType) && !IS_TARANIS_X9E(cstate.fromType)) {
|
||||
strncpy(sliderName[0], sliderName[2], sizeof(sliderName[0]));
|
||||
strncpy(sliderName[1], sliderName[3], sizeof(sliderName[1]));
|
||||
}
|
||||
else if (!IS_TARANIS_X9E(cstate.toType) && !IS_HORUS_X12S(cstate.toType) && (IS_HORUS_X12S(cstate.fromType) || IS_TARANIS_X9E(cstate.fromType))) {
|
||||
strncpy(sliderName[2], sliderName[0], sizeof(sliderName[2]));
|
||||
strncpy(sliderName[3], sliderName[1], sizeof(sliderName[3]));
|
||||
}
|
||||
|
||||
if (IS_HORUS(cstate.toType)) {
|
||||
// 6P switch is only on Horus (by default)
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) == 2) {
|
||||
strncpy(potName[2], potName[1], sizeof(potName[2]));
|
||||
potName[1][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS(cstate.toType)) {
|
||||
// No S3 pot on Taranis boards by default
|
||||
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) > 2)
|
||||
strncpy(potName[1], potName[2], sizeof(potName[1]));
|
||||
|
||||
contrast = qBound<int>(getCurrentFirmware()->getCapability(MinContrast), contrast, getCurrentFirmware()->getCapability(MaxContrast));
|
||||
}
|
||||
|
||||
// TODO: Would be nice at this point to have GUI pause and ask the user to set up any custom hardware they have on the destination radio.
|
||||
|
||||
// Convert all global functions (do this after HW adjustments)
|
||||
for (int i=0; i<CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
customFn[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef GENERALSETTINGS_H
|
||||
#define GENERALSETTINGS_H
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
#include "customfunctiondata.h"
|
||||
#include "rawsource.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class Firmware;
|
||||
class ModelData;
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum UartModes {
|
||||
UART_MODE_NONE,
|
||||
UART_MODE_TELEMETRY_MIRROR,
|
||||
UART_MODE_TELEMETRY,
|
||||
UART_MODE_SBUS_TRAINER,
|
||||
UART_MODE_DEBUG
|
||||
};
|
||||
|
||||
class TrainerMix {
|
||||
public:
|
||||
TrainerMix() { clear(); }
|
||||
unsigned int src; // 0-7 = ch1-8
|
||||
RawSwitch swtch;
|
||||
int weight;
|
||||
unsigned int mode; // off, add-mode, subst-mode
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TrainerMix)); }
|
||||
};
|
||||
|
||||
class TrainerData {
|
||||
public:
|
||||
TrainerData() { clear(); }
|
||||
int calib[4];
|
||||
TrainerMix mix[4];
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TrainerData)); }
|
||||
};
|
||||
|
||||
class GeneralSettings {
|
||||
Q_DECLARE_TR_FUNCTIONS(GeneralSettings)
|
||||
|
||||
public:
|
||||
|
||||
enum BeeperMode {
|
||||
BEEPER_QUIET = -2,
|
||||
BEEPER_ALARMS_ONLY = -1,
|
||||
BEEPER_NOKEYS = 0,
|
||||
BEEPER_ALL = 1
|
||||
};
|
||||
|
||||
GeneralSettings();
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
void setDefaultControlTypes(Board::Type board);
|
||||
int getDefaultStick(unsigned int channel) const;
|
||||
RawSource getDefaultSource(unsigned int channel) const;
|
||||
int getDefaultChannel(unsigned int stick) const;
|
||||
|
||||
unsigned int version;
|
||||
unsigned int variant;
|
||||
int calibMid[CPN_MAX_ANALOGS];
|
||||
int calibSpanNeg[CPN_MAX_ANALOGS];
|
||||
int calibSpanPos[CPN_MAX_ANALOGS];
|
||||
unsigned int currModelIndex;
|
||||
char currModelFilename[16+1];
|
||||
unsigned int contrast;
|
||||
unsigned int vBatWarn;
|
||||
int txVoltageCalibration;
|
||||
int txCurrentCalibration;
|
||||
int vBatMin;
|
||||
int vBatMax;
|
||||
int backlightMode;
|
||||
TrainerData trainer;
|
||||
unsigned int view; // main screen view // TODO enum
|
||||
bool disableThrottleWarning;
|
||||
bool fai;
|
||||
bool disableMemoryWarning;
|
||||
BeeperMode beeperMode;
|
||||
bool disableAlarmWarning;
|
||||
bool disableRssiPoweroffAlarm;
|
||||
unsigned int usbMode;
|
||||
BeeperMode hapticMode;
|
||||
unsigned int stickMode; // TODO enum
|
||||
int timezone;
|
||||
bool adjustRTC;
|
||||
bool optrexDisplay;
|
||||
unsigned int inactivityTimer;
|
||||
bool minuteBeep;
|
||||
bool preBeep;
|
||||
bool flashBeep;
|
||||
unsigned int splashMode;
|
||||
int splashDuration;
|
||||
unsigned int backlightDelay;
|
||||
unsigned int templateSetup; //RETA order according to chout_ar array
|
||||
int PPM_Multiplier;
|
||||
int hapticLength;
|
||||
unsigned int reNavigation;
|
||||
unsigned int stickReverse;
|
||||
unsigned int speakerPitch;
|
||||
int hapticStrength;
|
||||
unsigned int speakerMode;
|
||||
char ownerName[10+1];
|
||||
int beeperLength;
|
||||
unsigned int gpsFormat;
|
||||
int speakerVolume;
|
||||
unsigned int backlightBright;
|
||||
unsigned int backlightOffBright;
|
||||
int switchesDelay;
|
||||
int temperatureCalib;
|
||||
int temperatureWarn;
|
||||
unsigned int mAhWarn;
|
||||
unsigned int mAhUsed;
|
||||
unsigned int globalTimer;
|
||||
char bluetoothName[10+1];
|
||||
unsigned int bluetoothBaudrate;
|
||||
unsigned int bluetoothMode;
|
||||
unsigned int sticksGain;
|
||||
unsigned int rotarySteps;
|
||||
unsigned int countryCode;
|
||||
bool jitterFilter;
|
||||
unsigned int imperial;
|
||||
char ttsLanguage[2+1];
|
||||
int beepVolume;
|
||||
int wavVolume;
|
||||
int varioVolume;
|
||||
int varioPitch;
|
||||
int varioRange;
|
||||
int varioRepeat;
|
||||
int backgroundVolume;
|
||||
unsigned int mavbaud;
|
||||
unsigned int switchUnlockStates;
|
||||
unsigned int hw_uartMode; // UartModes
|
||||
unsigned int backlightColor;
|
||||
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||
char switchName[CPN_MAX_SWITCHES][3+1];
|
||||
unsigned int switchConfig[CPN_MAX_SWITCHES];
|
||||
char stickName[CPN_MAX_STICKS][3+1];
|
||||
char potName[CPN_MAX_KNOBS][3+1];
|
||||
unsigned int potConfig[CPN_MAX_KNOBS];
|
||||
char sliderName[CPN_MAX_SLIDERS][3+1];
|
||||
unsigned int sliderConfig[CPN_MAX_SLIDERS];
|
||||
|
||||
char themeName[8+1];
|
||||
typedef uint8_t ThemeOptionData[8+1];
|
||||
ThemeOptionData themeOptionValue[5];
|
||||
|
||||
bool switchPositionAllowedTaranis(int index) const;
|
||||
bool switchSourceAllowedTaranis(int index) const;
|
||||
bool isPotAvailable(int index) const;
|
||||
bool isSliderAvailable(int index) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // GENERALSETTINGS_H
|
||||
@@ -1,729 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
#include "helpers.h"
|
||||
#include "gruvin9xeeprom.h"
|
||||
#include <QObject>
|
||||
|
||||
#define EEPROM_VER 106
|
||||
|
||||
extern void getEEPROMZString(char *dst, const char *src, int size);
|
||||
|
||||
RawSwitch gruvin9xToSwitch(int8_t sw)
|
||||
{
|
||||
if (sw == 0)
|
||||
return RawSwitch(SWITCH_TYPE_NONE);
|
||||
else if (sw <= 9)
|
||||
return RawSwitch(SWITCH_TYPE_SWITCH, sw);
|
||||
else
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, sw > 0 ? sw-9 : sw+9);
|
||||
}
|
||||
|
||||
t_Gruvin9xTrainerMix_v103::operator TrainerMix()
|
||||
{
|
||||
TrainerMix c9x;
|
||||
c9x.src = srcChn;
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
c9x.weight = (25 * studWeight) / 8;
|
||||
c9x.mode = mode;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xTrainerMix_v104::operator TrainerMix()
|
||||
{
|
||||
TrainerMix c9x;
|
||||
c9x.src = srcChn;
|
||||
c9x.weight = studWeight;
|
||||
c9x.mode = mode;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xTrainerData_v103::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xTrainerData_v104::operator TrainerData ()
|
||||
{
|
||||
TrainerData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++) {
|
||||
c9x.calib[i] = calib[i];
|
||||
c9x.mix[i] = mix[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
Gruvin9xGeneral_v103::operator GeneralSettings ()
|
||||
{
|
||||
GeneralSettings result;
|
||||
|
||||
for (int i=0; i<NUM_STICKS+BOARD_9X_NUM_POTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
|
||||
result.backlightMode = 0;
|
||||
if (lightSw == 22) {
|
||||
result.backlightMode = 4;
|
||||
}
|
||||
else if (lightAutoOff) {
|
||||
result.backlightMode |= 1;
|
||||
result.backlightDelay = lightAutoOff;
|
||||
}
|
||||
|
||||
result.trainer = trainer;
|
||||
result.view = view;
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = switchWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
case 0:
|
||||
result.beeperMode = GeneralSettings::BEEPER_QUIET;
|
||||
break;
|
||||
case 1:
|
||||
result.beeperMode = GeneralSettings::BEEPER_NOKEYS;
|
||||
break;
|
||||
default:
|
||||
result.beeperMode = GeneralSettings::BEEPER_ALL;
|
||||
result.beeperLength = beeperVal - 4;
|
||||
break;
|
||||
}
|
||||
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
result.disableAlarmWarning = disableAlarmWarning;
|
||||
result.stickMode = stickMode;
|
||||
result.inactivityTimer = inactivityTimer;
|
||||
result.minuteBeep = minuteBeep;
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
result.enableTelemetryAlarm = enableTelemetryAlarm;
|
||||
result.templateSetup = templateSetup;
|
||||
result.PPM_Multiplier = PPM_Multiplier;
|
||||
// TODO frskyRssiAlarms[2];
|
||||
return result;
|
||||
}
|
||||
|
||||
Gruvin9xGeneral_v104::operator GeneralSettings ()
|
||||
{
|
||||
GeneralSettings result;
|
||||
|
||||
for (int i=0; i<NUM_STICKS+BOARD_9X_NUM_POTS; i++) {
|
||||
result.calibMid[i] = calibMid[i];
|
||||
result.calibSpanNeg[i] = calibSpanNeg[i];
|
||||
result.calibSpanPos[i] = calibSpanPos[i];
|
||||
}
|
||||
|
||||
result.currModel = currModel;
|
||||
result.contrast = contrast;
|
||||
result.vBatWarn = vBatWarn;
|
||||
result.txVoltageCalibration = txVoltageCalibration;
|
||||
|
||||
result.backlightMode = 0;
|
||||
if (lightSw == 22) {
|
||||
result.backlightMode = 4;
|
||||
}
|
||||
else if (lightAutoOff) {
|
||||
result.backlightMode |= 1;
|
||||
result.backlightDelay = lightAutoOff;
|
||||
}
|
||||
|
||||
result.trainer = trainer;
|
||||
result.view = view;
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = switchWarning;
|
||||
result.beeperMode = (GeneralSettings::BeeperMode)beeperVal;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
result.disableAlarmWarning = disableAlarmWarning;
|
||||
result.stickMode = stickMode;
|
||||
result.inactivityTimer = inactivityTimer;
|
||||
result.minuteBeep = minuteBeep;
|
||||
result.preBeep = preBeep;
|
||||
result.flashBeep = flashBeep;
|
||||
result.splashMode = disableSplashScreen;
|
||||
result.enableTelemetryAlarm = enableTelemetryAlarm;
|
||||
result.templateSetup = templateSetup;
|
||||
result.PPM_Multiplier = PPM_Multiplier;
|
||||
// TODO frskyRssiAlarms[2];
|
||||
return result;
|
||||
}
|
||||
|
||||
t_Gruvin9xExpoData::t_Gruvin9xExpoData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xExpoData));
|
||||
}
|
||||
|
||||
t_Gruvin9xExpoData::operator ExpoData ()
|
||||
{
|
||||
ExpoData c9x;
|
||||
c9x.mode = mode;
|
||||
c9x.chn = chn;
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
if (negPhase) {
|
||||
c9x.flightModes= 1 << (phase -1);
|
||||
} else if (phase==0) {
|
||||
c9x.flightModes=0;
|
||||
} else {
|
||||
c9x.flightModes=63;
|
||||
c9x.flightModes &= ~(1 << (phase -1));
|
||||
}
|
||||
c9x.weight = weight;
|
||||
if (expo) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_EXPO;
|
||||
c9x.curve.value = expo;
|
||||
}
|
||||
else if (curve > 6) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_CUSTOM;
|
||||
c9x.curve.value = curve - 6;
|
||||
}
|
||||
else if (curve > 0) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_FUNC;
|
||||
c9x.curve.value = curve;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xLimitData::t_Gruvin9xLimitData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xLimitData));
|
||||
}
|
||||
|
||||
t_Gruvin9xLimitData::operator LimitData ()
|
||||
{
|
||||
LimitData c9x;
|
||||
c9x.min = 10*(min-100);
|
||||
c9x.max = 10*(max+100);
|
||||
c9x.revert = revert;
|
||||
c9x.offset = offset;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xMixData::t_Gruvin9xMixData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xMixData));
|
||||
}
|
||||
|
||||
t_Gruvin9xMixData::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
c9x.destCh = destCh;
|
||||
c9x.weight = weight;
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw == 8) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 9) {
|
||||
if (swtch < 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, -swtch - 1);
|
||||
c9x.weight = -weight;
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, swtch - 1);
|
||||
}
|
||||
if (mltpx != MLTPX_REP)
|
||||
c9x.swtch = RawSwitch(SWITCH_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 12) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw <= 20) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-13);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-21);
|
||||
}
|
||||
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
c9x.sOffset = sOffset;
|
||||
|
||||
if (curve > 6) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_CUSTOM;
|
||||
c9x.curve.value = curve - 6;
|
||||
}
|
||||
else if (curve > 0) {
|
||||
c9x.curve.type = CurveReference::CURVE_REF_FUNC;
|
||||
c9x.curve.value = curve;
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
RawSource gruvin9xToSource(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value == 8) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value == 9) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (value <= 12) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-10);
|
||||
}
|
||||
else if (value <= 20) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-13);
|
||||
}
|
||||
else if (value <= 36) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-21);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-36);
|
||||
}
|
||||
}
|
||||
|
||||
Gruvin9xLogicalSwitchData::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = gruvin9xToSource(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val2 = gruvin9xToSource(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = gruvin9xToSwitch(v1).toValue();
|
||||
c9x.val2 = gruvin9xToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
Gruvin9xCustomFunctionData::operator CustomFunctionData ()
|
||||
{
|
||||
CustomFunctionData c9x;
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
c9x.func = (AssignFunc)(func + G9X_NUM_CHNOUT);
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xSwashRingData::t_Gruvin9xSwashRingData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xSwashRingData));
|
||||
}
|
||||
|
||||
t_Gruvin9xSwashRingData::operator SwashRingData ()
|
||||
{
|
||||
SwashRingData c9x;
|
||||
c9x.elevatorWeight = invertELE ? -100 : 100;
|
||||
c9x.aileronWeight = invertAIL ? -100 : 100;
|
||||
c9x.collectiveWeight = invertCOL ? -100 : 100;
|
||||
c9x.type = type;
|
||||
c9x.collectiveSource = gruvin9xToSource(collectiveSource);
|
||||
c9x.value = value;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xFlightModeData_v102::operator FlightModeData ()
|
||||
{
|
||||
FlightModeData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
c9x.trim[i] = trim[i];
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.fadeIn = fadeIn;
|
||||
c9x.fadeOut = fadeOut;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xFlightModeData_v106::operator FlightModeData ()
|
||||
{
|
||||
FlightModeData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
c9x.trim[i] = (((int16_t)trim[i]) << 2) + ((trim_ext >> (2*i)) & 0x03);
|
||||
c9x.swtch = gruvin9xToSwitch(swtch);
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.fadeIn = fadeIn;
|
||||
c9x.fadeOut = fadeOut;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
extern RawSwitch getEr9xTimerMode(int mode);
|
||||
|
||||
t_Gruvin9xTimerData::operator TimerData ()
|
||||
{
|
||||
TimerData c9x;
|
||||
c9x.mode = getEr9xTimerMode(mode);
|
||||
c9x.val = val;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xFrSkyChannelData::t_Gruvin9xFrSkyChannelData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xFrSkyChannelData));
|
||||
}
|
||||
|
||||
t_Gruvin9xFrSkyChannelData::operator FrSkyChannelData ()
|
||||
{
|
||||
FrSkyChannelData c9x;
|
||||
c9x.ratio = ratio;
|
||||
c9x.alarms[0].value = alarms_value[0];
|
||||
c9x.alarms[0].level = alarms_level & 3;
|
||||
c9x.alarms[0].greater = alarms_greater & 1;
|
||||
c9x.alarms[1].value = alarms_value[1];
|
||||
c9x.alarms[1].level = (alarms_level >> 2) & 3;
|
||||
c9x.alarms[1].greater = (alarms_greater >> 1) & 1;
|
||||
c9x.type = type;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xFrSkyData::t_Gruvin9xFrSkyData()
|
||||
{
|
||||
memset(this, 0, sizeof(t_Gruvin9xFrSkyData));
|
||||
}
|
||||
|
||||
t_Gruvin9xFrSkyData::operator FrSkyData ()
|
||||
{
|
||||
FrSkyData c9x;
|
||||
c9x.channels[0] = channels[0];
|
||||
c9x.channels[1] = channels[1];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xModelData_v102::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0] = timer1;
|
||||
c9x.timers[1] = timer2;
|
||||
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_A;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_B;
|
||||
break;
|
||||
case 5:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_C;
|
||||
break;
|
||||
case 6:
|
||||
c9x.moduleData[0].protocol = PULSES_CTP1009;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
for (int i=0; i<G9X_MAX_FLIGHT_MODES; i++)
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int i=0; i<G9X_MAX_MIXERS; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<G9X_MAX_EXPOS; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
|
||||
for (int i=0; i<G9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<G9X_NUM_CSW; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xModelData_v103::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0] = timer1;
|
||||
c9x.timers[1] = timer2;
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_A;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_B;
|
||||
break;
|
||||
case 5:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_C;
|
||||
break;
|
||||
case 6:
|
||||
c9x.moduleData[0].protocol = PULSES_CTP1009;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
for (int i=0; i<G9X_MAX_FLIGHT_MODES; i++)
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int i=0; i<G9X_MAX_MIXERS; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<G9X_MAX_EXPOS; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
|
||||
for (int i=0; i<G9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<G9X_NUM_CSW; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xModelData_v105::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0] = timer1;
|
||||
c9x.timers[1] = timer2;
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_A;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_B;
|
||||
break;
|
||||
case 5:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_C;
|
||||
break;
|
||||
case 6:
|
||||
c9x.moduleData[0].protocol = PULSES_CTP1009;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<G9X_MAX_FLIGHT_MODES; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (flightModeData[i].trim[j] > 125) {
|
||||
c9x.flightModeData[i].trimRef[j] = 0;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
else if (flightModeData[i].trim[j] < -125) {
|
||||
c9x.flightModeData[i].trimRef[j] = 129 + flightModeData[i].trim[j];
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
else {
|
||||
c9x.flightModeData[i].trim[j] += subtrim[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_MIXERS; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<G9X_MAX_EXPOS; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
|
||||
for (int i=0; i<G9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<G9X_NUM_CSW; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<G9X_NUM_FSW; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Gruvin9xModelData_v106::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.timers[0] = timer1;
|
||||
c9x.timers[1] = timer2;
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_A;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_B;
|
||||
break;
|
||||
case 5:
|
||||
c9x.moduleData[0].protocol = PULSES_SILV_C;
|
||||
break;
|
||||
case 6:
|
||||
c9x.moduleData[0].protocol = PULSES_CTP1009;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc-2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<G9X_MAX_FLIGHT_MODES; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_MIXERS; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<G9X_MAX_EXPOS; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
|
||||
for (int i=0; i<G9X_MAX_CURVE5; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<G9X_MAX_CURVE9; i++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[G9X_MAX_CURVE5 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<G9X_NUM_CSW; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<G9X_NUM_FSW; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
// for (int i=0; i<G9X_NUM_CHNOUT; i++)
|
||||
// c9x.safetySw[i] = safetySw[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef gruvin9xeeprom_h
|
||||
#define gruvin9xeeprom_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "eeprominterface.h"
|
||||
#define GR9X_MAX_CSFUNC 13
|
||||
|
||||
PACK(typedef struct t_Gruvin9xTrainerMix_v103 {
|
||||
uint8_t srcChn:3; //0-7 = ch1-8
|
||||
int8_t swtch:5;
|
||||
int8_t studWeight:6;
|
||||
uint8_t mode:2; //off,add-mode,subst-mode
|
||||
|
||||
operator TrainerMix();
|
||||
t_Gruvin9xTrainerMix_v103() { memset(this, 0, sizeof(t_Gruvin9xTrainerMix_v103)); }
|
||||
|
||||
}) Gruvin9xTrainerMix_v103; //
|
||||
|
||||
PACK(typedef struct t_Gruvin9xTrainerMix_v104 {
|
||||
uint8_t srcChn:6; // 0-7 = ch1-8
|
||||
uint8_t mode:2; // off,add-mode,subst-mode
|
||||
int8_t studWeight;
|
||||
|
||||
operator TrainerMix();
|
||||
t_Gruvin9xTrainerMix_v104() { memset(this, 0, sizeof(t_Gruvin9xTrainerMix_v104)); }
|
||||
}) Gruvin9xTrainerMix_v104; //
|
||||
|
||||
PACK(typedef struct t_Gruvin9xTrainerData_v103 {
|
||||
int16_t calib[4];
|
||||
Gruvin9xTrainerMix_v103 mix[4];
|
||||
|
||||
operator TrainerData();
|
||||
}) Gruvin9xTrainerData_v103;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xTrainerData_v104 {
|
||||
int16_t calib[4];
|
||||
Gruvin9xTrainerMix_v104 mix[4];
|
||||
|
||||
operator TrainerData();
|
||||
t_Gruvin9xTrainerData_v104() { memset(this, 0, sizeof(t_Gruvin9xTrainerData_v104)); }
|
||||
}) Gruvin9xTrainerData_v104;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xFrSkyRSSIAlarm {
|
||||
uint8_t level:2;
|
||||
int8_t value:6;
|
||||
}) Gruvin9xFrSkyRSSIAlarm;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xGeneral_v103 {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[7];
|
||||
int16_t calibSpanNeg[7];
|
||||
int16_t calibSpanPos[7];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
uint8_t vBatWarn;
|
||||
int8_t txVoltageCalibration;
|
||||
int8_t lightSw;
|
||||
Gruvin9xTrainerData_v103 trainer;
|
||||
uint8_t view; //index of subview in main scrren
|
||||
uint8_t disableThrottleWarning:1;
|
||||
int8_t switchWarning:2; // -1=down, 0=off, 1=up
|
||||
uint8_t beeperVal:3;
|
||||
uint8_t disableMemoryWarning:1;
|
||||
uint8_t disableAlarmWarning:1;
|
||||
uint8_t stickMode;
|
||||
uint8_t inactivityTimer;
|
||||
uint8_t throttleReversed:1;
|
||||
uint8_t minuteBeep:1;
|
||||
uint8_t preBeep:1;
|
||||
uint8_t flashBeep:1;
|
||||
uint8_t disableSplashScreen:1;
|
||||
uint8_t enableTelemetryAlarm:1; // 0=no, 1=yes (Sound alarm when there's no telem. data coming in)
|
||||
uint8_t spare:2;
|
||||
uint8_t filterInput;
|
||||
uint8_t lightAutoOff;
|
||||
uint8_t templateSetup; //RETA order according to chout_ar array
|
||||
int8_t PPM_Multiplier;
|
||||
Gruvin9xFrSkyRSSIAlarm frskyRssiAlarms[2];
|
||||
|
||||
operator GeneralSettings();
|
||||
t_Gruvin9xGeneral_v103() { memset(this, 0, sizeof(t_Gruvin9xGeneral_v103)); }
|
||||
}) Gruvin9xGeneral_v103;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xGeneral_v104 {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[7];
|
||||
int16_t calibSpanNeg[7];
|
||||
int16_t calibSpanPos[7];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
uint8_t vBatWarn;
|
||||
int8_t txVoltageCalibration;
|
||||
int8_t lightSw;
|
||||
Gruvin9xTrainerData_v104 trainer;
|
||||
uint8_t view; //index of subview in main scrren
|
||||
uint8_t disableThrottleWarning:1;
|
||||
int8_t switchWarning:2; // -1=down, 0=off, 1=up
|
||||
uint8_t beeperVal:3;
|
||||
uint8_t disableMemoryWarning:1;
|
||||
uint8_t disableAlarmWarning:1;
|
||||
uint8_t stickMode;
|
||||
uint8_t inactivityTimer;
|
||||
uint8_t throttleReversed:1;
|
||||
uint8_t minuteBeep:1;
|
||||
uint8_t preBeep:1;
|
||||
uint8_t flashBeep:1;
|
||||
uint8_t disableSplashScreen:1;
|
||||
uint8_t enableTelemetryAlarm:1; // 0=no, 1=yes (Sound alarm when there's no telem. data coming in)
|
||||
uint8_t spare:2;
|
||||
uint8_t filterInput;
|
||||
uint8_t lightAutoOff;
|
||||
uint8_t templateSetup; //RETA order according to chout_ar array
|
||||
int8_t PPM_Multiplier;
|
||||
Gruvin9xFrSkyRSSIAlarm frskyRssiAlarms[2];
|
||||
|
||||
operator GeneralSettings();
|
||||
t_Gruvin9xGeneral_v104() { memset(this, 0, sizeof(t_Gruvin9xGeneral_v104)); }
|
||||
}) Gruvin9xGeneral_v104;
|
||||
|
||||
typedef Gruvin9xGeneral_v104 Gruvin9xGeneral;
|
||||
|
||||
// eeprom modelspec
|
||||
|
||||
PACK(typedef struct t_Gruvin9xExpoData {
|
||||
uint8_t mode:2; // 0=end, 1=pos, 2=neg, 3=both
|
||||
uint8_t chn:2;
|
||||
uint8_t curve:4; // 0=no curve, 1-6=std curves, 7-10=CV1-CV4, 11-15=CV9-CV13
|
||||
int8_t swtch:5;
|
||||
uint8_t phase:3; // if negPhase is 0: 0=normal, 5=FP4 if negPhase is 1: 5=!FP4
|
||||
uint8_t negPhase:1;
|
||||
uint8_t weight:7;
|
||||
int8_t expo;
|
||||
|
||||
operator ExpoData();
|
||||
t_Gruvin9xExpoData();
|
||||
}) Gruvin9xExpoData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xLimitData {
|
||||
int8_t min;
|
||||
int8_t max;
|
||||
bool revert;
|
||||
int16_t offset;
|
||||
|
||||
operator LimitData();
|
||||
t_Gruvin9xLimitData();
|
||||
}) Gruvin9xLimitData;
|
||||
|
||||
#define MLTPX_ADD 0
|
||||
#define MLTPX_MUL 1
|
||||
#define MLTPX_REP 2
|
||||
|
||||
PACK(typedef struct t_Gruvin9xMixData {
|
||||
uint8_t destCh:5; // 0, 1..C9X_NUM_CHNOUT
|
||||
uint8_t mixWarn:3; // mixer warning
|
||||
uint8_t srcRaw; //
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
uint8_t curve; // 0=symmetrisch, 1=no neg, 2=no pos
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint8_t carryTrim:1;
|
||||
uint8_t mltpx:3; // multiplex method 0=+ 1=* 2=replace
|
||||
int8_t phase:4; // -5=!FP4, 0=normal, 5=FP4
|
||||
int8_t sOffset;
|
||||
|
||||
operator MixData();
|
||||
t_Gruvin9xMixData();
|
||||
}) Gruvin9xMixData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xLogicalSwitchData { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Gruvin9xLogicalSwitchData() { memset(this, 0, sizeof(t_Gruvin9xLogicalSwitchData)); }
|
||||
}) Gruvin9xLogicalSwitchData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xSafetySwData { // Safety Switches data
|
||||
int8_t swtch;
|
||||
int8_t val;
|
||||
|
||||
t_Gruvin9xSafetySwData() { memset(this, 0, sizeof(t_Gruvin9xSafetySwData)); }
|
||||
}) Gruvin9xSafetySwData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xCustomFunctionData { // Function Switches data
|
||||
int8_t swtch; // input
|
||||
uint8_t func;
|
||||
|
||||
operator CustomFunctionData();
|
||||
t_Gruvin9xCustomFunctionData() { memset(this, 0, sizeof(t_Gruvin9xCustomFunctionData)); }
|
||||
}) Gruvin9xCustomFunctionData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xFrSkyChannelData {
|
||||
uint16_t ratio:12; // (Maximum resistor divider input volts +/- calibration. 0 means channel not used.
|
||||
// 0.01v steps from 0 to 40.95V. Ex. 6.60 Volts = 660. 40.95V = 4095
|
||||
uint16_t type:4; // channel display unit (0=volts, 1=raw, 2-15=reserverd.)
|
||||
uint8_t alarms_value[2]; // raw sample values 0..255
|
||||
uint8_t alarms_level:4; // two pairs of 2bits. none=0, yel=1, org=2, red=3
|
||||
uint8_t alarms_greater:2; // two alarms, 1 bit each. 0=LT(<), 1=GT(>)
|
||||
uint8_t spare:2;
|
||||
uint8_t barMin; // minimum for bar display (raw ADC value)
|
||||
uint8_t barMax; // ditto for max display (would G:NOT usually = ratio)
|
||||
|
||||
operator FrSkyChannelData();
|
||||
t_Gruvin9xFrSkyChannelData();
|
||||
}) Gruvin9xFrSkyChannelData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xFrSkyData {
|
||||
Gruvin9xFrSkyChannelData channels[2];
|
||||
|
||||
operator FrSkyData();
|
||||
t_Gruvin9xFrSkyData();
|
||||
}) Gruvin9xFrSkyData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xSwashRingData { // Swash Ring data
|
||||
uint8_t invertELE:1;
|
||||
uint8_t invertAIL:1;
|
||||
uint8_t invertCOL:1;
|
||||
uint8_t type:5;
|
||||
uint8_t collectiveSource;
|
||||
uint8_t value;
|
||||
|
||||
operator SwashRingData();
|
||||
t_Gruvin9xSwashRingData();
|
||||
}) Gruvin9xSwashRingData;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xFlightModeData_v102 {
|
||||
int8_t trim[4]; // -125..125 => trim value, 127 => use trim of phase 0, -128, -127, -126 => use trim of phases 1|2|3|4 instead
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
|
||||
operator FlightModeData();
|
||||
t_Gruvin9xFlightModeData_v102() { memset(this, 0, sizeof(t_Gruvin9xFlightModeData_v102)); }
|
||||
}) Gruvin9xFlightModeData_v102;
|
||||
|
||||
|
||||
PACK(typedef struct t_Gruvin9xFlightModeData_v106 {
|
||||
int8_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of phases 1|2|3|4 instead
|
||||
int8_t trim_ext:8; // 2 less significant extra bits per trim (10bits trims)
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
|
||||
operator FlightModeData();
|
||||
t_Gruvin9xFlightModeData_v106() { memset(this, 0, sizeof(t_Gruvin9xFlightModeData_v106)); }
|
||||
}) Gruvin9xFlightModeData_v106;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xTimerData {
|
||||
int8_t mode:7; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||
uint8_t dir:1; // 0=>Count Down, 1=>Count Up
|
||||
uint16_t val;
|
||||
|
||||
operator TimerData();
|
||||
t_Gruvin9xTimerData() { memset(this, 0, sizeof(t_Gruvin9xTimerData)); }
|
||||
}) Gruvin9xTimerData;
|
||||
|
||||
#define G9X_MAX_FLIGHT_MODES 5
|
||||
#define G9X_MAX_MIXERS 32
|
||||
#define G9X_MAX_EXPOS 14
|
||||
#define G9X_MAX_CURVE5 8
|
||||
#define G9X_MAX_CURVE9 8
|
||||
|
||||
#define G9X_NUM_CHNOUT 16 // number of real output channels CH1-CH16
|
||||
#define G9X_NUM_CSW 12 // number of custom switches
|
||||
#define G9X_NUM_FSW 12 // number of functions assigned to switches
|
||||
|
||||
// TODO
|
||||
PACK(typedef struct t_Gruvin9xModelData_v102 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Gruvin9xTimerData timer1;
|
||||
uint8_t protocol:3;
|
||||
int8_t ppmNCH:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t spare1:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Gruvin9xTimerData timer2;
|
||||
Gruvin9xMixData mixData[G9X_MAX_MIXERS];
|
||||
Gruvin9xLimitData limitData[G9X_NUM_CHNOUT];
|
||||
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
|
||||
int8_t curves5[G9X_MAX_CURVE5][5];
|
||||
int8_t curves9[G9X_MAX_CURVE9][9];
|
||||
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
|
||||
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
|
||||
Gruvin9xSwashRingData swashR;
|
||||
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
|
||||
Gruvin9xFrSkyData frsky;
|
||||
|
||||
operator ModelData();
|
||||
t_Gruvin9xModelData_v102() { memset(this, 0, sizeof(t_Gruvin9xModelData_v102)); }
|
||||
|
||||
}) Gruvin9xModelData_v102;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xModelData_v103 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Gruvin9xTimerData timer1;
|
||||
uint8_t protocol:3;
|
||||
int8_t ppmNCH:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t spare1:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Gruvin9xTimerData timer2;
|
||||
Gruvin9xMixData mixData[G9X_MAX_MIXERS];
|
||||
Gruvin9xLimitData limitData[G9X_NUM_CHNOUT];
|
||||
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
|
||||
int8_t curves5[G9X_MAX_CURVE5][5];
|
||||
int8_t curves9[G9X_MAX_CURVE9][9];
|
||||
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
|
||||
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
|
||||
Gruvin9xSwashRingData swashR;
|
||||
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
|
||||
Gruvin9xFrSkyData frsky;
|
||||
|
||||
operator ModelData();
|
||||
t_Gruvin9xModelData_v103() { memset(this, 0, sizeof(t_Gruvin9xModelData_v103)); }
|
||||
|
||||
}) Gruvin9xModelData_v103;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xModelData_v105 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Gruvin9xTimerData timer1;
|
||||
uint8_t protocol:3;
|
||||
int8_t ppmNCH:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t spare1:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Gruvin9xTimerData timer2;
|
||||
Gruvin9xMixData mixData[G9X_MAX_MIXERS];
|
||||
Gruvin9xLimitData limitData[G9X_NUM_CHNOUT];
|
||||
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
|
||||
int8_t curves5[G9X_MAX_CURVE5][5];
|
||||
int8_t curves9[G9X_MAX_CURVE9][9];
|
||||
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
|
||||
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
|
||||
Gruvin9xCustomFunctionData customFn[G9X_NUM_FSW];
|
||||
Gruvin9xSwashRingData swashR;
|
||||
Gruvin9xFlightModeData_v102 flightModeData[G9X_MAX_FLIGHT_MODES];
|
||||
int16_t subtrim[NUM_STICKS];
|
||||
Gruvin9xFrSkyData frsky;
|
||||
|
||||
operator ModelData();
|
||||
t_Gruvin9xModelData_v105() { memset(this, 0, sizeof(t_Gruvin9xModelData_v105)); }
|
||||
}) Gruvin9xModelData_v105;
|
||||
|
||||
PACK(typedef struct t_Gruvin9xModelData_v106 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Gruvin9xTimerData timer1;
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t thrExpo:1; // Enable Throttle Expo
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint8_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Gruvin9xTimerData timer2;
|
||||
Gruvin9xMixData mixData[G9X_MAX_MIXERS];
|
||||
Gruvin9xLimitData limitData[G9X_NUM_CHNOUT];
|
||||
Gruvin9xExpoData expoData[G9X_MAX_EXPOS];
|
||||
int8_t curves5[G9X_MAX_CURVE5][5];
|
||||
int8_t curves9[G9X_MAX_CURVE9][9];
|
||||
Gruvin9xLogicalSwitchData logicalSw[G9X_NUM_CSW];
|
||||
Gruvin9xSafetySwData safetySw[G9X_NUM_CHNOUT];
|
||||
Gruvin9xCustomFunctionData customFn[G9X_NUM_FSW];
|
||||
Gruvin9xSwashRingData swashR;
|
||||
Gruvin9xFlightModeData_v106 flightModeData[G9X_MAX_FLIGHT_MODES];
|
||||
Gruvin9xFrSkyData frsky;
|
||||
|
||||
operator ModelData();
|
||||
t_Gruvin9xModelData_v106() { memset(this, 0, sizeof(t_Gruvin9xModelData_v106)); }
|
||||
}) Gruvin9xModelData_v106;
|
||||
|
||||
typedef Gruvin9xModelData_v106 Gruvin9xModelData;
|
||||
|
||||
#endif
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "gruvin9xinterface.h"
|
||||
#include "gruvin9xeeprom.h"
|
||||
#include "file.h"
|
||||
#include "appdata.h"
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
#define FILE_GENERAL 0
|
||||
#define FILE_MODEL(n) (1+n)
|
||||
|
||||
Gruvin9xInterface::Gruvin9xInterface(BoardEnum board):
|
||||
EEPROMInterface(board),
|
||||
efile(new RleFile())
|
||||
{
|
||||
}
|
||||
|
||||
Gruvin9xInterface::~Gruvin9xInterface()
|
||||
{
|
||||
delete efile;
|
||||
}
|
||||
|
||||
const char * Gruvin9xInterface::getName()
|
||||
{
|
||||
if (board == BOARD_STOCK)
|
||||
return "Gruvin9x";
|
||||
else
|
||||
return "Gruvin9x v4";
|
||||
}
|
||||
|
||||
const int Gruvin9xInterface::getEEpromSize()
|
||||
{
|
||||
if (board == BOARD_STOCK) {
|
||||
QString avrMCU = g.mcu();
|
||||
if (avrMCU==QString("m128")) {
|
||||
return EESIZE_STOCK*2;
|
||||
}
|
||||
return EESIZE_STOCK;
|
||||
} else {
|
||||
return EESIZE_GRUVIN9X;
|
||||
}
|
||||
}
|
||||
|
||||
const int Gruvin9xInterface::getMaxModels()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Gruvin9xInterface::loadModel(ModelData &model, unsigned int stickMode, int version)
|
||||
{
|
||||
T _model;
|
||||
if ((version == 2 && efile->readRlc2((uint8_t*)&_model, sizeof(T))) ||
|
||||
(version == 1 && efile->readRlc1((uint8_t*)&_model, sizeof(T)))) {
|
||||
model = _model;
|
||||
if (stickMode) {
|
||||
applyStickModeToModel(model, stickMode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
model.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool Gruvin9xInterface::loadGeneral(GeneralSettings &settings, int version)
|
||||
{
|
||||
T _settings;
|
||||
if ((version == 2 && efile->readRlc2((uint8_t*)&_settings, sizeof(T))) ||
|
||||
(version == 1 && efile->readRlc1((uint8_t*)&_settings, sizeof(T)))) {
|
||||
settings = _settings;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::cerr << "error when loading general settings";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long Gruvin9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
|
||||
unsigned long Gruvin9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying " << getName() << " import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != this->getEEpromSize()) {
|
||||
std::cout << "wrong size\n";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
|
||||
uint8_t version;
|
||||
if (efile->readRlc2(&version, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (efile->readRlc1(&version, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)version << " ";
|
||||
|
||||
switch(version) {
|
||||
case 5:
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 104:
|
||||
case 105:
|
||||
// subtrims(16bits) + function switches added
|
||||
case 106:
|
||||
// trims(10bits), no subtrims
|
||||
break;
|
||||
default:
|
||||
std::cout << "not gruvin9x\n";
|
||||
errors.set(NOT_GRUVIN9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (version == 5) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings, 1)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else if (version < 104) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v103>(radioData.generalSettings)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else if (version <= 106) {
|
||||
if (!loadGeneral<Gruvin9xGeneral_v104>(radioData.generalSettings)) {
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "ko\n";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
efile->openRd(FILE_MODEL(i));
|
||||
if (version == 5) {
|
||||
loadModel<Gruvin9xModelData_v102>(radioData.models[i], radioData.generalSettings.stickMode+1, 1);
|
||||
}
|
||||
else if (version < 103) {
|
||||
loadModel<Gruvin9xModelData_v102>(radioData.models[i], radioData.generalSettings.stickMode+1);
|
||||
}
|
||||
else if (version == 103) {
|
||||
loadModel<Gruvin9xModelData_v103>(radioData.models[i], radioData.generalSettings.stickMode+1);
|
||||
}
|
||||
else if (version == 105) {
|
||||
loadModel<Gruvin9xModelData_v105>(radioData.models[i], radioData.generalSettings.stickMode+1);
|
||||
}
|
||||
else if (version == 106) {
|
||||
loadModel<Gruvin9xModelData_v106>(radioData.models[i], radioData.generalSettings.stickMode+1);
|
||||
}
|
||||
else {
|
||||
std::cout << "ko\n";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
unsigned long Gruvin9xInterface::loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index)
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
int Gruvin9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t variant, uint8_t version)
|
||||
{
|
||||
std::cout << "NO!\n";
|
||||
// TODO an error
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Gruvin9xInterface::getSize(const ModelData & model)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Gruvin9xInterface::getSize(const GeneralSettings & settings)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Gruvin9xInterface::isAvailable(PulsesProtocol proto, int port)
|
||||
{
|
||||
switch (proto) {
|
||||
case PULSES_PPM:
|
||||
case PULSES_SILV_A:
|
||||
case PULSES_SILV_B:
|
||||
case PULSES_SILV_C:
|
||||
case PULSES_CTP1009:
|
||||
case PULSES_DSM2:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#ifndef gruvin9x_interface_h
|
||||
#define gruvin9x_interface_h
|
||||
|
||||
#include "eeprominterface.h"
|
||||
|
||||
class RleFile;
|
||||
|
||||
class Gruvin9xInterface : public EEPROMInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Gruvin9xInterface(BoardEnum board);
|
||||
|
||||
virtual ~Gruvin9xInterface();
|
||||
|
||||
virtual const char * getName();
|
||||
|
||||
virtual const int getEEpromSize();
|
||||
|
||||
virtual const int getMaxModels();
|
||||
|
||||
virtual unsigned long load(RadioData &, const uint8_t *eeprom, int size);
|
||||
|
||||
|
||||
virtual unsigned long loadBackup(RadioData &, uint8_t *eeprom,int esize, int index);
|
||||
|
||||
virtual unsigned long loadxml(RadioData &radioData, QDomDocument &doc);
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0);
|
||||
|
||||
virtual int getSize(const ModelData &);
|
||||
|
||||
virtual int getSize(const GeneralSettings & settings);
|
||||
|
||||
virtual int isAvailable(PulsesProtocol proto, int port=0);
|
||||
|
||||
protected:
|
||||
|
||||
template <class T>
|
||||
void loadModel(ModelData &model, unsigned int stickMode=0, int version=2);
|
||||
|
||||
template <class T>
|
||||
bool loadGeneral(GeneralSettings &settings, int version=2);
|
||||
|
||||
RleFile *efile;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "gvardata.h"
|
||||
|
||||
#include "radiodata.h"
|
||||
|
||||
QString GVarData::unitToString() const
|
||||
{
|
||||
switch (unit) {
|
||||
case GVAR_UNIT_NUMBER:
|
||||
return tr("");
|
||||
case GVAR_UNIT_PERCENT:
|
||||
return tr("%");
|
||||
default:
|
||||
return tr("?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::precToString() const
|
||||
{
|
||||
switch (prec) {
|
||||
case GVAR_PREC_MUL10:
|
||||
return tr("0._");
|
||||
case GVAR_PREC_MUL1:
|
||||
return tr("0.0");
|
||||
default:
|
||||
return tr("?.?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("GV"), index + 1, name);
|
||||
}
|
||||
|
||||
int GVarData::multiplierSet()
|
||||
{
|
||||
return (prec == 0 ? 1 : 10);
|
||||
}
|
||||
|
||||
float GVarData::multiplierGet() const
|
||||
{
|
||||
return (prec == 0 ? 1 : 0.1);
|
||||
}
|
||||
|
||||
void GVarData::setMin(float val)
|
||||
{
|
||||
min = (val * multiplierSet()) - GVAR_MIN_VALUE;
|
||||
}
|
||||
|
||||
void GVarData::setMax(float val)
|
||||
{
|
||||
max = GVAR_MAX_VALUE - (val * multiplierSet());
|
||||
}
|
||||
|
||||
int GVarData::getMin() const
|
||||
{
|
||||
return GVAR_MIN_VALUE + min;
|
||||
}
|
||||
|
||||
int GVarData::getMax() const
|
||||
{
|
||||
return GVAR_MAX_VALUE - max;
|
||||
}
|
||||
|
||||
float GVarData::getMinPrec() const
|
||||
{
|
||||
return getMin() * multiplierGet();
|
||||
}
|
||||
|
||||
float GVarData::getMaxPrec() const
|
||||
{
|
||||
return getMax() * multiplierGet();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef GVARDATA_H
|
||||
#define GVARDATA_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#define GVAR_NAME_LEN 3
|
||||
#define GVAR_MAX_VALUE 1024
|
||||
#define GVAR_MIN_VALUE -GVAR_MAX_VALUE
|
||||
|
||||
class GVarData {
|
||||
Q_DECLARE_TR_FUNCTIONS(GVarData)
|
||||
|
||||
public:
|
||||
GVarData() { clear(); }
|
||||
|
||||
enum {
|
||||
GVAR_UNIT_NUMBER,
|
||||
GVAR_UNIT_PERCENT
|
||||
};
|
||||
|
||||
enum {
|
||||
GVAR_PREC_MUL10,
|
||||
GVAR_PREC_MUL1
|
||||
};
|
||||
|
||||
char name[GVAR_NAME_LEN+1];
|
||||
int min;
|
||||
int max;
|
||||
bool popup;
|
||||
unsigned int prec; // 0 0._ 1 0.0
|
||||
unsigned int unit; // 0 _ 1 %
|
||||
|
||||
void clear() {memset(this, 0, sizeof(GVarData)); }
|
||||
QString unitToString() const;
|
||||
QString precToString() const;
|
||||
QString nameToString(int index) const;
|
||||
int multiplierSet();
|
||||
float multiplierGet() const;
|
||||
void setMin(float val);
|
||||
void setMax(float val);
|
||||
int getMin() const;
|
||||
int getMax() const;
|
||||
float getMinPrec() const;
|
||||
float getMaxPrec() const;
|
||||
};
|
||||
|
||||
|
||||
#endif // GVARDATA_H
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "io_data.h"
|
||||
|
||||
#include "radiodata.h" // for RadioData::getElementName
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
/*
|
||||
* ExpoData
|
||||
*/
|
||||
|
||||
void ExpoData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("INP"), 3);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MixData
|
||||
*/
|
||||
|
||||
void MixData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("MIX"), 4);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LimitData
|
||||
*/
|
||||
|
||||
QString LimitData::minToString() const
|
||||
{
|
||||
return QString::number((qreal)min/10);
|
||||
}
|
||||
|
||||
QString LimitData::maxToString() const
|
||||
{
|
||||
return QString::number((qreal)max/10);
|
||||
}
|
||||
|
||||
QString LimitData::revertToString() const
|
||||
{
|
||||
return revert ? tr("INV") : tr("NOR");
|
||||
}
|
||||
|
||||
QString LimitData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CH"), index + 1, name);
|
||||
}
|
||||
|
||||
QString LimitData::offsetToString() const
|
||||
{
|
||||
return QString::number((qreal)offset/10, 'f', 1);
|
||||
}
|
||||
|
||||
void LimitData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(LimitData));
|
||||
min = -1000;
|
||||
max = +1000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CurveData
|
||||
*/
|
||||
|
||||
CurveData::CurveData()
|
||||
{
|
||||
clear(5);
|
||||
}
|
||||
|
||||
void CurveData::clear(int count)
|
||||
{
|
||||
memset(this, 0, sizeof(CurveData));
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
bool CurveData::isEmpty() const
|
||||
{
|
||||
for (int i=0; i<count; i++) {
|
||||
if (points[i].y != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CurveData::nameToString(const int idx) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CV"), idx + 1, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FlightModeData
|
||||
*/
|
||||
|
||||
void FlightModeData::clear(const int phase)
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(FlightModeData));
|
||||
if (phase != 0) {
|
||||
for (int idx=0; idx<CPN_MAX_GVARS; idx++) {
|
||||
gvars[idx] = 1025;
|
||||
}
|
||||
for (int idx=0; idx<CPN_MAX_ENCODERS; idx++) {
|
||||
rotaryEncoders[idx] = 1025;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString FlightModeData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("FM"), index, name); // names are zero-based, FM0, FM1, etc
|
||||
}
|
||||
|
||||
void FlightModeData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent("FMD", 2);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx));
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef IO_DATA_H
|
||||
#define IO_DATA_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "curvereference.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum InputMode {
|
||||
INPUT_MODE_NONE,
|
||||
INPUT_MODE_POS,
|
||||
INPUT_MODE_NEG,
|
||||
INPUT_MODE_BOTH
|
||||
};
|
||||
|
||||
class ExpoData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ExpoData)
|
||||
|
||||
public:
|
||||
ExpoData() { clear(); }
|
||||
RawSource srcRaw;
|
||||
unsigned int scale;
|
||||
unsigned int mode; // InputMode
|
||||
unsigned int chn;
|
||||
RawSwitch swtch;
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int weight;
|
||||
int offset;
|
||||
CurveReference curve;
|
||||
int carryTrim;
|
||||
char name[10+1];
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ExpoData)); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
};
|
||||
|
||||
enum MltpxValue {
|
||||
MLTPX_ADD=0,
|
||||
MLTPX_MUL=1,
|
||||
MLTPX_REP=2
|
||||
};
|
||||
|
||||
#define MIXDATA_NAME_LEN 10
|
||||
|
||||
class MixData {
|
||||
Q_DECLARE_TR_FUNCTIONS(MixData)
|
||||
|
||||
public:
|
||||
MixData() { clear(); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
unsigned int destCh; // 1..CPN_MAX_CHNOUT
|
||||
RawSource srcRaw;
|
||||
int weight;
|
||||
RawSwitch swtch;
|
||||
CurveReference curve; //0=symmetrisch
|
||||
unsigned int delayUp;
|
||||
unsigned int delayDown;
|
||||
unsigned int speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
unsigned int speedDown; // 0 nichts
|
||||
int carryTrim;
|
||||
bool noExpo;
|
||||
MltpxValue mltpx; // multiplex method 0=+ 1=* 2=replace
|
||||
unsigned int mixWarn; // mixer warning
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int sOffset;
|
||||
char name[MIXDATA_NAME_LEN+1];
|
||||
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(MixData)); }
|
||||
};
|
||||
|
||||
class LimitData {
|
||||
Q_DECLARE_TR_FUNCTIONS(LimitData)
|
||||
|
||||
public:
|
||||
LimitData() { clear(); }
|
||||
int min;
|
||||
int max;
|
||||
bool revert;
|
||||
int offset;
|
||||
int ppmCenter;
|
||||
bool symetrical;
|
||||
char name[6+1];
|
||||
CurveReference curve;
|
||||
QString minToString() const;
|
||||
QString maxToString() const;
|
||||
QString offsetToString() const;
|
||||
QString revertToString() const;
|
||||
QString nameToString(int index) const;
|
||||
void clear();
|
||||
};
|
||||
|
||||
class CurvePoint {
|
||||
public:
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
};
|
||||
|
||||
class CurveData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveData)
|
||||
|
||||
public:
|
||||
enum CurveType {
|
||||
CURVE_TYPE_STANDARD,
|
||||
CURVE_TYPE_CUSTOM,
|
||||
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
||||
};
|
||||
|
||||
CurveData();
|
||||
void clear(int count);
|
||||
bool isEmpty() const;
|
||||
QString nameToString(const int idx) const;
|
||||
|
||||
CurveType type;
|
||||
bool smooth;
|
||||
int count;
|
||||
CurvePoint points[CPN_MAX_POINTS];
|
||||
char name[6+1];
|
||||
};
|
||||
|
||||
class FlightModeData {
|
||||
Q_DECLARE_TR_FUNCTIONS(FlightModeData)
|
||||
|
||||
public:
|
||||
FlightModeData() { clear(0); }
|
||||
int trimMode[CPN_MAX_TRIMS];
|
||||
int trimRef[CPN_MAX_TRIMS];
|
||||
int trim[CPN_MAX_TRIMS];
|
||||
RawSwitch swtch;
|
||||
char name[10+1];
|
||||
unsigned int fadeIn;
|
||||
unsigned int fadeOut;
|
||||
int rotaryEncoders[CPN_MAX_ENCODERS];
|
||||
int gvars[CPN_MAX_GVARS];
|
||||
void clear(const int phase);
|
||||
QString nameToString(int index) const;
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
};
|
||||
|
||||
class SwashRingData {
|
||||
Q_DECLARE_TR_FUNCTIONS(SwashRingData)
|
||||
|
||||
public:
|
||||
SwashRingData() { clear(); }
|
||||
int elevatorWeight;
|
||||
int aileronWeight;
|
||||
int collectiveWeight;
|
||||
unsigned int type;
|
||||
RawSource collectiveSource;
|
||||
RawSource aileronSource;
|
||||
RawSource elevatorSource;
|
||||
unsigned int value;
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(SwashRingData)); }
|
||||
};
|
||||
|
||||
#endif // IO_DATA_H
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "logicalswitchdata.h"
|
||||
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
bool LogicalSwitchData::isEmpty() const
|
||||
{
|
||||
return (func == 0);
|
||||
}
|
||||
|
||||
CSFunctionFamily LogicalSwitchData::getFunctionFamily() const
|
||||
{
|
||||
if (func == LS_FN_EDGE)
|
||||
return LS_FAMILY_EDGE;
|
||||
else if (func == LS_FN_TIMER)
|
||||
return LS_FAMILY_TIMER;
|
||||
else if (func == LS_FN_STICKY)
|
||||
return LS_FAMILY_STICKY;
|
||||
else if (func < LS_FN_AND || func > LS_FN_ELESS)
|
||||
return LS_FAMILY_VOFS;
|
||||
else if (func < LS_FN_EQUAL)
|
||||
return LS_FAMILY_VBOOL;
|
||||
else
|
||||
return LS_FAMILY_VCOMP;
|
||||
}
|
||||
|
||||
unsigned int LogicalSwitchData::getRangeFlags() const
|
||||
{
|
||||
int f = 0;
|
||||
|
||||
if (func == LS_FN_DPOS || func == LS_FN_DAPOS)
|
||||
f |= RANGE_DELTA_FUNCTION;
|
||||
|
||||
if (func == LS_FN_DAPOS || func == LS_FN_APOS || func == LS_FN_ANEG)
|
||||
f |= RANGE_ABS_FUNCTION;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
QString LogicalSwitchData::funcToString() const
|
||||
{
|
||||
switch (func) {
|
||||
case LS_FN_OFF:
|
||||
return tr("---");
|
||||
case LS_FN_VPOS:
|
||||
return tr("a>x");
|
||||
case LS_FN_VNEG:
|
||||
return tr("a<x");
|
||||
case LS_FN_APOS:
|
||||
return tr("|a|>x");
|
||||
case LS_FN_ANEG:
|
||||
return tr("|a|<x");
|
||||
case LS_FN_AND:
|
||||
return tr("AND");
|
||||
case LS_FN_OR:
|
||||
return tr("OR");
|
||||
case LS_FN_XOR:
|
||||
return tr("XOR");
|
||||
case LS_FN_EQUAL:
|
||||
return tr("a=b");
|
||||
case LS_FN_NEQUAL:
|
||||
return tr("a!=b");
|
||||
case LS_FN_GREATER:
|
||||
return tr("a>b");
|
||||
case LS_FN_LESS:
|
||||
return tr("a<b");
|
||||
case LS_FN_EGREATER:
|
||||
return tr("a>=b");
|
||||
case LS_FN_ELESS:
|
||||
return tr("a<=b");
|
||||
case LS_FN_DPOS:
|
||||
return tr("d>=x");
|
||||
case LS_FN_DAPOS:
|
||||
return tr("|d|>=x");
|
||||
case LS_FN_VEQUAL:
|
||||
return tr("a=x");
|
||||
case LS_FN_VALMOSTEQUAL:
|
||||
return tr("a~x");
|
||||
case LS_FN_TIMER:
|
||||
return tr("Timer");
|
||||
case LS_FN_STICKY:
|
||||
return tr("Sticky");
|
||||
case LS_FN_EDGE:
|
||||
return tr("Edge");
|
||||
default:
|
||||
return tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
QString LogicalSwitchData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("L"), index + 1, NULL, true);
|
||||
}
|
||||
|
||||
void LogicalSwitchData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("LSW"), 7);
|
||||
cstate.setSubComp(RawSwitch(SWITCH_TYPE_VIRTUAL, cstate.subCompIdx + 1).toString(cstate.fromType, cstate.fromGS(), cstate.fromModel()));
|
||||
CSFunctionFamily family = getFunctionFamily();
|
||||
switch(family) {
|
||||
case LS_FAMILY_VOFS:
|
||||
val1 = RawSource(val1).convert(cstate.withComponentField("V1")).toValue();
|
||||
break;
|
||||
case LS_FAMILY_STICKY:
|
||||
case LS_FAMILY_VBOOL:
|
||||
val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue();
|
||||
val2 = RawSwitch(val2).convert(cstate.withComponentField("V2")).toValue();
|
||||
break;
|
||||
case LS_FAMILY_EDGE:
|
||||
val1 = RawSwitch(val1).convert(cstate.withComponentField("V1")).toValue();
|
||||
break;
|
||||
case LS_FAMILY_VCOMP:
|
||||
val1 = RawSource(val1).convert(cstate.withComponentField("V1")).toValue();
|
||||
val2 = RawSource(val2).convert(cstate.withComponentField("V2")).toValue();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
andsw = RawSwitch(andsw).convert(cstate.withComponentField("AND")).toValue();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef LOGICALSWITCHDATA_H
|
||||
#define LOGICALSWITCHDATA_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum CSFunction {
|
||||
LS_FN_OFF,
|
||||
LS_FN_VPOS,
|
||||
LS_FN_VNEG,
|
||||
LS_FN_APOS,
|
||||
LS_FN_ANEG,
|
||||
LS_FN_AND,
|
||||
LS_FN_OR,
|
||||
LS_FN_XOR,
|
||||
LS_FN_EQUAL,
|
||||
LS_FN_NEQUAL,
|
||||
LS_FN_GREATER,
|
||||
LS_FN_LESS,
|
||||
LS_FN_EGREATER,
|
||||
LS_FN_ELESS,
|
||||
LS_FN_DPOS,
|
||||
LS_FN_DAPOS,
|
||||
LS_FN_VEQUAL, // added at the end to avoid everything renumbered
|
||||
LS_FN_VALMOSTEQUAL,
|
||||
LS_FN_TIMER,
|
||||
LS_FN_STICKY,
|
||||
LS_FN_EDGE,
|
||||
// later ... LS_FN_RANGE,
|
||||
LS_FN_MAX
|
||||
};
|
||||
|
||||
enum CSFunctionFamily {
|
||||
LS_FAMILY_VOFS,
|
||||
LS_FAMILY_VBOOL,
|
||||
LS_FAMILY_VCOMP,
|
||||
LS_FAMILY_TIMER,
|
||||
LS_FAMILY_STICKY,
|
||||
LS_FAMILY_EDGE,
|
||||
};
|
||||
|
||||
class LogicalSwitchData {
|
||||
Q_DECLARE_TR_FUNCTIONS(LogicalSwitchData)
|
||||
|
||||
public:
|
||||
LogicalSwitchData(unsigned int func=0)
|
||||
{
|
||||
clear();
|
||||
this->func = func;
|
||||
}
|
||||
unsigned int func;
|
||||
int val1;
|
||||
int val2;
|
||||
int val3;
|
||||
unsigned int delay;
|
||||
unsigned int duration;
|
||||
int andsw;
|
||||
|
||||
void clear() { memset(this, 0, sizeof(LogicalSwitchData)); }
|
||||
bool isEmpty() const;
|
||||
CSFunctionFamily getFunctionFamily() const;
|
||||
unsigned int getRangeFlags() const;
|
||||
QString funcToString() const;
|
||||
QString nameToString(int index) const;
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
};
|
||||
|
||||
#endif // LOGICALSWITCHDATA_H
|
||||
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "modeldata.h"
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include "generalsettings.h"
|
||||
#include "macros.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
|
||||
QString removeAccents(const QString & str)
|
||||
{
|
||||
// UTF-8 ASCII Table
|
||||
static const QHash<QString, QVariant> map = {
|
||||
{"a", QRegularExpression("[áâãàä]")},
|
||||
{"A", QRegularExpression("[ÁÂÃÀÄ]")},
|
||||
{"e", QRegularExpression("[éèêě]")},
|
||||
{"E", QRegularExpression("[ÉÈÊĚ]")},
|
||||
{"o", QRegularExpression("[óôõö]")},
|
||||
{"O", QRegularExpression("[ÓÔÕÖ]")},
|
||||
{"u", QRegularExpression("[úü]")},
|
||||
{"U", QRegularExpression("[ÚÜ]")},
|
||||
{"i", "í"}, {"I", "Í"},
|
||||
{"c", "ç"}, {"C", "Ç"},
|
||||
{"y", "ý"}, {"Y", "Ý"},
|
||||
{"s", "š"}, {"S", "Š"},
|
||||
{"r", "ř"}, {"R", "Ř"}
|
||||
};
|
||||
|
||||
QString result(str);
|
||||
for (QHash<QString, QVariant>::const_iterator it = map.cbegin(), en = map.cend(); it != en; ++it) {
|
||||
if (it.value().canConvert<QRegularExpression>())
|
||||
result.replace(it.value().toRegularExpression(), it.key());
|
||||
else
|
||||
result.replace(it.value().toString(), it.key());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TimerData
|
||||
*/
|
||||
|
||||
void TimerData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("TMR"), 1);
|
||||
cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1));
|
||||
mode.convert(cstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ModelData
|
||||
*/
|
||||
|
||||
ModelData::ModelData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
ModelData::ModelData(const ModelData & src)
|
||||
{
|
||||
*this = src;
|
||||
}
|
||||
|
||||
ModelData & ModelData::operator = (const ModelData & src)
|
||||
{
|
||||
memcpy(reinterpret_cast<void *>(this), &src, sizeof(ModelData));
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpoData * ModelData::insertInput(const int idx)
|
||||
{
|
||||
memmove(&expoData[idx+1], &expoData[idx], (CPN_MAX_EXPOS-(idx+1))*sizeof(ExpoData));
|
||||
expoData[idx].clear();
|
||||
return &expoData[idx];
|
||||
}
|
||||
|
||||
bool ModelData::isInputValid(const unsigned int idx) const
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
const ExpoData * expo = &expoData[i];
|
||||
if (expo->mode == 0) break;
|
||||
if (expo->chn == idx)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelData::hasExpos(uint8_t inputIdx) const
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
const ExpoData & expo = expoData[i];
|
||||
if (expo.chn==inputIdx && expo.mode!=0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelData::hasMixes(uint8_t channelIdx) const
|
||||
{
|
||||
channelIdx += 1;
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++) {
|
||||
if (mixData[i].destCh == channelIdx) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<const ExpoData *> ModelData::expos(int input) const
|
||||
{
|
||||
QVector<const ExpoData *> result;
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
const ExpoData * ed = &expoData[i];
|
||||
if ((int)ed->chn==input && ed->mode!=0) {
|
||||
result << ed;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVector<const MixData *> ModelData::mixes(int channel) const
|
||||
{
|
||||
QVector<const MixData *> result;
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++) {
|
||||
const MixData * md = &mixData[i];
|
||||
if ((int)md->destCh == channel+1) {
|
||||
result << md;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ModelData::removeInput(const int idx, bool clearName)
|
||||
{
|
||||
unsigned int chn = expoData[idx].chn;
|
||||
|
||||
memmove(&expoData[idx], &expoData[idx+1], (CPN_MAX_EXPOS-(idx+1))*sizeof(ExpoData));
|
||||
expoData[CPN_MAX_EXPOS-1].clear();
|
||||
|
||||
//also remove input name if removing last line for this input
|
||||
if (clearName && !expos(chn).size())
|
||||
inputNames[chn][0] = 0;
|
||||
}
|
||||
|
||||
void ModelData::clearInputs()
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++)
|
||||
expoData[i].clear();
|
||||
|
||||
//clear all input names
|
||||
if (getCurrentFirmware()->getCapability(VirtualInputs)) {
|
||||
for (int i=0; i<CPN_MAX_INPUTS; i++) {
|
||||
inputNames[i][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::clearMixes()
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++)
|
||||
mixData[i].clear();
|
||||
}
|
||||
|
||||
void ModelData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(ModelData));
|
||||
modelIndex = -1; // an invalid index, this is managed by the TreeView data model
|
||||
moduleData[0].protocol = PULSES_OFF;
|
||||
moduleData[1].protocol = PULSES_OFF;
|
||||
moduleData[0].channelsCount = 8;
|
||||
moduleData[1].channelsStart = 0;
|
||||
moduleData[1].channelsCount = 8;
|
||||
moduleData[0].ppm.delay = 300;
|
||||
moduleData[1].ppm.delay = 300;
|
||||
moduleData[2].ppm.delay = 300; // Trainer PPM
|
||||
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
flightModeData[i].clear(i);
|
||||
}
|
||||
for (int i=0; i<CPN_MAX_GVARS; i++) {
|
||||
gvarData[i].clear();
|
||||
}
|
||||
clearInputs();
|
||||
clearMixes();
|
||||
for (int i=0; i<CPN_MAX_CHNOUT; i++)
|
||||
limitData[i].clear();
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++)
|
||||
expoData[i].clear();
|
||||
for (int i=0; i<CPN_MAX_LOGICAL_SWITCHES; i++)
|
||||
logicalSw[i].clear();
|
||||
for (int i=0; i<CPN_MAX_SPECIAL_FUNCTIONS; i++)
|
||||
customFn[i].clear();
|
||||
for (int i=0; i<CPN_MAX_CURVES; i++)
|
||||
curves[i].clear(5);
|
||||
for (int i=0; i<CPN_MAX_TIMERS; i++)
|
||||
timers[i].clear();
|
||||
swashRingData.clear();
|
||||
frsky.clear();
|
||||
rssiAlarms.clear();
|
||||
for (int i=0; i<CPN_MAX_SENSORS; i++)
|
||||
sensorData[i].clear();
|
||||
|
||||
static const uint8_t blob[] = { 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x32, 0x50, 0x31, 0x00, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x42, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
memcpy(customScreenData[0], blob, sizeof(blob));
|
||||
}
|
||||
|
||||
bool ModelData::isEmpty() const
|
||||
{
|
||||
return !used;
|
||||
}
|
||||
|
||||
void ModelData::setDefaultInputs(const GeneralSettings & settings)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (IS_ARM(board)) {
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
ExpoData * expo = &expoData[i];
|
||||
expo->chn = i;
|
||||
expo->mode = INPUT_MODE_BOTH;
|
||||
expo->srcRaw = settings.getDefaultSource(i);
|
||||
expo->weight = 100;
|
||||
strncpy(inputNames[i], removeAccents(expo->srcRaw.toString(this)).toLatin1().constData(), sizeof(inputNames[i])-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::setDefaultMixes(const GeneralSettings & settings)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (IS_ARM(board)) {
|
||||
setDefaultInputs(settings);
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKS; i++) {
|
||||
MixData * mix = &mixData[i];
|
||||
mix->destCh = i+1;
|
||||
mix->weight = 100;
|
||||
if (IS_ARM(board)) {
|
||||
mix->srcRaw = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i);
|
||||
}
|
||||
else {
|
||||
mix->srcRaw = RawSource(SOURCE_TYPE_STICK, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settings)
|
||||
{
|
||||
clear();
|
||||
used = true;
|
||||
sprintf(name, "MODEL%02d", id+1);
|
||||
for (int i=0; i<CPN_MAX_MODULES; i++) {
|
||||
moduleData[i].modelId = id+1;
|
||||
}
|
||||
setDefaultMixes(settings);
|
||||
}
|
||||
|
||||
int ModelData::getTrimValue(int phaseIdx, int trimIdx)
|
||||
{
|
||||
int result = 0;
|
||||
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
FlightModeData & phase = flightModeData[phaseIdx];
|
||||
if (phase.trimMode[trimIdx] < 0) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
if (phase.trimRef[trimIdx] == phaseIdx || phaseIdx == 0) {
|
||||
return result + phase.trim[trimIdx];
|
||||
}
|
||||
else {
|
||||
phaseIdx = phase.trimRef[trimIdx];
|
||||
if (phase.trimMode[trimIdx] != 0)
|
||||
result += phase.trim[trimIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ModelData::isGVarLinked(int phaseIdx, int gvarIdx)
|
||||
{
|
||||
return flightModeData[phaseIdx].gvars[gvarIdx] > 1024;
|
||||
}
|
||||
|
||||
int ModelData::getGVarFieldValue(int phaseIdx, int gvarIdx)
|
||||
{
|
||||
int idx = flightModeData[phaseIdx].gvars[gvarIdx];
|
||||
for (int i=0; idx>GVAR_MAX_VALUE && i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
int nextPhase = idx - GVAR_MAX_VALUE - 1;
|
||||
if (nextPhase >= phaseIdx) nextPhase += 1;
|
||||
phaseIdx = nextPhase;
|
||||
idx = flightModeData[phaseIdx].gvars[gvarIdx];
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
void ModelData::setTrimValue(int phaseIdx, int trimIdx, int value)
|
||||
{
|
||||
for (uint8_t i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
FlightModeData & phase = flightModeData[phaseIdx];
|
||||
int mode = phase.trimMode[trimIdx];
|
||||
int p = phase.trimRef[trimIdx];
|
||||
int & trim = phase.trim[trimIdx];
|
||||
if (mode < 0)
|
||||
return;
|
||||
if (p == phaseIdx || phaseIdx == 0) {
|
||||
trim = value;
|
||||
break;;
|
||||
}
|
||||
else if (mode == 0) {
|
||||
phaseIdx = p;
|
||||
}
|
||||
else {
|
||||
trim = value - getTrimValue(p, trimIdx);
|
||||
if (trim < -500)
|
||||
trim = -500;
|
||||
if (trim > 500)
|
||||
trim = 500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::removeGlobalVar(int & var)
|
||||
{
|
||||
if (var >= 126 && var <= 130)
|
||||
var = flightModeData[0].gvars[var-126];
|
||||
else if (var <= -126 && var >= -130)
|
||||
var = - flightModeData[0].gvars[-126-var];
|
||||
}
|
||||
|
||||
ModelData ModelData::removeGlobalVars()
|
||||
{
|
||||
ModelData result = *this;
|
||||
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++) {
|
||||
removeGlobalVar(mixData[i].weight);
|
||||
removeGlobalVar(mixData[i].curve.value);
|
||||
removeGlobalVar(mixData[i].sOffset);
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
removeGlobalVar(expoData[i].weight);
|
||||
removeGlobalVar(expoData[i].curve.value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ModelData::getChannelsMax(bool forceExtendedLimits) const
|
||||
{
|
||||
if (forceExtendedLimits || extendedLimits)
|
||||
return IS_HORUS_OR_TARANIS(getCurrentBoard()) ? 150 : 125;
|
||||
else
|
||||
return 100;
|
||||
}
|
||||
|
||||
bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
{
|
||||
unsigned index = abs(swtch.index) - 1;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_VIRTUAL) {
|
||||
return logicalSw[index].func != LS_FN_OFF;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_FLIGHT_MODE) {
|
||||
return index == 0 || flightModeData[index].swtch.type != SWITCH_TYPE_NONE;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_SENSOR) {
|
||||
return strlen(sensorData[index].label) > 0;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float ModelData::getGVarFieldValuePrec(int phaseIdx, int gvarIdx)
|
||||
{
|
||||
return getGVarFieldValue(phaseIdx, gvarIdx) * gvarData[gvarIdx].multiplierGet();
|
||||
}
|
||||
|
||||
void ModelData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
// Here we can add explicit conversions when moving from one board to another
|
||||
|
||||
QString origin = QString(name);
|
||||
if (origin.isEmpty())
|
||||
origin = QString::number(cstate.modelIdx+1);
|
||||
cstate.setOrigin(tr("Model: ") % origin);
|
||||
|
||||
cstate.setComponent("SET", 0);
|
||||
if (thrTraceSrc && (int)thrTraceSrc < cstate.fromBoard.getCapability(Board::Pots) + cstate.fromBoard.getCapability(Board::Sliders)) {
|
||||
cstate.setSubComp(tr("Throttle Source"));
|
||||
thrTraceSrc = RawSource(SOURCE_TYPE_STICK, (int)thrTraceSrc + 3).convert(cstate).index - 3;
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_TIMERS; i++) {
|
||||
timers[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++) {
|
||||
mixData[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
expoData[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_LOGICAL_SWITCHES; i++) {
|
||||
logicalSw[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_SPECIAL_FUNCTIONS; i++) {
|
||||
customFn[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
flightModeData[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_MODULES; i++) {
|
||||
moduleData[i].convert(cstate.withComponentIndex(i));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef MODELDATA_H
|
||||
#define MODELDATA_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "customfunctiondata.h"
|
||||
#include "gvardata.h"
|
||||
#include "io_data.h"
|
||||
#include "logicalswitchdata.h"
|
||||
#include "moduledata.h"
|
||||
#include "sensordata.h"
|
||||
#include "telem_data.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
|
||||
#define CHAR_FOR_NAMES " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
|
||||
#define CHAR_FOR_NAMES_REGEX "[ A-Za-z0-9_.-,]*"
|
||||
|
||||
class RSSIAlarmData {
|
||||
public:
|
||||
RSSIAlarmData() { clear(); }
|
||||
unsigned int level[2]; // AVR Only
|
||||
int warning;
|
||||
int critical;
|
||||
bool disabled;
|
||||
void clear() {
|
||||
this->level[0] = 2;
|
||||
this->level[1] = 3;
|
||||
this->warning = 45;
|
||||
this->critical = 42;
|
||||
this->disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
#define TIMER_NAME_LEN 8
|
||||
|
||||
class TimerData {
|
||||
Q_DECLARE_TR_FUNCTIONS(TimerData)
|
||||
|
||||
public:
|
||||
enum CountDownMode {
|
||||
COUNTDOWN_SILENT,
|
||||
COUNTDOWN_BEEPS,
|
||||
COUNTDOWN_VOICE,
|
||||
COUNTDOWN_HAPTIC
|
||||
};
|
||||
TimerData() { clear(); }
|
||||
RawSwitch mode;
|
||||
char name[TIMER_NAME_LEN+1];
|
||||
bool minuteBeep;
|
||||
unsigned int countdownBeep;
|
||||
unsigned int val;
|
||||
unsigned int persistent;
|
||||
int pvalue;
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TimerData)); mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
};
|
||||
|
||||
#define CPN_MAX_SCRIPTS 9
|
||||
#define CPN_MAX_SCRIPT_INPUTS 10
|
||||
class ScriptData {
|
||||
public:
|
||||
ScriptData() { clear(); }
|
||||
char filename[10+1];
|
||||
char name[10+1];
|
||||
int inputs[CPN_MAX_SCRIPT_INPUTS];
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ScriptData)); }
|
||||
};
|
||||
|
||||
/*
|
||||
* TODO ...
|
||||
*/
|
||||
#if 0
|
||||
class CustomScreenOptionData {
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
class CustomScreenZoneData {
|
||||
public:
|
||||
char widgetName[10+1];
|
||||
WidgetOptionData widgetOptions[5];
|
||||
};
|
||||
|
||||
class CustomScreenData {
|
||||
public:
|
||||
CustomScreenData();
|
||||
|
||||
char layoutName[10+1];
|
||||
CustomScreenZoneData zones[];
|
||||
CustomScreenOptionData options[];
|
||||
};
|
||||
#else
|
||||
typedef char CustomScreenData[610+1];
|
||||
typedef char TopbarData[216+1];
|
||||
#endif
|
||||
|
||||
enum TrainerMode {
|
||||
TRAINER_MODE_MASTER_TRAINER_JACK,
|
||||
TRAINER_MODE_SLAVE,
|
||||
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
|
||||
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
|
||||
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
|
||||
};
|
||||
|
||||
class ModelData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ModelData)
|
||||
|
||||
public:
|
||||
ModelData();
|
||||
ModelData(const ModelData & src);
|
||||
ModelData & operator = (const ModelData & src);
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
ExpoData * insertInput(const int idx);
|
||||
void removeInput(const int idx, bool clearName = true);
|
||||
|
||||
bool isInputValid(const unsigned int idx) const;
|
||||
bool hasExpos(uint8_t inputIdx) const;
|
||||
bool hasMixes(uint8_t output) const;
|
||||
|
||||
QVector<const ExpoData *> expos(int input) const;
|
||||
QVector<const MixData *> mixes(int channel) const;
|
||||
|
||||
bool used;
|
||||
int category;
|
||||
char name[15+1];
|
||||
char filename[16+1];
|
||||
int modelIndex; // Companion only, temporary index position managed by data model.
|
||||
|
||||
TimerData timers[CPN_MAX_TIMERS];
|
||||
bool noGlobalFunctions;
|
||||
bool thrTrim; // Enable Throttle Trim
|
||||
int trimInc; // Trim Increments
|
||||
unsigned int trimsDisplay;
|
||||
bool disableThrottleWarning;
|
||||
|
||||
unsigned int beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
|
||||
bool extendedLimits; // TODO xml
|
||||
bool extendedTrims;
|
||||
bool throttleReversed;
|
||||
FlightModeData flightModeData[CPN_MAX_FLIGHT_MODES];
|
||||
MixData mixData[CPN_MAX_MIXERS];
|
||||
LimitData limitData[CPN_MAX_CHNOUT];
|
||||
|
||||
char inputNames[CPN_MAX_INPUTS][4+1];
|
||||
ExpoData expoData[CPN_MAX_EXPOS];
|
||||
|
||||
CurveData curves[CPN_MAX_CURVES];
|
||||
LogicalSwitchData logicalSw[CPN_MAX_LOGICAL_SWITCHES];
|
||||
CustomFunctionData customFn[CPN_MAX_SPECIAL_FUNCTIONS];
|
||||
SwashRingData swashRingData;
|
||||
unsigned int thrTraceSrc;
|
||||
uint64_t switchWarningStates;
|
||||
unsigned int switchWarningEnable;
|
||||
unsigned int potsWarningMode;
|
||||
bool potsWarningEnabled[CPN_MAX_POTS];
|
||||
int potPosition[CPN_MAX_POTS];
|
||||
bool displayChecklist;
|
||||
GVarData gvarData[CPN_MAX_GVARS];
|
||||
MavlinkData mavlink;
|
||||
unsigned int telemetryProtocol;
|
||||
FrSkyData frsky;
|
||||
RSSIAlarmData rssiAlarms;
|
||||
|
||||
char bitmap[10+1];
|
||||
|
||||
unsigned int trainerMode; // TrainerMode
|
||||
|
||||
ModuleData moduleData[CPN_MAX_MODULES+1/*trainer*/];
|
||||
|
||||
ScriptData scriptData[CPN_MAX_SCRIPTS];
|
||||
|
||||
SensorData sensorData[CPN_MAX_SENSORS];
|
||||
|
||||
unsigned int toplcdTimer;
|
||||
|
||||
CustomScreenData customScreenData[5];
|
||||
|
||||
TopbarData topbarData;
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
void setDefaultInputs(const GeneralSettings & settings);
|
||||
void setDefaultMixes(const GeneralSettings & settings);
|
||||
void setDefaultValues(unsigned int id, const GeneralSettings & settings);
|
||||
|
||||
int getTrimValue(int phaseIdx, int trimIdx);
|
||||
void setTrimValue(int phaseIdx, int trimIdx, int value);
|
||||
|
||||
bool isGVarLinked(int phaseIdx, int gvarIdx);
|
||||
int getGVarFieldValue(int phaseIdx, int gvarIdx);
|
||||
float getGVarFieldValuePrec(int phaseIdx, int gvarIdx);
|
||||
|
||||
ModelData removeGlobalVars();
|
||||
|
||||
void clearMixes();
|
||||
void clearInputs();
|
||||
|
||||
int getChannelsMax(bool forceExtendedLimits=false) const;
|
||||
|
||||
bool isAvailable(const RawSwitch & swtch) const;
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
};
|
||||
|
||||
#endif // MODELDATA_H
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "moduledata.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "multiprotocols.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void ModuleData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
if (protocol == PULSES_PXX_R9M && (IS_TARANIS_XLITE(cstate.fromType) || IS_TARANIS_XLITE(cstate.toType))) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
QString ModuleData::rfProtocolToString() const
|
||||
{
|
||||
switch (protocol) {
|
||||
case PULSES_MULTIMODULE:
|
||||
return Multiprotocols::protocolToString((int)multi.rfProtocol, multi.customProto);
|
||||
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
QString ModuleData::subTypeToString(int type) const
|
||||
{
|
||||
static const char * strings[] = {
|
||||
"FCC",
|
||||
"EU",
|
||||
"868MHz",
|
||||
"915MHz"
|
||||
};
|
||||
|
||||
if (type < 0)
|
||||
type = subType;
|
||||
|
||||
switch (protocol) {
|
||||
case PULSES_MULTIMODULE:
|
||||
return Multiprotocols::subTypeToString(multi.customProto ? MM_RF_CUSTOM_SELECTED : (int)multi.rfProtocol, (unsigned)type);
|
||||
|
||||
case PULSES_PXX_R9M:
|
||||
return CHECK_IN_ARRAY(strings, type);
|
||||
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
QString ModuleData::powerValueToString(Firmware * fw) const
|
||||
{
|
||||
const QStringList & strRef = powerValueStrings(subType, fw);
|
||||
// EU module with telemetry can only be < 100/200mW.
|
||||
if (pxx.sport_out && subType == MODULE_SUBTYPE_R9M_EU && pxx.power > 1)
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
|
||||
return strRef.value(pxx.power, CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
// static
|
||||
QString ModuleData::indexToString(int index, Firmware * fw)
|
||||
{
|
||||
if (index < 0)
|
||||
return tr("Trainer Port");
|
||||
|
||||
if (fw->getCapability(NumModules) > 1) {
|
||||
if (IS_HORUS_OR_TARANIS(fw->getBoard()))
|
||||
return index == 0 ? tr("Internal Radio System") : tr("External Radio Module");
|
||||
if (index > 0)
|
||||
return tr("Extra Radio System");
|
||||
}
|
||||
return tr("Radio System");
|
||||
}
|
||||
|
||||
// static
|
||||
QString ModuleData::protocolToString(unsigned protocol)
|
||||
{
|
||||
static const char * strings[] = {
|
||||
"OFF",
|
||||
"PPM",
|
||||
"Silverlit A", "Silverlit B", "Silverlit C",
|
||||
"CTP1009",
|
||||
"LP45", "DSM2", "DSMX",
|
||||
"PPM16", "PPMsim",
|
||||
"FrSky XJT (D16)", "FrSky XJT (D8)", "FrSky XJT (LR12)", "FrSky DJT",
|
||||
"Crossfire",
|
||||
"DIY Multiprotocol Module",
|
||||
"FrSky R9M Module",
|
||||
"SBUS output at VBat"
|
||||
};
|
||||
|
||||
return CHECK_IN_ARRAY(strings, protocol);
|
||||
}
|
||||
|
||||
// static
|
||||
QStringList ModuleData::powerValueStrings(int subType, Firmware * fw)
|
||||
{
|
||||
static const QStringList strings[] = {
|
||||
{ tr("10mW - 16CH"), tr("100mW - 16CH"), tr("500mW - 16CH"), tr("Auto <= 1W - 16CH") }, // full-size FCC
|
||||
{ tr("25mW - 8CH"), tr("25mW - 16CH"), tr("200mW - 16CH (no telemetry)"), tr("500mW - 16CH (no telemetry)") }, // full-size EU
|
||||
{ tr("100mW - 16CH") }, // mini FCC
|
||||
{ tr("25mW - 8CH"), tr("25mW - 16CH"), tr("100mW - 16CH (no telemetry)") } // mini EU
|
||||
};
|
||||
int strIdx = 0;
|
||||
if (subType == MODULE_SUBTYPE_R9M_EU)
|
||||
strIdx += 1;
|
||||
if (fw->getCapability(HasModuleR9MMini))
|
||||
strIdx += 2;
|
||||
return strings[strIdx];
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef MODULEDATA_H
|
||||
#define MODULEDATA_H
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class Firmware;
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum PulsesProtocol {
|
||||
PULSES_OFF,
|
||||
PULSES_PPM,
|
||||
PULSES_SILV_A,
|
||||
PULSES_SILV_B,
|
||||
PULSES_SILV_C,
|
||||
PULSES_CTP1009,
|
||||
PULSES_LP45,
|
||||
PULSES_DSM2,
|
||||
PULSES_DSMX,
|
||||
PULSES_PPM16,
|
||||
PULSES_PPMSIM,
|
||||
PULSES_PXX_XJT_X16,
|
||||
PULSES_PXX_XJT_D8,
|
||||
PULSES_PXX_XJT_LR12,
|
||||
PULSES_PXX_DJT,
|
||||
PULSES_CROSSFIRE,
|
||||
PULSES_MULTIMODULE,
|
||||
PULSES_PXX_R9M,
|
||||
PULSES_SBUS,
|
||||
PULSES_PROTOCOL_LAST
|
||||
};
|
||||
|
||||
enum MultiModuleRFProtocols {
|
||||
MM_RF_PROTO_FLYSKY=0,
|
||||
MM_RF_PROTO_FIRST=MM_RF_PROTO_FLYSKY,
|
||||
MM_RF_PROTO_HUBSAN,
|
||||
MM_RF_PROTO_FRSKY,
|
||||
MM_RF_PROTO_HISKY,
|
||||
MM_RF_PROTO_V2X2,
|
||||
MM_RF_PROTO_DSM2,
|
||||
MM_RF_PROTO_DEVO,
|
||||
MM_RF_PROTO_YD717,
|
||||
MM_RF_PROTO_KN,
|
||||
MM_RF_PROTO_SYMAX,
|
||||
MM_RF_PROTO_SLT,
|
||||
MM_RF_PROTO_CX10,
|
||||
MM_RF_PROTO_CG023,
|
||||
MM_RF_PROTO_BAYANG,
|
||||
MM_RF_PROTO_ESky,
|
||||
MM_RF_PROTO_MT99XX,
|
||||
MM_RF_PROTO_MJXQ,
|
||||
MM_RF_PROTO_SHENQI,
|
||||
MM_RF_PROTO_FY326,
|
||||
MM_RF_PROTO_SFHSS,
|
||||
MM_RF_PROTO_J6PRO,
|
||||
MM_RF_PROTO_FQ777,
|
||||
MM_RF_PROTO_ASSAN,
|
||||
MM_RF_PROTO_HONTAI,
|
||||
MM_RF_PROTO_OLRS,
|
||||
MM_RF_PROTO_FS_AFHDS2A,
|
||||
MM_RF_PROTO_Q2X2,
|
||||
MM_RF_PROTO_WK_2X01,
|
||||
MM_RF_PROTO_Q303,
|
||||
MM_RF_PROTO_GW008,
|
||||
MM_RF_PROTO_DM002,
|
||||
MM_RF_PROTO_CABELL,
|
||||
MM_RF_PROTO_ESKY150,
|
||||
MM_RF_PROTO_H83D,
|
||||
MM_RF_PROTO_CORONA,
|
||||
MM_RF_PROTO_CFLIE,
|
||||
MM_RF_PROTO_HITEC,
|
||||
MM_RF_PROTO_WFLY,
|
||||
MM_RF_PROTO_BUGS,
|
||||
MM_RF_PROTO_BUGS_MINI,
|
||||
MM_RF_PROTO_TRAXXAS,
|
||||
MM_RF_PROTO_NCC1701,
|
||||
MM_RF_PROTO_E01X,
|
||||
MM_RF_PROTO_V911S,
|
||||
MM_RF_PROTO_GD00X,
|
||||
MM_RF_PROTO_LAST = MM_RF_PROTO_GD00X
|
||||
};
|
||||
|
||||
enum TrainerProtocol {
|
||||
TRAINER_MASTER_JACK,
|
||||
TRAINER_SLAVE_JACK,
|
||||
TRAINER_MASTER_SBUS_MODULE,
|
||||
TRAINER_MASTER_CPPM_MODULE,
|
||||
TRAINER_MASTER_SBUS_BATT_COMPARTMENT
|
||||
};
|
||||
|
||||
enum R9MSubTypes {
|
||||
MODULE_SUBTYPE_R9M_FCC,
|
||||
MODULE_SUBTYPE_R9M_EU,
|
||||
MODULE_SUBTYPE_R9M_EUPLUS,
|
||||
MODULE_SUBTYPE_R9M_AUPLUS,
|
||||
MODULE_SUBTYPE_R9M_LAST=MODULE_SUBTYPE_R9M_AUPLUS
|
||||
};
|
||||
|
||||
class ModuleData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ModuleData)
|
||||
|
||||
public:
|
||||
ModuleData() { clear(); }
|
||||
unsigned int modelId;
|
||||
int protocol;
|
||||
unsigned int subType;
|
||||
bool invertedSerial;
|
||||
unsigned int channelsStart;
|
||||
int channelsCount; // 0=8 channels
|
||||
unsigned int failsafeMode;
|
||||
int failsafeChannels[CPN_MAX_CHNOUT];
|
||||
|
||||
|
||||
struct {
|
||||
int delay;
|
||||
bool pulsePol; // false = positive
|
||||
bool outputType; // false = open drain, true = push pull
|
||||
int frameLength;
|
||||
} ppm;
|
||||
|
||||
struct {
|
||||
unsigned int rfProtocol;
|
||||
bool autoBindMode;
|
||||
bool lowPowerMode;
|
||||
bool customProto;
|
||||
int optionValue;
|
||||
} multi;
|
||||
|
||||
struct {
|
||||
int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
|
||||
bool receiver_telem_off; // false = receiver telem enabled
|
||||
bool receiver_channel_9_16; // false = pwm out 1-8, true 9-16
|
||||
bool external_antenna; // false = internal antenna, true = external antenna
|
||||
bool sport_out;
|
||||
} pxx;
|
||||
|
||||
|
||||
void clear() { memset(this, 0, sizeof(ModuleData)); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
QString polarityToString() const { return ppm.pulsePol ? tr("Positive") : tr("Negative"); }
|
||||
QString rfProtocolToString() const;
|
||||
QString subTypeToString(int type = -1) const;
|
||||
QString powerValueToString(Firmware * fw) const;
|
||||
static QString indexToString(int index, Firmware * fw);
|
||||
static QString protocolToString(unsigned protocol);
|
||||
static QStringList powerValueStrings(int subType, Firmware * fw);
|
||||
};
|
||||
|
||||
#endif // MODULEDATA_H
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "multiprotocols.h"
|
||||
#include "radiodata.h"
|
||||
|
||||
#define STR_MULTI_SUBTYPE QT_TRANSLATE_NOOP("Multiprotocols", "Subtype")
|
||||
#define STR_MULTI_VIDFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Video TX frequency")
|
||||
#define STR_MULTI_RFTUNE QT_TRANSLATE_NOOP("Multiprotocols", "CC2500 frequency fine tune")
|
||||
#define STR_MULTI_TELEMETRY QT_TRANSLATE_NOOP("Multiprotocols", "Telemetry")
|
||||
#define STR_MULTI_RFPOWER QT_TRANSLATE_NOOP("Multiprotocols", "Radio output power")
|
||||
#define STR_MULTI_SERVOFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Servo output frequency")
|
||||
#define STR_MULTI_OPTION QT_TRANSLATE_NOOP("Multiprotocols", "Option value")
|
||||
#define STR_MULTI_DEFAULT QT_TRANSLATE_NOOP("Multiprotocols", "DEFAULT")
|
||||
|
||||
static const QStringList STR_SUBTYPE_CUSTOM ({
|
||||
STR_MULTI_SUBTYPE " 0", STR_MULTI_SUBTYPE " 1", STR_MULTI_SUBTYPE " 2", STR_MULTI_SUBTYPE " 3",
|
||||
STR_MULTI_SUBTYPE " 4", STR_MULTI_SUBTYPE " 5", STR_MULTI_SUBTYPE " 6", STR_MULTI_SUBTYPE " 7"
|
||||
});
|
||||
static const QStringList STR_SUBTYPE_FLYSKY {"Standard", "V9x9", "V6x6", "V912", "CX20"};
|
||||
static const QStringList STR_SUBTYPE_HUBSAN {"H107", "H301", "H501"};
|
||||
static const QStringList STR_SUBTYPE_FRSKY {"D16", "D8", "D16 8ch", "V8", "D16 EU-LBT", "D16 EU-LBT 8ch"};
|
||||
static const QStringList STR_SUBTYPE_HISKY {"Standard", "HK310"};
|
||||
static const QStringList STR_SUBTYPE_V2X2 {"Standard", "JXD506"};
|
||||
static const QStringList STR_SUBTYPE_DSM {"DSM2 22ms", "DSM2 11ms", "DSMX 22ms", "DSMX 11ms"};
|
||||
static const QStringList STR_SUBTYPE_YD717 {"Standard", "Skywalker", "Syma X4", "XINXUN", "NIHUI"};
|
||||
static const QStringList STR_SUBTYPE_KN {"WLtoys", "FeiLun"};
|
||||
static const QStringList STR_SUBTYPE_SYMAX {"Standard", "Syma X5C"};
|
||||
static const QStringList STR_SUBTYPE_SLT {"V1 (6 Channel)", "V2 (8 Channel)", "Q100", "Q200", "MR100"};
|
||||
static const QStringList STR_SUBTYPE_CX10 {"Green", "Blue", "DM007", "-", "JC3015a", "JC3015b", "MK33041"};
|
||||
static const QStringList STR_SUBTYPE_CG023 {"Standard", "YD829"};
|
||||
static const QStringList STR_SUBTYPE_BAYANG {"Standard", "H8S3D", "X16 AH", "IRDRONE"};
|
||||
static const QStringList STR_SUBTYPE_MT99 {"MT99", "H7", "YZ", "LS", "FY805"};
|
||||
static const QStringList STR_SUBTYPE_MJXQ {"WLH08", "X600", "X800", "H26D", "E010", "H26WH"};
|
||||
static const QStringList STR_SUBTYPE_FY326 {"Standard", "FY319"};
|
||||
static const QStringList STR_SUBTYPE_HONTAI {"Standard", "JJRC X1", "X5C1 Clone", "FQ777_951"};
|
||||
static const QStringList STR_SUBTYPE_AFHDS2A {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS"};
|
||||
static const QStringList STR_SUBTYPE_Q2X2 {"Q222", "Q242", "Q282"};
|
||||
static const QStringList STR_SUBTYPE_WK2x01 {"WK2801", "WK2401", "W6_5_1", "W6_6_1", "W6_HEL", "W6_HEL_I"};
|
||||
static const QStringList STR_SUBTYPE_Q303 {"Standard", "CX35", "CX10D", "CX10WD"};
|
||||
static const QStringList STR_SUBTYPE_CABELL {"Cabell V3", "Cab V3 Telem", "-", "-", "-", "-", "Set FailSafe", "Unbind"};
|
||||
static const QStringList STR_SUBTYPE_H83D {"H8 Mini 3D", "H20H", "H20 Mini", "H30 Mini"};
|
||||
static const QStringList STR_SUBTYPE_CORONA {"V1", "V2", "Flydream V3"};
|
||||
static const QStringList STR_SUBTYPE_HITEC {"Optima", "Optima Hub Telem", "Minima"};
|
||||
static const QStringList STR_SUBTYPE_E01X {"E012", "E015"};
|
||||
|
||||
static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
|
||||
|
||||
|
||||
// Table is designed to be shared with gui_common_arm.cpp
|
||||
|
||||
const Multiprotocols multiProtocols {
|
||||
{MM_RF_PROTO_FLYSKY, 4, false, STR_SUBTYPE_FLYSKY, nullptr},
|
||||
{MM_RF_PROTO_HUBSAN, 2, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ},
|
||||
{MM_RF_PROTO_FRSKY, 5, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE},
|
||||
{MM_RF_PROTO_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr},
|
||||
{MM_RF_PROTO_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr},
|
||||
{MM_RF_PROTO_DSM2, 3, false, STR_SUBTYPE_DSM, nullptr},
|
||||
{MM_RF_PROTO_YD717, 4, false, STR_SUBTYPE_YD717, nullptr},
|
||||
{MM_RF_PROTO_KN, 1, false, STR_SUBTYPE_KN, nullptr},
|
||||
{MM_RF_PROTO_SYMAX, 1, false, STR_SUBTYPE_SYMAX, nullptr},
|
||||
{MM_RF_PROTO_SLT, 4, false, STR_SUBTYPE_SLT, nullptr},
|
||||
{MM_RF_PROTO_CX10, 6, false, STR_SUBTYPE_CX10, nullptr},
|
||||
{MM_RF_PROTO_CG023, 1, false, STR_SUBTYPE_CG023, nullptr},
|
||||
{MM_RF_PROTO_BAYANG, 3, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
|
||||
{MM_RF_PROTO_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MM_RF_PROTO_MJXQ, 5, false, STR_SUBTYPE_MJXQ, nullptr},
|
||||
{MM_RF_PROTO_FY326, 1, false, STR_SUBTYPE_FY326, nullptr},
|
||||
{MM_RF_PROTO_SFHSS, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MM_RF_PROTO_HONTAI, 3, false, STR_SUBTYPE_HONTAI, nullptr},
|
||||
{MM_RF_PROTO_OLRS, 0, false, NO_SUBTYPE, STR_MULTI_RFPOWER},
|
||||
{MM_RF_PROTO_FS_AFHDS2A, 3, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ},
|
||||
{MM_RF_PROTO_Q2X2, 2, false, STR_SUBTYPE_Q2X2, nullptr},
|
||||
{MM_RF_PROTO_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr},
|
||||
{MM_RF_PROTO_Q303, 3, false, STR_SUBTYPE_Q303, nullptr},
|
||||
{MM_RF_PROTO_CABELL, 7, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION},
|
||||
{MM_RF_PROTO_H83D, 3, false, STR_SUBTYPE_H83D, nullptr},
|
||||
{MM_RF_PROTO_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
|
||||
{MM_RF_PROTO_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE},
|
||||
{MM_RF_PROTO_E01X, 1, false, STR_SUBTYPE_E01X, nullptr},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION},
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
{ 0xfe, 0, false, NO_SUBTYPE, nullptr}
|
||||
};
|
||||
|
||||
int Multiprotocols::MultiProtocolDefinition::getOptionMin() const {
|
||||
if (optionsstr == STR_MULTI_RFPOWER)
|
||||
return -1;
|
||||
else if (optionsstr == STR_MULTI_SERVOFREQ)
|
||||
return 0;
|
||||
else
|
||||
return -128;
|
||||
}
|
||||
|
||||
int Multiprotocols::MultiProtocolDefinition::getOptionMax() const {
|
||||
if (optionsstr == STR_MULTI_RFPOWER)
|
||||
return 7;
|
||||
else if (optionsstr == STR_MULTI_SERVOFREQ)
|
||||
return 70;
|
||||
else
|
||||
return 127;
|
||||
}
|
||||
|
||||
const Multiprotocols::MultiProtocolDefinition & Multiprotocols::getProtocol(int protocol) const {
|
||||
for (const Multiprotocols::MultiProtocolDefinition & proto: protocols)
|
||||
if (proto.protocol == protocol)
|
||||
return proto;
|
||||
|
||||
// Protocol not found, return the default (last) proto
|
||||
Q_ASSERT(protocols.rbegin()->protocol == 0xfe);
|
||||
return *protocols.rbegin();
|
||||
}
|
||||
|
||||
// static
|
||||
QString Multiprotocols::protocolToString(int protocol, bool custom)
|
||||
{
|
||||
static const QStringList strings({
|
||||
"FlySky", "Hubsan", "FrSky", "Hisky", "V2x2", "DSM", "Devo", "YD717", "KN", "SymaX", "SLT", "CX10", "CG023",
|
||||
"Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","Open LRS",
|
||||
"FlySky AFHDS2A", "Q2x2", "Walkera", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie",
|
||||
"Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "V911S", "GD00X"
|
||||
});
|
||||
|
||||
if (protocol == MM_RF_CUSTOM_SELECTED || custom)
|
||||
return tr("Custom - proto %1)").arg(protocol);
|
||||
else
|
||||
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
// static
|
||||
QString Multiprotocols::subTypeToString(int protocol, unsigned subType)
|
||||
{
|
||||
return tr(qPrintable(multiProtocols.getProtocol(protocol).subTypeStrings.value(subType, CPN_STR_UNKNOWN_ITEM)));
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OPENTX_MULTI_H
|
||||
#define OPENTX_MULTI_H
|
||||
|
||||
#include <vector>
|
||||
#include <QtCore>
|
||||
|
||||
#define MM_RF_CUSTOM_SELECTED 0xff
|
||||
|
||||
class Multiprotocols
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Multiprotocols)
|
||||
|
||||
public:
|
||||
|
||||
struct radio_mm_definition {
|
||||
int protocol;
|
||||
unsigned int maxSubtype;
|
||||
bool hasFailsafe;
|
||||
QStringList protocols;
|
||||
QString optionsstr;
|
||||
};
|
||||
|
||||
struct MultiProtocolDefinition {
|
||||
const int protocol;
|
||||
const bool hasFailsafe;
|
||||
const QStringList subTypeStrings;
|
||||
const QString optionsstr;
|
||||
|
||||
unsigned int numSubTypes() const
|
||||
{
|
||||
return (unsigned int) subTypeStrings.length();
|
||||
}
|
||||
|
||||
int getOptionMin() const;
|
||||
|
||||
int getOptionMax() const;
|
||||
|
||||
MultiProtocolDefinition(const radio_mm_definition &rd) :
|
||||
protocol(rd.protocol),
|
||||
hasFailsafe(rd.hasFailsafe),
|
||||
subTypeStrings(rd.protocols),
|
||||
optionsstr(rd.optionsstr)
|
||||
{
|
||||
Q_ASSERT(rd.maxSubtype + 1 == (unsigned int) rd.protocols.length());
|
||||
}
|
||||
};
|
||||
|
||||
Multiprotocols(std::initializer_list<radio_mm_definition> l)
|
||||
{
|
||||
for (radio_mm_definition rd: l)
|
||||
protocols.push_back(MultiProtocolDefinition(rd));
|
||||
}
|
||||
|
||||
const MultiProtocolDefinition &getProtocol(int protocol) const;
|
||||
static QString protocolToString(int protocol, bool custom = false);
|
||||
static QString subTypeToString(int protocol, unsigned subType);
|
||||
|
||||
private:
|
||||
|
||||
std::vector<MultiProtocolDefinition> protocols;
|
||||
|
||||
};
|
||||
|
||||
extern const Multiprotocols multiProtocols;
|
||||
|
||||
#endif //OPENTX_MULTI_H
|
||||
@@ -1,838 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
#include "helpers.h"
|
||||
#include "open9xGruvin9xeeprom.h"
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
|
||||
extern void getEEPROMZString(char *dst, const char *src, int size);
|
||||
extern RawSwitch open9xStockToSwitch(int8_t sw);
|
||||
|
||||
t_Open9xGruvin9xFlightModeData_v207::operator FlightModeData ()
|
||||
{
|
||||
FlightModeData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
c9x.trim[i] = (((int16_t)trim[i]) << 2) + ((trim_ext >> (2*i)) & 0x03);
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.fadeIn = fadeIn;
|
||||
c9x.fadeOut = fadeOut;
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.rotaryEncoders[i] = rotaryEncoders[i];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xFlightModeData_v208::operator FlightModeData ()
|
||||
{
|
||||
FlightModeData c9x;
|
||||
for (int i=0; i<NUM_STICKS; i++)
|
||||
c9x.trim[i] = trim[i];
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
c9x.fadeIn = fadeIn;
|
||||
c9x.fadeOut = fadeOut;
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.rotaryEncoders[i] = rotaryEncoders[i];
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xMixData_v207::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
if (srcRaw) {
|
||||
c9x.destCh = destCh+1;
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw <= 9) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_ROTARY_ENCODER, srcRaw-8);
|
||||
}
|
||||
else if (srcRaw == 10) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
/* else if (srcRaw == 11) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_3POS);
|
||||
} */
|
||||
else if (srcRaw <= 32) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, srcRaw-11);
|
||||
}
|
||||
else if (srcRaw <= 35) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-33);
|
||||
}
|
||||
else if (srcRaw <= 43) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-36);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-44);
|
||||
}
|
||||
c9x.weight = weight;
|
||||
|
||||
if (differential) {
|
||||
c9x.curve = CurveReference(CurveReference::CURVE_REF_DIFF, differential*2);
|
||||
}
|
||||
else {
|
||||
// TODO c9x.curve = curve;
|
||||
}
|
||||
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
|
||||
if (phase<0) {
|
||||
c9x.flightModes= 1 << (-phase -1);
|
||||
}
|
||||
else if (phase==0) {
|
||||
c9x.flightModes=0;
|
||||
}
|
||||
else {
|
||||
c9x.flightModes=63;
|
||||
c9x.flightModes &= ~(1 << (phase -1));
|
||||
}
|
||||
c9x.sOffset = sOffset;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xMixData_v209::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
if (srcRaw) {
|
||||
c9x.destCh = destCh+1;
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw <= 9) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_ROTARY_ENCODER, srcRaw-8);
|
||||
}
|
||||
else if (srcRaw <= 13) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_TRIM, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw == 14) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 15) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0);
|
||||
}
|
||||
else if (srcRaw <= 36) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, srcRaw-15);
|
||||
}
|
||||
else if (srcRaw <= 39) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-37);
|
||||
}
|
||||
else if (srcRaw <= 47) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-40);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-48);
|
||||
}
|
||||
c9x.weight = weight;
|
||||
|
||||
if (differential) {
|
||||
c9x.curve = CurveReference(CurveReference::CURVE_REF_DIFF, differential*2);
|
||||
}
|
||||
else {
|
||||
// TODO c9x.curve = curve;
|
||||
}
|
||||
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
|
||||
if (phase<0) {
|
||||
c9x.flightModes= 1 << (-phase -1);
|
||||
}
|
||||
else if (phase==0) {
|
||||
c9x.flightModes=0;
|
||||
}
|
||||
else {
|
||||
c9x.flightModes=63;
|
||||
c9x.flightModes &= ~(1 << (phase -1));
|
||||
}
|
||||
c9x.sOffset = sOffset;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xMixData_v211::operator MixData ()
|
||||
{
|
||||
MixData c9x;
|
||||
if (srcRaw) {
|
||||
c9x.destCh = destCh+1;
|
||||
if (srcRaw == 0) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (srcRaw <= 7) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_STICK, srcRaw-1);
|
||||
}
|
||||
else if (srcRaw <= 9) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_ROTARY_ENCODER, srcRaw-8);
|
||||
}
|
||||
else if (srcRaw <= 13) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_TRIM, srcRaw-10);
|
||||
}
|
||||
else if (srcRaw == 14) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
else if (srcRaw == 15) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, 0);
|
||||
}
|
||||
else if (srcRaw <= 36) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_SWITCH, srcRaw-15);
|
||||
}
|
||||
else if (srcRaw <= 39) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CYC, srcRaw-37);
|
||||
}
|
||||
else if (srcRaw <= 47) {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_PPM, srcRaw-40);
|
||||
}
|
||||
else {
|
||||
c9x.srcRaw = RawSource(SOURCE_TYPE_CH, srcRaw-48);
|
||||
}
|
||||
c9x.weight = weight;
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
|
||||
if (curveMode==0) {
|
||||
c9x.curve = CurveReference(CurveReference::CURVE_REF_DIFF, curveParam);
|
||||
}
|
||||
else {
|
||||
// TODO c9x.curve = curve;
|
||||
}
|
||||
|
||||
c9x.delayUp = delayUp;
|
||||
c9x.delayDown = delayDown;
|
||||
c9x.speedUp = speedUp;
|
||||
c9x.speedDown = speedDown;
|
||||
c9x.carryTrim = carryTrim;
|
||||
c9x.noExpo = noExpo;
|
||||
c9x.mltpx = (MltpxValue)mltpx;
|
||||
c9x.mixWarn = mixWarn;
|
||||
c9x.flightModes = phases;
|
||||
c9x.sOffset = sOffset;
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
RawSource open9xV4207ToSource(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value <= 9) {
|
||||
return RawSource(SOURCE_TYPE_ROTARY_ENCODER, value - 8);
|
||||
}
|
||||
else if (value == 10) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
/* else if (value == 11) {
|
||||
return RawSource(SOURCE_TYPE_3POS);
|
||||
} */
|
||||
else if (value <= 14) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-12);
|
||||
}
|
||||
else if (value <= 22) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-15);
|
||||
}
|
||||
else if (value <= 38) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-23);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-38);
|
||||
}
|
||||
}
|
||||
|
||||
RawSource open9xV4209ToSource(int8_t value)
|
||||
{
|
||||
if (value == 0) {
|
||||
return RawSource(SOURCE_TYPE_NONE);
|
||||
}
|
||||
else if (value <= 7) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 1);
|
||||
}
|
||||
else if (value <= 9) {
|
||||
return RawSource(SOURCE_TYPE_ROTARY_ENCODER, value - 8);
|
||||
}
|
||||
else if (value <= 13) {
|
||||
return RawSource(SOURCE_TYPE_STICK, value - 10);
|
||||
}
|
||||
else if (value == 14) {
|
||||
return RawSource(SOURCE_TYPE_MAX);
|
||||
}
|
||||
/* else if (value == 15) {
|
||||
return RawSource(SOURCE_TYPE_3POS);
|
||||
} */
|
||||
else if (value <= 18) {
|
||||
return RawSource(SOURCE_TYPE_CYC, value-16);
|
||||
}
|
||||
else if (value <= 26) {
|
||||
return RawSource(SOURCE_TYPE_PPM, value-19);
|
||||
}
|
||||
else if (value <= 42) {
|
||||
return RawSource(SOURCE_TYPE_CH, value-27);
|
||||
}
|
||||
else {
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, value-42);
|
||||
}
|
||||
}
|
||||
|
||||
Open9xGruvin9xLogicalSwitchData_v207::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = open9xV4207ToSource(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val2 = open9xV4207ToSource(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = open9xStockToSwitch(v1).toValue();
|
||||
c9x.val2 = open9xStockToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
Open9xGruvin9xLogicalSwitchData_v209::operator LogicalSwitchData ()
|
||||
{
|
||||
LogicalSwitchData c9x;
|
||||
c9x.func = func;
|
||||
c9x.val1 = v1;
|
||||
c9x.val2 = v2;
|
||||
|
||||
if ((c9x.func >= LS_FN_VPOS && c9x.func <= LS_FN_ANEG) || c9x.func >= LS_FN_EQUAL) {
|
||||
c9x.val1 = open9xV4209ToSource(v1).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_EQUAL && c9x.func <= LS_FN_ELESS) {
|
||||
c9x.val2 = open9xV4209ToSource(v2).toValue();
|
||||
}
|
||||
|
||||
if (c9x.func >= LS_FN_AND && c9x.func <= LS_FN_XOR) {
|
||||
c9x.val1 = open9xStockToSwitch(v1).toValue();
|
||||
c9x.val2 = open9xStockToSwitch(v2).toValue();
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xCustomFunctionData_v203::operator CustomFunctionData ()
|
||||
{
|
||||
CustomFunctionData c9x;
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
if (func < 16) {
|
||||
c9x.func = (AssignFunc)(func);
|
||||
c9x.enabled=param & 0x01;
|
||||
c9x.param = (param>>1)<<1;
|
||||
}
|
||||
else {
|
||||
c9x.param = param;
|
||||
if (func <= 20)
|
||||
c9x.func = (AssignFunc)(func);
|
||||
else if (func == 21)
|
||||
c9x.func = FuncInstantTrim;
|
||||
else if (func == 22)
|
||||
c9x.func = FuncPlaySound;
|
||||
else if (func == 23)
|
||||
c9x.func = FuncPlayHaptic;
|
||||
else if (func == 24)
|
||||
c9x.func = FuncReset;
|
||||
else if (func == 25)
|
||||
c9x.func = FuncVario;
|
||||
else if (func == 26)
|
||||
c9x.func = FuncPlayPrompt;
|
||||
else if (func == 27)
|
||||
c9x.func = FuncPlayValue;
|
||||
else if (func == 28)
|
||||
c9x.func = FuncLogs;
|
||||
else if (func == 29)
|
||||
c9x.func = FuncBacklight;
|
||||
else if (func >= 30 && func <= 34)
|
||||
c9x.func = AssignFunc(FuncAdjustGV1 + func - 30);
|
||||
else
|
||||
c9x.clear();
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xCustomFunctionData_v210::operator CustomFunctionData ()
|
||||
{
|
||||
CustomFunctionData c9x;
|
||||
c9x.swtch = open9xStockToSwitch(swtch);
|
||||
c9x.param = param;
|
||||
if (func < 22) {
|
||||
c9x.func = (AssignFunc)(func);
|
||||
c9x.enabled = delay;
|
||||
} else {
|
||||
if (func == 22)
|
||||
c9x.func = FuncPlaySound;
|
||||
else if (func == 23)
|
||||
c9x.func = FuncPlayHaptic;
|
||||
else if (func == 24)
|
||||
c9x.func = FuncReset;
|
||||
else if (func == 25)
|
||||
c9x.func = FuncVario;
|
||||
else if (func == 26)
|
||||
c9x.func = FuncPlayPrompt;
|
||||
else if (func == 27)
|
||||
c9x.func = FuncPlayValue;
|
||||
else if (func == 28)
|
||||
c9x.func = FuncLogs;
|
||||
else
|
||||
c9x.clear();
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xSwashRingData_v208::operator SwashRingData ()
|
||||
{
|
||||
SwashRingData c9x;
|
||||
c9x.elevatorWeight = invertELE ? -100 : 100;
|
||||
c9x.aileronWeight = invertAIL ? -100 : 100;
|
||||
c9x.collectiveWeight = invertCOL ? -100 : 100;
|
||||
c9x.type = type;
|
||||
c9x.collectiveSource = open9xV4207ToSource(collectiveSource);
|
||||
c9x.value = value;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xSwashRingData_v209::operator SwashRingData ()
|
||||
{
|
||||
SwashRingData c9x;
|
||||
c9x.elevatorWeight = invertELE ? -100 : 100;
|
||||
c9x.aileronWeight = invertAIL ? -100 : 100;
|
||||
c9x.collectiveWeight = invertCOL ? -100 : 100;
|
||||
c9x.type = type;
|
||||
c9x.collectiveSource = open9xV4209ToSource(collectiveSource);
|
||||
c9x.value = value;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xModelData_v207::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.timers[i] = timers[i];
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<5; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<32; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<14; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[8 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[8 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[8 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<12; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
c9x.moduleData[0].ppm.frameLength = ppmFrameLength;
|
||||
c9x.thrTraceSrc = thrTraceSrc;
|
||||
c9x.moduleData[0].modelId = modelId;
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xModelData_v208::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.timers[i] = timers[i];
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_PPMSIM;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.disableThrottleWarning=disableThrottleWarning;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<5; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<32; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<14; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[8 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[8 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[8 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<12; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
c9x.frsky.varioSource = varioSource;
|
||||
c9x.frsky.varioCenterMax = varioSpeedUpMin;
|
||||
c9x.frsky.varioCenterMin = varioSpeedDownMin;
|
||||
c9x.moduleData[0].ppm.frameLength = ppmFrameLength;
|
||||
c9x.thrTraceSrc = thrTraceSrc;
|
||||
c9x.moduleData[0].modelId = modelId;
|
||||
for (int i=0; i<16; i++) {
|
||||
c9x.limitData[i].ppmCenter = servoCenter[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xModelData_v209::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.timers[i] = timers[i];
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_PPMSIM;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.disableThrottleWarning=disableThrottleWarning;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<5; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<32; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<14; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[i].count = 5;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
c9x.curves[i].points[j].x = -100 + 50 * i;
|
||||
c9x.curves[i].points[j].y = curves5[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<8; i++) {
|
||||
c9x.curves[8 + i].count = 9;
|
||||
for (int j = 0; j < 9; j++) {
|
||||
c9x.curves[8 + i].points[j].x = -100 + 25 * i;
|
||||
c9x.curves[8 + i].points[j].y = curves9[i][j];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<12; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
c9x.frsky.varioSource = varioSource;
|
||||
c9x.frsky.varioCenterMax = varioSpeedUpMin;
|
||||
c9x.frsky.varioCenterMin = varioSpeedDownMin;
|
||||
c9x.switchWarningStates = switchWarningStates;
|
||||
c9x.moduleData[0].ppm.frameLength = ppmFrameLength;
|
||||
c9x.thrTraceSrc = thrTraceSrc;
|
||||
c9x.moduleData[0].modelId = modelId;
|
||||
for (int i=0; i<16; i++) {
|
||||
c9x.limitData[i].ppmCenter = servoCenter[i];
|
||||
}
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xModelData_v210::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++)
|
||||
c9x.timers[i] = timers[i];
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_PPMSIM;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.disableThrottleWarning=disableThrottleWarning;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<5; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<32; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<14; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
for (int i=0; i<8; i++) {
|
||||
CurveInfo crvinfo = curveinfo(this, i);
|
||||
c9x.curves[i].type = (crvinfo.custom ? CurveData::CURVE_TYPE_CUSTOM : CurveData::CURVE_TYPE_STANDARD);
|
||||
c9x.curves[i].count = crvinfo.points;
|
||||
for (int j=0; j<crvinfo.points; j++)
|
||||
c9x.curves[i].points[j].y = crvinfo.crv[j];
|
||||
if (crvinfo.custom) {
|
||||
c9x.curves[i].points[0].x = -100;
|
||||
for (int j=1; j<crvinfo.points-1; j++)
|
||||
c9x.curves[i].points[j].x = crvinfo.crv[crvinfo.points+j-1];
|
||||
c9x.curves[i].points[crvinfo.points-1].x = +100;
|
||||
}
|
||||
else {
|
||||
for (int j=0; j<crvinfo.points; j++)
|
||||
c9x.curves[i].points[j].x = -100 + (200*i) / (crvinfo.points-1);
|
||||
}
|
||||
}
|
||||
for (int i=0; i<12; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
c9x.switchWarningStates = switchWarningStates;
|
||||
c9x.moduleData[0].ppm.frameLength = ppmFrameLength;
|
||||
c9x.thrTraceSrc = thrTraceSrc;
|
||||
c9x.moduleData[0].modelId = modelId;
|
||||
for (int i=0; i<16; i++) {
|
||||
c9x.limitData[i].ppmCenter = servoCenter[i];
|
||||
}
|
||||
|
||||
return c9x;
|
||||
}
|
||||
|
||||
t_Open9xGruvin9xModelData_v211::operator ModelData ()
|
||||
{
|
||||
ModelData c9x;
|
||||
c9x.used = true;
|
||||
getEEPROMZString(c9x.name, name, sizeof(name));
|
||||
for (int i=0; i<2; i++) {
|
||||
c9x.timers[i] = timers[i];
|
||||
c9x.timers[i].persistent = timersXtra[i].remanent;
|
||||
c9x.timers[i].val = timersXtra[i].value;
|
||||
}
|
||||
switch(protocol) {
|
||||
case 1:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM16;
|
||||
break;
|
||||
case 2:
|
||||
c9x.moduleData[0].protocol = PULSES_PPMSIM;
|
||||
break;
|
||||
case 3:
|
||||
c9x.moduleData[0].protocol = PULSES_PXX_DJT;
|
||||
break;
|
||||
case 4:
|
||||
c9x.moduleData[0].protocol = PULSES_DSM2;
|
||||
break;
|
||||
default:
|
||||
c9x.moduleData[0].protocol = PULSES_PPM;
|
||||
break;
|
||||
}
|
||||
c9x.moduleData[0].channelsCount = 8 + (2 * ppmNCH);
|
||||
c9x.thrTrim = thrTrim;
|
||||
c9x.trimInc = trimInc - 2;
|
||||
c9x.disableThrottleWarning=disableThrottleWarning;
|
||||
c9x.moduleData[0].ppm.delay = 300 + 50 * ppmDelay;
|
||||
c9x.beepANACenter = beepANACenter;
|
||||
c9x.moduleData[0].ppm.pulsePol = pulsePol;
|
||||
c9x.extendedLimits = extendedLimits;
|
||||
c9x.extendedTrims = extendedTrims;
|
||||
for (int i=0; i<5; i++) {
|
||||
c9x.flightModeData[i] = flightModeData[i];
|
||||
for (int j=0; j<NUM_STICKS; j++) {
|
||||
if (c9x.flightModeData[i].trim[j] > 500) {
|
||||
c9x.flightModeData[i].trimRef[j] = c9x.flightModeData[i].trim[j] - 501;
|
||||
if (c9x.flightModeData[i].trimRef[j] >= i)
|
||||
c9x.flightModeData[i].trimRef[j] += 1;
|
||||
c9x.flightModeData[i].trim[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0; i<32; i++)
|
||||
c9x.mixData[i] = mixData[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.limitData[i] = limitData[i];
|
||||
for (int i=0; i<14; i++)
|
||||
c9x.expoData[i] = expoData[i];
|
||||
for (int i=0; i<8; i++) {
|
||||
CurveInfo crvinfo = curveinfo(this, i);
|
||||
c9x.curves[i].type = (crvinfo.custom ? CurveData::CURVE_TYPE_CUSTOM : CurveData::CURVE_TYPE_STANDARD);
|
||||
c9x.curves[i].count = crvinfo.points;
|
||||
for (int j=0; j<crvinfo.points; j++)
|
||||
c9x.curves[i].points[j].y = crvinfo.crv[j];
|
||||
if (crvinfo.custom) {
|
||||
c9x.curves[i].points[0].x = -100;
|
||||
for (int j=1; j<crvinfo.points-1; j++)
|
||||
c9x.curves[i].points[j].x = crvinfo.crv[crvinfo.points+j-1];
|
||||
c9x.curves[i].points[crvinfo.points-1].x = +100;
|
||||
}
|
||||
else {
|
||||
for (int j=0; j<crvinfo.points; j++)
|
||||
c9x.curves[i].points[j].x = -100 + (200*i) / (crvinfo.points-1);
|
||||
}
|
||||
}
|
||||
for (int i=0; i<12; i++)
|
||||
c9x.logicalSw[i] = logicalSw[i];
|
||||
for (int i=0; i<16; i++)
|
||||
c9x.customFn[i] = customFn[i];
|
||||
c9x.swashRingData = swashR;
|
||||
c9x.frsky = frsky;
|
||||
c9x.switchWarningStates = switchWarningStates;
|
||||
c9x.moduleData[0].ppm.frameLength = ppmFrameLength;
|
||||
c9x.thrTraceSrc = thrTraceSrc;
|
||||
c9x.moduleData[0].modelId = modelId;
|
||||
return c9x;
|
||||
}
|
||||
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef open9xGruvin9xeeprom_h
|
||||
#define open9xGruvin9xeeprom_h
|
||||
|
||||
#define O9X_V4_MAX_CSFUNCOLD 13
|
||||
#define O9X_V4_MAX_CSFUNC 15
|
||||
|
||||
#include "open9xStockeeprom.h"
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xFlightModeData_v207 {
|
||||
int8_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of phases 1|2|3|4 instead
|
||||
int8_t trim_ext:8; // 2 less significant extra bits per trim (10bits trims)
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
int16_t rotaryEncoders[2];
|
||||
operator FlightModeData();
|
||||
t_Open9xGruvin9xFlightModeData_v207() { memset(this, 0, sizeof(t_Open9xGruvin9xFlightModeData_v207)); }
|
||||
}) Open9xGruvin9xFlightModeData_v207;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xFlightModeData_v208 {
|
||||
int16_t trim[4]; // -500..500 => trim value, 501 => use trim of phase 0, 502, 503, 504 => use trim of phases 1|2|3|4 instead
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
int16_t rotaryEncoders[2];
|
||||
operator FlightModeData();
|
||||
t_Open9xGruvin9xFlightModeData_v208() { memset(this, 0, sizeof(t_Open9xGruvin9xFlightModeData_v208)); }
|
||||
}) Open9xGruvin9xFlightModeData_v208;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xMixData_v207 {
|
||||
uint8_t destCh:4; // 0, 1..C9X_NUM_CHNOUT
|
||||
int8_t phase:4; // -5=!FP4, 0=normal, 5=FP4
|
||||
int8_t weight;
|
||||
int8_t swtch:6;
|
||||
uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
int8_t curve:6;
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint16_t srcRaw:7; //
|
||||
uint16_t differential:7;
|
||||
uint16_t carryTrim:2;
|
||||
int8_t sOffset;
|
||||
|
||||
operator MixData();
|
||||
t_Open9xGruvin9xMixData_v207() { memset(this, 0, sizeof(t_Open9xGruvin9xMixData_v207)); }
|
||||
}) Open9xGruvin9xMixData_v207;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xMixData_v209 {
|
||||
uint8_t destCh:4; // 0, 1..C9X_NUM_CHNOUT
|
||||
int8_t phase:4; // -5=!FP4, 0=normal, 5=FP4
|
||||
int8_t weight;
|
||||
int8_t swtch:6;
|
||||
uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
int8_t curve:6;
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint16_t srcRaw:6; //
|
||||
int16_t differential:7;
|
||||
int16_t carryTrim:3;
|
||||
int8_t sOffset;
|
||||
|
||||
operator MixData();
|
||||
t_Open9xGruvin9xMixData_v209() { memset(this, 0, sizeof(t_Open9xGruvin9xMixData_v209)); }
|
||||
}) Open9xGruvin9xMixData_v209;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xMixData_v211 {
|
||||
uint8_t destCh:4; // 0, 1..C9X_NUM_CHNOUT
|
||||
uint8_t curveMode:1; // O=curve, 1=differential
|
||||
uint8_t noExpo:1;
|
||||
uint8_t spare:2;
|
||||
int8_t weight;
|
||||
int8_t swtch:6;
|
||||
uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
uint8_t phases:5;
|
||||
int8_t carryTrim:3;
|
||||
uint8_t srcRaw:6;
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4;
|
||||
uint8_t speedDown:4;
|
||||
int8_t curveParam;
|
||||
int8_t sOffset;
|
||||
|
||||
operator MixData();
|
||||
t_Open9xGruvin9xMixData_v211() { memset(this, 0, sizeof(t_Open9xGruvin9xMixData_v211)); }
|
||||
}) Open9xGruvin9xMixData_v211;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xLogicalSwitchData_v207 { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Open9xGruvin9xLogicalSwitchData_v207() { memset(this, 0, sizeof(t_Open9xGruvin9xLogicalSwitchData_v207)); }
|
||||
int8_t fromSource(RawSource source);
|
||||
RawSource toSource(int8_t value);
|
||||
}) Open9xGruvin9xLogicalSwitchData_v207;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xLogicalSwitchData_v209 { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
|
||||
operator LogicalSwitchData();
|
||||
t_Open9xGruvin9xLogicalSwitchData_v209() { memset(this, 0, sizeof(t_Open9xGruvin9xLogicalSwitchData_v209)); }
|
||||
int8_t fromSource(RawSource source);
|
||||
RawSource toSource(int8_t value);
|
||||
}) Open9xGruvin9xLogicalSwitchData_v209;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xCustomFunctionData_v203 { // Function Switches data
|
||||
int8_t swtch; // input
|
||||
uint8_t func;
|
||||
uint8_t param;
|
||||
|
||||
operator CustomFunctionData();
|
||||
t_Open9xGruvin9xCustomFunctionData_v203() { memset(this, 0, sizeof(t_Open9xGruvin9xCustomFunctionData_v203)); }
|
||||
}) Open9xGruvin9xCustomFunctionData_v203;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xCustomFunctionData_v210 { // Function Switches data
|
||||
int8_t swtch; // input
|
||||
uint8_t func:5;
|
||||
uint8_t delay:3;
|
||||
uint8_t param;
|
||||
|
||||
operator CustomFunctionData();
|
||||
t_Open9xGruvin9xCustomFunctionData_v210() { memset(this, 0, sizeof(t_Open9xGruvin9xCustomFunctionData_v210)); }
|
||||
}) Open9xGruvin9xCustomFunctionData_v210;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xSwashRingData_v208 { // Swash Ring data
|
||||
uint8_t invertELE:1;
|
||||
uint8_t invertAIL:1;
|
||||
uint8_t invertCOL:1;
|
||||
uint8_t type:5;
|
||||
uint8_t collectiveSource;
|
||||
uint8_t value;
|
||||
|
||||
operator SwashRingData();
|
||||
t_Open9xGruvin9xSwashRingData_v208() { memset(this, 0, sizeof(t_Open9xGruvin9xSwashRingData_v208)); }
|
||||
}) Open9xGruvin9xSwashRingData_v208;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xSwashRingData_v209 { // Swash Ring data
|
||||
uint8_t invertELE:1;
|
||||
uint8_t invertAIL:1;
|
||||
uint8_t invertCOL:1;
|
||||
uint8_t type:5;
|
||||
uint8_t collectiveSource;
|
||||
uint8_t value;
|
||||
|
||||
operator SwashRingData();
|
||||
t_Open9xGruvin9xSwashRingData_v209() { memset(this, 0, sizeof(t_Open9xGruvin9xSwashRingData_v209)); }
|
||||
}) Open9xGruvin9xSwashRingData_v209;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xModelData_v207 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Open9xTimerData_v202 timers[2];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t spare1:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint16_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Open9xGruvin9xMixData_v207 mixData[32];
|
||||
Open9xLimitData_v201 limitData[16];
|
||||
Open9xExpoData_v201 expoData[14];
|
||||
int8_t curves5[8][5];
|
||||
int8_t curves9[8][9];
|
||||
Open9xGruvin9xLogicalSwitchData_v207 logicalSw[12];
|
||||
Open9xCustomFunctionData_v203 customFn[16];
|
||||
Open9xGruvin9xSwashRingData_v208 swashR;
|
||||
Open9xGruvin9xFlightModeData_v207 flightModeData[5];
|
||||
Open9xFrSkyData_v205 frsky;
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
uint8_t frskyLines[4];
|
||||
uint16_t frskyLinesXtra;
|
||||
|
||||
operator ModelData();
|
||||
t_Open9xGruvin9xModelData_v207() { memset(this, 0, sizeof(t_Open9xGruvin9xModelData_v207)); }
|
||||
}) Open9xGruvin9xModelData_v207;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xModelData_v208 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Open9xTimerData_v202 timers[2];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint16_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Open9xGruvin9xMixData_v207 mixData[32];
|
||||
Open9xLimitData_v201 limitData[16];
|
||||
Open9xExpoData_v201 expoData[14];
|
||||
int8_t curves5[8][5];
|
||||
int8_t curves9[8][9];
|
||||
Open9xGruvin9xLogicalSwitchData_v207 logicalSw[12];
|
||||
Open9xGruvin9xCustomFunctionData_v203 customFn[16];
|
||||
Open9xGruvin9xSwashRingData_v208 swashR;
|
||||
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
|
||||
Open9xFrSkyData_v208 frsky;
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
uint8_t frskyLines[4];
|
||||
uint16_t frskyLinesXtra;
|
||||
int8_t servoCenter[16];
|
||||
|
||||
uint8_t varioSource:3;
|
||||
uint8_t varioSpeedUpMin:5; // if increment in 0.2m/s = 3.0m/s max
|
||||
uint8_t varioSpeedDownMin;
|
||||
|
||||
operator ModelData();
|
||||
t_Open9xGruvin9xModelData_v208() { memset(this, 0, sizeof(t_Open9xGruvin9xModelData_v208)); }
|
||||
}) Open9xGruvin9xModelData_v208;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xModelData_v209 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Open9xTimerData_v202 timers[2];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint16_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Open9xGruvin9xMixData_v209 mixData[32];
|
||||
Open9xLimitData_v201 limitData[16];
|
||||
Open9xExpoData_v201 expoData[14];
|
||||
int8_t curves5[8][5];
|
||||
int8_t curves9[8][9];
|
||||
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
|
||||
Open9xGruvin9xCustomFunctionData_v203 customFn[16];
|
||||
Open9xGruvin9xSwashRingData_v209 swashR;
|
||||
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
|
||||
Open9xFrSkyData_v208 frsky;
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
uint8_t frskyLines[4];
|
||||
uint16_t frskyLinesXtra;
|
||||
int8_t servoCenter[16];
|
||||
|
||||
uint8_t varioSource:3;
|
||||
uint8_t varioSpeedUpMin:5; // if increment in 0.2m/s = 3.0m/s max
|
||||
uint8_t varioSpeedDownMin;
|
||||
uint8_t switchWarningStates;
|
||||
|
||||
operator ModelData();
|
||||
t_Open9xGruvin9xModelData_v209() { memset(this, 0, sizeof(t_Open9xGruvin9xModelData_v209)); }
|
||||
}) Open9xGruvin9xModelData_v209;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xModelData_v210 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Open9xTimerData_v202 timers[2];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare2:1;
|
||||
int8_t ppmDelay;
|
||||
uint16_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Open9xGruvin9xMixData_v209 mixData[32];
|
||||
Open9xLimitData_v201 limitData[16];
|
||||
Open9xExpoData_v201 expoData[14];
|
||||
int8_t curves[8];
|
||||
int8_t points[112-8];
|
||||
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
|
||||
Open9xGruvin9xCustomFunctionData_v210 customFn[16];
|
||||
Open9xGruvin9xSwashRingData_v209 swashR;
|
||||
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
|
||||
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
|
||||
int8_t servoCenter[16];
|
||||
|
||||
uint8_t switchWarningStates;
|
||||
|
||||
Open9xFrSkyData_v210 frsky;
|
||||
|
||||
operator ModelData();
|
||||
t_Open9xGruvin9xModelData_v210() { memset(this, 0, sizeof(t_Open9xGruvin9xModelData_v210)); }
|
||||
}) Open9xGruvin9xModelData_v210;
|
||||
|
||||
PACK(typedef struct t_Open9xGruvin9xModelData_v211 {
|
||||
char name[10]; // 10 must be first for eeLoadModelName
|
||||
Open9xTimerData_v202 timers[2];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare1:1;
|
||||
int8_t ppmDelay;
|
||||
uint16_t beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
Open9xGruvin9xMixData_v211 mixData[32];
|
||||
Open9xLimitData_v211 limitData[16];
|
||||
Open9xExpoData_v211 expoData[14];
|
||||
int8_t curves[8];
|
||||
int8_t points[112-8];
|
||||
Open9xGruvin9xLogicalSwitchData_v209 logicalSw[12];
|
||||
Open9xGruvin9xCustomFunctionData_v210 customFn[16];
|
||||
Open9xGruvin9xSwashRingData_v209 swashR;
|
||||
Open9xGruvin9xFlightModeData_v208 flightModeData[5];
|
||||
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
uint8_t switchWarningStates;
|
||||
|
||||
Open9xFrSkyData_v210 frsky;
|
||||
Open9xTimerDataExtra timersXtra[2];
|
||||
|
||||
operator ModelData();
|
||||
t_Open9xGruvin9xModelData_v211() { memset(this, 0, sizeof(t_Open9xGruvin9xModelData_v211)); }
|
||||
}) Open9xGruvin9xModelData_v211;
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user