Compare commits
1016 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| af0c423359 | |||
| 45253e0008 | |||
| e32e5c2a47 | |||
| 3a4f9f06cb | |||
| a563030440 | |||
| 80d43896ff | |||
| 1c5949411f | |||
| 699b151939 | |||
| e6af1a08b9 | |||
| 7eac02f8d4 | |||
| 58e70e2500 | |||
| 56ca2021dc | |||
| e4e431dcee | |||
| abfff205ee | |||
| 6416e4e0d9 | |||
| 86f4730db7 | |||
| 33a5479512 | |||
| 891859f4ca | |||
| d5bfb8201b | |||
| f49ef92f90 | |||
| 02d004b5bf | |||
| 55f8a8a1d0 | |||
| 068a69c80b | |||
| 375e66489f | |||
| cbbd034862 | |||
| f7fe948da5 | |||
| 478ce0863b | |||
| 329011460f | |||
| 48ec51a923 | |||
| 9936962c56 | |||
| 15111d1b20 | |||
| 07e6d90c98 | |||
| 85231cda01 | |||
| 8549b7b1b4 | |||
| 9f58ef9916 | |||
| c734ee9fd1 | |||
| 77d87902d9 | |||
| b5c8656ac9 | |||
| 28f6b73da6 | |||
| 521b505543 | |||
| c5a3310103 | |||
| 0c053c713a | |||
| bc06f93aae | |||
| 8e919aeeb1 | |||
| 6bd09e42e0 | |||
| 1f670b9919 | |||
| c805a58fb0 | |||
| 34517004df | |||
| b0506bcd96 | |||
| 7a3a6c04a6 | |||
| 54e4b08e1f | |||
| 67c22c5186 | |||
| 87aba86fa8 | |||
| 28ea300f42 | |||
| 858c26b46a | |||
| 70a6c7149c | |||
| b4a34216c8 | |||
| 3868f4eb98 | |||
| 44304ee5b3 | |||
| 9f4b8d65c8 | |||
| 665f8ce755 | |||
| e1d5348f23 | |||
| b596dc9eea | |||
| eb8370b86b | |||
| fa69686f0a | |||
| 3fe5372d28 | |||
| 3058d42b49 | |||
| 4975ee0028 | |||
| d4e1d809f3 | |||
| 44cb0d995e | |||
| c73d08187b | |||
| 4382c34539 | |||
| cb173b7bf9 | |||
| b5d4674471 | |||
| be1803dfb6 | |||
| 417c1af21e | |||
| 00bccd02da | |||
| 8596443da5 | |||
| a2eda76a26 | |||
| b4e25838bd | |||
| 44d703887c | |||
| 29fd3e4c96 | |||
| 0778b13e2b | |||
| bef1f6d8b8 | |||
| d6a0b04930 | |||
| 87ae60f323 | |||
| 85df061701 | |||
| 4ed44c638f | |||
| 54f0cd7864 | |||
| 4f523b1b9b | |||
| d492481a4f | |||
| 3975a45858 | |||
| 5f2fbb370c | |||
| d9bd6bbb32 | |||
| 31814bda37 | |||
| 8f61b590f8 | |||
| 37642c1f78 | |||
| 8ea7b4d4cb | |||
| 245f5c6e93 | |||
| 88d1c29621 | |||
| 44926393ac | |||
| 5d790c9406 | |||
| 66261b0f51 | |||
| e99a9abacd | |||
| b01c1455f5 | |||
| 650d794eec | |||
| acf74e7f6e | |||
| 53f0c2421d | |||
| 01d46615a7 | |||
| 57f55e4270 | |||
| 5c159e86d7 | |||
| fb03037923 | |||
| ff6e4aec9a | |||
| c78db0eb26 | |||
| 324e206b74 | |||
| 030dca051a | |||
| 24e3fd3267 | |||
| a28f6b1194 | |||
| 38e97aa79f | |||
| 8adfd1b10b | |||
| ffda7a53fe | |||
| 20ddd9157f | |||
| a3f329bd7a | |||
| 13c6837b60 | |||
| 84fe9fbc74 | |||
| e5ec92ac2a | |||
| 12155f9390 | |||
| 00da0bd0d1 | |||
| 4bf5943ac5 | |||
| f205de7205 | |||
| f782c535f9 | |||
| 030d6bc4bb | |||
| 9c10574e49 | |||
| 9512e5c3db | |||
| 8686fef96a | |||
| 06285c11c7 | |||
| 3b58790c96 | |||
| a8b494f960 | |||
| 72c6f448d0 | |||
| ce3c75817c | |||
| 56c943d6d1 | |||
| 21b0b4c524 | |||
| 51daf691b3 | |||
| e889aff42c | |||
| df07b6dc9e | |||
| 63c15b54d6 | |||
| b76a231083 | |||
| e0f58e1916 | |||
| 78bfa604e2 | |||
| dcbe0c40b0 | |||
| f384d75de8 | |||
| cf6084071b | |||
| 0150796064 | |||
| f91186ffa4 | |||
| ba73da321b | |||
| 8ae3e1ea98 | |||
| fa5b075af5 | |||
| a66fced2f7 | |||
| 33492602fb | |||
| b7dae1025b | |||
| 7627a00dce | |||
| d761bac85c | |||
| 3bf1cca118 | |||
| cdb056e8ba | |||
| e47256eae7 | |||
| 5f1874edae | |||
| 22376e873e | |||
| 02d882a7c3 | |||
| d878e0c450 | |||
| 1430cfd6b4 | |||
| 5a3493c0c9 | |||
| 911f8f6de6 | |||
| fe8fbd058b | |||
| c4529a0949 | |||
| 6ec3a68f0a | |||
| 458731778d | |||
| 64547271dc | |||
| 9e584951ac | |||
| c859fdd08e | |||
| 1380ee6f20 | |||
| 2da2272a53 | |||
| 17b6996ae4 | |||
| 0f82b6efba | |||
| 178fcb9717 | |||
| 19f0c653d1 | |||
| 7dc76876e4 | |||
| 60457886cc | |||
| ec078b6ccc | |||
| ec730a4383 | |||
| b2b3255f59 | |||
| df925cfcb0 | |||
| 5b96f30b1a | |||
| 8feb870c8f | |||
| d0b2340a73 | |||
| efac298eb0 | |||
| 453c5b0d6e | |||
| 816010582a | |||
| a260eb11a8 | |||
| b1d271f1c2 | |||
| 3faa959c09 | |||
| a12a5e1637 | |||
| 7c6d59a292 | |||
| 9836d8595c | |||
| c9d5dfaf1b | |||
| 028f6cbb4e | |||
| c56d1b0bec | |||
| 2e61f6c13d | |||
| 8437467320 | |||
| 039be43c2b | |||
| a1af7d9b9f | |||
| 4ce37964f4 | |||
| c1cdfa78d3 | |||
| ff4911116c | |||
| bb9d98cc0c | |||
| 2d93d9b3cc | |||
| 1c60ba6e7f | |||
| 11b3989615 | |||
| c9f26a48c7 | |||
| 75cbaf0f06 | |||
| de1dc6828d | |||
| e6bf23e536 | |||
| 5b16ff4a69 | |||
| ed42c3fd29 | |||
| 9cd67eedc1 | |||
| acc589bdb6 | |||
| 2d78512ca2 | |||
| 84023a5f66 | |||
| 443f378d1b | |||
| d4989d7576 | |||
| 860b0b64e3 | |||
| ba40253a46 | |||
| 95b81b6425 | |||
| b664c2bed1 | |||
| c6c4c17b30 | |||
| 5e46016c4d | |||
| da874738d6 | |||
| 0a68a056d8 | |||
| 5a3a32462d | |||
| c70762f871 | |||
| 6c28496dd8 | |||
| 90ed6e1fdd | |||
| 60d7675a36 | |||
| a9b42127d1 | |||
| 01fdcfdfec | |||
| 2d383e237f | |||
| 143b3d98b1 | |||
| 6f4377de76 | |||
| 722056e78a | |||
| 21710ddfb3 | |||
| 13f590c6a2 | |||
| d604ae2d77 | |||
| 7a35c253cb | |||
| b5129f702e | |||
| 6b1e51b4f6 | |||
| 3776bff594 | |||
| 3afcc7fdf9 | |||
| e74921cbdf | |||
| e9c33e3bea | |||
| 36d4db49ca | |||
| 2c40c77403 | |||
| 15febaf851 | |||
| 02dce1af2e | |||
| 5915ceb0a5 | |||
| d6f666d9a0 | |||
| 37fa69fc39 | |||
| 8e47927805 | |||
| f1c1161da5 | |||
| 392382e3e3 | |||
| d6403918b6 | |||
| fc9b0b233c | |||
| f16755b86b | |||
| f45e975b14 | |||
| b3de6a283d | |||
| 7fa204fc9c | |||
| f284a9691b | |||
| 9bb63a68f5 | |||
| 77d20e89c8 | |||
| 66f664207a | |||
| bac69f95d8 | |||
| 75e372ac9b | |||
| ef31192f33 | |||
| fde707b726 | |||
| e158e95245 | |||
| 5b23cc2e33 | |||
| c72cdff0f1 | |||
| 831c8f73b0 | |||
| 2dc6c62acb | |||
| 9e1d1a056c | |||
| 9a32ae2c6d | |||
| b1a2003a84 | |||
| e2c1d62552 | |||
| db0f6d6c0b | |||
| bc44ee8056 | |||
| 65a9bd55d8 | |||
| 2aa0668c28 | |||
| 9f5e37a03c | |||
| f27763870c | |||
| ab22e02db8 | |||
| 257afd3525 | |||
| eec38de558 | |||
| 35de677999 | |||
| 8b9dfdf96d | |||
| c830ef88ca | |||
| ba0daed776 | |||
| f37d946b4e | |||
| 477419cc32 | |||
| 70e8d1c4b3 | |||
| 732f795be4 | |||
| 00536fa3d9 | |||
| 042f00cc58 | |||
| acef89ea03 | |||
| d7770d285f | |||
| 7932941a01 | |||
| c4eac5e62b | |||
| 763bd60e74 | |||
| 3fa52e7ac5 | |||
| 9104afdef7 | |||
| 942c95e736 | |||
| dc696a0f45 | |||
| d26e9da6c4 | |||
| ea09b1f6bc | |||
| da033eb28e | |||
| b2a0ccba05 | |||
| 3f146c94e5 | |||
| 9d92bdcd75 | |||
| 6354d8ccca | |||
| 1d0237f15d | |||
| c535d033ec | |||
| fcf900c5e0 | |||
| c265ce8222 | |||
| 658b90067a | |||
| 80b6496780 | |||
| 711934a249 | |||
| ea5e397595 | |||
| c8dc416071 | |||
| 30026fc307 | |||
| 7b0fdcd721 | |||
| c0afb3b95e | |||
| 5504bf23d1 | |||
| 28b51d3335 | |||
| fb91726c35 | |||
| a97a7edca6 | |||
| 92b4909fc8 | |||
| 3998c21178 | |||
| 41d925d7c9 | |||
| 7029636291 | |||
| a916c1067f | |||
| 7322d4da8b | |||
| 31f15b12cb | |||
| 4d3e463aba | |||
| 166526dbbe | |||
| 348ada3f0d | |||
| 2c5f6d8332 | |||
| e128d548f4 | |||
| bb2ab1c1fe | |||
| 715bedb71a | |||
| 8fed9e47d1 | |||
| 89f8f7e25e | |||
| 7bbba293a6 | |||
| d57a694d3c | |||
| f31d5c04c8 | |||
| 85f66a8fec | |||
| 48ec606bc5 | |||
| 75cc809b16 | |||
| 2a27a491e7 | |||
| 3e75d70632 | |||
| cf2d094df6 | |||
| 18a7955240 | |||
| 22ebc27997 | |||
| c53ee24b5b | |||
| 25e681c04a | |||
| 365e0b49ae | |||
| e3dc78b28e | |||
| e3319f6fe4 | |||
| 0a9b006a94 | |||
| 5692be3b66 | |||
| 6ea5dea849 | |||
| 8debcf0fa2 | |||
| 1cf4845cb2 | |||
| b9d1292add | |||
| 19063fd8db | |||
| 76cf732100 | |||
| 30a7eef611 | |||
| 99f0020583 | |||
| f2e0da47ed | |||
| ca66a428d8 | |||
| f077a4e074 | |||
| e46631a960 | |||
| 2da1957c70 | |||
| ad6c48688d | |||
| 71da7fb384 | |||
| 0159e0e41e | |||
| 457a3fdc7a | |||
| 8507c0138d | |||
| 4f7901b946 | |||
| e239dc039b | |||
| 1428eeba06 | |||
| adcf6fb86d | |||
| de2d663968 | |||
| 60f6c683a3 | |||
| f8009672e9 | |||
| 9fe5ac1994 | |||
| 58efb51c07 | |||
| 5c3a064746 | |||
| 94aefa6dba | |||
| 7f6e96459c | |||
| 6fe57be115 | |||
| 37b3f28065 | |||
| 0b9468da1b | |||
| e558f21ebc | |||
| 71c1512ef2 | |||
| d03ebdace8 | |||
| d86b9119a4 | |||
| 0ab872e152 | |||
| 5e7f81678d | |||
| ff510248e9 | |||
| bba5d4380d | |||
| 39ad95d4db | |||
| e9adde8ac6 | |||
| 8fc120d9f9 | |||
| 7f8339aedf | |||
| d2183f3b91 | |||
| 11b4aa7308 | |||
| 51481daf03 | |||
| 1bdd0f6e26 | |||
| 1de492973e | |||
| eea96dac73 | |||
| ebc378a620 | |||
| 3d08ca0cc1 | |||
| f11cc41df8 | |||
| 19ce59b1b4 | |||
| 5101ac9d8e | |||
| 5149882bb5 | |||
| 26222ee853 | |||
| 0394e2cda9 | |||
| 501b310efa | |||
| 53e0b1b81c | |||
| 81be616847 | |||
| b9b2c9afb0 | |||
| 848cd9a485 | |||
| 75921e1130 | |||
| 0b14639c66 | |||
| 5c54f85de4 | |||
| 0202313bc8 | |||
| 2671826b19 | |||
| 7dc89ad090 | |||
| c54f0ea329 | |||
| d90f3ce309 | |||
| bcc6ced47c | |||
| 1b5c61a285 | |||
| ca95192de3 | |||
| c2e04443e3 | |||
| f4f8c94c6a | |||
| f957fca162 | |||
| 9671711bf5 | |||
| ea3d4c67f8 | |||
| cab1f59181 | |||
| 8c01611850 | |||
| d6b682ab88 | |||
| d2beaa0ab9 | |||
| ce0fafd45b | |||
| c0dbd00b74 | |||
| a556aed34f | |||
| 8d19ee8ab3 | |||
| 8c4c80731c | |||
| de6619b383 | |||
| 941dc253fb | |||
| 25705a6b02 | |||
| 4d56269130 | |||
| 96236df293 | |||
| f447482e32 | |||
| 401b8fc496 | |||
| 2e2a2aaf03 | |||
| 66c2ab38ed | |||
| 6e0b7e2c23 | |||
| f335623f69 | |||
| f8369ee39a | |||
| 2a1bacdfa4 | |||
| a93dd6586d | |||
| f3dd1be125 | |||
| 5b49530df9 | |||
| 00555e3c75 | |||
| 972746d388 | |||
| db3aaf96c7 | |||
| e12c87b869 | |||
| ad80b000c9 | |||
| 9bcc54c56c | |||
| 3e6d207bf0 | |||
| 6c836e0fde | |||
| 5f9e123571 | |||
| 20ba624de2 | |||
| 12426cf8a7 | |||
| 1cd6f00c59 | |||
| 365d5784b7 | |||
| a90cddf589 | |||
| 5f71017142 | |||
| c81402b8ce | |||
| 6122410db1 | |||
| 42e240c9ab | |||
| 01459b7759 | |||
| cd2f4480f4 | |||
| ce92679be0 | |||
| e9705b2cc5 | |||
| a2007dd59e | |||
| d6052b718e | |||
| 6bfc79fb03 | |||
| e9a5f30c71 | |||
| 9a61b7f13b | |||
| 2073f3d7ed | |||
| 774cd46892 | |||
| f593ee7c9f | |||
| 47d35446e2 | |||
| 3e16969808 | |||
| 3e95f5cd05 | |||
| 15a8437d79 | |||
| 6a213bffa6 | |||
| 5be01a7577 | |||
| 89b8eabe0c | |||
| 3cecc34a9c | |||
| 9e76214be8 | |||
| 5b059f974f | |||
| ecb4f64f91 | |||
| 992121c659 | |||
| cbc41214d8 | |||
| 53c7a81666 | |||
| a63065b44f | |||
| cec4494ce6 | |||
| 60411027ca | |||
| 8d7b9293b5 | |||
| 2133dfd80c | |||
| 1a75f51aa6 | |||
| 2a8c036c63 | |||
| c90f357bff | |||
| 4d381452b5 | |||
| 087b53c1c5 | |||
| 58a2769f2b | |||
| ce38c3e5c5 | |||
| 12f7d5e4b6 | |||
| fd703dd4d1 | |||
| 3ef4c1f6e0 | |||
| 0e95444552 | |||
| aca90db2c2 | |||
| 09edd055e6 | |||
| 892ef6b1b3 | |||
| ed838815ef | |||
| 8d8c4d1a95 | |||
| debdf917ea | |||
| f03961bc19 | |||
| fb4572264d | |||
| d7445a70f9 | |||
| 78bcf9a738 | |||
| d71c85412f | |||
| f5c9ab72ef | |||
| 5c4cd74c39 | |||
| 5a1daf5dc9 | |||
| 4de2a45195 | |||
| 91d3a6ecb7 | |||
| 763918e129 | |||
| 525c166f62 | |||
| 6b2ed24fc3 | |||
| 1eae3a032f | |||
| 755cfe19d5 | |||
| 559331cf82 | |||
| 18fddb1537 | |||
| 861620cb6e | |||
| 568f3ae94f | |||
| 0af00a313e | |||
| ff52f020e2 | |||
| 55bf7bcbda | |||
| bccb740c45 | |||
| b7307adc10 | |||
| edb71dcef0 | |||
| 7ddf232615 | |||
| a7cdb0a514 | |||
| 7157e571c8 | |||
| d073b7b3c0 | |||
| 27d67398fb | |||
| cc6ced9197 | |||
| 712e42c71f | |||
| 53efc96e30 | |||
| 5b2ac0f022 | |||
| b5cdcc29bc | |||
| df3e6e5fb7 | |||
| 27145bdabe | |||
| 71aedfd96d | |||
| 8530292fef | |||
| f1bc268f58 | |||
| 2e79f5a369 | |||
| 1427b1709a | |||
| 960d4d35fb | |||
| 7a467ce860 | |||
| cd46314b4e | |||
| 9c81acff53 | |||
| d8b2e2873b | |||
| 98cd6675d9 | |||
| 002085ad32 | |||
| 2e525dfdcc | |||
| a378e3a72d | |||
| 7e14b2fc5a | |||
| 51016f9258 | |||
| adad723110 | |||
| a10e7ab279 | |||
| 0c124327de | |||
| 6c5f706064 | |||
| 2422e72713 | |||
| e49e4a5e67 | |||
| 14d8d65de0 | |||
| d3305cadb6 | |||
| 17c28ca584 | |||
| 151905c5f3 | |||
| ab49ea07e8 | |||
| 8e436e6b55 | |||
| de5414ec19 | |||
| e5d71579af | |||
| 5ec4c9714c | |||
| eafb2558c2 | |||
| 4cefcb26c2 | |||
| 8a86e7d0f7 | |||
| b20fb61e1c | |||
| feeed99c62 | |||
| aa5008f865 | |||
| c4ce2aa977 | |||
| 7cc31a473c | |||
| a8193012aa | |||
| eb0ecedecf | |||
| de44abd529 | |||
| 9807ca99f9 | |||
| 8c9d2d6f1d | |||
| 65ef1f384c | |||
| bf2cc36719 | |||
| 34ffe7eefa | |||
| b756c8b9ec | |||
| 19a98c9ad6 | |||
| e159025ebb | |||
| 05e81ad923 | |||
| 8e1a0eb20f | |||
| a881b8fa5a | |||
| 6982030013 | |||
| 01da4c6af5 | |||
| a42805d4cc | |||
| 01145c4581 | |||
| 4d1dfb58ff | |||
| 43f44a4142 | |||
| b314d3cafe | |||
| 9bbf28e44b | |||
| d995d25f69 | |||
| 1f58b8e6a7 | |||
| eeb881cdc2 | |||
| 807874ce5d | |||
| 213d11c8e9 | |||
| dfd0761506 | |||
| 4c30086896 | |||
| 1efdca399e | |||
| 4f27c8051a | |||
| d43693fef0 | |||
| 88f0202b16 | |||
| be98e0b543 | |||
| 8a907bb3f3 | |||
| 1b34a478a1 | |||
| cda0bba555 | |||
| dae1b10de1 | |||
| 0c4e72ece2 | |||
| 77dfd51b28 | |||
| b601a549d0 | |||
| c4907edd76 | |||
| dcf4148d75 | |||
| 8afeef568f | |||
| dd5635d9cd | |||
| 62a6ddf3ca | |||
| 195daa97f3 | |||
| b1c5c87443 | |||
| 1ab88940f9 | |||
| 8ba97b8a74 | |||
| e7f5442a64 | |||
| 066dd866b1 | |||
| fa0722a9e2 | |||
| 5f276f6b22 | |||
| c45b5751af | |||
| 161802cf9d | |||
| 0679832b04 | |||
| b20d6f8820 | |||
| 52fb40d543 | |||
| 067279d2e8 | |||
| a0bbed6c6c | |||
| 9371125eb0 | |||
| 0a0f6cdce9 | |||
| fc350be3a1 | |||
| be731a99c0 | |||
| c65fd1d7ae | |||
| be899159f3 | |||
| 2400e6578b | |||
| 1aac2b8e75 | |||
| c7581220b8 | |||
| f3968215e0 | |||
| 56a8011b78 | |||
| adccae7937 | |||
| 1c63c1937a | |||
| 4753f7bb51 | |||
| d7fec7d10a | |||
| 3c90a29b1e | |||
| 98de361bf4 | |||
| c1df10e064 | |||
| 3743e0bc03 | |||
| 12e6a4d0ae | |||
| 969511953a | |||
| 223e2e04b0 | |||
| 0b0368ffcc | |||
| 9e4684b524 | |||
| d825c7e4ea | |||
| c38c996773 | |||
| 71a9ef00ee | |||
| 89a30ae5ee | |||
| 94bd0e057b | |||
| 0efc6338bb | |||
| 3b98da1d86 | |||
| 6927c68811 | |||
| f0909ba3a0 | |||
| 2f7d2873f7 | |||
| 7a6b6aa335 | |||
| 2861ef0c73 | |||
| 059fc06f3a | |||
| a971576de0 | |||
| a4e059e3ec | |||
| 07408b7bc3 | |||
| 9722f7b71e | |||
| 45d8413d59 | |||
| 5c400457a9 | |||
| 3e9ee5890f | |||
| 1acdb40498 | |||
| 1dc0b00133 | |||
| f2208389bd | |||
| ab92c3e15b | |||
| 018e35295a | |||
| 2c9e90eee0 | |||
| 847f21f7dc | |||
| b90dfbe3b0 | |||
| c230794c82 | |||
| 7f83aa7253 | |||
| 1039815017 | |||
| 2c43eac80d | |||
| 4aa6ad3203 | |||
| 730b05ad1b | |||
| 5a7b2c5029 | |||
| 7ae551de9d | |||
| 96dd3faef0 | |||
| ffdc8cd9ff | |||
| 8256ac3bee | |||
| 037ab83519 | |||
| a56e77310d | |||
| 5350fb7f5d | |||
| 9161f89057 | |||
| 1d2abeb20b | |||
| 833c21192a | |||
| 86168e454f | |||
| a20c2ce29a | |||
| 874b27c56d | |||
| a7dc44e4e1 | |||
| 047d08882e | |||
| 52df1ad963 | |||
| c2cec37928 | |||
| 239a186b36 | |||
| 5aeb2ebc05 | |||
| a7e87aaae5 | |||
| eb545eca57 | |||
| 44ab1827bf | |||
| 96b4f024b4 | |||
| b070035770 | |||
| 1b0c3d8c00 | |||
| 2e71cb08d0 | |||
| 3da5d12bee | |||
| e8019bbb92 | |||
| 30dab27202 | |||
| cc7077d783 | |||
| fda7e9f39d | |||
| e178533493 | |||
| e3ad9296bc | |||
| 01042a62ae | |||
| 7bd940ddb3 | |||
| f168702aad | |||
| 2a33c0c375 | |||
| eea240d7f2 | |||
| afb98a374c | |||
| ed0d28eaf6 | |||
| 50345101e5 | |||
| c0e4010c88 | |||
| 193d7accb4 | |||
| a9be34c627 | |||
| 0e14226968 | |||
| 068b03a0bb | |||
| b99f9ae752 | |||
| 3519871f80 | |||
| e9db853f28 | |||
| a6fdd89e1d | |||
| b8bfe7acc1 | |||
| dd5d5589ff | |||
| 7d460e093c | |||
| 54e86915b0 | |||
| ab2effd776 | |||
| 4f0da67a83 | |||
| 014ca36a4a | |||
| 2971e64182 | |||
| d7737c13ff | |||
| eebcc9c925 | |||
| 0c90b39a96 | |||
| 4f3f96337f | |||
| e855ca72aa | |||
| 8ff47bf8e2 | |||
| 9d75f69a79 | |||
| ae33977e10 | |||
| 07b5f35b98 | |||
| c4acf006dd | |||
| 12b80307a7 | |||
| 43fd399d10 | |||
| cc5d8940bf | |||
| 09ed1ab683 | |||
| 26c85fd18a | |||
| 894615bee6 | |||
| aeed094be0 | |||
| 61068ee166 | |||
| bdce25cb8c | |||
| 6a71bf5653 | |||
| 3007ddc093 | |||
| 4495e1649f | |||
| f960cdea9b | |||
| b70b2a65bc | |||
| 4a73e90da8 | |||
| fc59bef156 | |||
| 512f4ca4e4 | |||
| f254ca57c6 | |||
| 5e35dac1da | |||
| 44cbd408ce | |||
| 6fbe9de1a8 | |||
| 3b1410f913 | |||
| f9265923a9 | |||
| 3282848631 | |||
| f142363bfa | |||
| c0e9800179 | |||
| 97308ca31c | |||
| 02992954c2 | |||
| 78d4f178a3 | |||
| fe577d9dd0 | |||
| 007010067b | |||
| bc2d8dab31 | |||
| 296f8645fb | |||
| 2d76c8ff0d | |||
| 0a3d9f9876 | |||
| 2a1d0b19ce | |||
| a99c57ab1a | |||
| 6832049ccc | |||
| 6d72753216 | |||
| b6b3898536 | |||
| 99922d38e2 | |||
| 161623a8d2 | |||
| 155a7a6582 | |||
| 6aafe9dee0 | |||
| 680c9d64cb | |||
| ca395492d5 | |||
| ea920d352f | |||
| 0c0031455b | |||
| a8a9893ce4 | |||
| 5143743661 | |||
| 88a42b25cc | |||
| b371bf6efa | |||
| 3bc7ed6f8c | |||
| f996510969 | |||
| 58fd119636 | |||
| f275792604 | |||
| 9f8ead5e4e | |||
| a35ccbbe5b | |||
| 9a60a8838f | |||
| bb9e02da6b | |||
| 0fd0c5ecc1 | |||
| c89961ebf0 | |||
| 0f81e82206 | |||
| 7c7c8c4f34 | |||
| 3d7362aa9d | |||
| f3061a2526 | |||
| 2657af1aef | |||
| dd03ed4b30 | |||
| 64c6b05963 | |||
| 05017b0236 | |||
| efd9cce4ef | |||
| 144c78fa4b | |||
| 3147aa539c | |||
| ad4532932b | |||
| ffac3462af | |||
| 7c163592b5 | |||
| 37987ddb57 | |||
| 2b342ca33b | |||
| 97e6df7f59 | |||
| a2bb67a828 | |||
| d14e28d7b3 | |||
| 0a0ee3cc98 | |||
| 99e6a254e1 | |||
| 68714ebad8 | |||
| 48ef4144bc | |||
| 78a4da4945 | |||
| af0861877a | |||
| a23b96ba75 | |||
| 47704f7591 | |||
| 755f90f38b | |||
| 8a56406c19 | |||
| 887ea94a4d | |||
| 499b3ddf3e | |||
| 83e55b1074 | |||
| 1f87ed77e4 | |||
| 93b7d210dc | |||
| 10d9d84f84 | |||
| fc9a4d5431 | |||
| 4b3a2531a6 | |||
| ed4871548e | |||
| 1284b8da8b | |||
| 95455603a1 | |||
| 813c54a166 | |||
| fa2a2d51a5 | |||
| 4b68b636ce | |||
| 0a01b0af69 | |||
| e4e809f3fe | |||
| 1667b79fa8 | |||
| 31272ff0fe | |||
| 9335063d68 | |||
| 39dfaf3acb | |||
| 3e7ecd51fd | |||
| c9ee4a304e | |||
| 2f1bf7bdbe | |||
| 41890f6bb4 | |||
| 24cd7cab58 | |||
| 473d9387d4 | |||
| f5495adce1 | |||
| d802ec4b59 | |||
| 8f69e2a204 | |||
| c3fc579907 | |||
| 9568fe7d4d | |||
| cc06370bcd | |||
| ed15ec2469 | |||
| 3f7d5ff041 | |||
| d5bcf40cbb | |||
| 49c196814f | |||
| c4282ce936 | |||
| cd1c09127f | |||
| 9afebe0851 | |||
| 9a7382ea06 | |||
| 7a7e723009 | |||
| 9d772284cc | |||
| a981761deb | |||
| fc13ffa242 | |||
| 878b2cd639 | |||
| 995922d2d7 | |||
| 0d100aa9be | |||
| d4fabed317 | |||
| 9eff781103 | |||
| 0353da3d27 | |||
| 3cbdc6e9fe | |||
| ce71afd704 | |||
| 603d491bed | |||
| 20a792f135 | |||
| 87f5e7f3a6 | |||
| e272925f3d | |||
| 19091ade7b | |||
| e62c065e2c | |||
| 2312381b82 | |||
| 639942d444 | |||
| 55a5b9d0ba | |||
| a33517e5d0 | |||
| c981586bcf | |||
| b473238f02 | |||
| 1d9b92080f | |||
| 7f89d4d39f | |||
| 4f00ec2277 | |||
| 26db10a083 | |||
| 3ec2ceb725 | |||
| 667ac39e06 | |||
| 993d62a8c8 | |||
| 09a70d4573 | |||
| 3afa730751 | |||
| 3245ddbfe7 | |||
| def55943ed | |||
| 4accc9c018 | |||
| 579d612397 | |||
| daabce1d2f | |||
| 5885829585 | |||
| 3e7b9e68d5 | |||
| 4a52139457 | |||
| 79ea403273 | |||
| 397d7fa6c8 | |||
| ac787a6f51 | |||
| 0418e77d34 | |||
| a2c6a3669b | |||
| b8d22240a8 | |||
| b458d570a1 | |||
| 5022df0d14 | |||
| 220b48b144 | |||
| 8aeed46181 | |||
| 38b34eae2f | |||
| 648b21f972 | |||
| 09717a966b | |||
| eef46fe743 | |||
| 5f91566fa7 | |||
| c83a476ebe | |||
| 954bba274c | |||
| d370a5c13d | |||
| 181189bee0 | |||
| c678f5e85a | |||
| 0fabf83c62 | |||
| b7e8d19290 | |||
| d0db71602a | |||
| 112efddb4e | |||
| 4cea81e564 | |||
| 3a40a34566 | |||
| a4ff87a7d5 | |||
| 797077c47b | |||
| 075d950249 | |||
| 22d14b2a4f | |||
| 4272e2e2b2 | |||
| 34279cfacf | |||
| 85f4a4c36a |
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "thirdparty/zlib"]
|
||||||
|
path = thirdparty/zlib
|
||||||
|
url = https://github.com/madler/zlib
|
||||||
|
[submodule "thirdparty/SDL2"]
|
||||||
|
path = thirdparty/SDL2
|
||||||
|
url = https://github.com/spurious/SDL-mirror.git
|
||||||
@@ -2,56 +2,129 @@ language: cpp
|
|||||||
branches:
|
branches:
|
||||||
except:
|
except:
|
||||||
- latest-master
|
- latest-master
|
||||||
|
- latest-cmake
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
env: BUILD_TYPE=PSP
|
||||||
|
sudo: required
|
||||||
|
- os: linux
|
||||||
|
env: BUILD_TYPE=SDL
|
||||||
|
sudo: required
|
||||||
|
- os: linux
|
||||||
|
env: BUILD_TYPE=Qt
|
||||||
|
sudo: required
|
||||||
|
- os: osx
|
||||||
|
env: BUILD_TYPE=Qt
|
||||||
|
- os: osx
|
||||||
|
env: BUILD_TYPE=iOS
|
||||||
|
- os: linux
|
||||||
|
language: android
|
||||||
|
env: BUILD_TYPE=ANDROID
|
||||||
|
sudo: required
|
||||||
|
- os: osx
|
||||||
|
env: BUILD_TYPE=Emscripten
|
||||||
|
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
- platform-tools
|
||||||
|
- build-tools-23.0.1
|
||||||
|
- android-10
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- opt/pspsdk
|
||||||
|
- android-ndk-r9
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- export BUILD_PSP=YES
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||||
- export BUILD_ANDROID=YES
|
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty universe" &&
|
||||||
- export BUILD_Qt=YES
|
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty main" &&
|
||||||
- export BUILD_MAC=NO
|
sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test &&
|
||||||
# Only building on Mac when not handling pull request
|
sudo apt-get -qq update &&
|
||||||
- if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
sudo apt-get -qq install g++-4.8 &&
|
||||||
export BUILD_MAC=YES;
|
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90;
|
||||||
fi
|
fi
|
||||||
- sudo apt-get update -qq
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||||
|
brew update &&
|
||||||
|
brew install dpkg &&
|
||||||
|
pwd &&
|
||||||
|
ls;
|
||||||
|
fi
|
||||||
|
- if [ "$BUILD_TYPE" == "iOS" ]; then
|
||||||
|
curl -s -f -L https://raw.github.com/r-plus/dotfiles/master/install_theos.sh | bash &&
|
||||||
|
pwd &&
|
||||||
|
ls;
|
||||||
|
fi
|
||||||
# Building for PSP here
|
# Building for PSP here
|
||||||
- if [ "$BUILD_PSP" == "YES" ]; then
|
- if [ "$BUILD_TYPE" == "PSP" ]; then
|
||||||
export PSPDEV="$TRAVIS_BUILD_DIR/opt/pspsdk" &&
|
export PSPDEV="$TRAVIS_BUILD_DIR/opt/pspsdk" &&
|
||||||
export PSPSDK="$PSPDEV/psp/sdk" &&
|
export PSPSDK="$PSPDEV/psp/sdk" &&
|
||||||
export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" &&
|
export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" &&
|
||||||
wget -O sdk.lzma http://superb-sea2.dl.sourceforge.net/project/minpspw/SDK%20%2B%20devpak/pspsdk%200.11.2/minpspw_0.11.2-amd64.tar.lzma;
|
wget -O sdk.lzma https://sourceforge.net/projects/minpspw/files/SDK%20%2B%20devpak/pspsdk%200.11.2/minpspw_0.11.2-amd64.tar.lzma/download;
|
||||||
fi
|
|
||||||
# Building for Qt here
|
|
||||||
- if [ "$BUILD_Qt" == "YES" ]; then
|
|
||||||
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty universe" &&
|
|
||||||
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty main" &&
|
|
||||||
sudo apt-get -qq update &&
|
|
||||||
sudo apt-get -qq install qt5-qmake qtbase5-dev qtdeclarative5-dev qttools5-dev qtmultimedia5-dev pulseaudio libpulse-dev &&
|
|
||||||
export QMAKE="qmake -qt=qt5";
|
|
||||||
fi
|
fi
|
||||||
# Building for Android here
|
# Building for Android here
|
||||||
- if [ "$BUILD_ANDROID" == "YES" ]; then
|
- if [ "$BUILD_TYPE" == "ANDROID" ]; then
|
||||||
export ANDROID="android-sdk-linux/tools/android" &&
|
export ANDROID="/usr/local/android-sdk-linux/tools/android" &&
|
||||||
if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch jq; fi &&
|
export PATH=$PATH:"/usr/local/android-sdk-linux/tools" &&
|
||||||
wget http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2 -nv &&
|
wget http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2 -nv &&
|
||||||
wget http://dl.google.com/android/android-sdk_r24.3.4-linux.tgz -nv;
|
wget https://bitbucket.org/ewing/sdl_androidcmake/get/4e9e88c03f04.zip -nv;
|
||||||
fi
|
fi
|
||||||
|
# Building for Qt here
|
||||||
|
- if [ "$BUILD_TYPE" == "Qt" ] && [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||||
|
brew install qt5 &&
|
||||||
|
export QMAKE="qmake -qt=qt5";
|
||||||
|
fi
|
||||||
|
- if [ "$BUILD_TYPE" == "Qt" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||||
|
sudo apt-get install -qq qt5-qmake qtbase5-dev qtdeclarative5-dev qttools5-dev qtmultimedia5-dev pulseaudio libpulse-dev &&
|
||||||
|
export QMAKE="qmake -qt=qt5";
|
||||||
|
fi
|
||||||
|
# Building for SDL here
|
||||||
|
- if [ "$BUILD_TYPE" == "SDL" ]; then
|
||||||
|
export SDL2DIR="$TRAVIS_BUILD_DIR/thirdparty/SDL2";
|
||||||
|
fi
|
||||||
|
# Building for Emscripten here
|
||||||
|
- if [ "$BUILD_TYPE" == "Emscripten" ] && [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||||
|
brew install emscripten && export LLVM=/usr/local/opt/emscripten/libexec/llvm/bin && emcc;
|
||||||
|
fi
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ "$BUILD_PSP" == "YES" ]; then
|
- |
|
||||||
tar -x --xz -f sdk.lzma;
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
fi
|
if [[ -z "$(ls -A ${DEPS_DIR}/cmake/bin)" ]]; then
|
||||||
- if [ "$BUILD_ANDROID" == "YES" ]; then
|
CMAKE_URL="https://cmake.org/files/v3.7/cmake-3.7.2-Linux-x86_64.tar.gz"
|
||||||
tar --absolute-names -jxf android-ndk-r9-linux-x86_64.tar.bz2 &&
|
mkdir -p cmake && travis_retry wget --no-check-certificate --quiet -O - "${CMAKE_URL}" | tar --strip-components=1 -xz -C cmake
|
||||||
tar -zxf android-sdk_r24.3.4-linux.tgz &&
|
fi
|
||||||
$ANDROID list sdk --extended -a &&
|
export PATH="${DEPS_DIR}/cmake/bin:${PATH}"
|
||||||
echo yes | $ANDROID update sdk -a -t tools,platform-tools,build-tools-23.0.1,android-10 --no-ui --force --no-https;
|
fi
|
||||||
fi
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||||
- sudo pip install pyjavaproperties
|
if ! brew ls --version cmake &>/dev/null; then brew install cmake; fi
|
||||||
- sudo pip install github3.py
|
fi
|
||||||
- sudo pip install cpp-coveralls
|
- if [ "$BUILD_TYPE" == "PSP" ]; then
|
||||||
|
tar -x --xz -f sdk.lzma;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_TYPE" == "ANDROID" ]; then
|
||||||
|
jdk_switcher use openjdk7 %%
|
||||||
|
tar --absolute-names -jxf android-ndk-r9-linux-x86_64.tar.bz2 &&
|
||||||
|
export ANDROID_NDK=`pwd`/android-ndk-r9 &&
|
||||||
|
unzip 4e9e88c03f04.zip &&
|
||||||
|
rm -rf thirdparty/SDL2/* &&
|
||||||
|
mv ewing-sdl_androidcmake-4e9e88c03f04/* thirdparty/SDL2/ &&
|
||||||
|
sudo pip install cpp-coveralls &&
|
||||||
|
sudo apt-get install --force-yes -qq libtinyxml-dev libjpeg-dev libpng-dev libgif-dev libz-dev libboost-system-dev libboost-thread-dev libboost-date-time-dev ant;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_TYPE" != "ANDROID" ]; then
|
||||||
|
jdk_switcher use openjdk7 &&
|
||||||
|
sudo pip install cpp-coveralls &&
|
||||||
|
sudo apt-get install --force-yes -qq libtinyxml-dev libjpeg-dev libpng-dev libgif-dev libz-dev libboost-system-dev libboost-thread-dev libboost-date-time-dev ant;
|
||||||
|
fi
|
||||||
|
- sudo pip install pyjavaproperties
|
||||||
|
- sudo pip install github3.py
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
# - JAVA_HOME=/usr/lib/jvm/java-7-oracle # Force set JVM version to comply with Travis Ant version (1.8.2)
|
||||||
- secure: "EBzr1+qjQsOhn0s+tcFmXR1jP9B0xiOSXuXbRXWZ1OEHNvp8+A5/pS84LYVFlaZqmxr5dApxvPtwhgLIUbQ3EPXm8LpC3KgSD4dS+9/QMbxhe5TK4oczgFRGcDTMJQZsCzhOh7hp3tbcbJg5Gp+VT7aFjFQSHDGwhzSJXsXwh/8="
|
- secure: "EBzr1+qjQsOhn0s+tcFmXR1jP9B0xiOSXuXbRXWZ1OEHNvp8+A5/pS84LYVFlaZqmxr5dApxvPtwhgLIUbQ3EPXm8LpC3KgSD4dS+9/QMbxhe5TK4oczgFRGcDTMJQZsCzhOh7hp3tbcbJg5Gp+VT7aFjFQSHDGwhzSJXsXwh/8="
|
||||||
- secure: "X5dTQfofqAutnXxmu11Ep2MQ5QYnMN8m0AITRtwymhEF2UclcOudI1+skPtuhAGbWQnSO+lhunV3cvMfw2/Ml3k/VDz6VdFSKFrzAu7ja1VLJfcxr7chi0s8q30pVBb66tGydjIBac3B+RQyqgmZQW1frbRrhC/kPFQ6wPWOJdQ="
|
- secure: "X5dTQfofqAutnXxmu11Ep2MQ5QYnMN8m0AITRtwymhEF2UclcOudI1+skPtuhAGbWQnSO+lhunV3cvMfw2/Ml3k/VDz6VdFSKFrzAu7ja1VLJfcxr7chi0s8q30pVBb66tGydjIBac3B+RQyqgmZQW1frbRrhC/kPFQ6wPWOJdQ="
|
||||||
- secure: "T97NUPnxCpVZ/c5HH0zfo0FO3DPSRMSmze58ubW5EUTZOjAMtEt+OFdsrNZvUTCugUj2M1agtonZbAbczpaAL+lgZcHDgXgWMkfO0pMnsWX1yyCNqMuE/iTMpJr/xsLQeyWlftWjJLsseQU45abZsd1XVmda/G+ZhrDLF1y55SA="
|
- secure: "T97NUPnxCpVZ/c5HH0zfo0FO3DPSRMSmze58ubW5EUTZOjAMtEt+OFdsrNZvUTCugUj2M1agtonZbAbczpaAL+lgZcHDgXgWMkfO0pMnsWX1yyCNqMuE/iTMpJr/xsLQeyWlftWjJLsseQU45abZsd1XVmda/G+ZhrDLF1y55SA="
|
||||||
@@ -59,7 +132,22 @@ env:
|
|||||||
script: "tools/travis-script.sh"
|
script: "tools/travis-script.sh"
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- coveralls -b . -e JGE/src -e JGE/include -i projects/mtg/include -i projects/mtg/src --gcov-options '\-lp'
|
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_TYPE" == "Qt" ]; then
|
||||||
- python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l core.zip -r Wagic-core.zip -b $TRAVIS_BRANCH
|
coveralls -b . -e JGE/src -e JGE/include -i projects/mtg/include -i projects/mtg/src --gcov-options '\-lp';
|
||||||
- python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l projects/mtg/Android/bin/Wagic-debug.apk -r Wagic-android.apk -b $TRAVIS_BRANCH
|
fi
|
||||||
- python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l projects/mtg/psprelease.zip -r Wagic-psp.zip -b $TRAVIS_BRANCH
|
- if [ "$BUILD_TYPE" == "ANDROID" ]; then
|
||||||
|
python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l core.zip -r Wagic-core.zip -b $TRAVIS_BRANCH &&
|
||||||
|
python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l build_android/package/bin/Wagic_*.apk -r Wagic-android.apk -b $TRAVIS_BRANCH;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "$BUILD_TYPE" == "PSP" ]; then
|
||||||
|
python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l build_psp/psprelease.zip -r Wagic-psp.zip -b $TRAVIS_BRANCH;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$BUILD_TYPE" == "iOS" ]; then
|
||||||
|
python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l net.wagic_0.19.2-1_iphoneos-arm.deb -r Wagic-iOS.deb -b $TRAVIS_BRANCH;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$BUILD_TYPE" == "Qt" ]; then
|
||||||
|
python tools/upload-binaries.py -t $GH_TOKEN -s $TRAVIS_COMMIT -l build_qt_widget/wagic.dmg -r Wagic-macosx.dmg -b $TRAVIS_BRANCH;
|
||||||
|
fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "osx" ] && [ "$BUILD_TYPE" == "Emscripten" ]; then
|
||||||
|
./tools/deploy-emscripten.sh;
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1,6 +1,37 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [latest-master] (https://github.com/WagicProject/wagic/tree/latest-master)
|
## [latest-master] (https://github.com/WagicProject/wagic/tree/latest-master)
|
||||||
|
#### 8/3/16
|
||||||
|
- *Merged pull-request:* andAbility on ATokenCreator, Extend AAFlip [#\824] (https://github.com/WagicProject/wagic/pull/824) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/31/16
|
||||||
|
- *Merged pull-request:* Fix Chandra, Flamecaller & Cryptolith Rite [#\818] (https://github.com/WagicProject/wagic/pull/818) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/28/16
|
||||||
|
- *Merged pull-request:* changing some of the logic to the previous fixes, we want to avoid using code that looks for specific card names. [#\800] (https://github.com/WagicProject/wagic/pull/800) ([zethfoxster](https://github.com/zethfoxster))
|
||||||
|
|
||||||
|
#### 7/26/16
|
||||||
|
- *Merged pull-request:* granted flashback [#\791] (https://github.com/WagicProject/wagic/pull/791) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/23/16
|
||||||
|
- *Merged pull-request:* Fix Flying vs Moat (multiples of them). Fixes issue #526 [#\783] (https://github.com/WagicProject/wagic/pull/783) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/19/16
|
||||||
|
- *Merged pull-request:* pushing to master [#\770] (https://github.com/WagicProject/wagic/pull/770) ([zethfoxster](https://github.com/zethfoxster))
|
||||||
|
|
||||||
|
#### 7/18/16
|
||||||
|
- *Merged pull-request:* Fix Deck Menu layer, Change Main Menu Layout, Fix Crash cdaactive on tokens [#\765] (https://github.com/WagicProject/wagic/pull/765) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/12/16
|
||||||
|
- *Merged pull-request:* Pushing fixes [#\750] (https://github.com/WagicProject/wagic/pull/750) ([zethfoxster](https://github.com/zethfoxster))
|
||||||
|
|
||||||
|
- *Merged pull-request:* try to fix failed logic here [#\747] (https://github.com/WagicProject/wagic/pull/747) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
#### 7/9/16
|
||||||
|
- *Merged pull-request:* pushing to master [#\738] (https://github.com/WagicProject/wagic/pull/738) ([zethfoxster](https://github.com/zethfoxster))
|
||||||
|
|
||||||
|
- *Merged pull-request:* Sorted Primitives and Cleanup Tabs [#\736] (https://github.com/WagicProject/wagic/pull/736) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
#### 7/7/16
|
#### 7/7/16
|
||||||
- *Merged pull-request:* Sorted Primitives and Cleanup Tabs [#\727] (https://github.com/WagicProject/wagic/pull/719) ([kevlahnota](https://github.com/kevlahnota))
|
- *Merged pull-request:* Sorted Primitives and Cleanup Tabs [#\727] (https://github.com/WagicProject/wagic/pull/719) ([kevlahnota](https://github.com/kevlahnota))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,239 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8.7)
|
||||||
|
if(CMAKE_MAJOR_VERSION STRGREATER 3)
|
||||||
|
cmake_policy(SET CMP0054 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeModules)
|
||||||
|
|
||||||
|
#this block will fix install prefixes to install everything in a subdirectory
|
||||||
|
#of cmake_binary_dir if we are on windows/android to make packaging more easy
|
||||||
|
if(NOT CMAKE_TOOLCHAIN_FILE)
|
||||||
|
if(WIN32)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Install directory")
|
||||||
|
else()
|
||||||
|
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Install directory")
|
||||||
|
endif()
|
||||||
|
else() #we are cross-compiling (psp/android)
|
||||||
|
#Android: set output folder for platform/android to pick up
|
||||||
|
set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "library output root")
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Install directory")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#set available build types (debug/release)
|
||||||
|
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE)
|
||||||
|
if(DEFINED CMAKE_BUILD_TYPE)
|
||||||
|
set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Application output directory")
|
||||||
|
|
||||||
|
|
||||||
|
project(wagic CXX C)
|
||||||
|
#todo: somehow determine wagics version
|
||||||
|
set(WAGIC_VERSION "0.19")
|
||||||
|
|
||||||
|
#add standard paths to search for libraries. borrowed from opencv
|
||||||
|
if(UNIX AND NOT ANDROID)
|
||||||
|
if(X86_64 OR CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
if(EXISTS /lib64)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /lib64)
|
||||||
|
else()
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /lib)
|
||||||
|
endif()
|
||||||
|
if(EXISTS /usr/lib64)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /usr/lib64)
|
||||||
|
else()
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /usr/lib)
|
||||||
|
endif()
|
||||||
|
elseif(X86 OR CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
if(EXISTS /lib32)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /lib32)
|
||||||
|
else()
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /lib)
|
||||||
|
endif()
|
||||||
|
if(EXISTS /usr/lib32)
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /usr/lib32)
|
||||||
|
else()
|
||||||
|
list(APPEND CMAKE_LIBRARY_PATH /usr/lib)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ANDROID OR PSP OR IOS)
|
||||||
|
#to allow finding of pathes/headers/libs within the source tree
|
||||||
|
#even if only search for target platform libs
|
||||||
|
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR} ${CMAKE_FIND_ROOT_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#also borrowed from opencv
|
||||||
|
if(MINGW)
|
||||||
|
if(EXISTS /mingw)
|
||||||
|
list(APPEND CMAKE_INCLUDE_PATH /mingw)
|
||||||
|
endif()
|
||||||
|
if(EXISTS /mingw32)
|
||||||
|
list(APPEND CMAKE_INCLUDE_PATH /mingw32)
|
||||||
|
endif()
|
||||||
|
if(EXISTS /mingw64)
|
||||||
|
list(APPEND CMAKE_INCLUDE_PATH /mingw64)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(utils)
|
||||||
|
|
||||||
|
#select the target backend
|
||||||
|
if(PSP)
|
||||||
|
WAGIC_OPTION(backend_psp "build for psp" ON)
|
||||||
|
endif()
|
||||||
|
if(WIN32 OR ANDROID OR UNIX)
|
||||||
|
WAGIC_OPTION(backend_sdl "build for sdl" (WIN32 OR ANDROID OR EMSCRIPTEN))
|
||||||
|
endif()
|
||||||
|
if(NOT backend_sdl AND UNIX AND NOT ANDROID AND NOT IOS)
|
||||||
|
WAGIC_OPTION(backend_qt_console "build qt-console version with testsuit" ON)
|
||||||
|
WAGIC_OPTION(backend_qt_widget "build qt-widget version" OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#third party build options
|
||||||
|
WAGIC_OPTION(BUILD_ZLIB "build zlib from source" WIN32 OR APPLE)
|
||||||
|
WAGIC_OPTION(BUILD_JPEG "build jpeg from source" (WIN32 OR APPLE OR PSP OR ANDROID OR EMSCRIPTEN))
|
||||||
|
WAGIC_OPTION(BUILD_PNG "build png from source" (WIN32 OR APPLE OR PSP OR ANDROID OR EMSCRIPTEN))
|
||||||
|
WAGIC_OPTION(BUILD_UNZIP "build unzip from source" ON)
|
||||||
|
WAGIC_OPTION(BUILD_TINYXML "build tinyxml from source" (WIN32 OR APPLE OR PSP OR ANDROID OR EMSCRIPTEN OR IOS))
|
||||||
|
WAGIC_OPTION(BUILD_ZIPFS "build zipfs from source" ON)
|
||||||
|
WAGIC_OPTION(BUILD_SDL2 "build SDL2 from source" (backend_sdl AND (UNIX OR WIN32 OR ANDROID) AND (NOT EMSCRIPTEN AND NOT IOS)))
|
||||||
|
|
||||||
|
#project options
|
||||||
|
if(ANDROID)
|
||||||
|
WAGIC_OPTION(BUILD_ANDROID_PACKAGE "put the compiled code in an android package" ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}")
|
||||||
|
set(3P_LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}")
|
||||||
|
set(WAGIC_LIB_INSTALL_PATH sdk/native/libs/${ANDROID_NDK_ABI_NAME})
|
||||||
|
set(WAGIC_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME})
|
||||||
|
set(WAGIC_CONFIG_INSTALL_PATH sdk/native/jni)
|
||||||
|
set(WAGIC_INCLUDE_INSTALL_PATH sdk/native/jni/include)
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/package/bin")
|
||||||
|
else()
|
||||||
|
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
|
||||||
|
set(3P_LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}")
|
||||||
|
set(WAGIC_LIB_INSTALL_PATH lib${LIB_SUFFIX})
|
||||||
|
set(WAGIC_3P_LIB_INSTALL_PATH share/wagic/3rdparty/${WAGIC_LIB_INSTALL_PATH})
|
||||||
|
set(WAGIC_INCLUDE_INSTALL_PATH "include")
|
||||||
|
set(WAGIC_CONFIG_INSTALL_PATH share/wagic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${WAGIC_LIB_INSTALL_PATH}")
|
||||||
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
|
#if no build type is specified, we assume debug
|
||||||
|
if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||||
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindOrBuild)
|
||||||
|
|
||||||
|
#set platform dependend configurations
|
||||||
|
if(PSP)
|
||||||
|
FindOrBuildPSPSDK()
|
||||||
|
include(platforms/psp/configure.cmake)
|
||||||
|
elseif(EMSCRIPTEN)
|
||||||
|
include(platforms/emscripten/configure.cmake)
|
||||||
|
elseif(WIN32)
|
||||||
|
include(platforms/win/configure.cmake)
|
||||||
|
elseif(APPLE)
|
||||||
|
include(platforms/macosx/configure.cmake)
|
||||||
|
elseif(UNIX AND NOT ANDROID)
|
||||||
|
include(platforms/unix/configure.cmake)
|
||||||
|
elseif(ANDROID)
|
||||||
|
include(platforms/android/configure.cmake)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#set backend dependend configurations
|
||||||
|
if(backend_qt_console OR backend_qt_widget)
|
||||||
|
add_definitions(-DQT_CONFIG)
|
||||||
|
if(backend_qt_console)
|
||||||
|
add_definitions(-DTESTSUITE -D_DEBUG)
|
||||||
|
add_definitions(-DCONSOLE_CONFIG -DCAPTURE_STDERR)
|
||||||
|
endif()
|
||||||
|
elseif(backend_sdl)
|
||||||
|
add_definitions(-DSDL_CONFIG)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find or build 3rd party libraries
|
||||||
|
FindOrBuildZLIB()
|
||||||
|
FindOrBuildOpenGL()
|
||||||
|
FindOrBuildTinyXML()
|
||||||
|
FindOrBuildZipFS()
|
||||||
|
FindOrBuildUNZIP()
|
||||||
|
FindOrBuildPNG()
|
||||||
|
FindOrBuildJPEG()
|
||||||
|
FindOrBuildBoost()
|
||||||
|
if(PSP)
|
||||||
|
FindOrBuildGIF()
|
||||||
|
endif()
|
||||||
|
if(ANDROID)
|
||||||
|
FindOrBuildOpenSL()
|
||||||
|
endif()
|
||||||
|
if(backend_sdl)
|
||||||
|
FindOrBuildSDL2()
|
||||||
|
endif()
|
||||||
|
if(backend_psp)
|
||||||
|
FindOrBuildFreetype()
|
||||||
|
FindOrBuildHgeTools()
|
||||||
|
FindOrBuildMikMod()
|
||||||
|
endif()
|
||||||
|
if(backend_qt_console OR backend_qt_widget)
|
||||||
|
FindOrBuildQt()
|
||||||
|
endif()
|
||||||
|
if(ANDROID)
|
||||||
|
include(DetectAndroidSDK)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_ANDROID_PACKAGE)
|
||||||
|
find_package(Ant REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#add jge and mtg projects
|
||||||
|
add_subdirectory(JGE)
|
||||||
|
add_subdirectory(projects/mtg)
|
||||||
|
|
||||||
|
if(BUILD_ANDROID_PACKAGE)
|
||||||
|
add_subdirectory(platforms/android/package)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IOS)
|
||||||
|
list_add_prefix(JGE_SOURCES " JGE/")
|
||||||
|
list_add_prefix(MTG_generic_src " projects/mtg/")
|
||||||
|
list_add_prefix(JGE_INCLUDE_DIRS " -IJGE/")
|
||||||
|
list_add_prefix(MTG_INCLUDE_DIRS " -Iprojects/mtg/")
|
||||||
|
list_add_prefix(TINYXML_SRC " thirdparty/tinyxml/")
|
||||||
|
list_add_prefix(UNZIP_SRC " thirdparty/unzip/")
|
||||||
|
list_add_prefix(ZIPFS_SRC " thirdparty/zipFS/")
|
||||||
|
|
||||||
|
file(WRITE makefile.ios
|
||||||
|
"ARCHS= armv7 armv7s \n"
|
||||||
|
"include ${THEOS_PATH}/makefiles/common.mk\n"
|
||||||
|
"TARGET= iphone:clang:latest:8.0 \n"
|
||||||
|
"APPLICATION_NAME = " ${PROJECT_NAME} "\n"
|
||||||
|
${PROJECT_NAME} "_FILES =" ${ZIPFS_SRC} ${UNZIP_SRC} ${TINYXML_SRC} ${JGE_SOURCES} ${MTG_generic_src} " thirdparty/Boost/lib/pthread/once.cpp thirdparty/Boost/lib/pthread/thread.cpp\n"
|
||||||
|
${PROJECT_NAME} "_LDFLAGS = -lz\n"
|
||||||
|
${PROJECT_NAME} "_FRAMEWORKS = UIKit CoreGraphics OpenGLES Foundation CFNetwork MobileCoreServices AVFoundation OpenAL AudioToolbox QuartzCore SystemConfiguration\n"
|
||||||
|
"include ${THEOS_PATH}/makefiles/application.mk\n"
|
||||||
|
"ADDITIONAL_CFLAGS = " ${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} " -I" ${ZIPFS_INCLUDE_DIR} " -I" ${UNZIP_INCLUDE_DIR} " -I" ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} " -I" ${ZLIB_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS} " "
|
||||||
|
"-DIOS -D__arm__ -DTIXML_USE_STL -DVERSION=\"$(GIT_VERSION)\" "
|
||||||
|
"-Wno-parentheses-equality -Wno-delete-non-virtual-dtor "
|
||||||
|
"-Wno-tautological-undefined-compare -Wno-undefined-bool-conversion "
|
||||||
|
"-Wno-visibility -Wno-deprecated-declarations -Wno-non-literal-null-conversion "
|
||||||
|
"-Wno-format -Wno-distributed-object-modifiers -Wno-missing-braces -Wno-uninitialized "
|
||||||
|
"-Wno-unused-const-variable -Wno-unused-function -Wno-unknown-warning-option -Wno-unused-local-typedef "
|
||||||
|
"-x objective-c++ \n"
|
||||||
|
|
||||||
|
"_THEOS_TARGET_ONLY_OBJCFLAGS :=\"\"\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
if(EXISTS "${ANDROID_EXECUTABLE}")
|
||||||
|
set(ANDROID_SDK_DETECT_QUIET TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
|
||||||
|
file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH)
|
||||||
|
|
||||||
|
if(CMAKE_HOST_WIN32)
|
||||||
|
set(ANDROID_SDK_OS windows)
|
||||||
|
elseif(CMAKE_HOST_APPLE)
|
||||||
|
set(ANDROID_SDK_OS macosx)
|
||||||
|
else()
|
||||||
|
set(ANDROID_SDK_OS linux)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#find android SDK: search in ANDROID_SDK first
|
||||||
|
find_host_program(ANDROID_EXECUTABLE
|
||||||
|
NAMES android.bat android
|
||||||
|
PATH_SUFFIXES tools
|
||||||
|
PATHS
|
||||||
|
ENV ANDROID_SDK
|
||||||
|
DOC "Android SDK location"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now search default paths
|
||||||
|
find_host_program(ANDROID_EXECUTABLE
|
||||||
|
NAMES android.bat android
|
||||||
|
PATH_SUFFIXES android-sdk-${ANDROID_SDK_OS}/tools
|
||||||
|
android-sdk-${ANDROID_SDK_OS}_x86/tools
|
||||||
|
android-sdk-${ANDROID_SDK_OS}_86/tools
|
||||||
|
android-sdk/tools
|
||||||
|
PATHS /opt
|
||||||
|
"${HOME_ENV_PATH}/NVPACK"
|
||||||
|
"$ENV{SystemDrive}/NVPACK"
|
||||||
|
"${ProgramFiles_ENV_PATH}/Android"
|
||||||
|
DOC "Android SDK location"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ANDROID_EXECUTABLE)
|
||||||
|
if(NOT ANDROID_SDK_DETECT_QUIET)
|
||||||
|
message(STATUS "Found android tool: ${ANDROID_EXECUTABLE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_filename_component(ANDROID_SDK_TOOLS_PATH "${ANDROID_EXECUTABLE}" PATH)
|
||||||
|
|
||||||
|
#read source.properties
|
||||||
|
if(EXISTS "${ANDROID_SDK_TOOLS_PATH}/source.properties")
|
||||||
|
file(STRINGS "${ANDROID_SDK_TOOLS_PATH}/source.properties" ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES REGEX "^[ ]*[^#].*$")
|
||||||
|
foreach(line ${ANDROID_SDK_TOOLS_SOURCE_PROPERTIES_LINES})
|
||||||
|
string(REPLACE "\\:" ":" line ${line})
|
||||||
|
string(REPLACE "=" ";" line ${line})
|
||||||
|
list(GET line 0 line_name)
|
||||||
|
list(GET line 1 line_value)
|
||||||
|
string(REPLACE "." "_" line_name ${line_name})
|
||||||
|
SET(ANDROID_TOOLS_${line_name} "${line_value}" CACHE INTERNAL "from ${ANDROID_SDK_TOOLS_PATH}/source.properties")
|
||||||
|
MARK_AS_ADVANCED(ANDROID_TOOLS_${line_name})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#fix missing revision (SDK tools before r9 don't set revision number correctly)
|
||||||
|
if(NOT ANDROID_TOOLS_Pkg_Revision)
|
||||||
|
SET(ANDROID_TOOLS_Pkg_Revision "Unknown" CACHE INTERNAL "")
|
||||||
|
MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Revision)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#fix missing description
|
||||||
|
if(NOT ANDROID_TOOLS_Pkg_Desc)
|
||||||
|
SET(ANDROID_TOOLS_Pkg_Desc "Android SDK Tools, revision ${ANDROID_TOOLS_Pkg_Revision}." CACHE INTERNAL "")
|
||||||
|
MARK_AS_ADVANCED(ANDROID_TOOLS_Pkg_Desc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#warn about outdated SDK
|
||||||
|
if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13)
|
||||||
|
SET(ANDROID_TOOLS_Pkg_Desc "${ANDROID_TOOLS_Pkg_Desc} It is recommended to update your SDK tools to revision 14 or newer." CACHE INTERNAL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ANDROID_TOOLS_Pkg_Revision GREATER 13)
|
||||||
|
SET(ANDROID_PROJECT_PROPERTIES_FILE project.properties)
|
||||||
|
SET(ANDROID_ANT_PROPERTIES_FILE ant.properties)
|
||||||
|
else()
|
||||||
|
SET(ANDROID_PROJECT_PROPERTIES_FILE default.properties)
|
||||||
|
SET(ANDROID_ANT_PROPERTIES_FILE build.properties)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ANDROID_MANIFEST_FILE AndroidManifest.xml)
|
||||||
|
set(ANDROID_LIB_PROJECT_FILES build.xml local.properties proguard-project.txt ${ANDROID_PROJECT_PROPERTIES_FILE})
|
||||||
|
set(ANDROID_PROJECT_FILES ${ANDROID_LIB_PROJECT_FILES})
|
||||||
|
|
||||||
|
#get installed targets
|
||||||
|
if(ANDROID_TOOLS_Pkg_Revision GREATER 11)
|
||||||
|
execute_process(COMMAND ${ANDROID_EXECUTABLE} list target -c
|
||||||
|
RESULT_VARIABLE ANDROID_PROCESS
|
||||||
|
OUTPUT_VARIABLE ANDROID_SDK_TARGETS
|
||||||
|
ERROR_VARIABLE ANDROID_PROCESS_ERRORS
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REGEX MATCHALL "[^\n]+" ANDROID_SDK_TARGETS "${ANDROID_SDK_TARGETS}")
|
||||||
|
else()
|
||||||
|
#old SDKs (r11 and older) don't provide compact list
|
||||||
|
execute_process(COMMAND ${ANDROID_EXECUTABLE} list target
|
||||||
|
RESULT_VARIABLE ANDROID_PROCESS
|
||||||
|
OUTPUT_VARIABLE ANDROID_SDK_TARGETS_FULL
|
||||||
|
ERROR_VARIABLE ANDROID_PROCESS_ERRORS
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REGEX MATCHALL "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" ANDROID_SDK_TARGETS_FULL "${ANDROID_SDK_TARGETS_FULL}")
|
||||||
|
|
||||||
|
SET(ANDROID_SDK_TARGETS "")
|
||||||
|
if(ANDROID_PROCESS EQUAL 0)
|
||||||
|
foreach(line ${ANDROID_SDK_TARGETS_FULL})
|
||||||
|
string(REGEX REPLACE "(^|\n)id: [0-9]+ or \"([^\n]+[0-9+])\"(\n|$)" "\\2" line "${line}")
|
||||||
|
list(APPEND ANDROID_SDK_TARGETS "${line}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID_PROCESS EQUAL 0)
|
||||||
|
message(ERROR "Failed to get list of installed Android targets.")
|
||||||
|
set(ANDROID_EXECUTABLE "ANDROID_EXECUTABLE-NOTFOUND")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# clear ANDROID_SDK_TARGET if no target is provided by user
|
||||||
|
if(NOT ANDROID_SDK_TARGET)
|
||||||
|
set(ANDROID_SDK_TARGET "" CACHE STRING "Android SDK target for the Wagic Java API and samples")
|
||||||
|
endif()
|
||||||
|
if(ANDROID_SDK_TARGETS)
|
||||||
|
set_property( CACHE ANDROID_SDK_TARGET PROPERTY STRINGS ${ANDROID_SDK_TARGETS} )
|
||||||
|
endif()
|
||||||
|
endif(ANDROID_EXECUTABLE)
|
||||||
|
|
||||||
|
# finds minimal installed SDK target compatible with provided names or API levels
|
||||||
|
# usage:
|
||||||
|
# get_compatible_android_api_level(VARIABLE [level1] [level2] ...)
|
||||||
|
macro(android_get_compatible_target VAR)
|
||||||
|
set(${VAR} "${VAR}-NOTFOUND")
|
||||||
|
if(ANDROID_SDK_TARGETS)
|
||||||
|
list(GET ANDROID_SDK_TARGETS 0 __lvl)
|
||||||
|
string(REGEX MATCH "[0-9]+$" __lvl "${__lvl}")
|
||||||
|
|
||||||
|
#find minimal level mathing to all provided levels
|
||||||
|
foreach(lvl ${ARGN})
|
||||||
|
string(REGEX MATCH "[0-9]+$" __level "${lvl}")
|
||||||
|
if(__level GREATER __lvl)
|
||||||
|
set(__lvl ${__level})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#search for compatible levels
|
||||||
|
foreach(lvl ${ANDROID_SDK_TARGETS})
|
||||||
|
string(REGEX MATCH "[0-9]+$" __level "${lvl}")
|
||||||
|
if(__level EQUAL __lvl)
|
||||||
|
#look for exact match
|
||||||
|
foreach(usrlvl ${ARGN})
|
||||||
|
if("${usrlvl}" STREQUAL "${lvl}")
|
||||||
|
set(${VAR} "${lvl}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if("${${VAR}}" STREQUAL "${lvl}")
|
||||||
|
break() #exact match was found
|
||||||
|
elseif(NOT ${VAR})
|
||||||
|
set(${VAR} "${lvl}")
|
||||||
|
endif()
|
||||||
|
elseif(__level GREATER __lvl)
|
||||||
|
if(NOT ${VAR})
|
||||||
|
set(${VAR} "${lvl}")
|
||||||
|
endif()
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
unset(__lvl)
|
||||||
|
unset(__level)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
unset(__android_project_chain CACHE)
|
||||||
|
|
||||||
|
# add_android_project(target_name ${path} NATIVE_DEPS opencv_core LIBRARY_DEPS ${Wagic_BINARY_DIR} SDK_TARGET 11)
|
||||||
|
macro(add_android_project target path)
|
||||||
|
# parse arguments
|
||||||
|
set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST)
|
||||||
|
set(__varname "android_proj_")
|
||||||
|
foreach(v ${android_proj_arglist})
|
||||||
|
set(${__varname}${v} "")
|
||||||
|
endforeach()
|
||||||
|
foreach(arg ${ARGN})
|
||||||
|
set(__var "${__varname}")
|
||||||
|
foreach(v ${android_proj_arglist})
|
||||||
|
if("${v}" STREQUAL "${arg}")
|
||||||
|
set(__varname "android_proj_${v}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(__var STREQUAL __varname)
|
||||||
|
list(APPEND ${__var} "${arg}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# get compatible SDK target
|
||||||
|
android_get_compatible_target(android_proj_sdk_target ${ANDROID_NATIVE_API_LEVEL} ${android_proj_SDK_TARGET})
|
||||||
|
|
||||||
|
if(NOT android_proj_sdk_target)
|
||||||
|
message(WARNING "Can not find any SDK target compatible with: ${ANDROID_NATIVE_API_LEVEL} ${android_proj_SDK_TARGET}
|
||||||
|
The project ${target} will not be build")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# check native dependencies
|
||||||
|
if(android_proj_IGNORE_JAVA)
|
||||||
|
ocv_check_dependencies(${android_proj_NATIVE_DEPS})
|
||||||
|
else()
|
||||||
|
ocv_check_dependencies(${android_proj_NATIVE_DEPS} opencv_java)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EXISTS "${path}/jni/Android.mk" )
|
||||||
|
# find if native_app_glue is used
|
||||||
|
file(STRINGS "${path}/jni/Android.mk" NATIVE_APP_GLUE REGEX ".*(call import-module,android/native_app_glue)" )
|
||||||
|
if(NATIVE_APP_GLUE)
|
||||||
|
if(ANDROID_NATIVE_API_LEVEL LESS 9 OR NOT EXISTS "${ANDROID_NDK}/sources/android/native_app_glue")
|
||||||
|
set(OCV_DEPENDENCIES_FOUND FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(OCV_DEPENDENCIES_FOUND AND android_proj_sdk_target AND ANDROID_EXECUTABLE AND ANT_EXECUTABLE AND ANDROID_TOOLS_Pkg_Revision GREATER 13 AND EXISTS "${path}/${ANDROID_MANIFEST_FILE}")
|
||||||
|
|
||||||
|
project(${target})
|
||||||
|
set(android_proj_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/.build")
|
||||||
|
|
||||||
|
# get project sources
|
||||||
|
file(GLOB_RECURSE android_proj_files RELATIVE "${path}" "${path}/res/*" "${path}/src/*")
|
||||||
|
|
||||||
|
if(NOT android_proj_IGNORE_MANIFEST)
|
||||||
|
list(APPEND android_proj_files ${ANDROID_MANIFEST_FILE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# copy sources out from the build tree
|
||||||
|
set(android_proj_file_deps "")
|
||||||
|
foreach(f ${android_proj_files})
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${android_proj_bin_dir}/${f}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${path}/${f}" "${android_proj_bin_dir}/${f}"
|
||||||
|
MAIN_DEPENDENCY "${path}/${f}"
|
||||||
|
COMMENT "Copying ${f}")
|
||||||
|
list(APPEND android_proj_file_deps "${path}/${f}" "${android_proj_bin_dir}/${f}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(android_proj_lib_deps_commands "")
|
||||||
|
set(android_proj_target_files ${ANDROID_PROJECT_FILES})
|
||||||
|
ocv_list_add_prefix(android_proj_target_files "${android_proj_bin_dir}/")
|
||||||
|
|
||||||
|
# process Android library dependencies
|
||||||
|
foreach(dep ${android_proj_LIBRARY_DEPS})
|
||||||
|
file(RELATIVE_PATH __dep "${android_proj_bin_dir}" "${dep}")
|
||||||
|
list(APPEND android_proj_lib_deps_commands
|
||||||
|
COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${android_proj_bin_dir}" --library "${__dep}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# fix Android project
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${android_proj_target_files}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove ${android_proj_target_files}
|
||||||
|
COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${android_proj_bin_dir}" --target "${android_proj_sdk_target}" --name "${target}"
|
||||||
|
${android_proj_lib_deps_commands}
|
||||||
|
MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
DEPENDS "${path}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
COMMENT "Updating Android project at ${path}. SDK target: ${android_proj_sdk_target}"
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND android_proj_file_deps ${android_proj_target_files})
|
||||||
|
|
||||||
|
# build native part
|
||||||
|
file(GLOB_RECURSE android_proj_jni_files "${path}/jni/*.c" "${path}/jni/*.h" "${path}/jni/*.cpp" "${path}/jni/*.hpp")
|
||||||
|
ocv_list_filterout(android_proj_jni_files "\\\\.svn")
|
||||||
|
|
||||||
|
if(android_proj_jni_files AND EXISTS ${path}/jni/Android.mk AND NOT DEFINED JNI_LIB_NAME)
|
||||||
|
# find local module name in Android.mk file to build native lib
|
||||||
|
file(STRINGS "${path}/jni/Android.mk" JNI_LIB_NAME REGEX "LOCAL_MODULE[ ]*:=[ ]*.*" )
|
||||||
|
string(REGEX REPLACE "LOCAL_MODULE[ ]*:=[ ]*([a-zA-Z_][a-zA-Z_0-9]*)[ ]*" "\\1" JNI_LIB_NAME "${JNI_LIB_NAME}")
|
||||||
|
|
||||||
|
if(JNI_LIB_NAME)
|
||||||
|
ocv_include_modules_recurse(${android_proj_NATIVE_DEPS})
|
||||||
|
ocv_include_directories("${path}/jni")
|
||||||
|
|
||||||
|
if(NATIVE_APP_GLUE)
|
||||||
|
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
|
||||||
|
list(APPEND android_proj_jni_files ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
|
||||||
|
ocv_warnings_disable(CMAKE_C_FLAGS -Wstrict-prototypes -Wunused-parameter -Wmissing-prototypes)
|
||||||
|
set(android_proj_NATIVE_DEPS ${android_proj_NATIVE_DEPS} android)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(${JNI_LIB_NAME} MODULE ${android_proj_jni_files})
|
||||||
|
target_link_libraries(${JNI_LIB_NAME} ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS})
|
||||||
|
|
||||||
|
set_target_properties(${JNI_LIB_NAME} PROPERTIES
|
||||||
|
OUTPUT_NAME "${JNI_LIB_NAME}"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}"
|
||||||
|
)
|
||||||
|
|
||||||
|
get_target_property(android_proj_jni_location "${JNI_LIB_NAME}" LOCATION)
|
||||||
|
if (NOT (CMAKE_BUILD_TYPE MATCHES "debug"))
|
||||||
|
add_custom_command(TARGET ${JNI_LIB_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${android_proj_jni_location}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# build java part
|
||||||
|
if(android_proj_IGNORE_JAVA)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${android_proj_bin_dir}/bin/${target}-debug.apk"
|
||||||
|
COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "${android_proj_bin_dir}/bin/${target}-debug.apk" # needed because ant does not update the timestamp of updated apk
|
||||||
|
WORKING_DIRECTORY "${android_proj_bin_dir}"
|
||||||
|
MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
DEPENDS ${android_proj_file_deps} ${JNI_LIB_NAME})
|
||||||
|
else()
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${android_proj_bin_dir}/bin/${target}-debug.apk"
|
||||||
|
COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "${android_proj_bin_dir}/bin/${target}-debug.apk" # needed because ant does not update the timestamp of updated apk
|
||||||
|
WORKING_DIRECTORY "${android_proj_bin_dir}"
|
||||||
|
MAIN_DEPENDENCY "${android_proj_bin_dir}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
DEPENDS "${Wagic_BINARY_DIR}/bin/classes.jar.dephelper" opencv_java # as we are part of Wagic we can just force this dependency
|
||||||
|
DEPENDS ${android_proj_file_deps} ${JNI_LIB_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(JNI_LIB_NAME)
|
||||||
|
|
||||||
|
add_custom_target(${target} ALL SOURCES "${android_proj_bin_dir}/bin/${target}-debug.apk" )
|
||||||
|
if(NOT android_proj_IGNORE_JAVA)
|
||||||
|
add_dependencies(${target} opencv_java)
|
||||||
|
endif()
|
||||||
|
if(android_proj_native_deps)
|
||||||
|
add_dependencies(${target} ${android_proj_native_deps})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(__android_project_chain)
|
||||||
|
add_dependencies(${target} ${__android_project_chain})
|
||||||
|
endif()
|
||||||
|
set(__android_project_chain ${target} CACHE INTERNAL "auxiliary variable used for Android progects chaining")
|
||||||
|
|
||||||
|
# put the final .apk to the Wagic's bin folder
|
||||||
|
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${android_proj_bin_dir}/bin/${target}-debug.apk" "${Wagic_BINARY_DIR}/bin/${target}.apk")
|
||||||
|
if(INSTALL_ANDROID_EXAMPLES AND "${target}" MATCHES "^example-")
|
||||||
|
#apk
|
||||||
|
install(FILES "${Wagic_BINARY_DIR}/bin/${target}.apk" DESTINATION "samples" COMPONENT main)
|
||||||
|
get_filename_component(sample_dir "${path}" NAME)
|
||||||
|
#java part
|
||||||
|
list(REMOVE_ITEM android_proj_files ${ANDROID_MANIFEST_FILE})
|
||||||
|
foreach(f ${android_proj_files} ${ANDROID_MANIFEST_FILE})
|
||||||
|
get_filename_component(install_subdir "${f}" PATH)
|
||||||
|
install(FILES "${android_proj_bin_dir}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main)
|
||||||
|
endforeach()
|
||||||
|
#jni part + eclipse files
|
||||||
|
file(GLOB_RECURSE jni_files RELATIVE "${path}" "${path}/jni/*" "${path}/.cproject")
|
||||||
|
ocv_list_filterout(jni_files "\\\\.svn")
|
||||||
|
foreach(f ${jni_files} ".classpath" ".project" ".settings/org.eclipse.jdt.core.prefs")
|
||||||
|
get_filename_component(install_subdir "${f}" PATH)
|
||||||
|
install(FILES "${path}/${f}" DESTINATION "samples/${sample_dir}/${install_subdir}" COMPONENT main)
|
||||||
|
endforeach()
|
||||||
|
#update proj
|
||||||
|
if(android_proj_lib_deps_commands)
|
||||||
|
set(inst_lib_opt " --library ../../sdk/java")
|
||||||
|
endif()
|
||||||
|
install(CODE "EXECUTE_PROCESS(COMMAND ${ANDROID_EXECUTABLE} --silent update project --path . --target \"${android_proj_sdk_target}\" --name \"${target}\" ${inst_lib_opt}
|
||||||
|
WORKING_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}\"
|
||||||
|
)" COMPONENT main)
|
||||||
|
#empty 'gen'
|
||||||
|
install(CODE "MAKE_DIRECTORY(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}/gen\")" COMPONENT main)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
find_host_program(ANT_EXECUTABLE "ant")
|
||||||
|
|
||||||
|
if(ANT_EXECUTABLE)
|
||||||
|
set(ANT_FOUND ON)
|
||||||
|
else()
|
||||||
|
set(ANT_FOUND OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ANT REQUIRED_VARS ANT_EXECUTABLE)
|
||||||
|
mark_as_advanced(ANT_EXECUTABLE ANT_FOUND)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# - Find OpenSL (actually OpenSLES)
|
||||||
|
# Find the OpenSLES includes and libraries
|
||||||
|
#
|
||||||
|
# OPENSL_INCLUDE_DIR - where to find dsound.h
|
||||||
|
# OPENSL_LIBRARIES - List of libraries when using dsound.
|
||||||
|
# OPENSL_FOUND - True if dsound found.
|
||||||
|
|
||||||
|
if(OPENSL_INCLUDE_DIR)
|
||||||
|
# Already in cache, be silent
|
||||||
|
set(OPENSL_FIND_QUIETLY TRUE)
|
||||||
|
endif(OPENSL_INCLUDE_DIR)
|
||||||
|
|
||||||
|
find_path(OPENSL_INCLUDE_DIR SLES/OpenSLES.h)
|
||||||
|
|
||||||
|
find_library(OPENSL_LIBRARY NAMES OpenSLES)
|
||||||
|
|
||||||
|
# Handle the QUIETLY and REQUIRED arguments and set OPENSL_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE.
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(OPENSL DEFAULT_MSG
|
||||||
|
OPENSL_INCLUDE_DIR OPENSL_LIBRARY)
|
||||||
|
|
||||||
|
if(OPENSL_FOUND)
|
||||||
|
set(OPENSL_LIBRARIES ${OPENSL_LIBRARY})
|
||||||
|
else(OPENSL_FOUND)
|
||||||
|
set(OPENSL_LIBRARIES)
|
||||||
|
endif(OPENSL_FOUND)
|
||||||
|
|
||||||
|
mark_as_advanced(OPENSL_INCLUDE_DIR OPENSL_LIBRARY)
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
macro(FindOrBuildZipFS)
|
||||||
|
if(BUILD_ZIPFS)
|
||||||
|
add_subdirectory(
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/zipFS
|
||||||
|
${CMAKE_BINARY_DIR}/thirdparty/zipFS)
|
||||||
|
set(ZIPFS_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/zipFS)
|
||||||
|
set(ZIPFS_LIBRARY zipFS)
|
||||||
|
else()
|
||||||
|
message(WARNING "ZIPFS must get build")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildTinyXML)
|
||||||
|
if(BUILD_TINYXML)
|
||||||
|
add_definitions(-DTIXML_USE_STL)
|
||||||
|
add_subdirectory(
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/tinyxml
|
||||||
|
${CMAKE_BINARY_DIR}/thirdparty/tinyxml)
|
||||||
|
set(TINYXML_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/tinyxml)
|
||||||
|
set(TINYXML_LIBRARIES tinyxml)
|
||||||
|
else()
|
||||||
|
find_package(TinyXML REQUIRED)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildSDL2)
|
||||||
|
if(BUILD_SDL2)
|
||||||
|
if(WIN32)
|
||||||
|
#SDL2 DirectX build is somehow broken...
|
||||||
|
set(SDL_AUDIO FALSE)
|
||||||
|
set(SDL_JOYSTICK FALSE)
|
||||||
|
set(SDL_HAPTIC FALSE)
|
||||||
|
set(SDL_SHARED FALSE)
|
||||||
|
endif()
|
||||||
|
add_subdirectory(${CMAKE_SOURCE_DIR}/thirdparty/SDL2)
|
||||||
|
set(SDL2_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/SDL2/include ${CMAKE_BINARY_DIR}/thirdparty/SDL2)
|
||||||
|
if(EMSCRIPTEN)
|
||||||
|
set(SDL2_LIBRARY SDL2-static)
|
||||||
|
else()
|
||||||
|
set(SDL2_LIBRARY SDL2)
|
||||||
|
endif()
|
||||||
|
elseif(NOT EMSCRIPTEN)
|
||||||
|
find_package(SDL2)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildUNZIP)
|
||||||
|
if(BUILD_UNZIP)
|
||||||
|
add_subdirectory(
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/unzip
|
||||||
|
${CMAKE_BINARY_DIR}/thirdparty/unzip)
|
||||||
|
set(UNZIP_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/unzip)
|
||||||
|
set(UNZIP_LIBRARY unzip)
|
||||||
|
else()
|
||||||
|
message(WARNING "UNZIP must get build")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildBoost)
|
||||||
|
if(PSP OR UNIX OR WIN32 OR IOS)
|
||||||
|
#the psp build does not need more than a few headers
|
||||||
|
#todo: remove from the repository
|
||||||
|
set(BOOST_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/Boost)
|
||||||
|
# elseif(WIN32)
|
||||||
|
#set BOOST_ROOT to the root of boost
|
||||||
|
# set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
# set(Boost_USE_MULTITHREADED ON)
|
||||||
|
# set(BOOST_ROOT $ENV{BOOST_ROOT})
|
||||||
|
|
||||||
|
# set(BOOST_LIBRARYDIR ${BOOST_ROOT}/libs)
|
||||||
|
# set(BOOST_INCLUDEDIR ${BOOST_ROOT})
|
||||||
|
|
||||||
|
# find_package(Boost COMPONENTS system thread date_time REQUIRED)
|
||||||
|
# if(NOT Boost_FOUND)
|
||||||
|
# message("Set the BOOST_ROOT environment variable to point to your boost installation.")
|
||||||
|
# message("We need system thread and date_time compiled static libs")
|
||||||
|
# message("These libs are compiler specific.")
|
||||||
|
# endif()
|
||||||
|
# elseif(UNIX AND NOT ANDROID)
|
||||||
|
# find_package(Boost COMPONENTS system thread date_time REQUIRED)
|
||||||
|
elseif(ANDROID)
|
||||||
|
#this is a hack. we compile a few boost libds directly into
|
||||||
|
#the application. we should require static libs for android
|
||||||
|
#to be available. maybe we could add the build option to
|
||||||
|
#download and build a compatible boost version
|
||||||
|
find_path(BOOST_INCLUDE_DIRS NAMES bind.hpp HINTS $ENV{ANDROID_BOOST_ROOT} PATH_SUFFIXES boost)
|
||||||
|
|
||||||
|
if(BOOST_INCLUDE_DIRS)
|
||||||
|
get_filename_component(BOOST_INCLUDE_DIRS ${BOOST_INCLUDE_DIRS} PATH)
|
||||||
|
set(ANDROID_BOOST_PTHREAD_SRC_DIR ${BOOST_INCLUDE_DIRS}/libs/thread/src/pthread)
|
||||||
|
set(ANDROID_BOOST_SYSTEM_SRC_DIR ${BOOST_INCLUDE_DIRS}/libs/system/src/)
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "We require a few boost sources to get compiled into wagic. Please point the ANDROID_BOOST_ROOT environment variable to a boost-source copy root.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
macro(FindOrBuildZLIB)
|
||||||
|
if(BUILD_ZLIB)
|
||||||
|
add_subdirectory(${CMAKE_SOURCE_DIR}/thirdparty/zlib)
|
||||||
|
set(ZLIB_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/zlib ${CMAKE_BINARY_DIR}/thirdparty/zlib)
|
||||||
|
set(ZLIB_LIBRARIES zlib)
|
||||||
|
else()
|
||||||
|
if(WIN32)
|
||||||
|
set(ZLIB_ROOT ${CMAKE_SOURCE_DIR}/thirdparty/binary/win)
|
||||||
|
find_package(ZLIB)
|
||||||
|
else()
|
||||||
|
if(backend_qt_console OR backend_qt_widget OR EMSCRIPTEN)
|
||||||
|
set(ZLIB_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/zlib)
|
||||||
|
else()
|
||||||
|
find_package(ZLIB)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildGIF)
|
||||||
|
if(BUILD_GIF)
|
||||||
|
message(WARNING "GIF sources are currently not included within the wagic tree")
|
||||||
|
else()
|
||||||
|
if(PSP)
|
||||||
|
find_package(GIF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildJPEG)
|
||||||
|
if(BUILD_JPEG)
|
||||||
|
add_subdirectory(${CMAKE_SOURCE_DIR}/thirdparty/libjpeg ${CMAKE_BINARY_DIR}/thirdparty/libjpeg)
|
||||||
|
set(JPEG_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/libjpeg)
|
||||||
|
set(JPEG_LIBRARY jpeg)
|
||||||
|
else()
|
||||||
|
if(WIN32)
|
||||||
|
#findJPEG does currently not provide prefix vars to guide it
|
||||||
|
find_path(JPEG_INCLUDE_DIR jpeglib.h HINTS ${CMAKE_SOURCE_DIR}/thirdparty/binary/win/include)
|
||||||
|
find_library(JPEG_LIBRARY NAMES libjpeg-static-mt HINTS ${CMAKE_SOURCE_DIR}/thirdparty/binary/win/lib)
|
||||||
|
|
||||||
|
if(JPEG_INCLUDE_DIR AND JPEG_LIBRARY)
|
||||||
|
set(JPEG_FOUND ON)
|
||||||
|
mark_as_advanced(JPEG_INCLUDE_DIR JPEG_LIBRARY)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not find JPEG on windows")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
find_package(JPEG)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildPNG)
|
||||||
|
if(BUILD_PNG)
|
||||||
|
add_subdirectory(${CMAKE_SOURCE_DIR}/thirdparty/libpng ${CMAKE_BINARY_DIR}/thirdparty/libpng)
|
||||||
|
set(PNG_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/libpng)
|
||||||
|
# find_path(PNG_INCLUDE_DIRS NAMES png.h HINTS ${CMAKE_SOURCE_DIR}/thirdparty/libpng)
|
||||||
|
set(PNG_LIBRARIES png)
|
||||||
|
else()
|
||||||
|
if(WIN32)
|
||||||
|
#findPNG does currently not provide prefix vars. so we find
|
||||||
|
find_path(PNG_INCLUDE_DIRS png.h HINTS ${CMAKE_SOURCE_DIR}/thirdparty/binary/win/include)
|
||||||
|
find_library(PNG_LIBRARIES libpng HINTS ${CMAKE_SOURCE_DIR}/thirdparty/binary/win/lib)
|
||||||
|
|
||||||
|
if (PNG_LIBRARIES AND PNG_INCLUDE_DIRS)
|
||||||
|
set(PNG_FOUND ON)
|
||||||
|
mark_as_advanced(PNG_INCLUDE_DIRS PNG_LIBRARIES)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not find PNG on windows")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
find_package(PNG)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildFreetype)
|
||||||
|
if(PSP)
|
||||||
|
set(ENV{FREETYPE_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/include)
|
||||||
|
set(ENV{FREETYPE_LIBRARIES} freetype)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildHgeTools)
|
||||||
|
if(PSP)
|
||||||
|
find_library(HGETOOLS_LIBRARY NAMES hgetools HINTS "${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/lib")
|
||||||
|
set(HGETOOLS_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/include")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildMikMod)
|
||||||
|
if(PSP)
|
||||||
|
find_library(MIKMOD_LIBRARY NAMES mikmod HINTS "${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/lib")
|
||||||
|
set(MIKMOD_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/include")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildQt)
|
||||||
|
if(backend_qt_console)
|
||||||
|
add_definitions(-DCONSOLE_CONFIG -DTESTSUITE)
|
||||||
|
find_package(Qt5Core REQUIRED)
|
||||||
|
find_package(Qt5 COMPONENTS Core Network Multimedia REQUIRED)
|
||||||
|
elseif(backend_qt_widget)
|
||||||
|
add_definitions(-DQT_WIDGET)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
|
find_package(Qt5 COMPONENTS Core Gui OpenGL Network Multimedia REQUIRED)
|
||||||
|
endif()
|
||||||
|
# include(${QT_USE_FILE})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildOpenGL)
|
||||||
|
if(backend_sdl OR backend_qt_console OR backend_qt_widget)
|
||||||
|
if(ANDROID)
|
||||||
|
#find openglesv on android
|
||||||
|
set(OPENGL_LIBRARIES "-ldl -lGLESv1_CM -lGLESv2 -llog -landroid")
|
||||||
|
elseif(EMSCRIPTEN)
|
||||||
|
set(OPENGL_LIBRARIES "")
|
||||||
|
else()
|
||||||
|
find_package(OpenGL)
|
||||||
|
# find_package(GLUT)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildOpenSL)
|
||||||
|
find_package(OpenSL)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(FindOrBuildPSPSDK)
|
||||||
|
find_package(PSPSDK COMPONENTS psppower pspmpeg pspaudiocodec pspaudiolib pspaudio pspmp3 pspgum pspgu psprtc pspfpu REQUIRED)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# - Try to find PSPSDK
|
||||||
|
# Once done this will define
|
||||||
|
# PSPSDK_FOUND - System has PSPSDK
|
||||||
|
# PSPSDK_INCLUDE_DIR - The PSPSDK include directories
|
||||||
|
# PSPSDK_LIB - The libraries requested with the components field
|
||||||
|
# PSPSDK_REQUIRED_LIB - The libriries the PSPSDK needs always
|
||||||
|
# PSPSDK_CFLAGS - The CFLAGS to use
|
||||||
|
# PSPSDK_PATH - The output of psp-config --pspsdk-path
|
||||||
|
# PSPSDK_PREFIX - The output of psp-config --psp-prefix
|
||||||
|
# PSPSDK_CXX_COMPILER - The PSPSDK CXX Compilers path
|
||||||
|
# PSPSDK_CXX_LINKER - The PSPSDK CXX Linker command
|
||||||
|
# PSPSDK_FIXUP_IMPORTS_COMMAND - psp-fixup-imports command
|
||||||
|
# PSPSDK_PRXGEN_COMMAND - psp-prxgen command
|
||||||
|
# PSPSDK_PACK_PBP_COMMAND - pack-pbp command
|
||||||
|
# PSPSDK_MKSFO_COMMAND - mksfo command
|
||||||
|
|
||||||
|
#find the psp-config progams absolute path
|
||||||
|
#psp-config needs to be reachable via the system shell (PATH)
|
||||||
|
find_program(PSP_CONFIG_PROGRAM psp-config)
|
||||||
|
|
||||||
|
#TODO: check if something is REQUIRED and throw errors instead of messages
|
||||||
|
if(PSP_CONFIG_PROGRAM)
|
||||||
|
find_program(PSPSDK_CXX_COMPILER psp-g++)
|
||||||
|
find_program(PSPSDK_CXX_LINKER psp-gcc)
|
||||||
|
find_program(PSPSDK_FIXUP_IMPORTS_COMMAND psp-fixup-imports)
|
||||||
|
find_program(PSPSDK_PRXGEN_COMMAND psp-prxgen)
|
||||||
|
find_program(PSPSDK_PACK_PBP_COMMAND pack-pbp)
|
||||||
|
find_program(PSPSDK_MKSFO_COMMAND mksfo)
|
||||||
|
|
||||||
|
#ask psp-config for the
|
||||||
|
execute_process(COMMAND psp-config --pspsdk-path OUTPUT_VARIABLE PSPSDK_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
execute_process(COMMAND psp-config --psp-prefix OUTPUT_VARIABLE PSPSDK_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
set(PSPSDK_INCLUDE_DIR "${PSPSDK_PATH}/include")
|
||||||
|
|
||||||
|
foreach(_COMPONENT ${PSPSDK_FIND_COMPONENTS})
|
||||||
|
find_library(PSPSDK_${_COMPONENT} NAMES ${_COMPONENT})
|
||||||
|
if(NOT PSPSDK_${_COMPONENT})
|
||||||
|
message(SEND_ERROR "PSPSDK: ${_COMPONENT} not found")
|
||||||
|
else()
|
||||||
|
set(PSPSDK_LIB ${PSPSDK_LIB} ${PSPSDK_${_COMPONENT}})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#find libs which pspsdk does require to link even if the programs does not need one of them directly
|
||||||
|
foreach(_COMPONENT pspdebug pspdisplay pspge pspctrl pspsdk c pspnet pspnet_inet pspnet_apctl pspnet_resolver psputility pspuser)
|
||||||
|
find_library(PSPSDK_${_COMPONENT} NAMES ${_COMPONENT})
|
||||||
|
if(NOT PSPSDK_${_COMPONENT})
|
||||||
|
message(SEND_ERROR "PSPSDK: ${_COMPONENT} not found")
|
||||||
|
else()
|
||||||
|
set(PSPSDK_REQUIRED_LIB ${PSPSDK_REQUIRED_LIB} ${PSPSDK_${_COMPONENT}})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE
|
||||||
|
# if all listed variables are TRUE
|
||||||
|
find_package_handle_standard_args(PSPSDK DEFAULT_MSG
|
||||||
|
PSPSDK_CXX_LINKER PSPSDK_CXX_COMPILER PSPSDK_PATH PSPSDK_PREFIX PSPSDK_LIB PSPSDK_REQUIRED_LIB PSPSDK_INCLUDE_DIR)
|
||||||
|
|
||||||
|
mark_as_advanced(PSPSDK_CXX_LINKER PSPSDK_CXX_COMPILER PSPSDK_PATH PSPSDK_PREFIX PSPSDK_LIB PSPSDK_REQUIRED_LIB PSPSDK_INCLUDE_DIR)
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
|
||||||
|
# Locate SDL2 library
|
||||||
|
# This module defines
|
||||||
|
# SDL2_LIBRARY, the name of the library to link against
|
||||||
|
# SDL2_FOUND, if false, do not try to link to SDL2
|
||||||
|
# SDL2_INCLUDE_DIR, where to find SDL.h
|
||||||
|
#
|
||||||
|
# This module responds to the the flag:
|
||||||
|
# SDL2_BUILDING_LIBRARY
|
||||||
|
# If this is defined, then no SDL2_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 the proper link flags
|
||||||
|
# as part of the returned SDL2_LIBRARY variable.
|
||||||
|
#
|
||||||
|
# Don't forget to include SDL2main.h and SDL2main.m your project for the
|
||||||
|
# OS X framework based version. (Other versions link to -lSDL2main 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 SDL2_LIBRARY_TEMP in your configuration
|
||||||
|
# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
|
||||||
|
# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
|
||||||
|
# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
|
||||||
|
# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
|
||||||
|
# as appropriate. These values are used to generate the final SDL2_LIBRARY
|
||||||
|
# variable, but when these values are unset, SDL2_LIBRARY does not get created.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# $SDL2DIR is an environment variable that would
|
||||||
|
# correspond to the ./configure --prefix=$SDL2DIR
|
||||||
|
# used in building SDL2.
|
||||||
|
# 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" SDL2 guidelines.
|
||||||
|
# Added a search for SDL2main 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
|
||||||
|
# SDL2_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 SDL2/SDL.h to just SDL.h
|
||||||
|
# This needed to change because "proper" SDL2 convention
|
||||||
|
# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
|
||||||
|
# reasons because not all systems place things in SDL2/ (see FreeBSD).
|
||||||
|
#
|
||||||
|
# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake
|
||||||
|
# module with the minor edit of changing "SDL" to "SDL2" where necessary. This
|
||||||
|
# was not created for redistribution, and exists temporarily pending official
|
||||||
|
# SDL2 CMake modules.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2003-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
|
||||||
|
HINTS
|
||||||
|
$ENV{SDL2DIR}
|
||||||
|
PATH_SUFFIXES include/SDL2 include
|
||||||
|
PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/usr/local/include/SDL2
|
||||||
|
/usr/include/SDL2
|
||||||
|
/sw # Fink
|
||||||
|
/opt/local # DarwinPorts
|
||||||
|
/opt/csw # Blastwave
|
||||||
|
/opt
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(SDL2_LIBRARY_TEMP
|
||||||
|
NAMES SDL2
|
||||||
|
HINTS
|
||||||
|
$ENV{SDL2DIR}
|
||||||
|
PATH_SUFFIXES lib64 lib
|
||||||
|
PATHS
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
)
|
||||||
|
|
||||||
|
#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}")
|
||||||
|
|
||||||
|
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
|
IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||||
|
# Non-OS X framework versions expect you to also dynamically link to
|
||||||
|
# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
|
||||||
|
# seem to provide SDL2main for compatibility even though they don't
|
||||||
|
# necessarily need it.
|
||||||
|
FIND_LIBRARY(SDL2MAIN_LIBRARY
|
||||||
|
NAMES SDL2main
|
||||||
|
HINTS
|
||||||
|
$ENV{SDL2DIR}
|
||||||
|
PATH_SUFFIXES lib64 lib
|
||||||
|
PATHS
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
)
|
||||||
|
ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
|
||||||
|
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
|
|
||||||
|
# SDL2 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 -lSDL2main -lSDL2 -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(SDL2_FOUND "NO")
|
||||||
|
IF(SDL2_LIBRARY_TEMP)
|
||||||
|
# For SDL2main
|
||||||
|
IF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
|
IF(SDL2MAIN_LIBRARY)
|
||||||
|
SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||||
|
ENDIF(SDL2MAIN_LIBRARY)
|
||||||
|
ENDIF(NOT SDL2_BUILDING_LIBRARY)
|
||||||
|
|
||||||
|
# For OS X, SDL2 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)
|
||||||
|
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
|
||||||
|
ENDIF(APPLE)
|
||||||
|
|
||||||
|
# For threads, as mentioned Apple doesn't need this.
|
||||||
|
# In fact, there seems to be a problem if I used the Threads package
|
||||||
|
# and try using this line, so I'm just skipping it entirely for OS X.
|
||||||
|
IF(NOT APPLE)
|
||||||
|
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
ENDIF(NOT APPLE)
|
||||||
|
|
||||||
|
# For MinGW library
|
||||||
|
IF(MINGW)
|
||||||
|
SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
|
||||||
|
ENDIF(MINGW)
|
||||||
|
|
||||||
|
# Set the final string here so the GUI reflects the final state.
|
||||||
|
SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
|
||||||
|
# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
|
||||||
|
SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
|
||||||
|
|
||||||
|
SET(SDL2_FOUND "YES")
|
||||||
|
ENDIF(SDL2_LIBRARY_TEMP)
|
||||||
|
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
|
||||||
|
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
||||||
|
mark_as_advanced(SDL2MAIN_LIBRARY SDL2_LIBRARY SDL2_INCLUDE_DIR)
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# - Find TinyXML
|
||||||
|
# Find the native TinyXML includes and library
|
||||||
|
#
|
||||||
|
# TINYXML_FOUND - True if TinyXML found.
|
||||||
|
# TINYXML_INCLUDE_DIR - where to find tinyxml.h, etc.
|
||||||
|
# TINYXML_LIBRARIES - List of libraries when using TinyXML.
|
||||||
|
#
|
||||||
|
|
||||||
|
IF( TINYXML_INCLUDE_DIR )
|
||||||
|
# Already in cache, be silent
|
||||||
|
SET( TinyXML_FIND_QUIETLY TRUE )
|
||||||
|
ENDIF( TINYXML_INCLUDE_DIR )
|
||||||
|
|
||||||
|
FIND_PATH( TINYXML_INCLUDE_DIR "tinyxml.h"
|
||||||
|
PATH_SUFFIXES "tinyxml" )
|
||||||
|
|
||||||
|
FIND_LIBRARY( TINYXML_LIBRARIES
|
||||||
|
NAMES "tinyxml"
|
||||||
|
PATH_SUFFIXES "tinyxml" )
|
||||||
|
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set TINYXML_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
INCLUDE( "FindPackageHandleStandardArgs" )
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS( "TinyXML" DEFAULT_MSG TINYXML_INCLUDE_DIR TINYXML_LIBRARIES )
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED( TINYXML_INCLUDE_DIR TINYXML_LIBRARIES )
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
include(CMakeForceCompiler)
|
||||||
|
|
||||||
|
# this one is important
|
||||||
|
SET(CMAKE_SYSTEM_NAME "Generic")
|
||||||
|
#this one not so much
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
|
||||||
|
set (CMAKE_SYSTEM_NAME Generic)
|
||||||
|
|
||||||
|
# Just point to anything that exists.
|
||||||
|
# We don't need CMake to generate proper build files.
|
||||||
|
set(CMAKE_C_COMPILER ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
set(CMAKE_CXX_COMPILER ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
# Skip the platform compiler checks
|
||||||
|
set (CMAKE_CXX_COMPILER_WORKS TRUE)
|
||||||
|
set (CMAKE_C_COMPILER_WORKS TRUE)
|
||||||
|
|
||||||
|
#how libraries look
|
||||||
|
SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
|
||||||
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
|
||||||
|
|
||||||
|
SET(CMAKE_SYSTEM_INCLUDE_PATH
|
||||||
|
${THEOS_PATH}/include
|
||||||
|
${CMAKE_INSTALL_PREFIX}/include
|
||||||
|
${CMAKE_SYSTEM_INCLUDE_PATH})
|
||||||
|
|
||||||
|
# where is the target environment
|
||||||
|
SET(CMAKE_SYSTEM_LIBRARY_PATH
|
||||||
|
${THEOS_PATH}/lib
|
||||||
|
${CMAKE_INSTALL_PREFIX}/lib
|
||||||
|
${CMAKE_SYSTEM_LIBRARY_PATH})
|
||||||
|
|
||||||
|
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH
|
||||||
|
${CMAKE_SOURCE_DIR}
|
||||||
|
${THEOS_PATH}
|
||||||
|
${THEOS_PATH}/lib
|
||||||
|
${THEOS_PATH}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
# for libraries and headers in the target directories and then in the host
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY FIRST)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE FIRST)
|
||||||
|
|
||||||
|
set(IOS 1)
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
include(CMakeForceCompiler)
|
||||||
|
|
||||||
|
# this one is important
|
||||||
|
SET(CMAKE_SYSTEM_NAME "Generic")
|
||||||
|
#this one not so much
|
||||||
|
SET(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
|
||||||
|
find_program(PSP_CONFIG_PROGRAM psp-config)
|
||||||
|
|
||||||
|
execute_process(COMMAND psp-config --pspsdk-path OUTPUT_VARIABLE PSPSDK_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
execute_process(COMMAND psp-config --psp-prefix OUTPUT_VARIABLE PSPSDK_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
# specify compiler and linker:
|
||||||
|
find_program(PSP_GPP psp-g++)
|
||||||
|
find_program(PSP_GCC psp-gcc)
|
||||||
|
|
||||||
|
CMAKE_FORCE_C_COMPILER(${PSP_GCC} GNU)
|
||||||
|
CMAKE_FORCE_CXX_COMPILER(${PSP_GPP} GNU)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -G0")
|
||||||
|
|
||||||
|
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||||
|
set(CMAKE_CXX_LINK_EXECUTABLE "${PSP_GCC} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||||
|
|
||||||
|
#how libraries look
|
||||||
|
SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
|
||||||
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
|
||||||
|
|
||||||
|
# where is the target environment
|
||||||
|
SET(CMAKE_SYSTEM_INCLUDE_PATH
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/include
|
||||||
|
${PSPSDK_PATH}/include
|
||||||
|
${PSPSDK_PREFIX}/include
|
||||||
|
${CMAKE_INSTALL_PREFIX}/include
|
||||||
|
${CMAKE_SYSTEM_INCLUDE_PATH})
|
||||||
|
|
||||||
|
SET(CMAKE_SYSTEM_LIBRARY_PATH
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/lib
|
||||||
|
${PSPSDK_PATH}/lib
|
||||||
|
${PSPSDK_PREFIX}/lib
|
||||||
|
${CMAKE_INSTALL_PREFIX}/lib
|
||||||
|
${CMAKE_SYSTEM_LIBRARY_PATH})
|
||||||
|
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/binary/psp
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/lib
|
||||||
|
${CMAKE_SOURCE_DIR}/thirdparty/binary/psp/include
|
||||||
|
${PSPSDK_PATH}
|
||||||
|
${PSPSDK_PATH}/lib
|
||||||
|
${PSPSDK_PATH}/include
|
||||||
|
${PSPSDK_PREFIX}
|
||||||
|
${PSPSDK_PREFIX}/lib
|
||||||
|
${PSPSDK_PREFIX}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
# search for programs in the build host directories
|
||||||
|
# for libraries and headers in the target directories and then in the host
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY FIRST)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE FIRST)
|
||||||
|
|
||||||
|
set(PSP 1)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
macro(WAGIC_OPTION variable description value)
|
||||||
|
set(__value ${value})
|
||||||
|
set(__condition "")
|
||||||
|
set(__varname "__value")
|
||||||
|
foreach(arg ${ARGN})
|
||||||
|
if(arg STREQUAL "IF" OR arg STREQUAL "if")
|
||||||
|
set(__varname "__condition")
|
||||||
|
else()
|
||||||
|
list(APPEND ${__varname} ${arg})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
unset(__varname)
|
||||||
|
if("${__condition}" STREQUAL "")
|
||||||
|
set(__condition 2 GREATER 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${__condition})
|
||||||
|
if("${__value}" MATCHES ";")
|
||||||
|
if(${__value})
|
||||||
|
option(${variable} "${description}" ON)
|
||||||
|
else()
|
||||||
|
option(${variable} "${description}" OFF)
|
||||||
|
endif()
|
||||||
|
elseif(DEFINED ${__value})
|
||||||
|
if(${__value})
|
||||||
|
option(${variable} "${description}" ON)
|
||||||
|
else()
|
||||||
|
option(${variable} "${description}" OFF)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
option(${variable} "${description}" ${__value})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
unset(${variable} CACHE)
|
||||||
|
endif()
|
||||||
|
unset(__condition)
|
||||||
|
unset(__value)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# add prefix to each item in the list
|
||||||
|
macro(list_add_prefix LST PREFIX)
|
||||||
|
set(__tmp "")
|
||||||
|
foreach(item ${${LST}})
|
||||||
|
list(APPEND __tmp "${PREFIX}${item}")
|
||||||
|
endforeach()
|
||||||
|
set(${LST} ${__tmp})
|
||||||
|
unset(__tmp)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
macro(find_host_program)
|
||||||
|
set(_find_program ${CMAKE_FIND_ROOT_PATH_MODE_PROGRAM})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
find_program(${ARGN})
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ${_find_program})
|
||||||
|
unset(_find_program)
|
||||||
|
endmacro()
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
#the sources, jge will need always
|
||||||
|
set(JGE_generic_src
|
||||||
|
src/Encoding.cpp
|
||||||
|
src/JAnimator.cpp
|
||||||
|
src/JApp.cpp
|
||||||
|
src/JDistortionMesh.cpp
|
||||||
|
src/JFileSystem.cpp
|
||||||
|
src/JGameObject.cpp
|
||||||
|
src/JGE.cpp
|
||||||
|
src/JGui.cpp
|
||||||
|
src/JLogger.cpp
|
||||||
|
src/JLBFont.cpp
|
||||||
|
src/JOBJModel.cpp
|
||||||
|
src/JParticle.cpp
|
||||||
|
src/JParticleEffect.cpp
|
||||||
|
src/JParticleEmitter.cpp
|
||||||
|
src/JParticleSystem.cpp
|
||||||
|
src/JResourceManager.cpp
|
||||||
|
src/JSpline.cpp
|
||||||
|
src/JSprite.cpp
|
||||||
|
src/Vector2D.cpp)
|
||||||
|
|
||||||
|
set(JGE_hge_src
|
||||||
|
src/hge/hgecolor.cpp
|
||||||
|
src/hge/hgedistort.cpp
|
||||||
|
src/hge/hgefont.cpp
|
||||||
|
src/hge/hgeparticle.cpp
|
||||||
|
src/hge/hgerect.cpp
|
||||||
|
src/hge/hgevector.cpp)
|
||||||
|
|
||||||
|
#the sources we need to get graphical output desktops
|
||||||
|
#used by qt-widget build option
|
||||||
|
set(JGE_graphics_src
|
||||||
|
src/Downloader.cpp
|
||||||
|
include/Downloader.h
|
||||||
|
src/JMD2Model.cpp
|
||||||
|
src/pc/JGfx.cpp)
|
||||||
|
|
||||||
|
#the sources we need to fake graphical output on desktops
|
||||||
|
#these are used for the console-only testsuit
|
||||||
|
set(JGE_console_src
|
||||||
|
src/OutputCapturer.cpp
|
||||||
|
src/JGfx-fake.cpp)
|
||||||
|
|
||||||
|
#the sources we need on linux
|
||||||
|
set(JGE_linux_src
|
||||||
|
src/JNetwork.cpp
|
||||||
|
src/pc/JSocket.cpp
|
||||||
|
src/pc/JSfx.cpp)
|
||||||
|
|
||||||
|
set(JGE_android_src
|
||||||
|
src/JNetwork.cpp
|
||||||
|
src/JSocket.cpp
|
||||||
|
src/android/JSfx.cpp)
|
||||||
|
|
||||||
|
#the sources we need if we compile for psp
|
||||||
|
#note: main.cpp contains the main-function.
|
||||||
|
#the other main functions reside in projects/mtg to reduce cross-library dependencies.
|
||||||
|
#there may be a way to get all main-functions into the same project
|
||||||
|
set(JGE_psp_src
|
||||||
|
src/JNetwork.cpp
|
||||||
|
src/JSocket.cpp
|
||||||
|
src/JGfx.cpp
|
||||||
|
src/JSfx.cpp
|
||||||
|
src/JAudio.cpp
|
||||||
|
src/JMP3.cpp
|
||||||
|
src/decoder_prx.cpp
|
||||||
|
src/main.cpp
|
||||||
|
src/vram.cpp)
|
||||||
|
|
||||||
|
set(JGE_ios_src
|
||||||
|
src/iOS/main.m
|
||||||
|
src/iOS/wagicAppDelegate.m
|
||||||
|
src/iOS/ES2Renderer.m
|
||||||
|
src/iOS/EAGLView.m
|
||||||
|
src/iOS/EAGLViewController.m
|
||||||
|
src/iOS/JSfx.cpp)
|
||||||
|
|
||||||
|
set(JGE_windows_src
|
||||||
|
src/JNetwork.cpp
|
||||||
|
src/pc/JSocket.cpp
|
||||||
|
src/windows/JSfx.cpp)
|
||||||
|
|
||||||
|
set(JGE_INCLUDE_DIRS include include/hge)
|
||||||
|
set(EXTRA_INCLUDE_DIR ../projects/mtg/extra)
|
||||||
|
|
||||||
|
#turn moc on
|
||||||
|
if(backend_qt_console OR backend_qt_widget)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(CMAKE_AUTOMOC TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(backend_qt_console)
|
||||||
|
if(UNIX AND NOT ANDROID)
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS})
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_console_src} ${JGE_linux_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Multimedia_LIBRARIES} ${ZIPFS_LIBRARY} ${UNZIP_LIRARY}
|
||||||
|
${JPEG_LIBRARIES} ${PNG_LIBRARIES})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "qt builds of jge platforms other than linux are not supported")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(backend_qt_widget)
|
||||||
|
if(UNIX AND NOT ANDROID)
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS} ${Qt5OpenGL_INCLUDE_DIRS} )
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_graphics_src} ${JGE_linux_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Multimedia_LIBRARIES} ${Qt5OpenGL_LIBRARIES} ${ZIPFS_LIBRARY} ${UNZIP_LIRARY}
|
||||||
|
${JPEG_LIBRARIES} ${PNG_LIBRARIES})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "qt builds of jge platforms other than linux are not supported")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(backend_sdl)
|
||||||
|
if((UNIX OR EMSCRIPTEN) AND NOT ANDROID)
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}
|
||||||
|
${SDL2_INCLUDE_DIR} ${UNZIP_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_graphics_src} ${JGE_linux_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${ZIPFS_LIBRARY} ${UNZIP_LIRARY} ${JPEG_LIBRARY}
|
||||||
|
${PNG_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
|
||||||
|
elseif(ANDROID)
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${BOOST_INCLUDE_DIRS} ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR}
|
||||||
|
${SDL2_INCLUDE_DIR} ${UNZIP_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR}
|
||||||
|
${OPENSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_android_src} ${JGE_graphics_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${ZIPFS_LIBRARY} ${UNZIP_LIRARY} ${JPEG_LIBRARY} ${PNG_LIBRARIES}
|
||||||
|
${OPENSL_LIBRARIES})
|
||||||
|
elseif(WIN32)
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${EXTRA_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR} ${SDL2_INCLUDE_DIR}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/thirdparty/binary/win/include)
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_graphics_src} ${JGE_windows_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${ZIPFS_LIBRARY} ${UNZIP_LIRARY} ${JPEG_LIBRARY} ${PNG_LIBRARIES})
|
||||||
|
set(JGE_LINK_DIRECTORIES ${Boost_LIBRARY_DIR})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(backend_psp)
|
||||||
|
if(PSP)
|
||||||
|
#${PSPSDK_PATH}/include should be in system pathes
|
||||||
|
set(JGE_INTERNAL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/thirdparty/psp/include ${TINYXML_INCLUDE_DIR}
|
||||||
|
${ZIPFS_INCLUDE_DIR} ${UNZIP_INCLUDE_DIR} ${BOOST_INCLUDE_DIRS} ${GIF_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} )
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_psp_src} ${JGE_hge_src})
|
||||||
|
set(JGE_LINK_LIBRARIES ${TINYXML_LIBRARIES} ${ZIPFS_LIBRARY} ${UNZIP_LIRARY})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "use the cross-compile toolchain to build as the psp target")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IOS)
|
||||||
|
set(JGE_SOURCES ${JGE_generic_src} ${JGE_ios_src} ${JGE_hge_src} src/pc/JGfx.cpp)
|
||||||
|
set(JGE_SOURCES ${JGE_SOURCES} PARENT_SCOPE)
|
||||||
|
set(JGE_INCLUDE_DIRS ${JGE_INCLUDE_DIRS} src/iOS PARENT_SCOPE)
|
||||||
|
set(JGE_LINK_LIBRARIES ${TINYXML_LIBRARIES} ${ZIPFS_LIBRARY} ${UNZIP_LIRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(jge STATIC ${JGE_SOURCES})
|
||||||
|
include_directories(${JGE_INTERNAL_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(jge ${JGE_LINK_LIBRARIES})
|
||||||
|
link_directories(${JGE_LINK_DIRECTORIES})
|
||||||
|
|
||||||
|
set(${JGE_LIBRARIES} jge)
|
||||||
@@ -32,6 +32,7 @@ HGE_OBJS = src/hge/hgecolor.o src/hge/hgeparticle.o \
|
|||||||
|
|
||||||
CXXFLAGS = -W -Wall -Werror -Wno-unused
|
CXXFLAGS = -W -Wall -Werror -Wno-unused
|
||||||
CXXFLAGS += -DTIXML_USE_STL
|
CXXFLAGS += -DTIXML_USE_STL
|
||||||
|
CXXFLAGS += -Wno-deprecated-declarations -Wno-sign-compare
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CXXFLAGS += -ggdb3
|
CXXFLAGS += -ggdb3
|
||||||
@@ -82,7 +83,7 @@ ifeq ($(TARGET_ARCHITECTURE),linux)
|
|||||||
OBJS = $(GENERIC_OBJS) $(LINUX_OBJS)
|
OBJS = $(GENERIC_OBJS) $(LINUX_OBJS)
|
||||||
TARGET_LIB = libjge.a
|
TARGET_LIB = libjge.a
|
||||||
TARGET_HGE = libhgetools.a
|
TARGET_HGE = libhgetools.a
|
||||||
INCDIR = $(shell freetype-config --cflags 2> /dev/null) -I/usr/X11/include -I../Boost -Isrc/zipFS -Iinclude/
|
INCDIR = $(shell freetype-config --cflags 2> /dev/null) -I/usr/X11/include -I/usr/include/boost -Isrc/zipFS -Iinclude/
|
||||||
CXXFLAGS += -DLINUX $(FMOD)
|
CXXFLAGS += -DLINUX $(FMOD)
|
||||||
CXXFLAGS += $(INCDIR)
|
CXXFLAGS += $(INCDIR)
|
||||||
LIBDIR = lib/linux
|
LIBDIR = lib/linux
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ using namespace std;
|
|||||||
template <class T>
|
template <class T>
|
||||||
std::string ToHex(T* pointer)
|
std::string ToHex(T* pointer)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << hex << showbase << setfill('0') << setw(8) << (uint64_t) pointer;
|
stream << hex << showbase << setfill('0') << setw(8) << (uint64_t) pointer;
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
#define OutputDebugString(val) (std::cerr << val);
|
#define OutputDebugString(val) (std::cerr << val);
|
||||||
|
#define OutputDebugStringA(val) (std::cerr << val);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -42,9 +43,9 @@ std::string ToHex(T* pointer)
|
|||||||
#else // CAPTURE_STDERR
|
#else // CAPTURE_STDERR
|
||||||
#define DebugTrace(inString) \
|
#define DebugTrace(inString) \
|
||||||
{ \
|
{ \
|
||||||
std::ostringstream stream; \
|
std::ostringstream stream; \
|
||||||
stream << inString; \
|
stream << inString; \
|
||||||
qDebug("%s", stream.str().c_str()); \
|
qDebug("%s", stream.str().c_str()); \
|
||||||
}
|
}
|
||||||
#endif // CAPTURE_STDERR
|
#endif // CAPTURE_STDERR
|
||||||
|
|
||||||
@@ -52,16 +53,16 @@ std::string ToHex(T* pointer)
|
|||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#define DebugTrace(inString) \
|
#define DebugTrace(inString) \
|
||||||
{ \
|
{ \
|
||||||
std::ostringstream stream; \
|
std::ostringstream stream; \
|
||||||
stream << inString; \
|
stream << inString; \
|
||||||
__android_log_write(ANDROID_LOG_DEBUG, "Wagic", stream.str().c_str());\
|
__android_log_write(ANDROID_LOG_DEBUG, "Wagic", stream.str().c_str());\
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define DebugTrace(inString) \
|
#define DebugTrace(inString) \
|
||||||
{ \
|
{ \
|
||||||
std::ostringstream stream; \
|
std::ostringstream stream; \
|
||||||
stream << inString << std::endl; \
|
stream << inString << std::endl; \
|
||||||
OutputDebugStringA(stream.str().c_str()); \
|
OutputDebugStringA(stream.str().c_str()); \
|
||||||
}
|
}
|
||||||
#endif // QT_CONFIG
|
#endif // QT_CONFIG
|
||||||
#endif // Win32, Linux
|
#endif // Win32, Linux
|
||||||
@@ -71,7 +72,7 @@ std::string ToHex(T* pointer)
|
|||||||
#ifndef DebugTrace
|
#ifndef DebugTrace
|
||||||
#define DebugTrace(inString) \
|
#define DebugTrace(inString) \
|
||||||
{ \
|
{ \
|
||||||
std::cerr << inString << std::endl; \
|
std::cerr << inString << std::endl; \
|
||||||
}
|
}
|
||||||
#endif //DEBUG
|
#endif //DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class DownloadRequest
|
|||||||
private slots:
|
private slots:
|
||||||
#endif
|
#endif
|
||||||
void fileDownloaded();
|
void fileDownloaded();
|
||||||
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
void downloadProgress(int64_t bytesReceived, int64_t bytesTotal);
|
||||||
|
|
||||||
#ifdef QT_CONFIG
|
#ifdef QT_CONFIG
|
||||||
signals:
|
signals:
|
||||||
@@ -72,7 +72,13 @@ protected:
|
|||||||
QNetworkReply* mNetworkReply;
|
QNetworkReply* mNetworkReply;
|
||||||
static QNetworkAccessManager networkAccessManager;
|
static QNetworkAccessManager networkAccessManager;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
static void onLoadCb(unsigned int handle, DownloadRequest* req, const char *buffer, unsigned int size);
|
||||||
|
static void onErrorCb(unsigned int handle, DownloadRequest* req, int errorCode, const char* errorText);
|
||||||
|
static void onProgressCb(unsigned int handle, DownloadRequest* req, int bytesReceived, int bytesTotal);
|
||||||
|
#endif
|
||||||
|
void processError(int errorCode, const char* errorText);
|
||||||
|
void processBufferDownloaded(unsigned int size, const char*buffer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DownloadRequest(string localPath="",
|
DownloadRequest(string localPath="",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ typedef u32 LocalKeySym;
|
|||||||
|
|
||||||
#elif defined(SDL_CONFIG)
|
#elif defined(SDL_CONFIG)
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
typedef SDLKey LocalKeySym;
|
typedef SDL_Keycode LocalKeySym;
|
||||||
#define LOCAL_KEY_NONE SDLK_UNKNOWN
|
#define LOCAL_KEY_NONE SDLK_UNKNOWN
|
||||||
|
|
||||||
#elif defined(WIN32)
|
#elif defined(WIN32)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#if (!defined IOS) && (!defined ANDROID) && (!defined QT_CONFIG)
|
#if (!defined IOS) && (!defined ANDROID) && (!defined QT_CONFIG) && (!defined SDL_CONFIG)
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
#endif //IOS ANDROID
|
#endif //IOS ANDROID
|
||||||
|
|
||||||
@@ -567,7 +567,7 @@ private:
|
|||||||
#if (!defined IOS) && (!defined QT_CONFIG)
|
#if (!defined IOS) && (!defined QT_CONFIG)
|
||||||
void LoadJPG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
void LoadJPG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
||||||
int LoadPNG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
int LoadPNG(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
||||||
#if (!defined ANDROID) && (!defined QT_CONFIG)
|
#if (!defined ANDROID) && (!defined QT_CONFIG) && (!defined SDL_CONFIG)
|
||||||
void LoadGIF(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
void LoadGIF(TextureInfo &textureInfo, const char *filename, int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
||||||
int image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bgcolor, InputFunc readFunc,int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
int image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bgcolor, InputFunc readFunc,int mode = 0, int TextureFormat = TEXTURE_FORMAT);
|
||||||
#endif // (ANDROID) How can we get gif support for android ?
|
#endif // (ANDROID) How can we get gif support for android ?
|
||||||
|
|||||||
@@ -18,20 +18,20 @@
|
|||||||
|
|
||||||
#include "JTypes.h"
|
#include "JTypes.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#include <SLES/OpenSLES.h>
|
#include <SLES/OpenSLES.h>
|
||||||
#include "SLES/OpenSLES_Android.h"
|
#include "SLES/OpenSLES_Android.h"
|
||||||
|
#elif defined(USE_PHONON)
|
||||||
#elif defined USE_PHONON
|
|
||||||
#include <phonon/AudioOutput>
|
#include <phonon/AudioOutput>
|
||||||
#include <phonon/MediaObject>
|
#include <phonon/MediaObject>
|
||||||
#elif (defined QT_CONFIG)
|
#elif defined (QT_CONFIG)
|
||||||
#include "QMediaPlayer"
|
#include "QMediaPlayer"
|
||||||
#include "QMediaPlaylist"
|
#include "QMediaPlaylist"
|
||||||
#include "QSoundEffect"
|
#include "QSoundEffect"
|
||||||
#elif defined WIN32
|
#elif defined(WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define WITH_FMOD
|
//#define WITH_FMOD
|
||||||
#elif defined (PSP)
|
#elif defined (PSP)
|
||||||
#include <pspgu.h>
|
#include <pspgu.h>
|
||||||
#include <pspkernel.h>
|
#include <pspkernel.h>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FMOD
|
#ifdef WITH_FMOD
|
||||||
#include "../Dependencies/include/fmod.h"
|
#include "fmod.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
@@ -79,20 +79,26 @@ public slots:
|
|||||||
std::string filename;
|
std::string filename;
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string ext;
|
std::string ext;
|
||||||
|
void* mTrack;
|
||||||
#elif defined WITH_FMOD
|
#elif defined WITH_FMOD
|
||||||
FSOUND_SAMPLE* mTrack; // MP3 needed to be of "sample" type for FMOD, FMUSIC_MODULE is for MODs
|
FSOUND_SAMPLE* mTrack; // MP3 needed to be of "sample" type for FMOD, FMUSIC_MODULE is for MODs
|
||||||
|
void* mTrack;
|
||||||
#elif defined ANDROID
|
#elif defined ANDROID
|
||||||
SLObjectItf playerObject;
|
SLObjectItf playerObject;
|
||||||
SLPlayItf playInterface;
|
SLPlayItf playInterface;
|
||||||
SLSeekItf seekInterface;
|
SLSeekItf seekInterface;
|
||||||
SLVolumeItf musicVolumeInterface;
|
SLVolumeItf musicVolumeInterface;
|
||||||
|
void* mTrack;
|
||||||
#elif (defined QT_CONFIG)
|
#elif (defined QT_CONFIG)
|
||||||
QMediaPlaylist* playlist;
|
QMediaPlaylist* playlist;
|
||||||
QMediaPlayer* player;
|
QMediaPlayer* player;
|
||||||
string fullpath;
|
string fullpath;
|
||||||
#else
|
void* mTrack;
|
||||||
void* mTrack;
|
#elif (defined WIN32)
|
||||||
#endif //WITH_FMOD
|
std::string filename;
|
||||||
|
void* mTrack;
|
||||||
|
#endif
|
||||||
|
//#endif //WITH_FMOD
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,28 +113,30 @@ public:
|
|||||||
unsigned long fileSize();
|
unsigned long fileSize();
|
||||||
#if (defined QT_CONFIG) && (!defined USE_PHONON)
|
#if (defined QT_CONFIG) && (!defined USE_PHONON)
|
||||||
QMediaPlayer* effect;
|
QMediaPlayer* effect;
|
||||||
void* mSample;
|
void* mSample;
|
||||||
#elif defined (PSP)
|
#elif defined (PSP)
|
||||||
WAVDATA *mSample;
|
WAVDATA* mSample;
|
||||||
#elif defined (IOS)
|
#elif defined (IOS)
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string key;
|
std::string key;
|
||||||
std::string ext;
|
std::string ext;
|
||||||
|
void* mSample;
|
||||||
void* mSample;
|
|
||||||
#elif defined (WITH_FMOD)
|
#elif defined (WITH_FMOD)
|
||||||
FSOUND_SAMPLE *mSample;
|
FSOUND_SAMPLE *mSample;
|
||||||
#elif defined (USE_PHONON)
|
#elif defined (USE_PHONON)
|
||||||
Phonon::AudioOutput* mOutput;
|
Phonon::AudioOutput* mOutput;
|
||||||
Phonon::MediaObject* mMediaObject;
|
Phonon::MediaObject* mMediaObject;
|
||||||
void* mSample;
|
void* mSample;
|
||||||
#elif defined ANDROID
|
#elif defined ANDROID
|
||||||
SLObjectItf playerObject;
|
SLObjectItf playerObject;
|
||||||
SLPlayItf playInterface;
|
SLPlayItf playInterface;
|
||||||
SLVolumeItf sampleVolumeInterface;
|
SLVolumeItf sampleVolumeInterface;
|
||||||
void* mSample;
|
void* mSample;
|
||||||
|
#elif (defined WIN32)
|
||||||
|
std::string filename;
|
||||||
|
void* mSample;
|
||||||
#else
|
#else
|
||||||
void* mSample;
|
void* mSample;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,16 @@
|
|||||||
#include "JAudio.h"
|
#include "JAudio.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
//#define __STDC_LIMIT_MACROS
|
||||||
#include <stdint.h>
|
#ifdef IOS
|
||||||
|
#include <tr1/cstdint>
|
||||||
|
#else
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
//#include <stdint.h>
|
||||||
|
//the MSC version might only define _MSC_STDINT_H_
|
||||||
|
//and that might cause redefinition of standard types
|
||||||
|
//#define _STDINT_H_
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -140,9 +148,14 @@ typedef uint32_t u32;
|
|||||||
#include <GLES/gl.h>
|
#include <GLES/gl.h>
|
||||||
#include <GLES/glext.h>
|
#include <GLES/glext.h>
|
||||||
#elif defined (WIN32) || defined (LINUX)
|
#elif defined (WIN32) || defined (LINUX)
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#else
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <QtOpenGL>
|
#include <QtOpenGL>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef PRECOMPILEDHEADER_H
|
||||||
|
#define PRECOMPILEDHEADER_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "DebugRoutines.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "JGE.h"
|
||||||
|
#include "JFileSystem.h"
|
||||||
|
#include "JLogger.h"
|
||||||
|
|
||||||
|
//#ifndef WP8
|
||||||
|
//#include <boost/shared_ptr.hpp>
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#if defined (WP8) || defined (IOS) || defined (ANDROID) || defined (QT_CONFIG) || defined (SDL_CONFIG)
|
||||||
|
#define TOUCH_ENABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //PRECOMPILEDHEADER_H
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef THREADING_H
|
#ifndef THREADING_H
|
||||||
#define THREADING_H
|
#define THREADING_H
|
||||||
|
|
||||||
#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L)
|
#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L) && !(_MSC_VER >= 1700)
|
||||||
#include <boost/date_time.hpp>
|
#include <boost/date_time.hpp>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -537,7 +537,7 @@ namespace boost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif (__cplusplus > 199711L)
|
#elif (__cplusplus > 199711L) || (_MSC_VER >= 1700)
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* vrelptr( void *ptr ); // make a pointer relative to memory base address (ATTENTION: A NULL rel ptr is not illegal/invalid!)
|
void* vrelptr( void *ptr ); // make a pointer relative to memory base address (ATTENTION: A NULL rel ptr is not illegal/invalid!)
|
||||||
|
|
||||||
void* vabsptr( void *ptr ); // make a pointer absolute (default return type of valloc)
|
void* vabsptr( void *ptr ); // make a pointer absolute (default return type of valloc)
|
||||||
|
|
||||||
void* valloc( size_t size );
|
void* valloc( size_t size );
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
#ifdef QT_CONFIG
|
#ifdef QT_CONFIG
|
||||||
QNetworkAccessManager DownloadRequest::networkAccessManager;
|
QNetworkAccessManager DownloadRequest::networkAccessManager;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include "emscripten.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
DownloadRequest::DownloadRequest(string localPath,
|
DownloadRequest::DownloadRequest(string localPath,
|
||||||
string remoteResourceURL,
|
string remoteResourceURL,
|
||||||
@@ -48,15 +51,71 @@ void DownloadRequest::startGet()
|
|||||||
JFileSystem::GetInstance()->Remove(getTempLocalPath());
|
JFileSystem::GetInstance()->Remove(getTempLocalPath());
|
||||||
JFileSystem::GetInstance()->openForWrite(mFile, getTempLocalPath());
|
JFileSystem::GetInstance()->openForWrite(mFile, getTempLocalPath());
|
||||||
#ifdef QT_CONFIG
|
#ifdef QT_CONFIG
|
||||||
connect(mNetworkReply, SIGNAL(downloadProgress(qint64, qint64)),
|
connect(mNetworkReply, SIGNAL(downloadProgress(int64_t, int64_t)),
|
||||||
SLOT(downloadProgress(qint64, qint64)));
|
SLOT(downloadProgress(int64_t, int64_t)));
|
||||||
connect(mNetworkReply, SIGNAL(finished()), SLOT(fileDownloaded()));
|
connect(mNetworkReply, SIGNAL(finished()), SLOT(fileDownloaded()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
emscripten_async_wget2_data(mRemoteResourceURL.c_str(), "GET", 0, this, 1,
|
||||||
|
(em_async_wget2_data_onload_func)DownloadRequest::onLoadCb,
|
||||||
|
(em_async_wget2_data_onerror_func)DownloadRequest::onErrorCb,
|
||||||
|
(em_async_wget2_data_onprogress_func)DownloadRequest::onProgressCb);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
void DownloadRequest::onLoadCb(unsigned int handle, DownloadRequest* req, const char *buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
|
||||||
|
DebugTrace("DownloadRequest::onLoadCb: " << size);
|
||||||
|
req->processBufferDownloaded(size, buffer);
|
||||||
|
Downloader::GetInstance()->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadRequest::onErrorCb(unsigned int handle, DownloadRequest* req, int errorCode, const char* errorText)
|
||||||
|
{
|
||||||
|
DebugTrace("DownloadRequest::onErrorCb");
|
||||||
|
req->processError(errorCode, errorText);
|
||||||
|
Downloader::GetInstance()->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadRequest::onProgressCb(unsigned int handle, DownloadRequest* req, int bytesReceived, int bytesTotal)
|
||||||
|
{
|
||||||
|
DebugTrace("DownloadRequest::onProgressCb");
|
||||||
|
req->DownloadRequest::downloadProgress(bytesReceived, bytesTotal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DownloadRequest::processError(int errorCode, const char* errorText)
|
||||||
|
{
|
||||||
|
DebugTrace(errorText);
|
||||||
|
mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR;
|
||||||
|
mFile.close();
|
||||||
|
JFileSystem::GetInstance()->Remove(getTempLocalPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadRequest::processBufferDownloaded(unsigned int size, const char*buffer)
|
||||||
|
{
|
||||||
|
if(mFile.is_open())
|
||||||
|
{
|
||||||
|
mTotalSize = size;
|
||||||
|
mFile.write(buffer, size);
|
||||||
|
mFile.close();
|
||||||
|
if(!JFileSystem::GetInstance()->Rename(getTempLocalPath(), mLocalPath)) {
|
||||||
|
mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDownloadStatus = DownloadRequest::DOWNLOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadRequest::fileDownloaded()
|
void DownloadRequest::fileDownloaded()
|
||||||
{
|
{
|
||||||
do {
|
#ifdef QT_CONFIG
|
||||||
|
do {
|
||||||
QByteArray eTagByteArray = mNetworkReply->rawHeader("ETag");
|
QByteArray eTagByteArray = mNetworkReply->rawHeader("ETag");
|
||||||
if(!eTagByteArray.isEmpty()) {
|
if(!eTagByteArray.isEmpty()) {
|
||||||
string oldETag = mETag;
|
string oldETag = mETag;
|
||||||
@@ -67,10 +126,7 @@ void DownloadRequest::fileDownloaded()
|
|||||||
|
|
||||||
// let's check some error
|
// let's check some error
|
||||||
if(mNetworkReply->error() != QNetworkReply::NoError) {
|
if(mNetworkReply->error() != QNetworkReply::NoError) {
|
||||||
DebugTrace(mNetworkReply->errorString().toStdString());
|
processError((int)mNetworkReply->error(), mNetworkReply->errorString().toStdString().c_str());
|
||||||
mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR;
|
|
||||||
mFile.close();
|
|
||||||
JFileSystem::GetInstance()->Remove(getTempLocalPath());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,35 +145,31 @@ void DownloadRequest::fileDownloaded()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mFile.is_open())
|
QByteArray byteArray = mNetworkReply->readAll();
|
||||||
{
|
processBufferDownloaded(byteArray.size(), byteArray.constData());
|
||||||
QByteArray byteArray = mNetworkReply->readAll();
|
|
||||||
mFile.write(byteArray.constData(), byteArray.size());
|
|
||||||
mFile.close();
|
|
||||||
if(!JFileSystem::GetInstance()->Rename(getTempLocalPath(), mLocalPath)) {
|
|
||||||
mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mDownloadStatus = DownloadRequest::DOWNLOADED;
|
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
Downloader::GetInstance()->Update();
|
Downloader::GetInstance()->Update();
|
||||||
mNetworkReply->deleteLater();
|
|
||||||
|
|
||||||
|
mNetworkReply->deleteLater();
|
||||||
emit statusChanged((int)mDownloadStatus);
|
emit statusChanged((int)mDownloadStatus);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadRequest::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
|
void DownloadRequest::downloadProgress(int64_t bytesReceived, int64_t bytesTotal)
|
||||||
{
|
{
|
||||||
QByteArray byteArray = mNetworkReply->readAll();
|
#ifdef QT_CONFIG
|
||||||
|
QByteArray byteArray = mNetworkReply->readAll();
|
||||||
mFile.write(byteArray.constData(), byteArray.size());
|
mFile.write(byteArray.constData(), byteArray.size());
|
||||||
|
#endif
|
||||||
mCurrentSize = bytesReceived;
|
mCurrentSize = bytesReceived;
|
||||||
mTotalSize = bytesTotal;
|
mTotalSize = bytesTotal;
|
||||||
int percent = 0;
|
int percent = 0;
|
||||||
if(bytesTotal)
|
if(bytesTotal)
|
||||||
percent = (bytesReceived/bytesTotal)*100;
|
percent = (bytesReceived/bytesTotal)*100;
|
||||||
|
#ifdef QT_CONFIG
|
||||||
emit percentChanged(percent);
|
emit percentChanged(percent);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Downloader* Downloader::mInstance = 0;
|
Downloader* Downloader::mInstance = 0;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "../include/JSprite.h"
|
#include "../include/JSprite.h"
|
||||||
#include "../include/JAnimator.h"
|
#include "../include/JAnimator.h"
|
||||||
|
|
||||||
#include "tinyxml/tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ User folder is the only one that is really needed to guarantee both read and wri
|
|||||||
The content that users should not be touching.
|
The content that users should not be touching.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PSP
|
#include "dirent.h"
|
||||||
#include "PrecompiledHeader.h"
|
|
||||||
#endif //PSP
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#pragma warning(disable : 4786)
|
#pragma warning(disable : 4786)
|
||||||
@@ -32,7 +30,8 @@ The content that users should not be touching.
|
|||||||
#include "../include/JGE.h"
|
#include "../include/JGE.h"
|
||||||
#include "../include/JFileSystem.h"
|
#include "../include/JFileSystem.h"
|
||||||
#include "../include/JLogger.h"
|
#include "../include/JLogger.h"
|
||||||
#include <dirent.h>
|
#include "DebugRoutines.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef QT_CONFIG
|
#ifdef QT_CONFIG
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -125,6 +124,10 @@ JFileSystem::JFileSystem(const string & _userPath, const string & _systemPath)
|
|||||||
userPath = [[documentsDirectory stringByAppendingString: @"/User/"] cStringUsingEncoding:1];
|
userPath = [[documentsDirectory stringByAppendingString: @"/User/"] cStringUsingEncoding:1];
|
||||||
systemPath = [[documentsDirectory stringByAppendingString: @"/Res/"] cStringUsingEncoding:1];
|
systemPath = [[documentsDirectory stringByAppendingString: @"/Res/"] cStringUsingEncoding:1];
|
||||||
|
|
||||||
|
#elif defined (__EMSCRIPTEN__)
|
||||||
|
systemPath = "/";
|
||||||
|
DebugTrace("User path " << userPath);
|
||||||
|
DebugTrace("System path " << systemPath);
|
||||||
#elif defined (ANDROID)
|
#elif defined (ANDROID)
|
||||||
userPath = JGE::GetInstance()->getFileSystemLocation();
|
userPath = JGE::GetInstance()->getFileSystemLocation();
|
||||||
systemPath = "";
|
systemPath = "";
|
||||||
@@ -140,9 +143,9 @@ JFileSystem::JFileSystem(const string & _userPath, const string & _systemPath)
|
|||||||
userPath = QDir::toNativeSeparators(dir.absolutePath()).toStdString();
|
userPath = QDir::toNativeSeparators(dir.absolutePath()).toStdString();
|
||||||
systemPath = QDir::toNativeSeparators(sysDir.absolutePath()).toStdString();
|
systemPath = QDir::toNativeSeparators(sysDir.absolutePath()).toStdString();
|
||||||
|
|
||||||
DebugTrace("User path " << userPath);
|
DebugTrace("User path " + userPath);
|
||||||
DebugTrace("System path " << systemPath);
|
DebugTrace("System path " + systemPath);
|
||||||
DebugTrace("Current path " << QDir::currentPath().toStdString());
|
DebugTrace("Current path " + QDir::currentPath().toStdString());
|
||||||
#else
|
#else
|
||||||
//Find the Res.txt file and matching Res folders for backwards compatibility
|
//Find the Res.txt file and matching Res folders for backwards compatibility
|
||||||
ifstream mfile("Res.txt");
|
ifstream mfile("Res.txt");
|
||||||
@@ -297,6 +300,7 @@ void JFileSystem::DetachZipFile()
|
|||||||
|
|
||||||
bool JFileSystem::openForRead(izfstream & File, const string & FilePath) {
|
bool JFileSystem::openForRead(izfstream & File, const string & FilePath) {
|
||||||
|
|
||||||
|
DebugTrace("JFileSystem::openForRead " << FilePath);
|
||||||
File.open(FilePath.c_str(), mUserFS);
|
File.open(FilePath.c_str(), mUserFS);
|
||||||
if (File)
|
if (File)
|
||||||
return true;
|
return true;
|
||||||
@@ -407,7 +411,6 @@ bool JFileSystem::OpenFile(const string &filename)
|
|||||||
mCurrentFileInZip = &(it2->second);
|
mCurrentFileInZip = &(it2->second);
|
||||||
mFileSize = it2->second.m_Size;
|
mFileSize = it2->second.m_Size;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
#if defined (WIN32) // WIN32 specific code
|
#if defined (WIN32) // WIN32 specific code
|
||||||
#include "../../Dependencies/include/fmod.h"
|
#include "fmod.h"
|
||||||
|
|
||||||
u8 JGE::GetAnalogX()
|
u8 JGE::GetAnalogX()
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ u8 JGE::GetAnalogY()
|
|||||||
#elif defined (LINUX) // Unix specific code
|
#elif defined (LINUX) // Unix specific code
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#ifdef WITH_FMOD
|
#ifdef WITH_FMOD
|
||||||
#include "../Dependencies/include/fmod.h"
|
#include "fmod.h"
|
||||||
#endif //WITH_FMOD
|
#endif //WITH_FMOD
|
||||||
|
|
||||||
|
|
||||||
@@ -249,6 +249,7 @@ u32 JGE::BindKey(LocalKeySym sym, JButton button)
|
|||||||
u32 JGE::UnbindKey(LocalKeySym sym, JButton button)
|
u32 JGE::UnbindKey(LocalKeySym sym, JButton button)
|
||||||
{
|
{
|
||||||
for (keycodes_it it = keyBinds.begin(); it != keyBinds.end(); )
|
for (keycodes_it it = keyBinds.begin(); it != keyBinds.end(); )
|
||||||
|
{
|
||||||
if (sym == it->first && button == it->second)
|
if (sym == it->first && button == it->second)
|
||||||
{
|
{
|
||||||
keycodes_it er = it;
|
keycodes_it er = it;
|
||||||
@@ -256,7 +257,8 @@ u32 JGE::UnbindKey(LocalKeySym sym, JButton button)
|
|||||||
keyBinds.erase(er);
|
keyBinds.erase(er);
|
||||||
}
|
}
|
||||||
else ++it;
|
else ++it;
|
||||||
return keyBinds.size();
|
}
|
||||||
|
return keyBinds.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 JGE::UnbindKey(LocalKeySym sym)
|
u32 JGE::UnbindKey(LocalKeySym sym)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <pspaudio.h>
|
#include <pspaudio.h>
|
||||||
#include <pspmp3.h>
|
#include <pspmp3.h>
|
||||||
#include <psputility.h>
|
#include <psputility.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define PSP_AUDIO_VOLUME_MAX 100
|
#define PSP_AUDIO_VOLUME_MAX 100
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "../include/JFileSystem.h"
|
#include "../include/JFileSystem.h"
|
||||||
#include "../include/JResourceManager.h"
|
#include "../include/JResourceManager.h"
|
||||||
|
|
||||||
#include "tinyxml/tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "../include/JResourceManager.h"
|
#include "../include/JResourceManager.h"
|
||||||
#include "../include/JFileSystem.h"
|
#include "../include/JFileSystem.h"
|
||||||
#include "../include/JLBFont.h"
|
#include "../include/JLBFont.h"
|
||||||
#include "tinyxml/tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
#if defined (_DEBUG) && defined (WIN32) && (!defined LINUX)
|
#if defined (_DEBUG) && defined (WIN32) && (!defined LINUX)
|
||||||
#include "crtdbg.h"
|
#include "crtdbg.h"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "../include/JFileSystem.h"
|
#include "../include/JFileSystem.h"
|
||||||
#include "../include/JSpline.h"
|
#include "../include/JSpline.h"
|
||||||
|
|
||||||
#include "tinyxml/tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
#define SMALL_NUMBER 0.0001f
|
#define SMALL_NUMBER 0.0001f
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../include/decoder_prx.h"
|
#include "decoder_prx.h"
|
||||||
|
#include <psputility.h>
|
||||||
|
|
||||||
char *prx_static_init()
|
char *prx_static_init()
|
||||||
{
|
{
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#if (!defined IOS) && (!defined QT_CONFIG)
|
#if (!defined IOS) && (!defined QT_CONFIG)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#pragma warning(disable : 4786)
|
#pragma warning(disable : 4786)
|
||||||
#pragma comment( lib, "giflib.lib" )
|
//#pragma comment( lib, "giflib.lib" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
@@ -1804,7 +1804,7 @@ static void PNGCustomReadDataFn(png_structp png_ptr, png_bytep data, png_size_t
|
|||||||
{
|
{
|
||||||
png_size_t check;
|
png_size_t check;
|
||||||
|
|
||||||
JFileSystem *fileSystem = (JFileSystem*)png_ptr->io_ptr;
|
JFileSystem *fileSystem = (JFileSystem*)png_get_io_ptr(png_ptr);
|
||||||
|
|
||||||
check = fileSystem->ReadFile(data, length);
|
check = fileSystem->ReadFile(data, length);
|
||||||
|
|
||||||
@@ -1887,7 +1887,7 @@ int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode
|
|||||||
//fclose(fp);
|
//fclose(fp);
|
||||||
fileSystem->CloseFile();
|
fileSystem->CloseFile();
|
||||||
|
|
||||||
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||||
|
|
||||||
return JGE_ERR_PNG;
|
return JGE_ERR_PNG;
|
||||||
}
|
}
|
||||||
@@ -1896,11 +1896,15 @@ int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode
|
|||||||
|
|
||||||
png_set_sig_bytes(png_ptr, sig_read);
|
png_set_sig_bytes(png_ptr, sig_read);
|
||||||
png_read_info(png_ptr, info_ptr);
|
png_read_info(png_ptr, info_ptr);
|
||||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
|
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
|
||||||
png_set_strip_16(png_ptr);
|
png_set_strip_16(png_ptr);
|
||||||
png_set_packing(png_ptr);
|
png_set_packing(png_ptr);
|
||||||
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
|
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
|
||||||
|
#if PNG_LIBPNG_VER >= 10400
|
||||||
|
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
|
||||||
|
#else
|
||||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
|
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
|
||||||
|
#endif
|
||||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
|
||||||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||||
|
|
||||||
@@ -1910,7 +1914,7 @@ int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode
|
|||||||
//fclose(fp);
|
//fclose(fp);
|
||||||
fileSystem->CloseFile();
|
fileSystem->CloseFile();
|
||||||
|
|
||||||
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||||
return JGE_ERR_MALLOC_FAILED;
|
return JGE_ERR_MALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1932,7 +1936,7 @@ int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode
|
|||||||
|
|
||||||
for (y = 0; y < (int)height; y++)
|
for (y = 0; y < (int)height; y++)
|
||||||
{
|
{
|
||||||
png_read_row(png_ptr, (BYTE*) line, png_bytep_NULL);
|
png_read_row(png_ptr, (BYTE*) line, NULL);
|
||||||
for (x = 0; x < (int)width; x++)
|
for (x = 0; x < (int)width; x++)
|
||||||
{
|
{
|
||||||
DWORD color32 = line[x];
|
DWORD color32 = line[x];
|
||||||
@@ -1955,7 +1959,7 @@ int JRenderer::LoadPNG(TextureInfo &textureInfo, const char *filename, int mode
|
|||||||
free (line);
|
free (line);
|
||||||
|
|
||||||
png_read_end(png_ptr, info_ptr);
|
png_read_end(png_ptr, info_ptr);
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||||
|
|
||||||
fileSystem->CloseFile();
|
fileSystem->CloseFile();
|
||||||
|
|
||||||
@@ -1998,8 +2002,15 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
GifFileType *GifFileIn = NULL;
|
GifFileType *GifFileIn = NULL;
|
||||||
ColorMapObject *palette;
|
ColorMapObject *palette;
|
||||||
int ExtCode;
|
int ExtCode;
|
||||||
|
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
if ((GifFileIn = DGifOpen(handle, readFunc, NULL)) == NULL)
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
if ((GifFileIn = DGifOpen(handle, readFunc)) == NULL)
|
if ((GifFileIn = DGifOpen(handle, readFunc)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
*bgcolor = 0;
|
*bgcolor = 0;
|
||||||
textureInfo.mWidth = 0;
|
textureInfo.mWidth = 0;
|
||||||
textureInfo.mHeight = 0;
|
textureInfo.mHeight = 0;
|
||||||
@@ -2008,7 +2019,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
do {
|
do {
|
||||||
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
|
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2017,12 +2032,20 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
{
|
{
|
||||||
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
|
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
|
||||||
{
|
{
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if((palette = (GifFileIn->SColorMap != NULL) ? GifFileIn->SColorMap : GifFileIn->Image.ColorMap) == NULL)
|
if((palette = (GifFileIn->SColorMap != NULL) ? GifFileIn->SColorMap : GifFileIn->Image.ColorMap) == NULL)
|
||||||
{
|
{
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
textureInfo.mWidth = GifFileIn->Image.Width;
|
textureInfo.mWidth = GifFileIn->Image.Width;
|
||||||
@@ -2030,7 +2053,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
*bgcolor = gif_color32(GifFileIn->SBackGroundColor);
|
*bgcolor = gif_color32(GifFileIn->SBackGroundColor);
|
||||||
if((LineIn = (GifRowType) malloc(GifFileIn->Image.Width * sizeof(GifPixelType))) == NULL)
|
if((LineIn = (GifRowType) malloc(GifFileIn->Image.Width * sizeof(GifPixelType))) == NULL)
|
||||||
{
|
{
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
textureInfo.mTexWidth = getNextPower2(GifFileIn->Image.Width);
|
textureInfo.mTexWidth = getNextPower2(GifFileIn->Image.Width);
|
||||||
@@ -2040,7 +2067,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
if((p32 = (DWORD *)malloc(sizeof(PIXEL_TYPE) * textureInfo.mTexWidth * textureInfo.mTexHeight)) == NULL)
|
if((p32 = (DWORD *)malloc(sizeof(PIXEL_TYPE) * textureInfo.mTexWidth * textureInfo.mTexHeight)) == NULL)
|
||||||
{
|
{
|
||||||
free((void *)LineIn);
|
free((void *)LineIn);
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
DWORD * curr = p32;
|
DWORD * curr = p32;
|
||||||
@@ -2052,7 +2083,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
{
|
{
|
||||||
free((void *)p32);
|
free((void *)p32);
|
||||||
free((void *)LineIn);
|
free((void *)LineIn);
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (GifWord j = 0; j < GifFileIn->Image.Width; j ++)
|
for (GifWord j = 0; j < GifFileIn->Image.Width; j ++)
|
||||||
@@ -2081,7 +2116,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
}
|
}
|
||||||
if(LineIn != NULL)
|
if(LineIn != NULL)
|
||||||
free((void *)LineIn);
|
free((void *)LineIn);
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while (Extension != NULL) {
|
while (Extension != NULL) {
|
||||||
@@ -2094,7 +2133,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
}
|
}
|
||||||
if(LineIn != NULL)
|
if(LineIn != NULL)
|
||||||
free((void *)LineIn);
|
free((void *)LineIn);
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2109,7 +2152,11 @@ int JRenderer::image_readgif(void * handle, TextureInfo &textureInfo, DWORD * bg
|
|||||||
|
|
||||||
if(LineIn != NULL)
|
if(LineIn != NULL)
|
||||||
free((void *)LineIn);
|
free((void *)LineIn);
|
||||||
|
#if GIFLIB_MAJOR >= 5
|
||||||
|
DGifCloseFile(GifFileIn, NULL);
|
||||||
|
#else
|
||||||
DGifCloseFile(GifFileIn);
|
DGifCloseFile(GifFileIn);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ static int __largest_block = __MEM_BLOCKS;
|
|||||||
static int __mem_free = __MEM_BLOCKS;
|
static int __mem_free = __MEM_BLOCKS;
|
||||||
|
|
||||||
|
|
||||||
inline void* vrelptr( void *ptr )
|
void* vrelptr( void *ptr )
|
||||||
{
|
{
|
||||||
return (void*)((unsigned int)ptr & ~__MEM_START);
|
return (void*)((unsigned int)ptr & ~__MEM_START);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
#include <Windows.h>
|
||||||
|
#include <Mmsystem.h>
|
||||||
|
#include <mciapi.h>
|
||||||
|
//these two headers are already included in the <Windows.h> header
|
||||||
|
#pragma comment(lib, "Winmm.lib")
|
||||||
|
|
||||||
|
#include "DebugRoutines.h"
|
||||||
|
#include "../../include/JSoundSystem.h"
|
||||||
|
#include "../../include/JFileSystem.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
JMusic::JMusic()
|
||||||
|
:
|
||||||
|
mTrack(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void JMusic::Update(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int JMusic::getPlayTime(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JMusic::~JMusic()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
JSample::JSample()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
JSample::~JSample()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long JSample::fileSize()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
JSoundSystem* JSoundSystem::mInstance = NULL;
|
||||||
|
|
||||||
|
JSoundSystem* JSoundSystem::GetInstance()
|
||||||
|
{
|
||||||
|
if (mInstance == NULL)
|
||||||
|
{
|
||||||
|
mInstance = new JSoundSystem();
|
||||||
|
mInstance->InitSoundSystem();
|
||||||
|
}
|
||||||
|
return mInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::Destroy()
|
||||||
|
{
|
||||||
|
if (mInstance)
|
||||||
|
{
|
||||||
|
mInstance->DestroySoundSystem();
|
||||||
|
delete mInstance;
|
||||||
|
mInstance = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JSoundSystem::JSoundSystem()
|
||||||
|
{
|
||||||
|
mVolume = 0;
|
||||||
|
mSampleVolume = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSoundSystem::~JSoundSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSoundSystem::InitSoundSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::DestroySoundSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JMusic *JSoundSystem::LoadMusic(const char *fileName)
|
||||||
|
{
|
||||||
|
JMusic* music = NULL;
|
||||||
|
music = new JMusic();
|
||||||
|
if (music)
|
||||||
|
{
|
||||||
|
music->filename = JFileSystem::GetInstance()->GetResourceFile(fileName);
|
||||||
|
std::string aString = "open \"" + music->filename + "\" type mpegvideo alias mp3";
|
||||||
|
mciSendString(aString.c_str(), NULL, 0, NULL);
|
||||||
|
music->mTrack = (void*)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::PlayMusic(JMusic *music, bool looping)
|
||||||
|
{
|
||||||
|
if (music && music->mTrack)
|
||||||
|
{
|
||||||
|
if(looping)
|
||||||
|
mciSendString("play mp3 repeat", NULL, 0, NULL);
|
||||||
|
else
|
||||||
|
mciSendString("play mp3", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::StopMusic(JMusic *music)
|
||||||
|
{
|
||||||
|
if (music && music->mTrack)
|
||||||
|
{
|
||||||
|
mciSendString("stop mp3", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::PauseMusic(JMusic *music)
|
||||||
|
{
|
||||||
|
if (music && music->mTrack)
|
||||||
|
{
|
||||||
|
mciSendString("pause mp3", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::ResumeMusic(JMusic *music)
|
||||||
|
{
|
||||||
|
if (music && music->mTrack)
|
||||||
|
{
|
||||||
|
mciSendString("resume mp3", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::SetVolume(int volume)
|
||||||
|
{
|
||||||
|
SetMusicVolume(volume);
|
||||||
|
SetSfxVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSoundSystem::SetMusicVolume(int volume)
|
||||||
|
{
|
||||||
|
mVolume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSoundSystem::SetSfxVolume(int volume)
|
||||||
|
{
|
||||||
|
mSampleVolume = volume;
|
||||||
|
SetMusicVolume(mVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSample *JSoundSystem::LoadSample(const char *fileName)
|
||||||
|
{
|
||||||
|
JSample* sample = NULL;
|
||||||
|
sample = new JSample();
|
||||||
|
if (sample)
|
||||||
|
{
|
||||||
|
sample->filename = JFileSystem::GetInstance()->GetResourceFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSoundSystem::PlaySample(JSample *sample)
|
||||||
|
{
|
||||||
|
if(sample)
|
||||||
|
{
|
||||||
|
sndPlaySound(sample->filename.c_str(), SND_FILENAME | SND_ASYNC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ It is highly customizable and allows the player to tweak the rules / create thei
|
|||||||
|
|
||||||
Info, downloads, discussions and more at http://wololo.net/forum/index.php
|
Info, downloads, discussions and more at http://wololo.net/forum/index.php
|
||||||
|
|
||||||
-
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ skip_tags: true
|
|||||||
#---------------------------------#
|
#---------------------------------#
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
DXSDK_DIR: "C:/Program Files (x86)/Microsoft DirectX SDK/"
|
||||||
GH_TOKEN:
|
GH_TOKEN:
|
||||||
secure: dYnBDQkiY5oVjIlswzBX9BJigNtBGXgGlp1tK3XbHzrDEDrs2vaKD5m+Oz5OSz1C
|
secure: dYnBDQkiY5oVjIlswzBX9BJigNtBGXgGlp1tK3XbHzrDEDrs2vaKD5m+Oz5OSz1C
|
||||||
|
|
||||||
@@ -26,6 +27,10 @@ install:
|
|||||||
- "C:/Python27/python.exe C:/get-pip.py"
|
- "C:/Python27/python.exe C:/get-pip.py"
|
||||||
- "C:/Python27/Scripts/pip.exe install pyjavaproperties"
|
- "C:/Python27/Scripts/pip.exe install pyjavaproperties"
|
||||||
- "C:/Python27/Scripts/pip.exe install github3.py"
|
- "C:/Python27/Scripts/pip.exe install github3.py"
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- cd thirdparty/SDL2
|
||||||
|
# - git checkout release-2.0.3
|
||||||
|
- cd ../..
|
||||||
|
|
||||||
#---------------------------------#
|
#---------------------------------#
|
||||||
# build configuration #
|
# build configuration #
|
||||||
@@ -34,8 +39,16 @@ install:
|
|||||||
# build Configuration, i.e. Debug, Release, etc.
|
# build Configuration, i.e. Debug, Release, etc.
|
||||||
configuration: Release
|
configuration: Release
|
||||||
|
|
||||||
|
# scripts to run before build
|
||||||
|
before_build:
|
||||||
|
- echo Running cmake...
|
||||||
|
- mkdir build
|
||||||
|
- cd build
|
||||||
|
- cmake -Dbackend_sdl=ON ..
|
||||||
|
- cd ..
|
||||||
|
|
||||||
build:
|
build:
|
||||||
project: projects/mtg/mtg_vs2010.sln # path to Visual Studio solution or project
|
project: build/wagic.sln # path to Visual Studio solution or project
|
||||||
|
|
||||||
#---------------------------------#
|
#---------------------------------#
|
||||||
# tests configuration #
|
# tests configuration #
|
||||||
@@ -61,7 +74,7 @@ artifacts:
|
|||||||
# scripts to run before deployment
|
# scripts to run before deployment
|
||||||
before_deploy:
|
before_deploy:
|
||||||
- cd projects/mtg/bin
|
- cd projects/mtg/bin
|
||||||
- "C:/Python27/python.exe createWindowsZip.py"
|
- "C:/Python27/python.exe createWindowsZip.py -b ../../../build"
|
||||||
- cd ../../..
|
- cd ../../..
|
||||||
|
|
||||||
# scripts to run after deployment
|
# scripts to run after deployment
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
add_definitions(-DANDROID -DLINUX)
|
||||||
|
add_definitions(-D_STLP_USE_SIMPLE_NODE_ALLOC -D__arm__ -D_REENTRANT -D_GLIBCXX__PTHREADS)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="0192" android:versionName="@string/app_version" package="net.wagic.app">
|
||||||
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<application android:debuggable="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
|
<activity android:configChanges="keyboard|keyboardHidden|orientation" android:label="@string/app_name" android:name="org.libsdl.app.SDLActivity" android:screenOrientation="sensorLandscape">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:configChanges="keyboard|keyboardHidden|orientation" android:name="com.google.ads.AdActivity" android:screenOrientation="sensorLandscape"/>
|
||||||
|
</application>
|
||||||
|
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" android:targetSdkVersion="@ANDROID_NATIVE_API_LEVEL@"/>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
if(NOT ANDROID_PACKAGE_RELEASE)
|
||||||
|
set(ANDROID_PACKAGE_RELEASE 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID_PACKAGE_PLATFORM)
|
||||||
|
if(ARMEABI_V7A)
|
||||||
|
if(NEON)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM armv7a_neon)
|
||||||
|
else()
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM armv7a)
|
||||||
|
endif()
|
||||||
|
elseif(ARMEABI_V6)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM armv6)
|
||||||
|
elseif(ARMEABI)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM armv5)
|
||||||
|
elseif(X86)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM x86)
|
||||||
|
elseif(MIPS)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM mips)
|
||||||
|
else()
|
||||||
|
message(ERROR "Can not automatically determine the value for ANDROID_PACKAGE_PLATFORM")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID_PACKAGE_PLATFORM_NAME)
|
||||||
|
if(ARMEABI_V7A)
|
||||||
|
if(NEON)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v7a with NEON")
|
||||||
|
else()
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v7a")
|
||||||
|
endif()
|
||||||
|
elseif(ARMEABI_V6)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v6")
|
||||||
|
elseif(ARMEABI)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi")
|
||||||
|
elseif(X86)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "x86")
|
||||||
|
elseif(MIPS)
|
||||||
|
set(ANDROID_PACKAGE_PLATFORM_NAME "mips")
|
||||||
|
else()
|
||||||
|
message(ERROR "Can not automatically determine the value for ANDROID_PACKAGE_PLATFORM_NAME")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if("${ANDROID_NATIVE_API_LEVEL}" MATCHES "[1-9][0-9]*$")
|
||||||
|
set(ANDROID_SDK_VERSION ${CMAKE_MATCH_0})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID_SDK_VERSION GREATER 7)
|
||||||
|
set(ANDROID_SDK_VERSION 8)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PACKAGE_DIR "${CMAKE_BINARY_DIR}/package")
|
||||||
|
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
|
||||||
|
"${PACKAGE_DIR}/AndroidManifest.xml" @ONLY)
|
||||||
|
#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml"
|
||||||
|
# "${PACKAGE_DIR}/build.xml" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/values/strings.xml"
|
||||||
|
"${PACKAGE_DIR}/res/values/strings.xml" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/drawable-hdpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-hdpi/icon.png" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/drawable-ldpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-ldpi/icon.png" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/drawable-mdpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-mdpi/icon.png" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/layout/main.xml"
|
||||||
|
"${PACKAGE_DIR}/res/layout/main.xml" COPYONLY)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assets/_keystore/wagic-release.keystore"
|
||||||
|
"${PACKAGE_DIR}/assets/_keystore/wagic-release.keystore" COPYONLY)
|
||||||
|
|
||||||
|
string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL_NUMBER "${ANDROID_NATIVE_API_LEVEL}" )
|
||||||
|
|
||||||
|
set(target_name "Wagic_${WAGIC_VERSION}_binary_pack_${ANDROID_PACKAGE_PLATFORM}")
|
||||||
|
get_target_property(wagic_location wagic LOCATION)
|
||||||
|
|
||||||
|
string(TOLOWER ${CMAKE_BUILD_TYPE} android_build_type)
|
||||||
|
|
||||||
|
set(android_proj_target_files ${ANDROID_PROJECT_FILES})
|
||||||
|
list_add_prefix(android_proj_target_files "${PACKAGE_DIR}/")
|
||||||
|
set(APK_NAME "${PACKAGE_DIR}/bin/${target_name}-${android_build_type}-unsigned.apk")
|
||||||
|
|
||||||
|
file(GLOB camera_wrappers "${OpenCV_SOURCE_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}/libnative_camera_r*.so")
|
||||||
|
set(CAMERA_LIB_COMMANDS "")
|
||||||
|
|
||||||
|
foreach(wrapper ${camera_wrappers})
|
||||||
|
list(APPEND CAMERA_LIB_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${APK_NAME}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/libs"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/bin"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/gen"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove ${android_proj_target_files}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${PACKAGE_DIR}/src"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/"
|
||||||
|
# COMMAND ${CMAKE_COMMAND} -E copy "${SDL2_LIBRARY}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/"
|
||||||
|
# COMMAND ${CMAKE_COMMAND} -E copy "${ZLIB_LIBRARY}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/"
|
||||||
|
# COMMAND ${CMAKE_COMMAND} -E copy "${OPENSL_LIBRARY}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${wagic_location}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/src" "${PACKAGE_DIR}/src"
|
||||||
|
# COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${PACKAGE_DIR}" --target "android-${ANDROID_NATIVE_API_LEVEL}" --name "${target_name}"
|
||||||
|
COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${PACKAGE_DIR}" --target "android-10" --name "${target_name}"
|
||||||
|
COMMAND ${ANT_EXECUTABLE} -noinput -k ${android_build_type}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "${APK_NAME}"
|
||||||
|
WORKING_DIRECTORY "${PACKAGE_DIR}"
|
||||||
|
MAIN_DEPENDENCY "${PACKAGE_DIR}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
DEPENDS
|
||||||
|
"${PACKAGE_DIR}/res/values/strings.xml"
|
||||||
|
"${PACKAGE_DIR}/res/layout/main.xml"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-mdpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-ldpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/res/drawable-hdpi/icon.png"
|
||||||
|
"${PACKAGE_DIR}/${ANDROID_MANIFEST_FILE}"
|
||||||
|
wagic
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES "${APK_NAME}" DESTINATION "apk/" COMPONENT main)
|
||||||
|
add_custom_target(android_package ALL SOURCES "${APK_NAME}" )
|
||||||
|
add_dependencies(android_package wagic)
|
||||||
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/mainLayout"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Wagic"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Wagic</string>
|
||||||
|
<string name="app_version">0.19.2</string>
|
||||||
|
<string name="info_text">Wagic v0.19.2\\nAll Rights Reserved.</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
package net.wagic.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class StorageOptions
|
||||||
|
{
|
||||||
|
private static ArrayList<String> mMounts = new ArrayList<String>();
|
||||||
|
private static ArrayList<String> mVold = new ArrayList<String>();
|
||||||
|
|
||||||
|
public static String[] labels;
|
||||||
|
public static String[] paths;
|
||||||
|
public static int count = 0;
|
||||||
|
public static String defaultMountPoint;
|
||||||
|
|
||||||
|
public static void determineStorageOptions()
|
||||||
|
{
|
||||||
|
initializeMountPoints();
|
||||||
|
readMountsFile();
|
||||||
|
readVoldFile();
|
||||||
|
compareMountsWithVold();
|
||||||
|
testAndCleanMountsList();
|
||||||
|
setProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initializeMountPoints()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
defaultMountPoint = Environment.getExternalStorageDirectory().getCanonicalPath();
|
||||||
|
} catch (Exception ioEx)
|
||||||
|
{
|
||||||
|
// an error occurred trying to get the canonical path, use '/mnt/sdcard' instead
|
||||||
|
defaultMountPoint = "/mnt/sdcard";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readMountsFile()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Scan the /proc/mounts file and look for lines like this: /dev/block/vold/179:1 /mnt/sdcard vfat
|
||||||
|
* rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0602,dmask=0602,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
|
||||||
|
*
|
||||||
|
* When one is found, split it into its elements and then pull out the path to the that mount point and add it to the arraylist
|
||||||
|
*/
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Scanner scanner = new Scanner(new File("/proc/mounts"));
|
||||||
|
while (scanner.hasNext())
|
||||||
|
{
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
if (line.startsWith("/dev/block/vold/"))
|
||||||
|
{
|
||||||
|
String[] lineElements = line.split(" ");
|
||||||
|
lineElements[1].replaceAll(":.*$", "");
|
||||||
|
mMounts.add(lineElements[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException fnfex)
|
||||||
|
{
|
||||||
|
// if proc/mount doesn't exist we just use
|
||||||
|
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
||||||
|
mMounts.add(defaultMountPoint);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
|
||||||
|
mMounts.add(defaultMountPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readVoldFile()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Scan the /system/etc/vold.fstab file and look for lines like this: dev_mount sdcard /mnt/sdcard 1 /devices/platform/s3c-sdhci.0/mmc_host/mmc0
|
||||||
|
*
|
||||||
|
* When one is found, split it into its elements and then pull out the path to the that mount point and add it to the arraylist
|
||||||
|
*/
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));
|
||||||
|
while (scanner.hasNext())
|
||||||
|
{
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
if (line.startsWith("dev_mount"))
|
||||||
|
{
|
||||||
|
String[] lineElements = line.split(" ");
|
||||||
|
lineElements[2] = lineElements[2].replaceAll(":.*$", "");
|
||||||
|
mVold.add(lineElements[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException fnfex)
|
||||||
|
{
|
||||||
|
// if vold.fstab doesn't exist we use the value gathered from the Environment
|
||||||
|
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
||||||
|
mMounts.add(defaultMountPoint);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
|
||||||
|
mMounts.add(defaultMountPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void compareMountsWithVold()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Sometimes the two lists of mount points will be different. We only want those mount points that are in both list.
|
||||||
|
*
|
||||||
|
* Compare the two lists together and remove items that are not in both lists.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (int i = 0; i < mMounts.size(); i++)
|
||||||
|
{
|
||||||
|
String mount = mMounts.get(i);
|
||||||
|
if (!mVold.contains(mount))
|
||||||
|
mMounts.remove(i--);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't need this anymore, clear the vold list to reduce memory
|
||||||
|
// use and to prepare it for the next time it's needed.
|
||||||
|
mVold.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testAndCleanMountsList()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Now that we have a cleaned list of mount paths Test each one to make sure it's a valid and available path. If it is not, remove it from the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (int i = 0; i < mMounts.size(); i++)
|
||||||
|
{
|
||||||
|
String mount = mMounts.get(i);
|
||||||
|
File root = new File(mount);
|
||||||
|
if (!root.exists() || !root.isDirectory() || !root.canWrite())
|
||||||
|
mMounts.remove(i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setProperties()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* At this point all the paths in the list should be valid. Build the public properties.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ArrayList<String> mLabels = new ArrayList<String>();
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (String path : mMounts)
|
||||||
|
{ // TODO: /mnt/sdcard is assumed to always mean internal storage. Use this comparison until there is a better way to do this
|
||||||
|
if ("/mnt/sdcard".equalsIgnoreCase(path))
|
||||||
|
mLabels.add("Built-in Storage");
|
||||||
|
else
|
||||||
|
mLabels.add("External SD Card " + i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
labels = new String[mLabels.size()];
|
||||||
|
mLabels.toArray(labels);
|
||||||
|
|
||||||
|
paths = new String[mMounts.size()];
|
||||||
|
mMounts.toArray(paths);
|
||||||
|
|
||||||
|
count = Math.min(labels.length, paths.length);
|
||||||
|
|
||||||
|
// don't need this anymore, clear the mounts list to reduce memory
|
||||||
|
// use and to prepare it for the next time it's needed.
|
||||||
|
mMounts.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,771 @@
|
|||||||
|
package org.libsdl.app;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import android.app.*;
|
||||||
|
import android.content.*;
|
||||||
|
import android.view.*;
|
||||||
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputConnection;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.AbsoluteLayout;
|
||||||
|
import android.os.*;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.graphics.*;
|
||||||
|
import android.media.*;
|
||||||
|
import android.hardware.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
SDL Activity
|
||||||
|
*/
|
||||||
|
public class SDLActivity extends Activity {
|
||||||
|
private static final String TAG = "SDL";
|
||||||
|
|
||||||
|
// Keep track of the paused state
|
||||||
|
public static boolean mIsPaused = false, mIsSurfaceReady = false, mHasFocus = true;
|
||||||
|
|
||||||
|
// Main components
|
||||||
|
protected static SDLActivity mSingleton;
|
||||||
|
protected static SDLSurface mSurface;
|
||||||
|
protected static View mTextEdit;
|
||||||
|
protected static ViewGroup mLayout;
|
||||||
|
|
||||||
|
// This is what SDL runs in. It invokes SDL_main(), eventually
|
||||||
|
protected static Thread mSDLThread;
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
protected static Thread mAudioThread;
|
||||||
|
protected static AudioTrack mAudioTrack;
|
||||||
|
|
||||||
|
// Load the .so
|
||||||
|
static {
|
||||||
|
System.loadLibrary("SDL2");
|
||||||
|
//System.loadLibrary("SDL2_image");
|
||||||
|
//System.loadLibrary("SDL2_mixer");
|
||||||
|
//System.loadLibrary("SDL2_net");
|
||||||
|
//System.loadLibrary("SDL2_ttf");
|
||||||
|
System.loadLibrary("wagic");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
//Log.v("SDL", "onCreate()");
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// So we can call stuff from static callbacks
|
||||||
|
mSingleton = this;
|
||||||
|
|
||||||
|
// Set up the surface
|
||||||
|
mSurface = new SDLSurface(getApplication());
|
||||||
|
|
||||||
|
mLayout = new AbsoluteLayout(this);
|
||||||
|
mLayout.addView(mSurface);
|
||||||
|
|
||||||
|
setContentView(mLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
Log.v("SDL", "onPause()");
|
||||||
|
super.onPause();
|
||||||
|
SDLActivity.handlePause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
Log.v("SDL", "onResume()");
|
||||||
|
super.onResume();
|
||||||
|
SDLActivity.handleResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
Log.v("SDL", "onWindowFocusChanged(): " + hasFocus);
|
||||||
|
|
||||||
|
SDLActivity.mHasFocus = hasFocus;
|
||||||
|
if (hasFocus) {
|
||||||
|
SDLActivity.handleResume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory() {
|
||||||
|
Log.v("SDL", "onLowMemory()");
|
||||||
|
super.onLowMemory();
|
||||||
|
SDLActivity.nativeLowMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
Log.v("SDL", "onDestroy()");
|
||||||
|
// Send a quit message to the application
|
||||||
|
SDLActivity.nativeQuit();
|
||||||
|
|
||||||
|
// Now wait for the SDL thread to quit
|
||||||
|
if (mSDLThread != null) {
|
||||||
|
try {
|
||||||
|
mSDLThread.join();
|
||||||
|
} catch(Exception e) {
|
||||||
|
Log.v("SDL", "Problem stopping thread: " + e);
|
||||||
|
}
|
||||||
|
mSDLThread = null;
|
||||||
|
|
||||||
|
//Log.v("SDL", "Finished waiting for SDL thread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||||
|
int keyCode = event.getKeyCode();
|
||||||
|
// Ignore certain special keys so they're handled by Android
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
|
||||||
|
keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
|
||||||
|
keyCode == KeyEvent.KEYCODE_CAMERA ||
|
||||||
|
keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */
|
||||||
|
keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.dispatchKeyEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed
|
||||||
|
* is the first to be called, mIsSurfaceReady should still be set
|
||||||
|
* to 'true' during the call to onPause (in a usual scenario).
|
||||||
|
*/
|
||||||
|
public static void handlePause() {
|
||||||
|
if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) {
|
||||||
|
SDLActivity.mIsPaused = true;
|
||||||
|
SDLActivity.nativePause();
|
||||||
|
mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready.
|
||||||
|
* Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume
|
||||||
|
* every time we get one of those events, only if it comes after surfaceDestroyed
|
||||||
|
*/
|
||||||
|
public static void handleResume() {
|
||||||
|
if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) {
|
||||||
|
SDLActivity.mIsPaused = false;
|
||||||
|
SDLActivity.nativeResume();
|
||||||
|
mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Messages from the SDLMain thread
|
||||||
|
static final int COMMAND_CHANGE_TITLE = 1;
|
||||||
|
static final int COMMAND_UNUSED = 2;
|
||||||
|
static final int COMMAND_TEXTEDIT_HIDE = 3;
|
||||||
|
|
||||||
|
protected static final int COMMAND_USER = 0x8000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called by SDL if SDL did not handle a message itself.
|
||||||
|
* This happens if a received message contains an unsupported command.
|
||||||
|
* Method can be overwritten to handle Messages in a different class.
|
||||||
|
* @param command the command of the message.
|
||||||
|
* @param param the parameter of the message. May be null.
|
||||||
|
* @return if the message was handled in overridden method.
|
||||||
|
*/
|
||||||
|
protected boolean onUnhandledMessage(int command, Object param) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Handler class for Messages from native SDL applications.
|
||||||
|
* It uses current Activities as target (e.g. for the title).
|
||||||
|
* static to prevent implicit references to enclosing object.
|
||||||
|
*/
|
||||||
|
protected static class SDLCommandHandler extends Handler {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context == null) {
|
||||||
|
Log.e(TAG, "error handling message, getContext() returned null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (msg.arg1) {
|
||||||
|
case COMMAND_CHANGE_TITLE:
|
||||||
|
if (context instanceof Activity) {
|
||||||
|
((Activity) context).setTitle((String)msg.obj);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "error handling message, getContext() returned no Activity");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMMAND_TEXTEDIT_HIDE:
|
||||||
|
if (mTextEdit != null) {
|
||||||
|
mTextEdit.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
|
||||||
|
Log.e(TAG, "error handling message, command is " + msg.arg1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler for the messages
|
||||||
|
Handler commandHandler = new SDLCommandHandler();
|
||||||
|
|
||||||
|
// Send a message from the SDLMain thread
|
||||||
|
boolean sendCommand(int command, Object data) {
|
||||||
|
Message msg = commandHandler.obtainMessage();
|
||||||
|
msg.arg1 = command;
|
||||||
|
msg.obj = data;
|
||||||
|
return commandHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// C functions we call
|
||||||
|
public static native void nativeInit();
|
||||||
|
public static native void nativeLowMemory();
|
||||||
|
public static native void nativeQuit();
|
||||||
|
public static native void nativePause();
|
||||||
|
public static native void nativeResume();
|
||||||
|
public static native void onNativeResize(int x, int y, int format);
|
||||||
|
public static native void onNativeKeyDown(int keycode);
|
||||||
|
public static native void onNativeKeyUp(int keycode);
|
||||||
|
public static native void onNativeKeyboardFocusLost();
|
||||||
|
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
|
||||||
|
int action, float x,
|
||||||
|
float y, float p);
|
||||||
|
public static native void onNativeAccel(float x, float y, float z);
|
||||||
|
public static native void onNativeSurfaceChanged();
|
||||||
|
public static native void onNativeSurfaceDestroyed();
|
||||||
|
public static native void nativeFlipBuffers();
|
||||||
|
|
||||||
|
public static void flipBuffers() {
|
||||||
|
SDLActivity.nativeFlipBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean setActivityTitle(String title) {
|
||||||
|
// Called from SDLMain() thread and can't directly affect the view
|
||||||
|
return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean sendMessage(int command, int param) {
|
||||||
|
return mSingleton.sendCommand(command, Integer.valueOf(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context getContext() {
|
||||||
|
return mSingleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ShowTextInputTask implements Runnable {
|
||||||
|
/*
|
||||||
|
* This is used to regulate the pan&scan method to have some offset from
|
||||||
|
* the bottom edge of the input region and the top edge of an input
|
||||||
|
* method (soft keyboard)
|
||||||
|
*/
|
||||||
|
static final int HEIGHT_PADDING = 15;
|
||||||
|
|
||||||
|
public int x, y, w, h;
|
||||||
|
|
||||||
|
public ShowTextInputTask(int x, int y, int w, int h) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.w = w;
|
||||||
|
this.h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
|
||||||
|
w, h + HEIGHT_PADDING, x, y);
|
||||||
|
|
||||||
|
if (mTextEdit == null) {
|
||||||
|
mTextEdit = new DummyEdit(getContext());
|
||||||
|
|
||||||
|
mLayout.addView(mTextEdit, params);
|
||||||
|
} else {
|
||||||
|
mTextEdit.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTextEdit.setVisibility(View.VISIBLE);
|
||||||
|
mTextEdit.requestFocus();
|
||||||
|
|
||||||
|
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mTextEdit, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean showTextInput(int x, int y, int w, int h) {
|
||||||
|
// Transfer the task to the main thread as a Runnable
|
||||||
|
return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Surface getNativeSurface() {
|
||||||
|
return SDLActivity.mSurface.getNativeSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
||||||
|
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||||
|
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
||||||
|
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
||||||
|
|
||||||
|
Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||||
|
|
||||||
|
// Let the user pick a larger buffer if they really want -- but ye
|
||||||
|
// gods they probably shouldn't, the minimums are horrifyingly high
|
||||||
|
// latency already
|
||||||
|
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
|
||||||
|
|
||||||
|
if (mAudioTrack == null) {
|
||||||
|
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
|
||||||
|
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
|
||||||
|
|
||||||
|
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
|
||||||
|
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
|
||||||
|
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
|
||||||
|
|
||||||
|
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
|
||||||
|
Log.e("SDL", "Failed during initialization of Audio Track");
|
||||||
|
mAudioTrack = null;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAudioTrack.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void audioWriteShortBuffer(short[] buffer) {
|
||||||
|
for (int i = 0; i < buffer.length; ) {
|
||||||
|
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||||
|
if (result > 0) {
|
||||||
|
i += result;
|
||||||
|
} else if (result == 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
// Nom nom
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w("SDL", "SDL audio: error return from write(short)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void audioWriteByteBuffer(byte[] buffer) {
|
||||||
|
for (int i = 0; i < buffer.length; ) {
|
||||||
|
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||||
|
if (result > 0) {
|
||||||
|
i += result;
|
||||||
|
} else if (result == 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
// Nom nom
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w("SDL", "SDL audio: error return from write(byte)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void audioQuit() {
|
||||||
|
if (mAudioTrack != null) {
|
||||||
|
mAudioTrack.stop();
|
||||||
|
mAudioTrack = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an array which may be empty but is never null.
|
||||||
|
*/
|
||||||
|
public static int[] inputGetInputDeviceIds(int sources) {
|
||||||
|
int[] ids = InputDevice.getDeviceIds();
|
||||||
|
int[] filtered = new int[ids.length];
|
||||||
|
int used = 0;
|
||||||
|
for (int i = 0; i < ids.length; ++i) {
|
||||||
|
InputDevice device = InputDevice.getDevice(ids[i]);
|
||||||
|
if ((device != null) && ((device.getSources() & sources) != 0)) {
|
||||||
|
filtered[used++] = device.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Arrays.copyOf(filtered, used);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Simple nativeInit() runnable
|
||||||
|
*/
|
||||||
|
class SDLMain implements Runnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Runs SDL_main()
|
||||||
|
SDLActivity.nativeInit();
|
||||||
|
|
||||||
|
//Log.v("SDL", "SDL thread terminated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
SDLSurface. This is what we draw on, so we need to know when it's created
|
||||||
|
in order to do anything useful.
|
||||||
|
|
||||||
|
Because of this, that's where we set up the SDL thread
|
||||||
|
*/
|
||||||
|
class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||||
|
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
|
||||||
|
|
||||||
|
// Sensors
|
||||||
|
protected static SensorManager mSensorManager;
|
||||||
|
protected static Display mDisplay;
|
||||||
|
|
||||||
|
// Keep track of the surface size to normalize touch events
|
||||||
|
protected static float mWidth, mHeight;
|
||||||
|
|
||||||
|
// Startup
|
||||||
|
public SDLSurface(Context context) {
|
||||||
|
super(context);
|
||||||
|
getHolder().addCallback(this);
|
||||||
|
|
||||||
|
setFocusable(true);
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
requestFocus();
|
||||||
|
setOnKeyListener(this);
|
||||||
|
setOnTouchListener(this);
|
||||||
|
|
||||||
|
mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||||
|
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
|
||||||
|
// Some arbitrary defaults to avoid a potential division by zero
|
||||||
|
mWidth = 1.0f;
|
||||||
|
mHeight = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Surface getNativeSurface() {
|
||||||
|
return getHolder().getSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when we have a valid drawing surface
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
Log.v("SDL", "surfaceCreated()");
|
||||||
|
holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when we lose the surface
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
Log.v("SDL", "surfaceDestroyed()");
|
||||||
|
// Call this *before* setting mIsSurfaceReady to 'false'
|
||||||
|
SDLActivity.handlePause();
|
||||||
|
SDLActivity.mIsSurfaceReady = false;
|
||||||
|
SDLActivity.onNativeSurfaceDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the surface is resized
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder,
|
||||||
|
int format, int width, int height) {
|
||||||
|
Log.v("SDL", "surfaceChanged()");
|
||||||
|
|
||||||
|
int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
|
||||||
|
switch (format) {
|
||||||
|
case PixelFormat.A_8:
|
||||||
|
Log.v("SDL", "pixel format A_8");
|
||||||
|
break;
|
||||||
|
case PixelFormat.LA_88:
|
||||||
|
Log.v("SDL", "pixel format LA_88");
|
||||||
|
break;
|
||||||
|
case PixelFormat.L_8:
|
||||||
|
Log.v("SDL", "pixel format L_8");
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGBA_4444:
|
||||||
|
Log.v("SDL", "pixel format RGBA_4444");
|
||||||
|
sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGBA_5551:
|
||||||
|
Log.v("SDL", "pixel format RGBA_5551");
|
||||||
|
sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGBA_8888:
|
||||||
|
Log.v("SDL", "pixel format RGBA_8888");
|
||||||
|
sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGBX_8888:
|
||||||
|
Log.v("SDL", "pixel format RGBX_8888");
|
||||||
|
sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGB_332:
|
||||||
|
Log.v("SDL", "pixel format RGB_332");
|
||||||
|
sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGB_565:
|
||||||
|
Log.v("SDL", "pixel format RGB_565");
|
||||||
|
sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
|
||||||
|
break;
|
||||||
|
case PixelFormat.RGB_888:
|
||||||
|
Log.v("SDL", "pixel format RGB_888");
|
||||||
|
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
|
||||||
|
sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.v("SDL", "pixel format unknown " + format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = height;
|
||||||
|
SDLActivity.onNativeResize(width, height, sdlFormat);
|
||||||
|
Log.v("SDL", "Window size:" + width + "x"+height);
|
||||||
|
|
||||||
|
// Set mIsSurfaceReady to 'true' *before* making a call to handleResume
|
||||||
|
SDLActivity.mIsSurfaceReady = true;
|
||||||
|
SDLActivity.onNativeSurfaceChanged();
|
||||||
|
|
||||||
|
|
||||||
|
if (SDLActivity.mSDLThread == null) {
|
||||||
|
// This is the entry point to the C app.
|
||||||
|
// Start up the C app thread and enable sensor input for the first time
|
||||||
|
|
||||||
|
SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread");
|
||||||
|
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||||
|
SDLActivity.mSDLThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unused
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas) {}
|
||||||
|
|
||||||
|
|
||||||
|
// Key events
|
||||||
|
@Override
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
|
//Log.v("SDL", "key down: " + keyCode);
|
||||||
|
SDLActivity.onNativeKeyDown(keyCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
//Log.v("SDL", "key up: " + keyCode);
|
||||||
|
SDLActivity.onNativeKeyUp(keyCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touch events
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
final int touchDevId = event.getDeviceId();
|
||||||
|
final int pointerCount = event.getPointerCount();
|
||||||
|
// touchId, pointerId, action, x, y, pressure
|
||||||
|
int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */
|
||||||
|
int pointerFingerId = event.getPointerId(actionPointerIndex);
|
||||||
|
int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */
|
||||||
|
|
||||||
|
float x = event.getX(actionPointerIndex) / mWidth;
|
||||||
|
float y = event.getY(actionPointerIndex) / mHeight;
|
||||||
|
float p = event.getPressure(actionPointerIndex);
|
||||||
|
|
||||||
|
if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
|
||||||
|
// TODO send motion to every pointer if its position has
|
||||||
|
// changed since prev event.
|
||||||
|
for (int i = 0; i < pointerCount; i++) {
|
||||||
|
pointerFingerId = event.getPointerId(i);
|
||||||
|
x = event.getX(i) / mWidth;
|
||||||
|
y = event.getY(i) / mHeight;
|
||||||
|
p = event.getPressure(i);
|
||||||
|
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sensor events
|
||||||
|
public void enableSensor(int sensortype, boolean enabled) {
|
||||||
|
// TODO: This uses getDefaultSensor - what if we have >1 accels?
|
||||||
|
if (enabled) {
|
||||||
|
mSensorManager.registerListener(this,
|
||||||
|
mSensorManager.getDefaultSensor(sensortype),
|
||||||
|
SensorManager.SENSOR_DELAY_GAME, null);
|
||||||
|
} else {
|
||||||
|
mSensorManager.unregisterListener(this,
|
||||||
|
mSensorManager.getDefaultSensor(sensortype));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||||
|
float x, y;
|
||||||
|
switch (mDisplay.getRotation()) {
|
||||||
|
case Surface.ROTATION_90:
|
||||||
|
x = -event.values[1];
|
||||||
|
y = event.values[0];
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
x = event.values[1];
|
||||||
|
y = -event.values[0];
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_180:
|
||||||
|
x = -event.values[1];
|
||||||
|
y = -event.values[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x = event.values[0];
|
||||||
|
y = event.values[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
|
||||||
|
y / SensorManager.GRAVITY_EARTH,
|
||||||
|
event.values[2] / SensorManager.GRAVITY_EARTH - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a fake invisible editor view that receives the input and defines the
|
||||||
|
* pan&scan region
|
||||||
|
*/
|
||||||
|
class DummyEdit extends View implements View.OnKeyListener {
|
||||||
|
InputConnection ic;
|
||||||
|
|
||||||
|
public DummyEdit(Context context) {
|
||||||
|
super(context);
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
setFocusable(true);
|
||||||
|
setOnKeyListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCheckIsTextEditor() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
|
||||||
|
// This handles the hardware keyboard input
|
||||||
|
if (event.isPrintingKey()) {
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
|
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
|
SDLActivity.onNativeKeyDown(keyCode);
|
||||||
|
return true;
|
||||||
|
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
SDLActivity.onNativeKeyUp(keyCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
@Override
|
||||||
|
public boolean onKeyPreIme (int keyCode, KeyEvent event) {
|
||||||
|
// As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
|
||||||
|
// FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
|
||||||
|
// FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
|
||||||
|
// FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
|
||||||
|
// FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
|
||||||
|
// FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
|
||||||
|
if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
|
if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
|
||||||
|
SDLActivity.onNativeKeyboardFocusLost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onKeyPreIme(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||||
|
ic = new SDLInputConnection(this, true);
|
||||||
|
|
||||||
|
outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
|
||||||
|
| 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
|
||||||
|
|
||||||
|
return ic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SDLInputConnection extends BaseInputConnection {
|
||||||
|
|
||||||
|
public SDLInputConnection(View targetView, boolean fullEditor) {
|
||||||
|
super(targetView, fullEditor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendKeyEvent(KeyEvent event) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This handles the keycodes from soft keyboard (and IME-translated
|
||||||
|
* input from hardkeyboard)
|
||||||
|
*/
|
||||||
|
int keyCode = event.getKeyCode();
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
|
if (event.isPrintingKey()) {
|
||||||
|
commitText(String.valueOf((char) event.getUnicodeChar()), 1);
|
||||||
|
}
|
||||||
|
SDLActivity.onNativeKeyDown(keyCode);
|
||||||
|
return true;
|
||||||
|
} else if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
|
||||||
|
SDLActivity.onNativeKeyUp(keyCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.sendKeyEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||||
|
|
||||||
|
nativeCommitText(text.toString(), newCursorPosition);
|
||||||
|
|
||||||
|
return super.commitText(text, newCursorPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||||
|
|
||||||
|
nativeSetComposingText(text.toString(), newCursorPosition);
|
||||||
|
|
||||||
|
return super.setComposingText(text, newCursorPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public native void nativeCommitText(String text, int newCursorPosition);
|
||||||
|
|
||||||
|
public native void nativeSetComposingText(String text, int newCursorPosition);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
set(CMAKE_CXX_FLAGS "-s USE_SDL=2 -s USE_ZLIB=1 -s FULL_ES2=1 -std=c++11 -s TOTAL_MEMORY=16777216 -O0 --preload-file ../../../projects/mtg/bin/Res@/")
|
||||||
|
#set(CMAKE_CXX_FLAGS "-s USE_SDL=2 -s FULL_ES2=1 -std=c++11 -g4 -s ALLOW_MEMORY_GROWTH=1 --preload-file ../../../projects/mtg/bin/Res@/")
|
||||||
|
set(CMAKE_EXECUTABLE_SUFFIX ".html")
|
||||||
|
add_definitions(-DLINUX)
|
||||||
|
add_definitions(-D_DEBUG)
|
||||||
|
add_definitions(-DUSERDIR=".wagic")
|
||||||
|
add_definitions(-DRESDIR="/")
|
||||||
|
add_definitions(-DGL_ES_VERSION_2_0)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
add_definitions(-DLINUX)
|
||||||
|
add_definitions(-DUSERDIR=".wagic")
|
||||||
|
add_definitions(-DRESDIR="Res")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++0x")
|
||||||
|
set(CMAKE_PREFIX_PATH "/usr/local/opt/qt5")
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
add_definitions(-DPSP -G0)
|
||||||
|
add_definitions(-D_PSP_FW_VERSION=371)
|
||||||
|
add_definitions(-DDEVHOOK -DPSPFW3XX)
|
||||||
|
|
||||||
|
include_directories(${PSPSDK_PATH}/include)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
add_definitions(-DLINUX)
|
||||||
|
add_definitions(-DUSERDIR=".wagic")
|
||||||
|
add_definitions(-DRESDIR="Res")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
add_definitions(-DWIN32)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
/gen
|
/gen
|
||||||
/bin
|
/bin
|
||||||
|
/libs
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,13 @@
|
|||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<application android:debuggable="false" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||||
<activity android:configChanges="keyboard|keyboardHidden|orientation" android:label="@string/app_name" android:name="org.libsdl.app.SDLActivity" android:screenOrientation="sensorLandscape">
|
<activity android:debuggable="false" android:configChanges="keyboard|keyboardHidden|orientation" android:label="@string/app_name" android:name="org.libsdl.app.SDLActivity" android:screenOrientation="sensorLandscape">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:configChanges="keyboard|keyboardHidden|orientation" android:name="com.google.ads.AdActivity" android:screenOrientation="sensorLandscape"/>
|
|
||||||
</application>
|
</application>
|
||||||
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
|
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
APP_PROJECT_PATH := $(call my-dir)/..
|
APP_PROJECT_PATH := $(call my-dir)/..
|
||||||
APP_CPPFLAGS += -frtti -fexceptions
|
APP_CPPFLAGS += -frtti -fexceptions
|
||||||
APP_ABI := armeabi armeabi-v7a
|
APP_ABI := armeabi armeabi-v7a
|
||||||
|
#APP_ABI := x86 # mainly for emulators
|
||||||
APP_STL := gnustl_static
|
APP_STL := gnustl_static
|
||||||
APP_MODULES := libpng libjpeg main SDL
|
APP_MODULES := libpng libjpeg main SDL
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -11,14 +11,13 @@ import android.util.Log;
|
|||||||
|
|
||||||
public class DeckImporter
|
public class DeckImporter
|
||||||
{
|
{
|
||||||
|
|
||||||
public static String importDeck( File f, String mypath, String activePath )
|
public static String importDeck( File f, String mypath, String activePath )
|
||||||
{
|
{
|
||||||
String message = "";
|
String message = "";
|
||||||
String deck = "";
|
String deck = "";
|
||||||
String deckname = "";
|
String deckname = "";
|
||||||
String prefix = "#SB:";
|
String prefix = "#SB:";
|
||||||
int cardcount = 0;
|
int cardcount = 0;
|
||||||
if(f.exists() && !f.isDirectory())
|
if(f.exists() && !f.isDirectory())
|
||||||
{
|
{
|
||||||
deckname = f.getName();
|
deckname = f.getName();
|
||||||
@@ -36,91 +35,86 @@ public class DeckImporter
|
|||||||
while (scanner.hasNext())
|
while (scanner.hasNext())
|
||||||
{
|
{
|
||||||
String line = scanner.nextLine();
|
String line = scanner.nextLine();
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (!line.equals("") && cardcount < 61) // don't write out blank lines
|
if (!line.equals("") && cardcount < 61) // don't write out blank lines
|
||||||
{
|
{
|
||||||
String[] slines = line.split("\\s+");
|
String[] slines = line.split("\\s+");
|
||||||
String arranged = "";
|
String arranged = "";
|
||||||
for(int idx = 1; idx < slines.length; idx++)
|
for (int idx = 1; idx < slines.length; idx++)
|
||||||
{
|
{
|
||||||
arranged += slines[idx] + " ";
|
arranged += slines[idx] + " ";
|
||||||
}
|
}
|
||||||
if ((isNumeric(slines[0])) && arranged != null)
|
if ((isNumeric(slines[0])) && arranged != null)
|
||||||
{
|
{
|
||||||
if (slines[1] != null && slines[1].startsWith("["))
|
if (slines[1] != null && slines[1].startsWith("["))
|
||||||
{
|
{
|
||||||
arranged = arranged.substring(5);
|
arranged = arranged.substring(5);
|
||||||
slines[1] = slines[1].replaceAll("\\[", "").replaceAll("\\]","");
|
slines[1] = slines[1].replaceAll("\\[", "").replaceAll("\\]", "");
|
||||||
deck += arranged + " (" + renameSet(slines[1]) + ") * " + slines[0] + "\n";
|
deck += arranged + " (" + renameSet(slines[1]) + ") * " + slines[0] + "\n";
|
||||||
}
|
} else
|
||||||
else
|
{
|
||||||
{
|
deck += arranged + "(*) * " + slines[0] + "\n";
|
||||||
deck += arranged + "(*) * " + slines[0] + "\n";
|
}
|
||||||
}
|
cardcount += Integer.parseInt(slines[0]);
|
||||||
cardcount += Integer.parseInt(slines[0]);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
File profile = new File(activePath + "/Res/settings/options.txt");
|
||||||
File profile = new File(activePath+"/Res/settings/options.txt");
|
if (profile.exists() && !profile.isDirectory())
|
||||||
if(profile.exists() && !profile.isDirectory())
|
{
|
||||||
{
|
String profileName = getActiveProfile(profile);
|
||||||
String profileName = getActiveProfile(profile);
|
if (profileName != "Missing!")
|
||||||
if(profileName != "Missing!")
|
{
|
||||||
{
|
File rootProfiles = new File(activePath + "/Res/profiles/" + profileName);
|
||||||
File rootProfiles = new File(activePath+"/Res/profiles/"+profileName);
|
if (rootProfiles.exists() && rootProfiles.isDirectory())
|
||||||
if(rootProfiles.exists() && rootProfiles.isDirectory())
|
{
|
||||||
{
|
//save deck
|
||||||
//save deck
|
int countdeck = 1;
|
||||||
int countdeck = 1;
|
File[] files = rootProfiles.listFiles();
|
||||||
File[] files = rootProfiles.listFiles();
|
for (int i = 0; i < files.length; i++)
|
||||||
for (int i = 0; i < files.length; i++)
|
{//check if there is available deck...
|
||||||
{//check if there is available deck...
|
if (files[i].getName().startsWith("deck"))
|
||||||
if(files[i].getName().startsWith("deck"))
|
countdeck++;
|
||||||
countdeck++;
|
}
|
||||||
}
|
File toSave = new File(rootProfiles + "/deck" + countdeck + ".txt");
|
||||||
File toSave = new File(rootProfiles+"/deck"+countdeck+".txt");
|
try
|
||||||
try
|
{
|
||||||
{
|
FileOutputStream fop = new FileOutputStream(toSave);
|
||||||
FileOutputStream fop = new FileOutputStream(toSave);
|
|
||||||
|
// if file doesn't exists, then create it
|
||||||
// if file doesn't exists, then create it
|
if (!toSave.exists())
|
||||||
if (!toSave.exists()) {
|
{
|
||||||
toSave.createNewFile();
|
toSave.createNewFile();
|
||||||
}
|
}
|
||||||
// get the content in bytes
|
// get the content in bytes
|
||||||
byte[] contentInBytes = deck.getBytes();
|
byte[] contentInBytes = deck.getBytes();
|
||||||
fop.write(contentInBytes);
|
fop.write(contentInBytes);
|
||||||
fop.flush();
|
fop.flush();
|
||||||
fop.close();
|
fop.close();
|
||||||
message = "Import Deck Success!\n"+cardcount+" total cards in this deck\n\n"+deck;
|
message = "Import Deck Success!\n" + cardcount + " total cards in this deck\n\n" + deck;
|
||||||
}
|
} catch (IOException e)
|
||||||
catch (IOException e)
|
{
|
||||||
{
|
message = e.getMessage();
|
||||||
message = e.getMessage();
|
}
|
||||||
}
|
} else
|
||||||
}
|
{
|
||||||
else
|
message = "Missing Folder!";
|
||||||
{
|
}
|
||||||
message = "Missing Folder!";
|
}
|
||||||
}
|
} else
|
||||||
}
|
{
|
||||||
}
|
message = "Invalid Profile!";
|
||||||
else
|
}
|
||||||
{
|
} else
|
||||||
message = "Invalid Profile!";
|
{
|
||||||
}
|
message = "No errors, and file EMPTY";
|
||||||
}
|
}
|
||||||
else
|
} catch (IOException e)
|
||||||
{
|
{
|
||||||
message = "No errors, and file EMPTY";
|
message = e.getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(IOException e)
|
return message;
|
||||||
{
|
|
||||||
message = e.getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNumeric(String input)
|
private static boolean isNumeric(String input)
|
||||||
@@ -135,7 +129,7 @@ public class DeckImporter
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getActiveProfile(File mypath)
|
private static String getActiveProfile(File mypath)
|
||||||
{
|
{
|
||||||
String name = "";
|
String name = "";
|
||||||
@@ -158,7 +152,7 @@ public class DeckImporter
|
|||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String renameSet(String set)
|
private static String renameSet(String set)
|
||||||
{
|
{
|
||||||
if (set == "")
|
if (set == "")
|
||||||
@@ -278,5 +272,4 @@ public class DeckImporter
|
|||||||
else
|
else
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
public class StorageOptions
|
public class StorageOptions
|
||||||
{
|
{
|
||||||
|
private static final String TAG = StorageOptions.class.getCanonicalName();
|
||||||
private static ArrayList<String> mMounts = new ArrayList<String>();
|
private static ArrayList<String> mMounts = new ArrayList<String>();
|
||||||
private static ArrayList<String> mVold = new ArrayList<String>();
|
private static ArrayList<String> mVold = new ArrayList<String>();
|
||||||
|
|
||||||
@@ -77,11 +78,11 @@ public class StorageOptions
|
|||||||
} catch (FileNotFoundException fnfex)
|
} catch (FileNotFoundException fnfex)
|
||||||
{
|
{
|
||||||
// if proc/mount doesn't exist we just use
|
// if proc/mount doesn't exist we just use
|
||||||
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
Log.i(TAG, fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
|
Log.e(TAG, e.getMessage() + ": unknown exception while reading mounts file");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,11 +112,11 @@ public class StorageOptions
|
|||||||
} catch (FileNotFoundException fnfex)
|
} catch (FileNotFoundException fnfex)
|
||||||
{
|
{
|
||||||
// if proc/mount doesn't exist we just use
|
// if proc/mount doesn't exist we just use
|
||||||
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
Log.i(TAG, fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
|
Log.e(TAG, e.getMessage() + ": unknown exception while reading mounts file");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,11 +145,11 @@ public class StorageOptions
|
|||||||
} catch (FileNotFoundException fnfex)
|
} catch (FileNotFoundException fnfex)
|
||||||
{
|
{
|
||||||
// if vold.fstab doesn't exist we use the value gathered from the Environment
|
// if vold.fstab doesn't exist we use the value gathered from the Environment
|
||||||
Log.i(StorageOptions.class.getCanonicalName(), fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
Log.i(TAG, fnfex.getMessage() + ": assuming " + defaultMountPoint + " is the only mount point");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e(StorageOptions.class.getCanonicalName(), e.getMessage() + ": unknown exception while reading mounts file");
|
Log.e(TAG, e.getMessage() + ": unknown exception while reading vold.fstab file");
|
||||||
mMounts.add(defaultMountPoint);
|
mMounts.add(defaultMountPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,15 +175,18 @@ public class StorageOptions
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Sometimes the two lists of mount points will be different. We only want those mount points that are in both list.
|
* Sometimes the two lists of mount points will be different. We only want those mount points that are in both list.
|
||||||
*
|
*
|
||||||
* Compare the two lists together and remove items that are not in both lists.
|
* Compare the two lists together and remove items that are not in both lists.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (int i = 0; i < mMounts.size(); i++)
|
if (mVold.size() > 0)
|
||||||
{
|
{
|
||||||
String mount = mMounts.get(i);
|
for (int i = 0; i < mMounts.size(); i++)
|
||||||
if (!mVold.contains(mount))
|
{
|
||||||
mMounts.remove(i--);
|
String mount = mMounts.get(i);
|
||||||
|
if (!mVold.contains(mount))
|
||||||
|
mMounts.remove(i--);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't need this anymore, clear the vold list to reduce memory
|
// don't need this anymore, clear the vold list to reduce memory
|
||||||
@@ -204,9 +208,10 @@ public class StorageOptions
|
|||||||
if (!root.exists() || !root.isDirectory() || !root.canWrite())
|
if (!root.exists() || !root.isDirectory() || !root.canWrite())
|
||||||
mMounts.remove(i--);
|
mMounts.remove(i--);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == 0 && Build.VERSION.SDK_INT >= 16 && findForcemount())
|
if (t == 0 && Build.VERSION.SDK_INT >= 16 && findForcemount())
|
||||||
{//if none is found lets force it for Jellybean and above...
|
{
|
||||||
|
//if none is found lets force it for Jellybean and above...
|
||||||
if (System.getenv("EXTERNAL_STORAGE") != null)
|
if (System.getenv("EXTERNAL_STORAGE") != null)
|
||||||
{
|
{
|
||||||
File root = new File(System.getenv("EXTERNAL_STORAGE"));
|
File root = new File(System.getenv("EXTERNAL_STORAGE"));
|
||||||
@@ -224,7 +229,7 @@ public class StorageOptions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.getenv("SECONDARY_STORAGE") != null)
|
if (System.getenv("SECONDARY_STORAGE") != null)
|
||||||
{
|
{
|
||||||
File root = new File(System.getenv("SECONDARY_STORAGE"));
|
File root = new File(System.getenv("SECONDARY_STORAGE"));
|
||||||
@@ -247,6 +252,7 @@ public class StorageOptions
|
|||||||
|
|
||||||
private static void setProperties()
|
private static void setProperties()
|
||||||
{
|
{
|
||||||
|
Log.d(TAG, "setProperties()");
|
||||||
/*
|
/*
|
||||||
* At this point all the paths in the list should be valid. Build the public properties.
|
* At this point all the paths in the list should be valid. Build the public properties.
|
||||||
*/
|
*/
|
||||||
@@ -268,7 +274,8 @@ public class StorageOptions
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (String path : mMounts)
|
for (String path : mMounts)
|
||||||
{ // TODO: /mnt/sdcard is assumed to always mean internal storage. Use this comparison until there is a better way to do this
|
{
|
||||||
|
// TODO: /mnt/sdcard is assumed to always mean internal storage. Use this comparison until there is a better way to do this
|
||||||
if ("/mnt/sdcard".equalsIgnoreCase(path))
|
if ("/mnt/sdcard".equalsIgnoreCase(path))
|
||||||
mLabels.add("Built-in Storage");
|
mLabels.add("Built-in Storage");
|
||||||
else
|
else
|
||||||
@@ -310,84 +317,97 @@ public class StorageOptions
|
|||||||
*
|
*
|
||||||
* @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
|
* @return <code>true</code> if the device is rooted, <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isRooted() {
|
public static boolean isRooted()
|
||||||
|
|
||||||
// get from build info
|
|
||||||
String buildTags = android.os.Build.TAGS;
|
|
||||||
if (buildTags != null && buildTags.contains("test-keys")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if /system/app/Superuser.apk is present
|
|
||||||
try {
|
|
||||||
File file = new File("/system/app/Superuser.apk");
|
|
||||||
if (file.exists()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File file = new File("/system/app/Superuser/Superuser.apk");
|
|
||||||
if (file.exists()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
//SuperSU
|
|
||||||
try {
|
|
||||||
File file = new File("/system/app/SuperSU.apk");
|
|
||||||
if (file.exists()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File file = new File("/system/app/SuperSU/SuperSU.apk");
|
|
||||||
if (file.exists()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e1) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
// try executing commands
|
|
||||||
return canExecuteCommand("/system/xbin/which su")
|
|
||||||
|| canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
|
|
||||||
}
|
|
||||||
|
|
||||||
// executes a command on the system
|
|
||||||
private static boolean canExecuteCommand(String command) {
|
|
||||||
boolean executedSuccesfully;
|
|
||||||
try {
|
|
||||||
Runtime.getRuntime().exec(command);
|
|
||||||
executedSuccesfully = true;
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
executedSuccesfully = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return executedSuccesfully;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean findForcemount(){
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
File file = new File(System.getenv("EXTERNAL_STORAGE")+"/forcemount");
|
// get from build info
|
||||||
if (file.exists())
|
String buildTags = android.os.Build.TAGS;
|
||||||
|
if (buildTags != null && buildTags.contains("test-keys"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception e1)
|
// check if /system/app/Superuser.apk is present
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File("/system/app/Superuser.apk");
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e1)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File("/system/app/Superuser/Superuser.apk");
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e1)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
//SuperSU
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File("/system/app/SuperSU.apk");
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e1)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File("/system/app/SuperSU/SuperSU.apk");
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e1)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
// try executing commands
|
||||||
|
return canExecuteCommand("/system/xbin/which su")
|
||||||
|
|| canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
|
||||||
|
}
|
||||||
|
|
||||||
|
// executes a command on the system
|
||||||
|
private static boolean canExecuteCommand(String command)
|
||||||
{
|
{
|
||||||
|
boolean executedSuccesfully;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Runtime.getRuntime().exec(command);
|
||||||
|
executedSuccesfully = true;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
executedSuccesfully = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return executedSuccesfully;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean findForcemount()
|
||||||
|
{
|
||||||
|
Log.d(TAG, "findForcemount()");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File(System.getenv("EXTERNAL_STORAGE") + "/forcemount");
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.w(TAG, e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import java.net.URLConnection;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import javax.microedition.khronos.egl.EGL10;
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.egl.EGLContext;
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
@@ -68,12 +66,11 @@ import android.widget.FrameLayout.LayoutParams;
|
|||||||
*/
|
*/
|
||||||
public class SDLActivity extends Activity implements OnKeyListener
|
public class SDLActivity extends Activity implements OnKeyListener
|
||||||
{
|
{
|
||||||
|
private static final String TAG = SDLActivity.class.getCanonicalName();
|
||||||
|
|
||||||
//import deck globals
|
//import deck globals
|
||||||
public ArrayList<String> myresult = new ArrayList<String>();
|
public ArrayList<String> myresult = new ArrayList<String>();
|
||||||
public String myclickedItem = "";
|
public String myclickedItem = "";
|
||||||
|
|
||||||
// TAG used for debugging in DDMS
|
|
||||||
public static String TAG = Activity.class.getCanonicalName();
|
|
||||||
|
|
||||||
// Main components
|
// Main components
|
||||||
private static SDLActivity mSingleton;
|
private static SDLActivity mSingleton;
|
||||||
@@ -352,7 +349,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
updateStorageLocations();
|
updateStorageLocations();
|
||||||
} catch (Exception ioex)
|
} catch (Exception ioex)
|
||||||
{
|
{
|
||||||
Log.e("SDL", "An error occurred in setting up the storage locations.");
|
Log.e(TAG, "An error occurred in setting up the storage locations.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,14 +494,12 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
// Log.v("SDL", "onCreate()");
|
//Log.d(TAG, "onCreate()");
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// So we can call stuff from static callbacks
|
// So we can call stuff from static callbacks
|
||||||
mSingleton = this;
|
mSingleton = this;
|
||||||
mContext = this.getApplicationContext();
|
mContext = this.getApplicationContext();
|
||||||
// get the current version of the app to set the core filename
|
|
||||||
String versionCodeString = getApplicationCode();
|
|
||||||
RES_FILENAME = getResourceName();
|
RES_FILENAME = getResourceName();
|
||||||
|
|
||||||
StorageOptions.determineStorageOptions();
|
StorageOptions.determineStorageOptions();
|
||||||
@@ -532,7 +527,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause()
|
protected void onPause()
|
||||||
{
|
{
|
||||||
// Log.v("SDL", "onPause()");
|
// Log.d(TAG, "onPause()");
|
||||||
super.onPause();
|
super.onPause();
|
||||||
SDLActivity.nativePause();
|
SDLActivity.nativePause();
|
||||||
}
|
}
|
||||||
@@ -540,7 +535,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
@Override
|
@Override
|
||||||
protected void onResume()
|
protected void onResume()
|
||||||
{
|
{
|
||||||
// Log.v("SDL", "onResume()");
|
// Log.d(TAG, "onResume()");
|
||||||
super.onResume();
|
super.onResume();
|
||||||
SDLActivity.nativeResume();
|
SDLActivity.nativeResume();
|
||||||
}
|
}
|
||||||
@@ -548,8 +543,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy()
|
public void onDestroy()
|
||||||
{
|
{
|
||||||
// Log.v("SDL", "onDestroy()");
|
// Log.d(TAG, "onDestroy()");
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
mSurface.onDestroy();
|
mSurface.onDestroy();
|
||||||
}
|
}
|
||||||
@@ -660,7 +654,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
||||||
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
||||||
|
|
||||||
// Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
// Log.d(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||||
|
|
||||||
// Let the user pick a larger buffer if they really want -- but ye
|
// Let the user pick a larger buffer if they really want -- but ye
|
||||||
// gods they probably shouldn't, the minimums are horrifyingly high
|
// gods they probably shouldn't, the minimums are horrifyingly high
|
||||||
@@ -671,7 +665,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
|
|
||||||
audioStartThread();
|
audioStartThread();
|
||||||
|
|
||||||
// Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) +
|
// Log.d(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) +
|
||||||
// "kHz, " + desiredFrames + " frames buffer");
|
// "kHz, " + desiredFrames + " frames buffer");
|
||||||
|
|
||||||
if (is16Bit)
|
if (is16Bit)
|
||||||
@@ -719,7 +713,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
Log.w("SDL", "SDL audio: error return from write(short)");
|
Log.w(TAG, "SDL audio: error return from write(short)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,7 +738,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
Log.w("SDL", "SDL audio: error return from write(short)");
|
Log.w(TAG, "SDL audio: error return from write(short)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -759,11 +753,11 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
mAudioThread.join();
|
mAudioThread.join();
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.v("SDL", "Problem stopping audio thread: " + e);
|
Log.e(TAG, "Problem stopping audio thread: " + e);
|
||||||
}
|
}
|
||||||
mAudioThread = null;
|
mAudioThread = null;
|
||||||
|
|
||||||
// Log.v("SDL", "Finished waiting for audio thread");
|
// Log.d(TAG, "Finished waiting for audio thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAudioTrack != null)
|
if (mAudioTrack != null)
|
||||||
@@ -775,7 +769,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
|
|
||||||
class DownloadFileAsync extends AsyncTask<String, Integer, Long>
|
class DownloadFileAsync extends AsyncTask<String, Integer, Long>
|
||||||
{
|
{
|
||||||
final String TAG1 = DownloadFileAsync.class.getCanonicalName();
|
private final String TAG = DownloadFileAsync.class.getCanonicalName();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute()
|
protected void onPreExecute()
|
||||||
@@ -794,7 +788,6 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare the sdcard folders in order to download the resource file
|
// Prepare the sdcard folders in order to download the resource file
|
||||||
//
|
//
|
||||||
@@ -815,7 +808,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
conexion.connect();
|
conexion.connect();
|
||||||
|
|
||||||
int lengthOfFile = conexion.getContentLength();
|
int lengthOfFile = conexion.getContentLength();
|
||||||
// Log.d("Wagic - " + TAG1, " Length of file: " + lengthOfFile);
|
// Log.d(TAG, " Length of file: " + lengthOfFile);
|
||||||
|
|
||||||
input = new BufferedInputStream(url.openStream());
|
input = new BufferedInputStream(url.openStream());
|
||||||
// create a File object for the output file
|
// create a File object for the output file
|
||||||
@@ -838,8 +831,8 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
{
|
{
|
||||||
String errorMessage = "An error happened while downloading the resources. It could be that our server is temporarily down, that your device is not connected to a network, or that we cannot write to " + mSingleton.getSystemStorageLocation() + ". Please check your phone settings and try again. For more help please go to http://wagic.net";
|
String errorMessage = "An error happened while downloading the resources. It could be that our server is temporarily down, that your device is not connected to a network, or that we cannot write to " + mSingleton.getSystemStorageLocation() + ". Please check your phone settings and try again. For more help please go to http://wagic.net";
|
||||||
mSingleton.downloadError(errorMessage);
|
mSingleton.downloadError(errorMessage);
|
||||||
Log.e(TAG1, errorMessage);
|
Log.e(TAG, errorMessage);
|
||||||
Log.e(TAG1, e.getMessage());
|
Log.e(TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Long.valueOf(totalBytes);
|
return Long.valueOf(totalBytes);
|
||||||
@@ -849,7 +842,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
{
|
{
|
||||||
if (progress[0] != mProgressDialog.getProgress())
|
if (progress[0] != mProgressDialog.getProgress())
|
||||||
{
|
{
|
||||||
// Log.d("Wagic - " + TAG1, "current progress : " + progress[0]);
|
// Log.d(TAG, "current progress : " + progress[0]);
|
||||||
mProgressDialog.setProgress(progress[0]);
|
mProgressDialog.setProgress(progress[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -922,6 +915,7 @@ public class SDLActivity extends Activity implements OnKeyListener
|
|||||||
*/
|
*/
|
||||||
class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnKeyListener, View.OnTouchListener, SensorEventListener
|
class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnKeyListener, View.OnTouchListener, SensorEventListener
|
||||||
{
|
{
|
||||||
|
private static final String TAG = SDLSurface.class.getCanonicalName();
|
||||||
|
|
||||||
// This is what SDL runs in. It invokes SDL_main(), eventually
|
// This is what SDL runs in. It invokes SDL_main(), eventually
|
||||||
private Thread mSDLThread;
|
private Thread mSDLThread;
|
||||||
@@ -961,7 +955,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
|
|
||||||
SDLActivity.nativeQuit();
|
SDLActivity.nativeQuit();
|
||||||
|
|
||||||
Log.v("SDL", "SDL thread terminated");
|
Log.d(TAG, "SDL thread terminated");
|
||||||
|
|
||||||
// On exit, tear everything down for a fresh restart next time.
|
// On exit, tear everything down for a fresh restart next time.
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
@@ -988,7 +982,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
// Called when we have a valid drawing surface
|
// Called when we have a valid drawing surface
|
||||||
public void surfaceCreated(SurfaceHolder holder)
|
public void surfaceCreated(SurfaceHolder holder)
|
||||||
{
|
{
|
||||||
Log.v("SDL", "surfaceCreated()");
|
//Log.d(TAG, "surfaceCreated()");
|
||||||
|
|
||||||
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||||
}
|
}
|
||||||
@@ -1008,18 +1002,18 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
mSDLThread.join();
|
mSDLThread.join();
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.v("SDL", "Problem stopping thread: " + e);
|
Log.e(TAG, "Problem stopping thread: " + e);
|
||||||
}
|
}
|
||||||
mSDLThread = null;
|
mSDLThread = null;
|
||||||
|
|
||||||
// Log.v("SDL", "Finished waiting for SDL thread");
|
// Log.d(TAG, "Finished waiting for SDL thread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when we lose the surface
|
// Called when we lose the surface
|
||||||
public void surfaceDestroyed(SurfaceHolder holder)
|
public void surfaceDestroyed(SurfaceHolder holder)
|
||||||
{
|
{
|
||||||
Log.v("SDL", "surfaceDestroyed()");
|
Log.d(TAG, "surfaceDestroyed()");
|
||||||
synchronized (mSemSurface)
|
synchronized (mSemSurface)
|
||||||
{
|
{
|
||||||
mSurfaceValid = false;
|
mSurfaceValid = false;
|
||||||
@@ -1031,51 +1025,51 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
// Called when the surface is resized
|
// Called when the surface is resized
|
||||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|
||||||
{
|
{
|
||||||
Log.d("SDL", "surfaceChanged()");
|
Log.d(TAG, "surfaceChanged()");
|
||||||
|
|
||||||
int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
|
int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case PixelFormat.A_8:
|
case PixelFormat.A_8:
|
||||||
Log.d("SDL", "pixel format A_8");
|
Log.d("TAG", "pixel format A_8");
|
||||||
break;
|
break;
|
||||||
case PixelFormat.LA_88:
|
case PixelFormat.LA_88:
|
||||||
Log.d("SDL", "pixel format LA_88");
|
Log.d("TAG", "pixel format LA_88");
|
||||||
break;
|
break;
|
||||||
case PixelFormat.L_8:
|
case PixelFormat.L_8:
|
||||||
Log.d("SDL", "pixel format L_8");
|
Log.d("TAG", "pixel format L_8");
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGBA_4444:
|
case PixelFormat.RGBA_4444:
|
||||||
Log.d("SDL", "pixel format RGBA_4444");
|
Log.d("TAG", "pixel format RGBA_4444");
|
||||||
sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
|
sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGBA_5551:
|
case PixelFormat.RGBA_5551:
|
||||||
Log.d("SDL", "pixel format RGBA_5551");
|
Log.d(TAG, "pixel format RGBA_5551");
|
||||||
sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
|
sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGBA_8888:
|
case PixelFormat.RGBA_8888:
|
||||||
Log.d("SDL", "pixel format RGBA_8888");
|
Log.d(TAG, "pixel format RGBA_8888");
|
||||||
sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
|
sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGBX_8888:
|
case PixelFormat.RGBX_8888:
|
||||||
Log.d("SDL", "pixel format RGBX_8888");
|
Log.d(TAG, "pixel format RGBX_8888");
|
||||||
sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
|
sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGB_332:
|
case PixelFormat.RGB_332:
|
||||||
Log.d("SDL", "pixel format RGB_332");
|
Log.d(TAG, "pixel format RGB_332");
|
||||||
sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
|
sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGB_565:
|
case PixelFormat.RGB_565:
|
||||||
Log.d("SDL", "pixel format RGB_565");
|
Log.d(TAG, "pixel format RGB_565");
|
||||||
sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
|
sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
|
||||||
break;
|
break;
|
||||||
case PixelFormat.RGB_888:
|
case PixelFormat.RGB_888:
|
||||||
Log.d("SDL", "pixel format RGB_888");
|
Log.d(TAG, "pixel format RGB_888");
|
||||||
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
|
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
|
||||||
sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
|
sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.d("SDL", "pixel format unknown " + format);
|
Log.d(TAG, "pixel format unknown " + format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SDLActivity.onNativeResize(width, height, sdlFormat);
|
SDLActivity.onNativeResize(width, height, sdlFormat);
|
||||||
@@ -1092,11 +1086,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
// EGL functions
|
// EGL functions
|
||||||
public boolean initEGL(int majorVersion, int minorVersion)
|
public boolean initEGL(int majorVersion, int minorVersion)
|
||||||
{
|
{
|
||||||
Log.d("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
|
Log.d(TAG, "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
EGL10 egl = (EGL10) EGLContext.getEGL();
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||||
|
|
||||||
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||||
@@ -1122,7 +1115,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
int[] num_config = new int[1];
|
int[] num_config = new int[1];
|
||||||
if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0)
|
if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0)
|
||||||
{
|
{
|
||||||
Log.e("SDL", "No EGL config available");
|
Log.e(TAG, "No EGL config available");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mEGLConfig = configs[0];
|
mEGLConfig = configs[0];
|
||||||
@@ -1130,7 +1123,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
EGLContext ctx = egl.eglCreateContext(dpy, mEGLConfig, EGL10.EGL_NO_CONTEXT, null);
|
EGLContext ctx = egl.eglCreateContext(dpy, mEGLConfig, EGL10.EGL_NO_CONTEXT, null);
|
||||||
if (ctx == EGL10.EGL_NO_CONTEXT)
|
if (ctx == EGL10.EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
Log.e("SDL", "Couldn't create context");
|
Log.e(TAG, "Couldn't create context");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1144,10 +1137,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
|
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e("SDL", e + "");
|
Log.e(TAG, e + "");
|
||||||
for (StackTraceElement s : e.getStackTrace())
|
for (StackTraceElement s : e.getStackTrace())
|
||||||
{
|
{
|
||||||
Log.e("SDL", s.toString());
|
Log.e(TAG, s.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1162,7 +1155,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
EGL10 egl = (EGL10) EGLContext.getEGL();
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||||
if (mEGLSurface != null)
|
if (mEGLSurface != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unbind and destroy the old EGL surface, if there is one.
|
* Unbind and destroy the old EGL surface, if there is one.
|
||||||
*/
|
*/
|
||||||
@@ -1176,7 +1168,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
mEGLSurface = egl.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, holder, null);
|
mEGLSurface = egl.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, holder, null);
|
||||||
if (mEGLSurface == EGL10.EGL_NO_SURFACE)
|
if (mEGLSurface == EGL10.EGL_NO_SURFACE)
|
||||||
{
|
{
|
||||||
Log.e("SDL", "Couldn't create surface");
|
Log.e(TAG, "Couldn't create surface");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,7 +1177,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
*/
|
*/
|
||||||
if (!egl.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext))
|
if (!egl.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext))
|
||||||
{
|
{
|
||||||
Log.e("SDL", "Couldn't make context current");
|
Log.e(TAG, "Couldn't make context current");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,7 +1189,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
// EGL buffer flip
|
// EGL buffer flip
|
||||||
public void flipEGL()
|
public void flipEGL()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!mSurfaceValid)
|
if (!mSurfaceValid)
|
||||||
{
|
{
|
||||||
createSurface(this.getHolder());
|
createSurface(this.getHolder());
|
||||||
@@ -1207,7 +1198,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
{
|
{
|
||||||
EGL10 egl = (EGL10) EGLContext.getEGL();
|
EGL10 egl = (EGL10) EGLContext.getEGL();
|
||||||
|
|
||||||
egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
|
egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
|
||||||
|
|
||||||
// drawing here
|
// drawing here
|
||||||
|
|
||||||
@@ -1217,13 +1208,12 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
|
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e("SDL", "flipEGL(): " + e);
|
Log.e(TAG, "flipEGL(): " + e);
|
||||||
for (StackTraceElement s : e.getStackTrace())
|
for (StackTraceElement s : e.getStackTrace())
|
||||||
{
|
{
|
||||||
Log.e("SDL", s.toString());
|
Log.e(TAG, s.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key events
|
// Key events
|
||||||
@@ -1234,14 +1224,15 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
|
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN)
|
if (event.getAction() == KeyEvent.ACTION_DOWN)
|
||||||
{
|
{
|
||||||
// Log.d("SDL", "key down: " + keyCode);
|
// Log.d(TAG, "key down: " + keyCode);
|
||||||
SDLActivity.onNativeKeyDown(keyCode);
|
SDLActivity.onNativeKeyDown(keyCode);
|
||||||
return true;
|
return true;
|
||||||
} else if (event.getAction() == KeyEvent.ACTION_UP)
|
} else if (event.getAction() == KeyEvent.ACTION_UP)
|
||||||
{
|
{
|
||||||
// Log.d("SDL", "key up: " + keyCode);
|
// Log.d(TAG, "key up: " + keyCode);
|
||||||
SDLActivity.onNativeKeyUp(keyCode);
|
SDLActivity.onNativeKeyUp(keyCode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1252,7 +1243,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
// Touch events
|
// Touch events
|
||||||
public boolean onTouch(View v, MotionEvent event)
|
public boolean onTouch(View v, MotionEvent event)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int index = 0; index < event.getPointerCount(); ++index)
|
for (int index = 0; index < event.getPointerCount(); ++index)
|
||||||
{
|
{
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
@@ -1319,3 +1309,4 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnK
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,233 @@
|
|||||||
|
#MTGs common sources
|
||||||
|
set(MTG_generic_src
|
||||||
|
src/AbilityParser.cpp
|
||||||
|
src/ActionElement.cpp
|
||||||
|
src/ActionLayer.cpp
|
||||||
|
src/ActionStack.cpp
|
||||||
|
src/AIHints.cpp
|
||||||
|
src/AIMomirPlayer.cpp
|
||||||
|
src/AIPlayer.cpp
|
||||||
|
src/AIPlayerBaka.cpp
|
||||||
|
src/AIStats.cpp
|
||||||
|
src/AllAbilities.cpp
|
||||||
|
src/CardDescriptor.cpp
|
||||||
|
src/CardDisplay.cpp
|
||||||
|
src/CardGui.cpp
|
||||||
|
src/CardPrimitive.cpp
|
||||||
|
src/CardSelector.cpp
|
||||||
|
src/CardSelectorSingleton.cpp
|
||||||
|
src/CarouselDeckView.cpp
|
||||||
|
src/Closest.cpp
|
||||||
|
src/Counters.cpp
|
||||||
|
src/Credits.cpp
|
||||||
|
src/Damage.cpp
|
||||||
|
src/DamagerDamaged.cpp
|
||||||
|
src/DeckDataWrapper.cpp
|
||||||
|
src/DeckEditorMenu.cpp
|
||||||
|
src/DeckManager.cpp
|
||||||
|
src/DeckMenu.cpp
|
||||||
|
src/DeckMenuItem.cpp
|
||||||
|
src/DeckMetaData.cpp
|
||||||
|
src/DeckStats.cpp
|
||||||
|
src/DeckView.cpp
|
||||||
|
src/DuelLayers.cpp
|
||||||
|
src/ExtraCost.cpp
|
||||||
|
src/GameApp.cpp
|
||||||
|
src/GameLauncher.cpp
|
||||||
|
src/GameObserver.cpp
|
||||||
|
src/GameOptions.cpp
|
||||||
|
src/GameStateAwards.cpp
|
||||||
|
src/GameState.cpp
|
||||||
|
src/GameStateDeckViewer.cpp
|
||||||
|
src/GameStateDuel.cpp
|
||||||
|
src/GameStateMenu.cpp
|
||||||
|
src/GameStateOptions.cpp
|
||||||
|
src/GameStateShop.cpp
|
||||||
|
src/GameStateStory.cpp
|
||||||
|
src/GameStateTransitions.cpp
|
||||||
|
src/GridDeckView.cpp
|
||||||
|
src/GuiAvatars.cpp
|
||||||
|
src/GuiBackground.cpp
|
||||||
|
src/GuiCardsController.cpp
|
||||||
|
src/GuiCombat.cpp
|
||||||
|
src/GuiFrame.cpp
|
||||||
|
src/GuiHand.cpp
|
||||||
|
src/GuiLayers.cpp
|
||||||
|
src/GuiMana.cpp
|
||||||
|
src/GuiPhaseBar.cpp
|
||||||
|
src/GuiPlay.cpp
|
||||||
|
src/GuiStatic.cpp
|
||||||
|
src/IconButton.cpp
|
||||||
|
src/InteractiveButton.cpp
|
||||||
|
src/ManaCost.cpp
|
||||||
|
src/ManaCostHybrid.cpp
|
||||||
|
src/MenuItem.cpp
|
||||||
|
src/ModRules.cpp
|
||||||
|
src/MTGAbility.cpp
|
||||||
|
src/MTGCard.cpp
|
||||||
|
src/MTGCardInstance.cpp
|
||||||
|
src/MTGDeck.cpp
|
||||||
|
src/MTGDefinitions.cpp
|
||||||
|
src/MTGGamePhase.cpp
|
||||||
|
src/MTGGameZones.cpp
|
||||||
|
src/MTGPack.cpp
|
||||||
|
src/MTGRules.cpp
|
||||||
|
src/ObjectAnalytics.cpp
|
||||||
|
src/OptionItem.cpp
|
||||||
|
src/PhaseRing.cpp
|
||||||
|
src/Player.cpp
|
||||||
|
src/PlayerData.cpp
|
||||||
|
src/PlayGuiObject.cpp
|
||||||
|
src/PlayGuiObjectController.cpp
|
||||||
|
src/PlayRestrictions.cpp
|
||||||
|
src/Pos.cpp
|
||||||
|
src/PriceList.cpp
|
||||||
|
src/ReplacementEffects.cpp
|
||||||
|
src/Rules.cpp
|
||||||
|
src/SimpleMenu.cpp
|
||||||
|
src/SimpleMenuItem.cpp
|
||||||
|
src/SimpleButton.cpp
|
||||||
|
src/SimplePad.cpp
|
||||||
|
src/SimplePopup.cpp
|
||||||
|
src/StoryFlow.cpp
|
||||||
|
src/Subtypes.cpp
|
||||||
|
src/StyleManager.cpp
|
||||||
|
src/TargetChooser.cpp
|
||||||
|
src/TargetsList.cpp
|
||||||
|
src/Tasks.cpp
|
||||||
|
src/TextScroller.cpp
|
||||||
|
src/ThisDescriptor.cpp
|
||||||
|
src/Token.cpp
|
||||||
|
src/Translate.cpp
|
||||||
|
src/TranslateKeys.cpp
|
||||||
|
src/Trash.cpp
|
||||||
|
src/utils.cpp
|
||||||
|
src/WCachedResource.cpp
|
||||||
|
src/WDataSrc.cpp
|
||||||
|
src/WEvent.cpp
|
||||||
|
src/WFilter.cpp
|
||||||
|
src/WFont.cpp
|
||||||
|
src/WGui.cpp
|
||||||
|
src/WResourceManager.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MTG_network_src src/NetworkPlayer.cpp)
|
||||||
|
|
||||||
|
#the sources we need if we compile a graphical qt version
|
||||||
|
#TODO: add declarative version since this only works with QWidget right now
|
||||||
|
set(MTG_qt_graphic_src
|
||||||
|
src/qt/filedownloader.cpp
|
||||||
|
src/qt/corewrapper.cpp
|
||||||
|
include/qt/corewrapper.h #so automoc finds it
|
||||||
|
include/qt/filedownloader.h
|
||||||
|
src/Qtmain.cpp)
|
||||||
|
|
||||||
|
#the sources we need to compile the testsuit
|
||||||
|
set(MTG_qt_console_src
|
||||||
|
src/Qtconsole.cpp
|
||||||
|
src/TestSuiteAI.cpp)
|
||||||
|
|
||||||
|
set(MTG_sdl_src
|
||||||
|
src/SDLmain.cpp)
|
||||||
|
|
||||||
|
set(MTG_android_sdl_src
|
||||||
|
src/SDLmain.cpp)
|
||||||
|
|
||||||
|
set(MTG_iOS_src
|
||||||
|
iOS/UI/WagicDownloadProgressViewController.m
|
||||||
|
iOS/asi-http-request/ASIAuthenticationDialog.m
|
||||||
|
iOS/asi-http-request/ASIDataCompressor.m
|
||||||
|
iOS/asi-http-request/ASIDataDecompressor.m
|
||||||
|
iOS/asi-http-request/ASIDownloadCache.m
|
||||||
|
iOS/asi-http-request/ASIFormDataRequest.m
|
||||||
|
iOS/asi-http-request/ASIHTTPRequest.m
|
||||||
|
iOS/asi-http-request/ASIInputStream.m
|
||||||
|
iOS/asi-http-request/ASINetworkQueue.m
|
||||||
|
iOS/SoundManager/SoundManager.m
|
||||||
|
iOS/SoundManager/MyOpenALSupport.c
|
||||||
|
iOS/Reachability/Reachability/Reachability.m
|
||||||
|
iOS/ZipArchive/ZipArchive.mm)
|
||||||
|
|
||||||
|
|
||||||
|
set(MTG_iOS_INCLUDE_DIRS iOS/UI iOS/Reachability/Reachability iOS/asi-http-request iOS/ZipArchive iOS/SoundManager)
|
||||||
|
|
||||||
|
set(MTG_INCLUDE_DIRS include include/qt)
|
||||||
|
set(JGE_INCLUDE_DIRS ../../JGE/include ../../JGE/include/hge)
|
||||||
|
set(JGE_LIBRARY jge)
|
||||||
|
set(EXTRA_INCLUDE_DIR extra)
|
||||||
|
|
||||||
|
#turn moc on
|
||||||
|
if(backend_qt_console OR backend_qt_widget)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
set(CMAKE_AUTOMOC TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(backend_qt_console)
|
||||||
|
if(UNIX AND NOT ANDROID)
|
||||||
|
include_directories(${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${ZIPFS_INCLUDE_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default)
|
||||||
|
add_executable(wagic ${MTG_generic_src} ${MTG_qt_console_src} ${MTG_network_src})
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS} ${TINYXML_LIBRARIES}
|
||||||
|
${HGE_LIBRARY} ${ZLIB_LIBRARIES})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "qt-console builds are only supported on unix platforms")
|
||||||
|
endif()
|
||||||
|
elseif(backend_qt_widget)
|
||||||
|
if(UNIX AND NOT ANDROID)
|
||||||
|
include_directories(${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${ZIPFS_INCLUDE_DIR} ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} ${QT_MKSPECS_DIR}/default)
|
||||||
|
add_executable(wagic ${MTG_generic_src} ${MTG_qt_graphic_src} ${MTG_network_src})
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${Qt5Core_INCLUDE_DIRS} ${Qt5Multimedia_INCLUDE_DIRS} ${OPENGL_LIBRARIES} ${TINYXML_LIBRARIES}
|
||||||
|
${HGE_LIBRARY} ${ZLIB_LIBRARIES})# ${X11_LIBRARIES})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "qt-widget builds are only supported on unix platforms")
|
||||||
|
endif()
|
||||||
|
elseif(backend_sdl)
|
||||||
|
if((UNIX OR EMSCRIPTEN) AND NOT ANDROID)
|
||||||
|
include_directories(${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR} ${UNZIP_INCLUDE_DIR} ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||||
|
add_executable(wagic ${MTG_generic_src} ${MTG_sdl_src} ${MTG_network_src} src/TestSuiteAI.cpp src/AIPlayerBakaB.cpp)
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${SDL2_LIBRARY} ${OPENGL_LIBRARIES} ${TINYXML_LIBRARIES} ${HGE_LIBRARY} ${ZLIB_LIBRARIES})
|
||||||
|
elseif(ANDROID)
|
||||||
|
include_directories(${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR} ${BOOST_INCLUDE_DIRS} ${UNZIP_INCLUDE_DIR} ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR})
|
||||||
|
#we should try to get rid of this hack
|
||||||
|
add_library(wagic SHARED ${MTG_generic_src} ${MTG_network_src} ${MTG_android_sdl_src} src/TestSuiteAI.cpp)
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${SDL2_LIBRARY} ${OPENGL_LIBRARIES} ${TINYXML_LIBRARIES} ${HGE_LIBRARY} ${ZLIB_LIBRARIES})
|
||||||
|
elseif(WIN32)
|
||||||
|
include_directories(${EXTRA_INCLUDE_DIR} ${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR}
|
||||||
|
${Boost_INCLUDE_DIRS} ${UNZIP_INCLUDE_DIR} ${HGE_INCLUDE_DIR} ${TINYXML_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||||
|
add_executable(wagic ${MTG_generic_src} ${MTG_sdl_src} src/TestSuiteAI.cpp src/AIPlayerBakaB.cpp)
|
||||||
|
link_directories(${Boost_LIBRARY_DIR} ${SDL2_LIBRARY_DIR})
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${SDL2_LIBRARY} ${OPENGL_LIBRARIES} ${TINYXML_LIBRARIES} ${BOOST_date_time} ${HGE_LIBRARY} ${ZLIB_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
elseif(backend_psp)
|
||||||
|
if(PSP)
|
||||||
|
#${PSPSDK_PATH}/include
|
||||||
|
include_directories(${MTG_INCLUDE_DIRS} ${JGE_INCLUDE_DIRS} ${TINYXML_INCLUDE_DIR} ${ZIPFS_INCLUDE_DIR}
|
||||||
|
${UNZIP_INCLUDE_DIR} ${BOOST_INCLUDE_DIRS} ${GIF_INCLUDE_DIR} ${HGETOOLS_INCLUDE_DIRS})
|
||||||
|
add_executable(wagic ${MTG_generic_src} ${MTG_network_src})
|
||||||
|
target_link_libraries(wagic ${JGE_LIBRARY} ${PSPSDK_LIB} ${HGETOOLS_LIBRARY} ${FREETYPE_LIB} ${JPEG_LIBRARY}
|
||||||
|
${GIF_LIBRARIES} ${PNG_LIBRARIES} z m ${MIKMOD_LIBRARY} ${TINYXML_LIBRARIES}
|
||||||
|
stdc++ ${PSPSDK_REQUIRED_LIB})
|
||||||
|
|
||||||
|
set(PRXSPECS_FILE "${PSPSDK_PATH}/lib/prxspecs")
|
||||||
|
set(LINKFILE_FILE "${PSPSDK_PATH}/lib/linkfile.prx")
|
||||||
|
|
||||||
|
get_property(wagic_elf_location TARGET wagic PROPERTY LOCATION)
|
||||||
|
get_filename_component(wagic_elf_directory ${wagic_elf_location} PATH)
|
||||||
|
|
||||||
|
set_target_properties(wagic PROPERTIES LINK_FLAGS "-specs=${PRXSPECS_FILE} -Wl,-q,-T${LINKFILE_FILE}")
|
||||||
|
|
||||||
|
add_custom_command(TARGET wagic POST_BUILD
|
||||||
|
COMMAND ${PSPSDK_MKSFO_COMMAND} ARGS "'Wagic, the Homebrew?!'" "${wagic_elf_directory}/PARAM.SFO"
|
||||||
|
COMMAND ${PSPSDK_FIXUP_IMPORTS_COMMAND} ARGS ${wagic_elf_location}
|
||||||
|
COMMAND ${PSPSDK_PRXGEN_COMMAND} ARGS ${wagic_elf_location} "${wagic_elf_directory}/wagic.prx"
|
||||||
|
COMMAND ${PSPSDK_PACK_PBP_COMMAND} ARGS ${wagic_elf_directory}/EBOOT.PBP ${wagic_elf_directory}/PARAM.SFO ${CMAKE_CURRENT_SOURCE_DIR}/icon.png NULL ${CMAKE_CURRENT_SOURCE_DIR}/pic0.png ${CMAKE_CURRENT_SOURCE_DIR}/pic1.png NULL "${wagic_elf_directory}/wagic.prx" NULL)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "use the cross-compile toolchain to build as the psp target")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(IOS)
|
||||||
|
set(MTG_generic_src ${MTG_generic_src} ${MTG_iOS_src} PARENT_SCOPE)
|
||||||
|
set(MTG_INCLUDE_DIRS ${MTG_INCLUDE_DIRS} ${MTG_iOS_INCLUDE_DIRS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
endif()
|
||||||
@@ -59,7 +59,6 @@ endif
|
|||||||
|
|
||||||
ifeq ($(TARGET_ARCHITECTURE),psp)
|
ifeq ($(TARGET_ARCHITECTURE),psp)
|
||||||
DEFAULT_RULE = 3xx
|
DEFAULT_RULE = 3xx
|
||||||
TARGET_ARCHITECTURE = psp
|
|
||||||
PSP_FW_VERSION=371
|
PSP_FW_VERSION=371
|
||||||
BUILD_PRX = 1
|
BUILD_PRX = 1
|
||||||
SIGN_PRX = 1
|
SIGN_PRX = 1
|
||||||
@@ -74,19 +73,36 @@ PSP_EBOOT_PIC1 = pic1.png
|
|||||||
INCDIR = ../../JGE/include ../../JGE/src/zipFS ../../JGE/include/psp ../../JGE/include/psp/freetype2 ../../JGE/src ../../projects/mtg/include ../../Boost
|
INCDIR = ../../JGE/include ../../JGE/src/zipFS ../../JGE/include/psp ../../JGE/include/psp/freetype2 ../../JGE/src ../../projects/mtg/include ../../Boost
|
||||||
LIBDIR = ../../JGE/lib/psp
|
LIBDIR = ../../JGE/lib/psp
|
||||||
CFLAGS = -O2 -G0 -DPSPFW3XX -DDEVHOOK -DUSE_PRECOMPILED_HEADERS=1 -DPSP -DTIXML_USE_STL
|
CFLAGS = -O2 -G0 -DPSPFW3XX -DDEVHOOK -DUSE_PRECOMPILED_HEADERS=1 -DPSP -DTIXML_USE_STL
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
ifeq ($(MAKECMDGOALS),x11)
|
||||||
|
|
||||||
|
OBJS += objs/TestSuiteAI.o
|
||||||
|
INCDIR = -I../../JGE/include -I../../JGE/src -I/usr/X11/include -I../../projects/mtg/include -I/usr/include/boost -I../../JGE/src/zipFS
|
||||||
|
LIBDIR = -L../../JGE/lib/linux -L../../JGE -L/usr/X11/lib
|
||||||
|
LIBS = -ljge -lfreetype -ljpeg -lgif -lpng -lz -lm -lstdc++ -lhgetools -lGL -lGLU -lX11 -lpthread $(FMOD)
|
||||||
|
CFLAGS = $(INCDIR) -DLINUX -DUSE_PRECOMPILED_HEADERS=1 -DTIXML_USE_STL -Wno-nonnull-compare
|
||||||
|
|
||||||
|
ASFLAGS = $(CXXFLAGS)
|
||||||
|
|
||||||
|
all: $(DEFAULT_RULE)
|
||||||
|
else
|
||||||
|
|
||||||
OBJS += objs/TestSuiteAI.o
|
OBJS += objs/TestSuiteAI.o
|
||||||
INCDIR = -I../../JGE/include -I../../JGE/src -I/usr/X11/include -I../../projects/mtg/include -I../../Boost -I../../JGE/src/zipFS
|
INCDIR = -I../../JGE/include -I../../JGE/src -I/usr/X11/include -I../../projects/mtg/include -I../../Boost -I../../JGE/src/zipFS
|
||||||
LIBDIR = -L../../JGE/lib/linux -L../../JGE -L/usr/X11/lib -L../../Boost/lib
|
LIBDIR = -L../../JGE/lib/linux -L../../JGE -L/usr/X11/lib -L../../Boost/lib
|
||||||
LIBS = -ljge -lfreetype -ljpeg -lgif -lpng -lz -lm -lstdc++ -lhgetools -lGL -lGLU -lX11 -lboost_thread $(FMOD)
|
LIBS = -ljge -lfreetype -ljpeg -lgif -lpng -lz -lm -lstdc++ -lhgetools -lGL -lGLU -lX11 -lboost_thread $(FMOD)
|
||||||
CFLAGS = $(INCDIR) -DLINUX -DUSE_PRECOMPILED_HEADERS=1
|
CFLAGS = $(INCDIR) -DLINUX -DUSE_PRECOMPILED_HEADERS=1 -Wno-nonnull-compare
|
||||||
|
|
||||||
ASFLAGS = $(CXXFLAGS)
|
ASFLAGS = $(CXXFLAGS)
|
||||||
|
|
||||||
all: $(DEFAULT_RULE)
|
all: $(DEFAULT_RULE)
|
||||||
|
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS := -Wall -W -Werror -Wno-unused $(CFLAGS)
|
CFLAGS := -Wall -W -Werror -Wno-unused -Wno-deprecated-declarations $(CFLAGS)
|
||||||
CXXFLAGS += $(CFLAGS)
|
CXXFLAGS += $(CFLAGS)
|
||||||
# -fno-exceptions
|
# -fno-exceptions
|
||||||
|
|
||||||
@@ -110,8 +126,6 @@ debug: all
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(TARGET): Makefile.$(TARGET_ARCHITECTURE) $(OBJS) ../../JGE/lib/linux/libjge.a
|
$(TARGET): Makefile.$(TARGET_ARCHITECTURE) $(OBJS) ../../JGE/lib/linux/libjge.a
|
||||||
$(CXX) -o $(TARGET) $(OBJS) $(LIBS) $(LIBDIR)
|
$(CXX) -o $(TARGET) $(OBJS) $(LIBS) $(LIBDIR)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#NAME:Etched Affinity
|
#NAME:Etched Affinity
|
||||||
#DESC:Modern URB Aggro
|
#DESC:Modern URB Aggro
|
||||||
#HINT:dontattackwith(creature[power<=0])
|
#HINT:dontattackwith(creature[power<=0])
|
||||||
#HINT:combo hold(Glimmervoid|myhand)^until(artifact|mybattlefield)^cast(Glimmervoid|myhand)^totalmananeeded({0})
|
|
||||||
#HINT:combo hold(Galvanic Blast|myhand)^cast(Galvanic Blast|myhand)^restriction{type(artifact|mybattlefield)~morethan~2,turn:3}^totalmananeeded({R})
|
#HINT:combo hold(Galvanic Blast|myhand)^cast(Galvanic Blast|myhand)^restriction{type(artifact|mybattlefield)~morethan~2,turn:3}^totalmananeeded({R})
|
||||||
|
|
||||||
#25 creatures
|
#25 creatures
|
||||||
|
|||||||
@@ -23,23 +23,23 @@
|
|||||||
369072
|
369072
|
||||||
|
|
||||||
#4 x Armada Wurm (RTR), {2}{g}{g}{w}{w}, Creature Wurm, 5/5, trample;
|
#4 x Armada Wurm (RTR), {2}{g}{g}{w}{w}, Creature Wurm, 5/5, trample;
|
||||||
999009
|
253587
|
||||||
999009
|
253587
|
||||||
999009
|
253587
|
||||||
999009
|
253587
|
||||||
|
|
||||||
#2 x Precinct Captain (RTR), {w}{w}, Creature Human Soldier, 2/2, first strike;
|
#2 x Precinct Captain (RTR), {w}{w}, Creature Human Soldier, 2/2, first strike;
|
||||||
999171
|
270792
|
||||||
999171
|
270792
|
||||||
|
|
||||||
#4 x Wayfaring Temple (RTR), {1}{g}{w}, Creature Elemental, 0/0,
|
#4 x Wayfaring Temple (RTR), {1}{g}{w}, Creature Elemental, 0/0,
|
||||||
999260
|
253539
|
||||||
999260
|
253539
|
||||||
999260
|
253539
|
||||||
999260
|
253539
|
||||||
|
|
||||||
#1 x Worldspine Wurm (RTR), {8}{g}{g}{g}, Creature Wurm, 15/15, trample;
|
#1 x Worldspine Wurm (RTR), {8}{g}{g}{g}, Creature Wurm, 15/15, trample;
|
||||||
999262
|
253575
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -57,14 +57,14 @@
|
|||||||
369060
|
369060
|
||||||
|
|
||||||
#2 x Chromatic Lantern (RTR), {3}, Artifact,
|
#2 x Chromatic Lantern (RTR), {3}, Artifact,
|
||||||
999039
|
290542
|
||||||
999039
|
290542
|
||||||
|
|
||||||
#4 x Growing Ranks (RTR), {2}{g/w}{g/w}, Enchantment,
|
#4 x Growing Ranks (RTR), {2}{g/w}{g/w}, Enchantment,
|
||||||
999106
|
270957
|
||||||
999106
|
270957
|
||||||
999106
|
270957
|
||||||
999106
|
270957
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -84,26 +84,26 @@
|
|||||||
369018
|
369018
|
||||||
|
|
||||||
#4 x Forest (RTR), Basic Land Forest,
|
#4 x Forest (RTR), Basic Land Forest,
|
||||||
999086
|
289326
|
||||||
999086
|
289326
|
||||||
999086
|
289326
|
||||||
999086
|
289326
|
||||||
|
|
||||||
#4 x Plains (RTR), Basic Land Plains,
|
#4 x Plains (RTR), Basic Land Plains,
|
||||||
999168
|
289310
|
||||||
999168
|
289310
|
||||||
999168
|
289310
|
||||||
999168
|
289310
|
||||||
|
|
||||||
#2 x Temple Garden (RTR), Land Forest Plains,
|
#2 x Temple Garden (RTR), Land Forest Plains,
|
||||||
999238
|
253681
|
||||||
999238
|
253681
|
||||||
|
|
||||||
#4 x Plains (RTR), Basic Land Plains,
|
#4 x Plains (RTR), Basic Land Plains,
|
||||||
999265
|
289309
|
||||||
999265
|
289309
|
||||||
999265
|
289309
|
||||||
999265
|
289309
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,127 @@
|
|||||||
|
[card]
|
||||||
|
name=Aura Graft
|
||||||
|
text=Gain control of target Aura that's attached to a permanent. Attach it to another permanent it can enchant.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Coat of Arms
|
||||||
|
text=Each creature gets +1/+1 for each other creature on the battlefield that shares at least one creature type with it. (For example, if two Goblin Warriors and a Goblin Shaman are on the battlefield, each gets +2/+2.)
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Cone of Flame
|
||||||
|
text=Cone of Flame deals 1 damage to target creature or player, 2 damage to another target creature or player, and 3 damage to a third target creature or player.
|
||||||
|
mana={3}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Furnace of Rath
|
||||||
|
text=If a source would deal damage to a creature or player, it deals double that damage to that creature or player instead.
|
||||||
|
mana={1}{R}{R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gaea's Herald
|
||||||
|
text=Creature spells can't be countered.
|
||||||
|
mana={1}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elf
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guerrilla Tactics
|
||||||
|
text=Guerrilla Tactics deals 2 damage to target creature or player. -- When a spell or ability an opponent controls causes you to discard Guerrilla Tactics, Guerrilla Tactics deals 4 damage to target creature or player.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Hail of Arrows
|
||||||
|
text=Hail of Arrows deals X damage divided as you choose among any number of target attacking creatures.
|
||||||
|
mana={X}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=High Ground
|
||||||
|
text=Each creature you control can block an additional creature.
|
||||||
|
mana={W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Royal Guard
|
||||||
|
text={T}: All combat damage that would be dealt to you by unblocked creatures this turn is dealt to Kjeldoran Royal Guard instead.
|
||||||
|
mana={3}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Knight of Dusk
|
||||||
|
text={B}{B}: Destroy target creature blocking Knight of Dusk.
|
||||||
|
mana={1}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Knight
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Bend
|
||||||
|
text=Change the text of target permanent by replacing all instances of one color word with another or one basic land type with another. (For example, you may change "nonblack creature" to "nongreen creature" or "forestwalk" to "islandwalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pariah
|
||||||
|
text=Enchant creature -- All damage that would be dealt to you is dealt to enchanted creature instead.
|
||||||
|
mana={2}{W}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pithing Needle
|
||||||
|
text=As Pithing Needle enters the battlefield, name a card. -- Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rootwater Matriarch
|
||||||
|
text={T}: Gain control of target creature for as long as that creature is enchanted.
|
||||||
|
mana={2}{U}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Merfolk
|
||||||
|
power=2
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Shunt
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={1}{R}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Story Circle
|
||||||
|
text=As Story Circle enters the battlefield, choose a color. -- {W}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Telepathy
|
||||||
|
text=Your opponents play with their hands revealed.
|
||||||
|
mana={U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Time Stop
|
||||||
|
text=End the turn. (Exile all spells and abilities on the stack, including this card. The player whose turn it is discards down to his or her maximum hand size. Damage wears off, and "this turn" and "until end of turn" effects end.)
|
||||||
|
mana={4}{U}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Warp World
|
||||||
|
text=Each player shuffles all permanents he or she owns into his or her library, then reveals that many cards from the top of his or her library. Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards, then puts all cards revealed this way that weren't put onto the battlefield on the bottom of his or her library.
|
||||||
|
mana={5}{R}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
[card]
|
||||||
|
name=Benalish Hero
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Blaze of Glory
|
||||||
|
text=Cast Blaze of Glory only during combat before blockers are declared. -- Target creature defending player controls can block any number of creatures this turn. It blocks each attacking creature this turn if able.
|
||||||
|
mana={W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Camouflage
|
||||||
|
text=Cast Camouflage only during your declare attackers step. -- This turn, instead of declaring blockers, each defending player chooses any number of creatures he or she controls and divides them into a number of piles equal to the number of attacking creatures for whom that player is the defending player. Creatures he or she controls that can block additional creatures may likewise be put into additional piles. Assign each pile to a different one of those attacking creatures at random. Each creature in a pile that can block the creature that pile is assigned to does so. (Piles can be empty.)
|
||||||
|
mana={G}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Channel
|
||||||
|
text=Until end of turn, any time you could activate a mana ability, you may pay 1 life. If you do, add {1} to your mana pool.
|
||||||
|
mana={G}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Chaos Orb
|
||||||
|
text={1}, {T}: If Chaos Orb is on the battlefield, flip Chaos Orb onto the battlefield from a height of at least one foot. If Chaos Orb turns over completely at least once during the flip, destroy all permanents it touches. Then destroy Chaos Orb.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Contract from Below
|
||||||
|
text=Remove Contract from Below from your deck before playing if you're not playing for ante. -- Discard your hand, add the top card of your library to the ante, then draw seven cards.
|
||||||
|
mana={B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Darkpact
|
||||||
|
text=Remove Darkpact from your deck before playing if you're not playing for ante. -- You own target card in the ante. Exchange that card with the top card of your library.
|
||||||
|
mana={B}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Demonic Attorney
|
||||||
|
text=Remove Demonic Attorney from your deck before playing if you're not playing for ante. -- Each player antes the top card of his or her library.
|
||||||
|
mana={1}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Drain Power
|
||||||
|
text=Target player activates a mana ability of each land he or she controls. Then put all mana from that player's mana pool into yours.
|
||||||
|
mana={U}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=False Orders
|
||||||
|
text=Cast False Orders only during the declare blockers step. -- Remove target creature defending player controls from combat. Creatures it was blocking that had become blocked by only that creature this combat become unblocked. You may have it block an attacking creature of your choice.
|
||||||
|
mana={R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Forcefield
|
||||||
|
text={1}: The next time an unblocked creature of your choice would deal combat damage to you this turn, prevent all but 1 of that damage.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gaea's Liege
|
||||||
|
text=As long as Gaea's Liege isn't attacking, its power and toughness are each equal to the number of Forests you control. As long as Gaea's Liege is attacking, its power and toughness are each equal to the number of Forests defending player controls. -- {T}: Target land becomes a Forest until Gaea's Liege leaves the battlefield.
|
||||||
|
mana={3}{G}{G}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar
|
||||||
|
power=*
|
||||||
|
toughness=*
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gloom
|
||||||
|
text=White spells cost {3} more to cast. -- Activated abilities of white enchantments cost {3} more to activate.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guardian Angel
|
||||||
|
text=Prevent the next X damage that would be dealt to target creature or player this turn. Until end of turn, you may pay {1} any time you could cast an instant. If you do, prevent the next 1 damage that would be dealt to that creature or player this turn.
|
||||||
|
mana={X}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Helm of Chatzuk
|
||||||
|
text={1}, {T}: Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Illusionary Mask
|
||||||
|
text={X}: You may choose a creature card in your hand whose mana cost could be paid by some amount of, or all of, the mana you spent on {X}. If you do, you may cast that card face down as a 2/2 creature spell without paying its mana cost. If the creature that spell becomes as it resolves has not been turned face up and would assign or deal damage, be dealt damage, or become tapped, instead it's turned face up and assigns or deals damage, is dealt damage, or becomes tapped. Activate this ability only any time you could cast a sorcery.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Island Sanctuary
|
||||||
|
text=If you would draw a card during your draw step, instead you may skip that draw. If you do, until your next turn, you can't be attacked except by creatures with flying and/or islandwalk.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jade Monolith
|
||||||
|
text={1}: The next time a source of your choice would deal damage to target creature this turn, that source deals that damage to you instead.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Library of Leng
|
||||||
|
text=You have no maximum hand size. -- If an effect causes you to discard a card, discard it, but you may put it on top of your library instead of into your graveyard.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Lich
|
||||||
|
text=As Lich enters the battlefield, you lose life equal to your life total. -- You don't lose the game for having 0 or less life. -- If you would gain life, draw that many cards instead. -- Whenever you're dealt damage, sacrifice that many nontoken permanents. If you can't, you lose the game. -- When Lich is put into a graveyard from the battlefield, you lose the game.
|
||||||
|
mana={B}{B}{B}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Magical Hack
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one basic land type with another. (For example, you may change "swampwalk" to "plainswalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mesa Pegasus
|
||||||
|
text=Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Pegasus
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nether Shadow
|
||||||
|
text=Haste -- At the beginning of your upkeep, if Nether Shadow is in your graveyard with three or more creature cards above it, you may put Nether Shadow onto the battlefield.
|
||||||
|
mana={B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nettling Imp
|
||||||
|
text={T}: Choose target non-Wall creature the active player has controlled continuously since the beginning of the turn. That creature attacks this turn if able. If it doesn't, destroy it at the beginning of the next end step. Activate this ability only during an opponent's turn, before attackers are declared.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Imp
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Personal Incarnation
|
||||||
|
text={0}: The next 1 damage that would be dealt to Personal Incarnation this turn is dealt to its owner instead. Any player may activate this ability, but only if he or she owns Personal Incarnation. -- When Personal Incarnation dies, its owner loses half his or her life, rounded up.
|
||||||
|
mana={3}{W}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar Incarnation
|
||||||
|
power=6
|
||||||
|
toughness=6
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Sink
|
||||||
|
text=Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool.
|
||||||
|
mana={X}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Surge
|
||||||
|
text=At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands he or she controlled at the beginning of this turn.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Raging River
|
||||||
|
text=Whenever one or more creatures you control attack, each defending player divides all creatures without flying he or she controls into a "left" pile and a "right" pile. Then, for each attacking creature you control, choose "left" or "right." That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Siren's Call
|
||||||
|
text=Cast Siren's Call only during an opponent's turn, before attackers are declared. -- Creatures the active player controls attack this turn if able. -- At the beginning of the next end step, destroy all non-Wall creatures that player controls that didn't attack this turn. Ignore this effect for each creature the player didn't control continuously since the beginning of the turn.
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sleight of Mind
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one color word with another. (For example, you may change "target black spell" to "target blue spell." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Smoke
|
||||||
|
text=Players can't untap more than one creature during their untap steps.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Stone Giant
|
||||||
|
text={T}: Target creature you control with toughness less than Stone Giant's power gains flying until end of turn. Destroy that creature at the beginning of the next end step.
|
||||||
|
mana={2}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Giant
|
||||||
|
power=3
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Timber Wolves
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Wolf
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Time Vault
|
||||||
|
text=Time Vault enters the battlefield tapped. -- Time Vault doesn't untap during your untap step. -- If you would begin your turn while Time Vault is tapped, you may skip that turn instead. If you do, untap Time Vault. -- {T}: Take an extra turn after this one.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Two-Headed Giant of Foriys
|
||||||
|
text=Trample -- Two-Headed Giant of Foriys can block an additional creature.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Giant
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Vesuvan Doppelganger
|
||||||
|
text=You may have Vesuvan Doppelganger enter the battlefield as a copy of any creature on the battlefield except it doesn't copy that creature's color and it gains "At the beginning of your upkeep, you may have this creature become a copy of target creature except it doesn't copy that creature's color. If you do, this creature gains this ability."
|
||||||
|
mana={3}{U}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=0
|
||||||
|
toughness=0
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Veteran Bodyguard
|
||||||
|
text=As long as Veteran Bodyguard is untapped, all damage that would be dealt to you by unblocked creatures is dealt to Veteran Bodyguard instead.
|
||||||
|
mana={3}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Winter Orb
|
||||||
|
text=As long as Winter Orb is untapped, players can't untap more than one land during their untap steps.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Word of Command
|
||||||
|
text=Look at target opponent's hand and choose a card from it. You control that player until Word of Command finishes resolving. The player plays that card if able. While doing so, the player can activate mana abilities only if they're from lands he or she controls and only if mana they produce is spent to activate other mana abilities of lands he or she controls and/or play that card. If the chosen card is cast as a spell, you control the player while that spell is resolving.
|
||||||
|
mana={B}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
[card]
|
||||||
|
name=Aladdin's Lamp
|
||||||
|
text={X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
||||||
|
mana={10}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Battering Ram
|
||||||
|
text=At the beginning of combat on your turn, Battering Ram gains banding until end of combat. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's blocking.) -- Whenever Battering Ram becomes blocked by a Wall, destroy that Wall at end of combat.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Benalish Hero
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Bronze Tablet
|
||||||
|
text=Remove Bronze Tablet from your deck before playing if you're not playing for ante. -- Bronze Tablet enters the battlefield tapped. -- {4}, {T}: Exile Bronze Tablet and target nontoken permanent an opponent owns. That player may pay 10 life. If he or she does, put Bronze Tablet into its owner's graveyard. Otherwise, that player owns Bronze Tablet and you own the other exiled card.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Channel
|
||||||
|
text=Until end of turn, any time you could activate a mana ability, you may pay 1 life. If you do, add {1} to your mana pool.
|
||||||
|
mana={G}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Circle of Protection: Artifacts
|
||||||
|
text={2}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Cursed Rack
|
||||||
|
text=As Cursed Rack enters the battlefield, choose an opponent. -- The chosen player's maximum hand size is four.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Drain Power
|
||||||
|
text=Target player activates a mana ability of each land he or she controls. Then put all mana from that player's mana pool into yours.
|
||||||
|
mana={U}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Erosion
|
||||||
|
text=Enchant land -- At the beginning of the upkeep of enchanted land's controller, destroy that land unless that player pays {1} or 1 life.
|
||||||
|
mana={U}{U}{U}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Fortified Area
|
||||||
|
text=Wall creatures you control get +1/+0 and have banding. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gaea's Liege
|
||||||
|
text=As long as Gaea's Liege isn't attacking, its power and toughness are each equal to the number of Forests you control. As long as Gaea's Liege is attacking, its power and toughness are each equal to the number of Forests defending player controls. -- {T}: Target land becomes a Forest until Gaea's Liege leaves the battlefield.
|
||||||
|
mana={3}{G}{G}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar
|
||||||
|
power=*
|
||||||
|
toughness=*
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gloom
|
||||||
|
text=White spells cost {3} more to cast. -- Activated abilities of white enchantments cost {3} more to activate.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Helm of Chatzuk
|
||||||
|
text={1}, {T}: Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Island Sanctuary
|
||||||
|
text=If you would draw a card during your draw step, instead you may skip that draw. If you do, until your next turn, you can't be attacked except by creatures with flying and/or islandwalk.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jade Monolith
|
||||||
|
text={1}: The next time a source of your choice would deal damage to target creature this turn, that source deals that damage to you instead.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Library of Leng
|
||||||
|
text=You have no maximum hand size. -- If an effect causes you to discard a card, discard it, but you may put it on top of your library instead of into your graveyard.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Magical Hack
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one basic land type with another. (For example, you may change "swampwalk" to "plainswalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mana Clash
|
||||||
|
text=You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mesa Pegasus
|
||||||
|
text=Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Pegasus
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Bomb
|
||||||
|
text=Each player may discard up to three cards. Mind Bomb deals damage to each player equal to 3 minus the number of cards he or she discarded this way.
|
||||||
|
mana={U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mishra's War Machine
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -- At the beginning of your upkeep, unless you discard a card, tap Mishra's War Machine and it deals 3 damage to you.
|
||||||
|
mana={7}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Juggernaut
|
||||||
|
power=5
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nafs Asp
|
||||||
|
text=Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays {1} before that draw step.
|
||||||
|
mana={G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Snake
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nether Shadow
|
||||||
|
text=Haste -- At the beginning of your upkeep, if Nether Shadow is in your graveyard with three or more creature cards above it, you may put Nether Shadow onto the battlefield.
|
||||||
|
mana={B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Personal Incarnation
|
||||||
|
text={0}: The next 1 damage that would be dealt to Personal Incarnation this turn is dealt to its owner instead. Any player may activate this ability, but only if he or she owns Personal Incarnation. -- When Personal Incarnation dies, its owner loses half his or her life, rounded up.
|
||||||
|
mana={3}{W}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar Incarnation
|
||||||
|
power=6
|
||||||
|
toughness=6
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pikemen
|
||||||
|
text=First strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Sink
|
||||||
|
text=Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool.
|
||||||
|
mana={X}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Surge
|
||||||
|
text=At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands he or she controlled at the beginning of this turn.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrotechnics
|
||||||
|
text=Pyrotechnics deals 4 damage divided as you choose among any number of target creatures and/or players.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rag Man
|
||||||
|
text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Minion
|
||||||
|
power=2
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rebirth
|
||||||
|
text=Remove Rebirth from your deck before playing if you're not playing for ante. -- -- Each player may put the top card of his or her library into the ante. If a player does, his or her life total becomes 20.
|
||||||
|
mana={3}{G}{G}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Shapeshifter
|
||||||
|
text=As Shapeshifter enters the battlefield, choose a number between 0 and 7. -- At the beginning of your upkeep, you may choose a number between 0 and 7. -- Shapeshifter's power is equal to the last chosen number and its toughness is equal to 7 minus that number.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=*
|
||||||
|
toughness=7-*
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sindbad
|
||||||
|
text={T}: Draw a card and reveal it. If it isn't a land card, discard it.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Siren's Call
|
||||||
|
text=Cast Siren's Call only during an opponent's turn, before attackers are declared. -- Creatures the active player controls attack this turn if able. -- At the beginning of the next end step, destroy all non-Wall creatures that player controls that didn't attack this turn. Ignore this effect for each creature the player didn't control continuously since the beginning of the turn.
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sleight of Mind
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one color word with another. (For example, you may change "target black spell" to "target blue spell." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Smoke
|
||||||
|
text=Players can't untap more than one creature during their untap steps.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Stone Giant
|
||||||
|
text={T}: Target creature you control with toughness less than Stone Giant's power gains flying until end of turn. Destroy that creature at the beginning of the next end step.
|
||||||
|
mana={2}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Giant
|
||||||
|
power=3
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sylvan Library
|
||||||
|
text=At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library.
|
||||||
|
mana={1}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tempest Efreet
|
||||||
|
text=Remove Tempest Efreet from your deck before playing if you're not playing for ante. -- {T}, Sacrifice Tempest Efreet: Target opponent may pay 10 life. If that player doesn't, he or she reveals a card at random from his or her hand. Exchange ownership of the revealed card and Tempest Efreet. Put the revealed card into your hand and Tempest Efreet from anywhere into that player's graveyard.
|
||||||
|
mana={1}{R}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Efreet
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Timber Wolves
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Wolf
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Titania's Song
|
||||||
|
text=Each noncreature artifact loses all abilities and becomes an artifact creature with power and toughness each equal to its converted mana cost. If Titania's Song leaves the battlefield, this effect continues until end of turn.
|
||||||
|
mana={3}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Urza's Avenger
|
||||||
|
text={0}: Urza's Avenger gets -1/-1 and gains your choice of banding, flying, first strike, or trample until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={6}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Visions
|
||||||
|
text=Look at the top five cards of target player's library. You may then have that player shuffle that library.
|
||||||
|
mana={W}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Winter Orb
|
||||||
|
text=As long as Winter Orb is untapped, players can't untap more than one land during their untap steps.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Xenic Poltergeist
|
||||||
|
text={T}: Until your next upkeep, target noncreature artifact becomes an artifact creature with power and toughness each equal to its converted mana cost.
|
||||||
|
mana={1}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
[card]
|
||||||
|
name=Abuna's Chant
|
||||||
|
text=Choose one — You gain 5 life; or prevent the next 5 damage that would be dealt to target creature this turn. -- Entwine {2} (Choose both if you pay the entwine cost.)
|
||||||
|
mana={3}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Circle of Protection: Artifacts
|
||||||
|
text={2}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Disruption Aura
|
||||||
|
text=Enchant artifact -- Enchanted artifact has "At the beginning of your upkeep, sacrifice this artifact unless you pay its mana cost."
|
||||||
|
mana={2}{U}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ensouled Scimitar
|
||||||
|
text={3}: Ensouled Scimitar becomes a 1/5 Spirit artifact creature with flying until end of turn. (Equipment that's a creature can't equip a creature.) -- Equipped creature gets +1/+5. -- Equip {2} ({2}: Attach to target creature you control. Equip only as a sorcery.)
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
subtype=Equipment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ferropede
|
||||||
|
text=Ferropede is unblockable. -- Whenever Ferropede deals combat damage to a player, you may remove a counter from target permanent.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Insect
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Fist of Suns
|
||||||
|
text=You may pay {W}{U}{B}{R}{G} rather than pay the mana cost for spells that you cast.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Grafted Wargear
|
||||||
|
text=Equipped creature gets +3/+2. -- Whenever Grafted Wargear becomes unattached from a permanent, sacrifice that permanent. -- Equip {0} ({0}: Attach to target creature you control. Equip only as a sorcery.)
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
subtype=Equipment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Lantern of Insight
|
||||||
|
text=Each player plays with the top card of his or her library revealed. -- {T}, Sacrifice Lantern of Insight: Target player shuffles his or her library.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ouphe Vandals
|
||||||
|
text={G}, Sacrifice Ouphe Vandals: Counter target activated ability from an artifact source and destroy that artifact if it's on the battlefield. (Mana abilities can't be targeted.)
|
||||||
|
mana={2}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Ouphe Rogue
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Plunge into Darkness
|
||||||
|
text=Choose one — Sacrifice any number of creatures, then you gain 3 life for each sacrificed creature; or pay X life, then look at the top X cards of your library, put one of those cards into your hand, and exile the rest. -- Entwine {B} (Choose both if you pay the entwine cost.)
|
||||||
|
mana={1}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rain of Rust
|
||||||
|
text=Choose one — Destroy target artifact; or destroy target land. -- Entwine {3}{R} (Choose both if you pay the entwine cost.)
|
||||||
|
mana={3}{R}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reversal of Fortune
|
||||||
|
text=Target opponent reveals his or her hand. You may copy an instant or sorcery card in it. If you do, you may cast the copy without paying its mana cost.
|
||||||
|
mana={4}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Silent Arbiter
|
||||||
|
text=No more than one creature can attack each combat. -- No more than one creature can block each combat.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=1
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Spectral Shift
|
||||||
|
text=Choose one — Change the text of target spell or permanent by replacing all instances of one basic land type with another; or change the text of target spell or permanent by replacing all instances of one color word with another. (These effects last indefinitely.) -- Entwine {2} (Choose both if you pay the entwine cost.)
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Spinal Parasite
|
||||||
|
text=Sunburst (This enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.) -- Remove two +1/+1 counters from Spinal Parasite: Remove a counter from target permanent.
|
||||||
|
mana={5}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Insect
|
||||||
|
power=-1
|
||||||
|
toughness=-1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Summoner's Egg
|
||||||
|
text=Imprint — When Summoner's Egg enters the battlefield, you may exile a card from your hand face down. -- When Summoner's Egg dies, turn the exiled card face up. If it's a creature card, put it onto the battlefield under your control.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=0
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Vicious Betrayal
|
||||||
|
text=As an additional cost to cast Vicious Betrayal, sacrifice any number of creatures. -- Target creature gets +2/+2 until end of turn for each creature sacrificed this way.
|
||||||
|
mana={3}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
[card]
|
||||||
|
name=AEther Storm
|
||||||
|
text=Creature spells can't be cast. -- Pay 4 life: Destroy AEther Storm. It can't be regenerated. Any player may activate this ability.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Anti-Magic Aura
|
||||||
|
text=Enchant creature -- Enchanted creature can't be the target of spells and can't be enchanted. This effect doesn't remove Anti-Magic Aura.
|
||||||
|
mana={2}{U}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Battering Ram
|
||||||
|
text=At the beginning of combat on your turn, Battering Ram gains banding until end of combat. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's blocking.) -- Whenever Battering Ram becomes blocked by a Wall, destroy that Wall at end of combat.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Benalish Hero
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Broken Visage
|
||||||
|
text=Destroy target nonartifact attacking creature. It can't be regenerated. Put a black Spirit creature token with that creature's power and toughness onto the battlefield. Sacrifice the token at the beginning of the next end step.
|
||||||
|
mana={4}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Circle of Protection: Artifacts
|
||||||
|
text={2}: The next time an artifact source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Crown of the Ages
|
||||||
|
text={4}, {T}: Attach target Aura attached to a creature to another creature.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Dance of Many
|
||||||
|
text=When Dance of Many enters the battlefield, put a token that's a copy of target nontoken creature onto the battlefield. -- When Dance of Many leaves the battlefield, exile the token. -- When the token leaves the battlefield, sacrifice Dance of Many. -- At the beginning of your upkeep, sacrifice Dance of Many unless you pay {U}{U}.
|
||||||
|
mana={U}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Deflection
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Drain Power
|
||||||
|
text=Target player activates a mana ability of each land he or she controls. Then put all mana from that player's mana pool into yours.
|
||||||
|
mana={U}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Dwarven Catapult
|
||||||
|
text=Dwarven Catapult deals X damage divided evenly, rounded down, among all creatures target opponent controls.
|
||||||
|
mana={X}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Elkin Bottle
|
||||||
|
text={3}, {T}: Exile the top card of your library. Until the beginning of your next upkeep, you may play that card.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Game of Chaos
|
||||||
|
text=Flip a coin. If you win the flip, you gain 1 life and target opponent loses 1 life, and you decide whether to flip again. If you lose the flip, you lose 1 life and that opponent gains 1 life, and that player decides whether to flip again. Double the life stakes with each flip.
|
||||||
|
mana={R}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gauntlets of Chaos
|
||||||
|
text={5}, Sacrifice Gauntlets of Chaos: Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gloom
|
||||||
|
text=White spells cost {3} more to cast. -- Activated abilities of white enchantments cost {3} more to activate.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Greater Realm of Preservation
|
||||||
|
text={1}{W}: The next time a black or red source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Helm of Chatzuk
|
||||||
|
text={1}, {T}: Target creature gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Hipparion
|
||||||
|
text=Hipparion can't block creatures with power 3 or greater unless you pay {1}.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Horse
|
||||||
|
power=1
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Icatian Phalanx
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={4}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Infinite Hourglass
|
||||||
|
text=At the beginning of your upkeep, put a time counter on Infinite Hourglass. -- All creatures get +1/+0 for each time counter on Infinite Hourglass. -- {3}: Remove a time counter from Infinite Hourglass. Any player may activate this ability but only during any upkeep step.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ironclaw Curse
|
||||||
|
text=Enchant creature -- Enchanted creature gets -0/-1. -- Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
|
||||||
|
mana={R}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Island Sanctuary
|
||||||
|
text=If you would draw a card during your draw step, instead you may skip that draw. If you do, until your next turn, you can't be attacked except by creatures with flying and/or islandwalk.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jade Monolith
|
||||||
|
text={1}: The next time a source of your choice would deal damage to target creature this turn, that source deals that damage to you instead.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Juxtapose
|
||||||
|
text=You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Royal Guard
|
||||||
|
text={T}: All combat damage that would be dealt to you by unblocked creatures this turn is dealt to Kjeldoran Royal Guard instead.
|
||||||
|
mana={3}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Skycaptain
|
||||||
|
text=Flying; first strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={4}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Library of Leng
|
||||||
|
text=You have no maximum hand size. -- If an effect causes you to discard a card, discard it, but you may put it on top of your library instead of into your graveyard.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Magical Hack
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one basic land type with another. (For example, you may change "swampwalk" to "plainswalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mana Clash
|
||||||
|
text=You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mesa Pegasus
|
||||||
|
text=Flying; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Pegasus
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Bomb
|
||||||
|
text=Each player may discard up to three cards. Mind Bomb deals damage to each player equal to 3 minus the number of cards he or she discarded this way.
|
||||||
|
mana={U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Necropotence
|
||||||
|
text=Skip your draw step. -- Whenever you discard a card, exile that card from your graveyard. -- Pay 1 life: Exile the top card of your library face down. Put that card into your hand at the beginning of your next end step.
|
||||||
|
mana={B}{B}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nether Shadow
|
||||||
|
text=Haste -- At the beginning of your upkeep, if Nether Shadow is in your graveyard with three or more creature cards above it, you may put Nether Shadow onto the battlefield.
|
||||||
|
mana={B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Orcish Farmer
|
||||||
|
text={T}: Target land becomes a Swamp until its controller's next untap step.
|
||||||
|
mana={1}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Orc
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pentagram of the Ages
|
||||||
|
text={4}, {T}: The next time a source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Personal Incarnation
|
||||||
|
text={0}: The next 1 damage that would be dealt to Personal Incarnation this turn is dealt to its owner instead. Any player may activate this ability, but only if he or she owns Personal Incarnation. -- When Personal Incarnation dies, its owner loses half his or her life, rounded up.
|
||||||
|
mana={3}{W}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar Incarnation
|
||||||
|
power=6
|
||||||
|
toughness=6
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pikemen
|
||||||
|
text=First strike; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Sink
|
||||||
|
text=Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool.
|
||||||
|
mana={X}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pox
|
||||||
|
text=Each player loses a third of his or her life, then discards a third of the cards in his or her hand, then sacrifices a third of the creatures he or she controls, then sacrifices a third of the lands he or she controls. Round up each time.
|
||||||
|
mana={B}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Primordial Ooze
|
||||||
|
text=Primordial Ooze attacks each turn if able. -- At the beginning of your upkeep, put a +1/+1 counter on Primordial Ooze. Then you may pay {X}, where X is the number of +1/+1 counters on it. If you don't, tap Primordial Ooze and it deals X damage to you.
|
||||||
|
mana={R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Ooze
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrotechnics
|
||||||
|
text=Pyrotechnics deals 4 damage divided as you choose among any number of target creatures and/or players.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rag Man
|
||||||
|
text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Minion
|
||||||
|
power=2
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Recall
|
||||||
|
text=Discard X cards, then return a card from your graveyard to your hand for each card discarded this way. Exile Recall.
|
||||||
|
mana={X}{X}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sacred Boon
|
||||||
|
text=Prevent the next 3 damage that would be dealt to target creature this turn. At the beginning of the next end step, put a +0/+1 counter on that creature for each 1 damage prevented this way.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Seasinger
|
||||||
|
text=When you control no Islands, sacrifice Seasinger. -- You may choose not to untap Seasinger during your untap step. -- {T}: Gain control of target creature whose controller controls an Island for as long as you control Seasinger and Seasinger remains tapped.
|
||||||
|
mana={1}{U}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Merfolk
|
||||||
|
power=0
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Seraph
|
||||||
|
text=Flying -- Whenever a creature dealt damage by Seraph this turn dies, put that card onto the battlefield under your control at the beginning of the next end step. Sacrifice the creature when you lose control of Seraph.
|
||||||
|
mana={6}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Angel
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Shapeshifter
|
||||||
|
text=As Shapeshifter enters the battlefield, choose a number between 0 and 7. -- At the beginning of your upkeep, you may choose a number between 0 and 7. -- Shapeshifter's power is equal to the last chosen number and its toughness is equal to 7 minus that number.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=*
|
||||||
|
toughness=7-*
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Shield Bearer
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=0
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sleight of Mind
|
||||||
|
text=Change the text of target spell or permanent by replacing all instances of one color word with another. (For example, you may change "target black spell" to "target blue spell." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Smoke
|
||||||
|
text=Players can't untap more than one creature during their untap steps.
|
||||||
|
mana={R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Soul Barrier
|
||||||
|
text=Whenever an opponent casts a creature spell, Soul Barrier deals 2 damage to that player unless he or she pays {2}.
|
||||||
|
mana={2}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Stone Giant
|
||||||
|
text={T}: Target creature you control with toughness less than Stone Giant's power gains flying until end of turn. Destroy that creature at the beginning of the next end step.
|
||||||
|
mana={2}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Giant
|
||||||
|
power=3
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sylvan Library
|
||||||
|
text=At the beginning of your draw step, you may draw two additional cards. If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library.
|
||||||
|
mana={1}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=The Wretched
|
||||||
|
text=At end of combat, gain control of all creatures blocking The Wretched for as long as you control The Wretched.
|
||||||
|
mana={3}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Demon
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Titania's Song
|
||||||
|
text=Each noncreature artifact loses all abilities and becomes an artifact creature with power and toughness each equal to its converted mana cost. If Titania's Song leaves the battlefield, this effect continues until end of turn.
|
||||||
|
mana={3}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Urza's Avenger
|
||||||
|
text={0}: Urza's Avenger gets -1/-1 and gains your choice of banding, flying, first strike, or trample until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={6}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Urza's Bauble
|
||||||
|
text={T}, Sacrifice Urza's Bauble: Look at a card at random in target player's hand. You draw a card at the beginning of the next turn's upkeep.
|
||||||
|
mana={0}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Winter Orb
|
||||||
|
text=As long as Winter Orb is untapped, players can't untap more than one land during their untap steps.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Xenic Poltergeist
|
||||||
|
text={T}: Until your next upkeep, target noncreature artifact becomes an artifact creature with power and toughness each equal to its converted mana cost.
|
||||||
|
mana={1}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Zur's Weirding
|
||||||
|
text=Players play with their hands revealed. -- If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
[card]
|
||||||
|
name=Celestial Dawn
|
||||||
|
text=Lands you control are Plains. -- Nonland cards you own that aren't on the battlefield, spells you control, and nonland permanents you control are white. -- You may spend white mana as though it were mana of any color. You may spend other mana only as though it were colorless mana.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Deflection
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Desertion
|
||||||
|
text=Counter target spell. If an artifact or creature spell is countered this way, put that card onto the battlefield under your control instead of into its owner's graveyard.
|
||||||
|
mana={3}{U}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Doomsday
|
||||||
|
text=Search your library and graveyard for five cards and exile the rest. Put the chosen cards on top of your library in any order. You lose half your life, rounded up.
|
||||||
|
mana={B}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Flash
|
||||||
|
text=You may put a creature card from your hand onto the battlefield. If you do, sacrifice it unless you pay its mana cost reduced by up to {2}.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Grinning Totem
|
||||||
|
text={2}, {T}, Sacrifice Grinning Totem: Search target opponent's library for a card and exile it. Then that player shuffles his or her library. Until the beginning of your next upkeep, you may play that card. At the beginning of your next upkeep, if you haven't played it, put it into its owner's graveyard.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Illicit Auction
|
||||||
|
text=Each player may bid life for control of target creature. You start the bidding with a bid of 0. In turn order, each player may top the high bid. The bidding ends if the high bid stands. The high bidder loses life equal to the high bid and gains control of the creature. (This effect lasts indefinitely.)
|
||||||
|
mana={3}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jade Monolith
|
||||||
|
text={1}: The next time a source of your choice would deal damage to target creature this turn, that source deals that damage to you instead.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Juxtapose
|
||||||
|
text=You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Royal Guard
|
||||||
|
text={T}: All combat damage that would be dealt to you by unblocked creatures this turn is dealt to Kjeldoran Royal Guard instead.
|
||||||
|
mana={3}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Library of Lat-Nam
|
||||||
|
text=An opponent chooses one — You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library.
|
||||||
|
mana={4}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pentagram of the Ages
|
||||||
|
text={4}, {T}: The next time a source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Power Sink
|
||||||
|
text=Counter target spell unless its controller pays {X}. If he or she doesn't, that player taps all lands with mana abilities he or she controls and empties his or her mana pool.
|
||||||
|
mana={X}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Psychic Transfer
|
||||||
|
text=If the difference between your life total and target player's life total is 5 or less, exchange life totals with that player.
|
||||||
|
mana={4}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrotechnics
|
||||||
|
text=Pyrotechnics deals 4 damage divided as you choose among any number of target creatures and/or players.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rag Man
|
||||||
|
text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Minion
|
||||||
|
power=2
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Recall
|
||||||
|
text=Discard X cards, then return a card from your graveyard to your hand for each card discarded this way. Exile Recall.
|
||||||
|
mana={X}{X}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Remedy
|
||||||
|
text=Prevent the next 5 damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rowen
|
||||||
|
text=Reveal the first card you draw each turn. Whenever you reveal a basic land card this way, draw a card.
|
||||||
|
mana={2}{G}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tariff
|
||||||
|
text=Each player sacrifices the creature he or she controls with the highest converted mana cost unless he or she pays that creature's mana cost. If two creatures a player controls are tied for highest cost, that player chooses one.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Zur's Weirding
|
||||||
|
text=Players play with their hands revealed. -- If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
[card]
|
||||||
|
name=Coat of Arms
|
||||||
|
text=Each creature gets +1/+1 for each other creature on the battlefield that shares at least one creature type with it. (For example, if two Goblin Warriors and a Goblin Shaman are on the battlefield, each gets +2/+2.)
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Deflection
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Royal Guard
|
||||||
|
text={T}: All combat damage that would be dealt to you by unblocked creatures this turn is dealt to Kjeldoran Royal Guard instead.
|
||||||
|
mana={3}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mana Clash
|
||||||
|
text=You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Necrologia
|
||||||
|
text=Cast Necrologia only during your end step. -- As an additional cost to cast Necrologia, pay X life. -- Draw X cards.
|
||||||
|
mana={3}{B}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Okk
|
||||||
|
text=Okk can't attack unless a creature with greater power also attacks. -- Okk can't block unless a creature with greater power also blocks.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Goblin
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pariah
|
||||||
|
text=Enchant creature -- All damage that would be dealt to you is dealt to enchanted creature instead.
|
||||||
|
mana={2}{W}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Phyrexian Colossus
|
||||||
|
text=Phyrexian Colossus doesn't untap during your untap step. -- Pay 8 life: Untap Phyrexian Colossus. -- Phyrexian Colossus can't be blocked except by three or more creatures.
|
||||||
|
mana={7}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Golem
|
||||||
|
power=8
|
||||||
|
toughness=8
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrotechnics
|
||||||
|
text=Pyrotechnics deals 4 damage divided as you choose among any number of target creatures and/or players.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rag Man
|
||||||
|
text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Minion
|
||||||
|
power=2
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rowen
|
||||||
|
text=Reveal the first card you draw each turn. Whenever you reveal a basic land card this way, draw a card.
|
||||||
|
mana={2}{G}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sacred Ground
|
||||||
|
text=Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Static Orb
|
||||||
|
text=As long as Static Orb is untapped, players can't untap more than two permanents during their untap steps.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Telepathy
|
||||||
|
text=Your opponents play with their hands revealed.
|
||||||
|
mana={U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
[card]
|
||||||
|
name=Avatar of Hope
|
||||||
|
text=If you have 3 or less life, Avatar of Hope costs {6} less to cast. -- Flying -- Avatar of Hope can block any number of creatures.
|
||||||
|
mana={6}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Avatar
|
||||||
|
power=4
|
||||||
|
toughness=9
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Coat of Arms
|
||||||
|
text=Each creature gets +1/+1 for each other creature on the battlefield that shares at least one creature type with it. (For example, if two Goblin Warriors and a Goblin Shaman are on the battlefield, each gets +2/+2.)
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Defense Grid
|
||||||
|
text=Each spell costs {3} more to cast except during its controller's turn.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Deflection
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Furnace of Rath
|
||||||
|
text=If a source would deal damage to a creature or player, it deals double that damage to that creature or player instead.
|
||||||
|
mana={1}{R}{R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gaea's Herald
|
||||||
|
text=Creature spells can't be countered.
|
||||||
|
mana={1}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elf
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guerrilla Tactics
|
||||||
|
text=Guerrilla Tactics deals 2 damage to target creature or player. -- When a spell or ability an opponent controls causes you to discard Guerrilla Tactics, Guerrilla Tactics deals 4 damage to target creature or player.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mana Clash
|
||||||
|
text=You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Bend
|
||||||
|
text=Change the text of target permanent by replacing all instances of one color word with another or one basic land type with another. (For example, you may change "nonblack creature" to "nongreen creature" or "forestwalk" to "islandwalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Murderous Betrayal
|
||||||
|
text={B}{B}, Pay half your life, rounded up: Destroy target nonblack creature. It can't be regenerated.
|
||||||
|
mana={B}{B}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Okk
|
||||||
|
text=Okk can't attack unless a creature with greater power also attacks. -- Okk can't block unless a creature with greater power also blocks.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Goblin
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Oracle's Attendants
|
||||||
|
text={T}: All damage that would be dealt to target creature this turn by a source of your choice is dealt to Oracle's Attendants instead.
|
||||||
|
mana={3}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Phyrexian Colossus
|
||||||
|
text=Phyrexian Colossus doesn't untap during your untap step. -- Pay 8 life: Untap Phyrexian Colossus. -- Phyrexian Colossus can't be blocked except by three or more creatures.
|
||||||
|
mana={7}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Golem
|
||||||
|
power=8
|
||||||
|
toughness=8
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrotechnics
|
||||||
|
text=Pyrotechnics deals 4 damage divided as you choose among any number of target creatures and/or players.
|
||||||
|
mana={4}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sacred Ground
|
||||||
|
text=Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Story Circle
|
||||||
|
text=As Story Circle enters the battlefield, choose a color. -- {W}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Telepathy
|
||||||
|
text=Your opponents play with their hands revealed.
|
||||||
|
mana={U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Thieves' Auction
|
||||||
|
text=Exile all nontoken permanents. Starting with you, each player chooses one of the exiled cards and puts it onto the battlefield tapped under his or her control. Repeat this process until all cards exiled this way have been chosen.
|
||||||
|
mana={4}{R}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Two-Headed Dragon
|
||||||
|
text=Flying -- {1}{R}: Two-Headed Dragon gets +2/+0 until end of turn. -- Two-Headed Dragon can't be blocked except by two or more creatures. -- Two-Headed Dragon can block an additional creature.
|
||||||
|
mana={4}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Dragon
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Urza's Armor
|
||||||
|
text=If a source would deal damage to you, prevent 1 of that damage.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Vexing Arcanix
|
||||||
|
text={3}, {T}: Target player names a card, then reveals the top card of his or her library. If it's the named card, the player puts it into his or her hand. Otherwise, the player puts it into his or her graveyard and Vexing Arcanix deals 2 damage to him or her.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Zur's Weirding
|
||||||
|
text=Players play with their hands revealed. -- If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
[card]
|
||||||
|
name=Booby Trap
|
||||||
|
text=As Booby Trap enters the battlefield, name a card other than a basic land card and choose an opponent. -- The chosen player reveals each card he or she draws. -- When the chosen player draws the named card, sacrifice Booby Trap. If you do, Booby Trap deals 10 damage to that player.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Coat of Arms
|
||||||
|
text=Each creature gets +1/+1 for each other creature on the battlefield that shares at least one creature type with it. (For example, if two Goblin Warriors and a Goblin Shaman are on the battlefield, each gets +2/+2.)
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Defense Grid
|
||||||
|
text=Each spell costs {3} more to cast except during its controller's turn.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Furnace of Rath
|
||||||
|
text=If a source would deal damage to a creature or player, it deals double that damage to that creature or player instead.
|
||||||
|
mana={1}{R}{R}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guerrilla Tactics
|
||||||
|
text=Guerrilla Tactics deals 2 damage to target creature or player. -- When a spell or ability an opponent controls causes you to discard Guerrilla Tactics, Guerrilla Tactics deals 4 damage to target creature or player.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mana Clash
|
||||||
|
text=You and target opponent each flip a coin. Mana Clash deals 1 damage to each player whose coin comes up tails. Repeat this process until both players' coins come up heads on the same flip.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Bend
|
||||||
|
text=Change the text of target permanent by replacing all instances of one color word with another or one basic land type with another. (For example, you may change "nonblack creature" to "nongreen creature" or "forestwalk" to "islandwalk." This effect lasts indefinitely.)
|
||||||
|
mana={U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Oracle's Attendants
|
||||||
|
text={T}: All damage that would be dealt to target creature this turn by a source of your choice is dealt to Oracle's Attendants instead.
|
||||||
|
mana={3}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=1
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Reverse Damage
|
||||||
|
text=The next time a source of your choice would deal damage to you this turn, prevent that damage. You gain life equal to the damage prevented this way.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sacred Ground
|
||||||
|
text=Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sanctum Guardian
|
||||||
|
text=Sacrifice Sanctum Guardian: The next time a source of your choice would deal damage to target creature or player this turn, prevent that damage.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Cleric
|
||||||
|
power=1
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Storage Matrix
|
||||||
|
text=As long as Storage Matrix is untapped, each player chooses artifact, creature, or land during his or her untap step. That player can untap only permanents of the chosen type this step.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Story Circle
|
||||||
|
text=As Story Circle enters the battlefield, choose a color. -- {W}: The next time a source of your choice of the chosen color would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Telepathy
|
||||||
|
text=Your opponents play with their hands revealed.
|
||||||
|
mana={U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Zealous Inquisitor
|
||||||
|
text={1}{W}: The next 1 damage that would be dealt to Zealous Inquisitor this turn is dealt to target creature instead.
|
||||||
|
mana={2}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Cleric
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Zur's Weirding
|
||||||
|
text=Players play with their hands revealed. -- If a player would draw a card, he or she reveals it instead. Then any other player may pay 2 life. If a player does, put that card into its owner's graveyard. Otherwise, that player draws a card.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
[card]
|
||||||
|
name=Aid from the Cowl
|
||||||
|
text=Revolt — At the beginning of your end step, if a permanent you controlled left the battlefield this turn, reveal the top card of your library. If it's a permanent card, you may put it onto the battlefield. Otherwise, you may put it on the bottom of your library.
|
||||||
|
mana={3}{G}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ajani's Aid
|
||||||
|
text=When Ajani's Aid enters the battlefield, you may search your library and/or graveyard for a card named Ajani, Valiant Protector, reveal it, and put it into your hand. If you search your library this way, shuffle it. -- Sacrifice Ajani's Aid: Prevent all combat damage a creature of your choice would deal this turn.
|
||||||
|
mana={2}{G}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Baral, Chief of Compliance
|
||||||
|
text=Instant and sorcery spells you cast cost {1} less to cast. -- Whenever a spell or ability you control counters a spell, you may draw a card. If you do, discard a card.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Legendary Creature
|
||||||
|
subtype=Human Wizard
|
||||||
|
power=1
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Battle at the Bridge
|
||||||
|
other={improvise} name(Improvise)
|
||||||
|
text=Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.) -- Target creature gets -X/-X until end of turn. You gain X life.
|
||||||
|
mana={X}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Crackdown Construct
|
||||||
|
text=Whenever you activate an ability of an artifact or creature that isn't a mana ability, Crackdown Construct gets +1/+1 until end of turn.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Dark Intimations
|
||||||
|
text=Each opponent sacrifices a creature or planeswalker, then discards a card. You return a creature or planeswalker card from your graveyard to your hand, then draw a card. -- When you cast a Bolas planeswalker spell, exile Dark Intimations from your graveyard. That planeswalker enters the battlefield with an additional loyalty counter on it.
|
||||||
|
mana={2}{U}{B}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Deft Dismissal
|
||||||
|
text=Deft Dismissal deals 3 damage divided as you choose among one, two, or three target attacking or blocking creatures.
|
||||||
|
mana={3}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Destructive Tampering
|
||||||
|
text=Choose one — --Destroy target artifact. --Creatures without flying can't block this turn.
|
||||||
|
mana={2}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Disallow
|
||||||
|
text=Counter target spell, activated ability, or triggered ability. (Mana abilities can't be targeted.)
|
||||||
|
mana={1}{U}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Exquisite Archangel
|
||||||
|
abilities=flying
|
||||||
|
text=Flying -- If you would lose the game, instead exile Exquisite Archangel and your life total becomes equal to your starting life total.
|
||||||
|
mana={5}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Angel
|
||||||
|
power=5
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Hungry Flames
|
||||||
|
text=Hungry Flames deals 3 damage to target creature and 2 damage to target player.
|
||||||
|
mana={2}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Indomitable Creativity
|
||||||
|
target=<prex>artifact,creature|battlefield
|
||||||
|
auto=destroy and!( if cantargetcard(*[creature;artifact]|nonbattlezone) then reveal:x revealzone(targetcontrollerlibrary) revealuntil(*[creature;artifact]|targetcontrollerlibrary) optionone all(*|reveal) moveto(exile) and!(moveto(ownerbattlefield))! optiononeend revealend )!
|
||||||
|
text=Destroy X target artifacts and/or creatures. For each permanent destroyed this way, its controller reveals cards from the top of his or her library until an artifact or creature card is revealed and exiles that card. Those players put the exiled cards onto the battlefield, then shuffle their libraries.
|
||||||
|
mana={X}{R}{R}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Inspiring Statuary
|
||||||
|
text=Nonartifact spells you cast have improvise. (Your artifacts can help cast those spells. Each artifact you tap after you're done activating mana abilities pays for {1}.)
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Invigorated Rampage
|
||||||
|
text=Choose one — --Target creature gets +4/+0 and gains trample until end of turn. --Two target creatures each get +2/+0 and gain trample until end of turn.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Merchant's Dockhand
|
||||||
|
text={3}{U}, {T}, Tap X untapped artifacts you control: Look at the top X cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=1
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Monstrous Onslaught
|
||||||
|
text=Monstrous Onslaught deals X damage divided as you choose among any number of target creatures, where X is the greatest power among creatures you control as you cast Monstrous Onslaught.
|
||||||
|
mana={3}{G}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Night Market Guard
|
||||||
|
text=Night Market Guard can block an additional creature each combat.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Construct
|
||||||
|
power=3
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pia's Revolution
|
||||||
|
text=Whenever a nontoken artifact is put into your graveyard from the battlefield, return that card to your hand unless target opponent has Pia's Revolution deal 3 damage to him or her.
|
||||||
|
mana={2}{R}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tezzeret's Betrayal
|
||||||
|
text=Destroy target creature. You may search your library and/or graveyard for a card named Tezzeret, Master of Metal, reveal it, and put it into your hand. If you search your library this way, shuffle it.
|
||||||
|
mana={3}{U}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Whir of Invention
|
||||||
|
other={improvise} name(Improvise)
|
||||||
|
text=Improvise (Your artifacts can help cast this spell. Each artifact you tap after you're done activating mana abilities pays for {1}.) -- Search your library for an artifact card with converted mana cost X or less, put it onto the battlefield, then shuffle your library.
|
||||||
|
mana={X}{U}{U}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Winding Constrictor
|
||||||
|
text=If one or more counters would be placed on an artifact or creature you control, that many plus one of each of those kinds of counters are placed on that permanent instead. -- If you would get one or more counters, you get that many plus one of each of those kinds of counters instead.
|
||||||
|
mana={B}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Snake
|
||||||
|
power=2
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
[card]
|
||||||
|
name=Branching Bolt
|
||||||
|
text=Choose one or both — Branching Bolt deals 3 damage to target creature with flying; and/or Branching Bolt deals 3 damage to target creature without flying.
|
||||||
|
mana={1}{R}{G}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Brilliant Ultimatum
|
||||||
|
text=Exile the top five cards of your library. An opponent separates those cards into two piles. You may play any number of cards from one of those piles without paying their mana costs.
|
||||||
|
mana={W}{W}{U}{U}{U}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Clarion Ultimatum
|
||||||
|
text=Choose five permanents you control. For each of those permanents, you may search your library for a card with the same name as that permanent. Put those cards onto the battlefield tapped, then shuffle your library.
|
||||||
|
mana={G}{G}{W}{W}{W}{U}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Covenant of Minds
|
||||||
|
text=Reveal the top three cards of your library. Target opponent may choose to put those cards into your hand. If he or she doesn't, put those cards into your graveyard and draw five cards.
|
||||||
|
mana={4}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Empyrial Archangel
|
||||||
|
text=Flying, shroud -- All damage that would be dealt to you is dealt to Empyrial Archangel instead.
|
||||||
|
mana={4}{G}{W}{W}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Angel
|
||||||
|
power=5
|
||||||
|
toughness=8
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Feral Hydra
|
||||||
|
text=Feral Hydra enters the battlefield with X +1/+1 counters on it. -- {3}: Put a +1/+1 counter on Feral Hydra. Any player may activate this ability.
|
||||||
|
mana={X}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Hydra Beast
|
||||||
|
power=0
|
||||||
|
toughness=0
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gather Specimens
|
||||||
|
text=If a creature would enter the battlefield under an opponent's control this turn, it enters the battlefield under your control instead.
|
||||||
|
mana={3}{U}{U}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Hindering Light
|
||||||
|
text=Counter target spell that targets you or a permanent you control. -- Draw a card.
|
||||||
|
mana={W}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Immortal Coil
|
||||||
|
text={T}, Exile two cards from your graveyard: Draw a card. -- If damage would be dealt to you, prevent that damage. Exile a card from your graveyard for each 1 damage prevented this way. -- When there are no cards in your graveyard, you lose the game.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kresh the Bloodbraided
|
||||||
|
text=Whenever another creature dies, you may put X +1/+1 counters on Kresh the Bloodbraided, where X is that creature's power.
|
||||||
|
mana={2}{B}{R}{G}
|
||||||
|
type=Legendary Creature
|
||||||
|
subtype=Human Warrior
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Lich's Mirror
|
||||||
|
text=If you would lose the game, instead shuffle your hand, your graveyard, and all permanents you own into your library, then draw seven cards and your life total becomes 20.
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mindlock Orb
|
||||||
|
text=Players can't search libraries.
|
||||||
|
mana={3}{U}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Prince of Thralls
|
||||||
|
text=Whenever a permanent an opponent controls is put into a graveyard, put that card onto the battlefield under your control unless that opponent pays 3 life.
|
||||||
|
mana={4}{U}{B}{B}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Demon
|
||||||
|
power=7
|
||||||
|
toughness=7
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Qasali Ambusher
|
||||||
|
text=Reach -- If a creature is attacking you and you control a Forest and a Plains, you may cast Qasali Ambusher without paying its mana cost and as though it had flash.
|
||||||
|
mana={1}{G}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Cat Warrior
|
||||||
|
power=2
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sacellum Godspeaker
|
||||||
|
text={T}: Reveal any number of creature cards with power 5 or greater from your hand. Add {G} to your mana pool for each card revealed this way.
|
||||||
|
mana={2}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elf Druid
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Skill Borrower
|
||||||
|
text=Play with the top card of your library revealed. -- As long as the top card of your library is an artifact or creature card, Skill Borrower has all activated abilities of that card. (If any of the abilities use that card's name, use this creature's name instead.)
|
||||||
|
mana={2}{U}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Human Wizard
|
||||||
|
power=1
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Stoic Angel
|
||||||
|
text=Flying, vigilance -- Players can't untap more than one creature during their untap steps.
|
||||||
|
mana={1}{G}{W}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Angel
|
||||||
|
power=3
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Swerve
|
||||||
|
text=Change the target of target spell with a single target.
|
||||||
|
mana={U}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tar Fiend
|
||||||
|
text=Devour 2 (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with twice that many +1/+1 counters on it.) -- When Tar Fiend enters the battlefield, target player discards a card for each creature it devoured.
|
||||||
|
mana={5}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elemental
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
[card]
|
||||||
|
name=Awesome Presence
|
||||||
|
text=Enchant creature -- Enchanted creature can't be blocked unless defending player pays {3} for each creature he or she controls that's blocking it.
|
||||||
|
mana={U}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Bounty of the Hunt
|
||||||
|
text=You may exile a green card from your hand rather than pay Bounty of the Hunt's mana cost. -- Distribute three +1/+1 counters among one, two, or three target creatures. For each +1/+1 counter you put on a creature this way, remove a +1/+1 counter from that creature at the beginning of the next cleanup step.
|
||||||
|
mana={3}{G}{G}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Chaos Harlequin
|
||||||
|
text={R}: Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn.
|
||||||
|
mana={2}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Death Spark
|
||||||
|
text=Death Spark deals 1 damage to target creature or player. -- At the beginning of your upkeep, if Death Spark is in your graveyard with a creature card directly above it, you may pay {1}. If you do, return Death Spark to your hand.
|
||||||
|
mana={R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Diminishing Returns
|
||||||
|
text=Each player shuffles his or her hand and graveyard into his or her library. You exile the top ten cards of your library. Then each player draws up to seven cards.
|
||||||
|
mana={2}{U}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Errand of Duty
|
||||||
|
text=Put a 1/1 white Knight creature token with banding onto the battlefield. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={1}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Fatal Lore
|
||||||
|
text=An opponent chooses one — You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated.
|
||||||
|
mana={2}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gorilla Berserkers
|
||||||
|
text=Trample; rampage 2 (Whenever this creature becomes blocked, it gets +2/+2 until end of turn for each creature blocking it beyond the first.) -- Gorilla Berserkers can't be blocked except by three or more creatures.
|
||||||
|
mana={3}{G}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Ape Berserker
|
||||||
|
power=2
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guerrilla Tactics
|
||||||
|
text=Guerrilla Tactics deals 2 damage to target creature or player. -- When a spell or ability an opponent controls causes you to discard Guerrilla Tactics, Guerrilla Tactics deals 4 damage to target creature or player.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gustha's Scepter
|
||||||
|
text={T}: Exile a card from your hand face down. You may look at it for as long as it remains exiled. -- {T}: Return a card you own exiled with Gustha's Scepter to your hand. -- When you lose control of Gustha's Scepter, put all cards exiled with Gustha's Scepter into their owner's graveyard.
|
||||||
|
mana={0}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Helm of Obedience
|
||||||
|
text={X}, {T}: Target opponent puts cards from the top of his or her library into his or her graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Kjeldoran Escort
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={2}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Soldier
|
||||||
|
power=2
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Krovikan Horror
|
||||||
|
text=At the beginning of the end step, if Krovikan Horror is in your graveyard with a creature card directly above it, you may return Krovikan Horror to your hand. -- {1}, Sacrifice a creature: Krovikan Horror deals 1 damage to target creature or player.
|
||||||
|
mana={3}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Horror Spirit
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Library of Lat-Nam
|
||||||
|
text=An opponent chooses one — You draw three cards at the beginning of the next turn's upkeep; or you search your library for a card, put that card into your hand, then shuffle your library.
|
||||||
|
mana={4}{U}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Lim-Dul's Vault
|
||||||
|
text=Look at the top five cards of your library. As many times as you choose, you may pay 1 life, put those cards on the bottom of your library in any order, then look at the top five cards of your library. Then shuffle your library and put the last cards you looked at this way on top of it in any order.
|
||||||
|
mana={U}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Martyrdom
|
||||||
|
text=Until end of turn, target creature you control gains "{0}: The next 1 damage that would be dealt to target creature or player this turn is dealt to this creature instead." Only you may activate this ability.
|
||||||
|
mana={1}{W}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nature's Blessing
|
||||||
|
text={G}{W}, Discard a card: Put a +1/+1 counter on target creature or that creature gains banding, first strike, or trample. (This effect lasts indefinitely. Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding a player controls are blocking or being blocked by a creature, that player divides that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={2}{G}{W}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Omen of Fire
|
||||||
|
text=Return all Islands to their owners' hands. -- -- Each player sacrifices a Plains or a white permanent for each white permanent he or she controls.
|
||||||
|
mana={3}{R}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Phyrexian Portal
|
||||||
|
text={3}: If your library has ten or more cards in it, target opponent looks at the top ten cards of your library and separates them into two face-down piles. Exile one of those piles. Search the other pile for a card, put it into your hand, then shuffle the rest of that pile into your library.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Primitive Justice
|
||||||
|
text=As an additional cost to cast Primitive Justice, you may pay {1}{R} and/or {1}{G} any number of times. -- Destroy target artifact. For each additional {1}{R} you paid, destroy another target artifact. For each additional {1}{G} you paid, destroy another target artifact, and you gain 1 life.
|
||||||
|
mana={1}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyrokinesis
|
||||||
|
text=You may exile a red card from your hand rather than pay Pyrokinesis's mana cost. -- Pyrokinesis deals 4 damage divided as you choose among any number of target creatures.
|
||||||
|
mana={4}{R}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Scarab of the Unseen
|
||||||
|
text={T}, Sacrifice Scarab of the Unseen: Return all Auras attached to target permanent you own to their owners' hands. Draw a card at the beginning of the next turn's upkeep.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Scars of the Veteran
|
||||||
|
text=You may exile a white card from your hand rather than pay Scars of the Veteran's mana cost. -- Prevent the next 7 damage that would be dealt to target creature or player this turn. At the beginning of the next end step, put a +0/+1 counter on that creature for each 1 damage prevented this way.
|
||||||
|
mana={4}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Seasoned Tactician
|
||||||
|
text={3}, Exile the top four cards of your library: The next time a source of your choice would deal damage to you this turn, prevent that damage.
|
||||||
|
mana={2}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Advisor
|
||||||
|
power=1
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Soldevi Adnate
|
||||||
|
text={T}, Sacrifice a black or artifact creature: Add to your mana pool an amount of {B} equal to the sacrificed creature's converted mana cost.
|
||||||
|
mana={1}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Cleric
|
||||||
|
power=1
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Soldevi Digger
|
||||||
|
text={2}: Put the top card of your graveyard on the bottom of your library.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Soldevi Sentry
|
||||||
|
text={1}: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates this way, that player may draw a card.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Soldier
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Spiny Starfish
|
||||||
|
text={U}: Regenerate Spiny Starfish. -- At the beginning of each end step, if Spiny Starfish regenerated this turn, put a 0/1 blue Starfish creature token onto the battlefield for each time it regenerated this turn.
|
||||||
|
mana={2}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Starfish
|
||||||
|
power=0
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Storm Elemental
|
||||||
|
text=Flying -- {U}, Exile the top card of your library: Tap target creature with flying. -- {U}, Exile the top card of your library: If the exiled card is a snow land, Storm Elemental gets +1/+1 until end of turn.
|
||||||
|
mana={5}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elemental
|
||||||
|
power=3
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Stromgald Spy
|
||||||
|
text=Whenever Stromgald Spy attacks and isn't blocked, you may have defending player play with his or her hand revealed for as long as Stromgald Spy remains on the battlefield. If you do, Stromgald Spy assigns no combat damage this turn.
|
||||||
|
mana={3}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Rogue
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Suffocation
|
||||||
|
text=Cast Suffocation only if you were dealt damage this turn by a red instant or sorcery spell. -- Suffocation deals 4 damage to the controller of the last red instant or sorcery spell that dealt damage to you this turn. -- Draw a card at the beginning of the next turn's upkeep.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sworn Defender
|
||||||
|
text={1}: Sworn Defender's power becomes the toughness of target creature blocking or being blocked by Sworn Defender minus 1 until end of turn, and Sworn Defender's toughness becomes 1 plus the power of that creature until end of turn.
|
||||||
|
mana={2}{W}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Knight
|
||||||
|
power=1
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tidal Control
|
||||||
|
text=Cumulative upkeep {2} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Pay 2 life or {2}: Counter target red or green spell. Any player may activate this ability.
|
||||||
|
mana={1}{U}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Urza's Engine
|
||||||
|
text=Trample -- {3}: Urza's Engine gains banding until end of turn. (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -- {3}: Attacking creatures banded with Urza's Engine gain trample until end of turn.
|
||||||
|
mana={5}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Juggernaut
|
||||||
|
power=1
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Whip Vine
|
||||||
|
text=Defender; reach (This creature can block creatures with flying.) -- You may choose not to untap Whip Vine during your untap step. -- {T}: Tap target creature with flying blocked by Whip Vine. That creature doesn't untap during its controller's untap step for as long as Whip Vine remains tapped.
|
||||||
|
mana={2}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Plant Wall
|
||||||
|
power=1
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Winter's Night
|
||||||
|
text=Whenever a player taps a snow land for mana, that player adds one mana to his or her mana pool of any type that land produced. That land doesn't untap during its controller's next untap step.
|
||||||
|
mana={R}{G}{W}
|
||||||
|
type=World Enchantment
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
[card]
|
||||||
|
name=Anavolver
|
||||||
|
text=Kicker {1}{U} and/or {B} (You may pay an additional {1}{U} and/or {B} as you cast this spell.) -- If Anavolver was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying. -- If Anavolver was kicked with its {B} kicker, it enters the battlefield with a +1/+1 counter on it and with "Pay 3 life: Regenerate Anavolver."
|
||||||
|
mana={3}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Volver
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Captain's Maneuver
|
||||||
|
text=The next X damage that would be dealt to target creature or player this turn is dealt to another target creature or player instead.
|
||||||
|
mana={X}{R}{W}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Cetavolver
|
||||||
|
text=Kicker {1}{R} and/or {G} (You may pay an additional {1}{R} and/or {G} as you cast this spell.) -- If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike. -- If Cetavolver was kicked with its {G} kicker, it enters the battlefield with a +1/+1 counter on it and with trample.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Volver
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Coalition Flag
|
||||||
|
text=Enchant creature you control -- Enchanted creature is a Flagbearer. -- While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able.
|
||||||
|
mana={W}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Coalition Honor Guard
|
||||||
|
text=While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able.
|
||||||
|
mana={3}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Flagbearer
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Consume Strength
|
||||||
|
text=Target creature gets +2/+2 until end of turn. Another target creature gets -2/-2 until end of turn.
|
||||||
|
mana={1}{B}{G}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Cromat
|
||||||
|
text={W}{B}: Destroy target creature blocking or blocked by Cromat. -- {U}{R}: Cromat gains flying until end of turn. -- {B}{G}: Regenerate Cromat. -- {R}{W}: Cromat gets +1/+1 until end of turn. -- {G}{U}: Put Cromat on top of its owner's library.
|
||||||
|
mana={W}{U}{B}{R}{G}
|
||||||
|
type=Legendary Creature
|
||||||
|
subtype=Illusion
|
||||||
|
power=5
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Dead Ringers
|
||||||
|
text=Destroy two target nonblack creatures unless either one is a color the other isn't. They can't be regenerated.
|
||||||
|
mana={4}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Degavolver
|
||||||
|
text=Kicker {1}{B} and/or {R} (You may pay an additional {1}{B} and/or {R} as you cast this spell.) -- If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with "Pay 3 life: Regenerate Degavolver." -- If Degavolver was kicked with its {R} kicker, it enters the battlefield with a +1/+1 counter on it and with first strike.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Volver
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Dodecapod
|
||||||
|
text=If a spell or ability an opponent controls causes you to discard Dodecapod, put it onto the battlefield with two +1/+1 counters on it instead of putting it into your graveyard.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Golem
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Emblazoned Golem
|
||||||
|
text=Kicker {X} (You may pay an additional {X} as you cast this spell.) -- Spend only colored mana on X. No more than one mana of each color may be spent this way. -- If Emblazoned Golem was kicked, it enters the battlefield with X +1/+1 counters on it.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Golem
|
||||||
|
power=1
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Evasive Action
|
||||||
|
text=Domain — Counter target spell unless its controller pays {1} for each basic land type among lands you control.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=False Dawn
|
||||||
|
text=Until end of turn, spells and abilities you control that would add colored mana to your mana pool add that much white mana instead. Until end of turn, you may spend white mana as though it were mana of any color. -- -- Draw a card.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Fire // Ice
|
||||||
|
text=Fire deals 2 damage divided as you choose among one or two target creatures and/or players. -- // -- Tap target permanent. -- Draw a card.
|
||||||
|
mana={1}{R} // {1}{U}
|
||||||
|
type=Instant // Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gaea's Balance
|
||||||
|
text=As an additional cost to cast Gaea's Balance, sacrifice five lands. -- Search your library for a land card of each basic land type and put them onto the battlefield. Then shuffle your library.
|
||||||
|
mana={3}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Gerrard's Verdict
|
||||||
|
text=Target player discards two cards. You gain 3 life for each land card discarded this way.
|
||||||
|
mana={W}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ice Cave
|
||||||
|
text=Whenever a player casts a spell, any other player may pay that spell's mana cost. If a player does, counter the spell. (Mana cost includes color.)
|
||||||
|
mana={3}{U}{U}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Illuminate
|
||||||
|
text=Kicker {2}{R} and/or {3}{U} (You may pay an additional {2}{R} and/or {3}{U} as you cast this spell.) -- Illuminate deals X damage to target creature. If Illuminate was kicked with its {2}{R} kicker, it deals X damage to that creature's controller. If Illuminate was kicked with its {3}{U} kicker, you draw X cards.
|
||||||
|
mana={X}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Illusion // Reality
|
||||||
|
text=Target spell or permanent becomes the color of your choice until end of turn. -- // -- Destroy target artifact.
|
||||||
|
mana={U} // {2}{G}
|
||||||
|
type=Instant // Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jaded Response
|
||||||
|
text=Counter target spell if it shares a color with a creature you control.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Life // Death
|
||||||
|
text=All lands you control become 1/1 creatures until end of turn. They're still lands. -- // -- Return target creature card from your graveyard to the battlefield. You lose life equal to its converted mana cost.
|
||||||
|
mana={G} // {1}{B}
|
||||||
|
type=Sorcery // Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mind Extraction
|
||||||
|
text=As an additional cost to cast Mind Extraction, sacrifice a creature. -- Target player reveals his or her hand and discards all cards of each of the sacrificed creature's colors.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Necravolver
|
||||||
|
text=Kicker {1}{G} and/or {W} (You may pay an additional {1}{G} and/or {W} as you cast this spell.) -- If Necravolver was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample. -- If Necravolver was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with "Whenever Necravolver deals damage, you gain that much life."
|
||||||
|
mana={2}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Volver
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Night // Day
|
||||||
|
text=Target creature gets -1/-1 until end of turn. -- // -- Creatures target player controls get +1/+1 until end of turn.
|
||||||
|
mana={B} // {2}{W}
|
||||||
|
type=Instant // Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Order // Chaos
|
||||||
|
text=Exile target attacking creature. -- // -- Creatures can't block this turn.
|
||||||
|
mana={3}{W} // {2}{R}
|
||||||
|
type=Instant // Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Rakavolver
|
||||||
|
text=Kicker {1}{W} and/or {U} (You may pay an additional {1}{W} and/or {U} as you cast this spell.) -- If Rakavolver was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with "Whenever Rakavolver deals damage, you gain that much life." -- If Rakavolver was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying.
|
||||||
|
mana={2}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Volver
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Squee's Revenge
|
||||||
|
text=Choose a number. Flip a coin that many times or until you lose a flip, whichever comes first. If you win all the flips, draw two cards for each flip.
|
||||||
|
mana={1}{U}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Standard Bearer
|
||||||
|
text=While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able.
|
||||||
|
mana={1}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Flagbearer
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Suffocating Blast
|
||||||
|
text=Counter target spell and Suffocating Blast deals 3 damage to target creature.
|
||||||
|
mana={1}{U}{U}{R}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Suppress
|
||||||
|
text=Target player exiles all cards from his or her hand face down. At the beginning of the end step of that player's next turn, that player returns those cards to his or her hand.
|
||||||
|
mana={2}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Tahngarth's Glare
|
||||||
|
text=Look at the top three cards of target opponent's library, then put them back in any order. That player looks at the top three cards of your library, then puts them back in any order.
|
||||||
|
mana={R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
[card]
|
||||||
|
name=Aven Mimeomancer
|
||||||
|
text=Flying -- At the beginning of your upkeep, you may put a feather counter on target creature. If you do, that creature is 3/1 and has flying for as long as it has a feather counter on it.
|
||||||
|
mana={1}{W}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Bird Wizard
|
||||||
|
power=3
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Enigma Sphinx
|
||||||
|
text=Flying -- When Enigma Sphinx is put into your graveyard from the battlefield, put it into your library third from the top. -- Cascade (When you cast this spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom in a random order.)
|
||||||
|
mana={4}{W}{U}{B}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Sphinx
|
||||||
|
power=5
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Giant Ambush Beetle
|
||||||
|
text=Haste -- When Giant Ambush Beetle enters the battlefield, you may have target creature block it this turn if able.
|
||||||
|
mana={3}{BG}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Insect
|
||||||
|
power=4
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Meddling Mage
|
||||||
|
text=As Meddling Mage enters the battlefield, name a nonland card. -- The named card can't be cast.
|
||||||
|
mana={W}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human Wizard
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sen Triplets
|
||||||
|
text=At the beginning of your upkeep, choose target opponent. This turn, that player can't cast spells or activate abilities and plays with his or her hand revealed. You may play cards from that player's hand this turn.
|
||||||
|
mana={2}{W}{U}{B}
|
||||||
|
type=Legendary Artifact Creature
|
||||||
|
subtype=Human Wizard
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Singe-Mind Ogre
|
||||||
|
text=When Singe-Mind Ogre enters the battlefield, target player reveals a card at random from his or her hand, then loses life equal to that card's converted mana cost.
|
||||||
|
mana={2}{B}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Ogre Mutant
|
||||||
|
power=3
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Soul Manipulation
|
||||||
|
text=Choose one or both — Counter target creature spell; and/or return target creature card from your graveyard to your hand.
|
||||||
|
mana={1}{U}{B}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sovereigns of Lost Alara
|
||||||
|
text=Exalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.) -- Whenever a creature you control attacks alone, you may search your library for an Aura card that could enchant that creature, put it onto the battlefield attached to that creature, then shuffle your library.
|
||||||
|
mana={4}{W}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Spirit
|
||||||
|
power=4
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Spellbreaker Behemoth
|
||||||
|
text=Spellbreaker Behemoth can't be countered. -- Creature spells you control with power 5 or greater can't be countered.
|
||||||
|
mana={1}{R}{G}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Beast
|
||||||
|
power=5
|
||||||
|
toughness=5
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Thought Hemorrhage
|
||||||
|
text=Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library.
|
||||||
|
mana={2}{B}{R}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Vengeful Rebirth
|
||||||
|
text=Return target card from your graveyard to your hand. If you return a nonland card to your hand this way, Vengeful Rebirth deals damage equal to that card's converted mana cost to target creature or player. -- Exile Vengeful Rebirth.
|
||||||
|
mana={4}{R}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
[card]
|
||||||
|
name=Branching Bolt
|
||||||
|
text=Choose one or both — Branching Bolt deals 3 damage to target creature with flying; and/or Branching Bolt deals 3 damage to target creature without flying.
|
||||||
|
mana={1}{R}{G}
|
||||||
|
type=Instant
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Duplicant
|
||||||
|
text=Imprint — When Duplicant enters the battlefield, you may exile target nontoken creature. -- As long as the exiled card is a creature card, Duplicant has that card's power, toughness, and creature types. It's still a Shapeshifter.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Shapeshifter
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Feral Hydra
|
||||||
|
text=Feral Hydra enters the battlefield with X +1/+1 counters on it. -- {3}: Put a +1/+1 counter on Feral Hydra. Any player may activate this ability.
|
||||||
|
mana={X}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Hydra Beast
|
||||||
|
power=0
|
||||||
|
toughness=0
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Incremental Blight
|
||||||
|
text=Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature.
|
||||||
|
mana={3}{B}{B}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Inferno Trap
|
||||||
|
text=If you've been dealt damage by two or more creatures this turn, you may pay {R} rather than pay Inferno Trap's mana cost. -- Inferno Trap deals 4 damage to target creature.
|
||||||
|
mana={3}{R}
|
||||||
|
type=Instant
|
||||||
|
subtype=Trap
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Mosswort Bridge
|
||||||
|
text=Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.) -- {T}: Add {G} to your mana pool. -- {G}, {T}: You may play the exiled card without paying its mana cost if creatures you control have total power 10 or greater.
|
||||||
|
type=Land
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Primal Command
|
||||||
|
text=Choose two — Target player gains 7 life; or put target noncreature permanent on top of its owner's library; or target player shuffles his or her graveyard into his or her library; or search your library for a creature card, reveal it, put it into your hand, then shuffle your library.
|
||||||
|
mana={3}{G}{G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Spider Umbra
|
||||||
|
text=Enchant creature -- Enchanted creature gets +1/+1 and has reach. (It can block creatures with flying.) -- Totem armor (If enchanted creature would be destroyed, instead remove all damage from it and destroy this Aura.)
|
||||||
|
mana={G}
|
||||||
|
type=Enchantment
|
||||||
|
subtype=Aura
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sundering Titan
|
||||||
|
text=When Sundering Titan enters the battlefield or leaves the battlefield, choose a land of each basic land type, then destroy those lands.
|
||||||
|
mana={8}
|
||||||
|
type=Artifact Creature
|
||||||
|
subtype=Golem
|
||||||
|
power=7
|
||||||
|
toughness=10
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Thunderstaff
|
||||||
|
text=As long as Thunderstaff is untapped, if a creature would deal combat damage to you, prevent 1 of that damage. -- {2}, {T}: Attacking creatures get +1/+0 until end of turn.
|
||||||
|
mana={3}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Two-Headed Dragon
|
||||||
|
text=Flying -- {1}{R}: Two-Headed Dragon gets +2/+0 until end of turn. -- Two-Headed Dragon can't be blocked except by two or more creatures. -- Two-Headed Dragon can block an additional creature.
|
||||||
|
mana={4}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Dragon
|
||||||
|
power=4
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Wax // Wane
|
||||||
|
text=Target creature gets +2/+2 until end of turn. -- // -- Destroy target enchantment.
|
||||||
|
mana={G} // {W}
|
||||||
|
type=Instant // Instant
|
||||||
|
[/card]
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
[card]
|
||||||
|
name=Abu Ja'far
|
||||||
|
text=When Abu Ja'far dies, destroy all creatures blocking or blocked by it. They can't be regenerated.
|
||||||
|
mana={W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human
|
||||||
|
power=0
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Aladdin's Lamp
|
||||||
|
text={X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
||||||
|
mana={10}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Camel
|
||||||
|
text=Banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.) -- As long as Camel is attacking, prevent all damage Deserts would deal to Camel and to creatures banded with Camel.
|
||||||
|
mana={W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Camel
|
||||||
|
power=0
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=City in a Bottle
|
||||||
|
text=Whenever a nontoken permanent from the Arabian Nights expansion other than City in a Bottle is on the battlefield, its controller sacrifices it. -- Players can't play cards from the Arabian Nights expansion.
|
||||||
|
mana={2}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Cyclone
|
||||||
|
text=At the beginning of your upkeep, put a wind counter on Cyclone, then sacrifice Cyclone unless you pay {G} for each wind counter on it. If you pay, Cyclone deals damage equal to the number of wind counters on it to each creature and each player.
|
||||||
|
mana={2}{G}{G}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Guardian Beast
|
||||||
|
text=As long as Guardian Beast is untapped, noncreature artifacts you control can't be enchanted, they're indestructible, and other players can't gain control of them. This effect doesn't remove Auras already attached to those artifacts.
|
||||||
|
mana={3}{B}
|
||||||
|
type=Creature
|
||||||
|
subtype=Beast
|
||||||
|
power=2
|
||||||
|
toughness=4
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ifh-Biff Efreet
|
||||||
|
text=Flying -- {G}: Ifh-Biff Efreet deals 1 damage to each creature with flying and each player. Any player may activate this ability.
|
||||||
|
mana={2}{G}{G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Efreet
|
||||||
|
power=3
|
||||||
|
toughness=3
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Jeweled Bird
|
||||||
|
text=Remove Jeweled Bird from your deck before playing if you're not playing for ante. -- {T}: Put Jeweled Bird into the ante. If you do, put all other cards you own from the ante into your graveyard, then draw a card.
|
||||||
|
mana={1}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Metamorphosis
|
||||||
|
text=As an additional cost to cast Metamorphosis, sacrifice a creature. -- Add X mana of any one color to your mana pool, where X is one plus the sacrificed creature's converted mana cost. Spend this mana only to cast creature spells.
|
||||||
|
mana={G}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Nafs Asp
|
||||||
|
text=Whenever Nafs Asp deals damage to a player, that player loses 1 life at the beginning of his or her next draw step unless he or she pays {1} before that draw step.
|
||||||
|
mana={G}
|
||||||
|
type=Creature
|
||||||
|
subtype=Snake
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Oubliette
|
||||||
|
text=When Oubliette enters the battlefield, exile target creature and all Auras attached to it. Note the number and kind of counters that were on that creature. -- When Oubliette leaves the battlefield, return the exiled card to the battlefield under its owner's control tapped with the noted number and kind of counters on it. If you do, return the exiled Aura cards to the battlefield under their owner's control attached to that permanent.
|
||||||
|
mana={1}{B}{B}
|
||||||
|
type=Enchantment
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Pyramids
|
||||||
|
text={2}: Choose one — Destroy target Aura attached to a land; or the next time target land would be destroyed this turn, remove all damage marked on it instead.
|
||||||
|
mana={6}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ring of Ma'ruf
|
||||||
|
text={5}, {T}, Exile Ring of Ma'ruf: The next time you would draw a card this turn, instead choose a card you own from outside the game and put it into your hand.
|
||||||
|
mana={5}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sandals of Abdallah
|
||||||
|
text={2}, {T}: Target creature gains islandwalk until end of turn. When that creature dies this turn, destroy Sandals of Abdallah.
|
||||||
|
mana={4}
|
||||||
|
type=Artifact
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Shahrazad
|
||||||
|
text=Players play a MAGIC subgame, using their libraries as their decks. Each player who doesn't win the subgame loses half his or her life, rounded up.
|
||||||
|
mana={W}{W}
|
||||||
|
type=Sorcery
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Sindbad
|
||||||
|
text={T}: Draw a card and reveal it. If it isn't a land card, discard it.
|
||||||
|
mana={1}{U}
|
||||||
|
type=Creature
|
||||||
|
subtype=Human
|
||||||
|
power=1
|
||||||
|
toughness=1
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=War Elephant
|
||||||
|
text=Trample; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
|
||||||
|
mana={3}{W}
|
||||||
|
type=Creature
|
||||||
|
subtype=Elephant
|
||||||
|
power=2
|
||||||
|
toughness=2
|
||||||
|
[/card]
|
||||||
|
[card]
|
||||||
|
name=Ydwen Efreet
|
||||||
|
text=Whenever Ydwen Efreet blocks, flip a coin. If you lose the flip, remove Ydwen Efreet from combat and it can't block this turn. Creatures it was blocking that had become blocked by only Ydwen Efreet this combat become unblocked.
|
||||||
|
mana={R}{R}{R}
|
||||||
|
type=Creature
|
||||||
|
subtype=Efreet
|
||||||
|
power=3
|
||||||
|
toughness=6
|
||||||
|
[/card]
|
||||||