mirror of
https://github.com/flyinghead/flycast.git
synced 2026-11-07 17:11:09 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f13d7ad2dc | ||
|
|
90b06a688b | ||
|
|
1b6b61d253 | ||
|
|
24954ec599 | ||
|
|
c386f64faa | ||
|
|
17db07703e | ||
|
|
75f64efe93 | ||
|
|
ab8b4f0e54 | ||
|
|
0517a4600c | ||
|
|
8e96590065 | ||
|
|
d46b181084 | ||
|
|
3c38fc1f16 | ||
|
|
47b6a90bec | ||
|
|
7438094d7c | ||
|
|
8f486e71cb | ||
|
|
9d6eab74e1 | ||
|
|
a0c81d2f2a | ||
|
|
d6efbc513c | ||
|
|
ed78eb4d50 | ||
|
|
236b747db8 | ||
|
|
c9fafa0ed1 | ||
|
|
4bd8866164 | ||
|
|
f346bcd68b | ||
|
|
187991d71f | ||
|
|
40cdef6c1c | ||
|
|
c7ee42f0ba | ||
|
|
966ff3767d | ||
|
|
056a02357d | ||
|
|
6115a918b2 | ||
|
|
3ffb09ec72 | ||
|
|
de89d8cfed | ||
|
|
c7d6525c51 | ||
|
|
5ce1f92e5c | ||
|
|
464defe0d7 | ||
|
|
d323490d1f | ||
|
|
d8c15de030 | ||
|
|
b55054249f | ||
|
|
0aa8910742 | ||
|
|
43bb7c83f7 | ||
|
|
391da7023f | ||
|
|
960b8134c1 | ||
|
|
5a51749daa | ||
|
|
d2dc60ec00 | ||
|
|
33bcf4443f | ||
|
|
f63a82afc4 | ||
|
|
c052822fd4 | ||
|
|
2846b3002b | ||
|
|
19a240503d | ||
|
|
c9d3096e41 | ||
|
|
d6ae47d0f7 | ||
|
|
40a7c08d14 | ||
|
|
6f8a588794 | ||
|
|
156aafe95b | ||
|
|
1017d3eb95 | ||
|
|
3059b43121 | ||
|
|
93789e2a63 | ||
|
|
6639d6b167 | ||
|
|
daef33cea5 | ||
|
|
a7c89701fe | ||
|
|
9a119e7646 | ||
|
|
c8462e1f78 | ||
|
|
50944772b7 | ||
|
|
952a785bf0 | ||
|
|
f9eed1ed3f | ||
|
|
b7df183c7c | ||
|
|
13edf858e3 | ||
|
|
d45de9e8a9 | ||
|
|
81cbf45bdb | ||
|
|
d340b620c3 | ||
|
|
443d5a2ba6 | ||
|
|
894a38fb71 | ||
|
|
aea37b3bd8 | ||
|
|
bc51aefa9c | ||
|
|
67c4e62c51 | ||
|
|
44fa364f36 | ||
|
|
7029e1615a | ||
|
|
3469b7fca7 | ||
|
|
c146a92f83 | ||
|
|
d4fa3c441e | ||
|
|
47eeab9985 | ||
|
|
be8c559b2f | ||
|
|
51d25bb49b | ||
|
|
6d69598800 | ||
|
|
36684bf82c | ||
|
|
cdaaeb5b27 | ||
|
|
4220c0d64f | ||
|
|
e286f98f72 | ||
|
|
e714e94510 | ||
|
|
8715e5a5e9 | ||
|
|
1153238e2c | ||
|
|
617d82f5a2 | ||
|
|
471e0a7786 | ||
|
|
887e616f76 | ||
|
|
aa2fa1f611 | ||
|
|
57c88e07c4 | ||
|
|
593b3205bd | ||
|
|
ecce9157bd | ||
|
|
b2d96d77d7 | ||
|
|
e1537ddbda | ||
|
|
4c7e57ebd6 | ||
|
|
116dc0e1ed | ||
|
|
10d3ffdf09 | ||
|
|
cbd01fba38 | ||
|
|
88fd2641d9 | ||
|
|
70a69cf48d | ||
|
|
f8d5517b8e | ||
|
|
16b2f59a47 | ||
|
|
07d6ca6c84 | ||
|
|
c9c015976a | ||
|
|
2615cc13f1 | ||
|
|
599dc92d11 | ||
|
|
e26302ef03 | ||
|
|
fd3e74e224 | ||
|
|
5b5d7b01eb | ||
|
|
f6b01aba0c | ||
|
|
19bb4a6e5d | ||
|
|
bc70d9118d | ||
|
|
393c3dbfd9 | ||
|
|
8fd6fefda7 | ||
|
|
a620a432c9 | ||
|
|
9e37d1e726 | ||
|
|
c1b087df83 | ||
|
|
2add951f70 | ||
|
|
070ac717d3 | ||
|
|
cfb7ff3054 | ||
|
|
e03c37b013 | ||
|
|
0b0904cdc5 | ||
|
|
195f401044 | ||
|
|
552e5b7d7a | ||
|
|
2a48049216 | ||
|
|
c001240797 | ||
|
|
e7d0a5f2f9 | ||
|
|
032cc17659 | ||
|
|
c0c6f206bf | ||
|
|
6aa59c54a5 | ||
|
|
9c964ac955 | ||
|
|
5734556440 | ||
|
|
e76b76dcc4 | ||
|
|
cab19ad54b | ||
|
|
a7702c622a | ||
|
|
9f9b29b833 | ||
|
|
06529b63f7 | ||
|
|
0d36154618 | ||
|
|
c7b6f22e10 | ||
|
|
d069b45bff | ||
|
|
4a0ace5de2 | ||
|
|
57c2dcd961 | ||
|
|
790f5b1ad2 | ||
|
|
54ac9c6361 | ||
|
|
449b871e0c | ||
|
|
e057370e97 | ||
|
|
c938f7b0df | ||
|
|
99dc278ad2 | ||
|
|
bccdc6600a | ||
|
|
ba1a68a69f | ||
|
|
363c2c4c3f | ||
|
|
fe429ec01e | ||
|
|
192838b9c1 | ||
|
|
2a19ccf945 | ||
|
|
00954f1b60 | ||
|
|
bf4346c849 | ||
|
|
32502e7459 | ||
|
|
99031e23d3 | ||
|
|
f4f087a6ea | ||
|
|
0433fd824c | ||
|
|
9137ff998f | ||
|
|
7cc77b10ed | ||
|
|
07f208d2a2 | ||
|
|
05cd7ee8d3 | ||
|
|
d8e61520af | ||
|
|
e9beea484d | ||
|
|
4aecdbbb25 | ||
|
|
d7c28a4805 | ||
|
|
939e2bc68f | ||
|
|
ce4a3a7147 | ||
|
|
5fde889d7c | ||
|
|
fd2a87fca2 | ||
|
|
153dbb0c56 | ||
|
|
e53433e6f5 | ||
|
|
db7895cea5 | ||
|
|
f3a774ab4e | ||
|
|
bd25c14cfd | ||
|
|
035ea0b0c0 | ||
|
|
d6593b9c6e | ||
|
|
105ab95efa | ||
|
|
2c711e46fe | ||
|
|
923be3899d | ||
|
|
cb518b5481 | ||
|
|
a18e3701c6 | ||
|
|
2ed4b4a984 | ||
|
|
f11a5981fe | ||
|
|
ea83b08f89 | ||
|
|
b785944560 | ||
|
|
8f3124d14e | ||
|
|
14f3507b86 | ||
|
|
4efacd7d71 | ||
|
|
a9d5b77053 | ||
|
|
bc28c7ccb3 | ||
|
|
f14c29fd04 | ||
|
|
3303ecbbd1 | ||
|
|
c4c4c2fde0 | ||
|
|
78a874d20e | ||
|
|
ef321d81a4 | ||
|
|
df83ca436c | ||
|
|
665ef86cf0 | ||
|
|
b9601d26e3 | ||
|
|
038df0d923 | ||
|
|
73cbd7a183 | ||
|
|
ab25cc73a9 | ||
|
|
a0014bc810 | ||
|
|
6de5879cb4 | ||
|
|
32ecb141df | ||
|
|
4cd90d8ebb | ||
|
|
46eab502e4 | ||
|
|
535fbe29f8 | ||
|
|
41723a831f | ||
|
|
abe1d4fd27 | ||
|
|
dda04e63fa | ||
|
|
e60f30b357 | ||
|
|
f0f27558af | ||
|
|
0f6a92caad | ||
|
|
9a60cd7ded | ||
|
|
926877397c | ||
|
|
b92277ac58 | ||
|
|
9a7bf75e4e | ||
|
|
1253e1199d | ||
|
|
51508dcdc6 | ||
|
|
f6b3577de5 | ||
|
|
a4ec706c79 | ||
|
|
cb890c7b6f | ||
|
|
dbfead6a15 | ||
|
|
fd3f207e45 | ||
|
|
594b403997 | ||
|
|
bafe07de85 | ||
|
|
3e047a6e03 | ||
|
|
29c0dca0ce | ||
|
|
5cfd3f0ba3 | ||
|
|
923dcf10a7 | ||
|
|
7b71bd319c | ||
|
|
51089c5e0a | ||
|
|
24944e00a7 | ||
|
|
66faf0d330 | ||
|
|
c0de126b2b | ||
|
|
c1f0a5a15f | ||
|
|
f640b32cc9 | ||
|
|
93e47dd410 | ||
|
|
8fb3def2d5 | ||
|
|
98a0f2b821 | ||
|
|
4fafa91506 | ||
|
|
09a1fea40f | ||
|
|
e55d70c0e6 | ||
|
|
ca45ff3834 | ||
|
|
35c71ebcfd | ||
|
|
33edcca348 | ||
|
|
dac5b991e0 | ||
|
|
8ba5e05421 | ||
|
|
35b7be3905 | ||
|
|
b7d923e02b | ||
|
|
eaf2c0064c | ||
|
|
a65cd9e5f9 | ||
|
|
e94b26f1df | ||
|
|
e96b38ff5c | ||
|
|
e894d4df5c | ||
|
|
c58ae4daac | ||
|
|
cb9af7d742 | ||
|
|
2a364dee67 | ||
|
|
56107b3667 | ||
|
|
31aab32d95 | ||
|
|
0b66409ed2 | ||
|
|
8ae288d2ca | ||
|
|
4419ff310a | ||
|
|
2f524923da | ||
|
|
07d761a880 | ||
|
|
f6f6637973 | ||
|
|
2cd3ffb33f | ||
|
|
abd9219347 | ||
|
|
417a42ae10 | ||
|
|
0e12153c45 | ||
|
|
cb33387ed6 | ||
|
|
38d4689b63 | ||
|
|
23d1db9c75 | ||
|
|
4e079b5d0b | ||
|
|
3fcbdd3fc5 | ||
|
|
78b44919c5 | ||
|
|
13a8d49c90 | ||
|
|
7308f9a704 | ||
|
|
18f9b84af6 | ||
|
|
56517b027a | ||
|
|
d4a02e3c2b | ||
|
|
33131e1395 | ||
|
|
73ac46f421 | ||
|
|
7fc70ee1f4 | ||
|
|
d9b5f27311 | ||
|
|
252838d896 | ||
|
|
cb91ad3ae0 | ||
|
|
60f3d718ac | ||
|
|
e8e382372a | ||
|
|
205c365b1b | ||
|
|
09857008bd | ||
|
|
5eddc26850 | ||
|
|
496429d6f4 | ||
|
|
a915f185f8 | ||
|
|
0f6e1752e3 | ||
|
|
e57ccde532 | ||
|
|
f75a16f40c | ||
|
|
a869e183db | ||
|
|
c60edb0090 | ||
|
|
84d82f360b | ||
|
|
b002bdff39 | ||
|
|
5ffcdb5f1e | ||
|
|
79bbd86c2f | ||
|
|
39a212140a | ||
|
|
dddd712f08 | ||
|
|
a7dbbbe578 | ||
|
|
2445739c0e | ||
|
|
403f1f635b | ||
|
|
879372cb79 | ||
|
|
6b05c0ab01 | ||
|
|
289f264371 | ||
|
|
869ddb643d | ||
|
|
c63f1a9997 | ||
|
|
0fc0dc5101 | ||
|
|
213bc70e2d | ||
|
|
c839bc89eb | ||
|
|
84f2871650 | ||
|
|
e1b4d4d703 | ||
|
|
b564b0bf91 | ||
|
|
7e1dcf9003 | ||
|
|
0f4c903fed | ||
|
|
0ac483acfc | ||
|
|
f4835a89d3 | ||
|
|
139f248572 | ||
|
|
b23d37f76f | ||
|
|
56358be542 | ||
|
|
1377e61d03 | ||
|
|
ce694ba8b5 | ||
|
|
8eae6b97fc | ||
|
|
d29645cc49 | ||
|
|
f870ccc23c | ||
|
|
3aa2f922e7 | ||
|
|
129fff1c2a | ||
|
|
10b13dfe9c | ||
|
|
d506cc40a2 | ||
|
|
358a54152b | ||
|
|
06e2c455e8 | ||
|
|
a1838eee30 | ||
|
|
56b082def7 | ||
|
|
92a10ba0f0 | ||
|
|
c637ae8281 | ||
|
|
40953b17c4 | ||
|
|
a473154250 | ||
|
|
13f3c3e228 | ||
|
|
817cc87c8c | ||
|
|
ab09efa762 | ||
|
|
7061c043d9 | ||
|
|
92a19e9250 | ||
|
|
4f5fd31d81 | ||
|
|
1b565f9879 | ||
|
|
d2b475ae41 | ||
|
|
9c61006941 | ||
|
|
4db26bc092 | ||
|
|
8c0f543bc8 | ||
|
|
8e3a48eb6f | ||
|
|
7a22318b0f | ||
|
|
a0bf24f7cc | ||
|
|
3c6eaa4d34 | ||
|
|
3bf817aea1 | ||
|
|
a3ebe02f85 | ||
|
|
4eda9ebffc | ||
|
|
278f26aadd | ||
|
|
17b82ab5d3 | ||
|
|
30e66d1c17 | ||
|
|
2089015221 | ||
|
|
e19a62aa07 | ||
|
|
42d003597e | ||
|
|
f9da57d87f | ||
|
|
daf8230cca | ||
|
|
f02265b662 | ||
|
|
5eb893a995 | ||
|
|
dfd517706a | ||
|
|
b47f4f56ef | ||
|
|
a870fb7f6c | ||
|
|
7cd308fcae | ||
|
|
6e6f75386b | ||
|
|
aad4921e09 | ||
|
|
8b8113b482 | ||
|
|
98acd1178d | ||
|
|
0070f9abad | ||
|
|
dca048981f | ||
|
|
74b98d85ed | ||
|
|
67a7637b9f | ||
|
|
2511a19d2d | ||
|
|
f04ddad94f | ||
|
|
b4e5af6346 | ||
|
|
f679fd9ba9 | ||
|
|
b6930a2a9e | ||
|
|
4db7137dbf | ||
|
|
bee534922b | ||
|
|
d6fe46649c | ||
|
|
236539c881 | ||
|
|
2644c2ef47 | ||
|
|
f590766421 | ||
|
|
fa1c62d11a | ||
|
|
ffc0a42c18 | ||
|
|
bc3c1ab628 | ||
|
|
6c249ee4d2 | ||
|
|
3330f01267 | ||
|
|
bd946bfbea | ||
|
|
bb92e9f7a4 | ||
|
|
63686eeee1 | ||
|
|
c0a286532a | ||
|
|
ce0354f294 | ||
|
|
231a1b624f | ||
|
|
9b8fd39d12 | ||
|
|
90c4e42c11 | ||
|
|
ee806bc035 | ||
|
|
d76611730e | ||
|
|
bdd677d66a | ||
|
|
2299c9fade | ||
|
|
885714e883 | ||
|
|
f95c7212bf | ||
|
|
bb0da9488f | ||
|
|
1aeacb0297 | ||
|
|
b92b7a3ece | ||
|
|
0a1fe0135f | ||
|
|
4391058563 | ||
|
|
ea9bdd03e4 | ||
|
|
ed99c96232 | ||
|
|
755e17dc97 | ||
|
|
76af42ae6e | ||
|
|
e94babe57e | ||
|
|
416e4c5366 | ||
|
|
6b9840268f | ||
|
|
415d8c2ea3 | ||
|
|
3f456c6738 | ||
|
|
59480ea5a6 | ||
|
|
920666bc70 | ||
|
|
eebcb322cf | ||
|
|
04b0489ff3 | ||
|
|
dd5f44ff91 | ||
|
|
a7b89ba06a | ||
|
|
e5344d37d0 | ||
|
|
c07f862ef2 | ||
|
|
8b0add47a2 | ||
|
|
fe9ce46ab1 | ||
|
|
01c5c98396 | ||
|
|
d00f07acb8 | ||
|
|
83bfa9158d | ||
|
|
ac2637286b | ||
|
|
541544292a | ||
|
|
97bd3fc082 | ||
|
|
71ce2a2415 | ||
|
|
4b0d377e66 | ||
|
|
ae2bc8182f | ||
|
|
d9ec14e048 | ||
|
|
c0f0a758df | ||
|
|
06270e66c8 | ||
|
|
75fe707de3 | ||
|
|
1a5a2f64d4 | ||
|
|
220fd51b27 | ||
|
|
29cdc77817 | ||
|
|
483c59f2e4 | ||
|
|
1fdab613fd | ||
|
|
539b9e7746 | ||
|
|
045f693eef | ||
|
|
3192f84576 | ||
|
|
27038d4cf9 | ||
|
|
4acb670b88 | ||
|
|
79b9b49218 | ||
|
|
5f161df06b | ||
|
|
fc3b9046d8 | ||
|
|
754d2a53a0 | ||
|
|
e913bae9e3 | ||
|
|
22d228c1b0 | ||
|
|
d3a3cab425 | ||
|
|
1fe7352ed0 | ||
|
|
9d1a5cf0d3 | ||
|
|
c8a45d95a7 | ||
|
|
92a1c1891b | ||
|
|
858174791f | ||
|
|
fb4e653269 | ||
|
|
210100a108 | ||
|
|
edd1487378 | ||
|
|
68f4ce1ec5 | ||
|
|
c3c355a8c5 | ||
|
|
70d3e221a9 | ||
|
|
b556617e1d | ||
|
|
e327172fd0 | ||
|
|
c5f82483e6 | ||
|
|
a418b05272 | ||
|
|
5c3f66fe05 | ||
|
|
81ce3f7d10 | ||
|
|
64cfba735e | ||
|
|
8828b4fe52 | ||
|
|
87fdd203b5 | ||
|
|
187674ddac | ||
|
|
f94a08f12f | ||
|
|
252ad711f1 | ||
|
|
9d6bfd4786 | ||
|
|
d3690b12c6 | ||
|
|
32e08ca165 | ||
|
|
bc4f8fbe60 | ||
|
|
fd3deeb318 | ||
|
|
7108358ebd | ||
|
|
98daea0e97 | ||
|
|
48acb03b81 | ||
|
|
08ac485eac | ||
|
|
c033a81eca | ||
|
|
5df9127add | ||
|
|
b9e9cc534c | ||
|
|
79be464326 | ||
|
|
f67aad0b2d | ||
|
|
55b36fe719 | ||
|
|
7cce77cccd | ||
|
|
170f794c3a | ||
|
|
ae4bd79ca1 | ||
|
|
d76982bbeb | ||
|
|
fb4229c4ae | ||
|
|
caec338d25 | ||
|
|
b94200233d | ||
|
|
eb3ebe24e8 | ||
|
|
4514a4bfcc | ||
|
|
5e4e48fffe | ||
|
|
47a33f97f9 | ||
|
|
b36ef9da1e | ||
|
|
068861d0cc | ||
|
|
f2f8f3ccd2 | ||
|
|
2d7a1ce71a | ||
|
|
74d72eb257 | ||
|
|
9512ee657a | ||
|
|
78f80eb7dc | ||
|
|
fa525b4488 | ||
|
|
ee3e83e09c | ||
|
|
ea4354ba2e | ||
|
|
5c5c872afc | ||
|
|
9f2ffd102c | ||
|
|
34f8941868 | ||
|
|
07b217d9f8 | ||
|
|
cb83d319b9 | ||
|
|
23daa3efdf | ||
|
|
3a1ffceb58 | ||
|
|
f3431bd95d | ||
|
|
01c7250be2 | ||
|
|
e6bc36e110 | ||
|
|
afc1f5f4e1 | ||
|
|
4a2ad8b145 | ||
|
|
17ab0aba26 | ||
|
|
cc1b45b7cc | ||
|
|
4d990947de | ||
|
|
5542d6db21 | ||
|
|
8ca89ead0e | ||
|
|
ebf5f24487 | ||
|
|
90269d5204 | ||
|
|
e4332f6275 | ||
|
|
cd7168772d | ||
|
|
77ded80450 | ||
|
|
fbc69b6ae1 | ||
|
|
ea7dd699b9 | ||
|
|
018a852995 | ||
|
|
8a28ddbfe6 | ||
|
|
f186046c98 | ||
|
|
5644e834fa | ||
|
|
0b1f69bfd2 | ||
|
|
4eb5cd928e | ||
|
|
b8d47fe0a8 | ||
|
|
abcd9d77d4 | ||
|
|
095e5ede81 | ||
|
|
52754cbbbb | ||
|
|
ea9d048bc9 | ||
|
|
942224c685 | ||
|
|
670a25b039 | ||
|
|
cab02c86bc | ||
|
|
b4a67460e0 | ||
|
|
b56750df30 | ||
|
|
aa5fd64777 | ||
|
|
5a13b4df28 | ||
|
|
67bba95dd1 | ||
|
|
cd6152b193 | ||
|
|
67c070c20f | ||
|
|
2355bb8bb5 | ||
|
|
c4d24254db | ||
|
|
27b6bafd0f | ||
|
|
9cbdcc6260 | ||
|
|
192bbb715e | ||
|
|
014da3a225 | ||
|
|
803f4cd298 | ||
|
|
885a0508c0 | ||
|
|
a1472fb190 | ||
|
|
b86df7217c | ||
|
|
26815d042a | ||
|
|
026f21eddf | ||
|
|
30501aebb1 | ||
|
|
4014b1b574 | ||
|
|
8d54382b10 | ||
|
|
47dd8241b6 | ||
|
|
195da2adcc | ||
|
|
2b430eec6f | ||
|
|
d51e36998b | ||
|
|
a970a1263c | ||
|
|
cf9ccea70b | ||
|
|
f885cbb4ea | ||
|
|
97dfabc416 | ||
|
|
8d2b0749a0 | ||
|
|
a3acf4a8cc | ||
|
|
e505ab6019 | ||
|
|
9b24984b07 | ||
|
|
7ce08ea860 | ||
|
|
a156edbd73 | ||
|
|
9dae5827cc | ||
|
|
5da799244f | ||
|
|
bf79183bd6 | ||
|
|
afcb3b7ad8 | ||
|
|
5bfbcb210c | ||
|
|
4f65d45e55 | ||
|
|
3f8ecfedbb | ||
|
|
d8137a967c | ||
|
|
ffec935e2f | ||
|
|
253301ba4f | ||
|
|
69d2cfd56d | ||
|
|
0f90293252 | ||
|
|
0d166e1403 | ||
|
|
b5879e6e1d | ||
|
|
5b169b7f9d | ||
|
|
099a758c94 | ||
|
|
638e5d233a | ||
|
|
cacfdbad90 | ||
|
|
811bf6f449 | ||
|
|
43f8f3e4ad | ||
|
|
debe21de7b | ||
|
|
084066bde7 | ||
|
|
46d7dfc750 | ||
|
|
37c17e4300 | ||
|
|
d3aed076a6 | ||
|
|
c461624a67 | ||
|
|
e6060aff6b | ||
|
|
d1e6ee9cd7 | ||
|
|
6480a6e4e5 | ||
|
|
301a7c5dcd | ||
|
|
e70a0dcf3d | ||
|
|
d1ab3461a6 | ||
|
|
b81a6762bc | ||
|
|
04c418d02a | ||
|
|
27ea6ca092 | ||
|
|
cb94354099 | ||
|
|
53dab29ddb | ||
|
|
b1479e6e34 | ||
|
|
ea3262f7b0 | ||
|
|
143073b61d | ||
|
|
c472d60f80 | ||
|
|
0c01075ba8 | ||
|
|
1149d499a8 | ||
|
|
99d5266aa0 | ||
|
|
45c9d6185b | ||
|
|
e18a4afcbb | ||
|
|
499f86b065 | ||
|
|
1c4871acb3 | ||
|
|
3b683648fa | ||
|
|
3923f10277 | ||
|
|
1a681746b5 | ||
|
|
5703ef26cf | ||
|
|
5096d50d37 | ||
|
|
31debefbe1 | ||
|
|
c7d214e55a | ||
|
|
8cdd171ab7 | ||
|
|
9473c235f2 | ||
|
|
b443467770 | ||
|
|
a6bf9dd39c | ||
|
|
458b233e16 | ||
|
|
528f15f117 | ||
|
|
7c72aa8a80 | ||
|
|
2420c05930 | ||
|
|
3a312f3814 | ||
|
|
bac67bd91a | ||
|
|
36e67203a4 | ||
|
|
a52d1c97ec | ||
|
|
ac24d9be5b | ||
|
|
a0e800f102 | ||
|
|
7e4572a86a | ||
|
|
4f0d3a958d | ||
|
|
06c5ba7f0e |
No files matched your search
-14
@@ -1,14 +0,0 @@
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-1
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
CIRRUS_CLONE_SUBMODULES: true
|
||||
|
||||
task:
|
||||
install_script: pkg install -y alsa-lib ccache cmake evdev-proto git libao libevdev libudev-devd libzip mesa-libs miniupnpc ninja pkgconf png pulseaudio sdl2
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache
|
||||
script:
|
||||
- cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
- cmake --build build --config Release
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
custom: ['https://utip.io/flyinghead', 'https://www.paypal.com/paypalme/FlycastEmu']
|
||||
buy_me_a_coffee: hhwtpernwq
|
||||
custom: ['https://www.paypal.com/paypalme/FlycastEmu']
|
||||
@@ -12,32 +12,30 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install ccache libcurl4-openssl-dev ninja-build
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
cache: 'gradle'
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: android-ccache-${{ github.sha }}
|
||||
restore-keys: android-ccache-
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: android-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: android-gradle-
|
||||
|
||||
- name: Gradle
|
||||
working-directory: shell/android-studio
|
||||
run: ./gradlew assembleRelease --parallel
|
||||
env:
|
||||
SENTRY_UPLOAD_URL: ${{ secrets.SENTRY_UPLOAD_URL }}
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: flycast-release.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/release/flycast-release.apk
|
||||
@@ -52,7 +50,7 @@ jobs:
|
||||
- name: Extract symbols
|
||||
run: |
|
||||
DUMP_SYMS=./core/deps/breakpad/bin/dump_syms
|
||||
SO_DIR=shell/android-studio/flycast/build/intermediates/cmake/release/obj
|
||||
SO_DIR=shell/android-studio/flycast/build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib
|
||||
for arch in arm64-v8a armeabi-v7a x86 x86_64 ; do
|
||||
$DUMP_SYMS $SO_DIR/$arch/libflycast.so > libflycast.so.sym
|
||||
BUILD_ID=`head -1 libflycast.so.sym | awk '{ print $4 }'`
|
||||
@@ -62,7 +60,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
@@ -74,7 +72,7 @@ jobs:
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
|
||||
- name: Setup Sentry CLI
|
||||
uses: mathieu-bour/setup-sentry-cli@1.2.0
|
||||
uses: mathieu-bour/setup-sentry-cli@v2
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
with:
|
||||
@@ -82,6 +80,7 @@ jobs:
|
||||
token: ${{ env.SENTRY_TOKEN }}
|
||||
organization: flycast
|
||||
project: minidump
|
||||
version: 2.21.2
|
||||
if: ${{ env.SENTRY_TOKEN != '' }}
|
||||
|
||||
- name: Upload symbols to Sentry
|
||||
@@ -89,7 +88,7 @@ jobs:
|
||||
VERSION=$(git describe --tags --always)
|
||||
sentry-cli releases new "$VERSION"
|
||||
sentry-cli releases set-commits "$VERSION" --auto
|
||||
sentry-cli upload-dif symbols
|
||||
sentry-cli debug-files upload symbols
|
||||
shell: bash
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
name: BSD CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
operating_system: [ freebsd, netbsd, openbsd ]
|
||||
architecture: [ arm64, x86-64 ]
|
||||
include:
|
||||
- operating_system: freebsd
|
||||
version: '14.0'
|
||||
pkginstall: sudo pkg install -y alsa-lib ccache cmake evdev-proto git libao libevdev libudev-devd libzip miniupnpc ninja pkgconf pulseaudio sdl2
|
||||
- operating_system: netbsd
|
||||
version: '9.3'
|
||||
pkginstall: sudo pkgin update && sudo pkgin -y install alsa-lib ccache cmake gcc12 git libao libzip miniupnpc ninja-build pkgconf pulseaudio SDL2 && export PATH=/usr/pkg/gcc12/bin:$PATH
|
||||
- operating_system: openbsd
|
||||
version: '7.4'
|
||||
pkginstall: sudo pkg_add ccache cmake git libao libzip miniupnpc ninja pkgconf pulseaudio sdl2
|
||||
exclude:
|
||||
- architecture: arm64
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ccache-${{ matrix.operating_system }}-${{ matrix.architecture }}-${{ github.sha }}
|
||||
restore-keys: ccache-${{ matrix.operating_system }}-${{ matrix.architecture }}-
|
||||
|
||||
- uses: cross-platform-actions/[email protected]
|
||||
with:
|
||||
operating_system: ${{ matrix.operating_system }}
|
||||
architecture: ${{ matrix.architecture }}
|
||||
version: ${{ matrix.version }}
|
||||
environment_variables: CCACHE_DIR
|
||||
run: |
|
||||
${{ matrix.pkginstall }}
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
cmake --build build --config Release
|
||||
+13
-11
@@ -29,14 +29,15 @@ jobs:
|
||||
steps:
|
||||
- name: Set up build environment (macOS)
|
||||
run: |
|
||||
sudo xcode-select -switch /Applications/Xcode_15.3.app
|
||||
# Unlink and re-link to prevent errors when github mac runner images install python outside of brew. See https://github.com/actions/setup-python/issues/577
|
||||
brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done
|
||||
brew update
|
||||
brew update || :
|
||||
brew install libao ldid ninja pulseaudio
|
||||
VULKAN_VER=1.3.224.1 && aria2c --parameterized-uri=true https://{sdk.lunarg.com/sdk/download/$VULKAN_VER/mac,distfiles.macports.org/MoltenVK}/vulkansdk-macos-$VULKAN_VER.dmg
|
||||
hdiutil attach ./vulkansdk-macos-*.dmg
|
||||
sudo /Volumes/vulkansdk-macos-*/InstallVulkan.app/Contents/MacOS/InstallVulkan --root $HOME/VulkanSDK --accept-licenses --default-answer --confirm-command install
|
||||
hdiutil detach /Volumes/vulkansdk-macos-*
|
||||
VULKAN_VER=1.3.261.1 && aria2c https://sdk.lunarg.com/sdk/download/$VULKAN_VER/mac/vulkansdk-macos-$VULKAN_VER.dmg
|
||||
hdiutil attach ./vulkansdk-macos-*.dmg -mountpoint /Volumes/VulkanSDK
|
||||
sudo /Volumes/VulkanSDK/InstallVulkan.app/Contents/MacOS/InstallVulkan --root $HOME/VulkanSDK --accept-licenses --default-answer --confirm-command install
|
||||
hdiutil detach /Volumes/VulkanSDK
|
||||
echo "VULKAN_SDK=$HOME/VulkanSDK/macOS" >> $GITHUB_ENV
|
||||
if: runner.os == 'macOS'
|
||||
|
||||
@@ -66,7 +67,7 @@ jobs:
|
||||
arch: ${{ matrix.config.arch }}
|
||||
if: matrix.config.shell == 'cmd'
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
@@ -79,7 +80,7 @@ jobs:
|
||||
run: ./shell/apple/emulator-ios/OpenMP/build_ios_openmp.sh --disableSimulator
|
||||
if: matrix.config.name == 'apple-ios'
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ccache-${{ matrix.config.name }}-${{ github.sha }}
|
||||
@@ -125,7 +126,7 @@ jobs:
|
||||
rm artifact/bin/flycast
|
||||
if: matrix.config.name == 'x86_64-pc-linux-gnu'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: flycast-${{ matrix.config.name }}
|
||||
path: artifact/bin
|
||||
@@ -144,7 +145,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
@@ -157,7 +158,7 @@ jobs:
|
||||
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
|
||||
|
||||
- name: Setup Sentry CLI
|
||||
uses: mathieu-bour/setup-sentry-cli@1.2.0
|
||||
uses: mathieu-bour/setup-sentry-cli@v2
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
with:
|
||||
@@ -165,6 +166,7 @@ jobs:
|
||||
token: ${{ env.SENTRY_TOKEN }}
|
||||
organization: flycast
|
||||
project: minidump
|
||||
version: 2.21.2
|
||||
if: ${{ env.SENTRY_TOKEN != '' }}
|
||||
|
||||
- name: Upload symbols to Sentry (Windows, macOS, Linux)
|
||||
@@ -172,7 +174,7 @@ jobs:
|
||||
VERSION=$(git describe --tags --always)
|
||||
sentry-cli releases new "$VERSION"
|
||||
sentry-cli releases set-commits "$VERSION" --auto
|
||||
sentry-cli upload-dif symbols
|
||||
sentry-cli debug-files upload symbols
|
||||
shell: bash
|
||||
env:
|
||||
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Upload Source
|
||||
shell: bash
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup Java JDK
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 18
|
||||
distribution: zulu
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
|
||||
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
git commit -m "Fetch translations & Recreate libretro_core_options_intl.h"
|
||||
|
||||
- name: GitHub Push
|
||||
uses: ad-m/github-push-action@v0.6.0
|
||||
uses: ad-m/github-push-action@v0.8.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
@@ -6,7 +6,7 @@ jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ubuntu-latest
|
||||
container: devkitpro/devkita64:20220128
|
||||
container: devkitpro/devkita64:latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -18,14 +18,17 @@ jobs:
|
||||
- name: Set up build environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install awscli ccache ninja-build
|
||||
sudo apt-get -y install awscli ccache
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- name: Mark git repository as safe
|
||||
run: git config --global --add safe.directory $PWD
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-switch-${{ matrix.config.name }}-${{ github.sha }}
|
||||
@@ -36,7 +39,7 @@ jobs:
|
||||
$DEVKITPRO/portlibs/switch/bin/aarch64-none-elf-cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=artifact -G Ninja ${{ matrix.config.cmakeArgs }}
|
||||
cmake --build build --config Release --target install
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: flycast-switch-${{ matrix.config.name }}
|
||||
path: artifact/bin
|
||||
@@ -47,7 +50,7 @@ jobs:
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
|
||||
@@ -6,31 +6,16 @@ jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg/bincache
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: bootstrap vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
mkdir vcpkg\bincache
|
||||
vcpkg\bootstrap-vcpkg.bat
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ env.VCPKG_DEFAULT_BINARY_CACHE }}
|
||||
key: vcpkg-${{ hashFiles( 'vcpkg.json' ) }}
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.22000.0 -DCMAKE_SYSTEM_PROCESSOR=AMD64 -DCMAKE_CROSSCOMPILING=OFF -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake
|
||||
cmake --build build --config Release --parallel 2
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.22000.0
|
||||
cmake --build build --config Release -- /m
|
||||
shell: cmd
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
@@ -49,14 +34,14 @@ jobs:
|
||||
run: signtool sign /f shell\uwp\sign_cert.pfx /p '${{ secrets.SIGN_CERT_PWD }}' /v /fd SHA256 build\artifact\flycast.appx
|
||||
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: flycast-uwp
|
||||
path: build/artifact
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
id: aws-credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
|
||||
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
build/
|
||||
artifact/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
@@ -6,8 +7,13 @@ shell/apple/emulator-ios/OpenMP/OpenMP.xcframework
|
||||
|
||||
# Visual Studio
|
||||
.vs/
|
||||
.vscode/
|
||||
out/
|
||||
|
||||
# JetBrains IDES
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
|
||||
# Dependencies from .gitmodules
|
||||
core/deps/breakpad/
|
||||
core/deps/glslang/
|
||||
+25
-1
@@ -19,7 +19,7 @@
|
||||
.core-defs-osx-x64:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release
|
||||
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64
|
||||
EXTRA_PATH: Release
|
||||
|
||||
.core-defs-osx-arm64:
|
||||
@@ -28,6 +28,11 @@
|
||||
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release
|
||||
EXTRA_PATH: Release
|
||||
|
||||
.core-defs-ios-arm64:
|
||||
extends: .core-defs
|
||||
variables:
|
||||
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
.core-defs-android:
|
||||
extends: .core-defs
|
||||
script:
|
||||
@@ -62,11 +67,19 @@ include:
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/android-cmake.yml'
|
||||
|
||||
# iOS arm64
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios-cmake.yml'
|
||||
|
||||
################################## CONSOLES ################################
|
||||
# Nintendo Switch
|
||||
# - project: 'libretro-infrastructure/ci-templates'
|
||||
# file: '/libnx-static.yml'
|
||||
|
||||
# tvOS arm64
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/tvos-cmake.yml'
|
||||
|
||||
# Stages for building
|
||||
stages:
|
||||
- build-prepare
|
||||
@@ -139,9 +152,20 @@ android-x86:
|
||||
- .libretro-android-cmake-x86
|
||||
- .core-defs-android
|
||||
|
||||
libretro-build-ios-arm64:
|
||||
extends:
|
||||
- .libretro-ios-cmake-arm64
|
||||
- .core-defs-ios-arm64
|
||||
|
||||
################################### CONSOLES #################################
|
||||
# Nintendo Switch
|
||||
#libretro-build-libnx-aarch64:
|
||||
# extends:
|
||||
# - .libretro-libnx-static-retroarch-master
|
||||
# - .core-defs
|
||||
|
||||
# tvOS arm64
|
||||
libretro-build-tvos-arm64:
|
||||
extends:
|
||||
- .libretro-tvos-cmake-arm64
|
||||
- .core-defs-ios-arm64
|
||||
@@ -4,6 +4,7 @@
|
||||
[submodule "core/deps/libchdr"]
|
||||
path = core/deps/libchdr
|
||||
url = https://github.com/rtissera/libchdr.git
|
||||
ignore = dirty
|
||||
[submodule "core/deps/luabridge"]
|
||||
path = core/deps/luabridge
|
||||
url = https://github.com/vinniefalco/LuaBridge.git
|
||||
@@ -22,3 +23,9 @@
|
||||
[submodule "core/deps/oboe"]
|
||||
path = core/deps/oboe
|
||||
url = https://github.com/google/oboe.git
|
||||
[submodule "core/deps/Syphon"]
|
||||
path = core/deps/Syphon
|
||||
url = https://github.com/vkedwardli/Syphon-Framework.git
|
||||
[submodule "core/deps/Spout"]
|
||||
path = core/deps/Spout
|
||||
url = https://github.com/vkedwardli/Spout2.git
|
||||
+320
-184
@@ -6,6 +6,48 @@ if(CCACHE_PROGRAM)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM} CACHE STRING "Compiler launcher for CXX.")
|
||||
endif()
|
||||
|
||||
set(SENTRY_UPLOAD_URL "" CACHE STRING "Sentry upload URL")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/shell/cmake")
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum iOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL tvOS)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum tvOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum macOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBRETRO)
|
||||
project(flycast_libretro)
|
||||
else()
|
||||
project(flycast)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if(NINTENDO_SWITCH)
|
||||
set(CMAKE_CXX_EXTENSIONS ON)
|
||||
else()
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
|
||||
include(DetectArchitecture)
|
||||
if(NOT DEFINED ARCHITECTURE)
|
||||
message(FATAL_ERROR "Unsupported architecture encountered. Ending CMake generation.")
|
||||
endif()
|
||||
message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||
|
||||
set(USE_HOST_SDL_DEFAULT OFF)
|
||||
if(NOT APPLE AND (NOT UNIX OR CMAKE_SYSTEM_NAME MATCHES "(FreeBSD|OpenBSD|NetBSD)"))
|
||||
set(USE_HOST_SDL_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
option(ENABLE_CTEST "Enables unit tests" OFF)
|
||||
option(ENABLE_OPROFILE "Enable OProfile" OFF)
|
||||
option(TEST_AUTOMATION "Enable test automation" OFF)
|
||||
@@ -13,7 +55,9 @@ option(ENABLE_LOG "Enable full logging" OFF)
|
||||
option(ASAN "Enable address sanitizer" OFF)
|
||||
option(USE_GLES "Use GLES[3] API" OFF)
|
||||
option(USE_GLES2 "Use GLES2 API" OFF)
|
||||
option(USE_HOST_GLSLANG "Use host glslang" OFF)
|
||||
option(USE_HOST_LIBZIP "Use host libzip" ON)
|
||||
option(USE_HOST_SDL "Use host SDL library" ${USE_HOST_SDL_DEFAULT})
|
||||
option(USE_OPENMP "Use OpenMP if available" ON)
|
||||
option(USE_VULKAN "Build with Vulkan support" ON)
|
||||
option(USE_DX9 "Build with Direct3D 9 support" ON)
|
||||
@@ -26,28 +70,12 @@ option(ENABLE_GDB_SERVER "Build with GDB debugging support" OFF)
|
||||
option(ENABLE_DC_PROFILER "Build with support for target machine (SH4) profiler" OFF)
|
||||
option(ENABLE_FC_PROFILER "Build with support for host app (Flycast) profiler" OFF)
|
||||
|
||||
set(SENTRY_UPLOAD_URL "" CACHE STRING "Sentry upload URL")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/shell/cmake")
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum iOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
|
||||
set(USE_VULKAN OFF CACHE BOOL "Force vulkan off" FORCE)
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum macOS deployment version")
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBRETRO)
|
||||
project(flycast_libretro)
|
||||
else()
|
||||
project(flycast)
|
||||
if(IOS AND NOT LIBRETRO)
|
||||
set(USE_VULKAN OFF CACHE BOOL "Force vulkan off" FORCE)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(CMakeRC)
|
||||
|
||||
if(ENABLE_CTEST)
|
||||
include(CTest)
|
||||
@@ -73,7 +101,7 @@ if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(WINDOWS_STORE)
|
||||
string(REPLACE "v" "" MS_VERSION ${GIT_VERSION})
|
||||
string(REGEX REPLACE "[Vv]" "" MS_VERSION ${GIT_VERSION})
|
||||
string(REPLACE "-" "." MS_VERSION ${MS_VERSION})
|
||||
string(REGEX REPLACE "\.g[0-9a-f]+" "" MS_VERSION ${MS_VERSION})
|
||||
string(REGEX MATCH "[0-9]+\.[0-9]+\.[0-9]+" VERSION_3PARTS ${MS_VERSION})
|
||||
@@ -95,11 +123,12 @@ if(NINTENDO_SWITCH)
|
||||
if(LIBRETRO)
|
||||
add_library(${PROJECT_NAME} STATIC core/emulator.cpp)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LIBRETRO HAVE_LIBNX HAVE_OPENGL HAVE_OIT)
|
||||
find_path(GLEXT_H_INCLUDE_DIR NAMES GL/glext.h REQUIRED)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${GLEXT_H_INCLUDE_DIR})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "flycast_libretro_libnx")
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "")
|
||||
else()
|
||||
add_executable(${PROJECT_NAME} core/emulator.cpp)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE EGL_NO_PLATFORM_SPECIFIC_TYPES)
|
||||
endif()
|
||||
if(USE_GLES)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES)
|
||||
@@ -108,18 +137,31 @@ if(NINTENDO_SWITCH)
|
||||
elseif(LIBRETRO)
|
||||
add_library(${PROJECT_NAME} SHARED core/emulator.cpp)
|
||||
if(APPLE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
|
||||
if(NOT IOS)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
|
||||
endif()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/shell/libretro/libretro.osx.def")
|
||||
else()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "flycast_libretro")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "flycast_libretro"
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
||||
)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LIBRETRO)
|
||||
if(APPLE)
|
||||
find_library(FOUNDATION Foundation)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${FOUNDATION})
|
||||
endif()
|
||||
if(ANDROID OR USE_GLES)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES3 HAVE_OPENGLES HAVE_OPENGLES3)
|
||||
find_library(GLES3_LIBRARIES NAMES GLESv3 GLESv2 NO_CACHE REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${GLES3_LIBRARIES})
|
||||
elseif(IOS)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES3 HAVE_OPENGLES HAVE_OPENGLES3)
|
||||
find_library(OPENGLES OpenGLES)
|
||||
find_library(GLKIT GLKit)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENGLES} ${GLKIT})
|
||||
elseif(USE_GLES2)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES2 HAVE_OPENGLES HAVE_OPENGLES2)
|
||||
if(USE_VIDEOCORE)
|
||||
@@ -136,9 +178,6 @@ elseif(LIBRETRO)
|
||||
else()
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_OIT)
|
||||
endif()
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "-lopengl32")
|
||||
endif()
|
||||
endif()
|
||||
elseif(ANDROID)
|
||||
add_library(${PROJECT_NAME} SHARED core/emulator.cpp)
|
||||
@@ -148,8 +187,14 @@ elseif(ANDROID)
|
||||
set(CMAKE_ANDROID_STL_TYPE "c++_static")
|
||||
elseif(WIN32)
|
||||
add_executable(${PROJECT_NAME} WIN32 core/emulator.cpp)
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
if(NOT CMAKE_VS_GLOBALS MATCHES "(^|;)UseMultiToolTask=")
|
||||
list(APPEND CMAKE_VS_GLOBALS UseMultiToolTask=true)
|
||||
endif()
|
||||
if(NOT CMAKE_VS_GLOBALS MATCHES "(^|;)EnforceProcessCountAcrossBuilds=")
|
||||
list(APPEND CMAKE_VS_GLOBALS EnforceProcessCountAcrossBuilds=true)
|
||||
endif()
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
add_executable(${PROJECT_NAME} MACOSX_BUNDLE core/emulator.cpp)
|
||||
@@ -160,13 +205,9 @@ endif()
|
||||
if(WINDOWS_STORE)
|
||||
set(USE_OPENGL OFF)
|
||||
set(USE_VULKAN OFF)
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE c_std_11 cxx_std_17)
|
||||
else()
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE c_std_11 cxx_std_11)
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
CXX_EXTENSIONS OFF
|
||||
LINK_FLAGS_RELEASE -s)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE -s)
|
||||
if(MSVC)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /GR /GS-)
|
||||
if(WINDOWS_STORE)
|
||||
@@ -178,36 +219,46 @@ else()
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wall>)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_OSX_SYSROOT} MATCHES "\/MacOSX.platform\/Developer\/SDKs")
|
||||
set(TARGET_MAC ON)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
$<$<BOOL:APPLE>:GL_SILENCE_DEPRECATION>
|
||||
$<$<BOOL:MSVC>:_CRT_NONSTDC_NO_WARNINGS>
|
||||
$<$<BOOL:MSVC>:_CRT_SECURE_NO_WARNINGS>
|
||||
$<$<BOOL:MSVC>:_USE_MATH_DEFINES>
|
||||
$<$<BOOL:MSVC>:NOMINMAX>
|
||||
$<$<BOOL:${APPLE}>:GL_SILENCE_DEPRECATION>
|
||||
$<$<BOOL:${ENABLE_LOG}>:DEBUGFAST>
|
||||
$<$<BOOL:${IOS}>:TARGET_IPHONE>
|
||||
$<$<BOOL:${TARGET_MAC}>:TARGET_MAC>
|
||||
$<$<BOOL:${IOS}>:GLES>
|
||||
$<$<BOOL:${IOS}>:GLES3>
|
||||
$<$<BOOL:${IOS}>:GLES_SILENCE_DEPRECATION>
|
||||
$<$<BOOL:${MSVC}>:_CRT_NONSTDC_NO_WARNINGS>
|
||||
$<$<BOOL:${MSVC}>:_CRT_SECURE_NO_WARNINGS>
|
||||
$<$<BOOL:${MSVC}>:_WINSOCK_DEPRECATED_NO_WARNING>
|
||||
$<$<BOOL:${MSVC}>:NOMINMAX>
|
||||
$<$<BOOL:${TEST_AUTOMATION}>:TEST_AUTOMATION>
|
||||
$<$<BOOL:${ENABLE_LOG}>:DEBUGFAST>)
|
||||
if(IOS)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
TARGET_IPHONE
|
||||
GLES
|
||||
GLES3
|
||||
GLES_SILENCE_DEPRECATION)
|
||||
$<$<BOOL:${WINDOWS_STORE}>:NOCRYPT>
|
||||
$<$<OR:$<BOOL:${MINGW}>,$<BOOL:${MSVC}>>:_USE_MATH_DEFINES>)
|
||||
|
||||
if(UNIX AND NOT ANDROID AND NOT APPLE)
|
||||
execute_process(COMMAND getconf PAGESIZE OUTPUT_VARIABLE PAGE_SIZE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE PAGE_SIZE=${PAGE_SIZE})
|
||||
endif()
|
||||
|
||||
if(NOT "${SENTRY_UPLOAD_URL}" STREQUAL "")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE SENTRY_UPLOAD="${SENTRY_UPLOAD_URL}")
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core core/deps core/deps/stb core/khronos core/deps/json)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core core/deps core/deps/stb core/deps/json)
|
||||
if(LIBRETRO)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE shell/libretro)
|
||||
endif()
|
||||
if(NINTENDO_SWITCH)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE shell/switch "${DEVKITPRO}/portlibs/switch/include")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE shell/switch)
|
||||
endif()
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
if((WIN32 AND NOT MSVC) OR (UNIX AND NOT APPLE AND NOT CMAKE_SYSTEM_NAME MATCHES "(FreeBSD|OpenBSD|NetBSD)"))
|
||||
find_program(SH_EXECUTABLE sh)
|
||||
if((ANDROID AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") OR (MINGW AND SH_EXECUTABLE) OR (CMAKE_SYSTEM_NAME STREQUAL "Linux"))
|
||||
add_subdirectory(core/deps/breakpad)
|
||||
if(WIN32)
|
||||
target_link_options(${PROJECT_NAME} PRIVATE "-Wl,--build-id")
|
||||
@@ -333,14 +384,20 @@ add_subdirectory(core/deps/glm)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
||||
|
||||
if(USE_VULKAN)
|
||||
option(BUILD_EXTERNAL "Build external dependencies in /External" OFF)
|
||||
option(SKIP_GLSLANG_INSTALL "Skip installation" ON)
|
||||
option(ENABLE_SPVREMAPPER "Enables building of SPVRemapper" OFF)
|
||||
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" OFF)
|
||||
option(ENABLE_HLSL "Enables HLSL input support" OFF)
|
||||
option(ENABLE_PCH "Enables Precompiled header" OFF)
|
||||
add_subdirectory(core/deps/glslang EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SPIRV)
|
||||
if(USE_HOST_GLSLANG)
|
||||
find_package(glslang REQUIRED)
|
||||
else()
|
||||
option(BUILD_EXTERNAL "Build external dependencies in /External" OFF)
|
||||
option(SKIP_GLSLANG_INSTALL "Skip installation" ON)
|
||||
option(ENABLE_SPVREMAPPER "Enables building of SPVRemapper" OFF)
|
||||
option(ENABLE_GLSLANG_BINARIES "Builds glslang and spirv-remap" OFF)
|
||||
option(ENABLE_HLSL "Enables HLSL input support" OFF)
|
||||
option(ENABLE_PCH "Enables Precompiled header" OFF)
|
||||
add_subdirectory(core/deps/glslang EXCLUDE_FROM_ALL)
|
||||
add_library(glslang::glslang-default-resource-limits ALIAS glslang-default-resource-limits)
|
||||
add_library(glslang::SPIRV ALIAS SPIRV)
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glslang::glslang-default-resource-limits glslang::SPIRV)
|
||||
endif()
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
@@ -356,10 +413,11 @@ if(NOT LIBRETRO)
|
||||
endif()
|
||||
|
||||
if(NOT ANDROID AND NOT IOS)
|
||||
if(NOT APPLE AND (NOT UNIX OR CMAKE_SYSTEM_NAME MATCHES "(FreeBSD|OpenBSD|NetBSD)"))
|
||||
find_package(SDL2)
|
||||
if(USE_HOST_SDL)
|
||||
find_package(SDL2 2.0.9)
|
||||
endif()
|
||||
if(NOT SDL2_FOUND)
|
||||
set(SDL_TEST_ENABLED_BY_DEFAULT OFF)
|
||||
add_subdirectory(core/deps/SDL EXCLUDE_FROM_ALL)
|
||||
set(SDL2_FOUND 1)
|
||||
endif()
|
||||
@@ -394,7 +452,7 @@ if(NOT LIBRETRO)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ZLIB::ZLIB)
|
||||
endif()
|
||||
|
||||
find_package(Lua)
|
||||
find_package(Lua 5.2)
|
||||
if(NOT APPLE AND LUA_FOUND)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_LUA)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${LUA_INCLUDE_DIR} core/deps/luabridge/Source)
|
||||
@@ -408,13 +466,15 @@ target_link_libraries(${PROJECT_NAME} PRIVATE chdr-static)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/libchdr/include)
|
||||
|
||||
if(NOT WITH_SYSTEM_ZLIB)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/core/deps/libchdr/deps/zlib-1.2.11")
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE zlib)
|
||||
set(ZLIB_RELATIVE_PATH "core/deps/libchdr/deps/zlib-1.3.1")
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_RELATIVE_PATH}" "${CMAKE_CURRENT_BINARY_DIR}/${ZLIB_RELATIVE_PATH}")
|
||||
# help libzip find the package
|
||||
set(ZLIB_FOUND TRUE)
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/core/deps/libchdr/deps/zlib-1.2.11")
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_RELATIVE_PATH}" "${CMAKE_CURRENT_BINARY_DIR}/${ZLIB_RELATIVE_PATH}")
|
||||
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
get_target_property(ZLIB_LIBRARY zlib LOCATION)
|
||||
get_target_property(ZLIB_LIBRARY_RELEASE zlibstatic LOCATION)
|
||||
get_target_property(ZLIB_LIBRARY_DEBUG zlibstatic LOCATION_Debug)
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig)
|
||||
@@ -464,11 +524,6 @@ if(PKG_CONFIG_FOUND AND NOT ANDROID AND NOT APPLE AND NOT LIBRETRO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NINTENDO_SWITCH AND USE_GLES)
|
||||
pkg_check_modules(GLESV2 IMPORTED_TARGET glesv2)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::GLESV2)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE AND NOT ANDROID)
|
||||
add_definitions(
|
||||
-DFLYCAST_DATADIR="${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/"
|
||||
@@ -480,25 +535,14 @@ if(UNIX AND NOT APPLE AND NOT ANDROID)
|
||||
if(USE_VIDEOCORE)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "-lbrcmGLESv2")
|
||||
target_link_directories(${PROJECT_NAME} PRIVATE "/opt/vc/lib")
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE GLESv2)
|
||||
endif()
|
||||
elseif(USE_GLES)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GLES GLES3)
|
||||
if(NOT SDL2_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE EGL)
|
||||
endif()
|
||||
find_library(GLES3_LIBRARIES NAMES GLESv3 GLESv2 NO_CACHE REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${GLES3_LIBRARIES})
|
||||
elseif(USE_OPENGL)
|
||||
set(OpenGL_GL_PREFERENCE LEGACY)
|
||||
find_package(OpenGL REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE OpenGL::GL)
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*" AND NOT LIBRETRO)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND "x86_64" IN_LIST ARCHITECTURE AND NOT LIBRETRO)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE False)
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.14.0")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
|
||||
@@ -512,8 +556,6 @@ if(UNIX AND NOT APPLE AND NOT ANDROID)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${X11_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${X11_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE EGL_NO_X11)
|
||||
endif()
|
||||
|
||||
find_library(LIBRT rt)
|
||||
@@ -534,6 +576,13 @@ if(ASAN)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID AND "arm" IN_LIST ARCHITECTURE)
|
||||
enable_language(ASM)
|
||||
option(LIBUNWIND_ENABLE_SHARED "Build libunwind as a shared library." OFF)
|
||||
add_subdirectory(core/deps/libunwind/libunwind)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE unwind_static)
|
||||
endif()
|
||||
|
||||
if(ANDROID AND NOT LIBRETRO)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(core/deps/oboe)
|
||||
@@ -545,7 +594,8 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/chdpsr/cdipsr.cpp
|
||||
core/deps/chdpsr/cdipsr.h)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/nowide/include)
|
||||
add_subdirectory(core/deps/nowide EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE nowide::nowide)
|
||||
|
||||
if(NOT MINIUPNP_FOUND)
|
||||
if(NINTENDO_SWITCH)
|
||||
@@ -581,8 +631,7 @@ if(NOT LIBZIP_FOUND OR NINTENDO_SWITCH)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
option(LIBZIP_DO_INSTALL "Install libzip and the related files" OFF)
|
||||
add_subdirectory(core/deps/libzip)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/libzip/lib)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE zip)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE libzip::zip)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@@ -651,15 +700,20 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE _7ZIP_ST)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/lzma/7zArcIn.c core/deps/lzma/7zBuf.c core/deps/lzma/7zCrc.c core/deps/lzma/7zCrcOpt.c core/deps/lzma/7zDec.c core/deps/lzma/7zFile.c core/deps/lzma/7zStream.c core/deps/lzma/Alloc.c core/deps/lzma/Bcj2.c core/deps/lzma/Bra86.c core/deps/lzma/Bra.c core/deps/lzma/BraIA64.c core/deps/lzma/CpuArch.c core/deps/lzma/Delta.c core/deps/lzma/LzFind.c core/deps/lzma/Lzma2Dec.c core/deps/lzma/Lzma86Dec.c core/deps/lzma/Lzma86Enc.c core/deps/lzma/LzmaDec.c core/deps/lzma/LzmaEnc.c core/deps/lzma/LzmaLib.c core/deps/lzma/Sort.c)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/libelf/elf32.cpp core/deps/libelf/elf64.cpp core/deps/libelf/elf.cpp)
|
||||
add_subdirectory(core/deps/libelf)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE elf)
|
||||
if(NOT LIBRETRO)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE IMGUI_DISABLE_DEMO_WINDOWS)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/imgui core/deps/imgui/backends)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/imgui/imgui.cpp
|
||||
core/deps/imgui/imgui_demo.cpp
|
||||
core/deps/imgui/imgui_draw.cpp
|
||||
core/deps/imgui/imgui_tables.cpp
|
||||
core/deps/imgui/imgui_widgets.cpp)
|
||||
|
||||
if(ENABLE_FC_PROFILER)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/implot)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/implot/implot.h
|
||||
core/deps/implot/implot.cpp
|
||||
@@ -670,6 +724,9 @@ endif()
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/xbrz/xbrz.cpp)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/md5/md5.cpp)
|
||||
|
||||
cmrc_add_resource_library(flycast-resources ALIAS flycast::res NAMESPACE flycast)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE flycast::res)
|
||||
|
||||
if(LIBRETRO)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/libretro-common/include)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
@@ -686,7 +743,7 @@ if(LIBRETRO)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/libretro-common/glsm/glsm.c
|
||||
core/deps/libretro-common/glsym/rglgen.c)
|
||||
if(ANDROID OR USE_GLES)
|
||||
if(ANDROID OR IOS OR USE_GLES)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/libretro-common/glsym/glsym_es3.c)
|
||||
elseif(USE_GLES2)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/deps/libretro-common/glsym/glsym_es2.c)
|
||||
@@ -706,6 +763,9 @@ if(LIBRETRO)
|
||||
shell/libretro/option.cpp
|
||||
shell/libretro/oslib.cpp
|
||||
shell/libretro/vmu_xhair.cpp)
|
||||
if(APPLE)
|
||||
target_sources(${PROJECT_NAME} PRIVATE shell/libretro/oslib_apple.mm)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
@@ -760,8 +820,14 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/bba/bba.cpp
|
||||
core/hw/bba/rtl8139c.h
|
||||
core/hw/bba/rtl8139c.cpp
|
||||
core/hw/flashrom/at93cxx.cpp
|
||||
core/hw/flashrom/at93cxx.h
|
||||
core/hw/flashrom/flashrom.cpp
|
||||
core/hw/flashrom/flashrom.h
|
||||
core/hw/flashrom/nvmem.cpp
|
||||
core/hw/flashrom/nvmem.h
|
||||
core/hw/flashrom/x76f100.cpp
|
||||
core/hw/flashrom/x76f100.h
|
||||
core/hw/gdrom/gdrom_if.h
|
||||
core/hw/gdrom/gdrom_response.cpp
|
||||
core/hw/gdrom/gdromv3.cpp
|
||||
@@ -781,8 +847,8 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/maple/maple_if.cpp
|
||||
core/hw/maple/maple_if.h
|
||||
core/hw/maple/maple_jvs.cpp
|
||||
core/hw/mem/_vmem.cpp
|
||||
core/hw/mem/_vmem.h
|
||||
core/hw/mem/addrspace.cpp
|
||||
core/hw/mem/addrspace.h
|
||||
core/hw/mem/mem_watch.cpp
|
||||
core/hw/mem/mem_watch.h
|
||||
core/hw/modem/modem.cpp
|
||||
@@ -799,6 +865,8 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/naomi/m1cartridge.h
|
||||
core/hw/naomi/m4cartridge.cpp
|
||||
core/hw/naomi/m4cartridge.h
|
||||
core/hw/naomi/multiboard.h
|
||||
core/hw/naomi/multiboard.cpp
|
||||
core/hw/naomi/naomi_cart.cpp
|
||||
core/hw/naomi/naomi_cart.h
|
||||
core/hw/naomi/naomi_flashrom.cpp
|
||||
@@ -811,12 +879,21 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/naomi/naomi_roms.cpp
|
||||
core/hw/naomi/naomi_roms.h
|
||||
core/hw/naomi/naomi_roms_input.h
|
||||
core/hw/naomi/netdimm.cpp
|
||||
core/hw/naomi/netdimm.h
|
||||
core/hw/naomi/card_reader.h
|
||||
core/hw/naomi/card_reader.cpp
|
||||
core/hw/naomi/touchscreen.h
|
||||
core/hw/naomi/touchscreen.cpp
|
||||
core/hw/naomi/printer.h
|
||||
core/hw/naomi/printer.cpp
|
||||
core/hw/naomi/systemsp.h
|
||||
core/hw/naomi/systemsp.cpp
|
||||
core/hw/naomi/hopper.h
|
||||
core/hw/naomi/hopper.cpp
|
||||
core/hw/pvr/elan.cpp
|
||||
core/hw/pvr/elan.h
|
||||
core/hw/pvr/elan_struct.h
|
||||
core/hw/pvr/helper_classes.h
|
||||
core/hw/pvr/pvr.cpp
|
||||
core/hw/pvr/pvr.h
|
||||
core/hw/pvr/pvr_mem.cpp
|
||||
@@ -872,6 +949,8 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/sh4/modules/ubc.cpp
|
||||
core/hw/sh4/modules/wince.h
|
||||
core/hw/sh4/sh4_cache.h
|
||||
core/hw/sh4/sh4_cycles.cpp
|
||||
core/hw/sh4/sh4_cycles.h
|
||||
core/hw/sh4/sh4_core.h
|
||||
core/hw/sh4/sh4_core_regs.cpp
|
||||
core/hw/sh4/sh4_if.h
|
||||
@@ -887,7 +966,47 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/hw/sh4/sh4_rom.cpp
|
||||
core/hw/sh4/sh4_rom.h
|
||||
core/hw/sh4/sh4_sched.cpp
|
||||
core/hw/sh4/sh4_sched.h)
|
||||
core/hw/sh4/sh4_sched.h
|
||||
core/hw/sh4/storeq.cpp)
|
||||
|
||||
cmrc_add_resources(flycast-resources
|
||||
WHENCE resources
|
||||
resources/flash/alienfnt.nvmem.zip # network settings
|
||||
resources/flash/gunsur2.nvmem.zip
|
||||
resources/flash/mazan.nvmem.zip # free play, calibrated
|
||||
resources/flash/otrigger.nvmem.zip
|
||||
resources/flash/wldkicks.nvmem.zip # free play
|
||||
resources/flash/wldkicksj.nvmem.zip # free play
|
||||
resources/flash/wldkicksu.nvmem.zip # free play
|
||||
resources/flash/f355.nvmem.zip # printer on
|
||||
resources/flash/f355twin.nvmem.zip # printer on
|
||||
resources/flash/f355twn2.nvmem.zip # printer on
|
||||
resources/flash/dirtypig.nvmem.zip # 4 players
|
||||
resources/flash/dirtypig.nvmem2.zip
|
||||
resources/flash/vf4.nvmem.zip # card all day, stage select
|
||||
resources/flash/vf4evob.nvmem.zip # card all day, stage select
|
||||
resources/flash/vf4tuned.nvmem.zip # card all day, stage select, 45 sec time limit, 3 match
|
||||
resources/flash/magicpop.nvmem.zip # debug: comm and all errors disabled
|
||||
resources/flash/ochaken.nvmem.zip # debug: comm and all errors disabled
|
||||
resources/flash/puyomedal.nvmem.zip # debug: comm and all errors disabled
|
||||
resources/flash/unomedal.nvmem.zip # debug: comm and all errors disabled
|
||||
resources/flash/westdrmg.nvmem.zip # debug: comm and all errors disabled
|
||||
resources/picture/f355_print_template.png)
|
||||
|
||||
cmrc_add_resources(flycast-resources
|
||||
fonts/printer_ascii8x16.bin.zip
|
||||
fonts/printer_ascii12x24.bin.zip
|
||||
fonts/printer_kanji16x16.bin.zip
|
||||
fonts/printer_kanji24x24.bin.zip)
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
cmrc_add_resources(flycast-resources fonts/Roboto-Medium.ttf.zip)
|
||||
if(ANDROID)
|
||||
cmrc_add_resources(flycast-resources
|
||||
WHENCE resources
|
||||
resources/picture/buttons.png)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/imgread/cdi.cpp
|
||||
@@ -930,7 +1049,10 @@ else()
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/linux/libnx_vmem.cpp
|
||||
shell/switch/stubs.c
|
||||
shell/switch/context_switch.S)
|
||||
shell/switch/context_switch.S
|
||||
shell/switch/nswitch.h
|
||||
shell/switch/switch_gamepad.h
|
||||
shell/switch/ucontext.h)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -961,6 +1083,8 @@ if(NOT LIBRETRO)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/network/alienfnt_modem.cpp
|
||||
core/network/alienfnt_modem.h
|
||||
core/network/dns.cpp
|
||||
core/network/ggpo.cpp
|
||||
core/network/ggpo.h
|
||||
@@ -983,25 +1107,31 @@ endif()
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/oslib/audiobackend_alsa.cpp
|
||||
core/oslib/audiobackend_coreaudio.cpp
|
||||
core/oslib/audiobackend_directsound.cpp
|
||||
core/oslib/audiobackend_libao.cpp
|
||||
core/oslib/audiobackend_null.cpp
|
||||
core/oslib/audiobackend_oboe.cpp
|
||||
core/oslib/audiobackend_omx.cpp
|
||||
core/oslib/audiobackend_oss.cpp
|
||||
core/oslib/audiobackend_pulseaudio.cpp
|
||||
core/oslib/audiobackend_sdl2.cpp
|
||||
core/oslib/audiostream.cpp
|
||||
core/audio/audiobackend_alsa.cpp
|
||||
core/audio/audiobackend_coreaudio.cpp
|
||||
core/audio/audiobackend_directsound.cpp
|
||||
core/audio/audiobackend_libao.cpp
|
||||
core/audio/audiobackend_null.cpp
|
||||
core/audio/audiobackend_oboe.cpp
|
||||
core/audio/audiobackend_omx.cpp
|
||||
core/audio/audiobackend_oss.cpp
|
||||
core/audio/audiobackend_pulseaudio.cpp
|
||||
core/audio/audiobackend_sdl2.cpp
|
||||
core/audio/audiostream.cpp
|
||||
core/oslib/oslib.cpp)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/oslib/audiostream.h
|
||||
core/audio/audiostream.h
|
||||
core/oslib/directory.h
|
||||
core/oslib/host_context.h
|
||||
core/oslib/oslib.h
|
||||
core/oslib/resources.cpp
|
||||
core/oslib/resources.h
|
||||
core/oslib/storage.cpp
|
||||
core/oslib/storage.h
|
||||
core/oslib/unwind_info.h
|
||||
core/oslib/virtmem.h
|
||||
core/lua/lua.cpp
|
||||
core/lua/lua.h)
|
||||
|
||||
@@ -1021,19 +1151,16 @@ if (ENABLE_FC_PROFILER)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE FC_PROFILER)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rec-cpp/rec_cpp.cpp)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/reios/descrambl.cpp
|
||||
core/reios/descrambl.h
|
||||
core/reios/font.h
|
||||
core/reios/gdrom_hle.cpp
|
||||
core/reios/gdrom_hle.h
|
||||
core/reios/reios.cpp
|
||||
core/reios/reios.h
|
||||
core/reios/reios_elf.cpp
|
||||
core/reios/reios_elf.h)
|
||||
cmrc_add_resources(flycast-resources fonts/biosfont.bin.zip)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/wsi/context.h
|
||||
@@ -1051,20 +1178,7 @@ if(USE_OPENGL)
|
||||
core/wsi/osx.cpp
|
||||
core/wsi/osx.h
|
||||
core/wsi/sdl.cpp
|
||||
core/wsi/sdl.h
|
||||
core/wsi/wgl.cpp
|
||||
core/wsi/wgl.h
|
||||
core/wsi/xgl.cpp
|
||||
core/wsi/xgl.h)
|
||||
|
||||
if(NOT APPLE AND NOT LIBRETRO)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/wsi/gl32funcs.c
|
||||
core/wsi/gl32funcs.h)
|
||||
endif()
|
||||
if(NOT (NINTENDO_SWITCH AND LIBRETRO))
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/wsi/gl4funcs.cpp)
|
||||
endif()
|
||||
core/wsi/sdl.h)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/gles/glcache.h
|
||||
@@ -1080,8 +1194,8 @@ if(USE_OPENGL)
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/gles/imgui_impl_opengl3.cpp
|
||||
core/rend/gles/imgui_impl_opengl3.h
|
||||
core/deps/imgui/backends/imgui_impl_opengl3.cpp
|
||||
core/deps/imgui/backends/imgui_impl_opengl3.h
|
||||
core/rend/gles/opengl_driver.cpp
|
||||
core/rend/gles/opengl_driver.h)
|
||||
endif()
|
||||
@@ -1155,15 +1269,16 @@ if(USE_VULKAN)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC VK_USE_PLATFORM_WIN32_KHR)
|
||||
elseif(APPLE)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC VK_USE_PLATFORM_MACOS_MVK)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC VK_USE_PLATFORM_METAL_EXT)
|
||||
endif()
|
||||
|
||||
add_subdirectory(core/deps/Vulkan-Headers)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Headers)
|
||||
|
||||
add_library(VulkanMemoryAllocator INTERFACE)
|
||||
add_subdirectory(core/deps/VulkanMemoryAllocator)
|
||||
target_compile_definitions(VulkanMemoryAllocator INTERFACE $<$<BOOL:${APPLE}>:VMA_USE_STL_SHARED_MUTEX=0>) # Only available on macOS 10.12+
|
||||
target_compile_options(VulkanMemoryAllocator INTERFACE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:AppleClang,Clang>>:-Wno-nullability-completeness>)
|
||||
target_include_directories(VulkanMemoryAllocator INTERFACE core/deps/VulkanMemoryAllocator/include)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE VulkanMemoryAllocator)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE GPUOpen::VulkanMemoryAllocator)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_VULKAN HAVE_VULKAN)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
@@ -1179,6 +1294,7 @@ if(USE_VULKAN)
|
||||
core/rend/vulkan/oit/oit_shaders.h
|
||||
core/rend/vulkan/buffer.cpp
|
||||
core/rend/vulkan/buffer.h
|
||||
core/rend/vulkan/commandpool.cpp
|
||||
core/rend/vulkan/commandpool.h
|
||||
core/rend/vulkan/compiler.cpp
|
||||
core/rend/vulkan/compiler.h
|
||||
@@ -1209,15 +1325,15 @@ if(USE_VULKAN)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/vulkan/vulkan_driver.h
|
||||
core/rend/vulkan/vulkan_context.cpp
|
||||
core/rend/vulkan/imgui_impl_vulkan.cpp
|
||||
core/rend/vulkan/imgui_impl_vulkan.h)
|
||||
core/deps/imgui/backends/imgui_impl_vulkan.cpp
|
||||
core/deps/imgui/backends/imgui_impl_vulkan.h)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE ImTextureID=ImU64)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32 AND USE_DX9 AND NOT LIBRETRO AND NOT WINDOWS_STORE)
|
||||
if(WIN32 AND USE_DX9 AND NOT LIBRETRO AND NOT WINDOWS_STORE AND ("x86" IN_LIST ARCHITECTURE OR "x86_64" IN_LIST ARCHITECTURE))
|
||||
set(REND_DX9_FILES
|
||||
core/rend/dx9/d3d_overlay.h
|
||||
core/rend/dx9/d3d_overlay.cpp
|
||||
@@ -1230,28 +1346,21 @@ if(WIN32 AND USE_DX9 AND NOT LIBRETRO AND NOT WINDOWS_STORE)
|
||||
core/rend/dx9/dx9_driver.h
|
||||
core/rend/dx9/dxcontext.cpp
|
||||
core/rend/dx9/dxcontext.h
|
||||
core/rend/dx9/imgui_impl_dx9.h
|
||||
core/rend/dx9/imgui_impl_dx9.cpp)
|
||||
core/deps/imgui/backends/imgui_impl_dx9.h
|
||||
core/deps/imgui/backends/imgui_impl_dx9.cpp)
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${REND_DX9_FILES})
|
||||
|
||||
if(NOT MINGW)
|
||||
set_source_files_properties(${REND_DX9_FILES} PROPERTIES INCLUDE_DIRECTORIES "$ENV{DXSDK_DIR}/Include")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
target_link_directories(${PROJECT_NAME} PUBLIC "$ENV{DXSDK_DIR}/Lib/x64")
|
||||
else()
|
||||
target_link_directories(${PROJECT_NAME} PUBLIC "$ENV{DXSDK_DIR}/Lib/x86")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_DX9)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC d3d9 d3dx9)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND USE_DX11)
|
||||
if(NOT LIBRETRO)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/dx11/imgui_impl_dx11.cpp
|
||||
core/rend/dx11/imgui_impl_dx11.h)
|
||||
core/deps/imgui/backends/imgui_impl_dx11.cpp
|
||||
core/deps/imgui/backends/imgui_impl_dx11.h)
|
||||
endif()
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rend/dx11/dx11_driver.h
|
||||
@@ -1278,7 +1387,7 @@ if(WIN32 AND USE_DX11)
|
||||
core/rend/dx11/oit/dx11_oitshaders.h)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_D3D11)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE d3d11 d3dcompiler)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE d3d11 d3dcompiler dxgi)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GDB_SERVER)
|
||||
@@ -1289,7 +1398,10 @@ if(ENABLE_GDB_SERVER)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GDB_SERVER)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)" AND NOT APPLE)
|
||||
if("arm" IN_LIST ARCHITECTURE AND NOT APPLE)
|
||||
if(MSVC)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE "/Zc:__cplusplus")
|
||||
endif()
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/vixl)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/rec-ARM/rec_arm.cpp
|
||||
@@ -1305,8 +1417,6 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)" AND NOT APPLE)
|
||||
core/deps/vixl/aarch32/macro-assembler-aarch32.h
|
||||
core/deps/vixl/aarch32/operands-aarch32.cc
|
||||
core/deps/vixl/aarch32/operands-aarch32.h
|
||||
core/deps/vixl/aarch32/disasm-aarch32.cc
|
||||
core/deps/vixl/aarch32/disasm-aarch32.h
|
||||
core/deps/vixl/assembler-base-vixl.h
|
||||
core/deps/vixl/code-buffer-vixl.cc
|
||||
core/deps/vixl/code-buffer-vixl.h
|
||||
@@ -1323,35 +1433,28 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)" AND NOT APPLE)
|
||||
core/deps/vixl/pool-manager-impl.h
|
||||
core/deps/vixl/utils-vixl.cc
|
||||
core/deps/vixl/utils-vixl.h)
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*)" OR CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
|
||||
if("arm64" IN_LIST ARCHITECTURE)
|
||||
if(MSVC)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE "/Zc:__cplusplus")
|
||||
endif()
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/vixl)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/vixl/aarch64/abi-aarch64.h
|
||||
core/deps/vixl/aarch64/assembler-aarch64.cc
|
||||
core/deps/vixl/aarch64/assembler-aarch64.h
|
||||
core/deps/vixl/aarch64/assembler-sve-aarch64.cc
|
||||
core/deps/vixl/aarch64/constants-aarch64.h
|
||||
core/deps/vixl/aarch64/cpu-aarch64.cc
|
||||
core/deps/vixl/aarch64/cpu-aarch64.h
|
||||
core/deps/vixl/aarch64/cpu-features-auditor-aarch64.cc
|
||||
core/deps/vixl/aarch64/cpu-features-auditor-aarch64.h
|
||||
core/deps/vixl/aarch64/decoder-aarch64.cc
|
||||
core/deps/vixl/aarch64/decoder-aarch64.h
|
||||
core/deps/vixl/aarch64/disasm-aarch64.cc
|
||||
core/deps/vixl/aarch64/disasm-aarch64.h
|
||||
core/deps/vixl/aarch64/instructions-aarch64.cc
|
||||
core/deps/vixl/aarch64/instructions-aarch64.h
|
||||
core/deps/vixl/aarch64/instrument-aarch64.cc
|
||||
core/deps/vixl/aarch64/instrument-aarch64.h
|
||||
core/deps/vixl/aarch64/logic-aarch64.cc
|
||||
core/deps/vixl/aarch64/macro-assembler-aarch64.cc
|
||||
core/deps/vixl/aarch64/macro-assembler-aarch64.h
|
||||
core/deps/vixl/aarch64/macro-assembler-sve-aarch64.cc
|
||||
core/deps/vixl/aarch64/operands-aarch64.cc
|
||||
core/deps/vixl/aarch64/operands-aarch64.h
|
||||
core/deps/vixl/aarch64/registers-aarch64.cc
|
||||
core/deps/vixl/aarch64/registers-aarch64.h
|
||||
core/deps/vixl/aarch64/pointer-auth-aarch64.cc
|
||||
core/deps/vixl/aarch64/simulator-aarch64.cc
|
||||
core/deps/vixl/aarch64/simulator-aarch64.h
|
||||
core/deps/vixl/aarch64/simulator-constants-aarch64.h
|
||||
core/deps/vixl/assembler-base-vixl.h
|
||||
core/deps/vixl/code-buffer-vixl.cc
|
||||
@@ -1370,9 +1473,8 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*)" OR CMAKE_OSX_
|
||||
core/deps/vixl/utils-vixl.cc
|
||||
core/deps/vixl/utils-vixl.h)
|
||||
target_sources(${PROJECT_NAME} PRIVATE core/rec-ARM64/rec_arm64.cpp core/rec-ARM64/arm64_regalloc.h)
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|x86_64.*|AMD64.*" OR CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
if("x86" IN_LIST ARCHITECTURE OR "x86_64" IN_LIST ARCHITECTURE)
|
||||
add_subdirectory(core/deps/xbyak EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xbyak::xbyak)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
@@ -1388,10 +1490,16 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|x86_64.*|AMD64.*"
|
||||
core/rec-x64/rec_x64.cpp
|
||||
core/rec-x64/x64_regalloc.h)
|
||||
endif()
|
||||
set(KNOWN_ARCHITECTURE_DETECTED ON)
|
||||
endif()
|
||||
if(NOT KNOWN_ARCHITECTURE_DETECTED)
|
||||
message(FATAL_ERROR "Unknown target processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
if((USE_OPENGL OR USE_GLES2 OR USE_GLES) AND NOT LIBRETRO)
|
||||
add_library(glad STATIC core/deps/glad/src/gl.c)
|
||||
if(NOT APPLE AND NOT WIN32 AND NOT SDL2_FOUND)
|
||||
# When SDL2 is not found, we can use EGL with ANativeWindow (Android), DispmanX (Raspberry Pi) or X11
|
||||
target_sources(glad PRIVATE core/deps/glad/src/egl.c)
|
||||
endif()
|
||||
target_include_directories(glad PUBLIC core/deps/glad/include)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glad)
|
||||
endif()
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
@@ -1440,7 +1548,7 @@ if(NOT LIBRETRO)
|
||||
shell/android-studio/flycast/src/main/jni/src/android_gamepad.h
|
||||
shell/android-studio/flycast/src/main/jni/src/android_keyboard.h)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE android EGL GLESv2 log)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE android log)
|
||||
elseif(APPLE)
|
||||
string(TIMESTAMP YEAR "%Y")
|
||||
string(REGEX MATCH "^[^-]+" TAG_VERSION ${GIT_VERSION})
|
||||
@@ -1506,7 +1614,6 @@ if(NOT LIBRETRO)
|
||||
|
||||
find_library(UIKIT UIKit)
|
||||
find_library(FOUNDATION Foundation)
|
||||
find_library(OPENGLES OpenGLES)
|
||||
find_library(GLKIT GLKit)
|
||||
find_library(GAMECONTROLLER GameController)
|
||||
find_library(AUDIOTOOLBOX AudioToolbox)
|
||||
@@ -1514,7 +1621,6 @@ if(NOT LIBRETRO)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
${UIKIT}
|
||||
${FOUNDATION}
|
||||
${OPENGLES}
|
||||
${GLKIT}
|
||||
${GAMECONTROLLER}
|
||||
${AUDIOTOOLBOX}
|
||||
@@ -1532,10 +1638,24 @@ if(NOT LIBRETRO)
|
||||
COMMAND ldid -S${CMAKE_CURRENT_SOURCE_DIR}/shell/apple/emulator-ios/emulator/flycast.entitlements ${CMAKE_CURRENT_BINARY_DIR}/Payload/Flycast.app/Flycast
|
||||
COMMAND ${CMAKE_COMMAND} -E tar "cfv" "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>-${CMAKE_OSX_SYSROOT}/Flycast.ipa" --format=zip ${CMAKE_CURRENT_BINARY_DIR}/Payload)
|
||||
else()
|
||||
|
||||
add_subdirectory(core/deps/Syphon)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Syphon)
|
||||
if(${CMAKE_GENERATOR} MATCHES "^Xcode.*")
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${SYPHON_METALLIB}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/Flycast.app/Contents/Resources/)
|
||||
else()
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${SYPHON_METALLIB}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/Flycast.app/Contents/Resources/)
|
||||
endif()
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE VIDEO_ROUTING)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
shell/apple/common/http_client.mm
|
||||
shell/apple/emulator-osx/emulator-osx/SDLMain.h
|
||||
shell/apple/emulator-osx/emulator-osx/SDLMain.mm
|
||||
shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.h
|
||||
shell/apple/emulator-osx/emulator-osx/SDLApplicationDelegate.mm
|
||||
shell/apple/emulator-osx/emulator-osx/osx-main.mm)
|
||||
set(ASSETS shell/apple/emulator-osx/emulator-osx/Images.xcassets)
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${ASSETS})
|
||||
@@ -1567,7 +1687,7 @@ if(NOT LIBRETRO)
|
||||
find_library(AUDIO_UNIT_LIBRARY AudioUnit)
|
||||
find_library(FOUNDATION_LIBRARY Foundation)
|
||||
find_library(AUDIO_TOOLBOX_LIBRARY AudioToolbox)
|
||||
find_library(OPENGL_LIBRARY OpenGL)
|
||||
find_library(METAL_LIBRARY Metal)
|
||||
find_library(IOSURFACE_LIBRARY IOSurface)
|
||||
find_library(MULTITOUCH_SUPPORT_LIBRARY MultitouchSupport /System/Library/PrivateFrameworks)
|
||||
|
||||
@@ -1575,7 +1695,7 @@ if(NOT LIBRETRO)
|
||||
${AUDIO_UNIT_LIBRARY}
|
||||
${FOUNDATION_LIBRARY}
|
||||
${AUDIO_TOOLBOX_LIBRARY}
|
||||
${OPENGL_LIBRARY}
|
||||
${METAL_LIBRARY}
|
||||
${IOSURFACE_LIBRARY}
|
||||
${MULTITOUCH_SUPPORT_LIBRARY})
|
||||
|
||||
@@ -1597,11 +1717,10 @@ if(NOT LIBRETRO)
|
||||
elseif(WIN32)
|
||||
if(NOT BUILD_TESTING)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/windows/clock.c
|
||||
core/windows/rawinput.cpp
|
||||
core/windows/rawinput.h
|
||||
core/windows/win_keyboard.h
|
||||
core/windows/winmain.cpp
|
||||
core/windows/xinput_gamepad.h)
|
||||
core/windows/winmain.cpp)
|
||||
endif()
|
||||
if(WINDOWS_STORE)
|
||||
file(READ shell/uwp/Package.appxmanifest MANIFEST)
|
||||
@@ -1622,8 +1741,20 @@ if(NOT LIBRETRO)
|
||||
shell/uwp/http_client.cpp)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES RESOURCE "${ResourceFiles}")
|
||||
else()
|
||||
if("x86" IN_LIST ARCHITECTURE OR "x86_64" IN_LIST ARCHITECTURE)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/Spout/SPOUTSDK/SpoutGL)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/Spout/SPOUTSDK/SpoutDirectX/SpoutDX)
|
||||
SET(SPOUT_BUILD_CMT OFF CACHE BOOL "For Visual Studio - build /MT to link runtime libraries" FORCE)
|
||||
SET(SPOUT_BUILD_SPOUTDX ON CACHE BOOL "Build SpoutDX DirectX11 support library" FORCE)
|
||||
SET(SPOUT_BUILD_LIBRARY OFF CACHE BOOL "Build C-compatible cross compiler library" FORCE)
|
||||
SET(SKIP_INSTALL_ALL ON CACHE BOOL "Install headers and libraries" FORCE)
|
||||
add_subdirectory(core/deps/Spout)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Spout_static SpoutDX_static)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE VIDEO_ROUTING)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE shell/windows/flycast.rc)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE dsound opengl32 winmm ws2_32 wsock32 xinput9_1_0 cfgmgr32 wininet)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE dsound winmm ws2_32 wsock32 xinput9_1_0 cfgmgr32 wininet)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -1640,7 +1771,8 @@ if(BUILD_TESTING)
|
||||
tests/src/test_stubs.cpp
|
||||
tests/src/serialize_test.cpp
|
||||
tests/src/AicaArmTest.cpp
|
||||
tests/src/Sh4InterpreterTest.cpp)
|
||||
tests/src/Sh4InterpreterTest.cpp
|
||||
tests/src/MmuTest.cpp)
|
||||
endif()
|
||||
|
||||
if(NINTENDO_SWITCH)
|
||||
@@ -1649,8 +1781,10 @@ if(NINTENDO_SWITCH)
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:xxHash::xxhash>
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:chdr-static>
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:zip>
|
||||
COMMAND ${CMAKE_AR} -rs flycast_libretro_libnx.a *.obj
|
||||
COMMAND rm *.obj
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:elf>
|
||||
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:flycast::res>
|
||||
COMMAND ${CMAKE_AR} -rs flycast_libretro_libnx.a *.o
|
||||
COMMAND rm *.o
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
|
||||
DEPENDS xxHash::xxhash chdr-static zip ${PROJECT_NAME})
|
||||
else()
|
||||
@@ -1690,5 +1824,7 @@ if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT LIBRETRO)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE SRC_FILES *.h *.cpp *.c *.cc *.mm)
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SRC_FILES})
|
||||
if(${CMAKE_GENERATOR} MATCHES "^Xcode.*|^Visual Studio.*")
|
||||
file(GLOB_RECURSE SRC_FILES *.h *.cpp *.c *.cc *.mm)
|
||||
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SRC_FILES})
|
||||
endif()
|
||||
@@ -4,6 +4,7 @@
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/switch.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml)
|
||||
[](https://github.com/flyinghead/flycast/actions/workflows/bsd.yml)
|
||||
|
||||

|
||||
|
||||
@@ -15,7 +16,7 @@ Join us on our [**Discord server**](https://discord.gg/X8YWP8w) for a chat.
|
||||
|
||||
## Install
|
||||
|
||||
### Flatpak (Linux)
|
||||
### Flatpak (Linux )
|
||||
|
||||
1. [Set up Flatpak](https://www.flatpak.org/setup/).
|
||||
|
||||
@@ -27,7 +28,7 @@ Join us on our [**Discord server**](https://discord.gg/X8YWP8w) for a chat.
|
||||
|
||||
`flatpak run org.flycast.Flycast`
|
||||
|
||||
### Homebrew (MacOS)
|
||||
### Homebrew (MacOS )
|
||||
|
||||
1. [Set up Homebrew](https://brew.sh).
|
||||
|
||||
@@ -35,16 +36,21 @@ Join us on our [**Discord server**](https://discord.gg/X8YWP8w) for a chat.
|
||||
|
||||
`brew install --cask flycast`
|
||||
|
||||
### Xbox One/Series
|
||||
### Xbox One/Series 
|
||||
|
||||
#### Retail:
|
||||
Open [**gamr13's github page**](https://gamr13.github.io/) from your Xbox console.
|
||||
|
||||
#### Dev Mode:
|
||||
Grab the latest build from [**the builds page**](https://flyinghead.github.io/flycast-builds/), or the [**GitHub Actions**](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml). Then install it using the **Xbox Device Portal**.
|
||||
|
||||
### Binaries
|
||||
### Binaries      
|
||||
|
||||
Get fresh builds for your system [**on the builds page**](https://flyinghead.github.io/flycast-builds/).
|
||||
|
||||
**New:** Now automated test results are available as well.
|
||||
|
||||
### Build instructions:
|
||||
```
|
||||
$ git clone --recursive https://github.com/flyinghead/flycast.git`
|
||||
$ cd flycast
|
||||
$ mkdir build && cd build
|
||||
$ cmake ..
|
||||
$ make
|
||||
```
|
||||
+1
-2
@@ -7,11 +7,10 @@ Here lies the core of our codebase. Everything that's OS inspecific rests here.
|
||||
### Some rudimentary categories are:
|
||||
- hw -- DC Hardware Components Implementation
|
||||
- nullDC.cpp -- Main entry points
|
||||
- khronos -- OpenGL and Vulkan headers
|
||||
- oslib -- Audio drivers
|
||||
- cfg -- Configuration backend structure
|
||||
- reios -- (Our) Implementation of the DreamCast BIOS
|
||||
- deps -- External dependencies
|
||||
- imgread -- Content drivers
|
||||
- rec-* -- Recompilers
|
||||
- rend -- OpenGL and Vulkan renderers
|
||||
- rend -- Graphics renderers and UI
|
||||
@@ -23,19 +23,19 @@
|
||||
#include "deps/lzma/7zCrc.h"
|
||||
#include "deps/lzma/Alloc.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define kInputBufSize ((size_t)1 << 18)
|
||||
|
||||
static bool crc_tables_generated;
|
||||
|
||||
bool SzArchive::Open(const char* path)
|
||||
bool SzArchive::Open(FILE *file)
|
||||
{
|
||||
SzArEx_Init(&szarchive);
|
||||
|
||||
File_Close(&archiveStream.file);
|
||||
File_Construct(&archiveStream.file);
|
||||
archiveStream.file.file = nowide::fopen(path, "rb");
|
||||
if (archiveStream.file.file == nullptr)
|
||||
return false;
|
||||
archiveStream.file.file = file;
|
||||
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
LookToRead2_CreateVTable(&lookStream, 0);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "deps/lzma/7zFile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
class SzArchive : public Archive
|
||||
{
|
||||
@@ -38,9 +39,10 @@ public:
|
||||
ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile *OpenFileByCrc(u32 crc) override;
|
||||
|
||||
private:
|
||||
bool Open(const char* path) override;
|
||||
protected:
|
||||
bool Open(FILE *file) override;
|
||||
|
||||
private:
|
||||
CSzArEx szarchive;
|
||||
UInt32 block_idx; /* it can have any value before first call (if outBuffer = 0) */
|
||||
Byte *out_buffer; /* it must be 0 before first call for each new archive. */
|
||||
@@ -53,16 +55,21 @@ private:
|
||||
class SzArchiveFile : public ArchiveFile
|
||||
{
|
||||
public:
|
||||
SzArchiveFile(u8 *data, u32 offset, u32 length) : data(data), offset(offset), length(length) {}
|
||||
SzArchiveFile(u8 *data, u32 offset, u32 length)
|
||||
: data(data), offset(offset), _length(length) {}
|
||||
u32 Read(void *buffer, u32 length) override
|
||||
{
|
||||
length = std::min(length, this->length);
|
||||
length = std::min(length, this->_length);
|
||||
memcpy(buffer, data + offset, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
size_t length() override {
|
||||
return _length;
|
||||
}
|
||||
|
||||
private:
|
||||
u8 *data;
|
||||
u32 offset;
|
||||
u32 length;
|
||||
u32 _length;
|
||||
};
|
||||
+50
-32
@@ -25,11 +25,8 @@ ZipArchive::~ZipArchive()
|
||||
zip_close(zip);
|
||||
}
|
||||
|
||||
bool ZipArchive::Open(const char* path)
|
||||
bool ZipArchive::Open(FILE *file)
|
||||
{
|
||||
FILE *file = nowide::fopen(path, "rb");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
zip_error_t error;
|
||||
zip_source_t *source = zip_source_filep_create(file, 0, -1, &error);
|
||||
if (source == nullptr)
|
||||
@@ -37,7 +34,7 @@ bool ZipArchive::Open(const char* path)
|
||||
std::fclose(file);
|
||||
return false;
|
||||
}
|
||||
zip = zip_open_from_source(source, 0, NULL);
|
||||
zip = zip_open_from_source(source, 0, nullptr);
|
||||
if (zip == nullptr)
|
||||
zip_source_free(source);
|
||||
return zip != nullptr;
|
||||
@@ -45,46 +42,67 @@ bool ZipArchive::Open(const char* path)
|
||||
|
||||
ArchiveFile* ZipArchive::OpenFile(const char* name)
|
||||
{
|
||||
zip_file *zip_file = zip_fopen(zip, name, 0);
|
||||
if (zip_file == NULL)
|
||||
return NULL;
|
||||
|
||||
return new ZipArchiveFile(zip_file);
|
||||
zip_file_t *zip_file = zip_fopen(zip, name, 0);
|
||||
if (zip_file == nullptr)
|
||||
return nullptr;
|
||||
zip_stat_t stat;
|
||||
zip_stat(zip, name, 0, &stat);
|
||||
return new ZipArchiveFile(zip_file, stat.size);
|
||||
}
|
||||
|
||||
struct zip_file *zip_fopen_by_crc(struct zip *za, u32 crc, int flags)
|
||||
static zip_file *zip_fopen_by_crc(zip_t *za, u32 crc, int flags, zip_uint64_t& index)
|
||||
{
|
||||
int i, n;
|
||||
struct zip_stat stat;
|
||||
if (crc == 0)
|
||||
return nullptr;
|
||||
|
||||
if (crc == 0) {
|
||||
return NULL;
|
||||
}
|
||||
zip_int64_t n = zip_get_num_entries(za, 0);
|
||||
for (index = 0; index < (zip_uint64_t)n; index++)
|
||||
{
|
||||
zip_stat_t stat;
|
||||
if (zip_stat_index(za, index, flags, &stat) < -1)
|
||||
return nullptr;
|
||||
if (stat.crc == crc)
|
||||
return zip_fopen_index(za, index, flags);
|
||||
}
|
||||
|
||||
n = zip_get_num_files(za);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (zip_stat_index(za, i, flags, &stat) < -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stat.crc == crc) {
|
||||
return zip_fopen_index(za, i, flags);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ArchiveFile* ZipArchive::OpenFileByCrc(u32 crc)
|
||||
{
|
||||
zip_file *zip_file = zip_fopen_by_crc(zip, crc, 0);
|
||||
if (zip_file == NULL)
|
||||
return NULL;
|
||||
zip_uint64_t index;
|
||||
zip_file_t *zip_file = zip_fopen_by_crc(zip, crc, 0, index);
|
||||
if (zip_file == nullptr)
|
||||
return nullptr;
|
||||
zip_stat_t stat;
|
||||
zip_stat_index(zip, index, 0, &stat);
|
||||
|
||||
return new ZipArchiveFile(zip_file);
|
||||
return new ZipArchiveFile(zip_file, stat.size);
|
||||
}
|
||||
|
||||
u32 ZipArchiveFile::Read(void* buffer, u32 length)
|
||||
{
|
||||
return zip_fread(zip_file, buffer, length);
|
||||
}
|
||||
|
||||
bool ZipArchive::Open(const void *data, size_t size)
|
||||
{
|
||||
zip_error_t error;
|
||||
zip_source_t *source = zip_source_buffer_create(data, size, 0, &error);
|
||||
if (source == nullptr)
|
||||
return false;
|
||||
zip = zip_open_from_source(source, 0, nullptr);
|
||||
if (zip == nullptr)
|
||||
zip_source_free(source);
|
||||
return zip != nullptr;
|
||||
}
|
||||
|
||||
ArchiveFile *ZipArchive::OpenFirstFile()
|
||||
{
|
||||
zip_file_t *zipFile = zip_fopen_index(zip, 0, 0);
|
||||
if (zipFile == nullptr)
|
||||
return nullptr;
|
||||
zip_stat_t stat;
|
||||
zip_stat_index(zip, 0, 0, &stat);
|
||||
return new ZipArchiveFile(zipFile, stat.size);
|
||||
}
|
||||
@@ -26,25 +26,35 @@
|
||||
class ZipArchive : public Archive
|
||||
{
|
||||
public:
|
||||
ZipArchive() : zip(NULL) {}
|
||||
~ZipArchive() override;
|
||||
|
||||
ArchiveFile* OpenFile(const char* name) override;
|
||||
ArchiveFile* OpenFileByCrc(u32 crc) override;
|
||||
|
||||
private:
|
||||
bool Open(const char* path) override;
|
||||
bool Open(const void *data, size_t size);
|
||||
ArchiveFile *OpenFirstFile();
|
||||
|
||||
struct zip *zip;
|
||||
protected:
|
||||
bool Open(FILE *file) override;
|
||||
|
||||
private:
|
||||
zip_t *zip = nullptr;
|
||||
};
|
||||
|
||||
class ZipArchiveFile : public ArchiveFile
|
||||
{
|
||||
public:
|
||||
ZipArchiveFile(struct zip_file *zip_file) : zip_file(zip_file) {}
|
||||
~ZipArchiveFile() override { zip_fclose(zip_file); }
|
||||
ZipArchiveFile(zip_file_t *zip_file, size_t length)
|
||||
: zip_file(zip_file), _length(length) {}
|
||||
~ZipArchiveFile() override {
|
||||
zip_fclose(zip_file);
|
||||
}
|
||||
u32 Read(void* buffer, u32 length) override;
|
||||
size_t length() override {
|
||||
return _length;
|
||||
}
|
||||
|
||||
private:
|
||||
struct zip_file *zip_file;
|
||||
zip_file_t *zip_file;
|
||||
size_t _length;
|
||||
};
|
||||
+49
-12
@@ -22,24 +22,61 @@
|
||||
#include "archive.h"
|
||||
#include "7zArchive.h"
|
||||
#include "ZipArchive.h"
|
||||
#include "oslib/storage.h"
|
||||
|
||||
Archive *OpenArchive(const char *path)
|
||||
Archive *OpenArchive(const std::string& path)
|
||||
{
|
||||
std::string base_path(path);
|
||||
|
||||
Archive *sz_archive = new SzArchive();
|
||||
if (sz_archive->Open(base_path.c_str()) || sz_archive->Open((base_path + ".7z").c_str()) || sz_archive->Open((base_path + ".7Z").c_str()))
|
||||
return sz_archive;
|
||||
delete sz_archive;
|
||||
|
||||
FILE *file = nullptr;
|
||||
hostfs::FileInfo fileInfo;
|
||||
try {
|
||||
fileInfo = hostfs::storage().getFileInfo(path);
|
||||
if (!fileInfo.isDirectory)
|
||||
file = hostfs::storage().openFile(path, "rb");
|
||||
} catch (const hostfs::StorageException& e) {
|
||||
}
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".7z", "rb");
|
||||
if (file == nullptr)
|
||||
file = hostfs::storage().openFile(path + ".7Z", "rb");
|
||||
}
|
||||
if (file != nullptr)
|
||||
{
|
||||
Archive *sz_archive = new SzArchive();
|
||||
if (sz_archive->Open(file))
|
||||
return sz_archive;
|
||||
delete sz_archive;
|
||||
file = nullptr;
|
||||
}
|
||||
// Retry as a zip file
|
||||
try {
|
||||
if (!fileInfo.isDirectory)
|
||||
file = hostfs::storage().openFile(path, "rb");
|
||||
} catch (const hostfs::StorageException& e) {
|
||||
}
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".zip", "rb");
|
||||
if (file == nullptr)
|
||||
{
|
||||
file = hostfs::storage().openFile(path + ".ZIP", "rb");
|
||||
if (file == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Archive *zip_archive = new ZipArchive();
|
||||
if (zip_archive->Open(base_path.c_str()) || zip_archive->Open((base_path + ".zip").c_str()) || zip_archive->Open((base_path + ".ZIP").c_str()))
|
||||
if (zip_archive->Open(file))
|
||||
return zip_archive;
|
||||
delete zip_archive;
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Archive::Open(const char* path)
|
||||
{
|
||||
FILE *file = nowide::fopen(path, "rb");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
return Open(file);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ class ArchiveFile
|
||||
public:
|
||||
virtual ~ArchiveFile() = default;
|
||||
virtual u32 Read(void *buffer, u32 length) = 0;
|
||||
virtual size_t length() = 0;
|
||||
};
|
||||
|
||||
class Archive
|
||||
@@ -36,10 +37,13 @@ public:
|
||||
virtual ArchiveFile *OpenFile(const char *name) = 0;
|
||||
virtual ArchiveFile *OpenFileByCrc(u32 crc) = 0;
|
||||
|
||||
friend Archive *OpenArchive(const char *path);
|
||||
protected:
|
||||
virtual bool Open(FILE *file) = 0;
|
||||
|
||||
private:
|
||||
virtual bool Open(const char *name) = 0;
|
||||
bool Open(const char *name);
|
||||
|
||||
friend Archive *OpenArchive(const std::string& path);
|
||||
};
|
||||
|
||||
Archive *OpenArchive(const char *path);
|
||||
Archive *OpenArchive(const std::string& path);
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "rzip.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
const u8 RZipHeader[8] = { '#', 'R', 'Z', 'I', 'P', 'v', 1, '#' };
|
||||
|
||||
bool RZipFile::Open(const std::string& path, bool write)
|
||||
@@ -52,7 +54,7 @@ bool RZipFile::Open(const std::string& path, bool write)
|
||||
}
|
||||
else
|
||||
{
|
||||
maxChunkSize = 1024 * 1024;
|
||||
maxChunkSize = 1_MB;
|
||||
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|
||||
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|
||||
|| std::fwrite(&size, sizeof(size), 1, file) != 1)
|
||||
|
||||
File renamed without changes.
@@ -257,7 +257,7 @@ public:
|
||||
}
|
||||
|
||||
AudioQueueBufferRef buffers[2];
|
||||
for (UInt32 i = 0; i < ARRAY_SIZE(buffers) && err == noErr; i++)
|
||||
for (UInt32 i = 0; i < std::size(buffers) && err == noErr; i++)
|
||||
{
|
||||
err = AudioQueueAllocateBuffer(recordQueue, 480, &buffers[i]);
|
||||
if (err == noErr)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -128,9 +128,14 @@ public:
|
||||
NOTICE_LOG(AUDIO, "Oboe driver stopping");
|
||||
if (stream != nullptr)
|
||||
{
|
||||
stream->stop();
|
||||
stream->close();
|
||||
// Don't let the AudioErrorCallback term/reinit while we are stopping
|
||||
// This won't prevent shit to hit the fan if it's already in the process
|
||||
// of doing so but this is a pretty rare event and happens on devices
|
||||
// that have audio issues already.
|
||||
auto localStream = stream;
|
||||
stream.reset();
|
||||
localStream->stop();
|
||||
localStream->close();
|
||||
}
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
+7
-129
@@ -1,120 +1,4 @@
|
||||
/*
|
||||
reicast build options
|
||||
|
||||
Reicast can support a lot of stuff, and this is an attempt
|
||||
to organize the build time options
|
||||
|
||||
Option categories
|
||||
|
||||
BUILD_* - BUILD_COMPILER, etc...
|
||||
definitions about the build machine
|
||||
|
||||
HOST_*
|
||||
definitions about the host machine
|
||||
|
||||
FEAT_*
|
||||
definitions about the features that this build targets
|
||||
This is higly related to HOST_*, but it's for options that might
|
||||
or might not be avaiable depending on the target host, or that
|
||||
features that are irrelevant of the host
|
||||
|
||||
Eg, Alsa, Pulse Audio and OSS might sense as HOST dedinitions
|
||||
but it usually makes more sense to detect them as runtime. In
|
||||
that context, HOST_ALSA makes no sense because the host might
|
||||
or might not have alsa installed/ running
|
||||
|
||||
MMU makes no sense as a HOST definition at all, so it should
|
||||
be FEAT_HAS_MMU
|
||||
|
||||
TARGET_*
|
||||
A preconfigured default. Eg TARGET_WIN86.
|
||||
|
||||
Naming of options, option values, and how to use them
|
||||
|
||||
for options that makes sense to have a list of values
|
||||
{CATEGORY}_{OPTION}
|
||||
{OPTION}_{VALUE}
|
||||
|
||||
eg.
|
||||
BUILD_COMPILER == COMPILER_GCC, HOST_CPU != CPU_X64, ...
|
||||
|
||||
for options that are boolean
|
||||
{CATEGORY}_IS_{OPTION} or {CATEGORY}_HAS_{OPTION}
|
||||
|
||||
Evaluates to 0 or 1
|
||||
|
||||
If an configuration cannot be neatly split into a set of
|
||||
of orthogonal options, then it makes sense to break things
|
||||
to "sets" or have a hierarchy of options.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
In the beggining it made sense to have an audio backend
|
||||
per operating system. It made sense to have it depend
|
||||
on HOST_OS and seleect DirectSound or alsa.
|
||||
|
||||
// no option needed
|
||||
|
||||
Then, as android was introduced, which also uses OS_LINUX
|
||||
atm, the audio could have been made an option. It could be
|
||||
a HOST_* option, or FEAT_* one. I'd prefer FEAT_*.
|
||||
FEAT_* makes more sense as future wise we might want
|
||||
to support multiple backends.
|
||||
|
||||
FEAT_AUDIO_BACKEND
|
||||
AUDIO_BACKEND_NONE
|
||||
AUDIO_BACKEND_DS
|
||||
AUDIO_BACKEND_ALSA
|
||||
AUDIO_BACKEND_ANDROID
|
||||
|
||||
Used like
|
||||
#if FEAT_AUDIO_BACKEND == AUDIO_BACKEND_DS ....
|
||||
|
||||
At some point, we might have multiple audio backends that
|
||||
can be compiled in and autodetected/selected at runtime.
|
||||
In that case, it might make sense to have the options like
|
||||
|
||||
FEAT_HAS_ALSA
|
||||
FEAT_HAS_DIRECTSOUND
|
||||
FEAT_HAS_ANDROID_AUDIO
|
||||
|
||||
or
|
||||
FEAT_HAS_AUDIO_ALSA
|
||||
FEAT_HAS_AUDIO_DS
|
||||
FEAT_HAS_AUDIO_ANDROID
|
||||
|
||||
The none option might or might not make sense. In this
|
||||
case it can be removed, as it should always be avaiable.
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
|
||||
General rule of thumb, don't overcomplicate things. Start
|
||||
with a simple option, and then make it more complicated
|
||||
as new uses apply (see the example above)
|
||||
|
||||
Don't use too long names, don't use too cryptic names.
|
||||
Most team developers should be able to understand or
|
||||
figure out most of the acronyms used.
|
||||
|
||||
Try to be consistent on the acronyms across all definitions
|
||||
|
||||
Code shouldn't depend on build level options whenever possible
|
||||
|
||||
Generally, the file should compile even if the option/module is
|
||||
disabled. This makes makefiles etc much easier to write
|
||||
|
||||
TARGET_* options should generally only be used in this file
|
||||
|
||||
The current source is *not* good example of these guidelines
|
||||
|
||||
We'll try to be smart and figure out some options/defaults on this file
|
||||
but this shouldn't get too complicated
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
//#define STRICT_MODE
|
||||
#ifndef STRICT_MODE
|
||||
#define FAST_MMU
|
||||
@@ -126,6 +10,7 @@
|
||||
#define DC_PLATFORM_NAOMI 2
|
||||
#define DC_PLATFORM_NAOMI2 3
|
||||
#define DC_PLATFORM_ATOMISWAVE 4
|
||||
#define DC_PLATFORM_SYSTEMSP 5
|
||||
|
||||
//HOST_CPU
|
||||
#define CPU_X86 0x20000001
|
||||
@@ -140,7 +25,6 @@
|
||||
//FEAT_SHREC, FEAT_AREC, FEAT_DSPREC
|
||||
#define DYNAREC_NONE 0x40000001
|
||||
#define DYNAREC_JIT 0x40000002
|
||||
#define DYNAREC_CPP 0x40000003
|
||||
|
||||
//automatic
|
||||
|
||||
@@ -170,12 +54,6 @@
|
||||
#define FEAT_DSPREC DYNAREC_NONE
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NO_JIT)
|
||||
#define FEAT_SHREC DYNAREC_CPP
|
||||
#define FEAT_AREC DYNAREC_NONE
|
||||
#define FEAT_DSPREC DYNAREC_NONE
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#define FEAT_NO_RWX_PAGES
|
||||
#endif
|
||||
@@ -226,12 +104,12 @@
|
||||
#define USE_GGPO
|
||||
#endif
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(TARGET_IPHONE) && !defined(TARGET_UWP) \
|
||||
&& !defined(__SWITCH__) && !defined(LIBRETRO) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
#define NAOMI_MULTIBOARD
|
||||
#endif
|
||||
|
||||
// TARGET PLATFORM
|
||||
|
||||
#define RAM_SIZE_MAX (32*1024*1024)
|
||||
#define VRAM_SIZE_MAX (16*1024*1024)
|
||||
#define ARAM_SIZE_MAX (8*1024*1024)
|
||||
|
||||
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
|
||||
#define AICA_CORE_CLOCK (GD_CLOCK * 4 / 3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
|
||||
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK / 2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ bool cfgLoadBool(const std::string& section, const std::string& key, bool def);
|
||||
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value);
|
||||
bool cfgIsVirtual(const std::string& section, const std::string& key);
|
||||
|
||||
bool ParseCommandLine(int argc, char *argv[]);
|
||||
void ParseCommandLine(int argc, char *argv[]);
|
||||
|
||||
void cfgSetAutoSave(bool autoSave);
|
||||
bool cfgHasSection(const std::string& section);
|
||||
|
||||
+1
-3
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
|
||||
#include "cfg/cfg.h"
|
||||
@@ -87,7 +86,7 @@ static int showhelp()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ParseCommandLine(int argc,char* argv[])
|
||||
void ParseCommandLine(int argc,char* argv[])
|
||||
{
|
||||
settings.content.path.clear();
|
||||
int cl=argc-2;
|
||||
@@ -141,5 +140,4 @@ bool ParseCommandLine(int argc,char* argv[])
|
||||
arg++;
|
||||
cl--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
+2
-7
@@ -260,18 +260,13 @@ void ConfigFile::parse(FILE* file)
|
||||
|
||||
void ConfigFile::save(FILE* file)
|
||||
{
|
||||
for (const auto& section_it : this->sections)
|
||||
for (const auto& [section_name, section] : this->sections)
|
||||
{
|
||||
const std::string& section_name = section_it.first;
|
||||
const ConfigSection& section = section_it.second;
|
||||
|
||||
if (!section_name.empty())
|
||||
std::fprintf(file, "[%s]\n", section_name.c_str());
|
||||
|
||||
for (const auto& entry_it : section.entries)
|
||||
for (const auto& [entry_name, entry] : section.entries)
|
||||
{
|
||||
const std::string& entry_name = entry_it.first;
|
||||
const ConfigEntry& entry = entry_it.second;
|
||||
std::fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
|
||||
}
|
||||
if (!section_name.empty())
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace emucfg {
|
||||
|
||||
|
||||
+15
-4
@@ -25,7 +25,7 @@ namespace config {
|
||||
// Dynarec
|
||||
|
||||
Option<bool> DynarecEnabled("Dynarec.Enabled", true);
|
||||
Option<bool> DynarecIdleSkip("Dynarec.idleskip", true);
|
||||
Option<int> Sh4Clock("Sh4Clock", 200);
|
||||
|
||||
// General
|
||||
|
||||
@@ -33,14 +33,13 @@ Option<int> Cable("Dreamcast.Cable", 3); // TV Composite
|
||||
Option<int> Region("Dreamcast.Region", 1); // USA
|
||||
Option<int> Broadcast("Dreamcast.Broadcast", 0); // NTSC
|
||||
Option<int> Language("Dreamcast.Language", 1); // English
|
||||
Option<bool> FullMMU("Dreamcast.FullMMU");
|
||||
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
|
||||
Option<bool> AutoLoadState("Dreamcast.AutoLoadState");
|
||||
Option<bool> AutoSaveState("Dreamcast.AutoSaveState");
|
||||
Option<int, false> SavestateSlot("Dreamcast.SavestateSlot");
|
||||
Option<bool> ForceFreePlay("ForceFreePlay", true);
|
||||
Option<bool, false> FetchBoxart("FetchBoxart", true);
|
||||
Option<bool, false> BoxartDisplayMode("BoxartDisplayMode", true);
|
||||
Option<int, false> UIScaling("UIScaling", 100);
|
||||
|
||||
// Sound
|
||||
|
||||
@@ -60,6 +59,7 @@ Option<bool> AutoLatency("aica.AutoLatency",
|
||||
|
||||
OptionString AudioBackend("backend", "auto", "audio");
|
||||
AudioVolumeOption AudioVolume;
|
||||
Option<bool> VmuSound("VmuSound", false, "audio");
|
||||
|
||||
// Rendering
|
||||
|
||||
@@ -93,12 +93,13 @@ std::array<Option<int>, 4> CrosshairColor {
|
||||
Option<int>("rend.CrossHairColor3"),
|
||||
Option<int>("rend.CrossHairColor4"),
|
||||
};
|
||||
Option<int> CrosshairSize("rend.CrosshairSize", 40);
|
||||
Option<int> SkipFrame("ta.skip");
|
||||
Option<int> MaxThreads("pvr.MaxThreads", 3);
|
||||
Option<int> AutoSkipFrame("pvr.AutoSkipFrame", 0);
|
||||
Option<int> RenderResolution("rend.Resolution", 480);
|
||||
Option<bool> VSync("rend.vsync", true);
|
||||
Option<int64_t> PixelBufferSize("rend.PixelBufferSize", 512 * 1024 * 1024);
|
||||
Option<int64_t> PixelBufferSize("rend.PixelBufferSize", 512_MB);
|
||||
Option<int> AnisotropicFiltering("rend.AnisotropicFiltering", 1);
|
||||
Option<int> TextureFiltering("rend.TextureFiltering", 0); // Default
|
||||
Option<bool> ThreadedRendering("rend.ThreadedRendering", true);
|
||||
@@ -106,6 +107,12 @@ Option<bool> DupeFrames("rend.DupeFrames", false);
|
||||
Option<int> PerPixelLayers("rend.PerPixelLayers", 32);
|
||||
Option<bool> NativeDepthInterpolation("rend.NativeDepthInterpolation", false);
|
||||
Option<bool> EmulateFramebuffer("rend.EmulateFramebuffer", false);
|
||||
Option<bool> FixUpscaleBleedingEdge("rend.FixUpscaleBleedingEdge", true);
|
||||
#ifdef VIDEO_ROUTING
|
||||
Option<bool, false> VideoRouting("rend.VideoRouting", false);
|
||||
Option<bool, false> VideoRoutingScale("rend.VideoRoutingScale", false);
|
||||
Option<int, false> VideoRoutingVRes("rend.VideoRoutingVRes", 720);
|
||||
#endif
|
||||
|
||||
// Misc
|
||||
|
||||
@@ -116,6 +123,7 @@ Option<int> GDBPort("Debug.GDBPort", debugger::DEFAULT_PORT);
|
||||
Option<bool> GDBWaitForConnection("Debug.GDBWaitForConnection");
|
||||
Option<bool> UseReios("UseReios");
|
||||
Option<bool> FastGDRomLoad("FastGDRomLoad", false);
|
||||
Option<bool> RamMod32MB("Dreamcast.RamMod32MB", false);
|
||||
|
||||
Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
|
||||
|
||||
@@ -146,6 +154,8 @@ Option<bool> GGPOChat("GGPOChat", true, "network");
|
||||
Option<bool> GGPOChatTimeoutToggle("GGPOChatTimeoutToggle", true, "network");
|
||||
Option<int> GGPOChatTimeout("GGPOChatTimeout", 10, "network");
|
||||
Option<bool> NetworkOutput("NetworkOutput", false, "network");
|
||||
Option<int> MultiboardSlaves("MultiboardSlaves", 1, "network");
|
||||
Option<bool> BattleCableEnable("BattleCable", false, "network");
|
||||
|
||||
#ifdef SUPPORT_DISPMANX
|
||||
Option<bool> DispmanxMaintainAspect("maintain_aspect", true, "dispmanx");
|
||||
@@ -180,6 +190,7 @@ std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
|
||||
Option<MapleDeviceType>("device4.1", MDT_None, "input"),
|
||||
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
|
||||
};
|
||||
Option<bool> PerGameVmu("PerGameVmu", false, "config");
|
||||
#ifdef _WIN32
|
||||
Option<bool, false> UseRawInput("RawInput", false, "input");
|
||||
#endif
|
||||
|
||||
+44
-28
@@ -21,6 +21,7 @@
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
#include "cfg.h"
|
||||
#include "hw/maple/maple_cfg.h"
|
||||
#ifdef LIBRETRO
|
||||
@@ -100,10 +101,6 @@ private:
|
||||
friend class Option;
|
||||
};
|
||||
|
||||
// Missing in C++11
|
||||
template <bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
template<typename T, bool PerGameOption = true>
|
||||
class Option : public BaseOption {
|
||||
public:
|
||||
@@ -173,36 +170,36 @@ public:
|
||||
|
||||
protected:
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, bool>::value, T>
|
||||
std::enable_if_t<std::is_same_v<U, bool>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadBool(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, int64_t>::value, T>
|
||||
std::enable_if_t<std::is_same<U, int64_t>::value, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadInt64(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
|
||||
&& !std::is_same<U, bool>::value && !std::is_same<U, int64_t>::value, T>
|
||||
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
|
||||
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return (T)cfgLoadInt(section, name, (int)value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, std::string>::value, T>
|
||||
std::enable_if_t<std::is_same_v<U, std::string>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
return cfgLoadStr(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<float, U>::value, T>
|
||||
std::enable_if_t<std::is_same_v<float, U>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string strValue = cfgLoadStr(section, name, "");
|
||||
@@ -213,7 +210,7 @@ protected:
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<std::vector<std::string>, U>::value, T>
|
||||
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>, T>
|
||||
doLoad(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string paths = cfgLoadStr(section, name, "");
|
||||
@@ -272,36 +269,36 @@ protected:
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, bool>::value>
|
||||
std::enable_if_t<std::is_same_v<U, bool>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveBool(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, int64_t>::value>
|
||||
std::enable_if_t<std::is_same<U, int64_t>::value>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveInt64(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
|
||||
&& !std::is_same<U, bool>::value && !std::is_same<U, int64_t>::value>
|
||||
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
|
||||
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveInt(section, name, (int)value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<U, std::string>::value>
|
||||
std::enable_if_t<std::is_same_v<U, std::string>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
cfgSaveStr(section, name, value);
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<float, U>::value>
|
||||
std::enable_if_t<std::is_same_v<float, U>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
char buf[64];
|
||||
@@ -310,7 +307,7 @@ protected:
|
||||
}
|
||||
|
||||
template <typename U = T>
|
||||
enable_if_t<std::is_same<std::vector<std::string>, U>::value>
|
||||
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>>
|
||||
doSave(const std::string& section, const std::string& name) const
|
||||
{
|
||||
std::string s;
|
||||
@@ -359,8 +356,9 @@ using OptionString = Option<std::string>;
|
||||
// Dynarec
|
||||
|
||||
extern Option<bool> DynarecEnabled;
|
||||
extern Option<bool> DynarecIdleSkip;
|
||||
constexpr bool DynarecSafeMode = false;
|
||||
#ifndef LIBRETRO
|
||||
extern Option<int> Sh4Clock;
|
||||
#endif
|
||||
|
||||
// General
|
||||
|
||||
@@ -368,14 +366,13 @@ extern Option<int> Cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV Composite
|
||||
extern Option<int> Region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default
|
||||
extern Option<int> Broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default
|
||||
extern Option<int> Language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
|
||||
extern Option<bool> FullMMU;
|
||||
extern Option<bool> ForceWindowsCE;
|
||||
extern Option<bool> AutoLoadState;
|
||||
extern Option<bool> AutoSaveState;
|
||||
extern Option<int, false> SavestateSlot;
|
||||
extern Option<bool> ForceFreePlay;
|
||||
extern Option<bool, false> FetchBoxart;
|
||||
extern Option<bool, false> BoxartDisplayMode;
|
||||
extern Option<int, false> UIScaling;
|
||||
|
||||
// Sound
|
||||
|
||||
@@ -409,19 +406,27 @@ public:
|
||||
}
|
||||
};
|
||||
extern AudioVolumeOption AudioVolume;
|
||||
extern Option<bool> VmuSound;
|
||||
|
||||
// Rendering
|
||||
|
||||
class RendererOption : public Option<RenderType> {
|
||||
public:
|
||||
RendererOption()
|
||||
#if defined(USE_DX11)
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX11) {}
|
||||
#elif defined(USE_DX9)
|
||||
: Option<RenderType>("pvr.rend", RenderType::DirectX9) {}
|
||||
#ifdef LIBRETRO
|
||||
RendererOption() : Option<RenderType>("",
|
||||
#else
|
||||
: Option<RenderType>("pvr.rend", RenderType::OpenGL) {}
|
||||
RendererOption() : Option<RenderType>("pvr.rend",
|
||||
#endif
|
||||
#if defined(USE_DX11)
|
||||
RenderType::DirectX11
|
||||
#elif defined(USE_DX9)
|
||||
RenderType::DirectX9
|
||||
#elif !defined(USE_OPENGL)
|
||||
RenderType::Vulkan
|
||||
#else
|
||||
RenderType::OpenGL
|
||||
#endif
|
||||
) {}
|
||||
|
||||
RenderType& operator=(const RenderType& v) { set(v); return value; }
|
||||
|
||||
@@ -455,6 +460,7 @@ extern Option<bool> PerStripSorting;
|
||||
extern Option<bool> DelayFrameSwapping; // Delay swapping frame until FB_R_SOF matches FB_W_SOF
|
||||
extern Option<bool> WidescreenGameHacks;
|
||||
extern std::array<Option<int>, 4> CrosshairColor;
|
||||
extern Option<int> CrosshairSize;
|
||||
extern Option<int> SkipFrame;
|
||||
extern Option<int> MaxThreads;
|
||||
extern Option<int> AutoSkipFrame; // 0: none, 1: some, 2: more
|
||||
@@ -467,6 +473,12 @@ extern Option<bool> ThreadedRendering;
|
||||
extern Option<bool> DupeFrames;
|
||||
extern Option<bool> NativeDepthInterpolation;
|
||||
extern Option<bool> EmulateFramebuffer;
|
||||
extern Option<bool> FixUpscaleBleedingEdge;
|
||||
#ifdef VIDEO_ROUTING
|
||||
extern Option<bool, false> VideoRouting;
|
||||
extern Option<bool, false> VideoRoutingScale;
|
||||
extern Option<int, false> VideoRoutingVRes;
|
||||
#endif
|
||||
|
||||
// Misc
|
||||
|
||||
@@ -477,6 +489,7 @@ extern Option<int> GDBPort;
|
||||
extern Option<bool> GDBWaitForConnection;
|
||||
extern Option<bool> UseReios;
|
||||
extern Option<bool> FastGDRomLoad;
|
||||
extern Option<bool> RamMod32MB;
|
||||
|
||||
extern Option<bool> OpenGlChecks;
|
||||
|
||||
@@ -507,6 +520,8 @@ extern Option<bool> GGPOChat;
|
||||
extern Option<bool> GGPOChatTimeoutToggle;
|
||||
extern Option<int> GGPOChatTimeout;
|
||||
extern Option<bool> NetworkOutput;
|
||||
extern Option<int> MultiboardSlaves;
|
||||
extern Option<bool> BattleCableEnable;
|
||||
|
||||
#ifdef SUPPORT_DISPMANX
|
||||
extern Option<bool> DispmanxMaintainAspect;
|
||||
@@ -523,6 +538,7 @@ extern Option<int> MouseSensitivity;
|
||||
extern Option<int> VirtualGamepadVibration;
|
||||
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
|
||||
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
|
||||
extern Option<bool> PerGameVmu;
|
||||
#ifdef _WIN32
|
||||
extern Option<bool, false> UseRawInput;
|
||||
#else
|
||||
|
||||
+72
-32
@@ -27,6 +27,7 @@
|
||||
#include "cfg/ini.h"
|
||||
#include "cfg/option.h"
|
||||
#include "emulator.h"
|
||||
#include "oslib/storage.h"
|
||||
|
||||
const WidescreenCheat CheatManager::widescreen_cheats[] =
|
||||
{
|
||||
@@ -51,6 +52,7 @@ const WidescreenCheat CheatManager::widescreen_cheats[] =
|
||||
{ "T6801M", nullptr, { 0x042F3C }, { 0x4384BC09 } }, // Buggy Heat (JP)
|
||||
{ "T46601D 05", nullptr, { 0xBB3D14 }, { 0x440A7C9A } }, // Cannon Spike (PAL)
|
||||
{ "T1215N", nullptr, { 0xBB3C74 }, { 0x440A7C9A } }, // Cannon Spike (USA)
|
||||
{ "HDR-0115", nullptr, { 0x10ACFC }, { 0x3F400000 } }, // Cardcaptor Sakura: Tomoyo no Video Daisakusen (JPN)
|
||||
{ "T44901D 50", nullptr, { 0xB0109C, 0xB010CC }, { 0x43F00000, 0x3F400000 } }, // Carrier (PAL)
|
||||
{ "T5701N", nullptr, { 0xAFD93C, 0xAFD96C }, { 0x43F00000, 0x3F400000 } }, // Carrier (USA)
|
||||
// Capcom vs. SNK Pro (JP)
|
||||
@@ -263,20 +265,23 @@ const WidescreenCheat CheatManager::widescreen_cheats[] =
|
||||
{ "T40206N", nullptr, { 0x43296C }, { 0x3F400000 } }, // Super Magnetic Neo (US)
|
||||
{ "T40206D 50", nullptr, { 0x43E34C }, { 0x3F400000 } }, // Super Magnetic Neo (EU)
|
||||
// { "T7014D 50", nullptr, { 0xE2B234 }, { 0x3F800000 } }, // Super Runabout (PAL) doesn't work?
|
||||
{ "T40216N", nullptr, { 0x45CE54 }, { 0x3F400000 } }, // Surf Rocket Racers (US)
|
||||
{ "T17721D 50", nullptr, { 0x45CED4 }, { 0x3F400000 } }, // Surf Rocket Racers (PAL) alt: 021EBF40 3F400000
|
||||
{ "T17703D 50", nullptr, { 0xCD8950 }, { 0x3F111111 } }, // Suzuki Alstare Extreme Racing
|
||||
{ "T36807D 05", nullptr, { 0x140F74, 0x140FA4 }, { 0x43FA0000, 0x3F400000 } }, // Sword of Bersek (PAL)
|
||||
{ "T-36805N", nullptr, { 0x13F1C4, 0x13F194 }, { 0x3F400000, 0x43F00000 } }, // Sword of Bersek (USA)
|
||||
{ "MK-51186", nullptr, { 0x4A19B0 }, { 0x43700000 } }, // Tennis 2K2 (USA)
|
||||
{ "T15123N", nullptr, { 0x29B7BC }, { 0x3F400000 } }, // Test Drive Le Mans (USA) doesn't work?
|
||||
{ "T15123N", nullptr, { 0x29B7BC }, { 0x3F400000 } }, // Test Drive Le Mans (USA)
|
||||
{ "T20801M", nullptr, { 0x1AAC80, 0x1AACB0 }, { 0x43F00000, 0x3F400000 } }, // Tetris 4D (JP)
|
||||
{ "MK-5101153", nullptr, { 0x14EFA8, 0x14EFD8 }, { 0x43F00000, 0x3F400000 } }, // Timestalkers (PAL)
|
||||
{ "T7009D50", nullptr, { 0x39173C }, { 0x3F400000 } }, // Tech Romancer (PAL)
|
||||
{ "T35402M", nullptr, { 0x315370, 0x3153A0 }, { 0x43F00000, 0x3F400000 } }, // Tokyo Bus Guide (JP) doesn't work?
|
||||
{ "T40201D 50", nullptr, { 0x1D9F10 }, { 0x3F400000 } }, // Tokyo Highway Challenge (PAL)
|
||||
{ "T40210D 50", nullptr, { 0x21E4F8 }, { 0x43700000 } }, // Tokyo Highway Challenge 2 (PAL)
|
||||
{ "xxxxxxxxxx", nullptr, { 0x21DEF8 }, { 0x3F400000 } }, // Tokyo Street Racer 2 (USA)
|
||||
{ "T40202N", nullptr, { 0x1D9EB0 }, { 0x3F400000 } }, // Tokyo Xtreme Racer (USA)
|
||||
{ "T40211N", nullptr, { 0x21DEF8 }, { 0x43700000 } }, // Tokyo Xtreme Racer 2 (USA)
|
||||
// { "T36804D05", nullptr, { 0xB75E28 }, { 0x3EC00000 } }, // Tomb Raider: The Last Revelation (UK) (PAL) clipping, use hex patch instead
|
||||
// { "T40205N", nullptr, { 0x160D80, 0x160D7C }, { 0xA, 0xA } }, // Tony Hawk's Pro Skater (USA) -> missing character on selection screen
|
||||
{ "T13008D 05", nullptr, { 0x1D7C20 }, { 0x3FA66666 } }, // Tony Hawk's Pro Skater 2 (PAL)
|
||||
{ "T13006N", nullptr, { 0x1D77A0 }, { 0x3FA66666 } }, // Tony Hawk's Pro Skater 2 (USA)
|
||||
{ "MK-5102050", nullptr, { 0x0D592C }, { 0x3FD00000 } }, // Toy Commander (PAL)
|
||||
@@ -296,7 +301,7 @@ const WidescreenCheat CheatManager::widescreen_cheats[] =
|
||||
// { "T0000", nullptr, { 0x3A514C, 0x3A6170 }, { 0x3F400000, 0x00000356 } }, // Volgarr the Viking. Not working
|
||||
{ "xxxxxxxxxx", nullptr, { 0x20BB68, 0x1ACBD0, 0x1B9ADC }, // Code 1 reduces clipping. Code 2 fixes the clock.
|
||||
{ 0x43700000, 0x7C1ACC60, 0x3F400000 } }, // What's Shenmue (JP)
|
||||
{ "T40504D 50", nullptr, { 0x75281C }, { 0x3F400000 } }, // Wetrix+ (PAL) not working?
|
||||
{ "T40504D 50", nullptr, { 0x75281C }, { 0x3F400000 } }, // Wetrix+ (PAL)
|
||||
{ "MK-51152", nullptr, { 0x014E90 }, { 0x43700000 } }, // World Series Baseball 2K2 (USA)
|
||||
{ "T20401M", nullptr, { 0x323CB0, 0x1ACBD0, 0x1B9ADC }, // Code 1 reduces clipping. Code 2 fixes the HUD.
|
||||
{ 0x43700000, 0x1ACC60, 0x3F400000 } }, // Zero Gunner 2 (JP)
|
||||
@@ -346,6 +351,8 @@ const WidescreenCheat CheatManager::naomi_widescreen_cheats[] =
|
||||
{ "GUN SPIKE", nullptr, { 0xBACD7C }, { 0x440A7C9A } },
|
||||
{ " JAMBO SAFARI ------------", nullptr, { 0x2B1DE0 }, { 0x3FE38E39 } },
|
||||
{ "SOUL SURFER IN JAPAN", nullptr, { 0x8962C8 }, { 0x3FE38E39 } },
|
||||
{ "LOVE AND BERRY 3 EXP VER1.002", nullptr, { 0x3C16E4 }, { 0x3F400000 } }, // loveber3
|
||||
{ "LOVE AND BERRY USA VER2.000", nullptr, { 0x4E92D0 }, { 0x3F400000 } }, // lovebery
|
||||
|
||||
{ nullptr },
|
||||
};
|
||||
@@ -368,7 +375,7 @@ void CheatManager::setActive(bool active)
|
||||
void CheatManager::loadCheatFile(const std::string& filename)
|
||||
{
|
||||
#ifndef LIBRETRO
|
||||
FILE* cheatfile = nowide::fopen(filename.c_str(), "r");
|
||||
FILE* cheatfile = hostfs::storage().openFile(filename, "r");
|
||||
if (cheatfile == nullptr)
|
||||
{
|
||||
WARN_LOG(COMMON, "Cannot open cheat file '%s'", filename.c_str());
|
||||
@@ -429,27 +436,61 @@ void CheatManager::reset(const std::string& gameId)
|
||||
if (!cheatFile.empty())
|
||||
loadCheatFile(cheatFile);
|
||||
#endif
|
||||
if (gameId == "VF4 FINAL TUNED JAPAN")
|
||||
size_t cheatCount = cheats.size();
|
||||
if (gameId == "Fixed BOOT strapper") // Extreme Hunting 2
|
||||
{
|
||||
setActive(true);
|
||||
cheats.emplace_back(Cheat::Type::setValue, "Skip DIMM version check", true, 16, 0x0007f486, 0xe001); // mov #1, r0
|
||||
cheats.back().builtIn = true;
|
||||
}
|
||||
else if (gameId == "Fixed BOOT strapper") // Extreme Hunting 2
|
||||
{
|
||||
setActive(true);
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "skip netbd check ifeq", true, 32, 0x00067b04, 0);
|
||||
cheats.back().builtIn = true;
|
||||
cheats.emplace_back(Cheat::Type::setValue, "skip netbd check", true, 32, 0x00067b04, 1); // 1 skips initNetwork()
|
||||
cheats.back().builtIn = true;
|
||||
cheats.emplace_back(Cheat::Type::setValue, "skip netbd check 2", true, 16, 0x0009acc8, 0x0009); // not acceptable by main board
|
||||
cheats.back().builtIn = true;
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "skip netbd check ifeq", true, 32, 0x00067b04, 0, true);
|
||||
cheats.emplace_back(Cheat::Type::setValue, "skip netbd check", true, 32, 0x00067b04, 1, true); // 1 skips initNetwork()
|
||||
cheats.emplace_back(Cheat::Type::setValue, "skip netbd check 2", true, 16, 0x0009acc8, 0x0009, true); // not acceptable by main board
|
||||
// ac010000 should be d202 9302, but is changed to 78c0 8c93
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "fix boot ifeq", true, 32, 0x00010000, 0x8c9378c0);
|
||||
cheats.back().builtIn = true;
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix boot", true, 32, 0x00010000, 0x9302d202);
|
||||
cheats.back().builtIn = true;
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "fix boot ifeq", true, 32, 0x00010000, 0x8c9378c0, true);
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix boot", true, 32, 0x00010000, 0x9302d202, true);
|
||||
}
|
||||
else if (gameId == "THE KING OF ROUTE66") {
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore drive error", true, 32, 0x00023ee0, 0x0009000B, true); // rts, nop
|
||||
}
|
||||
else if (gameId.substr(0, 8) == "MKG TKOB")
|
||||
{
|
||||
const auto& setMushikingCheats = [this](u32 addr) {
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 error", true, 32, addr, 0, true); // rfid[0].error = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 error", true, 32, addr + 0x48, 0, true); // rfid[1].error = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid1 status", true, 32, addr + 8, 0, true); // rfid[0].data18 = 0
|
||||
cheats.emplace_back(Cheat::Type::setValue, "ignore rfid2 status", true, 32, addr + 0x50, 0, true); // rfid[1].data18 = 0
|
||||
};
|
||||
if (gameId == "MKG TKOB 2 EXP VER1.001-") // mushi2eo
|
||||
setMushikingCheats(0x6fe1bc);
|
||||
else if (gameId == "MKG TKOB 2 JPN VER2.001-") // mushik2e
|
||||
setMushikingCheats(0x6ffe54);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND VER1.003-")// mushike
|
||||
setMushikingCheats(0x4ad7ec);
|
||||
else if (gameId == "MKG TKOB 4 JPN VER2.000-") // mushik4e
|
||||
setMushikingCheats(0xb0e538);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND VER1.002-")// mushikeo
|
||||
setMushikingCheats(0x4ad56c);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND KOR VER1.000-") // mushikk
|
||||
setMushikingCheats(0x4ac9b8);
|
||||
else if (gameId == "MKG TKOB 2K3 2ND CHN VER1.000-") // mushikc
|
||||
setMushikingCheats(0x4aa9b8);
|
||||
else if (gameId == "MKG TKOB 2 KOR VER1.000-") // mushik2k
|
||||
setMushikingCheats(0x706084);
|
||||
}
|
||||
else if (gameId == "T-8120N") { // Dave Mirra BMX (US)
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x0030b8cc, 0x42040000, true); // 33.0 ms
|
||||
}
|
||||
else if (gameId == "T8120D 50") { // Dave Mirra BMX (EU)
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix main loop time", true, 32, 0x003011cc, 0x42200000, true); // 40.0 ms
|
||||
}
|
||||
else if (gameId == "MK-0100") { // F355 US
|
||||
cheats.emplace_back(Cheat::Type::setValue, "increase datapump timeout", true, 16, 0x00131668, 1000, true);
|
||||
}
|
||||
else if (gameId == "T8118D 50") { // F355 EU
|
||||
cheats.emplace_back(Cheat::Type::setValue, "increase datapump timeout", true, 16, 0x00135588, 1000, true);
|
||||
}
|
||||
else if (gameId == "SAMURAI SPIRITS 6" || gameId == "T0002M") {
|
||||
cheats.emplace_back(Cheat::Type::setValue, "fix depth", true, 16, 0x0003e602, 0x0009, true); // nop (shift by 8 bits instead of 10)
|
||||
}
|
||||
if (cheats.size() > cheatCount)
|
||||
setActive(true);
|
||||
}
|
||||
if (config::WidescreenGameHacks)
|
||||
{
|
||||
@@ -471,10 +512,7 @@ void CheatManager::reset(const std::string& gameId)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string romName = get_file_basename(settings.content.path);
|
||||
size_t folder_pos = get_last_slash_pos(romName);
|
||||
if (folder_pos != std::string::npos)
|
||||
romName = romName.substr(folder_pos + 1);
|
||||
std::string romName = get_file_basename(settings.content.fileName);
|
||||
|
||||
for (int i = 0; naomi_widescreen_cheats[i].game_id != nullptr; i++)
|
||||
{
|
||||
@@ -489,7 +527,7 @@ void CheatManager::reset(const std::string& gameId)
|
||||
}
|
||||
}
|
||||
if (widescreen_cheat != nullptr)
|
||||
for (size_t i = 0; i < ARRAY_SIZE(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
|
||||
for (size_t i = 0; i < std::size(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
|
||||
verify(widescreen_cheat->addresses[i] < RAM_SIZE);
|
||||
}
|
||||
setActive(active);
|
||||
@@ -530,7 +568,7 @@ void CheatManager::apply()
|
||||
{
|
||||
if (widescreen_cheat != nullptr)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
|
||||
for (size_t i = 0; i < std::size(widescreen_cheat->addresses) && widescreen_cheat->addresses[i] != 0; i++)
|
||||
{
|
||||
u32 address = widescreen_cheat->addresses[i];
|
||||
u32 curVal = readRam(address, 32);
|
||||
@@ -538,11 +576,13 @@ void CheatManager::apply()
|
||||
writeRam(address, widescreen_cheat->values[i], 32);
|
||||
}
|
||||
}
|
||||
if (active && !settings.network.online)
|
||||
if (active)
|
||||
{
|
||||
bool skipCheat = false;
|
||||
for (const Cheat& cheat : cheats)
|
||||
{
|
||||
if (!cheat.builtIn && settings.network.online)
|
||||
continue;
|
||||
if (skipCheat) {
|
||||
skipCheat = false;
|
||||
continue;
|
||||
@@ -623,7 +663,7 @@ static std::vector<u32> parseCodes(const std::string& s)
|
||||
curCode += c;
|
||||
if (curCode.length() == 8)
|
||||
{
|
||||
codes.push_back(strtol(curCode.c_str(), nullptr, 16));
|
||||
codes.push_back(strtoul(curCode.c_str(), nullptr, 16));
|
||||
curCode.clear();
|
||||
}
|
||||
}
|
||||
@@ -634,7 +674,7 @@ static std::vector<u32> parseCodes(const std::string& s)
|
||||
{
|
||||
if (curCode.length() != 8)
|
||||
throw FlycastException("Invalid cheat code");
|
||||
codes.push_back(strtol(curCode.c_str(), nullptr, 16));
|
||||
codes.push_back(strtoul(curCode.c_str(), nullptr, 16));
|
||||
}
|
||||
|
||||
return codes;
|
||||
@@ -898,7 +938,7 @@ void CheatManager::saveCheatFile(const std::string& filename)
|
||||
i++;
|
||||
}
|
||||
cfg.set_int("", "cheats", i);
|
||||
FILE *fp = nowide::fopen(filename.c_str(), "w");
|
||||
FILE *fp = hostfs::storage().openFile(filename.c_str(), "w");
|
||||
if (fp == nullptr)
|
||||
throw FlycastException("Can't save cheat file");
|
||||
cfg.save(fp);
|
||||
|
||||
+11
-11
@@ -21,6 +21,8 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct WidescreenCheat
|
||||
{
|
||||
const char *game_id;
|
||||
@@ -49,19 +51,17 @@ struct Cheat
|
||||
u32 size;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u8 valueMask;
|
||||
u32 repeatCount;
|
||||
u32 repeatValueIncrement;
|
||||
u32 repeatAddressIncrement;
|
||||
u32 destAddress;
|
||||
u8 valueMask = 0;
|
||||
u32 repeatCount = 1;
|
||||
u32 repeatValueIncrement = 0;
|
||||
u32 repeatAddressIncrement = 0;
|
||||
u32 destAddress = 0;
|
||||
bool builtIn;
|
||||
|
||||
Cheat(Type type = Type::disabled, const std::string& description = "", bool enabled = false, u32 size = 0, u32 address = 0,
|
||||
u32 value = 0, u8 valueMask = 0, u32 repeatCount = 1, u32 repeatValueIncrement = 0,
|
||||
u32 repeatAddressIncrement = 0, u32 destAddress = 0, bool builtIn = false)
|
||||
: type(type), description(description), enabled(enabled), size(size), address(address), value(value), valueMask(valueMask),
|
||||
repeatCount(repeatCount), repeatValueIncrement(repeatValueIncrement), repeatAddressIncrement(repeatAddressIncrement),
|
||||
destAddress(destAddress), builtIn(builtIn)
|
||||
Cheat(Type type = Type::disabled, const std::string& description = "", bool enabled = false,
|
||||
u32 size = 0, u32 address = 0, u32 value = 0, bool builtIn = false)
|
||||
: type(type), description(description), enabled(enabled),
|
||||
size(size), address(address), value(value), builtIn(builtIn)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
+37
-39
@@ -34,9 +34,6 @@
|
||||
#define SIGBUS 7
|
||||
#endif
|
||||
|
||||
#define SWAP_32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff))
|
||||
#define SWAP_16(a) ((((a) & 0x00ff) << 8) | (((a) & 0xff00) >> 8))
|
||||
|
||||
const std::array<Sh4RegType, 59> Sh4RegList {
|
||||
reg_r0,
|
||||
reg_r1,
|
||||
@@ -76,6 +73,24 @@ const std::array<Sh4RegType, 59> Sh4RegList {
|
||||
class DebugAgent
|
||||
{
|
||||
public:
|
||||
struct Breakpoint {
|
||||
enum Type
|
||||
{
|
||||
BP_TYPE_SOFTWARE_BREAK,
|
||||
BP_TYPE_HARDWARE_BREAK,
|
||||
BP_TYPE_WRITE_WATCHPOINT,
|
||||
BP_TYPE_READ_WATCHPOINT,
|
||||
BP_TYPE_ACCESS_WATCHPOINT,
|
||||
BP_TYPE_COUNT
|
||||
};
|
||||
|
||||
Breakpoint() = default;
|
||||
Breakpoint(u16 type, u32 addr) : addr(addr), type(type) { }
|
||||
u32 addr = 0;
|
||||
u16 type = 0;
|
||||
u16 savedOp = 0;
|
||||
};
|
||||
|
||||
void doContinue(u32 pc = 1)
|
||||
{
|
||||
if (pc != 1)
|
||||
@@ -85,20 +100,20 @@ public:
|
||||
|
||||
void step()
|
||||
{
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::Type::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
u32 savedPc = Sh4cntx.pc;
|
||||
emu.step();
|
||||
if (restoreBreakpoint)
|
||||
insertMatchpoint(Breakpoint::Type::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
}
|
||||
|
||||
void stepRange(u32 from, u32 to)
|
||||
{
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::Type::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
|
||||
u32 savedPc = Sh4cntx.pc;
|
||||
emu.stepRange(from, to);
|
||||
if (restoreBreakpoint)
|
||||
insertMatchpoint(Breakpoint::Type::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
|
||||
}
|
||||
|
||||
int readAllRegs(u32 **regs)
|
||||
@@ -107,9 +122,9 @@ public:
|
||||
for (u32 i = 0; i < Sh4RegList.size(); i++)
|
||||
{
|
||||
if (Sh4RegList[i] == reg_sr_status)
|
||||
allregs[i] = SWAP_32(sh4_sr_GetFull());
|
||||
allregs[i] = sh4_sr_GetFull();
|
||||
else if (Sh4RegList[i] != NoReg)
|
||||
allregs[i] = SWAP_32(*GetRegPtr(Sh4RegList[i]));
|
||||
allregs[i] = *GetRegPtr(Sh4RegList[i]);
|
||||
}
|
||||
*regs = &allregs[0];
|
||||
return allregs.size();
|
||||
@@ -119,7 +134,7 @@ public:
|
||||
{
|
||||
for (u32 i = 0; i < Sh4RegList.size(); i++)
|
||||
if (Sh4RegList[i] != NoReg)
|
||||
*GetRegPtr(Sh4RegList[i]) = SWAP_32(regs[i]);
|
||||
*GetRegPtr(Sh4RegList[i]) = regs[i];
|
||||
}
|
||||
|
||||
u32 readReg(u32 regNum)
|
||||
@@ -128,9 +143,9 @@ public:
|
||||
return 0;
|
||||
Sh4RegType reg = Sh4RegList[regNum];
|
||||
if (reg == reg_sr_status)
|
||||
return SWAP_32(sh4_sr_GetFull());
|
||||
return sh4_sr_GetFull();
|
||||
if (reg != NoReg)
|
||||
return SWAP_32(*GetRegPtr(reg));
|
||||
return *GetRegPtr(reg);
|
||||
return 0;
|
||||
}
|
||||
void writeReg(u32 regNum, u32 value)
|
||||
@@ -139,9 +154,9 @@ public:
|
||||
return;
|
||||
Sh4RegType reg = Sh4RegList[regNum];
|
||||
if (reg == reg_sr_status)
|
||||
sh4_sr_SetFull(SWAP_32(value));
|
||||
sh4_sr_SetFull(value);
|
||||
else if (reg != NoReg)
|
||||
*GetRegPtr(reg) = SWAP_32(value);
|
||||
*GetRegPtr(reg) = value;
|
||||
}
|
||||
|
||||
const u8 *readMem(u32 addr, u32 len)
|
||||
@@ -153,14 +168,14 @@ public:
|
||||
{
|
||||
if (len >= 4 && (addr & 3) == 0)
|
||||
{
|
||||
*(u32 *)p = SWAP_32(ReadMem32_nommu(addr));
|
||||
*(u32 *)p = ReadMem32_nommu(addr);
|
||||
addr += 4;
|
||||
len -= 4;
|
||||
p += 4;
|
||||
}
|
||||
else if (len >= 2 && (addr & 1) == 0)
|
||||
{
|
||||
*(u16 *)p = SWAP_16(ReadMem16_nommu(addr));
|
||||
*(u16 *)p = ReadMem16_nommu(addr);
|
||||
addr += 2;
|
||||
len -= 2;
|
||||
p += 2;
|
||||
@@ -182,14 +197,14 @@ public:
|
||||
{
|
||||
if (len >= 4 && (addr & 3) == 0)
|
||||
{
|
||||
WriteMem32_nommu(addr, SWAP_32(*(u32 *)p));
|
||||
WriteMem32_nommu(addr, *(u32 *)p);
|
||||
addr += 4;
|
||||
len -= 4;
|
||||
p += 4;
|
||||
}
|
||||
else if (len >= 2 && (addr & 3) == 0)
|
||||
{
|
||||
WriteMem16_nommu(addr, SWAP_16(*(u16 *)p));
|
||||
WriteMem16_nommu(addr, *(u16 *)p);
|
||||
addr += 2;
|
||||
len -= 2;
|
||||
p += 2;
|
||||
@@ -202,9 +217,9 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
bool insertMatchpoint(char type, u32 addr, u32 len)
|
||||
bool insertMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
|
||||
{
|
||||
if (type == 0 && len != 2) {
|
||||
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
|
||||
WARN_LOG(COMMON, "insertMatchpoint: length != 2: %d", len);
|
||||
return false;
|
||||
}
|
||||
@@ -216,9 +231,9 @@ public:
|
||||
WriteMem16_nommu(addr, 0xC308); // trapa #0x20
|
||||
return true;
|
||||
}
|
||||
bool removeMatchpoint(char type, u32 addr, u32 len)
|
||||
bool removeMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
|
||||
{
|
||||
if (type == 0 && len != 2) {
|
||||
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
|
||||
WARN_LOG(COMMON, "removeMatchpoint: length != 2: %d", len);
|
||||
return false;
|
||||
}
|
||||
@@ -327,23 +342,6 @@ public:
|
||||
|
||||
u32 exception = 0;
|
||||
|
||||
struct Breakpoint {
|
||||
enum Type
|
||||
{
|
||||
BP_TYPE_SOFTWARE_BREAK,
|
||||
BP_TYPE_HARDWARE_BREAK,
|
||||
BP_TYPE_WRITE_WATCHPOINT,
|
||||
BP_TYPE_READ_WATCHPOINT,
|
||||
BP_TYPE_ACCESS_WATCHPOINT,
|
||||
BP_TYPE_COUNT
|
||||
};
|
||||
|
||||
Breakpoint() = default;
|
||||
Breakpoint(u16 type, u32 addr) : addr(addr), type(type) { }
|
||||
u32 addr = 0;
|
||||
u16 type = 0;
|
||||
u16 savedOp = 0;
|
||||
};
|
||||
std::map<u32, Breakpoint> breakpoints[Breakpoint::Type::BP_TYPE_COUNT];
|
||||
std::vector<std::pair<u32, u32>> stack;
|
||||
};
|
||||
+52
-25
@@ -103,7 +103,7 @@ public:
|
||||
if (config::GDBWaitForConnection)
|
||||
{
|
||||
DEBUG_LOG(COMMON, "Waiting for GDB connection...");
|
||||
agent.interrupt();
|
||||
agentInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,18 +198,22 @@ private:
|
||||
{
|
||||
NOTICE_LOG(NETWORK, "gdb: client connection");
|
||||
attached = true;
|
||||
agent.interrupt();
|
||||
agentInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void readCommand()
|
||||
{
|
||||
if (postDebugTrapNeeded)
|
||||
{
|
||||
postDebugTrapNeeded = false;
|
||||
agent.postDebugTrap();
|
||||
}
|
||||
try {
|
||||
try {
|
||||
if (postDebugTrapNeeded)
|
||||
{
|
||||
postDebugTrapNeeded = false;
|
||||
try {
|
||||
agent.postDebugTrap();
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
std::string packet = recvPacket();
|
||||
if (packet.empty())
|
||||
return;
|
||||
@@ -539,7 +543,7 @@ private:
|
||||
// Tell the remote stub about features supported by GDB,
|
||||
// and query the stub for features it supports
|
||||
char qsupported[128];
|
||||
sprintf_s(qsupported, 128, "PacketSize=%i;vContSupported+", MAX_PACKET_LEN);
|
||||
snprintf(qsupported, 128, "PacketSize=%i;vContSupported+", MAX_PACKET_LEN);
|
||||
sendPacket(qsupported);
|
||||
}
|
||||
else if (pkt.rfind("qSymbol:", 0) == 0)
|
||||
@@ -626,7 +630,7 @@ private:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN_LOG(COMMON, "vCont action not supported %s", pkt[6], pkt.c_str());
|
||||
WARN_LOG(COMMON, "vCont action not supported %s", pkt.c_str());
|
||||
}
|
||||
}
|
||||
else if (pkt.rfind("vFile:", 0) == 0)
|
||||
@@ -667,15 +671,23 @@ private:
|
||||
|
||||
void step(u32 what = 0)
|
||||
{
|
||||
agent.step();
|
||||
sendPacket("S05");
|
||||
try {
|
||||
agent.step();
|
||||
sendPacket("S05");
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void stepRange(u32 from, u32 to)
|
||||
{
|
||||
sendPacket("OK");
|
||||
agent.stepRange(from, to);
|
||||
sendPacket("S05");
|
||||
try {
|
||||
sendPacket("OK");
|
||||
agent.stepRange(from, to);
|
||||
sendPacket("S05");
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void insertMatchpoint(const std::string& pkt)
|
||||
@@ -688,22 +700,23 @@ private:
|
||||
sendPacket("E01");
|
||||
}
|
||||
switch (type) {
|
||||
case DebugAgent::Breakpoint::Type::BP_TYPE_SOFTWARE_BREAK: // soft bp
|
||||
if (agent.insertMatchpoint(0, addr, len))
|
||||
case DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK: // soft bp
|
||||
if (agent.insertMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
|
||||
addr, len))
|
||||
sendPacket("OK");
|
||||
else
|
||||
sendPacket("E01");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::Type::BP_TYPE_HARDWARE_BREAK: // hardware bp
|
||||
case DebugAgent::Breakpoint::BP_TYPE_HARDWARE_BREAK: // hardware bp
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::Type::BP_TYPE_WRITE_WATCHPOINT: // write watchpoint
|
||||
case DebugAgent::Breakpoint::BP_TYPE_WRITE_WATCHPOINT: // write watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::Type::BP_TYPE_READ_WATCHPOINT: // read watchpoint
|
||||
case DebugAgent::Breakpoint::BP_TYPE_READ_WATCHPOINT: // read watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
case DebugAgent::Breakpoint::Type::BP_TYPE_ACCESS_WATCHPOINT: // access watchpoint
|
||||
case DebugAgent::Breakpoint::BP_TYPE_ACCESS_WATCHPOINT: // access watchpoint
|
||||
sendPacket("");
|
||||
break;
|
||||
default:
|
||||
@@ -723,7 +736,8 @@ private:
|
||||
}
|
||||
switch (type) {
|
||||
case 0: // soft bp
|
||||
if (agent.removeMatchpoint(0, addr, len))
|
||||
if (agent.removeMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
|
||||
addr, len))
|
||||
sendPacket("OK");
|
||||
else
|
||||
sendPacket("E01");
|
||||
@@ -748,7 +762,7 @@ private:
|
||||
|
||||
void interrupt()
|
||||
{
|
||||
u32 signal = agent.interrupt();
|
||||
u32 signal = agentInterrupt();
|
||||
char s[10];
|
||||
sprintf(s, "S%02x", signal);
|
||||
sendPacket(s);
|
||||
@@ -888,6 +902,15 @@ private:
|
||||
throw Error("I/O error");
|
||||
}
|
||||
|
||||
u32 agentInterrupt()
|
||||
{
|
||||
try {
|
||||
return agent.interrupt();
|
||||
} catch (const FlycastException& e) {
|
||||
throw Error(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool initialised = false;
|
||||
bool stopRequested = false;
|
||||
bool attached = false;
|
||||
@@ -932,8 +955,12 @@ static void emuEventCallback(Event event, void *)
|
||||
switch (event)
|
||||
{
|
||||
case Event::Resume:
|
||||
if (!gdbServer.isRunning())
|
||||
gdbServer.run();
|
||||
try {
|
||||
if (!gdbServer.isRunning())
|
||||
gdbServer.run();
|
||||
} catch (const GdbServer::Error& e) {
|
||||
ERROR_LOG(COMMON, "%s", e.what());
|
||||
}
|
||||
break;
|
||||
case Event::Terminate:
|
||||
gdbServer.stop();
|
||||
|
||||
+1
-1
Submodule core/deps/SDL updated: f070c83a60...f461d91cd2.
Submodule
+1
Submodule core/deps/Spout added at 2110a918e7.
Submodule
+1
Submodule core/deps/Syphon added at 486dd8e4ef.
+1
-1
Submodule core/deps/Vulkan-Headers updated: b75e5a02b6...85c2334e92.
Submodule core/deps/VulkanMemoryAllocator updated: a6bfc23725...6eb62e1515.
+1
-1
Submodule core/deps/breakpad updated: 4c3d5fce1a...1ab24bcc81.
@@ -64,6 +64,12 @@ typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#elif defined(__QNX__)
|
||||
|
||||
typedef khronos_uintptr_t EGLNativeDisplayType;
|
||||
typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */
|
||||
typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */
|
||||
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
@@ -103,13 +109,7 @@ typedef intptr_t EGLNativeDisplayType;
|
||||
typedef intptr_t EGLNativePixmapType;
|
||||
typedef intptr_t EGLNativeWindowType;
|
||||
|
||||
#elif defined(__unix__) && defined(EGL_NO_X11)
|
||||
|
||||
typedef void *EGLNativeDisplayType;
|
||||
typedef khronos_uintptr_t EGLNativePixmapType;
|
||||
typedef khronos_uintptr_t EGLNativeWindowType;
|
||||
|
||||
#elif defined(__unix__) || defined(USE_X11)
|
||||
#elif defined(USE_X11)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
@@ -119,6 +119,12 @@ typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#elif defined(__unix__)
|
||||
|
||||
typedef void *EGLNativeDisplayType;
|
||||
typedef khronos_uintptr_t EGLNativePixmapType;
|
||||
typedef khronos_uintptr_t EGLNativeWindowType;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
@@ -90,12 +90,20 @@
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
@@ -145,6 +153,20 @@ typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
@@ -227,14 +249,21 @@ typedef unsigned short int khronos_uint16_t;
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* Loader generated by glad 2.0.4 on Sat Jan 20 11:00:00 2024
|
||||
*
|
||||
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
|
||||
*
|
||||
* Generator: C/C++
|
||||
* Specification: egl
|
||||
* Extensions: 0
|
||||
*
|
||||
* APIs:
|
||||
* - egl=1.5
|
||||
*
|
||||
* Options:
|
||||
* - ALIAS = False
|
||||
* - DEBUG = False
|
||||
* - HEADER_ONLY = False
|
||||
* - LOADER = True
|
||||
* - MX = False
|
||||
* - ON_DEMAND = False
|
||||
*
|
||||
* Commandline:
|
||||
* --api='egl=1.5' --extensions='' c --loader
|
||||
*
|
||||
* Online:
|
||||
* http://glad.sh/#api=egl%3D1.5&extensions=&generator=c&options=LOADER
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GLAD_EGL_H_
|
||||
#define GLAD_EGL_H_
|
||||
|
||||
|
||||
#define GLAD_EGL
|
||||
#define GLAD_OPTION_EGL_LOADER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef GLAD_PLATFORM_H_
|
||||
#define GLAD_PLATFORM_H_
|
||||
|
||||
#ifndef GLAD_PLATFORM_WIN32
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
|
||||
#define GLAD_PLATFORM_WIN32 1
|
||||
#else
|
||||
#define GLAD_PLATFORM_WIN32 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GLAD_PLATFORM_APPLE
|
||||
#ifdef __APPLE__
|
||||
#define GLAD_PLATFORM_APPLE 1
|
||||
#else
|
||||
#define GLAD_PLATFORM_APPLE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GLAD_PLATFORM_EMSCRIPTEN
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define GLAD_PLATFORM_EMSCRIPTEN 1
|
||||
#else
|
||||
#define GLAD_PLATFORM_EMSCRIPTEN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GLAD_PLATFORM_UWP
|
||||
#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
|
||||
#ifdef __has_include
|
||||
#if __has_include(<winapifamily.h>)
|
||||
#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
|
||||
#endif
|
||||
#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
|
||||
#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
|
||||
#include <winapifamily.h>
|
||||
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
|
||||
#define GLAD_PLATFORM_UWP 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GLAD_PLATFORM_UWP
|
||||
#define GLAD_PLATFORM_UWP 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GLAD_GNUC_EXTENSION __extension__
|
||||
#else
|
||||
#define GLAD_GNUC_EXTENSION
|
||||
#endif
|
||||
|
||||
#define GLAD_UNUSED(x) (void)(x)
|
||||
|
||||
#ifndef GLAD_API_CALL
|
||||
#if defined(GLAD_API_CALL_EXPORT)
|
||||
#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__)
|
||||
#if defined(GLAD_API_CALL_EXPORT_BUILD)
|
||||
#if defined(__GNUC__)
|
||||
#define GLAD_API_CALL __attribute__ ((dllexport)) extern
|
||||
#else
|
||||
#define GLAD_API_CALL __declspec(dllexport) extern
|
||||
#endif
|
||||
#else
|
||||
#if defined(__GNUC__)
|
||||
#define GLAD_API_CALL __attribute__ ((dllimport)) extern
|
||||
#else
|
||||
#define GLAD_API_CALL __declspec(dllimport) extern
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
|
||||
#define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
|
||||
#else
|
||||
#define GLAD_API_CALL extern
|
||||
#endif
|
||||
#else
|
||||
#define GLAD_API_CALL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef APIENTRY
|
||||
#define GLAD_API_PTR APIENTRY
|
||||
#elif GLAD_PLATFORM_WIN32
|
||||
#define GLAD_API_PTR __stdcall
|
||||
#else
|
||||
#define GLAD_API_PTR
|
||||
#endif
|
||||
|
||||
#ifndef GLAPI
|
||||
#define GLAPI GLAD_API_CALL
|
||||
#endif
|
||||
|
||||
#ifndef GLAPIENTRY
|
||||
#define GLAPIENTRY GLAD_API_PTR
|
||||
#endif
|
||||
|
||||
#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
|
||||
#define GLAD_VERSION_MAJOR(version) (version / 10000)
|
||||
#define GLAD_VERSION_MINOR(version) (version % 10000)
|
||||
|
||||
#define GLAD_GENERATOR_VERSION "2.0.4"
|
||||
|
||||
typedef void (*GLADapiproc)(void);
|
||||
|
||||
typedef GLADapiproc (*GLADloadfunc)(const char *name);
|
||||
typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name);
|
||||
|
||||
typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...);
|
||||
typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...);
|
||||
|
||||
#endif /* GLAD_PLATFORM_H_ */
|
||||
|
||||
#define EGL_ALPHA_FORMAT 0x3088
|
||||
#define EGL_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
#define EGL_ALPHA_SIZE 0x3021
|
||||
#define EGL_BACK_BUFFER 0x3084
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
#define EGL_BAD_PARAMETER 0x300C
|
||||
#define EGL_BAD_SURFACE 0x300D
|
||||
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
#define EGL_BLUE_SIZE 0x3022
|
||||
#define EGL_BUFFER_DESTROYED 0x3095
|
||||
#define EGL_BUFFER_PRESERVED 0x3094
|
||||
#define EGL_BUFFER_SIZE 0x3020
|
||||
#define EGL_CLIENT_APIS 0x308D
|
||||
#define EGL_CL_EVENT_HANDLE 0x309C
|
||||
#define EGL_COLORSPACE 0x3087
|
||||
#define EGL_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
#define EGL_CONDITION_SATISFIED 0x30F6
|
||||
#define EGL_CONFIG_CAVEAT 0x3027
|
||||
#define EGL_CONFIG_ID 0x3028
|
||||
#define EGL_CONFORMANT 0x3042
|
||||
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
#define EGL_CONTEXT_LOST 0x300E
|
||||
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
|
||||
#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
|
||||
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
|
||||
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
|
||||
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
|
||||
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
|
||||
#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_DISPLAY_SCALING 10000
|
||||
#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
|
||||
#define EGL_DRAW 0x3059
|
||||
#define EGL_EXTENSIONS 0x3055
|
||||
#define EGL_FALSE 0
|
||||
#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF
|
||||
#define EGL_GL_COLORSPACE 0x309D
|
||||
#define EGL_GL_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_GL_COLORSPACE_SRGB 0x3089
|
||||
#define EGL_GL_RENDERBUFFER 0x30B9
|
||||
#define EGL_GL_TEXTURE_2D 0x30B1
|
||||
#define EGL_GL_TEXTURE_3D 0x30B2
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
|
||||
#define EGL_GL_TEXTURE_LEVEL 0x30BC
|
||||
#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
|
||||
#define EGL_GREEN_SIZE 0x3023
|
||||
#define EGL_HEIGHT 0x3056
|
||||
#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
#define EGL_IMAGE_PRESERVED 0x30D2
|
||||
#define EGL_LARGEST_PBUFFER 0x3058
|
||||
#define EGL_LEVEL 0x3029
|
||||
#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
|
||||
#define EGL_LUMINANCE_BUFFER 0x308F
|
||||
#define EGL_LUMINANCE_SIZE 0x303D
|
||||
#define EGL_MATCH_NATIVE_PIXMAP 0x3041
|
||||
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MIPMAP_LEVEL 0x3083
|
||||
#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
|
||||
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
|
||||
#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
#define EGL_NONE 0x3038
|
||||
#define EGL_NON_CONFORMANT_CONFIG 0x3051
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
|
||||
#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
|
||||
#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
|
||||
#define EGL_NO_RESET_NOTIFICATION 0x31BE
|
||||
#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
|
||||
#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
|
||||
#define EGL_NO_TEXTURE 0x305C
|
||||
#define EGL_OPENGL_API 0x30A2
|
||||
#define EGL_OPENGL_BIT 0x0008
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||
#define EGL_OPENGL_ES3_BIT 0x00000040
|
||||
#define EGL_OPENGL_ES_API 0x30A0
|
||||
#define EGL_OPENGL_ES_BIT 0x0001
|
||||
#define EGL_OPENVG_API 0x30A1
|
||||
#define EGL_OPENVG_BIT 0x0002
|
||||
#define EGL_OPENVG_IMAGE 0x3096
|
||||
#define EGL_PBUFFER_BIT 0x0001
|
||||
#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
#define EGL_PIXMAP_BIT 0x0002
|
||||
#define EGL_READ 0x305A
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_RENDER_BUFFER 0x3086
|
||||
#define EGL_RGB_BUFFER 0x308E
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
#define EGL_SIGNALED 0x30F2
|
||||
#define EGL_SINGLE_BUFFER 0x3085
|
||||
#define EGL_SLOW_CONFIG 0x3050
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
|
||||
#define EGL_SYNC_CL_EVENT 0x30FE
|
||||
#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
|
||||
#define EGL_SYNC_CONDITION 0x30F8
|
||||
#define EGL_SYNC_FENCE 0x30F9
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
|
||||
#define EGL_SYNC_STATUS 0x30F1
|
||||
#define EGL_SYNC_TYPE 0x30F7
|
||||
#define EGL_TEXTURE_2D 0x305F
|
||||
#define EGL_TEXTURE_FORMAT 0x3080
|
||||
#define EGL_TEXTURE_RGB 0x305D
|
||||
#define EGL_TEXTURE_RGBA 0x305E
|
||||
#define EGL_TEXTURE_TARGET 0x3081
|
||||
#define EGL_TIMEOUT_EXPIRED 0x30F5
|
||||
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
#define EGL_TRANSPARENT_RGB 0x3052
|
||||
#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
#define EGL_TRUE 1
|
||||
#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
|
||||
#define EGL_UNSIGNALED 0x30F3
|
||||
#define EGL_VENDOR 0x3053
|
||||
#define EGL_VERSION 0x3054
|
||||
#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
|
||||
#define EGL_VG_COLORSPACE 0x3087
|
||||
#define EGL_VG_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
|
||||
#define EGL_VG_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_WIDTH 0x3057
|
||||
#define EGL_WINDOW_BIT 0x0004
|
||||
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct AHardwareBuffer;
|
||||
struct wl_buffer;
|
||||
struct wl_display;
|
||||
struct wl_resource;
|
||||
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef unsigned int EGLenum;
|
||||
typedef intptr_t EGLAttribKHR;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef void *EGLClientBuffer;
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLContext;
|
||||
typedef void *EGLDeviceEXT;
|
||||
typedef void *EGLDisplay;
|
||||
typedef void *EGLImage;
|
||||
typedef void *EGLImageKHR;
|
||||
typedef void *EGLLabelKHR;
|
||||
typedef void *EGLObjectKHR;
|
||||
typedef void *EGLOutputLayerEXT;
|
||||
typedef void *EGLOutputPortEXT;
|
||||
typedef void *EGLStreamKHR;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLSync;
|
||||
typedef void *EGLSyncKHR;
|
||||
typedef void *EGLSyncNV;
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeNV;
|
||||
typedef khronos_utime_nanoseconds_t EGLuint64NV;
|
||||
typedef khronos_uint64_t EGLuint64KHR;
|
||||
typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
|
||||
typedef int EGLNativeFileDescriptorKHR;
|
||||
typedef khronos_ssize_t EGLsizeiANDROID;
|
||||
typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
|
||||
typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
|
||||
struct EGLClientPixmapHI {
|
||||
void *pData;
|
||||
EGLint iWidth;
|
||||
EGLint iHeight;
|
||||
EGLint iStride;
|
||||
};
|
||||
typedef void (GLAD_API_PTR *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
|
||||
#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
|
||||
#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
|
||||
#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
|
||||
#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
|
||||
|
||||
|
||||
#define EGL_VERSION_1_0 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_0;
|
||||
#define EGL_VERSION_1_1 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_1;
|
||||
#define EGL_VERSION_1_2 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_2;
|
||||
#define EGL_VERSION_1_3 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_3;
|
||||
#define EGL_VERSION_1_4 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_4;
|
||||
#define EGL_VERSION_1_5 1
|
||||
GLAD_API_CALL int GLAD_EGL_VERSION_1_5;
|
||||
|
||||
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDAPIPROC)(EGLenum api);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config);
|
||||
typedef EGLint (GLAD_API_PTR *PFNEGLCLIENTWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLCOPYBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
typedef EGLContext (GLAD_API_PTR *PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list);
|
||||
typedef EGLImage (GLAD_API_PTR *PFNEGLCREATEIMAGEPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list);
|
||||
typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYIMAGEPROC)(EGLDisplay dpy, EGLImage image);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync sync);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGSPROC)(EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config);
|
||||
typedef EGLContext (GLAD_API_PTR *PFNEGLGETCURRENTCONTEXTPROC)(void);
|
||||
typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETCURRENTDISPLAYPROC)(void);
|
||||
typedef EGLSurface (GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw);
|
||||
typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
|
||||
typedef EGLint (GLAD_API_PTR *PFNEGLGETERRORPROC)(void);
|
||||
typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void * native_display, const EGLAttrib * attrib_list);
|
||||
typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char * procname);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint * major, EGLint * minor);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
typedef EGLenum (GLAD_API_PTR *PFNEGLQUERYAPIPROC)(void);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value);
|
||||
typedef const char * (GLAD_API_PTR *PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETHREADPROC)(void);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLSURFACEATTRIBPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLTERMINATEPROC)(EGLDisplay dpy);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITCLIENTPROC)(void);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITGLPROC)(void);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITNATIVEPROC)(EGLint engine);
|
||||
typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags);
|
||||
|
||||
GLAD_API_CALL PFNEGLBINDAPIPROC glad_eglBindAPI;
|
||||
#define eglBindAPI glad_eglBindAPI
|
||||
GLAD_API_CALL PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage;
|
||||
#define eglBindTexImage glad_eglBindTexImage
|
||||
GLAD_API_CALL PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig;
|
||||
#define eglChooseConfig glad_eglChooseConfig
|
||||
GLAD_API_CALL PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync;
|
||||
#define eglClientWaitSync glad_eglClientWaitSync
|
||||
GLAD_API_CALL PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers;
|
||||
#define eglCopyBuffers glad_eglCopyBuffers
|
||||
GLAD_API_CALL PFNEGLCREATECONTEXTPROC glad_eglCreateContext;
|
||||
#define eglCreateContext glad_eglCreateContext
|
||||
GLAD_API_CALL PFNEGLCREATEIMAGEPROC glad_eglCreateImage;
|
||||
#define eglCreateImage glad_eglCreateImage
|
||||
GLAD_API_CALL PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer;
|
||||
#define eglCreatePbufferFromClientBuffer glad_eglCreatePbufferFromClientBuffer
|
||||
GLAD_API_CALL PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface;
|
||||
#define eglCreatePbufferSurface glad_eglCreatePbufferSurface
|
||||
GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface;
|
||||
#define eglCreatePixmapSurface glad_eglCreatePixmapSurface
|
||||
GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface;
|
||||
#define eglCreatePlatformPixmapSurface glad_eglCreatePlatformPixmapSurface
|
||||
GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface;
|
||||
#define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface
|
||||
GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync;
|
||||
#define eglCreateSync glad_eglCreateSync
|
||||
GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface;
|
||||
#define eglCreateWindowSurface glad_eglCreateWindowSurface
|
||||
GLAD_API_CALL PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext;
|
||||
#define eglDestroyContext glad_eglDestroyContext
|
||||
GLAD_API_CALL PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage;
|
||||
#define eglDestroyImage glad_eglDestroyImage
|
||||
GLAD_API_CALL PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface;
|
||||
#define eglDestroySurface glad_eglDestroySurface
|
||||
GLAD_API_CALL PFNEGLDESTROYSYNCPROC glad_eglDestroySync;
|
||||
#define eglDestroySync glad_eglDestroySync
|
||||
GLAD_API_CALL PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib;
|
||||
#define eglGetConfigAttrib glad_eglGetConfigAttrib
|
||||
GLAD_API_CALL PFNEGLGETCONFIGSPROC glad_eglGetConfigs;
|
||||
#define eglGetConfigs glad_eglGetConfigs
|
||||
GLAD_API_CALL PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext;
|
||||
#define eglGetCurrentContext glad_eglGetCurrentContext
|
||||
GLAD_API_CALL PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay;
|
||||
#define eglGetCurrentDisplay glad_eglGetCurrentDisplay
|
||||
GLAD_API_CALL PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface;
|
||||
#define eglGetCurrentSurface glad_eglGetCurrentSurface
|
||||
GLAD_API_CALL PFNEGLGETDISPLAYPROC glad_eglGetDisplay;
|
||||
#define eglGetDisplay glad_eglGetDisplay
|
||||
GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError;
|
||||
#define eglGetError glad_eglGetError
|
||||
GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay;
|
||||
#define eglGetPlatformDisplay glad_eglGetPlatformDisplay
|
||||
GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress;
|
||||
#define eglGetProcAddress glad_eglGetProcAddress
|
||||
GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib;
|
||||
#define eglGetSyncAttrib glad_eglGetSyncAttrib
|
||||
GLAD_API_CALL PFNEGLINITIALIZEPROC glad_eglInitialize;
|
||||
#define eglInitialize glad_eglInitialize
|
||||
GLAD_API_CALL PFNEGLMAKECURRENTPROC glad_eglMakeCurrent;
|
||||
#define eglMakeCurrent glad_eglMakeCurrent
|
||||
GLAD_API_CALL PFNEGLQUERYAPIPROC glad_eglQueryAPI;
|
||||
#define eglQueryAPI glad_eglQueryAPI
|
||||
GLAD_API_CALL PFNEGLQUERYCONTEXTPROC glad_eglQueryContext;
|
||||
#define eglQueryContext glad_eglQueryContext
|
||||
GLAD_API_CALL PFNEGLQUERYSTRINGPROC glad_eglQueryString;
|
||||
#define eglQueryString glad_eglQueryString
|
||||
GLAD_API_CALL PFNEGLQUERYSURFACEPROC glad_eglQuerySurface;
|
||||
#define eglQuerySurface glad_eglQuerySurface
|
||||
GLAD_API_CALL PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage;
|
||||
#define eglReleaseTexImage glad_eglReleaseTexImage
|
||||
GLAD_API_CALL PFNEGLRELEASETHREADPROC glad_eglReleaseThread;
|
||||
#define eglReleaseThread glad_eglReleaseThread
|
||||
GLAD_API_CALL PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib;
|
||||
#define eglSurfaceAttrib glad_eglSurfaceAttrib
|
||||
GLAD_API_CALL PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers;
|
||||
#define eglSwapBuffers glad_eglSwapBuffers
|
||||
GLAD_API_CALL PFNEGLSWAPINTERVALPROC glad_eglSwapInterval;
|
||||
#define eglSwapInterval glad_eglSwapInterval
|
||||
GLAD_API_CALL PFNEGLTERMINATEPROC glad_eglTerminate;
|
||||
#define eglTerminate glad_eglTerminate
|
||||
GLAD_API_CALL PFNEGLWAITCLIENTPROC glad_eglWaitClient;
|
||||
#define eglWaitClient glad_eglWaitClient
|
||||
GLAD_API_CALL PFNEGLWAITGLPROC glad_eglWaitGL;
|
||||
#define eglWaitGL glad_eglWaitGL
|
||||
GLAD_API_CALL PFNEGLWAITNATIVEPROC glad_eglWaitNative;
|
||||
#define eglWaitNative glad_eglWaitNative
|
||||
GLAD_API_CALL PFNEGLWAITSYNCPROC glad_eglWaitSync;
|
||||
#define eglWaitSync glad_eglWaitSync
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GLAD_API_CALL int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr);
|
||||
GLAD_API_CALL int gladLoadEGL(EGLDisplay display, GLADloadfunc load);
|
||||
|
||||
#ifdef GLAD_EGL
|
||||
|
||||
GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display);
|
||||
|
||||
GLAD_API_CALL void gladLoaderUnloadEGL(void);
|
||||
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,397 @@
|
||||
/**
|
||||
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glad/egl.h>
|
||||
|
||||
#ifndef GLAD_IMPL_UTIL_C_
|
||||
#define GLAD_IMPL_UTIL_C_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
|
||||
#else
|
||||
#define GLAD_IMPL_UTIL_SSCANF sscanf
|
||||
#endif
|
||||
|
||||
#endif /* GLAD_IMPL_UTIL_C_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int GLAD_EGL_VERSION_1_0 = 0;
|
||||
int GLAD_EGL_VERSION_1_1 = 0;
|
||||
int GLAD_EGL_VERSION_1_2 = 0;
|
||||
int GLAD_EGL_VERSION_1_3 = 0;
|
||||
int GLAD_EGL_VERSION_1_4 = 0;
|
||||
int GLAD_EGL_VERSION_1_5 = 0;
|
||||
|
||||
|
||||
|
||||
PFNEGLBINDAPIPROC glad_eglBindAPI = NULL;
|
||||
PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage = NULL;
|
||||
PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig = NULL;
|
||||
PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync = NULL;
|
||||
PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers = NULL;
|
||||
PFNEGLCREATECONTEXTPROC glad_eglCreateContext = NULL;
|
||||
PFNEGLCREATEIMAGEPROC glad_eglCreateImage = NULL;
|
||||
PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer = NULL;
|
||||
PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface = NULL;
|
||||
PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface = NULL;
|
||||
PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface = NULL;
|
||||
PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface = NULL;
|
||||
PFNEGLCREATESYNCPROC glad_eglCreateSync = NULL;
|
||||
PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface = NULL;
|
||||
PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext = NULL;
|
||||
PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage = NULL;
|
||||
PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface = NULL;
|
||||
PFNEGLDESTROYSYNCPROC glad_eglDestroySync = NULL;
|
||||
PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib = NULL;
|
||||
PFNEGLGETCONFIGSPROC glad_eglGetConfigs = NULL;
|
||||
PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext = NULL;
|
||||
PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay = NULL;
|
||||
PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface = NULL;
|
||||
PFNEGLGETDISPLAYPROC glad_eglGetDisplay = NULL;
|
||||
PFNEGLGETERRORPROC glad_eglGetError = NULL;
|
||||
PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay = NULL;
|
||||
PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress = NULL;
|
||||
PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib = NULL;
|
||||
PFNEGLINITIALIZEPROC glad_eglInitialize = NULL;
|
||||
PFNEGLMAKECURRENTPROC glad_eglMakeCurrent = NULL;
|
||||
PFNEGLQUERYAPIPROC glad_eglQueryAPI = NULL;
|
||||
PFNEGLQUERYCONTEXTPROC glad_eglQueryContext = NULL;
|
||||
PFNEGLQUERYSTRINGPROC glad_eglQueryString = NULL;
|
||||
PFNEGLQUERYSURFACEPROC glad_eglQuerySurface = NULL;
|
||||
PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage = NULL;
|
||||
PFNEGLRELEASETHREADPROC glad_eglReleaseThread = NULL;
|
||||
PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib = NULL;
|
||||
PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers = NULL;
|
||||
PFNEGLSWAPINTERVALPROC glad_eglSwapInterval = NULL;
|
||||
PFNEGLTERMINATEPROC glad_eglTerminate = NULL;
|
||||
PFNEGLWAITCLIENTPROC glad_eglWaitClient = NULL;
|
||||
PFNEGLWAITGLPROC glad_eglWaitGL = NULL;
|
||||
PFNEGLWAITNATIVEPROC glad_eglWaitNative = NULL;
|
||||
PFNEGLWAITSYNCPROC glad_eglWaitSync = NULL;
|
||||
|
||||
|
||||
static void glad_egl_load_EGL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_EGL_VERSION_1_0) return;
|
||||
glad_eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) load(userptr, "eglChooseConfig");
|
||||
glad_eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC) load(userptr, "eglCopyBuffers");
|
||||
glad_eglCreateContext = (PFNEGLCREATECONTEXTPROC) load(userptr, "eglCreateContext");
|
||||
glad_eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC) load(userptr, "eglCreatePbufferSurface");
|
||||
glad_eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC) load(userptr, "eglCreatePixmapSurface");
|
||||
glad_eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) load(userptr, "eglCreateWindowSurface");
|
||||
glad_eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC) load(userptr, "eglDestroyContext");
|
||||
glad_eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) load(userptr, "eglDestroySurface");
|
||||
glad_eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) load(userptr, "eglGetConfigAttrib");
|
||||
glad_eglGetConfigs = (PFNEGLGETCONFIGSPROC) load(userptr, "eglGetConfigs");
|
||||
glad_eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay");
|
||||
glad_eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC) load(userptr, "eglGetCurrentSurface");
|
||||
glad_eglGetDisplay = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay");
|
||||
glad_eglGetError = (PFNEGLGETERRORPROC) load(userptr, "eglGetError");
|
||||
glad_eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC) load(userptr, "eglGetProcAddress");
|
||||
glad_eglInitialize = (PFNEGLINITIALIZEPROC) load(userptr, "eglInitialize");
|
||||
glad_eglMakeCurrent = (PFNEGLMAKECURRENTPROC) load(userptr, "eglMakeCurrent");
|
||||
glad_eglQueryContext = (PFNEGLQUERYCONTEXTPROC) load(userptr, "eglQueryContext");
|
||||
glad_eglQueryString = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString");
|
||||
glad_eglQuerySurface = (PFNEGLQUERYSURFACEPROC) load(userptr, "eglQuerySurface");
|
||||
glad_eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC) load(userptr, "eglSwapBuffers");
|
||||
glad_eglTerminate = (PFNEGLTERMINATEPROC) load(userptr, "eglTerminate");
|
||||
glad_eglWaitGL = (PFNEGLWAITGLPROC) load(userptr, "eglWaitGL");
|
||||
glad_eglWaitNative = (PFNEGLWAITNATIVEPROC) load(userptr, "eglWaitNative");
|
||||
}
|
||||
static void glad_egl_load_EGL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_EGL_VERSION_1_1) return;
|
||||
glad_eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC) load(userptr, "eglBindTexImage");
|
||||
glad_eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC) load(userptr, "eglReleaseTexImage");
|
||||
glad_eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC) load(userptr, "eglSurfaceAttrib");
|
||||
glad_eglSwapInterval = (PFNEGLSWAPINTERVALPROC) load(userptr, "eglSwapInterval");
|
||||
}
|
||||
static void glad_egl_load_EGL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_EGL_VERSION_1_2) return;
|
||||
glad_eglBindAPI = (PFNEGLBINDAPIPROC) load(userptr, "eglBindAPI");
|
||||
glad_eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) load(userptr, "eglCreatePbufferFromClientBuffer");
|
||||
glad_eglQueryAPI = (PFNEGLQUERYAPIPROC) load(userptr, "eglQueryAPI");
|
||||
glad_eglReleaseThread = (PFNEGLRELEASETHREADPROC) load(userptr, "eglReleaseThread");
|
||||
glad_eglWaitClient = (PFNEGLWAITCLIENTPROC) load(userptr, "eglWaitClient");
|
||||
}
|
||||
static void glad_egl_load_EGL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_EGL_VERSION_1_4) return;
|
||||
glad_eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) load(userptr, "eglGetCurrentContext");
|
||||
}
|
||||
static void glad_egl_load_EGL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_EGL_VERSION_1_5) return;
|
||||
glad_eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC) load(userptr, "eglClientWaitSync");
|
||||
glad_eglCreateImage = (PFNEGLCREATEIMAGEPROC) load(userptr, "eglCreateImage");
|
||||
glad_eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) load(userptr, "eglCreatePlatformPixmapSurface");
|
||||
glad_eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) load(userptr, "eglCreatePlatformWindowSurface");
|
||||
glad_eglCreateSync = (PFNEGLCREATESYNCPROC) load(userptr, "eglCreateSync");
|
||||
glad_eglDestroyImage = (PFNEGLDESTROYIMAGEPROC) load(userptr, "eglDestroyImage");
|
||||
glad_eglDestroySync = (PFNEGLDESTROYSYNCPROC) load(userptr, "eglDestroySync");
|
||||
glad_eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC) load(userptr, "eglGetPlatformDisplay");
|
||||
glad_eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC) load(userptr, "eglGetSyncAttrib");
|
||||
glad_eglWaitSync = (PFNEGLWAITSYNCPROC) load(userptr, "eglWaitSync");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int glad_egl_get_extensions(EGLDisplay display, const char **extensions) {
|
||||
*extensions = eglQueryString(display, EGL_EXTENSIONS);
|
||||
|
||||
return extensions != NULL;
|
||||
}
|
||||
|
||||
static int glad_egl_has_extension(const char *extensions, const char *ext) {
|
||||
const char *loc;
|
||||
const char *terminator;
|
||||
if(extensions == NULL) {
|
||||
return 0;
|
||||
}
|
||||
while(1) {
|
||||
loc = strstr(extensions, ext);
|
||||
if(loc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
terminator = loc + strlen(ext);
|
||||
if((loc == extensions || *(loc - 1) == ' ') &&
|
||||
(*terminator == ' ' || *terminator == '\0')) {
|
||||
return 1;
|
||||
}
|
||||
extensions = terminator;
|
||||
}
|
||||
}
|
||||
|
||||
static GLADapiproc glad_egl_get_proc_from_userptr(void *userptr, const char *name) {
|
||||
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
|
||||
}
|
||||
|
||||
static int glad_egl_find_extensions_egl(EGLDisplay display) {
|
||||
const char *extensions;
|
||||
if (!glad_egl_get_extensions(display, &extensions)) return 0;
|
||||
|
||||
GLAD_UNUSED(glad_egl_has_extension);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int glad_egl_find_core_egl(EGLDisplay display) {
|
||||
int major, minor;
|
||||
const char *version;
|
||||
|
||||
if (display == NULL) {
|
||||
display = EGL_NO_DISPLAY; /* this is usually NULL, better safe than sorry */
|
||||
}
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
display = eglGetCurrentDisplay();
|
||||
}
|
||||
#ifdef EGL_VERSION_1_4
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
}
|
||||
#endif
|
||||
#ifndef EGL_VERSION_1_5
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
version = eglQueryString(display, EGL_VERSION);
|
||||
(void) eglGetError();
|
||||
|
||||
if (version == NULL) {
|
||||
major = 1;
|
||||
minor = 0;
|
||||
} else {
|
||||
GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor);
|
||||
}
|
||||
|
||||
GLAD_EGL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
|
||||
GLAD_EGL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
|
||||
GLAD_EGL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1;
|
||||
GLAD_EGL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1;
|
||||
GLAD_EGL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1;
|
||||
GLAD_EGL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1;
|
||||
|
||||
return GLAD_MAKE_VERSION(major, minor);
|
||||
}
|
||||
|
||||
int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userptr) {
|
||||
int version;
|
||||
eglGetDisplay = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay");
|
||||
eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay");
|
||||
eglQueryString = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString");
|
||||
eglGetError = (PFNEGLGETERRORPROC) load(userptr, "eglGetError");
|
||||
if (eglGetDisplay == NULL || eglGetCurrentDisplay == NULL || eglQueryString == NULL || eglGetError == NULL) return 0;
|
||||
|
||||
version = glad_egl_find_core_egl(display);
|
||||
if (!version) return 0;
|
||||
glad_egl_load_EGL_VERSION_1_0(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_1(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_2(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_4(load, userptr);
|
||||
glad_egl_load_EGL_VERSION_1_5(load, userptr);
|
||||
|
||||
if (!glad_egl_find_extensions_egl(display)) return 0;
|
||||
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
int gladLoadEGL(EGLDisplay display, GLADloadfunc load) {
|
||||
return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef GLAD_EGL
|
||||
|
||||
#ifndef GLAD_LOADER_LIBRARY_C_
|
||||
#define GLAD_LOADER_LIBRARY_C_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
static void* glad_get_dlopen_handle(const char *lib_names[], int length) {
|
||||
void *handle = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
#if GLAD_PLATFORM_UWP
|
||||
size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR);
|
||||
LPWSTR buffer = (LPWSTR) malloc(buffer_size);
|
||||
if (buffer != NULL) {
|
||||
int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size);
|
||||
if (ret != 0) {
|
||||
handle = (void*) LoadPackagedLibrary(buffer, 0);
|
||||
}
|
||||
free((void*) buffer);
|
||||
}
|
||||
#else
|
||||
handle = (void*) LoadLibraryA(lib_names[i]);
|
||||
#endif
|
||||
#else
|
||||
handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL);
|
||||
#endif
|
||||
if (handle != NULL) {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void glad_close_dlopen_handle(void* handle) {
|
||||
if (handle != NULL) {
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
FreeLibrary((HMODULE) handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static GLADapiproc glad_dlsym_handle(void* handle, const char *name) {
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if GLAD_PLATFORM_WIN32
|
||||
return (GLADapiproc) GetProcAddress((HMODULE) handle, name);
|
||||
#else
|
||||
return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* GLAD_LOADER_LIBRARY_C_ */
|
||||
|
||||
struct _glad_egl_userptr {
|
||||
void *handle;
|
||||
PFNEGLGETPROCADDRESSPROC get_proc_address_ptr;
|
||||
};
|
||||
|
||||
static GLADapiproc glad_egl_get_proc(void *vuserptr, const char* name) {
|
||||
struct _glad_egl_userptr userptr = *(struct _glad_egl_userptr*) vuserptr;
|
||||
GLADapiproc result = NULL;
|
||||
|
||||
result = glad_dlsym_handle(userptr.handle, name);
|
||||
if (result == NULL) {
|
||||
result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.get_proc_address_ptr(name);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void* _egl_handle = NULL;
|
||||
|
||||
static void* glad_egl_dlopen_handle(void) {
|
||||
#if GLAD_PLATFORM_APPLE
|
||||
static const char *NAMES[] = {"libEGL.dylib"};
|
||||
#elif GLAD_PLATFORM_WIN32
|
||||
static const char *NAMES[] = {"libEGL.dll", "EGL.dll"};
|
||||
#else
|
||||
static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"};
|
||||
#endif
|
||||
|
||||
if (_egl_handle == NULL) {
|
||||
_egl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
|
||||
}
|
||||
|
||||
return _egl_handle;
|
||||
}
|
||||
|
||||
static struct _glad_egl_userptr glad_egl_build_userptr(void *handle) {
|
||||
struct _glad_egl_userptr userptr;
|
||||
userptr.handle = handle;
|
||||
userptr.get_proc_address_ptr = (PFNEGLGETPROCADDRESSPROC) glad_dlsym_handle(handle, "eglGetProcAddress");
|
||||
return userptr;
|
||||
}
|
||||
|
||||
int gladLoaderLoadEGL(EGLDisplay display) {
|
||||
int version = 0;
|
||||
void *handle = NULL;
|
||||
int did_load = 0;
|
||||
struct _glad_egl_userptr userptr;
|
||||
|
||||
did_load = _egl_handle == NULL;
|
||||
handle = glad_egl_dlopen_handle();
|
||||
if (handle != NULL) {
|
||||
userptr = glad_egl_build_userptr(handle);
|
||||
|
||||
if (userptr.get_proc_address_ptr != NULL) {
|
||||
version = gladLoadEGLUserPtr(display, glad_egl_get_proc, &userptr);
|
||||
}
|
||||
|
||||
if (!version && did_load) {
|
||||
gladLoaderUnloadEGL();
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
void gladLoaderUnloadEGL() {
|
||||
if (_egl_handle != NULL) {
|
||||
glad_close_dlopen_handle(_egl_handle);
|
||||
_egl_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GLAD_EGL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+11173
File diff suppressed because it is too large.
Load diff
+1
-1
Submodule core/deps/glslang updated: 10423ec659...76b52ebf77.
+165
-112
@@ -3,14 +3,21 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
@@ -26,7 +33,8 @@
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
// DirectX
|
||||
@@ -37,31 +45,47 @@
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
static ID3D11Device* g_pd3dDevice = NULL;
|
||||
static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
|
||||
static IDXGIFactory* g_pFactory = NULL;
|
||||
static ID3D11Buffer* g_pVB = NULL;
|
||||
static ID3D11Buffer* g_pIB = NULL;
|
||||
static ID3D11VertexShader* g_pVertexShader = NULL;
|
||||
static ID3D11InputLayout* g_pInputLayout = NULL;
|
||||
static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
|
||||
static ID3D11PixelShader* g_pPixelShader = NULL;
|
||||
ID3D11SamplerState* g_pFontSampler = NULL;
|
||||
ID3D11SamplerState* g_pTextureSampler = NULL;
|
||||
ID3D11ShaderResourceView*g_pFontTextureView = NULL;
|
||||
static ID3D11RasterizerState* g_pRasterizerState = NULL;
|
||||
static ID3D11BlendState* g_pBlendState = NULL;
|
||||
static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
|
||||
static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
|
||||
// DirectX11 data
|
||||
struct ImGui_ImplDX11_Data
|
||||
{
|
||||
ID3D11Device* pd3dDevice;
|
||||
ID3D11DeviceContext* pd3dDeviceContext;
|
||||
IDXGIFactory* pFactory;
|
||||
ID3D11Buffer* pVB;
|
||||
ID3D11Buffer* pIB;
|
||||
ID3D11VertexShader* pVertexShader;
|
||||
ID3D11InputLayout* pInputLayout;
|
||||
ID3D11Buffer* pVertexConstantBuffer;
|
||||
ID3D11PixelShader* pPixelShader;
|
||||
ID3D11SamplerState* pFontSampler;
|
||||
ID3D11SamplerState* pTextureSampler;
|
||||
ID3D11ShaderResourceView* pFontTextureView;
|
||||
ID3D11RasterizerState* pRasterizerState;
|
||||
ID3D11BlendState* pBlendState;
|
||||
ID3D11DepthStencilState* pDepthStencilState;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER_DX11
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
// Setup viewport
|
||||
D3D11_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||
@@ -75,23 +99,23 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(g_pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(g_pVertexShader, NULL, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
|
||||
ctx->PSSetShader(g_pPixelShader, NULL, 0);
|
||||
ctx->GSSetShader(NULL, NULL, 0);
|
||||
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
|
||||
// Setup blend state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
|
||||
ctx->RSSetState(g_pRasterizerState);
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
@@ -101,42 +125,43 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0)
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||
if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
@@ -148,16 +173,16 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
ctx->Unmap(g_pVB, 0);
|
||||
ctx->Unmap(g_pIB, 0);
|
||||
ctx->Unmap(bd->pVB, 0);
|
||||
ctx->Unmap(bd->pIB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
|
||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
@@ -170,7 +195,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
ctx->Unmap(g_pVertexConstantBuffer, 0);
|
||||
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
@@ -232,7 +257,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
@@ -243,16 +268,22 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
||||
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
|
||||
if (pcmd->TextureId != (ImTextureID)g_pFontTextureView)
|
||||
ctx->PSSetSamplers(0, 1, &g_pTextureSampler);
|
||||
else
|
||||
ctx->PSSetSamplers(0, 1, &g_pFontSampler);
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||
if (pcmd->TextureId != (ImTextureID)bd->pFontTextureView)
|
||||
ctx->PSSetSamplers(0, 1, &bd->pTextureSampler);
|
||||
else
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
@@ -285,6 +316,7 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
@@ -303,13 +335,13 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D* pTexture = NULL;
|
||||
ID3D11Texture2D* pTexture = nullptr;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = pixels;
|
||||
subResource.SysMemPitch = desc.Width * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
IM_ASSERT(pTexture != NULL);
|
||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
IM_ASSERT(pTexture != nullptr);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
@@ -318,14 +350,15 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
|
||||
pTexture->Release();
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)g_pFontTextureView);
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
|
||||
// Create texture samplers
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
@@ -337,19 +370,20 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
g_pd3dDevice->CreateSamplerState(&desc, &g_pTextureSampler);
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pTextureSampler);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (!bd->pd3dDevice)
|
||||
return false;
|
||||
if (g_pFontSampler)
|
||||
if (bd->pFontSampler)
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
@@ -389,9 +423,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
}";
|
||||
|
||||
ID3DBlob* vertexShaderBlob;
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL)))
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
|
||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false;
|
||||
@@ -400,11 +434,11 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
// Create the input layout
|
||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
|
||||
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false;
|
||||
@@ -414,12 +448,12 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
|
||||
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,9 +476,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
}";
|
||||
|
||||
ID3DBlob* pixelShaderBlob;
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL)))
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
|
||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||
{
|
||||
pixelShaderBlob->Release();
|
||||
return false;
|
||||
@@ -465,7 +499,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState);
|
||||
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
|
||||
}
|
||||
|
||||
// Create the rasterizer state
|
||||
@@ -476,7 +510,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
desc.CullMode = D3D11_CULL_NONE;
|
||||
desc.ScissorEnable = true;
|
||||
desc.DepthClipEnable = true;
|
||||
g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
|
||||
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Create depth-stencil State
|
||||
@@ -490,7 +524,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.BackFace = desc.FrontFace;
|
||||
g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
|
||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_CreateFontsTexture();
|
||||
@@ -500,62 +534,81 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
|
||||
void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
{
|
||||
if (!g_pd3dDevice)
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
|
||||
if (g_pTextureSampler) { g_pTextureSampler->Release(); g_pTextureSampler = NULL; }
|
||||
if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
|
||||
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
|
||||
|
||||
if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
|
||||
if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
|
||||
if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
|
||||
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
|
||||
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; }
|
||||
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; }
|
||||
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; }
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pTextureSampler) { bd->pTextureSampler->Release(); bd->pTextureSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
// Setup backend capabilities flags
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx11";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
||||
IDXGIFactory* pFactory = NULL;
|
||||
IDXGIDevice* pDXGIDevice = nullptr;
|
||||
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||
IDXGIFactory* pFactory = nullptr;
|
||||
|
||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||
{
|
||||
g_pd3dDevice = device;
|
||||
g_pd3dDeviceContext = device_context;
|
||||
g_pFactory = pFactory;
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDeviceContext = device_context;
|
||||
bd->pFactory = pFactory;
|
||||
}
|
||||
if (pDXGIDevice) pDXGIDevice->Release();
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
g_pd3dDevice->AddRef();
|
||||
g_pd3dDeviceContext->AddRef();
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->pd3dDeviceContext->AddRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
|
||||
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
|
||||
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_NewFrame()
|
||||
{
|
||||
if (!g_pFontSampler)
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -3,15 +3,19 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui/imgui.h" // IMGUI_IMPL_API
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
@@ -24,3 +28,5 @@ IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -0,0 +1,393 @@
|
||||
// dear imgui: Renderer Backend for DirectX9
|
||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||
// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-04-23: DirectX9: Explicitly setting up more graphics states to increase compatibility with unusual non-default states.
|
||||
// 2021-03-18: DirectX9: Calling IDirect3DStateBlock9::Capture() after CreateStateBlock() as a workaround for state restoring issues (see #3857).
|
||||
// 2021-03-03: DirectX9: Added support for IMGUI_USE_BGRA_PACKED_COLOR in user's imconfig file.
|
||||
// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects().
|
||||
// 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288.
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example.
|
||||
// 2018-06-08: DirectX9: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-05-07: Render: Saving/restoring Transform because they don't seem to be included in the StateBlock. Setting shading mode to Gouraud.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx9.h"
|
||||
|
||||
// DirectX
|
||||
#include <d3d9.h>
|
||||
|
||||
// DirectX data
|
||||
struct ImGui_ImplDX9_Data
|
||||
{
|
||||
LPDIRECT3DDEVICE9 pd3dDevice;
|
||||
LPDIRECT3DVERTEXBUFFER9 pVB;
|
||||
LPDIRECT3DINDEXBUFFER9 pIB;
|
||||
LPDIRECT3DTEXTURE9 FontTexture;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
|
||||
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
float pos[3];
|
||||
D3DCOLOR col;
|
||||
float uv[2];
|
||||
};
|
||||
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
|
||||
#ifdef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
#define IMGUI_COL_TO_DX9_ARGB(_COL) (_COL)
|
||||
#else
|
||||
#define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16))
|
||||
#endif
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
|
||||
// Setup viewport
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = vp.Y = 0;
|
||||
vp.Width = (DWORD)draw_data->DisplaySize.x;
|
||||
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
bd->pd3dDevice->SetViewport(&vp);
|
||||
|
||||
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
||||
bd->pd3dDevice->SetPixelShader(nullptr);
|
||||
bd->pd3dDevice->SetVertexShader(nullptr);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
// Setup orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
// Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
|
||||
{
|
||||
float L = draw_data->DisplayPos.x + 0.5f;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x + 0.5f;
|
||||
float T = draw_data->DisplayPos.y + 0.5f;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y + 0.5f;
|
||||
D3DMATRIX mat_identity = { { { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
D3DMATRIX mat_projection =
|
||||
{ { {
|
||||
2.0f/(R-L), 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 2.0f/(T-B), 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||
} } };
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
}
|
||||
}
|
||||
|
||||
// Render function.
|
||||
void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// Create and grow buffers if needed
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate buffers
|
||||
CUSTOMVERTEX* vtx_dst;
|
||||
ImDrawIdx* idx_dst;
|
||||
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
bd->pVB->Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer, convert colors to DX9 default format.
|
||||
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
||||
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||
vtx_dst->pos[2] = 0.0f;
|
||||
vtx_dst->col = IMGUI_COL_TO_DX9_ARGB(vtx_src->col);
|
||||
vtx_dst->uv[0] = vtx_src->uv.x;
|
||||
vtx_dst->uv[1] = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unlock();
|
||||
bd->pIB->Unlock();
|
||||
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
bd->pd3dDevice->SetIndices(bd->pIB);
|
||||
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||
bd->pd3dDevice->SetTexture(0, texture);
|
||||
if (texture != bd->FontTexture)
|
||||
{
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
}
|
||||
bd->pd3dDevice->SetScissorRect(&r);
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx9";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDevice->AddRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
|
||||
{
|
||||
IDirect3D9* pd3d = nullptr;
|
||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||
return false;
|
||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||
D3DDISPLAYMODE mode = {};
|
||||
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||
{
|
||||
pd3d->Release();
|
||||
return false;
|
||||
}
|
||||
// Font texture should support linear filter, color blend and write to render-target
|
||||
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||
pd3d->Release();
|
||||
return support;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height, bytes_per_pixel;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
||||
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
{
|
||||
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
||||
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
||||
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
||||
pixels = (unsigned char*)dst_start;
|
||||
}
|
||||
#else
|
||||
const bool rgba_support = false;
|
||||
#endif
|
||||
|
||||
// Upload texture to graphics system
|
||||
bd->FontTexture = nullptr;
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, rgba_support ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
return false;
|
||||
D3DLOCKED_RECT tex_locked_rect;
|
||||
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
||||
return false;
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
|
||||
bd->FontTexture->UnlockRect(0);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
||||
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
||||
ImGui::MemFree(pixels);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return false;
|
||||
if (!ImGui_ImplDX9_CreateFontsTexture())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX9_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -3,14 +3,19 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui/imgui.h" // IMGUI_IMPL_API
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
|
||||
@@ -22,3 +27,5 @@ IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+27
-25
@@ -54,7 +54,7 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
@@ -67,13 +67,13 @@
|
||||
#endif
|
||||
|
||||
#include "wsi/gl_context.h"
|
||||
#include "glcache.h"
|
||||
#include "rend/gles/glcache.h"
|
||||
#include "hw/pvr/Renderer_if.h"
|
||||
|
||||
// OpenGL Data
|
||||
static char g_GlslVersionString[32] = "";
|
||||
static GLuint g_FontTexture = 0;
|
||||
static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
||||
static GLuint g_ShaderHandle = 0;
|
||||
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
|
||||
static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
|
||||
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
|
||||
@@ -145,7 +145,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
||||
glcache.Enable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glcache.Disable(GL_CULL_FACE);
|
||||
glcache.Disable(GL_DEPTH_TEST);
|
||||
glcache.Enable(GL_SCISSOR_TEST);
|
||||
@@ -187,24 +187,21 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
#endif
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
|
||||
glEnableVertexAttribArray(g_AttribLocationPosition);
|
||||
glEnableVertexAttribArray(g_AttribLocationUV);
|
||||
glEnableVertexAttribArray(g_AttribLocationColor);
|
||||
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
|
||||
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
|
||||
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
|
||||
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos));
|
||||
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv));
|
||||
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col));
|
||||
|
||||
// Draw
|
||||
ImVec2 pos = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawIdx* idx_buffer_offset = 0;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
@@ -228,12 +225,14 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Bind texture, Draw
|
||||
glcache.BindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||
}
|
||||
}
|
||||
idx_buffer_offset += pcmd->ElemCount;
|
||||
}
|
||||
}
|
||||
// Make sure the state cache is coherent
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
#ifndef GLES2
|
||||
if (vao_handle != 0)
|
||||
glDeleteVertexArrays(1, &vao_handle);
|
||||
@@ -442,23 +441,28 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
|
||||
// Create shaders
|
||||
const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
|
||||
g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL);
|
||||
glCompileShader(g_VertHandle);
|
||||
CheckShader(g_VertHandle, "vertex shader");
|
||||
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vert_handle, 2, vertex_shader_with_version, NULL);
|
||||
glCompileShader(vert_handle);
|
||||
CheckShader(vert_handle, "vertex shader");
|
||||
|
||||
const GLchar* fragment_shader_with_version[2] = { g_GlslVersionString, fragment_shader };
|
||||
g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL);
|
||||
glCompileShader(g_FragHandle);
|
||||
CheckShader(g_FragHandle, "fragment shader");
|
||||
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(frag_handle, 2, fragment_shader_with_version, NULL);
|
||||
glCompileShader(frag_handle);
|
||||
CheckShader(frag_handle, "fragment shader");
|
||||
|
||||
g_ShaderHandle = glCreateProgram();
|
||||
glAttachShader(g_ShaderHandle, g_VertHandle);
|
||||
glAttachShader(g_ShaderHandle, g_FragHandle);
|
||||
glAttachShader(g_ShaderHandle, vert_handle);
|
||||
glAttachShader(g_ShaderHandle, frag_handle);
|
||||
glLinkProgram(g_ShaderHandle);
|
||||
CheckProgram(g_ShaderHandle, "shader program");
|
||||
|
||||
glDetachShader(g_ShaderHandle, vert_handle);
|
||||
glDetachShader(g_ShaderHandle, frag_handle);
|
||||
glDeleteShader(vert_handle);
|
||||
glDeleteShader(frag_handle);
|
||||
|
||||
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
||||
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
||||
g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
|
||||
@@ -481,8 +485,6 @@ static void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
||||
g_VboHandle = g_ElementsHandle = 0;
|
||||
|
||||
glcache.DeleteProgram(g_ShaderHandle);
|
||||
g_VertHandle = 0;
|
||||
g_FragHandle = 0;
|
||||
g_ShaderHandle = 0;
|
||||
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
File renamed without changes.
+378
-258
File diff suppressed because it is too large.
Load diff
+52
-18
@@ -2,20 +2,23 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
|
||||
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
|
||||
// You will use those if you want to use this rendering backend in your engine/app.
|
||||
@@ -24,7 +27,8 @@
|
||||
// Read comments in imgui_impl_vulkan.h.
|
||||
|
||||
#pragma once
|
||||
#include "imgui/imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// [Configuration] in order to use a custom Vulkan function loader:
|
||||
// (1) You'll need to disable default Vulkan function prototypes.
|
||||
@@ -42,9 +46,20 @@
|
||||
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#include <vulkan/vulkan.h>
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
@@ -53,32 +68,47 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
uint32_t Subpass;
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem, please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = NULL);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
@@ -87,8 +117,8 @@ IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*l
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the upcoming multi-viewport feature will need them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
@@ -137,10 +167,12 @@ struct ImGui_ImplVulkanH_Window
|
||||
VkPresentModeKHR PresentMode;
|
||||
VkRenderPass RenderPass;
|
||||
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
|
||||
bool UseDynamicRendering;
|
||||
bool ClearEnable;
|
||||
VkClearValue ClearValue;
|
||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
@@ -152,3 +184,5 @@ struct ImGui_ImplVulkanH_Window
|
||||
ClearEnable = true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+52
-38
@@ -1,5 +1,5 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -9,7 +9,7 @@
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
@@ -20,60 +20,87 @@
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||
|
||||
//---- Unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined, use the much faster STB sprintf library implementation of vsnprintf instead of the one from the default C library.
|
||||
// Note that stb_sprintf.h is meant to be provided by the user and available in the include path at compile time. Also, the compatibility checks of the arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
||||
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
@@ -87,31 +114,18 @@
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOG_TAG "flycast"
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
+7983
-3218
File diff suppressed because it is too large.
Load diff
+1468
-628
File diff suppressed because it is too large.
Load diff
+3945
-1016
File diff suppressed because it is too large.
Load diff
+970
-460
File diff suppressed because it is too large.
Load diff
+2122
-688
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+2555
-1893
File diff suppressed because it is too large.
Load diff
@@ -1,15 +1,19 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.00.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Added STBRP__CDECL
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
||||
//
|
||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Before #including,
|
||||
//
|
||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||
//
|
||||
// in the file that you want to have the implementation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
@@ -34,13 +38,14 @@
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
@@ -81,11 +86,10 @@ typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
#define STBRP__MAXVAL 0x7fffffff
|
||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
@@ -213,10 +217,9 @@ struct stbrp_context
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
@@ -262,9 +265,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
@@ -283,11 +283,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
@@ -433,7 +429,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
@@ -441,7 +437,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
@@ -529,7 +525,6 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
|
||||
return res;
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
@@ -541,7 +536,6 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
@@ -549,12 +543,6 @@ static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
@@ -602,38 +590,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
+131
-137
@@ -1,10 +1,12 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_textedit.h 1.13.
|
||||
// This is a slightly modified version of stb_textedit.h 1.14.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||
|
||||
// stb_textedit.h - v1.13 - public domain - Sean Barrett
|
||||
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
//
|
||||
// This C header file implements the guts of a multi-line text-editing
|
||||
@@ -19,7 +21,7 @@
|
||||
// texts, as its performance does not scale and it has limited undo).
|
||||
//
|
||||
// Non-trivial behaviors are modelled after Windows text controls.
|
||||
//
|
||||
//
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
@@ -29,12 +31,13 @@
|
||||
// DEPENDENCIES
|
||||
//
|
||||
// Uses the C runtime function 'memmove', which you can override
|
||||
// by defining STB_TEXTEDIT_memmove before the implementation.
|
||||
// by defining IMSTB_TEXTEDIT_memmove before the implementation.
|
||||
// Uses no other functions. Performs no runtime allocations.
|
||||
//
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.14 (2021-07-11) page up/down, various fixes
|
||||
// 1.13 (2019-02-07) fix bug in undo size management
|
||||
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
||||
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
||||
@@ -58,6 +61,7 @@
|
||||
// Ulf Winklemann: move-by-word in 1.1
|
||||
// Fabian Giesen: secondary key inputs in 1.5
|
||||
// Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6
|
||||
// Louis Schnellbach: page up/down in 1.14
|
||||
//
|
||||
// Bugfixes:
|
||||
// Scott Graham
|
||||
@@ -93,8 +97,8 @@
|
||||
// moderate sizes. The undo system does no memory allocations, so
|
||||
// it grows STB_TexteditState by the worst-case storage which is (in bytes):
|
||||
//
|
||||
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT
|
||||
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT
|
||||
// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATECOUNT
|
||||
// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHARCOUNT
|
||||
//
|
||||
//
|
||||
// Implementation mode:
|
||||
@@ -217,20 +221,20 @@
|
||||
// call this with the mouse x,y on a mouse down; it will update the cursor
|
||||
// and reset the selection start/end to the cursor point. the x,y must
|
||||
// be relative to the text widget, with (0,0) being the top left.
|
||||
//
|
||||
//
|
||||
// drag:
|
||||
// call this with the mouse x,y on a mouse drag/up; it will update the
|
||||
// cursor and the selection end point
|
||||
//
|
||||
//
|
||||
// cut:
|
||||
// call this to delete the current selection; returns true if there was
|
||||
// one. you should FIRST copy the current selection to the system paste buffer.
|
||||
// (To copy, just copy the current selection out of the string yourself.)
|
||||
//
|
||||
//
|
||||
// paste:
|
||||
// call this to paste text at the current cursor point or over the current
|
||||
// selection if there is one.
|
||||
//
|
||||
//
|
||||
// key:
|
||||
// call this for keyboard inputs sent to the textfield. you can use it
|
||||
// for "key down" events or for "translated" key events. if you need to
|
||||
@@ -241,7 +245,7 @@
|
||||
// clear. STB_TEXTEDIT_KEYTYPE defaults to int, but you can #define it to
|
||||
// anything other type you wante before including.
|
||||
//
|
||||
//
|
||||
//
|
||||
// When rendering, you can read the cursor position and selection state from
|
||||
// the STB_TexteditState.
|
||||
//
|
||||
@@ -271,8 +275,8 @@
|
||||
////
|
||||
////
|
||||
|
||||
#ifndef INCLUDE_STB_TEXTEDIT_H
|
||||
#define INCLUDE_STB_TEXTEDIT_H
|
||||
#ifndef INCLUDE_IMSTB_TEXTEDIT_H
|
||||
#define INCLUDE_IMSTB_TEXTEDIT_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -283,33 +287,33 @@
|
||||
// and undo state.
|
||||
//
|
||||
|
||||
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
|
||||
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
|
||||
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_CHARTYPE
|
||||
#define STB_TEXTEDIT_CHARTYPE int
|
||||
#ifndef IMSTB_TEXTEDIT_CHARTYPE
|
||||
#define IMSTB_TEXTEDIT_CHARTYPE int
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_POSITIONTYPE
|
||||
#define STB_TEXTEDIT_POSITIONTYPE int
|
||||
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
|
||||
#define IMSTB_TEXTEDIT_POSITIONTYPE int
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// private data
|
||||
STB_TEXTEDIT_POSITIONTYPE where;
|
||||
STB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||
STB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE where;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||
int char_storage;
|
||||
} StbUndoRecord;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// private data
|
||||
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
||||
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
||||
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
|
||||
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
|
||||
short undo_point, redo_point;
|
||||
int undo_char_point, redo_char_point;
|
||||
} StbUndoState;
|
||||
@@ -368,7 +372,7 @@ typedef struct
|
||||
float ymin,ymax; // height of row above and below baseline
|
||||
int num_chars;
|
||||
} StbTexteditRow;
|
||||
#endif //INCLUDE_STB_TEXTEDIT_H
|
||||
#endif //INCLUDE_IMSTB_TEXTEDIT_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -381,11 +385,11 @@ typedef struct
|
||||
|
||||
// implementation isn't include-guarded, since it might have indirectly
|
||||
// included just the "header" portion
|
||||
#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
||||
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||
|
||||
#ifndef STB_TEXTEDIT_memmove
|
||||
#ifndef IMSTB_TEXTEDIT_memmove
|
||||
#include <string.h>
|
||||
#define STB_TEXTEDIT_memmove memmove
|
||||
#define IMSTB_TEXTEDIT_memmove memmove
|
||||
#endif
|
||||
|
||||
|
||||
@@ -395,7 +399,7 @@ typedef struct
|
||||
//
|
||||
|
||||
// traverse the layout to locate the nearest character to a display position
|
||||
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
@@ -455,7 +459,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||
}
|
||||
|
||||
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
||||
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||
// goes off the top or bottom of the text
|
||||
@@ -473,7 +477,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||
}
|
||||
|
||||
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
||||
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
@@ -499,11 +503,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
//
|
||||
|
||||
// forward declarations
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -515,36 +519,21 @@ typedef struct
|
||||
|
||||
// find the x/y location of a character, and remember info about the previous row in
|
||||
// case we get a move-up event (for page up, we'll have to rescan)
|
||||
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int prev_start = 0;
|
||||
int z = STB_TEXTEDIT_STRINGLEN(str);
|
||||
int i=0, first;
|
||||
|
||||
if (n == z) {
|
||||
// if it's at the end, then find the last line -- simpler than trying to
|
||||
// explicitly handle this case in the regular code
|
||||
if (single_line) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
find->y = 0;
|
||||
find->first_char = 0;
|
||||
find->length = z;
|
||||
find->height = r.ymax - r.ymin;
|
||||
find->x = r.x1;
|
||||
} else {
|
||||
find->y = 0;
|
||||
find->x = 0;
|
||||
find->height = 1;
|
||||
while (i < z) {
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
prev_start = i;
|
||||
i += r.num_chars;
|
||||
}
|
||||
find->first_char = i;
|
||||
find->length = 0;
|
||||
find->prev_first = prev_start;
|
||||
}
|
||||
if (n == z && single_line) {
|
||||
// special case if it's at the end (may not be needed?)
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||
find->y = 0;
|
||||
find->first_char = 0;
|
||||
find->length = z;
|
||||
find->height = r.ymax - r.ymin;
|
||||
find->x = r.x1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -555,9 +544,16 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (n < i + r.num_chars)
|
||||
break;
|
||||
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
|
||||
break; // [DEAR IMGUI]
|
||||
prev_start = i;
|
||||
i += r.num_chars;
|
||||
find->y += r.baseline_y_delta;
|
||||
if (i == z) // [DEAR IMGUI]
|
||||
{
|
||||
r.num_chars = 0; // [DEAR IMGUI]
|
||||
break; // [DEAR IMGUI]
|
||||
}
|
||||
}
|
||||
|
||||
find->first_char = first = i;
|
||||
@@ -574,7 +570,7 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
||||
|
||||
// make the selection/cursor state valid if client altered the string
|
||||
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
@@ -588,7 +584,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||
}
|
||||
|
||||
// delete characters while updating undo
|
||||
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||
{
|
||||
stb_text_makeundo_delete(str, state, where, len);
|
||||
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
||||
@@ -596,7 +592,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
||||
}
|
||||
|
||||
// delete the section
|
||||
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
stb_textedit_clamp(str, state);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
@@ -633,7 +629,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// move cursor to last character of selection
|
||||
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_sortselection(state);
|
||||
@@ -645,13 +641,13 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
|
||||
}
|
||||
|
||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
||||
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||
{
|
||||
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
||||
}
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
--c; // always move at least one character
|
||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
||||
@@ -666,7 +662,7 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||
#endif
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
|
||||
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
||||
++c; // always move at least one character
|
||||
@@ -693,7 +689,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// API cut: delete selection
|
||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||
@@ -704,7 +700,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// API paste: replace existing selection with passed-in text
|
||||
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
{
|
||||
// if there's a selection, the paste should delete it
|
||||
stb_textedit_clamp(str, state);
|
||||
@@ -716,9 +712,7 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
}
|
||||
// remove the undo since we didn't actually insert the characters
|
||||
if (state->undostate.undo_point)
|
||||
--state->undostate.undo_point;
|
||||
// note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -727,14 +721,14 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
||||
#endif
|
||||
|
||||
// API key: process a keyboard input
|
||||
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
{
|
||||
retry:
|
||||
switch (key) {
|
||||
default: {
|
||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||
if (c > 0) {
|
||||
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
||||
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
||||
|
||||
// can't add newline in single-line mode
|
||||
if (c == '\n' && state->single_line)
|
||||
@@ -764,7 +758,7 @@ retry:
|
||||
state->insert_mode = !state->insert_mode;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
case STB_TEXTEDIT_K_UNDO:
|
||||
stb_text_undo(str, state);
|
||||
state->has_preferred_x = 0;
|
||||
@@ -779,7 +773,7 @@ retry:
|
||||
// if currently there's a selection, move cursor to start of selection
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_first(state);
|
||||
else
|
||||
else
|
||||
if (state->cursor > 0)
|
||||
--state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
@@ -828,7 +822,7 @@ retry:
|
||||
|
||||
#ifdef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
case STB_TEXTEDIT_K_WORDRIGHT:
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
if (STB_TEXT_HAS_SELECTION(state))
|
||||
stb_textedit_move_to_last(str, state);
|
||||
else {
|
||||
state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
|
||||
@@ -899,8 +893,8 @@ retry:
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
@@ -922,7 +916,7 @@ retry:
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case STB_TEXTEDIT_K_UP:
|
||||
case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT:
|
||||
case STB_TEXTEDIT_K_PGUP:
|
||||
@@ -961,8 +955,8 @@ retry:
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
@@ -1014,7 +1008,7 @@ retry:
|
||||
}
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2:
|
||||
#endif
|
||||
@@ -1031,7 +1025,7 @@ retry:
|
||||
state->select_start = state->select_end = 0;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef STB_TEXTEDIT_K_TEXTSTART2
|
||||
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
@@ -1119,8 +1113,8 @@ retry:
|
||||
|
||||
static void stb_textedit_flush_redo(StbUndoState *state)
|
||||
{
|
||||
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
}
|
||||
|
||||
// discard the oldest entry in the undo list
|
||||
@@ -1132,13 +1126,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->undo_char_point -= n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
||||
}
|
||||
--state->undo_point;
|
||||
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,7 +1142,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
// fill up even though the undo buffer didn't
|
||||
static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
{
|
||||
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||
|
||||
if (state->redo_point <= k) {
|
||||
// if the k'th undo state has characters, clean those up
|
||||
@@ -1156,7 +1150,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
// move the remaining redo character data to the end of the buffer
|
||||
state->redo_char_point += n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||
// adjust the position of all the other records to account for above memmove
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
@@ -1164,12 +1158,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
}
|
||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||
// [DEAR IMGUI]
|
||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
|
||||
// now move redo_point to point to the new one
|
||||
++state->redo_point;
|
||||
@@ -1183,32 +1177,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
|
||||
|
||||
// if we have no free records, we have to make room, by sliding the
|
||||
// existing records down
|
||||
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
// if the characters to store won't possibly fit in the buffer, we can't undo
|
||||
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
state->undo_point = 0;
|
||||
state->undo_char_point = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if we don't have enough free characters in the buffer, we have to make room
|
||||
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
||||
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
return &state->undo_rec[state->undo_point++];
|
||||
}
|
||||
|
||||
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||
{
|
||||
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
||||
if (r == NULL)
|
||||
return NULL;
|
||||
|
||||
r->where = pos;
|
||||
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||
|
||||
if (insert_len == 0) {
|
||||
r->char_storage = -1;
|
||||
@@ -1220,7 +1214,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord u, *r;
|
||||
@@ -1247,7 +1241,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
// characters stored for *undoing* don't leave room for redo
|
||||
// if the last is true, we have to bail
|
||||
|
||||
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
// the undo records take up too much character space; there's no space to store the redo characters
|
||||
r->insert_length = 0;
|
||||
} else {
|
||||
@@ -1256,7 +1250,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
// there's definitely room to store the characters eventually
|
||||
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
||||
// should never happen:
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
// there's currently not enough room, so discard a redo record
|
||||
stb_textedit_discard_redo(s);
|
||||
@@ -1288,11 +1282,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
s->redo_point--;
|
||||
}
|
||||
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord *u, r;
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
|
||||
// we need to do two things: apply the redo record, and create an undo record
|
||||
@@ -1344,20 +1338,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
|
||||
stb_text_createundo(&state->undostate, where, 0, length);
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||
if (p) {
|
||||
for (i=0; i < length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||
if (p) {
|
||||
for (i=0; i < old_length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
@@ -1369,8 +1363,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
||||
{
|
||||
state->undostate.undo_point = 0;
|
||||
state->undostate.undo_char_point = 0;
|
||||
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->select_end = state->select_start = 0;
|
||||
state->cursor = 0;
|
||||
state->has_preferred_x = 0;
|
||||
@@ -1393,16 +1387,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
|
||||
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||
{
|
||||
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif//STB_TEXTEDIT_IMPLEMENTATION
|
||||
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
@@ -1410,38 +1404,38 @@ This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
+535
-353
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+557
-395
File diff suppressed because it is too large.
Load diff
+74
-69
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.14
|
||||
// ImPlot v0.17
|
||||
|
||||
// Table of Contents:
|
||||
//
|
||||
@@ -45,7 +45,7 @@
|
||||
// [SECTION] Obsolete API
|
||||
|
||||
#pragma once
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Macros and Defines
|
||||
@@ -60,7 +60,7 @@
|
||||
#endif
|
||||
|
||||
// ImPlot version string.
|
||||
#define IMPLOT_VERSION "0.14"
|
||||
#define IMPLOT_VERSION "0.17"
|
||||
// Indicates variable should deduced automatically.
|
||||
#define IMPLOT_AUTO -1
|
||||
// Special color used to indicate that a color should be deduced automatically.
|
||||
@@ -135,17 +135,16 @@ enum ImPlotFlags_ {
|
||||
ImPlotFlags_NoInputs = 1 << 3, // the user will not be able to interact with the plot
|
||||
ImPlotFlags_NoMenus = 1 << 4, // the user will not be able to open context menus
|
||||
ImPlotFlags_NoBoxSelect = 1 << 5, // the user will not be able to box-select
|
||||
ImPlotFlags_NoChild = 1 << 6, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
|
||||
ImPlotFlags_NoFrame = 1 << 7, // the ImGui frame will not be rendered
|
||||
ImPlotFlags_Equal = 1 << 8, // x and y axes pairs will be constrained to have the same units/pixel
|
||||
ImPlotFlags_Crosshairs = 1 << 9, // the default mouse cursor will be replaced with a crosshair when hovered
|
||||
ImPlotFlags_NoFrame = 1 << 6, // the ImGui frame will not be rendered
|
||||
ImPlotFlags_Equal = 1 << 7, // x and y axes pairs will be constrained to have the same units/pixel
|
||||
ImPlotFlags_Crosshairs = 1 << 8, // the default mouse cursor will be replaced with a crosshair when hovered
|
||||
ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMouseText
|
||||
};
|
||||
|
||||
// Options for plot axes (see SetupAxis).
|
||||
enum ImPlotAxisFlags_ {
|
||||
ImPlotAxisFlags_None = 0, // default
|
||||
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels are also hidden if the supplied string name is NULL)
|
||||
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels are also hidden if the supplied string name is nullptr)
|
||||
ImPlotAxisFlags_NoGridLines = 1 << 1, // no grid lines will be displayed
|
||||
ImPlotAxisFlags_NoTickMarks = 1 << 2, // no tick marks will be displayed
|
||||
ImPlotAxisFlags_NoTickLabels = 1 << 3, // no text labels will be displayed
|
||||
@@ -287,8 +286,9 @@ enum ImPlotInfLinesFlags_ {
|
||||
|
||||
// Flags for PlotPieChart
|
||||
enum ImPlotPieChartFlags_ {
|
||||
ImPlotPieChartFlags_None = 0, // default
|
||||
ImPlotPieChartFlags_Normalize = 1 << 10 // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
|
||||
ImPlotPieChartFlags_None = 0, // default
|
||||
ImPlotPieChartFlags_Normalize = 1 << 10, // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
|
||||
ImPlotPieChartFlags_IgnoreHidden = 1 << 11 // ignore hidden slices when drawing the pie chart (as if they were not there)
|
||||
};
|
||||
|
||||
// Flags for PlotHeatmap
|
||||
@@ -464,41 +464,43 @@ enum ImPlotBin_ {
|
||||
};
|
||||
|
||||
// Double precision version of ImVec2 used by ImPlot. Extensible by end users.
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
struct ImPlotPoint {
|
||||
double x, y;
|
||||
ImPlotPoint() { x = y = 0.0; }
|
||||
ImPlotPoint(double _x, double _y) { x = _x; y = _y; }
|
||||
ImPlotPoint(const ImVec2& p) { x = p.x; y = p.y; }
|
||||
double operator[] (size_t idx) const { return (&x)[idx]; }
|
||||
double& operator[] (size_t idx) { return (&x)[idx]; }
|
||||
constexpr ImPlotPoint() : x(0.0), y(0.0) { }
|
||||
constexpr ImPlotPoint(double _x, double _y) : x(_x), y(_y) { }
|
||||
constexpr ImPlotPoint(const ImVec2& p) : x((double)p.x), y((double)p.y) { }
|
||||
double& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((double*)(void*)(char*)this)[idx]; }
|
||||
double operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const double*)(const void*)(const char*)this)[idx]; }
|
||||
#ifdef IMPLOT_POINT_CLASS_EXTRA
|
||||
IMPLOT_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h
|
||||
// to convert back and forth between your math types and ImPlotPoint.
|
||||
#endif
|
||||
};
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Range defined by a min/max value.
|
||||
struct ImPlotRange {
|
||||
double Min, Max;
|
||||
ImPlotRange() { Min = 0; Max = 0; }
|
||||
ImPlotRange(double _min, double _max) { Min = _min; Max = _max; }
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; }
|
||||
double Size() const { return Max - Min; }
|
||||
double Clamp(double value) const { return (value < Min) ? Min : (value > Max) ? Max : value; }
|
||||
constexpr ImPlotRange() : Min(0.0), Max(0.0) { }
|
||||
constexpr ImPlotRange(double _min, double _max) : Min(_min), Max(_max) { }
|
||||
bool Contains(double value) const { return value >= Min && value <= Max; }
|
||||
double Size() const { return Max - Min; }
|
||||
double Clamp(double value) const { return (value < Min) ? Min : (value > Max) ? Max : value; }
|
||||
};
|
||||
|
||||
// Combination of two range limits for X and Y axes. Also an AABB defined by Min()/Max().
|
||||
struct ImPlotRect {
|
||||
ImPlotRange X, Y;
|
||||
ImPlotRect() { }
|
||||
ImPlotRect(double x_min, double x_max, double y_min, double y_max) { X.Min = x_min; X.Max = x_max; Y.Min = y_min; Y.Max = y_max; }
|
||||
bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
|
||||
bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
|
||||
ImPlotPoint Size() const { return ImPlotPoint(X.Size(), Y.Size()); }
|
||||
ImPlotPoint Clamp(const ImPlotPoint& p) { return Clamp(p.x, p.y); }
|
||||
ImPlotPoint Clamp(double x, double y) { return ImPlotPoint(X.Clamp(x),Y.Clamp(y)); }
|
||||
ImPlotPoint Min() const { return ImPlotPoint(X.Min, Y.Min); }
|
||||
ImPlotPoint Max() const { return ImPlotPoint(X.Max, Y.Max); }
|
||||
constexpr ImPlotRect() : X(0.0,0.0), Y(0.0,0.0) { }
|
||||
constexpr ImPlotRect(double x_min, double x_max, double y_min, double y_max) : X(x_min, x_max), Y(y_min, y_max) { }
|
||||
bool Contains(const ImPlotPoint& p) const { return Contains(p.x, p.y); }
|
||||
bool Contains(double x, double y) const { return X.Contains(x) && Y.Contains(y); }
|
||||
ImPlotPoint Size() const { return ImPlotPoint(X.Size(), Y.Size()); }
|
||||
ImPlotPoint Clamp(const ImPlotPoint& p) { return Clamp(p.x, p.y); }
|
||||
ImPlotPoint Clamp(double x, double y) { return ImPlotPoint(X.Clamp(x),Y.Clamp(y)); }
|
||||
ImPlotPoint Min() const { return ImPlotPoint(X.Min, Y.Min); }
|
||||
ImPlotPoint Max() const { return ImPlotPoint(X.Max, Y.Max); }
|
||||
};
|
||||
|
||||
// Plot style structure
|
||||
@@ -596,9 +598,9 @@ namespace ImPlot {
|
||||
|
||||
// Creates a new ImPlot context. Call this after ImGui::CreateContext.
|
||||
IMPLOT_API ImPlotContext* CreateContext();
|
||||
// Destroys an ImPlot context. Call this before ImGui::DestroyContext. NULL = destroy current context.
|
||||
IMPLOT_API void DestroyContext(ImPlotContext* ctx = NULL);
|
||||
// Returns the current ImPlot context. NULL if no context has ben set.
|
||||
// Destroys an ImPlot context. Call this before ImGui::DestroyContext. nullptr = destroy current context.
|
||||
IMPLOT_API void DestroyContext(ImPlotContext* ctx = nullptr);
|
||||
// Returns the current ImPlot context. nullptr if no context has ben set.
|
||||
IMPLOT_API ImPlotContext* GetCurrentContext();
|
||||
// Sets the current ImPlot context.
|
||||
IMPLOT_API void SetCurrentContext(ImPlotContext* ctx);
|
||||
@@ -690,8 +692,8 @@ IMPLOT_API bool BeginSubplots(const char* title_id,
|
||||
int cols,
|
||||
const ImVec2& size,
|
||||
ImPlotSubplotFlags flags = 0,
|
||||
float* row_ratios = NULL,
|
||||
float* col_ratios = NULL);
|
||||
float* row_ratios = nullptr,
|
||||
float* col_ratios = nullptr);
|
||||
|
||||
// Only call EndSubplots() if BeginSubplots() returns true! Typically called at the end
|
||||
// of an if statement conditioned on BeginSublots(). See example above.
|
||||
@@ -726,24 +728,24 @@ IMPLOT_API void EndSubplots();
|
||||
// call it yourself, then the first subsequent plotting or utility function will
|
||||
// call it for you.
|
||||
|
||||
// Enables an axis or sets the label and/or flags for an existing axis. Leave #label = NULL for no label.
|
||||
IMPLOT_API void SetupAxis(ImAxis axis, const char* label=NULL, ImPlotAxisFlags flags=0);
|
||||
// Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked.
|
||||
// Enables an axis or sets the label and/or flags for an existing axis. Leave #label = nullptr for no label.
|
||||
IMPLOT_API void SetupAxis(ImAxis axis, const char* label=nullptr, ImPlotAxisFlags flags=0);
|
||||
// Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked. Inversion with v_min > v_max is not supported; use SetupAxisLimits instead.
|
||||
IMPLOT_API void SetupAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
|
||||
// Links an axis range limits to external values. Set to NULL for no linkage. The pointer data must remain valid until EndPlot.
|
||||
// Links an axis range limits to external values. Set to nullptr for no linkage. The pointer data must remain valid until EndPlot.
|
||||
IMPLOT_API void SetupAxisLinks(ImAxis axis, double* link_min, double* link_max);
|
||||
// Sets the format of numeric axis labels via formater specifier (default="%g"). Formated values will be double (i.e. use %f).
|
||||
IMPLOT_API void SetupAxisFormat(ImAxis axis, const char* fmt);
|
||||
// Sets the format of numeric axis labels via formatter callback. Given #value, write a label into #buff. Optionally pass user data.
|
||||
IMPLOT_API void SetupAxisFormat(ImAxis axis, ImPlotFormatter formatter, void* data=NULL);
|
||||
IMPLOT_API void SetupAxisFormat(ImAxis axis, ImPlotFormatter formatter, void* data=nullptr);
|
||||
// Sets an axis' ticks and optionally the labels. To keep the default ticks, set #keep_default=true.
|
||||
IMPLOT_API void SetupAxisTicks(ImAxis axis, const double* values, int n_ticks, const char* const labels[]=NULL, bool keep_default=false);
|
||||
IMPLOT_API void SetupAxisTicks(ImAxis axis, const double* values, int n_ticks, const char* const labels[]=nullptr, bool keep_default=false);
|
||||
// Sets an axis' ticks and optionally the labels for the next plot. To keep the default ticks, set #keep_default=true.
|
||||
IMPLOT_API void SetupAxisTicks(ImAxis axis, double v_min, double v_max, int n_ticks, const char* const labels[]=NULL, bool keep_default=false);
|
||||
IMPLOT_API void SetupAxisTicks(ImAxis axis, double v_min, double v_max, int n_ticks, const char* const labels[]=nullptr, bool keep_default=false);
|
||||
// Sets an axis' scale using built-in options.
|
||||
IMPLOT_API void SetupAxisScale(ImAxis axis, ImPlotScale scale);
|
||||
// Sets an axis' scale using user supplied forward and inverse transfroms.
|
||||
IMPLOT_API void SetupAxisScale(ImAxis axis, ImPlotTransform forward, ImPlotTransform inverse, void* data=NULL);
|
||||
IMPLOT_API void SetupAxisScale(ImAxis axis, ImPlotTransform forward, ImPlotTransform inverse, void* data=nullptr);
|
||||
// Sets an axis' limits constraints.
|
||||
IMPLOT_API void SetupAxisLimitsConstraints(ImAxis axis, double v_min, double v_max);
|
||||
// Sets an axis' zoom constraints.
|
||||
@@ -754,7 +756,7 @@ IMPLOT_API void SetupAxes(const char* x_label, const char* y_label, ImPlotAxisFl
|
||||
// Sets the primary X and Y axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits).
|
||||
IMPLOT_API void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImPlotCond cond = ImPlotCond_Once);
|
||||
|
||||
// Sets up the plot legend.
|
||||
// Sets up the plot legend. This can also be called immediately after BeginSubplots when using ImPlotSubplotFlags_ShareItems.
|
||||
IMPLOT_API void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags=0);
|
||||
// Set the location of the current plot's mouse position text (default = South|East).
|
||||
IMPLOT_API void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags=0);
|
||||
@@ -788,7 +790,7 @@ IMPLOT_API void SetupFinish();
|
||||
|
||||
// Sets an upcoming axis range limits. If ImPlotCond_Always is used, the axes limits will be locked.
|
||||
IMPLOT_API void SetNextAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
|
||||
// Links an upcoming axis range limits to external values. Set to NULL for no linkage. The pointer data must remain valid until EndPlot!
|
||||
// Links an upcoming axis range limits to external values. Set to nullptr for no linkage. The pointer data must remain valid until EndPlot!
|
||||
IMPLOT_API void SetNextAxisLinks(ImAxis axis, double* link_min, double* link_max);
|
||||
// Set an upcoming axis to auto fit to its data.
|
||||
IMPLOT_API void SetNextAxisToFit(ImAxis axis);
|
||||
@@ -890,10 +892,11 @@ IMPLOT_TMP void PlotStems(const char* label_id, const T* xs, const T* ys, int co
|
||||
// Plots infinite vertical or horizontal lines (e.g. for references or asymptotes).
|
||||
IMPLOT_TMP void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLinesFlags flags=0, int offset=0, int stride=sizeof(T));
|
||||
|
||||
// Plots a pie chart. Center and radius are in plot units. #label_fmt can be set to NULL for no labels.
|
||||
// Plots a pie chart. Center and radius are in plot units. #label_fmt can be set to nullptr for no labels.
|
||||
IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data=nullptr, double angle0=90, ImPlotPieChartFlags flags=0);
|
||||
IMPLOT_TMP void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* label_fmt="%.1f", double angle0=90, ImPlotPieChartFlags flags=0);
|
||||
|
||||
// Plots a 2D heatmap chart. Values are expected to be in row-major order by default. Leave #scale_min and scale_max both at 0 for automatic color scaling, or set them to a predefined range. #label_fmt can be set to NULL for no labels.
|
||||
// Plots a 2D heatmap chart. Values are expected to be in row-major order by default. Leave #scale_min and scale_max both at 0 for automatic color scaling, or set them to a predefined range. #label_fmt can be set to nullptr for no labels.
|
||||
IMPLOT_TMP void PlotHeatmap(const char* label_id, const T* values, int rows, int cols, double scale_min=0, double scale_max=0, const char* label_fmt="%.1f", const ImPlotPoint& bounds_min=ImPlotPoint(0,0), const ImPlotPoint& bounds_max=ImPlotPoint(1,1), ImPlotHeatmapFlags flags=0);
|
||||
|
||||
// Plots a horizontal histogram. #bins can be a positive integer or an ImPlotBin_ method. If #range is left unspecified, the min/max of #values will be used as the range.
|
||||
@@ -923,16 +926,18 @@ IMPLOT_API void PlotDummy(const char* label_id, ImPlotDummyFlags flags=0);
|
||||
|
||||
// The following can be used to render interactive elements and/or annotations.
|
||||
// Like the item plotting functions above, they apply to the current x and y
|
||||
// axes, which can be changed with `SetAxis/SetAxes`.
|
||||
// axes, which can be changed with `SetAxis/SetAxes`. These functions return true
|
||||
// when user interaction causes the provided coordinates to change. Additional
|
||||
// user interactions can be retrieved through the optional output parameters.
|
||||
|
||||
// Shows a draggable point at x,y. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragPoint(int id, double* x, double* y, const ImVec4& col, float size = 4, ImPlotDragToolFlags flags=0);
|
||||
IMPLOT_API bool DragPoint(int id, double* x, double* y, const ImVec4& col, float size = 4, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
// Shows a draggable vertical guide line at an x-value. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragLineX(int id, double* x, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags=0);
|
||||
IMPLOT_API bool DragLineX(int id, double* x, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
// Shows a draggable horizontal guide line at a y-value. #col defaults to ImGuiCol_Text.
|
||||
IMPLOT_API bool DragLineY(int id, double* y, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags=0);
|
||||
IMPLOT_API bool DragLineY(int id, double* y, const ImVec4& col, float thickness = 1, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
// Shows a draggable and resizeable rectangle.
|
||||
IMPLOT_API bool DragRect(int id, double* x1, double* y1, double* x2, double* y2, const ImVec4& col, ImPlotDragToolFlags flags=0);
|
||||
IMPLOT_API bool DragRect(int id, double* x1, double* y1, double* x2, double* y2, const ImVec4& col, ImPlotDragToolFlags flags = 0, bool* out_clicked = nullptr, bool* out_hovered = nullptr, bool* held = nullptr);
|
||||
|
||||
// Shows an annotation callout at a chosen point. Clamping keeps annotations in the plot area. Annotations are always rendered on top.
|
||||
IMPLOT_API void Annotation(double x, double y, const ImVec4& col, const ImVec2& pix_offset, bool clamp, bool round = false);
|
||||
@@ -1077,13 +1082,13 @@ IMPLOT_API void EndDragDropSource();
|
||||
IMPLOT_API ImPlotStyle& GetStyle();
|
||||
|
||||
// Style plot colors for current ImGui style (default).
|
||||
IMPLOT_API void StyleColorsAuto(ImPlotStyle* dst = NULL);
|
||||
IMPLOT_API void StyleColorsAuto(ImPlotStyle* dst = nullptr);
|
||||
// Style plot colors for ImGui "Classic".
|
||||
IMPLOT_API void StyleColorsClassic(ImPlotStyle* dst = NULL);
|
||||
IMPLOT_API void StyleColorsClassic(ImPlotStyle* dst = nullptr);
|
||||
// Style plot colors for ImGui "Dark".
|
||||
IMPLOT_API void StyleColorsDark(ImPlotStyle* dst = NULL);
|
||||
IMPLOT_API void StyleColorsDark(ImPlotStyle* dst = nullptr);
|
||||
// Style plot colors for ImGui "Light".
|
||||
IMPLOT_API void StyleColorsLight(ImPlotStyle* dst = NULL);
|
||||
IMPLOT_API void StyleColorsLight(ImPlotStyle* dst = nullptr);
|
||||
|
||||
// Use PushStyleX to temporarily modify your ImPlotStyle. The modification
|
||||
// will last until the matching call to PopStyleX. You MUST call a pop for
|
||||
@@ -1150,7 +1155,7 @@ IMPLOT_API ImPlotColormap AddColormap(const char* name, const ImU32* cols, int
|
||||
|
||||
// Returns the number of available colormaps (i.e. the built-in + user-added count).
|
||||
IMPLOT_API int GetColormapCount();
|
||||
// Returns a null terminated string name for a colormap given an index. Returns NULL if index is invalid.
|
||||
// Returns a null terminated string name for a colormap given an index. Returns nullptr if index is invalid.
|
||||
IMPLOT_API const char* GetColormapName(ImPlotColormap cmap);
|
||||
// Returns an index number for a colormap given a valid string name. Returns -1 if name is invalid.
|
||||
IMPLOT_API ImPlotColormap GetColormapIndex(const char* name);
|
||||
@@ -1179,18 +1184,18 @@ IMPLOT_API ImVec4 SampleColormap(float t, ImPlotColormap cmap = IMPLOT_AUTO);
|
||||
// Shows a vertical color scale with linear spaced ticks using the specified color map. Use double hashes to hide label (e.g. "##NoLabel"). If scale_min > scale_max, the scale to color mapping will be reversed.
|
||||
IMPLOT_API void ColormapScale(const char* label, double scale_min, double scale_max, const ImVec2& size = ImVec2(0,0), const char* format = "%g", ImPlotColormapScaleFlags flags = 0, ImPlotColormap cmap = IMPLOT_AUTO);
|
||||
// Shows a horizontal slider with a colormap gradient background. Optionally returns the color sampled at t in [0 1].
|
||||
IMPLOT_API bool ColormapSlider(const char* label, float* t, ImVec4* out = NULL, const char* format = "", ImPlotColormap cmap = IMPLOT_AUTO);
|
||||
IMPLOT_API bool ColormapSlider(const char* label, float* t, ImVec4* out = nullptr, const char* format = "", ImPlotColormap cmap = IMPLOT_AUTO);
|
||||
// Shows a button with a colormap gradient brackground.
|
||||
IMPLOT_API bool ColormapButton(const char* label, const ImVec2& size = ImVec2(0,0), ImPlotColormap cmap = IMPLOT_AUTO);
|
||||
|
||||
// When items in a plot sample their color from a colormap, the color is cached and does not change
|
||||
// unless explicitly overriden. Therefore, if you change the colormap after the item has already been plotted,
|
||||
// item colors will NOT update. If you need item colors to resample the new colormap, then use this
|
||||
// function to bust the cached colors. If #plot_title_id is NULL, then every item in EVERY existing plot
|
||||
// function to bust the cached colors. If #plot_title_id is nullptr, then every item in EVERY existing plot
|
||||
// will be cache busted. Otherwise only the plot specified by #plot_title_id will be busted. For the
|
||||
// latter, this function must be called in the same ImGui ID scope that the plot is in. You should rarely if ever
|
||||
// need this function, but it is available for applications that require runtime colormap swaps (e.g. Heatmaps demo).
|
||||
IMPLOT_API void BustColorCache(const char* plot_title_id = NULL);
|
||||
IMPLOT_API void BustColorCache(const char* plot_title_id = nullptr);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Input Mapping
|
||||
@@ -1200,9 +1205,9 @@ IMPLOT_API void BustColorCache(const char* plot_title_id = NULL);
|
||||
IMPLOT_API ImPlotInputMap& GetInputMap();
|
||||
|
||||
// Default input mapping: pan = LMB drag, box select = RMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
|
||||
IMPLOT_API void MapInputDefault(ImPlotInputMap* dst = NULL);
|
||||
IMPLOT_API void MapInputDefault(ImPlotInputMap* dst = nullptr);
|
||||
// Reverse input mapping: pan = RMB drag, box select = LMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
|
||||
IMPLOT_API void MapInputReverse(ImPlotInputMap* dst = NULL);
|
||||
IMPLOT_API void MapInputReverse(ImPlotInputMap* dst = nullptr);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Miscellaneous
|
||||
@@ -1227,18 +1232,18 @@ IMPLOT_API bool ShowColormapSelector(const char* label);
|
||||
// Shows ImPlot input map selector dropdown menu.
|
||||
IMPLOT_API bool ShowInputMapSelector(const char* label);
|
||||
// Shows ImPlot style editor block (not a window).
|
||||
IMPLOT_API void ShowStyleEditor(ImPlotStyle* ref = NULL);
|
||||
IMPLOT_API void ShowStyleEditor(ImPlotStyle* ref = nullptr);
|
||||
// Add basic help/info block for end users (not a window).
|
||||
IMPLOT_API void ShowUserGuide();
|
||||
// Shows ImPlot metrics/debug information window.
|
||||
IMPLOT_API void ShowMetricsWindow(bool* p_popen = NULL);
|
||||
IMPLOT_API void ShowMetricsWindow(bool* p_popen = nullptr);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Demo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Shows the ImPlot demo window (add implot_demo.cpp to your sources!)
|
||||
IMPLOT_API void ShowDemoWindow(bool* p_open = NULL);
|
||||
IMPLOT_API void ShowDemoWindow(bool* p_open = nullptr);
|
||||
|
||||
} // namespace ImPlot
|
||||
|
||||
@@ -1276,16 +1281,16 @@ namespace ImPlot {
|
||||
|
||||
// OBSOLETED in v0.13 -> PLANNED REMOVAL in v1.0
|
||||
IMPLOT_DEPRECATED( IMPLOT_API bool BeginPlot(const char* title_id,
|
||||
const char* x_label, // = NULL,
|
||||
const char* y_label, // = NULL,
|
||||
const char* x_label, // = nullptr,
|
||||
const char* y_label, // = nullptr,
|
||||
const ImVec2& size = ImVec2(-1,0),
|
||||
ImPlotFlags flags = ImPlotFlags_None,
|
||||
ImPlotAxisFlags x_flags = 0,
|
||||
ImPlotAxisFlags y_flags = 0,
|
||||
ImPlotAxisFlags y2_flags = ImPlotAxisFlags_AuxDefault,
|
||||
ImPlotAxisFlags y3_flags = ImPlotAxisFlags_AuxDefault,
|
||||
const char* y2_label = NULL,
|
||||
const char* y3_label = NULL) );
|
||||
const char* y2_label = nullptr,
|
||||
const char* y3_label = nullptr) );
|
||||
|
||||
} // namespace ImPlot
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2022 Evan Pezent
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,7 +20,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.14
|
||||
// ImPlot v0.17
|
||||
|
||||
// You may use this file to debug, understand or extend ImPlot features but we
|
||||
// don't provide any guarantee of forward compatibility!
|
||||
@@ -31,12 +31,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include "imgui/imgui_internal.h"
|
||||
#include "imgui_internal.h"
|
||||
|
||||
#ifndef IMPLOT_VERSION
|
||||
#error Must include implot.h before implot_internal.h
|
||||
@@ -400,18 +396,18 @@ struct ImPlotColormapData {
|
||||
_AppendTable(i);
|
||||
}
|
||||
|
||||
inline bool IsQual(ImPlotColormap cmap) const { return Quals[cmap]; }
|
||||
inline const char* GetName(ImPlotColormap cmap) const { return cmap < Count ? Text.Buf.Data + TextOffsets[cmap] : NULL; }
|
||||
inline ImPlotColormap GetIndex(const char* name) const { ImGuiID key = ImHashStr(name); return Map.GetInt(key,-1); }
|
||||
inline bool IsQual(ImPlotColormap cmap) const { return Quals[cmap]; }
|
||||
inline const char* GetName(ImPlotColormap cmap) const { return cmap < Count ? Text.Buf.Data + TextOffsets[cmap] : nullptr; }
|
||||
inline ImPlotColormap GetIndex(const char* name) const { ImGuiID key = ImHashStr(name); return Map.GetInt(key,-1); }
|
||||
|
||||
inline const ImU32* GetKeys(ImPlotColormap cmap) const { return &Keys[KeyOffsets[cmap]]; }
|
||||
inline int GetKeyCount(ImPlotColormap cmap) const { return KeyCounts[cmap]; }
|
||||
inline ImU32 GetKeyColor(ImPlotColormap cmap, int idx) const { return Keys[KeyOffsets[cmap]+idx]; }
|
||||
inline void SetKeyColor(ImPlotColormap cmap, int idx, ImU32 value) { Keys[KeyOffsets[cmap]+idx] = value; RebuildTables(); }
|
||||
inline const ImU32* GetKeys(ImPlotColormap cmap) const { return &Keys[KeyOffsets[cmap]]; }
|
||||
inline int GetKeyCount(ImPlotColormap cmap) const { return KeyCounts[cmap]; }
|
||||
inline ImU32 GetKeyColor(ImPlotColormap cmap, int idx) const { return Keys[KeyOffsets[cmap]+idx]; }
|
||||
inline void SetKeyColor(ImPlotColormap cmap, int idx, ImU32 value) { Keys[KeyOffsets[cmap]+idx] = value; RebuildTables(); }
|
||||
|
||||
inline const ImU32* GetTable(ImPlotColormap cmap) const { return &Tables[TableOffsets[cmap]]; }
|
||||
inline int GetTableSize(ImPlotColormap cmap) const { return TableSizes[cmap]; }
|
||||
inline ImU32 GetTableColor(ImPlotColormap cmap, int idx) const { return Tables[TableOffsets[cmap]+idx]; }
|
||||
inline const ImU32* GetTable(ImPlotColormap cmap) const { return &Tables[TableOffsets[cmap]]; }
|
||||
inline int GetTableSize(ImPlotColormap cmap) const { return TableSizes[cmap]; }
|
||||
inline ImU32 GetTableColor(ImPlotColormap cmap, int idx) const { return Tables[TableOffsets[cmap]+idx]; }
|
||||
|
||||
inline ImU32 LerpTable(ImPlotColormap cmap, float t) const {
|
||||
int off = TableOffsets[cmap];
|
||||
@@ -568,7 +564,7 @@ struct ImPlotTicker {
|
||||
|
||||
ImPlotTick& AddTick(double value, bool major, int level, bool show_label, const char* label) {
|
||||
ImPlotTick tick(value, major, level, show_label);
|
||||
if (show_label && label != NULL) {
|
||||
if (show_label && label != nullptr) {
|
||||
tick.TextOffset = TextBuffer.size();
|
||||
TextBuffer.append(label, label + strlen(label) + 1);
|
||||
tick.LabelSize = ImGui::CalcTextSize(TextBuffer.Buf.Data + tick.TextOffset);
|
||||
@@ -578,7 +574,7 @@ struct ImPlotTicker {
|
||||
|
||||
ImPlotTick& AddTick(double value, bool major, int level, bool show_label, ImPlotFormatter formatter, void* data) {
|
||||
ImPlotTick tick(value, major, level, show_label);
|
||||
if (show_label && formatter != NULL) {
|
||||
if (show_label && formatter != nullptr) {
|
||||
char buff[IMPLOT_LABEL_MAX_SIZE];
|
||||
tick.TextOffset = TextBuffer.size();
|
||||
formatter(tick.PlotPos, buff, sizeof(buff), data);
|
||||
@@ -677,23 +673,23 @@ struct ImPlotAxis
|
||||
Range.Min = 0;
|
||||
Range.Max = 1;
|
||||
Scale = ImPlotScale_Linear;
|
||||
TransformForward = TransformInverse = NULL;
|
||||
TransformData = NULL;
|
||||
TransformForward = TransformInverse = nullptr;
|
||||
TransformData = nullptr;
|
||||
FitExtents.Min = HUGE_VAL;
|
||||
FitExtents.Max = -HUGE_VAL;
|
||||
OrthoAxis = NULL;
|
||||
OrthoAxis = nullptr;
|
||||
ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
|
||||
ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
|
||||
LinkedMin = LinkedMax = NULL;
|
||||
LinkedMin = LinkedMax = nullptr;
|
||||
PickerLevel = 0;
|
||||
Datum1 = Datum2 = 0;
|
||||
PixelMin = PixelMax = 0;
|
||||
LabelOffset = -1;
|
||||
ColorMaj = ColorMin = ColorTick = ColorTxt = ColorBg = ColorHov = ColorAct = 0;
|
||||
ColorHiLi = IM_COL32_BLACK_TRANS;
|
||||
Formatter = NULL;
|
||||
FormatterData = NULL;
|
||||
Locator = NULL;
|
||||
Formatter = nullptr;
|
||||
FormatterData = nullptr;
|
||||
Locator = nullptr;
|
||||
Enabled = Hovered = Held = FitThisFrame = HasRange = HasFormatSpec = false;
|
||||
ShowDefaultTicks = true;
|
||||
}
|
||||
@@ -701,18 +697,18 @@ struct ImPlotAxis
|
||||
inline void Reset() {
|
||||
Enabled = false;
|
||||
Scale = ImPlotScale_Linear;
|
||||
TransformForward = TransformInverse = NULL;
|
||||
TransformData = NULL;
|
||||
TransformForward = TransformInverse = nullptr;
|
||||
TransformData = nullptr;
|
||||
LabelOffset = -1;
|
||||
HasFormatSpec = false;
|
||||
Formatter = NULL;
|
||||
FormatterData = NULL;
|
||||
Locator = NULL;
|
||||
Formatter = nullptr;
|
||||
FormatterData = nullptr;
|
||||
Locator = nullptr;
|
||||
ShowDefaultTicks = true;
|
||||
FitThisFrame = false;
|
||||
FitExtents.Min = HUGE_VAL;
|
||||
FitExtents.Max = -HUGE_VAL;
|
||||
OrthoAxis = NULL;
|
||||
OrthoAxis = nullptr;
|
||||
ConstraintRange = ImPlotRange(-INFINITY,INFINITY);
|
||||
ConstraintZoom = ImPlotRange(DBL_MIN,INFINITY);
|
||||
Ticker.Reset();
|
||||
@@ -810,7 +806,7 @@ struct ImPlotAxis
|
||||
|
||||
inline void UpdateTransformCache() {
|
||||
ScaleToPixel = (PixelMax - PixelMin) / Range.Size();
|
||||
if (TransformForward != NULL) {
|
||||
if (TransformForward != nullptr) {
|
||||
ScaleMin = TransformForward(Range.Min, TransformData);
|
||||
ScaleMax = TransformForward(Range.Max, TransformData);
|
||||
}
|
||||
@@ -821,7 +817,7 @@ struct ImPlotAxis
|
||||
}
|
||||
|
||||
inline float PlotToPixels(double plt) const {
|
||||
if (TransformForward != NULL) {
|
||||
if (TransformForward != nullptr) {
|
||||
double s = TransformForward(plt, TransformData);
|
||||
double t = (s - ScaleMin) / (ScaleMax - ScaleMin);
|
||||
plt = Range.Min + Range.Size() * t;
|
||||
@@ -832,7 +828,7 @@ struct ImPlotAxis
|
||||
|
||||
inline double PixelsToPlot(float pix) const {
|
||||
double plt = (pix - PixelMin) / ScaleToPixel + Range.Min;
|
||||
if (TransformInverse != NULL) {
|
||||
if (TransformInverse != nullptr) {
|
||||
double t = (plt - Range.Min) / Range.Size();
|
||||
double s = t * (ScaleMax - ScaleMin) + ScaleMin;
|
||||
plt = TransformInverse(s, TransformData);
|
||||
@@ -911,8 +907,9 @@ struct ImPlotAxis
|
||||
}
|
||||
|
||||
void PullLinks() {
|
||||
if (LinkedMin) { SetMin(*LinkedMin,true); }
|
||||
if (LinkedMax) { SetMax(*LinkedMax,true); }
|
||||
if (LinkedMin && LinkedMax) { SetRange(*LinkedMin, *LinkedMax); }
|
||||
else if (LinkedMin) { SetMin(*LinkedMin,true); }
|
||||
else if (LinkedMax) { SetMax(*LinkedMax,true); }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -969,9 +966,11 @@ struct ImPlotLegend
|
||||
ImPlotLegendFlags PreviousFlags;
|
||||
ImPlotLocation Location;
|
||||
ImPlotLocation PreviousLocation;
|
||||
ImVec2 Scroll;
|
||||
ImVector<int> Indices;
|
||||
ImGuiTextBuffer Labels;
|
||||
ImRect Rect;
|
||||
ImRect RectClamped;
|
||||
bool Hovered;
|
||||
bool Held;
|
||||
bool CanGoInside;
|
||||
@@ -981,6 +980,7 @@ struct ImPlotLegend
|
||||
CanGoInside = true;
|
||||
Hovered = Held = false;
|
||||
Location = PreviousLocation = ImPlotLocation_NorthWest;
|
||||
Scroll = ImVec2(0,0);
|
||||
}
|
||||
|
||||
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
|
||||
@@ -1071,7 +1071,7 @@ struct ImPlotPlot
|
||||
inline void ClearTextBuffer() { TextBuffer.Buf.shrink(0); }
|
||||
|
||||
inline void SetTitle(const char* title) {
|
||||
if (title && ImGui::FindRenderedTextEnd(title, NULL) != title) {
|
||||
if (title && ImGui::FindRenderedTextEnd(title, nullptr) != title) {
|
||||
TitleOffset = TextBuffer.size();
|
||||
TextBuffer.append(title, title + strlen(title) + 1);
|
||||
}
|
||||
@@ -1102,7 +1102,7 @@ struct ImPlotPlot
|
||||
}
|
||||
|
||||
inline void SetAxisLabel(ImPlotAxis& axis, const char* label) {
|
||||
if (label && ImGui::FindRenderedTextEnd(label, NULL) != label) {
|
||||
if (label && ImGui::FindRenderedTextEnd(label, nullptr) != label) {
|
||||
axis.LabelOffset = TextBuffer.size();
|
||||
TextBuffer.append(label, label + strlen(label) + 1);
|
||||
}
|
||||
@@ -1140,7 +1140,6 @@ struct ImPlotSubplot {
|
||||
ID = 0;
|
||||
Flags = PreviousFlags = ImPlotSubplotFlags_None;
|
||||
Rows = Cols = CurrentIdx = 0;
|
||||
FrameHovered = false;
|
||||
Items.Legend.Location = ImPlotLocation_North;
|
||||
Items.Legend.Flags = ImPlotLegendFlags_Horizontal|ImPlotLegendFlags_Outside;
|
||||
Items.Legend.CanGoInside = false;
|
||||
@@ -1166,7 +1165,7 @@ struct ImPlotNextPlotData
|
||||
for (int i = 0; i < ImAxis_COUNT; ++i) {
|
||||
HasRange[i] = false;
|
||||
Fit[i] = false;
|
||||
LinkedMin[i] = LinkedMax[i] = NULL;
|
||||
LinkedMin[i] = LinkedMax[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1219,9 +1218,6 @@ struct ImPlotContext {
|
||||
ImPlotAnnotationCollection Annotations;
|
||||
ImPlotTagCollection Tags;
|
||||
|
||||
// Flags
|
||||
bool ChildWindowMade;
|
||||
|
||||
// Style and Colormaps
|
||||
ImPlotStyle Style;
|
||||
ImVector<ImGuiColorMod> ColorModifiers;
|
||||
@@ -1292,9 +1288,10 @@ IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
|
||||
|
||||
// Lock Setup and call SetupFinish if necessary.
|
||||
static inline void SetupLock() {
|
||||
if (!GImPlot->CurrentPlot->SetupLocked)
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
if (!gp.CurrentPlot->SetupLocked)
|
||||
SetupFinish();
|
||||
GImPlot->CurrentPlot->SetupLocked = true;
|
||||
gp.CurrentPlot->SetupLocked = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1330,7 +1327,7 @@ bool BeginItemEx(const char* label_id, const _Fitter& fitter, ImPlotItemFlags fl
|
||||
IMPLOT_API void EndItem();
|
||||
|
||||
// Register or get an existing item from the current plot.
|
||||
IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool* just_created = NULL);
|
||||
IMPLOT_API ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool* just_created = nullptr);
|
||||
// Get a plot item from the current plot.
|
||||
IMPLOT_API ImPlotItem* GetItem(const char* label_id);
|
||||
// Gets the current item.
|
||||
@@ -1417,13 +1414,15 @@ IMPLOT_API void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bo
|
||||
|
||||
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
|
||||
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
|
||||
// Calculates the bounding box size of a legend
|
||||
// Calculates the bounding box size of a legend _before_ clipping.
|
||||
IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, bool vertical);
|
||||
// Clips calculated legend size
|
||||
IMPLOT_API bool ClampLegendRect(ImRect& legend_rect, const ImRect& outer_rect, const ImVec2& pad);
|
||||
// Renders legend entries into a bounding box
|
||||
IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, bool vertical, ImDrawList& DrawList);
|
||||
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
|
||||
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window! This is not thoroughly tested nor scrollable!).
|
||||
IMPLOT_API void ShowAltLegend(const char* title_id, bool vertical = true, const ImVec2 size = ImVec2(0,0), bool interactable = true);
|
||||
// Shows an legends's context menu.
|
||||
// Shows a legend's context menu.
|
||||
IMPLOT_API bool ShowLegendContextMenu(ImPlotLegend& legend, bool visible);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1442,7 +1441,7 @@ static inline const ImPlotNextItemData& GetItemData() { return GImPlot->NextItem
|
||||
|
||||
// Returns true if a color is set to be automatically determined
|
||||
static inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; }
|
||||
// Returns true if a style color is set to be automaticaly determined
|
||||
// Returns true if a style color is set to be automatically determined
|
||||
static inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); }
|
||||
// Returns the automatically deduced style color
|
||||
IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx);
|
||||
@@ -1452,9 +1451,9 @@ static inline ImVec4 GetStyleColorVec4(ImPlotCol idx) { return IsColorAuto(idx)
|
||||
static inline ImU32 GetStyleColorU32(ImPlotCol idx) { return ImGui::ColorConvertFloat4ToU32(GetStyleColorVec4(idx)); }
|
||||
|
||||
// Draws vertical text. The position is the bottom left of the text rect.
|
||||
IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMPLOT_API void AddTextVertical(ImDrawList *DrawList, ImVec2 pos, ImU32 col, const char* text_begin, const char* text_end = nullptr);
|
||||
// Draws multiline horizontal text centered.
|
||||
IMPLOT_API void AddTextCentered(ImDrawList* DrawList, ImVec2 top_center, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMPLOT_API void AddTextCentered(ImDrawList* DrawList, ImVec2 top_center, ImU32 col, const char* text_begin, const char* text_end = nullptr);
|
||||
// Calculates the size of vertical text
|
||||
static inline ImVec2 CalcTextSizeVertical(const char *text) {
|
||||
ImVec2 sz = ImGui::CalcTextSize(text);
|
||||
@@ -1593,7 +1592,7 @@ IMPLOT_API int FormatDateTime(const ImPlotTime& t, char* buffer, int size, ImPlo
|
||||
// #level = 0 for day, 1 for month, 2 for year. Modified by user interaction.
|
||||
// #t will be set when a day is clicked and the function will return true.
|
||||
// #t1 and #t2 are optional dates to highlight.
|
||||
IMPLOT_API bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime* t1 = NULL, const ImPlotTime* t2 = NULL);
|
||||
IMPLOT_API bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime* t1 = nullptr, const ImPlotTime* t2 = nullptr);
|
||||
// Shows a time picker widget block (hour/min/sec).
|
||||
// #t will be set when a new hour, minute, or sec is selected or am/pm is toggled, and the function will return true.
|
||||
IMPLOT_API bool ShowTimePicker(const char* id, ImPlotTime* t);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2020 Evan Pezent
|
||||
// Copyright (c) 2023 Evan Pezent
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -20,8 +20,9 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// ImPlot v0.14
|
||||
// ImPlot v0.17
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include "implot.h"
|
||||
#include "implot_internal.h"
|
||||
|
||||
@@ -81,7 +82,7 @@ static IMPLOT_INLINE float ImInvSqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
// unsigned long long ImU64; // 64-bit unsigned integer
|
||||
// (note: this list does *not* include `long`, `unsigned long` and `long double`)
|
||||
//
|
||||
// You can customize the supported types by defining IMPLOT_CUSTOM_NUMERIC_TYPES at compile time to define your own type list.
|
||||
// You can customize the supported types by defining IMPLOT_CUSTOM_NUMERIC_TYPES at compile time to define your own type list.
|
||||
// As an example, you could use the compile time define given by the line below in order to support only float and double.
|
||||
// -DIMPLOT_CUSTOM_NUMERIC_TYPES="(float)(double)"
|
||||
// In order to support all known C++ types, use:
|
||||
@@ -97,11 +98,11 @@ static IMPLOT_INLINE float ImInvSqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
#define _CAT(x, y) _CAT_(x, y)
|
||||
#define _CAT_(x,y) x ## y
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES(chain) _CAT(_INSTANTIATE_FOR_NUMERIC_TYPES_1 chain, _END)
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1(T) INSTANTIATE_MACRO(T); _INSTANTIATE_FOR_NUMERIC_TYPES_2
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2(T) INSTANTIATE_MACRO(T); _INSTANTIATE_FOR_NUMERIC_TYPES_1
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_2
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_1
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_1_END
|
||||
#define _INSTANTIATE_FOR_NUMERIC_TYPES_2_END
|
||||
#define CALL_INSTANTIATE_FOR_NUMERIC_TYPES() _INSTANTIATE_FOR_NUMERIC_TYPES(IMPLOT_NUMERIC_TYPES);
|
||||
#define CALL_INSTANTIATE_FOR_NUMERIC_TYPES() _INSTANTIATE_FOR_NUMERIC_TYPES(IMPLOT_NUMERIC_TYPES)
|
||||
|
||||
namespace ImPlot {
|
||||
|
||||
@@ -284,15 +285,15 @@ ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool*
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotItemGroup& Items = *gp.CurrentItems;
|
||||
ImGuiID id = Items.GetItemID(label_id);
|
||||
if (just_created != NULL)
|
||||
*just_created = Items.GetItem(id) == NULL;
|
||||
if (just_created != nullptr)
|
||||
*just_created = Items.GetItem(id) == nullptr;
|
||||
ImPlotItem* item = Items.GetOrAddItem(id);
|
||||
if (item->SeenThisFrame)
|
||||
return item;
|
||||
item->SeenThisFrame = true;
|
||||
int idx = Items.GetItemIndex(item);
|
||||
item->ID = id;
|
||||
if (!ImHasFlag(flags, ImPlotItemFlags_NoLegend) && ImGui::FindRenderedTextEnd(label_id, NULL) != label_id) {
|
||||
if (!ImHasFlag(flags, ImPlotItemFlags_NoLegend) && ImGui::FindRenderedTextEnd(label_id, nullptr) != label_id) {
|
||||
Items.Legend.Indices.push_back(idx);
|
||||
item->NameOffset = Items.Legend.Labels.size();
|
||||
Items.Legend.Labels.append(label_id, label_id + strlen(label_id) + 1);
|
||||
@@ -310,7 +311,7 @@ ImPlotItem* GetItem(const char* label_id) {
|
||||
|
||||
bool IsItemHidden(const char* label_id) {
|
||||
ImPlotItem* item = GetItem(label_id);
|
||||
return item != NULL && !item->Show;
|
||||
return item != nullptr && !item->Show;
|
||||
}
|
||||
|
||||
ImPlotItem* GetCurrentItem() {
|
||||
@@ -367,17 +368,17 @@ void BustItemCache() {
|
||||
|
||||
void BustColorCache(const char* plot_title_id) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
if (plot_title_id == NULL) {
|
||||
if (plot_title_id == nullptr) {
|
||||
BustItemCache();
|
||||
}
|
||||
else {
|
||||
ImGuiID id = ImGui::GetCurrentWindow()->GetID(plot_title_id);
|
||||
ImPlotPlot* plot = gp.Plots.GetByKey(id);
|
||||
if (plot != NULL)
|
||||
if (plot != nullptr)
|
||||
plot->Items.Reset();
|
||||
else {
|
||||
ImPlotSubplot* subplot = gp.Subplots.GetByKey(id);
|
||||
if (subplot != NULL)
|
||||
if (subplot != nullptr)
|
||||
subplot->Items.Reset();
|
||||
}
|
||||
}
|
||||
@@ -393,7 +394,7 @@ static const float ITEM_HIGHLIGHT_MARK_SCALE = 1.25f;
|
||||
// Begins a new item. Returns false if the item should not be plotted.
|
||||
bool BeginItem(const char* label_id, ImPlotItemFlags flags, ImPlotCol recolor_from) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotX() needs to be called between BeginPlot() and EndPlot()!");
|
||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "PlotX() needs to be called between BeginPlot() and EndPlot()!");
|
||||
SetupLock();
|
||||
bool just_created;
|
||||
ImPlotItem* item = RegisterOrGetItem(label_id, flags, &just_created);
|
||||
@@ -421,7 +422,7 @@ bool BeginItem(const char* label_id, ImPlotItemFlags flags, ImPlotCol recolor_fr
|
||||
// reset next item data
|
||||
gp.NextItemData.Reset();
|
||||
gp.PreviousItem = item;
|
||||
gp.CurrentItem = NULL;
|
||||
gp.CurrentItem = nullptr;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@@ -480,7 +481,7 @@ void EndItem() {
|
||||
gp.NextItemData.Reset();
|
||||
// set current item
|
||||
gp.PreviousItem = gp.CurrentItem;
|
||||
gp.CurrentItem = NULL;
|
||||
gp.CurrentItem = nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -784,7 +785,7 @@ struct Transformer1 {
|
||||
{ }
|
||||
|
||||
template <typename T> IMPLOT_INLINE float operator()(T p) const {
|
||||
if (TransformFwd != NULL) {
|
||||
if (TransformFwd != nullptr) {
|
||||
double s = TransformFwd(p, TransformData);
|
||||
double t = (s - ScaMin) / (ScaMax - ScaMin);
|
||||
p = PltMin + (PltMax - PltMin) * t;
|
||||
@@ -1286,7 +1287,7 @@ struct RendererShaded : RendererBase {
|
||||
return false;
|
||||
}
|
||||
const int intersect = (P11.y > P12.y && P22.y > P21.y) || (P12.y > P11.y && P21.y > P22.y);
|
||||
ImVec2 intersection = Intersection(P11,P21,P12,P22);
|
||||
const ImVec2 intersection = intersect == 0 ? ImVec2(0,0) : Intersection(P11,P21,P12,P22);
|
||||
draw_list._VtxWritePtr[0].pos = P11;
|
||||
draw_list._VtxWritePtr[0].uv = UV;
|
||||
draw_list._VtxWritePtr[0].col = Col;
|
||||
@@ -1568,6 +1569,10 @@ void RenderMarkers(const _Getter& getter, ImPlotMarker marker, float size, bool
|
||||
template <typename _Getter>
|
||||
void PlotLineEx(const char* label_id, const _Getter& getter, ImPlotLineFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<_Getter>(getter), flags, ImPlotCol_Line)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (getter.Count > 1) {
|
||||
if (ImHasFlag(flags, ImPlotLineFlags_Shaded) && s.RenderFill) {
|
||||
@@ -1639,6 +1644,10 @@ void PlotLineG(const char* label_id, ImPlotGetter getter_func, void* data, int c
|
||||
template <typename Getter>
|
||||
void PlotScatterEx(const char* label_id, const Getter& getter, ImPlotScatterFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_MarkerOutline)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImPlotMarker marker = s.Marker == ImPlotMarker_None ? ImPlotMarker_Circle: s.Marker;
|
||||
if (marker != ImPlotMarker_None) {
|
||||
@@ -1685,8 +1694,12 @@ void PlotScatterG(const char* label_id, ImPlotGetter getter_func, void* data, in
|
||||
template <typename Getter>
|
||||
void PlotStairsEx(const char* label_id, const Getter& getter, ImPlotStairsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter1<Getter>(getter), flags, ImPlotCol_Line)) {
|
||||
if (getter.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (getter.Count > 1 ) {
|
||||
if (getter.Count > 1) {
|
||||
if (s.RenderFill && ImHasFlag(flags,ImPlotStairsFlags_Shaded)) {
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
if (ImHasFlag(flags, ImPlotStairsFlags_PreStep))
|
||||
@@ -1745,6 +1758,10 @@ void PlotStairsG(const char* label_id, ImPlotGetter getter_func, void* data, int
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotShadedEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, ImPlotShadedFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<Getter1,Getter2>(getter1,getter2), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
if (s.RenderFill) {
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
@@ -1805,6 +1822,10 @@ void PlotShadedG(const char* label_id, ImPlotGetter getter_func1, void* data1, I
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotBarsVEx(const char* label_id, const Getter1& getter1, const Getter2 getter2, double width, ImPlotBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterBarV<Getter1,Getter2>(getter1,getter2,width), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
@@ -1825,6 +1846,10 @@ void PlotBarsVEx(const char* label_id, const Getter1& getter1, const Getter2 get
|
||||
template <typename Getter1, typename Getter2>
|
||||
void PlotBarsHEx(const char* label_id, const Getter1& getter1, const Getter2& getter2, double height, ImPlotBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterBarH<Getter1,Getter2>(getter1,getter2,height), flags, ImPlotCol_Fill)) {
|
||||
if (getter1.Count <= 0 || getter2.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_Fill]);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
@@ -1899,8 +1924,9 @@ void PlotBarGroups(const char* const label_ids[], const T* values, int item_coun
|
||||
const bool stack = ImHasFlag(flags, ImPlotBarGroupsFlags_Stacked);
|
||||
if (stack) {
|
||||
SetupLock();
|
||||
GImPlot->TempDouble1.resize(4*group_count);
|
||||
double* temp = GImPlot->TempDouble1.Data;
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
gp.TempDouble1.resize(4*group_count);
|
||||
double* temp = gp.TempDouble1.Data;
|
||||
double* neg = &temp[0];
|
||||
double* pos = &temp[group_count];
|
||||
double* curr_min = &temp[group_count*2];
|
||||
@@ -1980,6 +2006,10 @@ CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
template <typename _GetterPos, typename _GetterNeg>
|
||||
void PlotErrorBarsVEx(const char* label_id, const _GetterPos& getter_pos, const _GetterNeg& getter_neg, ImPlotErrorBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterPos,_GetterNeg>(getter_pos, getter_neg), flags, IMPLOT_AUTO)) {
|
||||
if (getter_pos.Count <= 0 || getter_neg.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_ErrorBar]);
|
||||
@@ -2001,6 +2031,10 @@ void PlotErrorBarsVEx(const char* label_id, const _GetterPos& getter_pos, const
|
||||
template <typename _GetterPos, typename _GetterNeg>
|
||||
void PlotErrorBarsHEx(const char* label_id, const _GetterPos& getter_pos, const _GetterNeg& getter_neg, ImPlotErrorBarsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterPos,_GetterNeg>(getter_pos, getter_neg), flags, IMPLOT_AUTO)) {
|
||||
if (getter_pos.Count <= 0 || getter_neg.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const ImU32 col = ImGui::GetColorU32(s.Colors[ImPlotCol_ErrorBar]);
|
||||
@@ -2058,13 +2092,17 @@ CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename _GetterM, typename _GetterB>
|
||||
void PlotStemsEx(const char* label_id, const _GetterM& get_mark, const _GetterB& get_base, ImPlotStemsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterM,_GetterB>(get_mark,get_base), flags, ImPlotCol_Line)) {
|
||||
void PlotStemsEx(const char* label_id, const _GetterM& getter_mark, const _GetterB& getter_base, ImPlotStemsFlags flags) {
|
||||
if (BeginItemEx(label_id, Fitter2<_GetterM,_GetterB>(getter_mark,getter_base), flags, ImPlotCol_Line)) {
|
||||
if (getter_mark.Count <= 0 || getter_base.Count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
// render stems
|
||||
if (s.RenderLine) {
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
RenderPrimitives2<RendererLineSegments2>(get_mark, get_base, col_line, s.LineWeight);
|
||||
RenderPrimitives2<RendererLineSegments2>(getter_mark, getter_base, col_line, s.LineWeight);
|
||||
}
|
||||
// render markers
|
||||
if (s.Marker != ImPlotMarker_None) {
|
||||
@@ -2072,7 +2110,7 @@ void PlotStemsEx(const char* label_id, const _GetterM& get_mark, const _GetterB&
|
||||
PushPlotClipRect(s.MarkerSize);
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerOutline]);
|
||||
const ImU32 col_fill = ImGui::GetColorU32(s.Colors[ImPlotCol_MarkerFill]);
|
||||
RenderMarkers<_GetterM>(get_mark, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
|
||||
RenderMarkers<_GetterM>(getter_mark, s.Marker, s.MarkerSize, s.RenderMarkerFill, col_fill, s.RenderMarkerLine, col_line, s.MarkerWeight);
|
||||
}
|
||||
EndItem();
|
||||
}
|
||||
@@ -2121,13 +2159,17 @@ template <typename T>
|
||||
void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLinesFlags flags, int offset, int stride) {
|
||||
const ImPlotRect lims = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
if (ImHasFlag(flags, ImPlotInfLinesFlags_Horizontal)) {
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> get_min(IndexerConst(lims.X.Min),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> get_max(IndexerConst(lims.X.Max),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
if (BeginItemEx(label_id, FitterY<GetterXY<IndexerConst,IndexerIdx<T>>>(get_min), flags, ImPlotCol_Line)) {
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> getter_min(IndexerConst(lims.X.Min),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
GetterXY<IndexerConst,IndexerIdx<T>> getter_max(IndexerConst(lims.X.Max),IndexerIdx<T>(values,count,offset,stride),count);
|
||||
if (BeginItemEx(label_id, FitterY<GetterXY<IndexerConst,IndexerIdx<T>>>(getter_min), flags, ImPlotCol_Line)) {
|
||||
if (count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
if (s.RenderLine)
|
||||
RenderPrimitives2<RendererLineSegments2>(get_min, get_max, col_line, s.LineWeight);
|
||||
RenderPrimitives2<RendererLineSegments2>(getter_min, getter_max, col_line, s.LineWeight);
|
||||
EndItem();
|
||||
}
|
||||
}
|
||||
@@ -2135,6 +2177,10 @@ void PlotInfLines(const char* label_id, const T* values, int count, ImPlotInfLin
|
||||
GetterXY<IndexerIdx<T>,IndexerConst> get_min(IndexerIdx<T>(values,count,offset,stride),IndexerConst(lims.Y.Min),count);
|
||||
GetterXY<IndexerIdx<T>,IndexerConst> get_max(IndexerIdx<T>(values,count,offset,stride),IndexerConst(lims.Y.Max),count);
|
||||
if (BeginItemEx(label_id, FitterX<GetterXY<IndexerIdx<T>,IndexerConst>>(get_min), flags, ImPlotCol_Line)) {
|
||||
if (count <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
const ImPlotNextItemData& s = GetItemData();
|
||||
const ImU32 col_line = ImGui::GetColorU32(s.Colors[ImPlotCol_Line]);
|
||||
if (s.RenderLine)
|
||||
@@ -2170,57 +2216,121 @@ IMPLOT_INLINE void RenderPieSlice(ImDrawList& draw_list, const ImPlotPoint& cent
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags) {
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != NULL, "PlotPieChart() needs to be called between BeginPlot() and EndPlot()!");
|
||||
ImDrawList & draw_list = *GetPlotDrawList();
|
||||
double PieChartSum(const T* values, int count, bool ignore_hidden) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
sum += (double)values[i];
|
||||
const bool normalize = ImHasFlag(flags,ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
ImPlotPoint center(x,y);
|
||||
PushPlotClipRect();
|
||||
if (ignore_hidden) {
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImPlotItemGroup& Items = *gp.CurrentItems;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (i >= Items.GetItemCount())
|
||||
break;
|
||||
|
||||
ImPlotItem* item = Items.GetItemByIndex(i);
|
||||
IM_ASSERT(item != nullptr);
|
||||
if (item->Show) {
|
||||
sum += (double)values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
sum += (double)values[i];
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChartEx(const char* const label_ids[], const T* values, int count, ImPlotPoint center, double radius, double angle0, ImPlotPieChartFlags flags) {
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
|
||||
const bool ignore_hidden = ImHasFlag(flags, ImPlotPieChartFlags_IgnoreHidden);
|
||||
const double sum = PieChartSum(values, count, ignore_hidden);
|
||||
const bool normalize = ImHasFlag(flags, ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
|
||||
double a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
double a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
ImPlotPoint Pmin = ImPlotPoint(x-radius,y-radius);
|
||||
ImPlotPoint Pmax = ImPlotPoint(x+radius,y+radius);
|
||||
ImPlotPoint Pmin = ImPlotPoint(center.x - radius, center.y - radius);
|
||||
ImPlotPoint Pmax = ImPlotPoint(center.x + radius, center.y + radius);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (BeginItemEx(label_ids[i], FitterRect(Pmin,Pmax))) {
|
||||
ImU32 col = GetCurrentItem()->Color;
|
||||
if (percent < 0.5) {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a1, col);
|
||||
}
|
||||
else {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5, col);
|
||||
RenderPieSlice(draw_list, center, radius, a0 + (a1 - a0) * 0.5, a1, col);
|
||||
ImPlotItem* item = GetItem(label_ids[i]);
|
||||
|
||||
const double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
const bool skip = sum <= 0.0 || (ignore_hidden && item != nullptr && !item->Show);
|
||||
if (!skip)
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
|
||||
if (BeginItemEx(label_ids[i], FitterRect(Pmin, Pmax))) {
|
||||
if (sum > 0.0) {
|
||||
ImU32 col = GetCurrentItem()->Color;
|
||||
if (percent < 0.5) {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a1, col);
|
||||
}
|
||||
else {
|
||||
RenderPieSlice(draw_list, center, radius, a0, a0 + (a1 - a0) * 0.5, col);
|
||||
RenderPieSlice(draw_list, center, radius, a0 + (a1 - a0) * 0.5, a1, col);
|
||||
}
|
||||
}
|
||||
EndItem();
|
||||
}
|
||||
a0 = a1;
|
||||
if (!skip)
|
||||
a0 = a1;
|
||||
}
|
||||
if (fmt != NULL) {
|
||||
a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
}
|
||||
|
||||
int PieChartFormatter(double value, char* buff, int size, void* data) {
|
||||
const char* fmt = (const char*)data;
|
||||
return snprintf(buff, size, fmt, value);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags) {
|
||||
PlotPieChart<T>(label_ids, values, count, x, y, radius, PieChartFormatter, (void*)fmt, angle0, flags);
|
||||
}
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart<T>(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags);
|
||||
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
#undef INSTANTIATE_MACRO
|
||||
|
||||
template <typename T>
|
||||
void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data, double angle0, ImPlotPieChartFlags flags) {
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "PlotPieChart() needs to be called between BeginPlot() and EndPlot()!");
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
|
||||
const bool ignore_hidden = ImHasFlag(flags, ImPlotPieChartFlags_IgnoreHidden);
|
||||
const double sum = PieChartSum(values, count, ignore_hidden);
|
||||
const bool normalize = ImHasFlag(flags, ImPlotPieChartFlags_Normalize) || sum > 1.0;
|
||||
ImPlotPoint center(x, y);
|
||||
|
||||
PushPlotClipRect();
|
||||
PlotPieChartEx(label_ids, values, count, center, radius, angle0, flags);
|
||||
if (fmt != nullptr) {
|
||||
double a0 = angle0 * 2 * IM_PI / 360.0;
|
||||
double a1 = angle0 * 2 * IM_PI / 360.0;
|
||||
char buffer[32];
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ImPlotItem* item = GetItem(label_ids[i]);
|
||||
double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (item->Show) {
|
||||
ImFormatString(buffer, 32, fmt, (double)values[i]);
|
||||
ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
double angle = a0 + (a1 - a0) * 0.5;
|
||||
ImVec2 pos = PlotToPixels(center.x + 0.5 * radius * cos(angle), center.y + 0.5 * radius * sin(angle),IMPLOT_AUTO,IMPLOT_AUTO);
|
||||
ImU32 col = CalcTextColor(ImGui::ColorConvertU32ToFloat4(item->Color));
|
||||
draw_list.AddText(pos - size * 0.5f, col, buffer);
|
||||
IM_ASSERT(item != nullptr);
|
||||
|
||||
const double percent = normalize ? (double)values[i] / sum : (double)values[i];
|
||||
const bool skip = ignore_hidden && item != nullptr && !item->Show;
|
||||
|
||||
if (!skip) {
|
||||
a1 = a0 + 2 * IM_PI * percent;
|
||||
if (item->Show) {
|
||||
fmt((double)values[i], buffer, 32, fmt_data);
|
||||
ImVec2 size = ImGui::CalcTextSize(buffer);
|
||||
double angle = a0 + (a1 - a0) * 0.5;
|
||||
ImVec2 pos = PlotToPixels(center.x + 0.5 * radius * cos(angle), center.y + 0.5 * radius * sin(angle), IMPLOT_AUTO, IMPLOT_AUTO);
|
||||
ImU32 col = CalcTextColor(ImGui::ColorConvertU32ToFloat4(item->Color));
|
||||
draw_list.AddText(pos - size * 0.5f, col, buffer);
|
||||
}
|
||||
a0 = a1;
|
||||
}
|
||||
a0 = a1;
|
||||
}
|
||||
}
|
||||
PopPlotClipRect();
|
||||
}
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart<T>(const char* const label_ids[], const T* values, int count, double x, double y, double radius, const char* fmt, double angle0, ImPlotPieChartFlags flags);
|
||||
#define INSTANTIATE_MACRO(T) template IMPLOT_API void PlotPieChart(const char* const label_ids[], const T* values, int count, double x, double y, double radius, ImPlotFormatter fmt, void* fmt_data, double angle0, ImPlotPieChartFlags flags);
|
||||
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||
#undef INSTANTIATE_MACRO
|
||||
|
||||
@@ -2253,7 +2363,8 @@ struct GetterHeatmapRowMaj {
|
||||
rect.Pos = p;
|
||||
rect.HalfSize = HalfSize;
|
||||
const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f);
|
||||
rect.Color = GImPlot->ColormapData.LerpTable(GImPlot->Style.Colormap, t);
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
rect.Color = gp.ColormapData.LerpTable(gp.Style.Colormap, t);
|
||||
return rect;
|
||||
}
|
||||
const T* const Values;
|
||||
@@ -2280,14 +2391,15 @@ struct GetterHeatmapColMaj {
|
||||
{ }
|
||||
template <typename I> IMPLOT_INLINE RectC operator()(I idx) const {
|
||||
double val = (double)Values[idx];
|
||||
const int r = idx % Cols;
|
||||
const int c = idx / Cols;
|
||||
const int r = idx % Rows;
|
||||
const int c = idx / Rows;
|
||||
const ImPlotPoint p(XRef + HalfSize.x + c*Width, YRef + YDir * (HalfSize.y + r*Height));
|
||||
RectC rect;
|
||||
rect.Pos = p;
|
||||
rect.HalfSize = HalfSize;
|
||||
const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f);
|
||||
rect.Color = GImPlot->ColormapData.LerpTable(GImPlot->Style.Colormap, t);
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
rect.Color = gp.ColormapData.LerpTable(gp.Style.Colormap, t);
|
||||
return rect;
|
||||
}
|
||||
const T* const Values;
|
||||
@@ -2324,7 +2436,7 @@ void RenderHeatmap(ImDrawList& draw_list, const T* values, int rows, int cols, d
|
||||
RenderPrimitives1<RendererRectC>(getter);
|
||||
}
|
||||
// labels
|
||||
if (fmt != NULL) {
|
||||
if (fmt != nullptr) {
|
||||
const double w = (bounds_max.x - bounds_min.x) / cols;
|
||||
const double h = (bounds_max.y - bounds_min.y) / rows;
|
||||
const ImPlotPoint half_size(w*0.5,h*0.5);
|
||||
@@ -2371,6 +2483,10 @@ void RenderHeatmap(ImDrawList& draw_list, const T* values, int rows, int cols, d
|
||||
template <typename T>
|
||||
void PlotHeatmap(const char* label_id, const T* values, int rows, int cols, double scale_min, double scale_max, const char* fmt, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, ImPlotHeatmapFlags flags) {
|
||||
if (BeginItemEx(label_id, FitterRect(bounds_min, bounds_max))) {
|
||||
if (rows <= 0 || cols <= 0) {
|
||||
EndItem();
|
||||
return;
|
||||
}
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
const bool col_maj = ImHasFlag(flags, ImPlotHeatmapFlags_ColMajor);
|
||||
RenderHeatmap(draw_list, values, rows, cols, scale_min, scale_max, fmt, bounds_min, bounds_max, true, col_maj);
|
||||
@@ -2408,8 +2524,9 @@ double PlotHistogram(const char* label_id, const T* values, int count, int bins,
|
||||
else
|
||||
width = range.Size() / bins;
|
||||
|
||||
ImVector<double>& bin_centers = GImPlot->TempDouble1;
|
||||
ImVector<double>& bin_counts = GImPlot->TempDouble2;
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImVector<double>& bin_centers = gp.TempDouble1;
|
||||
ImVector<double>& bin_counts = gp.TempDouble2;
|
||||
bin_centers.resize(bins);
|
||||
bin_counts.resize(bins);
|
||||
int below = 0;
|
||||
@@ -2506,7 +2623,8 @@ double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count
|
||||
|
||||
const int bins = x_bins * y_bins;
|
||||
|
||||
ImVector<double>& bin_counts = GImPlot->TempDouble1;
|
||||
ImPlotContext& gp = *GImPlot;
|
||||
ImVector<double>& bin_counts = gp.TempDouble1;
|
||||
bin_counts.resize(bins);
|
||||
|
||||
for (int b = 0; b < bins; ++b)
|
||||
@@ -2533,8 +2651,12 @@ double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count
|
||||
}
|
||||
|
||||
if (BeginItemEx(label_id, FitterRect(range))) {
|
||||
if (y_bins <= 0 || x_bins <= 0) {
|
||||
EndItem();
|
||||
return max_count;
|
||||
}
|
||||
ImDrawList& draw_list = *GetPlotDrawList();
|
||||
RenderHeatmap(draw_list, &bin_counts.Data[0], y_bins, x_bins, 0, max_count, NULL, range.Min(), range.Max(), false, col_maj);
|
||||
RenderHeatmap(draw_list, &bin_counts.Data[0], y_bins, x_bins, 0, max_count, nullptr, range.Min(), range.Max(), false, col_maj);
|
||||
EndItem();
|
||||
}
|
||||
return max_count;
|
||||
@@ -2591,8 +2713,8 @@ void PlotDigitalEx(const char* label_id, Getter getter, ImPlotDigitalFlags flags
|
||||
//do not extend plot outside plot range
|
||||
if (pMin.x < x_axis.PixelMin) pMin.x = x_axis.PixelMin;
|
||||
if (pMax.x < x_axis.PixelMin) pMax.x = x_axis.PixelMin;
|
||||
if (pMin.x > x_axis.PixelMax) pMin.x = x_axis.PixelMax;
|
||||
if (pMax.x > x_axis.PixelMax) pMax.x = x_axis.PixelMax;
|
||||
if (pMin.x > x_axis.PixelMax) pMin.x = x_axis.PixelMax - 1; //fix issue related to https://github.com/ocornut/imgui/issues/3976
|
||||
if (pMax.x > x_axis.PixelMax) pMax.x = x_axis.PixelMax - 1; //fix issue related to https://github.com/ocornut/imgui/issues/3976
|
||||
//plot a rectangle that extends up to x2 with y1 height
|
||||
if ((pMax.x > pMin.x) && (gp.CurrentPlot->PlotRect.Contains(pMin) || gp.CurrentPlot->PlotRect.Contains(pMax))) {
|
||||
// ImVec4 colAlpha = item->Color;
|
||||
@@ -2647,7 +2769,7 @@ void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PlotText(const char* text, double x, double y, const ImVec2& pixel_offset, ImPlotTextFlags flags) {
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != NULL, "PlotText() needs to be called between BeginPlot() and EndPlot()!");
|
||||
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "PlotText() needs to be called between BeginPlot() and EndPlot()!");
|
||||
SetupLock();
|
||||
ImDrawList & draw_list = *GetPlotDrawList();
|
||||
PushPlotClipRect();
|
||||
|
||||
+1
-1
Submodule core/deps/libchdr updated: 2781322c4a...7239eab39c.
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7.2)
|
||||
|
||||
project(libelf C)
|
||||
|
||||
add_library(elf STATIC EXCLUDE_FROM_ALL src/elf.c src/elf32.c src/elf64.c)
|
||||
target_include_directories(elf PUBLIC include)
|
||||
target_link_libraries(elf)
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#ifndef __ELF_DEBUG_32_H__
|
||||
#define __ELF_DEBUG_32_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include "elf32.h"
|
||||
|
||||
void elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, int flags);
|
||||
|
||||
#endif /* __ELF_DEBUG_32_H__ */
|
||||
@@ -1,376 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "elf.h"
|
||||
#include "debug.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef UINT64_MAX
|
||||
# define UINT64_MAX (__UINT64_C(18446744073709551615))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checks that elfFile points to a valid elf file. Returns 0 if the elf
|
||||
* file is valid, < 0 if invalid.
|
||||
*/
|
||||
|
||||
#define ISELF32(elfFile) ( ((struct Elf32_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS32 )
|
||||
#define ISELF64(elfFile) ( ((struct Elf64_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS64 )
|
||||
|
||||
int
|
||||
elf_checkFile(void *elfFile)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_checkFile((Elf32_Header*)elfFile)
|
||||
: elf64_checkFile((Elf64_Header*)elfFile);
|
||||
}
|
||||
|
||||
/* Program Headers Access functions */
|
||||
uint16_t
|
||||
elf_getNumProgramHeaders(void *elfFile)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getNumProgramHeaders((Elf32_Header*)elfFile)
|
||||
: elf64_getNumProgramHeaders((Elf64_Header*)elfFile);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf_getProgramHeaderFlags(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderFlags((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderFlags((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf_getProgramHeaderType(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderType((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderType((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderPaddr((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderPaddr((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderVaddr((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderVaddr((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderMemorySize((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderMemorySize((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderFileSize((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderFileSize((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getProgramHeaderOffset(void *elfFile, uint16_t ph)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getProgramHeaderOffset((Elf32_Header*)elfFile, ph)
|
||||
: elf64_getProgramHeaderOffset((Elf64_Header*)elfFile, ph);
|
||||
}
|
||||
|
||||
char *
|
||||
elf_getSegmentStringTable(void *elfFile)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSegmentStringTable((Elf32_Header*)elfFile)
|
||||
: elf64_getSegmentStringTable((Elf64_Header*)elfFile);
|
||||
}
|
||||
|
||||
char *
|
||||
elf_getStringTable(void *elfFile, int string_segment)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getStringTable((Elf32_Header*)elfFile)
|
||||
: elf64_getStringTable((Elf64_Header*)elfFile, string_segment);
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
elf_getNumSections(void *elfFile)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getNumSections((Elf32_Header*)elfFile)
|
||||
: elf64_getNumSections((Elf64_Header*)elfFile);
|
||||
}
|
||||
|
||||
char *
|
||||
elf_getSectionName(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionName((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionName((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf_getSectionFlags(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionFlags((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionFlags((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf_getSectionType(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionType((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionType((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getSectionSize(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionSize((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionSize((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getSectionLink(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionLink((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionLink((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getSectionAddr(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionAddr((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSectionAddr((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
elf_getSection(void *elfFile, int i)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSection((Elf32_Header*)elfFile, i)
|
||||
: elf64_getSection((Elf64_Header*)elfFile, i);
|
||||
}
|
||||
|
||||
void *
|
||||
elf_getSectionNamed(void *elfFile, char *_str)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getSectionNamed((Elf32_Header*)elfFile, _str)
|
||||
: elf64_getSectionNamed((Elf64_Header*)elfFile, _str);
|
||||
}
|
||||
|
||||
void
|
||||
elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
|
||||
uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset,
|
||||
uint64_t *p_memsz)
|
||||
{
|
||||
*p_vaddr = elf_getProgramHeaderVaddr(elfFile, ph);
|
||||
*p_paddr = elf_getProgramHeaderPaddr(elfFile, ph);
|
||||
*p_filesz = elf_getProgramHeaderFileSize(elfFile, ph);
|
||||
*p_offset = elf_getProgramHeaderOffset(elfFile, ph);
|
||||
*p_memsz = elf_getProgramHeaderMemorySize(elfFile, ph);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_getEntryPoint(void *elfFile)
|
||||
{
|
||||
return ISELF32 (elfFile)
|
||||
? elf32_getEntryPoint ((Elf32_Header*)elfFile)
|
||||
: elf64_getEntryPoint ((Elf64_Header*)elfFile);
|
||||
}
|
||||
|
||||
void
|
||||
elf_fprintf(FILE *f, void *file, int size, const char *name, int flags)
|
||||
{
|
||||
elf32_fprintf(f, (Elf32_Header*)file, size, name, flags);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max)
|
||||
{
|
||||
uint64_t mem_min = UINT64_MAX;
|
||||
uint64_t mem_max = 0;
|
||||
int i;
|
||||
|
||||
if (elf_checkFile(elfFile) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
|
||||
uint64_t sect_min, sect_max;
|
||||
|
||||
if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (phys) {
|
||||
sect_min = elf_getProgramHeaderPaddr(elfFile, i);
|
||||
} else {
|
||||
sect_min = elf_getProgramHeaderVaddr(elfFile, i);
|
||||
}
|
||||
|
||||
sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i);
|
||||
|
||||
if (sect_max > mem_max) {
|
||||
mem_max = sect_max;
|
||||
}
|
||||
if (sect_min < mem_min) {
|
||||
mem_min = sect_min;
|
||||
}
|
||||
}
|
||||
*min = mem_min;
|
||||
*max = mem_max;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
|
||||
{
|
||||
uint64_t min = elf_getProgramHeaderVaddr(elfFile, ph);
|
||||
uint64_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph);
|
||||
if (vaddr >= min && vaddr < max) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
|
||||
{
|
||||
uint64_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph);
|
||||
uint64_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph);
|
||||
uint64_t paddr;
|
||||
|
||||
paddr = vaddr - ph_virt + ph_phys;
|
||||
|
||||
return paddr;
|
||||
}
|
||||
|
||||
bool
|
||||
elf_loadFile(void *elfFile, bool phys)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (elf_checkFile(elfFile) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
|
||||
/* Load that section */
|
||||
uint64_t dest, src;
|
||||
size_t len;
|
||||
if (phys) {
|
||||
dest = elf_getProgramHeaderPaddr(elfFile, i);
|
||||
} else {
|
||||
dest = elf_getProgramHeaderVaddr(elfFile, i);
|
||||
}
|
||||
len = elf_getProgramHeaderFileSize(elfFile, i);
|
||||
src = (uint64_t) (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i);
|
||||
memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len);
|
||||
dest += len;
|
||||
memset((void*) (uintptr_t) dest, 0, elf_getProgramHeaderMemorySize(elfFile, i) - len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,392 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
|
||||
/*
|
||||
Authors: Luke Deller, Ben Leslie
|
||||
Created: 24/Sep/1999
|
||||
*/
|
||||
|
||||
/**
|
||||
\file
|
||||
|
||||
\brief Generic ELF library
|
||||
|
||||
The ELF library is designed to make the task of parsing and getting information
|
||||
out of an ELF file easier.
|
||||
|
||||
It provides function to obtain the various different fields in the ELF header, and
|
||||
the program and segment information.
|
||||
|
||||
Also importantly, it provides a function elf_loadFile which will load a given
|
||||
ELF file into memory.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ELF_ELF_H__
|
||||
#define __ELF_ELF_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "elf32.h"
|
||||
#include "elf64.h"
|
||||
|
||||
struct elf_symbol {
|
||||
uint32_t st_name; // Symbol name (string table index)
|
||||
uint32_t st_value; // Symbol value
|
||||
uint32_t st_size; // Symbol size
|
||||
uint8_t st_info; // Symbol type and binding
|
||||
uint8_t st_other; // No defined meaning, 0
|
||||
uint16_t st_shndx; // Section index
|
||||
};
|
||||
|
||||
struct elf64_symbol {
|
||||
uint32_t st_name;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
uint16_t st_shndx;
|
||||
uint64_t st_value;
|
||||
uint64_t st_size;
|
||||
};
|
||||
|
||||
/*
|
||||
* constants for Elf32_Phdr.p_flags
|
||||
*/
|
||||
#define PF_X 1 /* readable segment */
|
||||
#define PF_W 2 /* writeable segment */
|
||||
#define PF_R 4 /* executable segment */
|
||||
|
||||
/*
|
||||
* constants for indexing into Elf64_Header_t.e_ident
|
||||
*/
|
||||
#define EI_MAG0 0
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
|
||||
#define ELFMAG0 '\177'
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
/* Section Header type bits */
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
|
||||
/* Section Header flag bits */
|
||||
#define SHF_WRITE 1
|
||||
#define SHF_ALLOC 2
|
||||
#define SHF_EXECINSTR 4
|
||||
|
||||
/**/
|
||||
#define ELF_PRINT_PROGRAM_HEADERS 1
|
||||
#define ELF_PRINT_SECTIONS 2
|
||||
#define ELF_PRINT_ALL (ELF_PRINT_PROGRAM_HEADERS | ELF_PRINT_SECTIONS)
|
||||
|
||||
/* Symbol types */
|
||||
#define STT_FUNC 2 /* Function, code */
|
||||
|
||||
/**
|
||||
* Checks that elfFile points to a valid elf file.
|
||||
*
|
||||
* @param elfFile Potential ELF file to check
|
||||
*
|
||||
* \return 0 on success. -1 if not and elf, -2 if not 32 bit.
|
||||
*/
|
||||
int elf_checkFile(void *elfFile);
|
||||
|
||||
/**
|
||||
* Determine number of sections in an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header.
|
||||
*
|
||||
* \return Number of sections in the ELF file.
|
||||
*/
|
||||
unsigned elf_getNumSections(void *elfFile);
|
||||
|
||||
/**
|
||||
* Determine number of program headers in an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header.
|
||||
*
|
||||
* \return Number of program headers in the ELF file.
|
||||
*/
|
||||
uint16_t elf_getNumProgramHeaders(void *elfFile);
|
||||
|
||||
/**
|
||||
* Return the base physical address of given program header in an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header
|
||||
*/
|
||||
uint64_t elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the base virtual address of given program header in an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header
|
||||
*/
|
||||
uint64_t elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the memory size of a given program header in an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header
|
||||
*/
|
||||
uint64_t elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the file size of a given program header in an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The file size of the specified program header
|
||||
*/
|
||||
uint64_t elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the start offset of he file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The offset of this program header with relation to the start
|
||||
* of the elfFile.
|
||||
*/
|
||||
uint64_t elf_getProgramHeaderOffset(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the flags for a given program header
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The flags of a given program header
|
||||
*/
|
||||
uint32_t elf_getProgramHeaderFlags(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the type for a given program header
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The type of a given program header
|
||||
*/
|
||||
uint32_t elf_getProgramHeaderType(void *elfFile, uint16_t ph);
|
||||
|
||||
/**
|
||||
* Return the physical translation of a physical address, with respect
|
||||
* to a given program header
|
||||
*
|
||||
*/
|
||||
uint64_t elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* \return true if the address in in this program header
|
||||
*/
|
||||
bool elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
|
||||
|
||||
/**
|
||||
* Determine the memory bounds of an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param phys If true return bounds of physical memory, otherwise return
|
||||
* bounds of virtual memory
|
||||
* @param min Pointer to return value of the minimum
|
||||
* @param max Pointer to return value of the maximum
|
||||
*
|
||||
* \return true on success. false on failure, if for example, it is an invalid ELF file
|
||||
*/
|
||||
bool elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max);
|
||||
|
||||
/**
|
||||
* Find the entry point of an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
*
|
||||
* \return The entry point address as a 64-bit integer.
|
||||
*/
|
||||
uint64_t elf_getEntryPoint(void *elfFile);
|
||||
|
||||
/**
|
||||
* Load an ELF file into memory
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF file
|
||||
* @param phys If true load using the physical address, otherwise using the virtual addresses
|
||||
*
|
||||
* \return true on success, false on failure.
|
||||
*
|
||||
* The function assumes that the ELF file is loaded in memory at some
|
||||
* address different to the target address at which it will be loaded.
|
||||
* It also assumes direct access to the source and destination address, i.e:
|
||||
* Memory must be ale to me loaded with a simple memcpy.
|
||||
*
|
||||
* Obviously this also means that if we are loading a 64bit ELF on a 32bit
|
||||
* platform, we assume that any memory address are within the first 4GB.
|
||||
*
|
||||
*/
|
||||
bool elf_loadFile(void *elfFile, bool phys);
|
||||
|
||||
char *elf_getStringTable(void *elfFile, int string_segment);
|
||||
char *elf_getSegmentStringTable(void *elfFile);
|
||||
void *elf_getSectionNamed(void *elfFile, char *str);
|
||||
char *elf_getSectionName(void *elfFile, int i);
|
||||
uint64_t elf_getSectionSize(void *elfFile, int i);
|
||||
uint64_t elf_getSectionLink(void *elfFile, int i);
|
||||
uint64_t elf_getSectionAddr(void *elfFile, int i);
|
||||
|
||||
/**
|
||||
* Return the flags for a given sections
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param i Index of the sections
|
||||
*
|
||||
* \return The flags of a given section
|
||||
*/
|
||||
uint32_t elf_getSectionFlags(void *elfFile, int i);
|
||||
|
||||
/**
|
||||
* Return the type for a given sections
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF header
|
||||
* @param i Index of the sections
|
||||
*
|
||||
* \return The type of a given section
|
||||
*/
|
||||
uint32_t elf_getSectionType(void *elfFile, int i);
|
||||
|
||||
void *elf_getSection(void *elfFile, int i);
|
||||
void elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
|
||||
uint64_t *p_paddr, uint64_t *p_filesz,
|
||||
uint64_t *p_offset, uint64_t *p_memsz);
|
||||
|
||||
|
||||
/**
|
||||
* output the details of an ELF file to the stream f
|
||||
*/
|
||||
void elf_fprintf(FILE *f, void *elfFile, int size, const char *name, int flags);
|
||||
|
||||
#define SHT_DYNSYM 0xB
|
||||
#if 0
|
||||
/*
|
||||
* Returns a pointer to the program segment table, which is an array of
|
||||
* ELF64_Phdr_t structs. The size of the array can be found by calling
|
||||
* getNumProgramSegments.
|
||||
*/
|
||||
struct Elf32_Phdr *elf_getProgramSegmentTable(void *elfFile);
|
||||
#endif
|
||||
#if 0
|
||||
/**
|
||||
* Returns a pointer to the program segment table, which is an array of
|
||||
* ELF64_Phdr_t structs. The size of the array can be found by calling
|
||||
* getNumProgramSegments.
|
||||
*/
|
||||
struct Elf32_Shdr *elf_getSectionTable(void *elfFile);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,329 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#include "elf.h"
|
||||
#include "debug.h"
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int
|
||||
elf32_checkFile(struct Elf32_Header *file)
|
||||
{
|
||||
if (file->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| file->e_ident[EI_MAG1] != ELFMAG1
|
||||
|| file->e_ident[EI_MAG2] != ELFMAG2
|
||||
|| file->e_ident[EI_MAG3] != ELFMAG3)
|
||||
return -1; /* not an elf file */
|
||||
if (file->e_ident[EI_CLASS] != ELFCLASS32)
|
||||
return -2; /* not 32-bit file */
|
||||
return 0; /* elf file looks OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of program segments in this elf file.
|
||||
*/
|
||||
unsigned
|
||||
elf32_getNumSections(struct Elf32_Header *elfFile)
|
||||
{
|
||||
return elfFile->e_shnum;
|
||||
}
|
||||
|
||||
char *
|
||||
elf32_getStringTable(struct Elf32_Header *elfFile)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
return (char *)elfFile + sections[elfFile->e_shstrndx].sh_offset;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the program segment table, which is an array of
|
||||
* ELF32_Phdr_t structs. The size of the array can be found by calling
|
||||
* getNumProgramSegments. */
|
||||
struct Elf32_Phdr *
|
||||
elf32_getProgramSegmentTable(struct Elf32_Header *elfFile)
|
||||
{
|
||||
struct Elf32_Header *fileHdr = elfFile;
|
||||
return (struct Elf32_Phdr *) (fileHdr->e_phoff + (size_t) elfFile);
|
||||
}
|
||||
|
||||
/* Returns the number of program segments in this elf file. */
|
||||
uint16_t
|
||||
elf32_getNumProgramHeaders(struct Elf32_Header *elfFile)
|
||||
{
|
||||
struct Elf32_Header *fileHdr = elfFile;
|
||||
return fileHdr->e_phnum;
|
||||
}
|
||||
|
||||
char *
|
||||
elf32_getSectionName(struct Elf32_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
char *str_table = elf32_getSegmentStringTable(elfFile);
|
||||
if (str_table == NULL) {
|
||||
return "<corrupted>";
|
||||
} else {
|
||||
return str_table + sections[i].sh_name;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf32_getSectionSize(struct Elf32_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
return sections[i].sh_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf32_getSectionLink(struct Elf32_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
return sections[i].sh_link;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf32_getSectionAddr(struct Elf32_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
return sections[i].sh_addr;
|
||||
}
|
||||
|
||||
void *
|
||||
elf32_getSection(struct Elf32_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
return (char *)elfFile + sections[i].sh_offset;
|
||||
}
|
||||
|
||||
void *
|
||||
elf32_getSectionNamed(struct Elf32_Header *elfFile, char *str)
|
||||
{
|
||||
int numSections = elf32_getNumSections(elfFile);
|
||||
int i;
|
||||
for (i = 0; i < numSections; i++) {
|
||||
if (strcmp(str, elf32_getSectionName(elfFile, i)) == 0) {
|
||||
return elf32_getSection(elfFile, i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
elf32_getSegmentStringTable(struct Elf32_Header *elfFile)
|
||||
{
|
||||
struct Elf32_Header *fileHdr = (struct Elf32_Header *) elfFile;
|
||||
if (fileHdr->e_shstrndx == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return elf32_getStringTable(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ELF_DEBUG
|
||||
void
|
||||
elf32_printStringTable(struct Elf32_Header *elfFile)
|
||||
{
|
||||
int counter;
|
||||
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
|
||||
char * stringTable;
|
||||
|
||||
if (!sections) {
|
||||
printf("No sections.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
stringTable = ((void *)elfFile) + sections[elfFile->e_shstrndx].sh_offset;
|
||||
|
||||
printf("File is %p; sections is %p; string table is %p\n", elfFile, sections, stringTable);
|
||||
|
||||
for (counter=0; counter < sections[elfFile->e_shstrndx].sh_size; counter++) {
|
||||
printf("%02x %c ", stringTable[counter],
|
||||
stringTable[counter] >= 0x20 ? stringTable[counter] : '.');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
elf32_getSegmentType (struct Elf32_Header *elfFile, int segment)
|
||||
{
|
||||
return elf32_getProgramSegmentTable(elfFile)[segment].p_type;
|
||||
}
|
||||
|
||||
void
|
||||
elf32_getSegmentInfo(struct Elf32_Header *elfFile, int segment, uint64_t *p_vaddr, uint64_t *p_addr, uint64_t *p_filesz, uint64_t *p_offset, uint64_t *p_memsz)
|
||||
{
|
||||
struct Elf32_Phdr *segments;
|
||||
|
||||
segments = elf32_getProgramSegmentTable(elfFile);
|
||||
*p_addr = segments[segment].p_paddr;
|
||||
*p_vaddr = segments[segment].p_vaddr;
|
||||
*p_filesz = segments[segment].p_filesz;
|
||||
*p_offset = segments[segment].p_offset;
|
||||
*p_memsz = segments[segment].p_memsz;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
elf32_getEntryPoint (struct Elf32_Header *elfFile)
|
||||
{
|
||||
return elfFile->e_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugging functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* prints out some details of one elf file
|
||||
*/
|
||||
void
|
||||
elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, int flags)
|
||||
{
|
||||
struct Elf32_Phdr *segments;
|
||||
unsigned numSegments;
|
||||
struct Elf32_Shdr *sections;
|
||||
unsigned numSections;
|
||||
int i, r;
|
||||
char *str_table;
|
||||
|
||||
fprintf(f, "Found an elf32 file called \"%s\" located "
|
||||
"at address 0x%p\n", name, file);
|
||||
|
||||
if ((r = elf32_checkFile(file)) != 0) {
|
||||
char *magic = (char*) file;
|
||||
fprintf(f, "Invalid elf file (%d)\n", r);
|
||||
fprintf(f, "Magic is: %2.2hhx %2.2hhx %2.2hhx %2.2hhx\n",
|
||||
magic[0], magic[1], magic[2], magic[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get a pointer to the table of program segments
|
||||
*/
|
||||
segments = elf32_getProgramHeaderTable(file);
|
||||
numSegments = elf32_getNumProgramHeaders(file);
|
||||
|
||||
sections = elf32_getSectionTable(file);
|
||||
numSections = elf32_getNumSections(file);
|
||||
|
||||
if ((uintptr_t) sections > ((uintptr_t) file + size)) {
|
||||
fprintf(f, "Corrupted elfFile..\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* print out info about each section
|
||||
*/
|
||||
|
||||
if (flags & ELF_PRINT_PROGRAM_HEADERS) {
|
||||
/*
|
||||
* print out info about each program segment
|
||||
*/
|
||||
fprintf(f, "Program Headers:\n");
|
||||
fprintf(f, " Type Offset VirtAddr PhysAddr "
|
||||
"FileSiz MemSiz Flg Align\n");
|
||||
for (i = 0; i < numSegments; i++) {
|
||||
if (segments[i].p_type != 1) {
|
||||
fprintf(f, "segment %d is not loadable, "
|
||||
"skipping\n", i);
|
||||
} else {
|
||||
fprintf(f, " LOAD 0x%06d 0x%08d 0x%08d 0x%05d 0x%05d %c%c%c 0x%04d\n",
|
||||
segments[i].p_offset, segments[i].p_vaddr,
|
||||
segments[i].p_paddr,
|
||||
segments[i].p_filesz, segments[i].p_memsz,
|
||||
(segments[i].p_flags & PF_R) ? 'R' : ' ',
|
||||
(segments[i].p_flags & PF_W) ? 'W' : ' ',
|
||||
(segments[i].p_flags & PF_X) ? 'E' : ' ',
|
||||
segments[i].p_align);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags & ELF_PRINT_SECTIONS) {
|
||||
str_table = elf32_getSegmentStringTable(file);
|
||||
|
||||
printf("Section Headers:\n");
|
||||
printf(" [Nr] Name Type Addr Off\n");
|
||||
for (i = 0; i < numSections; i++) {
|
||||
//if (elf_checkSection(file, i) == 0) {
|
||||
fprintf(f, "[%2d] %s %x %x\n", i, elf32_getSectionName(file, i),
|
||||
//fprintf(f, "[%2d] %-17.17s %-15.15s %x %x\n", i, elf32_getSectionName(file, i), " ",
|
||||
///fprintf(f, "%-17.17s %-15.15s %08x %06x\n", elf32_getSectionName(file, i), " " /* sections[i].sh_type
|
||||
// */ ,
|
||||
sections[i].sh_addr, sections[i].sh_offset);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#ifndef __ELF_ELF_32_H__
|
||||
#define __ELF_ELF_32_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* File header
|
||||
*/
|
||||
struct Elf32_Header {
|
||||
unsigned char e_ident[16];
|
||||
uint16_t e_type; /* Relocatable=1, Executable=2 (+ some
|
||||
* more ..) */
|
||||
uint16_t e_machine; /* Target architecture: MIPS=8 */
|
||||
uint32_t e_version; /* Elf version (should be 1) */
|
||||
uint32_t e_entry; /* Code entry point */
|
||||
uint32_t e_phoff; /* Program header table */
|
||||
uint32_t e_shoff; /* Section header table */
|
||||
uint32_t e_flags; /* Flags */
|
||||
uint16_t e_ehsize; /* ELF header size */
|
||||
uint16_t e_phentsize; /* Size of one program segment
|
||||
* header */
|
||||
uint16_t e_phnum; /* Number of program segment
|
||||
* headers */
|
||||
uint16_t e_shentsize; /* Size of one section header */
|
||||
uint16_t e_shnum; /* Number of section headers */
|
||||
uint16_t e_shstrndx; /* Section header index of the
|
||||
* string table for section header
|
||||
* * names */
|
||||
};
|
||||
|
||||
/*
|
||||
* Section header
|
||||
*/
|
||||
struct Elf32_Shdr {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint32_t sh_flags;
|
||||
uint32_t sh_addr;
|
||||
uint32_t sh_offset;
|
||||
uint32_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint32_t sh_addralign;
|
||||
uint32_t sh_entsize;
|
||||
};
|
||||
|
||||
/*
|
||||
* Program header
|
||||
*/
|
||||
struct Elf32_Phdr {
|
||||
uint32_t p_type; /* Segment type: Loadable segment = 1 */
|
||||
uint32_t p_offset; /* Offset of segment in file */
|
||||
uint32_t p_vaddr; /* Reqd virtual address of segment
|
||||
* when loading */
|
||||
uint32_t p_paddr; /* Reqd physical address of
|
||||
* segment (ignore) */
|
||||
uint32_t p_filesz; /* How many bytes this segment
|
||||
* occupies in file */
|
||||
uint32_t p_memsz; /* How many bytes this segment
|
||||
* should occupy in * memory (when
|
||||
* * loading, expand the segment
|
||||
* by * concatenating enough zero
|
||||
* bytes to it) */
|
||||
uint32_t p_flags; /* Flags: logical "or" of PF_
|
||||
* constants below */
|
||||
uint32_t p_align; /* Reqd alignment of segment in
|
||||
* memory */
|
||||
};
|
||||
|
||||
int elf32_checkFile(struct Elf32_Header *file);
|
||||
struct Elf32_Phdr * elf32_getProgramSegmentTable(struct Elf32_Header *file);
|
||||
unsigned elf32_getNumSections(struct Elf32_Header *file);
|
||||
char * elf32_getStringTable(struct Elf32_Header *file);
|
||||
char * elf32_getSegmentStringTable(struct Elf32_Header *file);
|
||||
|
||||
static inline struct Elf32_Shdr *
|
||||
elf32_getSectionTable(struct Elf32_Header *file)
|
||||
{
|
||||
/* Cast heaven! */
|
||||
return (struct Elf32_Shdr*) (uintptr_t) (((uintptr_t) file) + file->e_shoff);
|
||||
}
|
||||
|
||||
/* accessor functions */
|
||||
static inline uint32_t
|
||||
elf32_getSectionType(struct Elf32_Header *file, uint16_t s)
|
||||
{
|
||||
return elf32_getSectionTable(file)[s].sh_type;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getSectionFlags(struct Elf32_Header *file, uint16_t s)
|
||||
{
|
||||
return elf32_getSectionTable(file)[s].sh_flags;
|
||||
}
|
||||
|
||||
char * elf32_getSectionName(struct Elf32_Header *file, int i);
|
||||
uint32_t elf32_getSectionSize(struct Elf32_Header *file, int i);
|
||||
uint32_t elf32_getSectionLink(struct Elf32_Header *elfFile, int i);
|
||||
uint32_t elf32_getSectionAddr(struct Elf32_Header *elfFile, int i);
|
||||
void * elf32_getSection(struct Elf32_Header *file, int i);
|
||||
void * elf32_getSectionNamed(struct Elf32_Header *file, char *str);
|
||||
int elf32_getSegmentType (struct Elf32_Header *file, int segment);
|
||||
void elf32_getSegmentInfo(struct Elf32_Header *file, int segment, uint64_t *p_vaddr,
|
||||
uint64_t *p_paddr, uint64_t *p_filesz,
|
||||
uint64_t *p_offset, uint64_t *p_memsz);
|
||||
uint32_t elf32_getEntryPoint (struct Elf32_Header *file);
|
||||
|
||||
/* Program header functions */
|
||||
uint16_t elf32_getNumProgramHeaders(struct Elf32_Header *file);
|
||||
|
||||
static inline struct Elf32_Phdr *
|
||||
elf32_getProgramHeaderTable(struct Elf32_Header *file)
|
||||
{
|
||||
/* Cast heaven! */
|
||||
return (struct Elf32_Phdr*) (uintptr_t) (((uintptr_t) file) + file->e_phoff);
|
||||
}
|
||||
|
||||
/* accessor functions */
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderFlags(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_flags;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderType(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_type;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderFileSize(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_filesz;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderMemorySize(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_memsz;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderVaddr(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_vaddr;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderPaddr(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_paddr;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf32_getProgramHeaderOffset(struct Elf32_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_offset;
|
||||
}
|
||||
|
||||
#endif /* __ELF_ELF_32_H__ */
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#include "elf.h"
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
elf64_checkFile(void *elfFile)
|
||||
{
|
||||
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
|
||||
if (fileHdr->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| fileHdr->e_ident[EI_MAG1] != ELFMAG1
|
||||
|| fileHdr->e_ident[EI_MAG2] != ELFMAG2
|
||||
|| fileHdr->e_ident[EI_MAG3] != ELFMAG3)
|
||||
return -1; /* not an elf file */
|
||||
if (fileHdr->e_ident[EI_CLASS] != ELFCLASS64)
|
||||
return -2; /* not 64-bit file */
|
||||
#if 0
|
||||
if (fileHdr->e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
return -3; /* not big-endian file */
|
||||
if (fileHdr->e_ident[EI_VERSION] != 1)
|
||||
return -4; /* wrong version of elf */
|
||||
if (fileHdr->e_machine != 8)
|
||||
return -5; /* wrong architecture (not MIPS) */
|
||||
if (fileHdr->e_type != 2)
|
||||
return -6; /* not an executable program */
|
||||
if (fileHdr->e_phentsize != sizeof(struct Elf64_Phdr))
|
||||
return -7; /* unexpected size of program segment
|
||||
* header */
|
||||
if (fileHdr->e_phnum == 0)
|
||||
return -8; /* no program segments */
|
||||
if ((fileHdr->e_flags & 0x7e) != 0)
|
||||
return -9; /* wrong flags (did you forgot to compile
|
||||
* with -mno-abicalls?) */
|
||||
#endif
|
||||
return 0; /* elf file looks OK */
|
||||
}
|
||||
|
||||
struct Elf64_Phdr *
|
||||
elf64_getProgramSegmentTable(void *elfFile)
|
||||
/*
|
||||
* Returns a pointer to the program segment table, which is an array of
|
||||
* ELF64_Phdr_t structs. The size of the array can be found by calling
|
||||
* getNumProgramSegments.
|
||||
*/
|
||||
{
|
||||
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
|
||||
return (struct Elf64_Phdr *) ((size_t)fileHdr->e_phoff + (size_t) elfFile);
|
||||
}
|
||||
|
||||
unsigned
|
||||
elf64_getNumSections(void *elfFile)
|
||||
/*
|
||||
* Returns the number of program segments in this elf file.
|
||||
*/
|
||||
{
|
||||
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
|
||||
return fileHdr->e_shnum;
|
||||
}
|
||||
|
||||
char *
|
||||
elf64_getStringTable(void *elfFile, int string_segment)
|
||||
{
|
||||
struct Elf64_Shdr *sections = elf64_getSectionTable((Elf64_Header*)elfFile);
|
||||
return (char *) elfFile + sections[string_segment].sh_offset;
|
||||
}
|
||||
|
||||
char *
|
||||
elf64_getSegmentStringTable(void *elfFile)
|
||||
{
|
||||
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
|
||||
if (fileHdr->e_shstrndx == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return elf64_getStringTable(elfFile, fileHdr->e_shstrndx);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
elf64_getSectionName(void *elfFile, int i)
|
||||
{
|
||||
struct Elf64_Shdr *sections = elf64_getSectionTable((Elf64_Header*)elfFile);
|
||||
char *str_table = elf64_getSegmentStringTable((Elf64_Header*)elfFile);
|
||||
if (str_table == NULL) {
|
||||
return (char*)"<corrupted>";
|
||||
} else {
|
||||
return str_table + sections[i].sh_name;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf64_getSectionSize(void *elfFile, int i)
|
||||
{
|
||||
struct Elf64_Shdr *sections = elf64_getSectionTable((Elf64_Header*)elfFile);
|
||||
return sections[i].sh_size;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf64_getSectionAddr(struct Elf64_Header *elfFile, int i)
|
||||
{
|
||||
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
|
||||
return sections[i].sh_addr;
|
||||
}
|
||||
|
||||
void *
|
||||
elf64_getSection(void *elfFile, int i)
|
||||
{
|
||||
struct Elf64_Shdr *sections = elf64_getSectionTable((Elf64_Header*)elfFile);
|
||||
return (char *)elfFile + sections[i].sh_offset;
|
||||
}
|
||||
|
||||
void *
|
||||
elf64_getSectionNamed(void *elfFile, char *str)
|
||||
{
|
||||
int numSections = elf64_getNumSections(elfFile);
|
||||
int i;
|
||||
for (i = 0; i < numSections; i++) {
|
||||
if (strcmp(str, elf64_getSectionName(elfFile, i)) == 0) {
|
||||
return elf64_getSection(elfFile, i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
elf64_getNumProgramHeaders(struct Elf64_Header *elfFile)
|
||||
{
|
||||
return elfFile->e_phnum;
|
||||
}
|
||||
|
||||
int
|
||||
elf64_getSegmentType (void *elfFile, int segment)
|
||||
{
|
||||
return elf64_getProgramSegmentTable(elfFile)[segment].p_type;
|
||||
}
|
||||
|
||||
void
|
||||
elf64_getSegmentInfo(void *elfFile, int segment, uint64_t *p_vaddr,
|
||||
uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset,
|
||||
uint64_t *p_memsz)
|
||||
{
|
||||
struct Elf64_Phdr *segments;
|
||||
|
||||
segments = elf64_getProgramSegmentTable(elfFile);
|
||||
*p_vaddr = segments[segment].p_vaddr;
|
||||
*p_paddr = segments[segment].p_paddr;
|
||||
*p_filesz = segments[segment].p_filesz;
|
||||
*p_offset = segments[segment].p_offset;
|
||||
*p_memsz = segments[segment].p_memsz;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
elf64_getEntryPoint (struct Elf64_Header *elfFile)
|
||||
{
|
||||
return elfFile->e_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugging functions
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* prints out some details of one elf file
|
||||
*/
|
||||
void
|
||||
elf64_showDetails(void *elfFile, int size, char *name)
|
||||
{
|
||||
struct Elf64_Phdr *segments;
|
||||
unsigned numSegments;
|
||||
struct Elf64_Shdr *sections;
|
||||
unsigned numSections;
|
||||
int i,
|
||||
r;
|
||||
char *str_table;
|
||||
|
||||
printf("Found an elf64 file called \"%s\" located "
|
||||
"at address 0x%lx\n", name, elfFile);
|
||||
|
||||
if ((r = elf64_checkFile(elfFile)) != 0) {
|
||||
char *magic = elfFile;
|
||||
printf("Invalid elf file (%d)\n", r);
|
||||
printf("Magic is: %02.2hhx %02.2hhx %02.2hhx %02.2hhx\n",
|
||||
magic[0], magic[1], magic[2], magic[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
str_table = elf64_getSegmentStringTable(elfFile);
|
||||
|
||||
printf("Got str_table... %p\n", str_table);
|
||||
|
||||
/*
|
||||
* get a pointer to the table of program segments
|
||||
*/
|
||||
segments = elf64_getProgramSegmentTable(elfFile);
|
||||
numSegments = elf64_getNumProgramSegments(elfFile);
|
||||
|
||||
sections = elf64_getSectionTable(elfFile);
|
||||
numSections = elf64_getNumSections(elfFile);
|
||||
|
||||
if ((void *) sections > (void *) elfFile + size ||
|
||||
(((uintptr_t) sections & 0xf) != 0)) {
|
||||
printf("Corrupted elfFile..\n");
|
||||
return;
|
||||
}
|
||||
printf("Sections: %p\n", sections);
|
||||
/*
|
||||
* print out info about each section
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* print out info about each program segment
|
||||
*/
|
||||
printf("Program Headers:\n");
|
||||
printf(" Type Offset VirtAddr PhysAddr "
|
||||
"FileSiz MemSiz Flg Align\n");
|
||||
for (i = 0; i < numSegments; i++) {
|
||||
|
||||
if (segments[i].p_type != 1) {
|
||||
printf("segment %d is not loadable, "
|
||||
"skipping\n", i);
|
||||
} else {
|
||||
printf(" LOAD 0x%06lx 0x%08lx 0x%08lx"
|
||||
" 0x%05lx 0x%05lx %c%c%c 0x%04lx\n",
|
||||
segments[i].p_offset, segments[i].p_vaddr,
|
||||
segments[i].p_vaddr,
|
||||
segments[i].p_filesz, segments[i].p_memsz,
|
||||
segments[i].p_flags & PF_R ? 'R' : ' ',
|
||||
segments[i].p_flags & PF_W ? 'W' : ' ',
|
||||
segments[i].p_flags & PF_X ? 'E' : ' ',
|
||||
segments[i].p_align);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Section Headers:\n");
|
||||
printf(" [Nr] Name Type Addr Off\n");
|
||||
for (i = 0; i < numSections; i++) {
|
||||
if (elf_checkSection(elfFile, i) == 0) {
|
||||
printf("%-17.17s %-15.15s %08x %06x\n", elf64_getSectionName(elfFile, i), " " /* sections[i].sh_type
|
||||
*/ ,
|
||||
sections[i].sh_addr, sections[i].sh_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Australian Public Licence B (OZPLB)
|
||||
*
|
||||
* Version 1-0
|
||||
*
|
||||
* Copyright (c) 2004 University of New South Wales
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
|
||||
* University of New South Wales
|
||||
* http://www.disy.cse.unsw.edu.au
|
||||
*
|
||||
* Permission is granted by University of New South Wales, free of charge, to
|
||||
* any person obtaining a copy of this software and any associated
|
||||
* documentation files (the "Software") to deal with the Software without
|
||||
* restriction, including (without limitation) the rights to use, copy,
|
||||
* modify, adapt, merge, publish, distribute, communicate to the public,
|
||||
* sublicense, and/or sell, lend or rent out copies of the Software, and
|
||||
* to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimers.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimers in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* * Neither the name of University of New South Wales, nor the names of its
|
||||
* contributors, may be used to endorse or promote products derived
|
||||
* from this Software without specific prior written permission.
|
||||
*
|
||||
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
|
||||
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
|
||||
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
|
||||
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
|
||||
* ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
*
|
||||
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
|
||||
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
|
||||
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
|
||||
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
|
||||
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
|
||||
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
||||
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
|
||||
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
|
||||
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
|
||||
* DAMAGES OR OTHER LIABILITY.
|
||||
*
|
||||
* If applicable legislation implies representations, warranties, or
|
||||
* conditions, or imposes obligations or liability on University of New South
|
||||
* Wales or one of its contributors in respect of the Software that
|
||||
* cannot be wholly or partly excluded, restricted or modified, the
|
||||
* liability of University of New South Wales or the contributor is limited, to
|
||||
* the full extent permitted by the applicable legislation, at its
|
||||
* option, to:
|
||||
* a. in the case of goods, any one or more of the following:
|
||||
* i. the replacement of the goods or the supply of equivalent goods;
|
||||
* ii. the repair of the goods;
|
||||
* iii. the payment of the cost of replacing the goods or of acquiring
|
||||
* equivalent goods;
|
||||
* iv. the payment of the cost of having the goods repaired; or
|
||||
* b. in the case of services:
|
||||
* i. the supplying of the services again; or
|
||||
* ii. the payment of the cost of having the services supplied again.
|
||||
*
|
||||
* The construction, validity and performance of this licence is governed
|
||||
* by the laws in force in New South Wales, Australia.
|
||||
*/
|
||||
#ifndef __LIBELF_64_H__
|
||||
#define __LIBELF_64_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* File header
|
||||
*/
|
||||
struct Elf64_Header {
|
||||
unsigned char e_ident[16];
|
||||
uint16_t e_type; /* Relocatable=1, Executable=2 (+ some
|
||||
* more ..) */
|
||||
uint16_t e_machine; /* Target architecture: MIPS=8 */
|
||||
uint32_t e_version; /* Elf version (should be 1) */
|
||||
uint64_t e_entry; /* Code entry point */
|
||||
uint64_t e_phoff; /* Program header table */
|
||||
uint64_t e_shoff; /* Section header table */
|
||||
uint32_t e_flags; /* Flags */
|
||||
uint16_t e_ehsize; /* ELF header size */
|
||||
uint16_t e_phentsize; /* Size of one program segment
|
||||
* header */
|
||||
uint16_t e_phnum; /* Number of program segment
|
||||
* headers */
|
||||
uint16_t e_shentsize; /* Size of one section header */
|
||||
uint16_t e_shnum; /* Number of section headers */
|
||||
uint16_t e_shstrndx; /* Section header index of the
|
||||
* string table for section header
|
||||
* * names */
|
||||
};
|
||||
|
||||
/*
|
||||
* Section header
|
||||
*/
|
||||
struct Elf64_Shdr {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint64_t sh_flags;
|
||||
uint64_t sh_addr;
|
||||
uint64_t sh_offset;
|
||||
uint64_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint64_t sh_addralign;
|
||||
uint64_t sh_entsize;
|
||||
};
|
||||
|
||||
/*
|
||||
* Program header
|
||||
*/
|
||||
struct Elf64_Phdr {
|
||||
uint32_t p_type; /* Segment type: Loadable segment = 1 */
|
||||
uint32_t p_flags; /* Flags: logical "or" of PF_
|
||||
* constants below */
|
||||
uint64_t p_offset; /* Offset of segment in file */
|
||||
uint64_t p_vaddr; /* Reqd virtual address of segment
|
||||
* when loading */
|
||||
uint64_t p_paddr; /* Reqd physical address of
|
||||
* segment */
|
||||
uint64_t p_filesz; /* How many bytes this segment
|
||||
* occupies in file */
|
||||
uint64_t p_memsz; /* How many bytes this segment
|
||||
* should occupy in * memory (when
|
||||
* * loading, expand the segment
|
||||
* by * concatenating enough zero
|
||||
* bytes to it) */
|
||||
uint64_t p_align; /* Reqd alignment of segment in
|
||||
* memory */
|
||||
};
|
||||
|
||||
int elf64_checkFile(void *elfFile);
|
||||
struct Elf64_Phdr * elf64_getProgramSegmentTable(void *elfFile);
|
||||
unsigned elf64_getNumSections(void *elfFile);
|
||||
char * elf64_getStringTable(void *elfFile, int string_segment);
|
||||
char * elf64_getSegmentStringTable(void *elfFile);
|
||||
|
||||
static inline struct Elf64_Shdr *
|
||||
elf64_getSectionTable(struct Elf64_Header *file)
|
||||
{
|
||||
/* Cast heaven! */
|
||||
return (struct Elf64_Shdr*) (uintptr_t) (((uintptr_t) file) + file->e_shoff);
|
||||
}
|
||||
|
||||
/* accessor functions */
|
||||
static inline uint32_t
|
||||
elf64_getSectionType(struct Elf64_Header *file, uint16_t s)
|
||||
{
|
||||
return elf64_getSectionTable(file)[s].sh_type;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t elf64_getSectionLink(struct Elf64_Header *file, int s)
|
||||
{
|
||||
return elf64_getSectionTable(file)[s].sh_link;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf64_getSectionFlags(struct Elf64_Header *file, uint16_t s)
|
||||
{
|
||||
return elf64_getSectionTable(file)[s].sh_flags;
|
||||
}
|
||||
|
||||
char * elf64_getSectionName(void *elfFile, int i);
|
||||
uint64_t elf64_getSectionSize(void *elfFile, int i);
|
||||
uint64_t elf64_getSectionAddr(struct Elf64_Header *elfFile, int i);
|
||||
void * elf64_getSection(void *elfFile, int i);
|
||||
void * elf64_getSectionNamed(void *elfFile, char *str);
|
||||
int elf64_getSegmentType (void *elfFile, int segment);
|
||||
void elf64_getSegmentInfo(void *elfFile, int segment, uint64_t *p_vaddr,
|
||||
uint64_t *p_paddr, uint64_t *p_filesz,
|
||||
uint64_t *p_offset, uint64_t *p_memsz);
|
||||
void elf64_showDetails(void *elfFile, int size, char *name);
|
||||
uint64_t elf64_getEntryPoint (struct Elf64_Header *elfFile);
|
||||
|
||||
/* Program Headers functions */
|
||||
/* Program header functions */
|
||||
uint16_t elf64_getNumProgramHeaders(struct Elf64_Header *file);
|
||||
|
||||
static inline struct Elf64_Phdr *
|
||||
elf64_getProgramHeaderTable(struct Elf64_Header *file)
|
||||
{
|
||||
/* Cast hell! */
|
||||
return (struct Elf64_Phdr*) (uintptr_t) (((uintptr_t) file) + file->e_phoff);
|
||||
}
|
||||
|
||||
/* accessor functions */
|
||||
static inline uint32_t
|
||||
elf64_getProgramHeaderFlags(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_flags;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
elf64_getProgramHeaderType(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_type;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
elf64_getProgramHeaderFileSize(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_filesz;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
elf64_getProgramHeaderMemorySize(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_memsz;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
elf64_getProgramHeaderVaddr(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_vaddr;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
elf64_getProgramHeaderPaddr(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_paddr;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
elf64_getProgramHeaderOffset(struct Elf64_Header *file, uint16_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_offset;
|
||||
}
|
||||
|
||||
#endif /* __LIBELF_64_H__ */
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
Authors: Luke Deller, Ben Leslie
|
||||
Created: 24/Sep/1999
|
||||
*/
|
||||
|
||||
/**
|
||||
\file
|
||||
|
||||
\brief Generic ELF library
|
||||
|
||||
The ELF library is designed to make the task of parsing and getting information
|
||||
out of an ELF file easier.
|
||||
|
||||
It provides function to obtain the various different fields in the ELF header, and
|
||||
the program and segment information.
|
||||
|
||||
Also importantly, it provides a function elf_loadFile which will load a given
|
||||
ELF file into memory.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
#include <elf/exec_elf.h>
|
||||
typedef Elf64_Ehdr Elf64_Header;
|
||||
typedef Elf32_Ehdr Elf32_Header;
|
||||
#else
|
||||
#include <elf.h>
|
||||
#endif
|
||||
|
||||
struct elf {
|
||||
void const *elfFile;
|
||||
size_t elfSize;
|
||||
unsigned char elfClass; /* 32-bit or 64-bit */
|
||||
};
|
||||
typedef struct elf elf_t;
|
||||
|
||||
enum elf_addr_type {
|
||||
VIRTUAL,
|
||||
PHYSICAL
|
||||
};
|
||||
typedef enum elf_addr_type elf_addr_type_t;
|
||||
|
||||
/* ELF header functions */
|
||||
/**
|
||||
* Initialises an elf_t structure and checks that the ELF file is valid.
|
||||
* This function must be called to validate the ELF before any other function.
|
||||
* Otherwise, attempting to call other functions with an invalid ELF file may
|
||||
* result in undefined behaviour.
|
||||
*
|
||||
* @param file ELF file to use
|
||||
* @param size Size of the ELF file
|
||||
* @param res elf_t to initialise
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_newFile(const void *file, size_t size, elf_t *res);
|
||||
|
||||
/**
|
||||
* Initialises and elf_t structure and checks that the ELF file is valid.
|
||||
* The validity of a potential ELF file can be determined by the arguments
|
||||
* check_pht and check_st.
|
||||
* If both check_pht and check_st are true, this function is equivalent to
|
||||
* elf_newFile.
|
||||
* Calling other functions with an invalid ELF file may result in undefined
|
||||
* behaviour.
|
||||
*
|
||||
* @param file ELF file to use
|
||||
* @param size Size of the ELF file
|
||||
* @param check_pht Whether to check the ELF program header table is valid
|
||||
* @param check_st Whether to check the ELF section table is valid
|
||||
* @param res elf_t to initialise
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_newFile_maybe_unsafe(const void *file, size_t size, bool check_pht, bool check_st, elf_t *res);
|
||||
|
||||
/**
|
||||
* Checks that file starts with the ELF magic number.
|
||||
* File must be at least 4 bytes (SELFMAG).
|
||||
*
|
||||
* @param file to check
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_check_magic(const char *file);
|
||||
|
||||
/**
|
||||
* Checks that elfFile points to an ELF file with a valid ELF header.
|
||||
*
|
||||
* @param elfFile Potential ELF file to check
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_checkFile(elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Checks that elfFile points to an ELF file with a valid program header table.
|
||||
*
|
||||
* @param elfFile Potential ELF file to check
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_checkProgramHeaderTable(const elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Checks that elfFile points to an ELF file with a valid section table.
|
||||
*
|
||||
* @param elfFile Potential ELF file to check
|
||||
*
|
||||
* \return 0 on success, otherwise < 0
|
||||
*/
|
||||
int elf_checkSectionTable(const elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Find the entry point of an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
*
|
||||
* \return The entry point address.
|
||||
*/
|
||||
uintptr_t elf_getEntryPoint(const elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Determine number of program headers in an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure.
|
||||
*
|
||||
* \return Number of program headers in the ELF file.
|
||||
*/
|
||||
size_t elf_getNumProgramHeaders(const elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Determine number of sections in an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure.
|
||||
*
|
||||
* \return Number of sections in the ELF file.
|
||||
*/
|
||||
size_t elf_getNumSections(const elf_t *elfFile);
|
||||
|
||||
/**
|
||||
* Get the index of the section header string table of an ELF file.
|
||||
*
|
||||
* @param elf Pointer to a valid ELF structure.
|
||||
*
|
||||
* \return The index of the section header string table.
|
||||
*/
|
||||
size_t elf_getSectionStringTableIndex(const elf_t *elf);
|
||||
|
||||
/**
|
||||
* Get a string table section of an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure.
|
||||
* @param string_section The section number of the string table.
|
||||
*
|
||||
* \return The string table, or NULL if the section is not a string table.
|
||||
*/
|
||||
const char *elf_getStringTable(const elf_t *elfFile, size_t string_segment);
|
||||
|
||||
/**
|
||||
* Get the string table for section header names.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure.
|
||||
*
|
||||
* \return The string table, or NULL if there is no table.
|
||||
*/
|
||||
const char *elf_getSectionStringTable(const elf_t *elfFile);
|
||||
|
||||
|
||||
/* Section header functions */
|
||||
/**
|
||||
* Get a section of an ELF file.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i The section number
|
||||
*
|
||||
* \return The section, or NULL if there is no section.
|
||||
*/
|
||||
const void *elf_getSection(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Get the section of an ELF file with a given name.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param str Name of the section
|
||||
* @param i Pointer to store the section number
|
||||
*
|
||||
* \return The section, or NULL if there is no section.
|
||||
*/
|
||||
const void *elf_getSectionNamed(const elf_t *elfFile, const char *str, size_t *i);
|
||||
|
||||
/**
|
||||
* Return the name of a given section.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The name of a given section.
|
||||
*/
|
||||
const char *elf_getSectionName(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the offset to the name of a given section in the section header
|
||||
* string table.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The offset to the name of a given section in the section header
|
||||
* string table.
|
||||
*/
|
||||
size_t elf_getSectionNameOffset(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the type of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The type of a given section.
|
||||
*/
|
||||
uint32_t elf_getSectionType(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the flags of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The flags of a given section.
|
||||
*/
|
||||
size_t elf_getSectionFlags(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the address of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The address of a given section.
|
||||
*/
|
||||
uintptr_t elf_getSectionAddr(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the offset of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The offset of a given section.
|
||||
*/
|
||||
size_t elf_getSectionOffset(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the size of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The size of a given section.
|
||||
*/
|
||||
size_t elf_getSectionSize(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the related section index of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The related section index of a given section.
|
||||
*/
|
||||
uint32_t elf_getSectionLink(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return extra information of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return Extra information of a given section.
|
||||
*/
|
||||
uint32_t elf_getSectionInfo(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the alignment of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The alignment of a given section.
|
||||
*/
|
||||
size_t elf_getSectionAddrAlign(const elf_t *elfFile, size_t i);
|
||||
|
||||
/**
|
||||
* Return the entry size of a given section
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param i Index of the section
|
||||
*
|
||||
* \return The entry size of a given section.
|
||||
*/
|
||||
size_t elf_getSectionEntrySize(const elf_t *elfFile, size_t i);
|
||||
|
||||
|
||||
/* Program header functions */
|
||||
|
||||
/**
|
||||
* Return the segment data for a given program header.
|
||||
*
|
||||
* @param elf Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return Pointer to the segment data
|
||||
*/
|
||||
const void *elf_getProgramSegment(const elf_t *elf, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the type for a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The type of a given program header.
|
||||
*/
|
||||
uint32_t elf_getProgramHeaderType(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the segment offset for a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The offset of this program header from the start of the file.
|
||||
*/
|
||||
size_t elf_getProgramHeaderOffset(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the base virtual address of given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header.
|
||||
*/
|
||||
uintptr_t elf_getProgramHeaderVaddr(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the base physical address of given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header.
|
||||
*/
|
||||
uintptr_t elf_getProgramHeaderPaddr(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the file size of a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The file size of the specified program header.
|
||||
*/
|
||||
size_t elf_getProgramHeaderFileSize(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the memory size of a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The memory size of the specified program header.
|
||||
*/
|
||||
size_t elf_getProgramHeaderMemorySize(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the flags for a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The flags of a given program header.
|
||||
*/
|
||||
uint32_t elf_getProgramHeaderFlags(const elf_t *elfFile, size_t ph);
|
||||
|
||||
/**
|
||||
* Return the alignment for a given program header.
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param ph Index of the program header
|
||||
*
|
||||
* \return The alignment of the given program header.
|
||||
*/
|
||||
size_t elf_getProgramHeaderAlign(const elf_t *elfFile, size_t ph);
|
||||
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
/**
|
||||
* Determine the memory bounds of an ELF file
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF structure
|
||||
* @param addr_type If PHYSICAL return bounds of physical memory, otherwise
|
||||
* return bounds of virtual memory
|
||||
* @param min Pointer to return value of the minimum
|
||||
* @param max Pointer to return value of the maximum
|
||||
*
|
||||
* \return true on success. false on failure, if for example, it is an invalid ELF file
|
||||
*/
|
||||
int elf_getMemoryBounds(const elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max);
|
||||
|
||||
/**
|
||||
*
|
||||
* \return true if the address in in this program header
|
||||
*/
|
||||
int elf_vaddrInProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr);
|
||||
|
||||
/**
|
||||
* Return the physical translation of a physical address, with respect
|
||||
* to a given program header
|
||||
*
|
||||
*/
|
||||
uintptr_t elf_vtopProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr);
|
||||
|
||||
/**
|
||||
* Load an ELF file into memory
|
||||
*
|
||||
* @param elfFile Pointer to a valid ELF file
|
||||
* @param addr_type If PHYSICAL load using the physical address, otherwise using the
|
||||
* virtual addresses
|
||||
*
|
||||
* \return true on success, false on failure.
|
||||
*
|
||||
* The function assumes that the ELF file is loaded in memory at some
|
||||
* address different to the target address at which it will be loaded.
|
||||
* It also assumes direct access to the source and destination address, i.e:
|
||||
* Memory must be able to be loaded with a simple memcpy.
|
||||
*
|
||||
* Obviously this also means that if we are loading a 64bit ELF on a 32bit
|
||||
* platform, we assume that any memory addresses are within the first 4GB.
|
||||
*
|
||||
*/
|
||||
int elf_loadFile(const elf_t *elfFile, elf_addr_type_t addr_type);
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <elf/elf.h>
|
||||
|
||||
/* ELF header functions */
|
||||
int elf32_checkFile(elf_t *elf);
|
||||
|
||||
int elf32_checkProgramHeaderTable(const elf_t *elf);
|
||||
|
||||
int elf32_checkSectionTable(const elf_t *elf);
|
||||
|
||||
static inline bool elf_isElf32(const elf_t *elf)
|
||||
{
|
||||
return elf->elfClass == ELFCLASS32;
|
||||
}
|
||||
|
||||
static inline Elf32_Ehdr elf32_getHeader(const elf_t *elf)
|
||||
{
|
||||
return *(Elf32_Ehdr *) elf->elfFile;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf32_getEntryPoint(const elf_t *elf)
|
||||
{
|
||||
return elf32_getHeader(elf).e_entry;
|
||||
}
|
||||
|
||||
static inline const Elf32_Phdr *elf32_getProgramHeaderTable(const elf_t *file)
|
||||
{
|
||||
return (Elf32_Phdr*) (uintptr_t) ((uintptr_t)(file->elfFile) + elf32_getHeader(file).e_phoff);
|
||||
}
|
||||
|
||||
static inline const Elf32_Shdr *elf32_getSectionTable(const elf_t *elf)
|
||||
{
|
||||
return (Elf32_Shdr*) (uintptr_t) ((uintptr_t)(elf->elfFile) + elf32_getHeader(elf).e_shoff);
|
||||
}
|
||||
|
||||
static inline size_t elf32_getNumProgramHeaders(const elf_t *elf)
|
||||
{
|
||||
return elf32_getHeader(elf).e_phnum;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getNumSections(const elf_t *elf)
|
||||
{
|
||||
return elf32_getHeader(elf).e_shnum;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionStringTableIndex(const elf_t *elf)
|
||||
{
|
||||
return elf32_getHeader(elf).e_shstrndx;
|
||||
}
|
||||
|
||||
|
||||
/* Section header functions */
|
||||
static inline size_t elf32_getSectionNameOffset(const elf_t *elf, size_t s)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[s].sh_name;
|
||||
}
|
||||
|
||||
static inline uint32_t elf32_getSectionType(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_type;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionFlags(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_flags;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf32_getSectionAddr(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_addr;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionOffset(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_offset;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionSize(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_size;
|
||||
}
|
||||
|
||||
static inline uint32_t elf32_getSectionLink(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_link;
|
||||
}
|
||||
|
||||
static inline uint32_t elf32_getSectionInfo(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_info;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionAddrAlign(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_addralign;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getSectionEntrySize(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf32_getSectionTable(elf)[i].sh_entsize;
|
||||
}
|
||||
|
||||
|
||||
/* Program header functions */
|
||||
static inline uint32_t elf32_getProgramHeaderType(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_type;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getProgramHeaderOffset(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_offset;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf32_getProgramHeaderVaddr(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_vaddr;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf32_getProgramHeaderPaddr(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_paddr;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getProgramHeaderFileSize(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_filesz;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getProgramHeaderMemorySize(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_memsz;
|
||||
}
|
||||
|
||||
static inline uint32_t elf32_getProgramHeaderFlags(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_flags;
|
||||
}
|
||||
|
||||
static inline size_t elf32_getProgramHeaderAlign(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf32_getProgramHeaderTable(file)[ph].p_align;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <elf/elf.h>
|
||||
|
||||
/* ELF header functions */
|
||||
int elf64_checkFile(elf_t *elf);
|
||||
|
||||
int elf64_checkProgramHeaderTable(const elf_t *elf);
|
||||
|
||||
int elf64_checkSectionTable(const elf_t *elf);
|
||||
|
||||
static inline bool elf_isElf64(const elf_t *elf)
|
||||
{
|
||||
return elf->elfClass == ELFCLASS64;
|
||||
}
|
||||
|
||||
static inline Elf64_Ehdr elf64_getHeader(const elf_t *elf)
|
||||
{
|
||||
return *(Elf64_Ehdr *) elf->elfFile;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf64_getEntryPoint(const elf_t *file)
|
||||
{
|
||||
return elf64_getHeader(file).e_entry;
|
||||
}
|
||||
|
||||
static inline const Elf64_Phdr *elf64_getProgramHeaderTable(const elf_t *file)
|
||||
{
|
||||
return (Elf64_Phdr*) (uintptr_t) ((uintptr_t)(file->elfFile) + elf64_getHeader(file).e_phoff);
|
||||
}
|
||||
|
||||
static inline const Elf64_Shdr *elf64_getSectionTable(const elf_t *file)
|
||||
{
|
||||
return (Elf64_Shdr*) (uintptr_t) ((uintptr_t)(file->elfFile) + elf64_getHeader(file).e_shoff);
|
||||
}
|
||||
|
||||
static inline size_t elf64_getNumProgramHeaders(const elf_t *file)
|
||||
{
|
||||
return elf64_getHeader(file).e_phnum;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getNumSections(const elf_t *elf)
|
||||
{
|
||||
return elf64_getHeader(elf).e_shnum;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionStringTableIndex(const elf_t *elf)
|
||||
{
|
||||
return elf64_getHeader(elf).e_shstrndx;
|
||||
}
|
||||
|
||||
|
||||
/* Section header functions */
|
||||
static inline size_t elf64_getSectionNameOffset(const elf_t *elf, size_t s)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[s].sh_name;
|
||||
}
|
||||
|
||||
static inline uint32_t elf64_getSectionType(const elf_t *file, size_t s)
|
||||
{
|
||||
return elf64_getSectionTable(file)[s].sh_type;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionFlags(const elf_t *file, size_t s)
|
||||
{
|
||||
return elf64_getSectionTable(file)[s].sh_flags;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf64_getSectionAddr(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_addr;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionOffset(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_offset;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionSize(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_size;
|
||||
}
|
||||
|
||||
static inline uint32_t elf64_getSectionLink(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_link;
|
||||
}
|
||||
|
||||
static inline uint32_t elf64_getSectionInfo(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_info;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionAddrAlign(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_addralign;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getSectionEntrySize(const elf_t *elf, size_t i)
|
||||
{
|
||||
return elf64_getSectionTable(elf)[i].sh_entsize;
|
||||
}
|
||||
|
||||
|
||||
/* Program header functions */
|
||||
static inline uint32_t elf64_getProgramHeaderType(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_type;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getProgramHeaderOffset(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_offset;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf64_getProgramHeaderVaddr(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_vaddr;
|
||||
}
|
||||
|
||||
static inline uintptr_t elf64_getProgramHeaderPaddr(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_paddr;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getProgramHeaderFileSize(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_filesz;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getProgramHeaderMemorySize(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_memsz;
|
||||
}
|
||||
|
||||
static inline uint32_t elf64_getProgramHeaderFlags(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_flags;
|
||||
}
|
||||
|
||||
static inline size_t elf64_getProgramHeaderAlign(const elf_t *file, size_t ph)
|
||||
{
|
||||
return elf64_getProgramHeaderTable(file)[ph].p_align;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,827 @@
|
||||
/* $OpenBSD: exec_elf.h,v 1.97 2022/10/27 23:17:18 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the ELF ABI header file
|
||||
* formerly known as "elf_abi.h".
|
||||
*/
|
||||
|
||||
#ifndef _SYS_EXEC_ELF_H_
|
||||
#define _SYS_EXEC_ELF_H_
|
||||
|
||||
typedef uint64_t __uint64_t;
|
||||
typedef int64_t __int64_t;
|
||||
typedef uint32_t __uint32_t;
|
||||
typedef int32_t __int32_t;
|
||||
typedef uint16_t __uint16_t;
|
||||
typedef int16_t __int16_t;
|
||||
|
||||
typedef __uint32_t Elf32_Addr; /* Unsigned program address */
|
||||
typedef __uint32_t Elf32_Off; /* Unsigned file offset */
|
||||
typedef __int32_t Elf32_Sword; /* Signed large integer */
|
||||
typedef __uint32_t Elf32_Word; /* Unsigned large integer */
|
||||
typedef __uint16_t Elf32_Half; /* Unsigned medium integer */
|
||||
typedef __uint64_t Elf32_Lword;
|
||||
|
||||
typedef __uint64_t Elf64_Addr;
|
||||
typedef __uint64_t Elf64_Off;
|
||||
typedef __int32_t Elf64_Shalf;
|
||||
|
||||
typedef __int32_t Elf64_Sword;
|
||||
typedef __uint32_t Elf64_Word;
|
||||
|
||||
typedef __int64_t Elf64_Sxword;
|
||||
typedef __uint64_t Elf64_Xword;
|
||||
typedef __uint64_t Elf64_Lword;
|
||||
|
||||
typedef __uint16_t Elf64_Half;
|
||||
|
||||
/*
|
||||
* e_ident[] identification indexes
|
||||
* See http://www.sco.com/developers/gabi/latest/ch4.eheader.html
|
||||
*/
|
||||
#define EI_MAG0 0 /* file ID */
|
||||
#define EI_MAG1 1 /* file ID */
|
||||
#define EI_MAG2 2 /* file ID */
|
||||
#define EI_MAG3 3 /* file ID */
|
||||
#define EI_CLASS 4 /* file class */
|
||||
#define EI_DATA 5 /* data encoding */
|
||||
#define EI_VERSION 6 /* ELF header version */
|
||||
#define EI_OSABI 7 /* OS/ABI ID */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define EI_PAD 9 /* start of pad bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
/* e_ident[] magic number */
|
||||
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
|
||||
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
|
||||
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
|
||||
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
|
||||
#define ELFMAG "\177ELF" /* magic */
|
||||
#define SELFMAG 4 /* size of magic */
|
||||
|
||||
/* e_ident[] file class */
|
||||
#define ELFCLASSNONE 0 /* invalid */
|
||||
#define ELFCLASS32 1 /* 32-bit objs */
|
||||
#define ELFCLASS64 2 /* 64-bit objs */
|
||||
#define ELFCLASSNUM 3 /* number of classes */
|
||||
|
||||
/* e_ident[] data encoding */
|
||||
#define ELFDATANONE 0 /* invalid */
|
||||
#define ELFDATA2LSB 1 /* Little-Endian */
|
||||
#define ELFDATA2MSB 2 /* Big-Endian */
|
||||
#define ELFDATANUM 3 /* number of data encode defines */
|
||||
|
||||
/* e_ident[] Operating System/ABI */
|
||||
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
|
||||
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
|
||||
#define ELFOSABI_NETBSD 2 /* NetBSD */
|
||||
#define ELFOSABI_LINUX 3 /* GNU/Linux */
|
||||
#define ELFOSABI_HURD 4 /* GNU/Hurd */
|
||||
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
|
||||
#define ELFOSABI_SOLARIS 6 /* Solaris */
|
||||
#define ELFOSABI_MONTEREY 7 /* Monterey */
|
||||
#define ELFOSABI_IRIX 8 /* IRIX */
|
||||
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
|
||||
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
/* e_ident */
|
||||
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
|
||||
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
|
||||
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
|
||||
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
|
||||
|
||||
/* ELF Header */
|
||||
typedef struct elfhdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF Identification */
|
||||
Elf32_Half e_type; /* object file type */
|
||||
Elf32_Half e_machine; /* machine */
|
||||
Elf32_Word e_version; /* object file version */
|
||||
Elf32_Addr e_entry; /* virtual entry point */
|
||||
Elf32_Off e_phoff; /* program header table offset */
|
||||
Elf32_Off e_shoff; /* section header table offset */
|
||||
Elf32_Word e_flags; /* processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size */
|
||||
Elf32_Half e_phentsize; /* program header entry size */
|
||||
Elf32_Half e_phnum; /* number of program header entries */
|
||||
Elf32_Half e_shentsize; /* section header entry size */
|
||||
Elf32_Half e_shnum; /* number of section header entries */
|
||||
Elf32_Half e_shstrndx; /* section header table's "section
|
||||
header string table" entry offset */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT]; /* Id bytes */
|
||||
Elf64_Half e_type; /* file type */
|
||||
Elf64_Half e_machine; /* machine type */
|
||||
Elf64_Word e_version; /* version number */
|
||||
Elf64_Addr e_entry; /* entry point */
|
||||
Elf64_Off e_phoff; /* Program hdr offset */
|
||||
Elf64_Off e_shoff; /* Section hdr offset */
|
||||
Elf64_Word e_flags; /* Processor flags */
|
||||
Elf64_Half e_ehsize; /* sizeof ehdr */
|
||||
Elf64_Half e_phentsize; /* Program header entry size */
|
||||
Elf64_Half e_phnum; /* Number of program headers */
|
||||
Elf64_Half e_shentsize; /* Section header entry size */
|
||||
Elf64_Half e_shnum; /* Number of section headers */
|
||||
Elf64_Half e_shstrndx; /* String table index */
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* e_type */
|
||||
#define ET_NONE 0 /* No file type */
|
||||
#define ET_REL 1 /* relocatable file */
|
||||
#define ET_EXEC 2 /* executable file */
|
||||
#define ET_DYN 3 /* shared object file */
|
||||
#define ET_CORE 4 /* core file */
|
||||
#define ET_NUM 5 /* number of types */
|
||||
#define ET_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define ET_HIPROC 0xffff /* specific e_type */
|
||||
|
||||
/* e_machine */
|
||||
#define EM_NONE 0 /* No Machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 80486 - unused? */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
|
||||
/*
|
||||
* Don't know if EM_MIPS_RS4_BE,
|
||||
* EM_SPARC64, EM_PARISC,
|
||||
* or EM_PPC are ABI compliant
|
||||
*/
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
|
||||
#define EM_SPARC64 11 /* SPARC v9 64-bit unofficial */
|
||||
#define EM_PARISC 15 /* HPPA */
|
||||
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_PPC64 21 /* PowerPC 64 */
|
||||
#define EM_ARM 40 /* Advanced RISC Machines ARM */
|
||||
#define EM_ALPHA 41 /* DEC ALPHA */
|
||||
#define EM_SH 42 /* Hitachi/Renesas Super-H */
|
||||
#define EM_SPARCV9 43 /* SPARC version 9 */
|
||||
#define EM_IA_64 50 /* Intel IA-64 Processor */
|
||||
#define EM_AMD64 62 /* AMD64 architecture */
|
||||
#define EM_X86_64 EM_AMD64
|
||||
#define EM_VAX 75 /* DEC VAX */
|
||||
#define EM_AARCH64 183 /* ARM 64-bit architecture (AArch64) */
|
||||
#define EM_RISCV 243 /* RISC-V */
|
||||
|
||||
/* Non-standard */
|
||||
#define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */
|
||||
#define EM__LAST__ (EM_ALPHA_EXP + 1)
|
||||
|
||||
#define EM_NUM 22 /* number of machine types */
|
||||
|
||||
/* Version */
|
||||
#define EV_NONE 0 /* Invalid */
|
||||
#define EV_CURRENT 1 /* Current */
|
||||
#define EV_NUM 2 /* number of versions */
|
||||
|
||||
/* Magic for e_phnum: get real value from sh_info of first section header */
|
||||
#define PN_XNUM 0xffff
|
||||
|
||||
/* Section Header */
|
||||
typedef struct {
|
||||
Elf32_Word sh_name; /* name - index into section header
|
||||
string table section */
|
||||
Elf32_Word sh_type; /* type */
|
||||
Elf32_Word sh_flags; /* flags */
|
||||
Elf32_Addr sh_addr; /* address */
|
||||
Elf32_Off sh_offset; /* file offset */
|
||||
Elf32_Word sh_size; /* section size */
|
||||
Elf32_Word sh_link; /* section header table index link */
|
||||
Elf32_Word sh_info; /* extra information */
|
||||
Elf32_Word sh_addralign; /* address alignment */
|
||||
Elf32_Word sh_entsize; /* section entry size */
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word sh_name; /* section name */
|
||||
Elf64_Word sh_type; /* section type */
|
||||
Elf64_Xword sh_flags; /* section flags */
|
||||
Elf64_Addr sh_addr; /* virtual address */
|
||||
Elf64_Off sh_offset; /* file offset */
|
||||
Elf64_Xword sh_size; /* section size */
|
||||
Elf64_Word sh_link; /* link to another */
|
||||
Elf64_Word sh_info; /* misc info */
|
||||
Elf64_Xword sh_addralign; /* memory alignment */
|
||||
Elf64_Xword sh_entsize; /* table entry size */
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* Special Section Indexes */
|
||||
#define SHN_UNDEF 0 /* undefined */
|
||||
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
|
||||
#define SHN_LOPROC 0xff00 /* reserved range for processor */
|
||||
#define SHN_HIPROC 0xff1f /* specific section indexes */
|
||||
#define SHN_ABS 0xfff1 /* absolute value */
|
||||
#define SHN_COMMON 0xfff2 /* common symbol */
|
||||
#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
|
||||
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0 /* inactive */
|
||||
#define SHT_PROGBITS 1 /* program defined information */
|
||||
#define SHT_SYMTAB 2 /* symbol table section */
|
||||
#define SHT_STRTAB 3 /* string table section */
|
||||
#define SHT_RELA 4 /* relocation section with addends*/
|
||||
#define SHT_HASH 5 /* symbol hash table section */
|
||||
#define SHT_DYNAMIC 6 /* dynamic section */
|
||||
#define SHT_NOTE 7 /* note section */
|
||||
#define SHT_NOBITS 8 /* no space section */
|
||||
#define SHT_REL 9 /* relocation section without addends */
|
||||
#define SHT_SHLIB 10 /* reserved - purpose unknown */
|
||||
#define SHT_DYNSYM 11 /* dynamic symbol table section */
|
||||
#define SHT_NUM 12 /* number of section types */
|
||||
#define SHT_INIT_ARRAY 14 /* pointers to init functions */
|
||||
#define SHT_FINI_ARRAY 15 /* pointers to termination functions */
|
||||
#define SHT_PREINIT_ARRAY 16 /* ptrs to funcs called before init */
|
||||
#define SHT_GROUP 17 /* defines a section group */
|
||||
#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
|
||||
#define SHT_RELR 19 /* relative-only relocation section */
|
||||
#define SHT_LOOS 0x60000000 /* reserved range for OS specific */
|
||||
#define SHT_SUNW_dof 0x6ffffff4 /* used by dtrace */
|
||||
#define SHT_GNU_LIBLIST 0x6ffffff7 /* libraries to be prelinked */
|
||||
#define SHT_SUNW_move 0x6ffffffa /* inf for partially init'ed symbols */
|
||||
#define SHT_SUNW_syminfo 0x6ffffffc /* ad symbol information */
|
||||
#define SHT_SUNW_verdef 0x6ffffffd /* symbol versioning inf */
|
||||
#define SHT_SUNW_verneed 0x6ffffffe /* symbol versioning req */
|
||||
#define SHT_SUNW_versym 0x6fffffff /* symbol versioning table */
|
||||
#define SHT_HIOS 0x6fffffff /* section header types */
|
||||
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define SHT_HIPROC 0x7fffffff /* specific section header types */
|
||||
#define SHT_LOUSER 0x80000000 /* reserved range for application */
|
||||
#define SHT_HIUSER 0xffffffff /* specific indexes */
|
||||
|
||||
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table section */
|
||||
|
||||
/* Section names */
|
||||
#define ELF_BSS ".bss" /* uninitialized data */
|
||||
#define ELF_DATA ".data" /* initialized data */
|
||||
#define ELF_CTF ".SUNW_ctf" /* CTF data */
|
||||
#define ELF_DEBUG ".debug" /* debug */
|
||||
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
|
||||
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
|
||||
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
|
||||
#define ELF_FINI ".fini" /* termination code */
|
||||
#define ELF_GOT ".got" /* global offset table */
|
||||
#define ELF_HASH ".hash" /* symbol hash table */
|
||||
#define ELF_INIT ".init" /* initialization code */
|
||||
#define ELF_REL_DATA ".rel.data" /* relocation data */
|
||||
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
|
||||
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
|
||||
#define ELF_REL_DYN ".rel.dyn" /* relocation dynamic link info */
|
||||
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
|
||||
#define ELF_REL_TEXT ".rel.text" /* relocation code */
|
||||
#define ELF_RODATA ".rodata" /* read-only data */
|
||||
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
|
||||
#define ELF_STRTAB ".strtab" /* string table */
|
||||
#define ELF_SYMTAB ".symtab" /* symbol table */
|
||||
#define ELF_TEXT ".text" /* code */
|
||||
#define ELF_OPENBSDRANDOMDATA ".openbsd.randomdata" /* constant randomdata */
|
||||
#define ELF_OPENBSDMUTABLE ".openbsd.mutable" /* mutable bss */
|
||||
|
||||
|
||||
/* Section Attribute Flags - sh_flags */
|
||||
#define SHF_WRITE 0x1 /* Writable */
|
||||
#define SHF_ALLOC 0x2 /* occupies memory */
|
||||
#define SHF_EXECINSTR 0x4 /* executable */
|
||||
#define SHF_MERGE 0x10 /* may be merged */
|
||||
#define SHF_STRINGS 0x20 /* contains strings */
|
||||
#define SHF_INFO_LINK 0x40 /* sh_info holds section index */
|
||||
#define SHF_LINK_ORDER 0x80 /* ordering requirements */
|
||||
#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required */
|
||||
#define SHF_GROUP 0x200 /* member of section group */
|
||||
#define SHF_TLS 0x400 /* thread local storage */
|
||||
#define SHF_COMPRESSED 0x800 /* contains compressed data */
|
||||
#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics */
|
||||
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific section attributes */
|
||||
|
||||
/* Symbol Table Entry */
|
||||
typedef struct elf32_sym {
|
||||
Elf32_Word st_name; /* name - index into string table */
|
||||
Elf32_Addr st_value; /* symbol value */
|
||||
Elf32_Word st_size; /* symbol size */
|
||||
unsigned char st_info; /* type and binding */
|
||||
unsigned char st_other; /* 0 - no defined meaning */
|
||||
Elf32_Half st_shndx; /* section header index */
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word st_name; /* Symbol name index in str table */
|
||||
unsigned char st_info; /* type / binding attrs */
|
||||
unsigned char st_other; /* unused */
|
||||
Elf64_Half st_shndx; /* section index of symbol */
|
||||
Elf64_Addr st_value; /* value of symbol */
|
||||
Elf64_Xword st_size; /* size of symbol */
|
||||
} Elf64_Sym;
|
||||
|
||||
/* Symbol table index */
|
||||
#define STN_UNDEF 0 /* undefined */
|
||||
|
||||
/* Extract symbol info - st_info */
|
||||
#define ELF32_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||
|
||||
#define ELF64_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
|
||||
|
||||
/* Symbol Binding - ELF32_ST_BIND - st_info */
|
||||
#define STB_LOCAL 0 /* Local symbol */
|
||||
#define STB_GLOBAL 1 /* Global symbol */
|
||||
#define STB_WEAK 2 /* like global - lower precedence */
|
||||
#define STB_NUM 3 /* number of symbol bindings */
|
||||
#define STB_LOPROC 13 /* reserved range for processor */
|
||||
#define STB_HIPROC 15 /* specific symbol bindings */
|
||||
|
||||
/* Symbol type - ELF32_ST_TYPE - st_info */
|
||||
#define STT_NOTYPE 0 /* not specified */
|
||||
#define STT_OBJECT 1 /* data object */
|
||||
#define STT_FUNC 2 /* function */
|
||||
#define STT_SECTION 3 /* section */
|
||||
#define STT_FILE 4 /* file */
|
||||
#define STT_TLS 6 /* thread local storage */
|
||||
#define STT_LOPROC 13 /* reserved range for processor */
|
||||
#define STT_HIPROC 15 /* specific symbol types */
|
||||
|
||||
/* Extract symbol visibility - st_other */
|
||||
#define ELF_ST_VISIBILITY(v) ((v) & 0x3)
|
||||
#define ELF32_ST_VISIBILITY ELF_ST_VISIBILITY
|
||||
#define ELF64_ST_VISIBILITY ELF_ST_VISIBILITY
|
||||
|
||||
#define STV_DEFAULT 0 /* Visibility set by binding type */
|
||||
#define STV_INTERNAL 1 /* OS specific version of STV_HIDDEN */
|
||||
#define STV_HIDDEN 2 /* can only be seen inside own .so */
|
||||
#define STV_PROTECTED 3 /* HIDDEN inside, DEFAULT outside */
|
||||
|
||||
/* Relocation entry with implicit addend */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
} Elf32_Rel;
|
||||
|
||||
/* Relocation entry with explicit addend */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset; /* offset of relocation */
|
||||
Elf32_Word r_info; /* symbol table index and type */
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
/* Extract relocation info - r_info */
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char) (i))
|
||||
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
|
||||
|
||||
typedef struct {
|
||||
Elf64_Addr r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Addr r_offset; /* where to do it */
|
||||
Elf64_Xword r_info; /* index & type of relocation */
|
||||
Elf64_Sxword r_addend; /* adjustment value */
|
||||
} Elf64_Rela;
|
||||
|
||||
#define ELF64_R_SYM(info) ((info) >> 32)
|
||||
#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s,t) (((s) << 32) + (__uint32_t)(t))
|
||||
|
||||
#if defined(__mips64__) && defined(__MIPSEL__)
|
||||
/*
|
||||
* The 64-bit MIPS ELF ABI uses a slightly different relocation format
|
||||
* than the regular ELF ABI: the r_info field is split into several
|
||||
* pieces (see gnu/usr.bin/binutils-2.17/include/elf/mips.h for details).
|
||||
*/
|
||||
#undef ELF64_R_SYM
|
||||
#undef ELF64_R_TYPE
|
||||
#undef ELF64_R_INFO
|
||||
#define ELF64_R_TYPE(info) ((__uint64_t)swap32((info) >> 32))
|
||||
#define ELF64_R_SYM(info) ((info) & 0xFFFFFFFF)
|
||||
#define ELF64_R_INFO(s,t) (((__uint64_t)swap32(t) << 32) + (__uint32_t)(s))
|
||||
#endif /* __mips64__ && __MIPSEL__ */
|
||||
|
||||
/*
|
||||
* Relative Relocation info.
|
||||
* c.f. decode_relrs() in gnu/llvm/llvm/lib/Object/ELF.cpp
|
||||
*/
|
||||
typedef Elf32_Word Elf32_Relr;
|
||||
typedef Elf64_Xword Elf64_Relr;
|
||||
|
||||
/* Program Header */
|
||||
typedef struct {
|
||||
Elf32_Word p_type; /* segment type */
|
||||
Elf32_Off p_offset; /* segment offset */
|
||||
Elf32_Addr p_vaddr; /* virtual address of segment */
|
||||
Elf32_Addr p_paddr; /* physical address - ignored? */
|
||||
Elf32_Word p_filesz; /* number of bytes in file for seg. */
|
||||
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
|
||||
Elf32_Word p_flags; /* flags */
|
||||
Elf32_Word p_align; /* memory alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word p_type; /* entry type */
|
||||
Elf64_Word p_flags; /* flags */
|
||||
Elf64_Off p_offset; /* offset */
|
||||
Elf64_Addr p_vaddr; /* virtual address */
|
||||
Elf64_Addr p_paddr; /* physical address */
|
||||
Elf64_Xword p_filesz; /* file size */
|
||||
Elf64_Xword p_memsz; /* memory size */
|
||||
Elf64_Xword p_align; /* memory & file alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* Segment types - p_type */
|
||||
#define PT_NULL 0 /* unused */
|
||||
#define PT_LOAD 1 /* loadable segment */
|
||||
#define PT_DYNAMIC 2 /* dynamic linking section */
|
||||
#define PT_INTERP 3 /* the RTLD */
|
||||
#define PT_NOTE 4 /* auxiliary information */
|
||||
#define PT_SHLIB 5 /* reserved - purpose undefined */
|
||||
#define PT_PHDR 6 /* program header */
|
||||
#define PT_TLS 7 /* thread local storage */
|
||||
#define PT_LOOS 0x60000000 /* reserved range for OS */
|
||||
#define PT_HIOS 0x6fffffff /* specific segment types */
|
||||
#define PT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define PT_HIPROC 0x7fffffff /* specific segment types */
|
||||
|
||||
#define PT_GNU_EH_FRAME 0x6474e550 /* Exception handling info */
|
||||
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
|
||||
|
||||
#define PT_OPENBSD_MUTABLE 0x65a3dbe5 /* like bss, but not immutable */
|
||||
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */
|
||||
#define PT_OPENBSD_WXNEEDED 0x65a3dbe7 /* program performs W^X violations */
|
||||
#define PT_OPENBSD_BOOTDATA 0x65a41be6 /* section for boot arguments */
|
||||
|
||||
/* Segment flags - p_flags */
|
||||
#define PF_X 0x1 /* Executable */
|
||||
#define PF_W 0x2 /* Writable */
|
||||
#define PF_R 0x4 /* Readable */
|
||||
#define PF_MASKOS 0x0ff00000 /* reserved bits for OS */
|
||||
/* specific segment flags */
|
||||
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
|
||||
/* specific segment flags */
|
||||
|
||||
#define PF_OPENBSD_MUTABLE 0x08000000 /* Mutable */
|
||||
|
||||
/* Dynamic structure */
|
||||
typedef struct {
|
||||
Elf32_Sword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf32_Word d_val; /* Multiple meanings - see d_tag */
|
||||
Elf32_Addr d_ptr; /* program virtual address */
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Xword d_tag; /* controls meaning of d_val */
|
||||
union {
|
||||
Elf64_Addr d_ptr;
|
||||
Elf64_Xword d_val;
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* Dynamic Array Tags - d_tag */
|
||||
#define DT_NULL 0 /* marks end of _DYNAMIC array */
|
||||
#define DT_NEEDED 1 /* string table offset of needed lib */
|
||||
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
|
||||
#define DT_PLTGOT 3 /* address PLT/GOT */
|
||||
#define DT_HASH 4 /* address of symbol hash table */
|
||||
#define DT_STRTAB 5 /* address of string table */
|
||||
#define DT_SYMTAB 6 /* address of symbol table */
|
||||
#define DT_RELA 7 /* address of relocation table */
|
||||
#define DT_RELASZ 8 /* size of relocation table */
|
||||
#define DT_RELAENT 9 /* size of relocation entry */
|
||||
#define DT_STRSZ 10 /* size of string table */
|
||||
#define DT_SYMENT 11 /* size of symbol table entry */
|
||||
#define DT_INIT 12 /* address of initialization func. */
|
||||
#define DT_FINI 13 /* address of termination function */
|
||||
#define DT_SONAME 14 /* string table offset of shared obj */
|
||||
#define DT_RPATH 15 /* string table offset of library
|
||||
search path */
|
||||
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
|
||||
#define DT_REL 17 /* address of rel. tbl. w addends */
|
||||
#define DT_RELSZ 18 /* size of DT_REL relocation table */
|
||||
#define DT_RELENT 19 /* size of DT_REL relocation entry */
|
||||
#define DT_PLTREL 20 /* PLT referenced relocation entry */
|
||||
#define DT_DEBUG 21 /* bugger */
|
||||
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
|
||||
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
|
||||
#define DT_BIND_NOW 24 /* Bind now regardless of env setting */
|
||||
#define DT_INIT_ARRAY 25 /* address of array of init func */
|
||||
#define DT_FINI_ARRAY 26 /* address of array of term func */
|
||||
#define DT_INIT_ARRAYSZ 27 /* size of array of init func */
|
||||
#define DT_FINI_ARRAYSZ 28 /* size of array of term func */
|
||||
#define DT_RUNPATH 29 /* strtab offset of lib search path */
|
||||
#define DT_FLAGS 30 /* Set of DF_* flags */
|
||||
#define DT_ENCODING 31 /* further DT_* follow encoding rules */
|
||||
#define DT_PREINIT_ARRAY 32 /* address of array of preinit func */
|
||||
#define DT_PREINIT_ARRAYSZ 33 /* size of array of preinit func */
|
||||
#define DT_RELRSZ 35 /* size of DT_RELR relocation table */
|
||||
#define DT_RELR 36 /* addr of DT_RELR relocation table */
|
||||
#define DT_RELRENT 37 /* size of DT_RELR relocation entry */
|
||||
#define DT_LOOS 0x6000000d /* reserved range for OS */
|
||||
#define DT_HIOS 0x6ffff000 /* specific dynamic array tags */
|
||||
#define DT_LOPROC 0x70000000 /* reserved range for processor */
|
||||
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
|
||||
|
||||
/* some other useful tags */
|
||||
#define DT_GNU_HASH 0x6ffffef5 /* address of GNU hash table */
|
||||
#define DT_RELACOUNT 0x6ffffff9 /* if present, number of RELATIVE */
|
||||
#define DT_RELCOUNT 0x6ffffffa /* relocs, which must come first */
|
||||
#define DT_FLAGS_1 0x6ffffffb
|
||||
|
||||
/* Dynamic Flags - DT_FLAGS .dynamic entry */
|
||||
#define DF_ORIGIN 0x00000001
|
||||
#define DF_SYMBOLIC 0x00000002
|
||||
#define DF_TEXTREL 0x00000004
|
||||
#define DF_BIND_NOW 0x00000008
|
||||
#define DF_STATIC_TLS 0x00000010
|
||||
|
||||
/* Dynamic Flags - DT_FLAGS_1 .dynamic entry */
|
||||
#define DF_1_NOW 0x00000001
|
||||
#define DF_1_GLOBAL 0x00000002
|
||||
#define DF_1_GROUP 0x00000004
|
||||
#define DF_1_NODELETE 0x00000008
|
||||
#define DF_1_LOADFLTR 0x00000010
|
||||
#define DF_1_INITFIRST 0x00000020
|
||||
#define DF_1_NOOPEN 0x00000040
|
||||
#define DF_1_ORIGIN 0x00000080
|
||||
#define DF_1_DIRECT 0x00000100
|
||||
#define DF_1_TRANS 0x00000200
|
||||
#define DF_1_INTERPOSE 0x00000400
|
||||
#define DF_1_NODEFLIB 0x00000800
|
||||
#define DF_1_NODUMP 0x00001000
|
||||
#define DF_1_CONLFAT 0x00002000
|
||||
#define DF_1_ENDFILTEE 0x00004000
|
||||
#define DF_1_DISPRELDNE 0x00008000
|
||||
#define DF_1_DISPRELPND 0x00010000
|
||||
#define DF_1_NODIRECT 0x00020000
|
||||
#define DF_1_IGNMULDEF 0x00040000
|
||||
#define DF_1_NOKSYMS 0x00080000
|
||||
#define DF_1_NOHDR 0x00100000
|
||||
#define DF_1_EDITED 0x00200000
|
||||
#define DF_1_NORELOC 0x00400000
|
||||
#define DF_1_SYMINTPOSE 0x00800000
|
||||
#define DF_1_GLOBAUDIT 0x01000000
|
||||
#define DF_1_SINGLETON 0x02000000
|
||||
#define DF_1_PIE 0x08000000
|
||||
|
||||
/*
|
||||
* Note header
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word n_namesz;
|
||||
Elf32_Word n_descsz;
|
||||
Elf32_Word n_type;
|
||||
} Elf32_Nhdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word n_namesz;
|
||||
Elf64_Word n_descsz;
|
||||
Elf64_Word n_type;
|
||||
} Elf64_Nhdr;
|
||||
|
||||
/*
|
||||
* Note Definitions
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word namesz;
|
||||
Elf32_Word descsz;
|
||||
Elf32_Word type;
|
||||
} Elf32_Note;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word namesz;
|
||||
Elf64_Word descsz;
|
||||
Elf64_Word type;
|
||||
} Elf64_Note;
|
||||
|
||||
/* Values for n_type. */
|
||||
#define NT_PRSTATUS 1 /* Process status. */
|
||||
#define NT_FPREGSET 2 /* Floating point registers. */
|
||||
#define NT_PRPSINFO 3 /* Process state info. */
|
||||
|
||||
/*
|
||||
* OpenBSD-specific core file information.
|
||||
*
|
||||
* OpenBSD ELF core files use notes to provide information about
|
||||
* the process's state. The note name is "OpenBSD" for information
|
||||
* that is global to the process, and "OpenBSD@nn", where "nn" is the
|
||||
* thread ID of the thread that the information belongs to (such as
|
||||
* register state).
|
||||
*
|
||||
* We use the following note identifiers:
|
||||
*
|
||||
* NT_OPENBSD_PROCINFO
|
||||
* Note is a "elfcore_procinfo" structure.
|
||||
* NT_OPENBSD_AUXV
|
||||
* Note is a a bunch of Auxiliary Vectors, terminated by
|
||||
* an AT_NULL entry.
|
||||
* NT_OPENBSD_REGS
|
||||
* Note is a "reg" structure.
|
||||
* NT_OPENBSD_FPREGS
|
||||
* Note is a "fpreg" structure.
|
||||
*
|
||||
* Please try to keep the members of the "elfcore_procinfo" structure
|
||||
* nicely aligned, and if you add elements, add them to the end and
|
||||
* bump the version.
|
||||
*/
|
||||
|
||||
#define NT_OPENBSD_PROCINFO 10
|
||||
#define NT_OPENBSD_AUXV 11
|
||||
|
||||
#define NT_OPENBSD_REGS 20
|
||||
#define NT_OPENBSD_FPREGS 21
|
||||
#define NT_OPENBSD_XFPREGS 22
|
||||
#define NT_OPENBSD_WCOOKIE 23
|
||||
|
||||
struct elfcore_procinfo {
|
||||
/* Version 1 fields start here. */
|
||||
uint32_t cpi_version; /* netbsd_elfcore_procinfo version */
|
||||
#define ELFCORE_PROCINFO_VERSION 1
|
||||
uint32_t cpi_cpisize; /* sizeof(netbsd_elfcore_procinfo) */
|
||||
uint32_t cpi_signo; /* killing signal */
|
||||
uint32_t cpi_sigcode; /* signal code */
|
||||
uint32_t cpi_sigpend; /* pending signals */
|
||||
uint32_t cpi_sigmask; /* blocked signals */
|
||||
uint32_t cpi_sigignore; /* ignored signals */
|
||||
uint32_t cpi_sigcatch; /* signals being caught by user */
|
||||
int32_t cpi_pid; /* process ID */
|
||||
int32_t cpi_ppid; /* parent process ID */
|
||||
int32_t cpi_pgrp; /* process group ID */
|
||||
int32_t cpi_sid; /* session ID */
|
||||
uint32_t cpi_ruid; /* real user ID */
|
||||
uint32_t cpi_euid; /* effective user ID */
|
||||
uint32_t cpi_svuid; /* saved user ID */
|
||||
uint32_t cpi_rgid; /* real group ID */
|
||||
uint32_t cpi_egid; /* effective group ID */
|
||||
uint32_t cpi_svgid; /* saved group ID */
|
||||
int8_t cpi_name[32]; /* copy of pr->ps_comm */
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX - these _KERNEL items aren't part of the ABI!
|
||||
*/
|
||||
#if defined(_KERNEL) || defined(_DYN_LOADER)
|
||||
|
||||
#define ELF32_NO_ADDR ((uint32_t) ~0) /* Indicates addr. not yet filled in */
|
||||
|
||||
typedef struct {
|
||||
Elf32_Sword au_id; /* 32-bit id */
|
||||
Elf32_Word au_v; /* 32-bit value */
|
||||
} Aux32Info;
|
||||
|
||||
#define ELF64_NO_ADDR ((__uint64_t) ~0)/* Indicates addr. not yet filled in */
|
||||
|
||||
typedef struct {
|
||||
Elf64_Shalf au_id; /* 32-bit id */
|
||||
Elf64_Xword au_v; /* 64-bit value */
|
||||
} Aux64Info;
|
||||
|
||||
enum AuxID {
|
||||
AUX_null = 0,
|
||||
AUX_ignore = 1,
|
||||
AUX_execfd = 2,
|
||||
AUX_phdr = 3, /* &phdr[0] */
|
||||
AUX_phent = 4, /* sizeof(phdr[0]) */
|
||||
AUX_phnum = 5, /* # phdr entries */
|
||||
AUX_pagesz = 6, /* PAGESIZE */
|
||||
AUX_base = 7, /* base addr for ld.so or static PIE */
|
||||
AUX_flags = 8, /* processor flags */
|
||||
AUX_entry = 9, /* a.out entry */
|
||||
AUX_sun_uid = 2000, /* euid */
|
||||
AUX_sun_ruid = 2001, /* ruid */
|
||||
AUX_sun_gid = 2002, /* egid */
|
||||
AUX_sun_rgid = 2003, /* rgid */
|
||||
AUX_openbsd_timekeep = 4000, /* userland clock_gettime */
|
||||
};
|
||||
|
||||
struct elf_args {
|
||||
u_long arg_entry; /* program entry point */
|
||||
u_long arg_interp; /* Interpreter load address */
|
||||
u_long arg_phaddr; /* program header address */
|
||||
u_long arg_phentsize; /* Size of program header */
|
||||
u_long arg_phnum; /* Number of program headers */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
|
||||
#define ELFSIZE ARCH_ELFSIZE
|
||||
#endif
|
||||
|
||||
#if defined(ELFSIZE)
|
||||
#define CONCAT(x,y) __CONCAT(x,y)
|
||||
#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
|
||||
#endif
|
||||
|
||||
#if defined(ELFSIZE) && (ELFSIZE == 32)
|
||||
#define Elf_Ehdr Elf32_Ehdr
|
||||
#define Elf_Phdr Elf32_Phdr
|
||||
#define Elf_Shdr Elf32_Shdr
|
||||
#define Elf_Sym Elf32_Sym
|
||||
#define Elf_Rel Elf32_Rel
|
||||
#define Elf_RelA Elf32_Rela
|
||||
#define Elf_Relr Elf32_Relr
|
||||
#define Elf_Dyn Elf32_Dyn
|
||||
#define Elf_Half Elf32_Half
|
||||
#define Elf_Word Elf32_Word
|
||||
#define Elf_Sword Elf32_Sword
|
||||
#define Elf_Addr Elf32_Addr
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Note Elf32_Note
|
||||
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
#define ELF_R_INFO ELF32_R_INFO
|
||||
#define ELFCLASS ELFCLASS32
|
||||
|
||||
#define ELF_ST_BIND ELF32_ST_BIND
|
||||
#define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
#define ELF_ST_INFO ELF32_ST_INFO
|
||||
|
||||
#define ELF_NO_ADDR ELF32_NO_ADDR
|
||||
#define AuxInfo Aux32Info
|
||||
#elif defined(ELFSIZE) && (ELFSIZE == 64)
|
||||
#define Elf_Ehdr Elf64_Ehdr
|
||||
#define Elf_Phdr Elf64_Phdr
|
||||
#define Elf_Shdr Elf64_Shdr
|
||||
#define Elf_Sym Elf64_Sym
|
||||
#define Elf_Rel Elf64_Rel
|
||||
#define Elf_RelA Elf64_Rela
|
||||
#define Elf_Relr Elf64_Relr
|
||||
#define Elf_Dyn Elf64_Dyn
|
||||
#define Elf_Half Elf64_Half
|
||||
#define Elf_Word Elf64_Word
|
||||
#define Elf_Sword Elf64_Sword
|
||||
#define Elf_Addr Elf64_Addr
|
||||
#define Elf_Off Elf64_Off
|
||||
#define Elf_Nhdr Elf64_Nhdr
|
||||
#define Elf_Note Elf64_Note
|
||||
|
||||
#define ELF_R_SYM ELF64_R_SYM
|
||||
#define ELF_R_TYPE ELF64_R_TYPE
|
||||
#define ELF_R_INFO ELF64_R_INFO
|
||||
#define ELFCLASS ELFCLASS64
|
||||
|
||||
#define ELF_ST_BIND ELF64_ST_BIND
|
||||
#define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
#define ELF_ST_INFO ELF64_ST_INFO
|
||||
|
||||
#define ELF_NO_ADDR ELF64_NO_ADDR
|
||||
#define AuxInfo Aux64Info
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* How many entries are in the AuxInfo array we pass to the process?
|
||||
*/
|
||||
#define ELF_AUX_ENTRIES 9
|
||||
#define ELF_AUX_WORDS (sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *))
|
||||
|
||||
struct exec_package;
|
||||
|
||||
int exec_elf_makecmds(struct proc *, struct exec_package *);
|
||||
int exec_elf_fixup(struct proc *, struct exec_package *);
|
||||
int coredump_elf(struct proc *, void *);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
|
||||
|
||||
#endif /* _SYS_EXEC_ELF_H_ */
|
||||
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <elf/elf.h>
|
||||
#include <elf/elf32.h>
|
||||
#include <elf/elf64.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ELF header functions */
|
||||
int elf_newFile(const void *file, size_t size, elf_t *res)
|
||||
{
|
||||
return elf_newFile_maybe_unsafe(file, size, true, true, res);
|
||||
}
|
||||
|
||||
int elf_newFile_maybe_unsafe(const void *file, size_t size, bool check_pht, bool check_st, elf_t *res)
|
||||
{
|
||||
elf_t new_file = {
|
||||
.elfFile = file,
|
||||
.elfSize = size
|
||||
};
|
||||
|
||||
int status = elf_checkFile(&new_file);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (check_pht) {
|
||||
status = elf_checkProgramHeaderTable(&new_file);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_st) {
|
||||
status = elf_checkSectionTable(&new_file);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (res) {
|
||||
*res = new_file;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int elf_check_magic(const char *file)
|
||||
{
|
||||
if (memcmp(file, ELFMAG, SELFMAG) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks that elfFile points to a valid elf file. Returns 0 if the elf
|
||||
* file is valid, < 0 if invalid.
|
||||
*/
|
||||
int elf_checkFile(elf_t *elfFile)
|
||||
{
|
||||
int res = elf32_checkFile(elfFile);
|
||||
if (res == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = elf64_checkFile(elfFile);
|
||||
if (res == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int elf_checkProgramHeaderTable(const elf_t *elfFile)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_checkProgramHeaderTable(elfFile);
|
||||
} else {
|
||||
return elf64_checkProgramHeaderTable(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
int elf_checkSectionTable(const elf_t *elfFile)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_checkSectionTable(elfFile);
|
||||
} else {
|
||||
return elf64_checkSectionTable(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t elf_getEntryPoint(const elf_t *elfFile)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getEntryPoint(elfFile);
|
||||
} else {
|
||||
return elf64_getEntryPoint(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getNumProgramHeaders(const elf_t *elfFile)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getNumProgramHeaders(elfFile);
|
||||
} else {
|
||||
return elf64_getNumProgramHeaders(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getNumSections(const elf_t *elfFile)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getNumSections(elfFile);
|
||||
} else {
|
||||
return elf64_getNumSections(elfFile);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionStringTableIndex(const elf_t *elf)
|
||||
{
|
||||
if (elf_isElf32(elf)) {
|
||||
return elf32_getSectionStringTableIndex(elf);
|
||||
} else {
|
||||
return elf64_getSectionStringTableIndex(elf);
|
||||
}
|
||||
}
|
||||
|
||||
const char *elf_getStringTable(const elf_t *elf, size_t string_segment)
|
||||
{
|
||||
const char *string_table = elf_getSection(elf, string_segment);
|
||||
if (string_table == NULL) {
|
||||
return NULL; /* no such section */
|
||||
}
|
||||
|
||||
if (elf_getSectionType(elf, string_segment) != SHT_STRTAB) {
|
||||
return NULL; /* not a string table */
|
||||
}
|
||||
|
||||
size_t size = elf_getSectionSize(elf, string_segment);
|
||||
if (string_table[size - 1] != 0) {
|
||||
return NULL; /* string table is not null-terminated */
|
||||
}
|
||||
|
||||
return string_table;
|
||||
}
|
||||
|
||||
const char *elf_getSectionStringTable(const elf_t *elf)
|
||||
{
|
||||
size_t index = elf_getSectionStringTableIndex(elf);
|
||||
return elf_getStringTable(elf, index);
|
||||
}
|
||||
|
||||
|
||||
/* Section header functions */
|
||||
const void *elf_getSection(const elf_t *elf, size_t i)
|
||||
{
|
||||
if (i == 0 || i >= elf_getNumSections(elf)) {
|
||||
return NULL; /* no such section */
|
||||
}
|
||||
|
||||
size_t section_offset = elf_getSectionOffset(elf, i);
|
||||
size_t section_size = elf_getSectionSize(elf, i);
|
||||
if (section_size == 0) {
|
||||
return NULL; /* section is empty */
|
||||
}
|
||||
|
||||
size_t section_end = section_offset + section_size;
|
||||
/* possible wraparound - check that section end is not before section start */
|
||||
if (section_end > elf->elfSize || section_end < section_offset) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *)elf->elfFile + section_offset;
|
||||
}
|
||||
|
||||
const void *elf_getSectionNamed(const elf_t *elfFile, const char *str, size_t *id)
|
||||
{
|
||||
size_t numSections = elf_getNumSections(elfFile);
|
||||
for (size_t i = 0; i < numSections; i++) {
|
||||
if (strcmp(str, elf_getSectionName(elfFile, i)) == 0) {
|
||||
if (id != NULL) {
|
||||
*id = i;
|
||||
}
|
||||
return elf_getSection(elfFile, i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *elf_getSectionName(const elf_t *elf, size_t i)
|
||||
{
|
||||
size_t str_table_idx = elf_getSectionStringTableIndex(elf);
|
||||
const char *str_table = elf_getStringTable(elf, str_table_idx);
|
||||
size_t offset = elf_getSectionNameOffset(elf, i);
|
||||
size_t size = elf_getSectionSize(elf, str_table_idx);
|
||||
|
||||
if (str_table == NULL || offset > size) {
|
||||
return "<corrupted>";
|
||||
}
|
||||
|
||||
return str_table + offset;
|
||||
}
|
||||
|
||||
size_t elf_getSectionNameOffset(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionNameOffset(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionNameOffset(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t elf_getSectionType(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionType(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionType(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionFlags(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionFlags(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionFlags(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t elf_getSectionAddr(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionAddr(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionAddr(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionOffset(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionOffset(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionOffset(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionSize(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionSize(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionSize(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t elf_getSectionLink(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionLink(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionLink(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t elf_getSectionInfo(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionInfo(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionInfo(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionAddrAlign(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionAddrAlign(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionAddrAlign(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getSectionEntrySize(const elf_t *elfFile, size_t i)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getSectionEntrySize(elfFile, i);
|
||||
} else {
|
||||
return elf64_getSectionEntrySize(elfFile, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Program headers function */
|
||||
const void *elf_getProgramSegment(const elf_t *elf, size_t ph)
|
||||
{
|
||||
size_t offset = elf_getProgramHeaderOffset(elf, ph);
|
||||
size_t file_size = elf_getProgramHeaderFileSize(elf, ph);
|
||||
size_t segment_end = offset + file_size;
|
||||
/* possible wraparound - check that segment end is not before segment start */
|
||||
if (elf->elfSize < segment_end || segment_end < offset) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *)elf->elfFile + offset;
|
||||
}
|
||||
|
||||
uint32_t elf_getProgramHeaderType(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderType(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderType(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getProgramHeaderOffset(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderOffset(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderOffset(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t elf_getProgramHeaderVaddr(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderVaddr(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderVaddr(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t elf_getProgramHeaderPaddr(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderPaddr(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderPaddr(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getProgramHeaderFileSize(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderFileSize(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderFileSize(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getProgramHeaderMemorySize(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderMemorySize(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderMemorySize(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t elf_getProgramHeaderFlags(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderFlags(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderFlags(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
size_t elf_getProgramHeaderAlign(const elf_t *elfFile, size_t ph)
|
||||
{
|
||||
if (elf_isElf32(elfFile)) {
|
||||
return elf32_getProgramHeaderAlign(elfFile, ph);
|
||||
} else {
|
||||
return elf64_getProgramHeaderAlign(elfFile, ph);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Utility functions */
|
||||
int elf_getMemoryBounds(const elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max)
|
||||
{
|
||||
uintptr_t mem_min = UINTPTR_MAX;
|
||||
uintptr_t mem_max = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < elf_getNumProgramHeaders(elfFile); i++) {
|
||||
uintptr_t sect_min, sect_max;
|
||||
|
||||
if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr_type == PHYSICAL) {
|
||||
sect_min = elf_getProgramHeaderPaddr(elfFile, i);
|
||||
} else {
|
||||
sect_min = elf_getProgramHeaderVaddr(elfFile, i);
|
||||
}
|
||||
|
||||
sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i);
|
||||
|
||||
if (sect_max > mem_max) {
|
||||
mem_max = sect_max;
|
||||
}
|
||||
if (sect_min < mem_min) {
|
||||
mem_min = sect_min;
|
||||
}
|
||||
}
|
||||
*min = mem_min;
|
||||
*max = mem_max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elf_vaddrInProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr)
|
||||
{
|
||||
uintptr_t min = elf_getProgramHeaderVaddr(elfFile, ph);
|
||||
uintptr_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph);
|
||||
if (vaddr >= min && vaddr < max) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t elf_vtopProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr)
|
||||
{
|
||||
uintptr_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph);
|
||||
uintptr_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph);
|
||||
uintptr_t paddr;
|
||||
|
||||
paddr = vaddr - ph_virt + ph_phys;
|
||||
|
||||
return paddr;
|
||||
}
|
||||
|
||||
int elf_loadFile(const elf_t *elf, elf_addr_type_t addr_type)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < elf_getNumProgramHeaders(elf); i++) {
|
||||
/* Load that section */
|
||||
uintptr_t dest, src;
|
||||
size_t len;
|
||||
if (addr_type == PHYSICAL) {
|
||||
dest = elf_getProgramHeaderPaddr(elf, i);
|
||||
} else {
|
||||
dest = elf_getProgramHeaderVaddr(elf, i);
|
||||
}
|
||||
len = elf_getProgramHeaderFileSize(elf, i);
|
||||
src = (uintptr_t) elf->elfFile + elf_getProgramHeaderOffset(elf, i);
|
||||
memcpy((void *) dest, (void *) src, len);
|
||||
dest += len;
|
||||
memset((void *) dest, 0, elf_getProgramHeaderMemorySize(elf, i) - len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <elf/elf.h>
|
||||
#include <elf/elf32.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ELF header functions */
|
||||
int elf32_checkFile(elf_t *elf)
|
||||
{
|
||||
if (elf->elfSize < sizeof(Elf32_Ehdr)) {
|
||||
return -1; /* file smaller than ELF header */
|
||||
}
|
||||
|
||||
if (elf_check_magic(elf->elfFile) < 0) {
|
||||
return -1; /* not an ELF file */
|
||||
}
|
||||
|
||||
Elf32_Ehdr const *header = elf->elfFile;
|
||||
if (header->e_ident[EI_CLASS] != ELFCLASS32) {
|
||||
return -1; /* not a 32-bit ELF */
|
||||
}
|
||||
|
||||
if (header->e_phentsize != sizeof(Elf32_Phdr)) {
|
||||
return -1; /* unexpected program header size */
|
||||
}
|
||||
|
||||
if (header->e_shentsize != sizeof(Elf32_Shdr)) {
|
||||
return -1; /* unexpected section header size */
|
||||
}
|
||||
|
||||
if (header->e_shstrndx >= header->e_shnum) {
|
||||
return -1; /* invalid section header string table section */
|
||||
}
|
||||
|
||||
elf->elfClass = header->e_ident[EI_CLASS];
|
||||
return 0; /* elf header looks OK */
|
||||
}
|
||||
|
||||
int elf32_checkProgramHeaderTable(const elf_t *elf)
|
||||
{
|
||||
const Elf32_Ehdr *header = elf->elfFile;
|
||||
size_t ph_end = header->e_phoff + header->e_phentsize * header->e_phnum;
|
||||
if (elf->elfSize < ph_end || ph_end < header->e_phoff) {
|
||||
return -1; /* invalid program header table */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf32_checkSectionTable(const elf_t *elf)
|
||||
{
|
||||
const Elf32_Ehdr *header = elf->elfFile;
|
||||
size_t sh_end = header->e_shoff + header->e_shentsize * header->e_shnum;
|
||||
if (elf->elfSize < sh_end || sh_end < header->e_shoff) {
|
||||
return -1; /* invalid section header table */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2004 University of New South Wales
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <elf/elf.h>
|
||||
#include <elf/elf64.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ELF header functions */
|
||||
int elf64_checkFile(elf_t *elf)
|
||||
{
|
||||
if (sizeof(uintptr_t) != sizeof(uint64_t)) {
|
||||
return -1; /* not supported on 32-bit architecture */
|
||||
}
|
||||
|
||||
if (elf->elfSize < sizeof(Elf64_Ehdr)) {
|
||||
return -1; /* file smaller than ELF header */
|
||||
}
|
||||
|
||||
if (elf_check_magic(elf->elfFile) < 0) {
|
||||
return -1; /* not an ELF file */
|
||||
}
|
||||
|
||||
Elf64_Ehdr const *header = elf->elfFile;
|
||||
if (header->e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
return -1; /* not a 64-bit ELF */
|
||||
}
|
||||
|
||||
if (header->e_phentsize != sizeof(Elf64_Phdr)) {
|
||||
return -1; /* unexpected program header size */
|
||||
}
|
||||
|
||||
if (header->e_shentsize != sizeof(Elf64_Shdr)) {
|
||||
return -1; /* unexpected section header size */
|
||||
}
|
||||
|
||||
if (header->e_shstrndx >= header->e_shnum) {
|
||||
return -1; /* invalid section header string table section */
|
||||
}
|
||||
|
||||
elf->elfClass = header->e_ident[EI_CLASS];
|
||||
return 0; /* elf header looks OK */
|
||||
}
|
||||
|
||||
int elf64_checkProgramHeaderTable(const elf_t *elf)
|
||||
{
|
||||
const Elf64_Ehdr *header = elf->elfFile;
|
||||
size_t ph_end = header->e_phoff + header->e_phentsize * header->e_phnum;
|
||||
if (elf->elfSize < ph_end || ph_end < header->e_phoff) {
|
||||
return -1; /* invalid program header table */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf64_checkSectionTable(const elf_t *elf)
|
||||
{
|
||||
const Elf64_Ehdr *header = elf->elfFile;
|
||||
size_t sh_end = header->e_shoff + header->e_shentsize * header->e_shnum;
|
||||
if (elf->elfSize < sh_end || sh_end < header->e_shoff) {
|
||||
return -1; /* invalid section header table */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2360,7 +2360,11 @@ void * rglMapBuffer( GLenum target, GLenum access)
|
||||
log_cb(RETRO_LOG_INFO, "glMapBuffer.\n");
|
||||
#endif
|
||||
#if defined(HAVE_OPENGLES)
|
||||
#ifdef glMapBufferOES
|
||||
return glMapBufferOES(target, access);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
#else
|
||||
return glMapBuffer(target, access);
|
||||
#endif
|
||||
@@ -2377,7 +2381,11 @@ GLboolean rglUnmapBuffer( GLenum target)
|
||||
log_cb(RETRO_LOG_INFO, "glUnmapBuffer.\n");
|
||||
#endif
|
||||
#if defined(HAVE_OPENGLES)
|
||||
#ifdef glUnmapBufferOES
|
||||
return glUnmapBufferOES(target);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
#else
|
||||
return glUnmapBuffer(target);
|
||||
#endif
|
||||
@@ -2735,6 +2743,14 @@ void rglPrimitiveRestartIndex(GLuint index)
|
||||
#endif
|
||||
}
|
||||
|
||||
void rglHint(GLenum target, GLenum mode)
|
||||
{
|
||||
#ifdef GLSM_DEBUG
|
||||
log_cb(RETRO_LOG_INFO, "glHint.\n");
|
||||
#endif
|
||||
glHint(target, mode);
|
||||
}
|
||||
|
||||
/* GLSM-side */
|
||||
|
||||
static void glsm_state_setup(void)
|
||||
|
||||
@@ -25,7 +25,7 @@ import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
banned_ext = [ 'AMD', 'APPLE', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ]
|
||||
banned_ext = [ 'AMD', 'APPLE', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ]
|
||||
|
||||
def noext(sym):
|
||||
for ext in banned_ext:
|
||||
@@ -57,7 +57,7 @@ def find_gl_symbols(lines):
|
||||
syms = []
|
||||
for line in lines:
|
||||
m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line)
|
||||
g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line)
|
||||
g = re.search(r'^.+\W(gl\S+)\W*\(.+\).*$', line)
|
||||
if m and noext(m.group(1)):
|
||||
typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC'))
|
||||
if g and noext(g.group(1)):
|
||||
@@ -73,8 +73,13 @@ def generate_defines(gl_syms):
|
||||
def generate_declarations(gl_syms):
|
||||
return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms]
|
||||
|
||||
def remove_prefix(text, prefix):
|
||||
if text.startswith(prefix):
|
||||
return text[len(prefix):]
|
||||
return text
|
||||
|
||||
def generate_macros(gl_syms):
|
||||
return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms]
|
||||
return [' SYM(' + remove_prefix(x, 'gl') + '),' for x in gl_syms]
|
||||
|
||||
def dump(f, lines):
|
||||
f.write('\n'.join(lines))
|
||||
|
||||
Loaded 100 of 1698 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user