mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 15:57:03 -05:00
Compare commits
1101 Commits
v1.27.0
...
disassembl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abd21637ce | ||
|
|
5b1f5c0dd8 | ||
|
|
fcdaf4685b | ||
|
|
2a55cd8a4f | ||
|
|
f71fa2f704 | ||
|
|
9afbfec64e | ||
|
|
ec7e89b5cf | ||
|
|
e6ad54b53b | ||
|
|
768982b67a | ||
|
|
4fd3167bb3 | ||
|
|
866cb5706d | ||
|
|
2cf642a2a4 | ||
|
|
f26076fb90 | ||
|
|
519d965a36 | ||
|
|
a50bb39978 | ||
|
|
8ee234e5a6 | ||
|
|
e370fdb0fc | ||
|
|
09904b77eb | ||
|
|
5e32b693f3 | ||
|
|
cceac20197 | ||
|
|
540e8458a5 | ||
|
|
80984f28ec | ||
|
|
56064df8d5 | ||
|
|
df7cc1fefd | ||
|
|
23fc232c47 | ||
|
|
37ce37862a | ||
|
|
75e26458cc | ||
|
|
e75fcadd8f | ||
|
|
2483c421d2 | ||
|
|
abf6e37938 | ||
|
|
eae73b3113 | ||
|
|
cbf82d7476 | ||
|
|
4ddd293210 | ||
|
|
813a95d283 | ||
|
|
c02c27b63d | ||
|
|
f6d4d5ab22 | ||
|
|
284f8534ab | ||
|
|
8e7716ebcc | ||
|
|
1b665fa1b3 | ||
|
|
9cbfaed5fe | ||
|
|
494223fff6 | ||
|
|
af77b8dfc4 | ||
|
|
47b6826ac4 | ||
|
|
64be4e692c | ||
|
|
8e8a926ad9 | ||
|
|
9306017f01 | ||
|
|
55c0170791 | ||
|
|
671b032125 | ||
|
|
f79fd0edbc | ||
|
|
8d20277a62 | ||
|
|
88032a85cd | ||
|
|
c821967633 | ||
|
|
7e660450ed | ||
|
|
e5f36ca08d | ||
|
|
d8249b3a7c | ||
|
|
3c36ef2c69 | ||
|
|
b050039e35 | ||
|
|
920c6f6507 | ||
|
|
96a3a74e08 | ||
|
|
fb00f688a8 | ||
|
|
d6d379108b | ||
|
|
d34ad33c3c | ||
|
|
8bdb39983e | ||
|
|
59b363d9b2 | ||
|
|
71df45a347 | ||
|
|
0b06b1e1e8 | ||
|
|
45a3ea18d0 | ||
|
|
951d74e24b | ||
|
|
445dba85ac | ||
|
|
d50533bbaf | ||
|
|
eafeac4e7b | ||
|
|
58c3b95c84 | ||
|
|
5a58ed5114 | ||
|
|
b619744093 | ||
|
|
32276b820f | ||
|
|
74e246feed | ||
|
|
de4ea4081a | ||
|
|
af18501726 | ||
|
|
ae24ccdfe6 | ||
|
|
095da62250 | ||
|
|
909f4b7fe8 | ||
|
|
c89a870fe9 | ||
|
|
fc23efdb25 | ||
|
|
3da209b562 | ||
|
|
9e0b02f86e | ||
|
|
a4e14497a5 | ||
|
|
5daf725ee3 | ||
|
|
ffbf409174 | ||
|
|
8b3c297514 | ||
|
|
2f8481f5e2 | ||
|
|
448d792988 | ||
|
|
1e98e641bb | ||
|
|
4b13cd666b | ||
|
|
836d66a150 | ||
|
|
de3e92e21b | ||
|
|
f9073ee8ee | ||
|
|
bd59bcda2c | ||
|
|
0e9302ff08 | ||
|
|
69bdebeb98 | ||
|
|
7b25d97ea2 | ||
|
|
9a33110ac3 | ||
|
|
99aae87cd2 | ||
|
|
ee681b5053 | ||
|
|
981ae5067c | ||
|
|
60b640d9f5 | ||
|
|
7a1efa8b9a | ||
|
|
a3f74098f2 | ||
|
|
8f4839d8ff | ||
|
|
3b01dcf230 | ||
|
|
37f9f5619c | ||
|
|
331716dd48 | ||
|
|
14f728ab76 | ||
|
|
1249eb3261 | ||
|
|
98e0a62e6e | ||
|
|
2d45dce075 | ||
|
|
e7bfa483f8 | ||
|
|
36a352b096 | ||
|
|
1f05deddc8 | ||
|
|
cec925bcdc | ||
|
|
3bd779a607 | ||
|
|
4a44cddcea | ||
|
|
bf53ee8246 | ||
|
|
f75d5dba84 | ||
|
|
2036dc91e6 | ||
|
|
39252dfe48 | ||
|
|
77c326d300 | ||
|
|
164e52207e | ||
|
|
1f7e2f5ed3 | ||
|
|
0bace013a1 | ||
|
|
1df8d19399 | ||
|
|
75df797b41 | ||
|
|
1136556a0d | ||
|
|
1331b0691f | ||
|
|
21057d51e1 | ||
|
|
f00daf171b | ||
|
|
22eee94436 | ||
|
|
0105ed447f | ||
|
|
dd2ecb3dd9 | ||
|
|
a51f9fd90c | ||
|
|
e32def409a | ||
|
|
657744cc28 | ||
|
|
a561cee54b | ||
|
|
2c0553f8fd | ||
|
|
13b72c8f93 | ||
|
|
73454905e8 | ||
|
|
8e58f469b0 | ||
|
|
5ec7826273 | ||
|
|
1f109ff59b | ||
|
|
10217b5530 | ||
|
|
43f1cc7bd0 | ||
|
|
5e523f4cd8 | ||
|
|
b78435c881 | ||
|
|
33e20df511 | ||
|
|
53c04a934e | ||
|
|
46d3402705 | ||
|
|
1ff4d76ae7 | ||
|
|
273573ce68 | ||
|
|
d3ed34d5eb | ||
|
|
375c74abe5 | ||
|
|
e0264a3459 | ||
|
|
1f73a87327 | ||
|
|
27f420c8ea | ||
|
|
29dd3d5fc3 | ||
|
|
0e671b1569 | ||
|
|
2c374e9761 | ||
|
|
f0465c63ed | ||
|
|
b04cb7648e | ||
|
|
46b1b0ba17 | ||
|
|
60e3a657f0 | ||
|
|
3d04669ef0 | ||
|
|
9fb60a8ab0 | ||
|
|
17540b0120 | ||
|
|
af77819913 | ||
|
|
1c8af096de | ||
|
|
7f35d81722 | ||
|
|
26f873a364 | ||
|
|
b101d11821 | ||
|
|
50a1956d92 | ||
|
|
5a4f31bfa5 | ||
|
|
7405219fb8 | ||
|
|
30ce4b6e3c | ||
|
|
7d53636e10 | ||
|
|
aa93bcb142 | ||
|
|
2073793fcd | ||
|
|
388523a4ea | ||
|
|
ec4942174b | ||
|
|
01f7a09012 | ||
|
|
c35ea228e4 | ||
|
|
498d8c1d65 | ||
|
|
3aacf0f1fb | ||
|
|
4fc2fb7a6f | ||
|
|
d12f5016e4 | ||
|
|
f1e0960a26 | ||
|
|
0f5d659ce2 | ||
|
|
a64aa6941d | ||
|
|
66cac8350e | ||
|
|
384c2a7701 | ||
|
|
ad4e7c3355 | ||
|
|
ea5d4ca3ae | ||
|
|
87e7f817c1 | ||
|
|
3af1840c6a | ||
|
|
e5ff04be29 | ||
|
|
da851c3c10 | ||
|
|
d160aeec4b | ||
|
|
e18275c1c0 | ||
|
|
1ca71ec30d | ||
|
|
759351cec0 | ||
|
|
ef320b74b0 | ||
|
|
6e6c5c4cb7 | ||
|
|
669e1921a4 | ||
|
|
924b4a9436 | ||
|
|
f49b5efac4 | ||
|
|
8581ab9eb3 | ||
|
|
7efe9acefb | ||
|
|
94f3664dbc | ||
|
|
d1f8053fbb | ||
|
|
713ce86e24 | ||
|
|
7efdcfd888 | ||
|
|
988a674617 | ||
|
|
4e4cdcdf61 | ||
|
|
0388bbdc6d | ||
|
|
30d47fd51b | ||
|
|
2e45069882 | ||
|
|
3b2cf5b851 | ||
|
|
4d456f1bc0 | ||
|
|
d6ba41c2d9 | ||
|
|
c9a728c318 | ||
|
|
4c2fe8e03c | ||
|
|
ec95c260bb | ||
|
|
e7eaa2b194 | ||
|
|
fe59ce3e60 | ||
|
|
45fb046a9a | ||
|
|
055e18058f | ||
|
|
fa5e32496c | ||
|
|
44a1efffa0 | ||
|
|
c839ee7d13 | ||
|
|
c7c01c1f24 | ||
|
|
615596dfe9 | ||
|
|
407ec1ceb6 | ||
|
|
eefdbe7ef1 | ||
|
|
cd6a62dd27 | ||
|
|
4e6af607e8 | ||
|
|
363b07fc0c | ||
|
|
a719627be6 | ||
|
|
f14f77b4f0 | ||
|
|
a92aa58be8 | ||
|
|
9617212ef1 | ||
|
|
4af66f7d3d | ||
|
|
c7cee59a77 | ||
|
|
7002e3bbf3 | ||
|
|
c37c53369b | ||
|
|
e827ad4b8d | ||
|
|
2fee380459 | ||
|
|
94ad6e6072 | ||
|
|
a980097d64 | ||
|
|
b2774bf472 | ||
|
|
44ce81211e | ||
|
|
c444ad9280 | ||
|
|
80ca6bf177 | ||
|
|
a0178ebab9 | ||
|
|
e63af24626 | ||
|
|
f94c23d64d | ||
|
|
bffc229fa8 | ||
|
|
aae5586b5c | ||
|
|
4f2d14e220 | ||
|
|
58189e5403 | ||
|
|
215e1ffdc8 | ||
|
|
9fdd4670b7 | ||
|
|
03af1687d9 | ||
|
|
cb2aee0ed7 | ||
|
|
e92f937587 | ||
|
|
73d7cc7c12 | ||
|
|
8cd0561e71 | ||
|
|
1b54a8858e | ||
|
|
c3825fff65 | ||
|
|
c51db87c34 | ||
|
|
beca8033cf | ||
|
|
72f2f0877d | ||
|
|
79f18d12e6 | ||
|
|
7fe9a768d4 | ||
|
|
f114239f51 | ||
|
|
c46e445a04 | ||
|
|
d91334abcd | ||
|
|
5227887dbf | ||
|
|
d07d36f784 | ||
|
|
c9cd7ad4a6 | ||
|
|
b4ee02b725 | ||
|
|
79e25b0889 | ||
|
|
5d50a3927e | ||
|
|
7769b556f7 | ||
|
|
58870f3057 | ||
|
|
8821f75e6b | ||
|
|
88b2f60291 | ||
|
|
c49aad6cd3 | ||
|
|
afceb34729 | ||
|
|
93c8a45de0 | ||
|
|
1f208dbb21 | ||
|
|
4e9cbd14eb | ||
|
|
da1b53420f | ||
|
|
5a71cc2d61 | ||
|
|
b98b60a126 | ||
|
|
929e0e64a5 | ||
|
|
48a1e93cfe | ||
|
|
b908965048 | ||
|
|
afa149f2db | ||
|
|
6c3c2849fa | ||
|
|
6cbfb00cca | ||
|
|
7b22c49329 | ||
|
|
c7c05e2621 | ||
|
|
7fc2ff3002 | ||
|
|
bb36000dd9 | ||
|
|
19ef188f7b | ||
|
|
23e1c714d6 | ||
|
|
a07b678a61 | ||
|
|
6cf3bfb89f | ||
|
|
85515a729f | ||
|
|
d36e299c35 | ||
|
|
9e5e3e94a3 | ||
|
|
4db10f1c8b | ||
|
|
5faf1380d7 | ||
|
|
baa5c34b55 | ||
|
|
d19d812ccb | ||
|
|
e2b7427e7b | ||
|
|
44ae942de4 | ||
|
|
e14efc6ca2 | ||
|
|
f982ff62e4 | ||
|
|
5b8947c36b | ||
|
|
07a274fe4c | ||
|
|
081c581b8c | ||
|
|
1c88c3a8bd | ||
|
|
eb41622a38 | ||
|
|
13c9b80bca | ||
|
|
c72853596f | ||
|
|
e57c9ff4f6 | ||
|
|
ed8c0794bb | ||
|
|
d7bf3746f7 | ||
|
|
6c773c0135 | ||
|
|
a06752b349 | ||
|
|
d15bd4771d | ||
|
|
a62ede7840 | ||
|
|
bcab657a06 | ||
|
|
9dbae2051b | ||
|
|
7400b9ce8a | ||
|
|
4436e8a589 | ||
|
|
e241adab0e | ||
|
|
51880fc2a8 | ||
|
|
89bffbd1bc | ||
|
|
e80c7bff1c | ||
|
|
b3ef615158 | ||
|
|
25ddaa08dc | ||
|
|
fb48eb91d6 | ||
|
|
865d7e9b20 | ||
|
|
f5b8021405 | ||
|
|
89abc8557f | ||
|
|
181a7c5b3d | ||
|
|
f79e2df11a | ||
|
|
be8c679d4a | ||
|
|
c577a42f62 | ||
|
|
ad69ac84b1 | ||
|
|
64a30a45d5 | ||
|
|
691df0fc83 | ||
|
|
1a2a926b77 | ||
|
|
da18428f27 | ||
|
|
5e86f62a98 | ||
|
|
e65021c85e | ||
|
|
83e26522b6 | ||
|
|
d011f37658 | ||
|
|
c07842d7ca | ||
|
|
4e7c3817ed | ||
|
|
68b203eb75 | ||
|
|
1bb0a72bed | ||
|
|
7685a22c5f | ||
|
|
fc91c8e4b0 | ||
|
|
57084fd797 | ||
|
|
2b8a9db0f0 | ||
|
|
9badfc043b | ||
|
|
4ff25819c2 | ||
|
|
563ff5a774 | ||
|
|
b042b8327a | ||
|
|
971c8739ca | ||
|
|
26f4aa0d9f | ||
|
|
dc5e5344c5 | ||
|
|
b2d1568abb | ||
|
|
632f388ece | ||
|
|
632ca944de | ||
|
|
0bbd21f25a | ||
|
|
367c4ec9c8 | ||
|
|
5538307838 | ||
|
|
eba8c82699 | ||
|
|
be3ac26306 | ||
|
|
fc1ad592cb | ||
|
|
f725d763d1 | ||
|
|
c2fe9f0966 | ||
|
|
235f4e39b4 | ||
|
|
58cef2361b | ||
|
|
60649d1cba | ||
|
|
ea9457c08c | ||
|
|
7bf9634e6e | ||
|
|
4288f876e2 | ||
|
|
10ad239fb9 | ||
|
|
550392c8d6 | ||
|
|
32e05cc62f | ||
|
|
886c52b322 | ||
|
|
ba66005585 | ||
|
|
bfc835fc54 | ||
|
|
32d6ac2241 | ||
|
|
758cdd91f3 | ||
|
|
6e81ce152e | ||
|
|
e487fd7450 | ||
|
|
bd75b70d85 | ||
|
|
6ef96c5533 | ||
|
|
6fc62bac94 | ||
|
|
baecf66716 | ||
|
|
7476ae230c | ||
|
|
175e66a60e | ||
|
|
a1dc979217 | ||
|
|
fbdcd22117 | ||
|
|
d50fb8d17b | ||
|
|
83e42ddfd9 | ||
|
|
6c8a90720f | ||
|
|
e70ec10b0e | ||
|
|
b4401b7df1 | ||
|
|
f598421705 | ||
|
|
84ceb45129 | ||
|
|
fc93f8bd66 | ||
|
|
8a2afd1c05 | ||
|
|
33e9ad7775 | ||
|
|
2059ad82c3 | ||
|
|
c25aad552d | ||
|
|
896091b124 | ||
|
|
d2e6d8e4d9 | ||
|
|
285b79f31e | ||
|
|
d468893bb0 | ||
|
|
df24d1e1e9 | ||
|
|
65c56a887c | ||
|
|
ef556d07ed | ||
|
|
882849e73c | ||
|
|
49d3fe65a3 | ||
|
|
a6aafa8cd6 | ||
|
|
ba9227c1e0 | ||
|
|
e77f138514 | ||
|
|
64a0c3f6e2 | ||
|
|
fae8f0a8d5 | ||
|
|
f2cfc70eca | ||
|
|
55e6761bf1 | ||
|
|
1a765ee5ab | ||
|
|
e1ca84d89c | ||
|
|
2082781cf5 | ||
|
|
d28d6d1a1b | ||
|
|
a61c93e99c | ||
|
|
e65497ec3b | ||
|
|
50dd6405e9 | ||
|
|
79eb53eb0d | ||
|
|
05ca498343 | ||
|
|
fbd4bc337b | ||
|
|
89115bcdde | ||
|
|
954c0d5bda | ||
|
|
bf8924ae0c | ||
|
|
30b202cf0c | ||
|
|
84766d5f6e | ||
|
|
106e669512 | ||
|
|
4d6e6cf75a | ||
|
|
26e7e12f09 | ||
|
|
b469e68ddb | ||
|
|
2e5a51bb05 | ||
|
|
4ae55f69e1 | ||
|
|
d079b8c3bb | ||
|
|
33f0d59545 | ||
|
|
42c36279d1 | ||
|
|
b55c6fa3e1 | ||
|
|
3a39d3c532 | ||
|
|
f67e808d0b | ||
|
|
e1d0a057ff | ||
|
|
e829c407e3 | ||
|
|
94a02c4b6d | ||
|
|
4792a29fac | ||
|
|
27c8e19c14 | ||
|
|
866c87b2bf | ||
|
|
aa4ce01c73 | ||
|
|
d0a5c144e6 | ||
|
|
5feb4dce51 | ||
|
|
4d4f223357 | ||
|
|
440e2d91fc | ||
|
|
bca73ef01e | ||
|
|
a032bfa0f5 | ||
|
|
ff8946b851 | ||
|
|
599b43db22 | ||
|
|
a4e4e01d2d | ||
|
|
8b3cd2d76d | ||
|
|
ffdaf0d16e | ||
|
|
b8d5e1e9c5 | ||
|
|
aa66d4b9e7 | ||
|
|
fdd2e1fcde | ||
|
|
591435761b | ||
|
|
4979c65566 | ||
|
|
f5fda76414 | ||
|
|
4b0d980d54 | ||
|
|
46ee3f0faa | ||
|
|
564ae6dd8c | ||
|
|
8aec382440 | ||
|
|
a99f8f78d0 | ||
|
|
0faea9d7c7 | ||
|
|
c294619102 | ||
|
|
f6bbfd7283 | ||
|
|
d3f493b6c2 | ||
|
|
bd8868d2c8 | ||
|
|
ee41a5a046 | ||
|
|
0033d9f4eb | ||
|
|
e5a793e8de | ||
|
|
3149183450 | ||
|
|
7c321a79c3 | ||
|
|
7c203e0635 | ||
|
|
ffd3efe5fa | ||
|
|
18dd754b31 | ||
|
|
3c97759aa7 | ||
|
|
f930b6e17d | ||
|
|
2d4f971d10 | ||
|
|
90267ec356 | ||
|
|
7fc53bf861 | ||
|
|
b9c2955b88 | ||
|
|
ed33dd0bb0 | ||
|
|
6d7f217e2a | ||
|
|
a83ca3c228 | ||
|
|
b9ec1a150d | ||
|
|
d9a4906b3c | ||
|
|
a83f87fbfa | ||
|
|
e9450b490f | ||
|
|
1588365d4a | ||
|
|
76e932ecc0 | ||
|
|
52c517d38d | ||
|
|
aac9bf3896 | ||
|
|
54891c6d8f | ||
|
|
d7238a5f80 | ||
|
|
0a6815da8f | ||
|
|
7631778edb | ||
|
|
1a3debd6c9 | ||
|
|
893b06c78b | ||
|
|
709f4b7e80 | ||
|
|
54fba5bf8b | ||
|
|
d977f1f988 | ||
|
|
2fea1975c2 | ||
|
|
5171bea0bf | ||
|
|
4e3b8111fd | ||
|
|
afcc01c3dc | ||
|
|
3a775e982f | ||
|
|
0f54a3a1f3 | ||
|
|
8500e4cba2 | ||
|
|
c1cdab72ef | ||
|
|
f4ae1fda6d | ||
|
|
aae3004f1f | ||
|
|
1aed960a38 | ||
|
|
6c4fdd146f | ||
|
|
04b56c3d4d | ||
|
|
1ed658bcdc | ||
|
|
8c0395bc7c | ||
|
|
cdc4f2db89 | ||
|
|
272b4b0cf8 | ||
|
|
10756c65a6 | ||
|
|
8524e93445 | ||
|
|
511ef3ef2b | ||
|
|
32ade6136b | ||
|
|
65d9509c38 | ||
|
|
ce9ce42c1c | ||
|
|
6343cb092b | ||
|
|
7cb26b1499 | ||
|
|
5d047a335d | ||
|
|
3e797eeea2 | ||
|
|
14bb98a519 | ||
|
|
a78d3f9977 | ||
|
|
2449b08f64 | ||
|
|
33d3bea472 | ||
|
|
c9c6f3aadb | ||
|
|
c9dbcbb3d3 | ||
|
|
924c816dbd | ||
|
|
695e11477e | ||
|
|
ac2a609d0a | ||
|
|
e3ae169833 | ||
|
|
25d6380963 | ||
|
|
f00b9f05ac | ||
|
|
b6881d2362 | ||
|
|
8e0349e2ac | ||
|
|
86c4c8fa96 | ||
|
|
33566137c2 | ||
|
|
f16bbfb469 | ||
|
|
b265d8e54a | ||
|
|
6a667d9493 | ||
|
|
ceed8c7420 | ||
|
|
d297b2d1cc | ||
|
|
39e74c627e | ||
|
|
28dea8e5bd | ||
|
|
a0c89858ed | ||
|
|
c6c3ca4d26 | ||
|
|
301418c728 | ||
|
|
730e67881b | ||
|
|
aec38328d0 | ||
|
|
050a71913a | ||
|
|
8cc6994dd0 | ||
|
|
f9909dab98 | ||
|
|
bc98556897 | ||
|
|
4f08ba3590 | ||
|
|
78cb0a2592 | ||
|
|
a5fac85727 | ||
|
|
8fdb60758b | ||
|
|
7510fa091e | ||
|
|
b87c32a94b | ||
|
|
b13494a192 | ||
|
|
d527675bda | ||
|
|
15cd2b693c | ||
|
|
cda883bb0f | ||
|
|
e03c91b888 | ||
|
|
9282f1fe75 | ||
|
|
af147b4f54 | ||
|
|
13b4201446 | ||
|
|
83bcbfebdd | ||
|
|
1a31b4aaff | ||
|
|
c280b16787 | ||
|
|
cc55ca3117 | ||
|
|
a449478e39 | ||
|
|
c1babc2a55 | ||
|
|
b644020e0f | ||
|
|
07ffd21c5a | ||
|
|
ddc0457d9a | ||
|
|
13599908f8 | ||
|
|
af951e3526 | ||
|
|
568e8d8d42 | ||
|
|
ade05f8e12 | ||
|
|
cabe9cf995 | ||
|
|
1e9cc97263 | ||
|
|
35d2fda0a4 | ||
|
|
2c6f1503ef | ||
|
|
dd72c0cc46 | ||
|
|
a7ecefb5a0 | ||
|
|
1b028dfc0a | ||
|
|
c787532ed9 | ||
|
|
b019283a2f | ||
|
|
ae06954771 | ||
|
|
cb3b71e2f3 | ||
|
|
d65e669bbb | ||
|
|
e1b0c1c268 | ||
|
|
b7d8e46288 | ||
|
|
3fe6cd057b | ||
|
|
da11c47693 | ||
|
|
98395afe9d | ||
|
|
9cd19063da | ||
|
|
6435d8d955 | ||
|
|
0da87cdb68 | ||
|
|
eed785d73f | ||
|
|
b223d9b0ff | ||
|
|
c8150f3261 | ||
|
|
6d1f639bc6 | ||
|
|
f703b15165 | ||
|
|
54061c56bf | ||
|
|
25154dd450 | ||
|
|
d9af85f458 | ||
|
|
e09b678426 | ||
|
|
5f6bc2507c | ||
|
|
03f377bf40 | ||
|
|
c2e023f567 | ||
|
|
90a576c3c7 | ||
|
|
0e5371b298 | ||
|
|
fdb1cace2d | ||
|
|
330c8399ce | ||
|
|
dd832bfa7e | ||
|
|
5c31b5cf0d | ||
|
|
3b514003f8 | ||
|
|
7de367a944 | ||
|
|
ef1d831158 | ||
|
|
54c6c9360a | ||
|
|
da137b3e3b | ||
|
|
03673b5846 | ||
|
|
9a9b211ebb | ||
|
|
f2509cda1d | ||
|
|
cac9a69ea2 | ||
|
|
f0be585fd8 | ||
|
|
34732a1ee7 | ||
|
|
ee57c449e7 | ||
|
|
e8ca139246 | ||
|
|
ef9cb31204 | ||
|
|
cde5940063 | ||
|
|
e90e414d5a | ||
|
|
73d4214fd3 | ||
|
|
0e8273eaa7 | ||
|
|
a485a0bc3a | ||
|
|
903d1fb555 | ||
|
|
6e3204b443 | ||
|
|
9baca91b16 | ||
|
|
81971eaf4a | ||
|
|
46270ab213 | ||
|
|
57bf878312 | ||
|
|
110c3ac310 | ||
|
|
99831a66a7 | ||
|
|
456895a6a6 | ||
|
|
1e2cf87532 | ||
|
|
48022bc295 | ||
|
|
b4ac46f719 | ||
|
|
44bbbb03af | ||
|
|
a125408410 | ||
|
|
b8457439a4 | ||
|
|
c690f7627f | ||
|
|
849e4ea370 | ||
|
|
9712329924 | ||
|
|
59aa52e744 | ||
|
|
60a95eddd7 | ||
|
|
7c23b215ba | ||
|
|
ae48ae659b | ||
|
|
e78c21cbfb | ||
|
|
cc55e5ec74 | ||
|
|
1134697b90 | ||
|
|
e518b8360c | ||
|
|
244e34ab84 | ||
|
|
100b9e3bca | ||
|
|
07aabe8efa | ||
|
|
25476d4e1e | ||
|
|
de76c37ffb | ||
|
|
6d19b33e32 | ||
|
|
1dff81f7cd | ||
|
|
aca949175d | ||
|
|
d2e455c4cb | ||
|
|
09dda0bc5e | ||
|
|
d10f033439 | ||
|
|
62ecfb0e0e | ||
|
|
504c022f01 | ||
|
|
117832e007 | ||
|
|
9dafdeb70a | ||
|
|
5e0ca4ac50 | ||
|
|
8d8a5a70f3 | ||
|
|
c8c3f5e753 | ||
|
|
ea756e620e | ||
|
|
e599d31625 | ||
|
|
0ba011dbe1 | ||
|
|
e578127f67 | ||
|
|
acfd89aee0 | ||
|
|
950760691c | ||
|
|
ba33629e80 | ||
|
|
d671cde6d2 | ||
|
|
ee94870e83 | ||
|
|
d2638c4f27 | ||
|
|
7d457998d7 | ||
|
|
79306fa6e1 | ||
|
|
320973c5ff | ||
|
|
26eac61ddf | ||
|
|
cb9a3b1f55 | ||
|
|
5bbf4342ee | ||
|
|
0e3da22c76 | ||
|
|
28778eaf8c | ||
|
|
e32fc639c2 | ||
|
|
7ce0613977 | ||
|
|
91635346be | ||
|
|
bfe698f883 | ||
|
|
f81276f7e3 | ||
|
|
6b28828174 | ||
|
|
2191eb14ae | ||
|
|
e7b51a56a5 | ||
|
|
df75218ecb | ||
|
|
f57d4f2f7a | ||
|
|
a2333fa22e | ||
|
|
2179c3c014 | ||
|
|
0563a59b1b | ||
|
|
446e0751a6 | ||
|
|
5666a5c5fb | ||
|
|
047c39e2c7 | ||
|
|
dc8245ce4c | ||
|
|
1b88b3704d | ||
|
|
6dbaac4283 | ||
|
|
180a27fdc9 | ||
|
|
c02465b892 | ||
|
|
f503a89f98 | ||
|
|
f94e5488d4 | ||
|
|
87621e9337 | ||
|
|
3219ba68de | ||
|
|
5d608603cb | ||
|
|
7336c8dddc | ||
|
|
c91e3875d4 | ||
|
|
0181325b64 | ||
|
|
11f55a7561 | ||
|
|
9bb3a92e12 | ||
|
|
3e9ba8c636 | ||
|
|
4faebf435c | ||
|
|
749823e044 | ||
|
|
608c9e2e7a | ||
|
|
96ee544538 | ||
|
|
7ea7c531e2 | ||
|
|
969a37877a | ||
|
|
3cb8e37182 | ||
|
|
3e4c4430d5 | ||
|
|
4ad66365d0 | ||
|
|
39276e123e | ||
|
|
0f9434740f | ||
|
|
7ed153a47b | ||
|
|
c9d673ce40 | ||
|
|
0be610f1cd | ||
|
|
f75aa1f1b0 | ||
|
|
5ef58cdf76 | ||
|
|
511375feb5 | ||
|
|
8119929ece | ||
|
|
e1620966e5 | ||
|
|
a5b0a8614a | ||
|
|
e28f2dfea1 | ||
|
|
0dcfeaefb3 | ||
|
|
3bd4a3ba8b | ||
|
|
7e9b23de7d | ||
|
|
a758676b0d | ||
|
|
636ed0095d | ||
|
|
14341d611d | ||
|
|
07565eea63 | ||
|
|
c006062540 | ||
|
|
e685d65be8 | ||
|
|
ab67e274b2 | ||
|
|
7656fd7a4e | ||
|
|
60a2b30e91 | ||
|
|
7ec7e562d1 | ||
|
|
c50d52d0a6 | ||
|
|
2b765617ce | ||
|
|
79cdf51588 | ||
|
|
7b048d9b96 | ||
|
|
d96fc6d41b | ||
|
|
610f109e2a | ||
|
|
609afebc55 | ||
|
|
3bd9ab6349 | ||
|
|
5027f36d95 | ||
|
|
a5498995ff | ||
|
|
f40b5d9811 | ||
|
|
d00fae03a9 | ||
|
|
3c4e1b2f27 | ||
|
|
6e5d6810e7 | ||
|
|
4afd5a7905 | ||
|
|
6709baa710 | ||
|
|
aa1bf0b764 | ||
|
|
a7327290ea | ||
|
|
857e90a37b | ||
|
|
aaeebd3fe9 | ||
|
|
0a7a190b04 | ||
|
|
21d922113d | ||
|
|
b0876e1c35 | ||
|
|
18bc5de169 | ||
|
|
0321743f1e | ||
|
|
f2af90fe06 | ||
|
|
2f511ec4fa | ||
|
|
0649e0dcd3 | ||
|
|
0b21e30e44 | ||
|
|
ceeaca1a4b | ||
|
|
2da89f4b9b | ||
|
|
49371398bc | ||
|
|
2e73d74cea | ||
|
|
688471fd61 | ||
|
|
ea482ff0f5 | ||
|
|
5c9d0e29c2 | ||
|
|
8f07f0f8ae | ||
|
|
4f17a96707 | ||
|
|
b0ab8698ec | ||
|
|
ab41899cc2 | ||
|
|
50c3cf8272 | ||
|
|
1d2b8ac1f3 | ||
|
|
0b29719fe9 | ||
|
|
5a6e5d2255 | ||
|
|
82111617a4 | ||
|
|
0574387ee1 | ||
|
|
2d1381860d | ||
|
|
82f5900759 | ||
|
|
e44eb2aa8e | ||
|
|
34e12e2515 | ||
|
|
980e4cad06 | ||
|
|
5680b90549 | ||
|
|
bec655a8c6 | ||
|
|
0c8b3e31e7 | ||
|
|
a33c7135d1 | ||
|
|
13a3942f8f | ||
|
|
1bdc1d7241 | ||
|
|
fe9026b68d | ||
|
|
b0028b0e51 | ||
|
|
f54617e92f | ||
|
|
306690762c | ||
|
|
58a0fe8109 | ||
|
|
1e39f4354f | ||
|
|
e1b12546da | ||
|
|
1b28bf1474 | ||
|
|
8245f3d4c9 | ||
|
|
5fc8e710a5 | ||
|
|
b8636a8589 | ||
|
|
bb8b4afb85 | ||
|
|
d5b1ef7875 | ||
|
|
6c122e5fbe | ||
|
|
7ae814f7fb | ||
|
|
bdc51dd8a5 | ||
|
|
04a5efc7a3 | ||
|
|
99a736df27 | ||
|
|
535aeb5e39 | ||
|
|
07bef10092 | ||
|
|
c32515bc44 | ||
|
|
1690cd2740 | ||
|
|
52925c99e8 | ||
|
|
1367e9cebe | ||
|
|
3e87022da1 | ||
|
|
143fe36d35 | ||
|
|
18d5fd5d3e | ||
|
|
2829bf2640 | ||
|
|
ffafb05d3d | ||
|
|
cf72b5ec5c | ||
|
|
803b99f2a9 | ||
|
|
86b49f34d9 | ||
|
|
7e144b136b | ||
|
|
aa7c5422c0 | ||
|
|
5512585cc5 | ||
|
|
013eaae715 | ||
|
|
349b5da810 | ||
|
|
e7494be5e7 | ||
|
|
320629931c | ||
|
|
87d0aae608 | ||
|
|
391c8acfe4 | ||
|
|
dc77d81e1b | ||
|
|
00c9a92977 | ||
|
|
af4dd9f5b0 | ||
|
|
09f1b56964 | ||
|
|
f9a08f5c11 | ||
|
|
e79664256a | ||
|
|
70f3014390 | ||
|
|
b4d0f984a4 | ||
|
|
d4ad457af1 | ||
|
|
cb5d197700 | ||
|
|
78e66f8959 | ||
|
|
f562260e42 | ||
|
|
21f38974a8 | ||
|
|
dfca7e923c | ||
|
|
6913598de4 | ||
|
|
ac858b37ed | ||
|
|
80edaea392 | ||
|
|
9c9ac23818 | ||
|
|
51e615095e | ||
|
|
d92e7d19cc | ||
|
|
248b93f41a | ||
|
|
c73f33aac2 | ||
|
|
7c18ad49ae | ||
|
|
5f713882d4 | ||
|
|
1698f1599b | ||
|
|
24e584c77b | ||
|
|
a5568d09d8 | ||
|
|
7a4f909c68 | ||
|
|
89aee456c6 | ||
|
|
4cf92103d8 | ||
|
|
e3b1ebb826 | ||
|
|
3658d8d96e | ||
|
|
6c047f01f9 | ||
|
|
fc105ecc3d | ||
|
|
649f6c28bf | ||
|
|
867972b7f5 | ||
|
|
efe3227ef2 | ||
|
|
aab8c88a96 | ||
|
|
af18ca011b | ||
|
|
24106b860a | ||
|
|
60efb6973b | ||
|
|
cffd55bdda | ||
|
|
88e767aaaf | ||
|
|
d6cda43618 | ||
|
|
3b229cd5cb | ||
|
|
72c4dbdb2f | ||
|
|
4da18d3630 | ||
|
|
2f04cfd5c6 | ||
|
|
8195db6d4c | ||
|
|
722f6315c4 | ||
|
|
173ed5475c | ||
|
|
1460044e91 | ||
|
|
06a7b6e446 | ||
|
|
28b7b4b7f1 | ||
|
|
8930adf532 | ||
|
|
f44b8a5618 | ||
|
|
6a9f79628e | ||
|
|
245c56ba8a | ||
|
|
98846421f6 | ||
|
|
0aaeeffff7 | ||
|
|
c2823facc2 | ||
|
|
fabb1596e5 | ||
|
|
725e32250b | ||
|
|
5fa264ea18 | ||
|
|
5e175b118d | ||
|
|
635173e55a | ||
|
|
eb2ed6852c | ||
|
|
2296766746 | ||
|
|
13be499510 | ||
|
|
fec5c567e1 | ||
|
|
8ef863cae1 | ||
|
|
9463105172 | ||
|
|
bb4819bce4 | ||
|
|
15be24db62 | ||
|
|
e7e2af9f91 | ||
|
|
8c5fd021f7 | ||
|
|
1a1ba19770 | ||
|
|
f95214d8fe | ||
|
|
631cfce2f8 | ||
|
|
45649264f9 | ||
|
|
0fd3cb0c4a | ||
|
|
3cfec69020 | ||
|
|
cec62d23b0 | ||
|
|
f3f0dda3d4 | ||
|
|
be16b66ac0 | ||
|
|
b9059aaa01 | ||
|
|
57a62d0544 | ||
|
|
d82f0e952f | ||
|
|
8731b7582b | ||
|
|
e6959dc572 | ||
|
|
a36b4d65e3 | ||
|
|
060ff56f9d | ||
|
|
0a0c0c0d07 | ||
|
|
17c4e405a6 | ||
|
|
53afa6ea43 | ||
|
|
a182e8daf2 | ||
|
|
a4dfaba03f | ||
|
|
6e23560e80 | ||
|
|
39e8d557e8 | ||
|
|
677c989664 | ||
|
|
c9342d90fb | ||
|
|
0693bb8d51 | ||
|
|
5cd3c305d0 | ||
|
|
e00b59c393 | ||
|
|
7c1e33dde6 | ||
|
|
367bd76046 | ||
|
|
1a1bf98905 | ||
|
|
4c1a24058c | ||
|
|
294e95caf8 | ||
|
|
031884c327 | ||
|
|
466dacaab4 | ||
|
|
1f8645fd43 | ||
|
|
880568cc60 | ||
|
|
f10fb56042 | ||
|
|
64be6d89ee | ||
|
|
5442c32a3f | ||
|
|
4ee53701e6 | ||
|
|
5097a223e3 | ||
|
|
7cdba75bef | ||
|
|
0312027ca8 | ||
|
|
c726c96286 | ||
|
|
5a2b2e0813 | ||
|
|
4271b2e9fd | ||
|
|
13ef4c04d1 | ||
|
|
96c3bb1e38 | ||
|
|
a0b36925ed | ||
|
|
daadc2ea71 | ||
|
|
ec2934b4b8 | ||
|
|
3a840c4ced | ||
|
|
bd190d2b65 | ||
|
|
9b05a36529 | ||
|
|
d9a498e8ec | ||
|
|
7d86b277a7 | ||
|
|
d463b3235e | ||
|
|
5a8433ede4 | ||
|
|
00a5fd2d7c | ||
|
|
55f9faea10 | ||
|
|
fb2e668589 | ||
|
|
0dafb3d230 | ||
|
|
e958934a22 | ||
|
|
069221757f | ||
|
|
505c1bc274 | ||
|
|
cdd5d33e89 | ||
|
|
f661f4d1d6 | ||
|
|
f435191585 | ||
|
|
00c2d7ea71 | ||
|
|
cddcc1e85d | ||
|
|
91928b45d8 | ||
|
|
277c83e6d8 | ||
|
|
0017cd2e40 | ||
|
|
774803492c | ||
|
|
83a9655772 | ||
|
|
58324b4539 | ||
|
|
09b7794d71 | ||
|
|
9e3fe9beb1 | ||
|
|
ff525fe750 | ||
|
|
94977ad216 | ||
|
|
64e34e42b8 | ||
|
|
21dc65f42a | ||
|
|
279e085887 | ||
|
|
d84dfa2c42 | ||
|
|
bf8089dc7e | ||
|
|
e48761b5c0 | ||
|
|
35437c0300 | ||
|
|
6cecc12d04 | ||
|
|
dec4231d49 | ||
|
|
fb1d12ebf3 | ||
|
|
b19276a3e9 | ||
|
|
5ccbfc1ff8 | ||
|
|
d3d6a8a838 | ||
|
|
ac83bbeb0e | ||
|
|
8cb76a26c1 | ||
|
|
20da22d59e | ||
|
|
d9fa4b452c | ||
|
|
6216d72aa6 | ||
|
|
851f132188 | ||
|
|
3067ff08ec | ||
|
|
07fd86fc9d | ||
|
|
504037c115 | ||
|
|
0fad21a980 | ||
|
|
8afd698284 | ||
|
|
9ec7b90192 | ||
|
|
08f0fff34b | ||
|
|
2c1073eda9 | ||
|
|
c9348f0651 | ||
|
|
accb461c08 | ||
|
|
75adcc0a96 | ||
|
|
61ce88ba9b | ||
|
|
4b451fd1d3 | ||
|
|
a87190960f | ||
|
|
45558027a6 | ||
|
|
e426606542 |
69
.clang-tidy
Normal file
69
.clang-tidy
Normal file
@@ -0,0 +1,69 @@
|
||||
# Generated from CLion Inspection settings
|
||||
---
|
||||
Checks: '-*,
|
||||
mpi-*,
|
||||
bugprone-*,
|
||||
-bugprone-signal-handler,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-redundant-branch-condition,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-shared-ptr-array-mismatch,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-signed-char-misuse,
|
||||
-bugprone-unhandled-exception-at-new,
|
||||
-bugprone-infinite-loop,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
cert-err52-cpp,
|
||||
cert-err60-cpp,
|
||||
cert-err34-c,
|
||||
cert-str34-c,
|
||||
cert-dcl21-cpp,
|
||||
cert-msc50-cpp,
|
||||
cert-msc51-cpp,
|
||||
cert-dcl58-cpp,
|
||||
cert-flp30-c,
|
||||
cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||
cppcoreguidelines-pro-type-member-init,
|
||||
cppcoreguidelines-slicing,
|
||||
cppcoreguidelines-interfaces-global-init,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-narrowing-conversions,
|
||||
google-default-arguments,
|
||||
google-runtime-operator,
|
||||
google-explicit-constructor,
|
||||
hicpp-multiway-paths-covered,
|
||||
hicpp-exception-baseclass,
|
||||
misc-*,
|
||||
-misc-definitions-in-headers,
|
||||
-misc-unused-parameters,
|
||||
-misc-unused-alias-decls,
|
||||
-misc-use-anonymous-namespace,
|
||||
-misc-misleading-identifier,
|
||||
-misc-confusable-identifiers,
|
||||
-misc-misleading-bidirectional,
|
||||
-misc-static-assert,
|
||||
-misc-no-recursion,
|
||||
-misc-const-correctness,
|
||||
modernize-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
openmp-use-default-none,
|
||||
performance-*,
|
||||
-performance-no-int-to-ptr,
|
||||
portability-*,
|
||||
-portability-restrict-system-includes,
|
||||
readability-*,
|
||||
-readability-redundant-preprocessor,
|
||||
-readability-named-parameter,
|
||||
-readability-function-size,
|
||||
-readability-use-anyofallof,
|
||||
-readability-identifier-length,
|
||||
-readability-magic-numbers,
|
||||
-readability-braces-around-statements,
|
||||
-readability-suspicious-call-argument,
|
||||
-readability-isolate-declaration,
|
||||
-readability-else-after-return,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-identifier-naming,
|
||||
*-include-cleaner,
|
||||
-readability-qualified-auto'
|
||||
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
cmake-build-*/
|
||||
build*/
|
||||
|
||||
local/
|
||||
**/Dockerfile
|
||||
9
.gdbinit
Normal file
9
.gdbinit
Normal file
@@ -0,0 +1,9 @@
|
||||
# Skip all std:: and __gnu_debug:: symbols
|
||||
skip -rfu ^std::
|
||||
skip -rfu ^__gnu_debug::
|
||||
|
||||
# Skip all ImGui:: symbols
|
||||
skip -rfu ^ImGui::
|
||||
|
||||
# Trigger breakpoint when execution reaches triggerSafeShutdown()
|
||||
break triggerSafeShutdown
|
||||
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<!--
|
||||
Please provide as much information as possible about what your PR aims to do.
|
||||
PRs with no description will most likely be closed until more information is provided.
|
||||
If you're planing on changing fundamental behaviour or add big new features, please open a GitHub Issue first before starting to work on it.
|
||||
If it's not something big and you still want to contact us about it, feel free to do so !
|
||||
-->
|
||||
|
||||
### Problem description
|
||||
<!-- Describe the bug that you fixed/feature request that you implemented, or link to an existing issue describing it -->
|
||||
|
||||
### Implementation description
|
||||
<!-- Explain what you did to correct the problem -->
|
||||
|
||||
### Screenshots
|
||||
<!-- If your change is visual, take a screenshot showing it. Ideally, make before/after sceenshots -->
|
||||
|
||||
### Additional things
|
||||
<!-- Anything else you would like to say -->
|
||||
7
.github/workflows/analysis.yml
vendored
7
.github/workflows/analysis.yml
vendored
@@ -28,8 +28,8 @@ jobs:
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build
|
||||
key: ${{ runner.os }}-analysis-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-analysis-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-analysis-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-analysis-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
@@ -46,6 +46,7 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
378
.github/workflows/build.yml
vendored
378
.github/workflows/build.yml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -20,8 +20,6 @@ jobs:
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
CCACHE_DIR: "${{ github.workspace }}/.ccache"
|
||||
CCACHE_MAXSIZE: "1000M"
|
||||
CCACHE_COMPRESS: "true"
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -32,16 +30,16 @@ jobs:
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
id: cache-ccache
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
key: ${{ runner.os }}-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🟦 Install msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
@@ -51,7 +49,6 @@ jobs:
|
||||
gcc:p
|
||||
lld:p
|
||||
cmake:p
|
||||
make:p
|
||||
ccache:p
|
||||
glfw:p
|
||||
file:p
|
||||
@@ -59,6 +56,14 @@ jobs:
|
||||
freetype:p
|
||||
dlfcn:p
|
||||
libbacktrace:p
|
||||
ninja:p
|
||||
curl-winssl:p
|
||||
capstone:p
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -67,28 +72,32 @@ jobs:
|
||||
# Windows cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
cmake -G "MinGW Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \
|
||||
-DUSE_SYSTEM_CAPSTONE=ON \
|
||||
-DDOTNET_EXECUTABLE="C:/Program Files/dotnet/dotnet.exe" \
|
||||
..
|
||||
mingw32-make -j4 install
|
||||
ninja install
|
||||
cpack
|
||||
mv imhex-*.msi ../imhex-${{env.IMHEX_VERSION}}-Windows-x86_64.msi
|
||||
mv ImHex-*.msi ../imhex-${{env.IMHEX_VERSION}}-Windows-x86_64.msi
|
||||
|
||||
echo "ImHex checks for the existence of this file to determine if it is running in portable mode. You should not delete this file" > $PWD/install/PORTABLE
|
||||
|
||||
- name: ⬆️ Upload Windows Installer
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer x86_64
|
||||
path: |
|
||||
imhex-*.msi
|
||||
@@ -96,6 +105,7 @@ jobs:
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
@@ -103,6 +113,7 @@ jobs:
|
||||
- name: ⬇️ Download Mesa3D for NoGPU version
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "NoGPU version Powered by Mesa 3D : https://fdossena.com/?p=mesa%2Findex.frag" > build/install/MESA.md
|
||||
curl https://werwolv.net/downloads/mesa/MesaForWindows-x64-latest.7z -L -o mesa.7z
|
||||
7z e mesa.7z
|
||||
@@ -111,15 +122,17 @@ jobs:
|
||||
- name: ⬆️ Upload NoGPU Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable NoGPU x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
|
||||
# MacOS build
|
||||
macos:
|
||||
runs-on: macos-11
|
||||
runs-on: macos-12
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- suffix: "-NoGPU"
|
||||
@@ -127,7 +140,7 @@ jobs:
|
||||
- suffix: ""
|
||||
custom_glfw: false
|
||||
|
||||
name: 🍎 macOS 11.0${{matrix.suffix}}
|
||||
name: 🍎 macOS 12.0${{matrix.suffix}}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -142,19 +155,21 @@ jobs:
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
key: ${{ runner.os }}${{ matrix.suffix }}-ccache-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}${{ matrix.suffix }}-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
set -x
|
||||
brew reinstall python || brew link --overwrite python
|
||||
brew bundle --no-lock --file dist/Brewfile
|
||||
rm -rf /usr/local/Cellar/capstone
|
||||
|
||||
@@ -163,67 +178,133 @@ jobs:
|
||||
run: |
|
||||
brew install glfw
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 🧰 Checkout glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: glfw/glfw
|
||||
path: glfw
|
||||
|
||||
|
||||
# GLFW custom build (to allow software rendering)
|
||||
- name: ⬇️ Patch and install custom glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
run: |
|
||||
set -x
|
||||
cd glfw
|
||||
git apply ../dist/macOS/0001-glfw-SW.patch
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
..
|
||||
make -j 4 install
|
||||
ninja install
|
||||
|
||||
# MacOS cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
MACOSX_DEPLOYMENT_TARGET="10.10" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="10.10" \
|
||||
-DCPACK_PACKAGE_FILE_NAME="imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}-x86_64" \
|
||||
CC=$(brew --prefix gcc@12)/bin/gcc-12 \
|
||||
CXX=$(brew --prefix gcc@12)/bin/g++-12 \
|
||||
OBJC=$(brew --prefix llvm)/bin/clang \
|
||||
OBJCXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \
|
||||
-DCPACK_PACKAGE_FILE_NAME="imhex-${{env.IMHEX_VERSION}}-macOS${{matrix.suffix}}-x86_64" \
|
||||
..
|
||||
make -j4 package
|
||||
ninja package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: macOS DMG${{matrix.suffix}} x86_64
|
||||
path: build/*.dmg
|
||||
|
||||
macos-arm64:
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🍎 macOS 12.1 arm64
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cache
|
||||
key: build-macos-arm64-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2 # Doesn't work with a MacOS runner ?
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/macOS/arm64.Dockerfile --progress=plain --build-arg 'JOBS=4' --build-arg "BUILD_TYPE=$(BUILD_TYPE)" --build-context imhex=$(pwd) --output out
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: macOS ZIP arm64
|
||||
path: out/
|
||||
|
||||
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
|
||||
- name: 🗑️ Delete old cache
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
gh actions-cache delete "build-macos-arm64-cache" --confirm
|
||||
|
||||
# Ubuntu build
|
||||
ubuntu:
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🐧 Ubuntu 22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Ubuntu
|
||||
release_num: 22.04
|
||||
- name: Ubuntu
|
||||
release_num: 23.04
|
||||
|
||||
name: 🐧 Ubuntu ${{ matrix.release_num }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: "ubuntu:${{ matrix.release_num }}"
|
||||
options: --privileged
|
||||
|
||||
steps:
|
||||
- name: ⬇️ Install setup dependencies
|
||||
run: apt update && apt install -y git curl
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -233,36 +314,54 @@ jobs:
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
key: Ubuntu-${{matrix.release_num}}-ccache-${{ github.run_id }}
|
||||
restore-keys: Ubuntu-${{matrix.release_num}}-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: Ubuntu-${{matrix.release_num}}-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo bash dist/get_deps_debian.sh
|
||||
apt update
|
||||
bash dist/get_deps_debian.sh
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 🏔️ Set Environment variables
|
||||
run: |
|
||||
echo COMMIT_SHA_SHORT=$(git rev-parse --short HEAD) >> $GITHUB_ENV
|
||||
echo COMMIT_SHA_LONG=$(git rev-parse HEAD) >> $GITHUB_ENV
|
||||
echo COMMIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) >> $GITHUB_ENV
|
||||
|
||||
# Ubuntu cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
git config --global --add safe.directory '*'
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
CC=gcc-12 CXX=g++-12 cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${{ env.COMMIT_SHA_SHORT }}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${{ env.COMMIT_SHA_LONG }}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${{ env.COMMIT_BRANCH }}" \
|
||||
-DIMHEX_ENABLE_LTO=ON \
|
||||
-DIMHEX_USE_GTK_FILE_PICKER=ON \
|
||||
-DDOTNET_EXECUTABLE="dotnet" \
|
||||
..
|
||||
make -j 4 install DESTDIR=DebDir
|
||||
DESTDIR=DebDir ninja install
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -272,12 +371,13 @@ jobs:
|
||||
run: |
|
||||
cp -r build/DEBIAN build/DebDir
|
||||
dpkg-deb -Zgzip --build build/DebDir
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-22.04-x86_64.deb
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Ubuntu 22.04 DEB x86_64
|
||||
if-no-files-found: error
|
||||
name: Ubuntu ${{ matrix.release_num }} DEB x86_64
|
||||
path: '*.deb'
|
||||
|
||||
# AppImage build
|
||||
@@ -285,74 +385,43 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
name: ⬇️ AppImage
|
||||
steps:
|
||||
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build-appimage/CMakeCache.txt
|
||||
key: ${{ runner.os }}-appimage-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
path: cache
|
||||
key: appimage-ccache-${{ github.run_id }}
|
||||
restore-keys: appimage-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo bash dist/get_deps_debian.sh
|
||||
docker buildx build . -f dist/appimage/Dockerfile --progress=plain --build-arg "BUILD_TYPE=$BUILD_TYPE" \
|
||||
--build-arg "GIT_COMMIT_HASH=$GITHUB_SHA" --build-arg "GIT_BRANCH=${GITHUB_REF##*/}" --output out
|
||||
|
||||
sudo apt install -y python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse
|
||||
sudo wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /usr/local/bin/appimagetool
|
||||
sudo chmod +x /usr/local/bin/appimagetool
|
||||
sudo pip3 install git+https://github.com/iTrooz/appimage-builder@dpkg-package-versions
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_ENV
|
||||
|
||||
# AppImage cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
mkdir -p build-appimage
|
||||
cd build-appimage
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
-DIMHEX_USE_BUNDLED_CA=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=AppDir
|
||||
|
||||
- name: 📦 Bundle AppImage
|
||||
run: |
|
||||
cd build-appimage
|
||||
export VERSION=${{env.IMHEX_VERSION}}
|
||||
appimage-builder --recipe ../dist/AppImageBuilder.yml
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage x86_64
|
||||
path: 'build-appimage/*.AppImage'
|
||||
path: 'out/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage zsync x86_64
|
||||
path: 'build-appimage/*.AppImage.zsync'
|
||||
path: 'out/*.AppImage.zsync'
|
||||
|
||||
# ArchLinux build
|
||||
archlinux-build:
|
||||
@@ -380,39 +449,48 @@ jobs:
|
||||
run: |
|
||||
dist/get_deps_archlinux.sh --noconfirm
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: archlinux-${{ secrets.CACHE_VERSION }}-build
|
||||
max-size: 50M
|
||||
key: archlinux-ccache-${{ github.run_id }}
|
||||
restore-keys: archlinux-ccache
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Restore CMakeCache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: archlinux-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
# ArchLinux cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc CXX=g++ cmake \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SYSTEM_FMT=ON \
|
||||
-DUSE_SYSTEM_YARA=ON \
|
||||
-DUSE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-DUSE_SYSTEM_CAPSTONE=OFF \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
||||
CC=gcc CXX=g++ cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DUSE_SYSTEM_FMT=ON \
|
||||
-DUSE_SYSTEM_YARA=ON \
|
||||
-DUSE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-DUSE_SYSTEM_CAPSTONE=OFF \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GITHUB_REF##*/}" \
|
||||
-DIMHEX_ENABLE_LTO=ON \
|
||||
-DIMHEX_USE_GTK_FILE_PICKER=ON \
|
||||
..
|
||||
make -j 4 install DESTDIR=installDir
|
||||
DESTDIR=installDir ninja install
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -426,6 +504,7 @@ jobs:
|
||||
# makepkg doesn't want to run as root, so I had to chmod 777 all over
|
||||
- name: 📦 Package ArchLinux .pkg.tar.zst
|
||||
run: |
|
||||
set -x
|
||||
cd build
|
||||
|
||||
# the name is a small trick to make makepkg recognize it as the source
|
||||
@@ -443,6 +522,7 @@ jobs:
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ArchLinux .pkg.tar.zst x86_64
|
||||
path: |
|
||||
build/imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
@@ -450,20 +530,21 @@ jobs:
|
||||
# RPM distro builds
|
||||
rpm-build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Fedora
|
||||
mock_release: rawhide
|
||||
release_num: rawhide
|
||||
mock_config: fedora-rawhide
|
||||
- name: Fedora
|
||||
mock_release: f38
|
||||
release_num: 38
|
||||
mock_config: fedora-38
|
||||
- name: Fedora
|
||||
mock_release: f37
|
||||
release_num: 37
|
||||
mock_config: fedora-37
|
||||
- name: Fedora
|
||||
mock_release: f36
|
||||
release_num: 36
|
||||
mock_config: fedora-36
|
||||
- name: RHEL-AlmaLinux
|
||||
mock_release: epel9
|
||||
release_num: 9
|
||||
@@ -490,22 +571,28 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/dnf
|
||||
key: ${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-dnf-${{ github.run_id }}
|
||||
key: ${{ matrix.mock_release }}-dnf-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-dnf-
|
||||
${{ matrix.mock_release }}-dnf-
|
||||
|
||||
- name: ⬇️ Update all packages and install dependencies
|
||||
run: |
|
||||
set -x
|
||||
dnf upgrade --disablerepo="*" --enablerepo="fedora,updates" -y
|
||||
dnf install --disablerepo="*" --enablerepo="fedora,updates" -y \
|
||||
fedpkg \
|
||||
ccache
|
||||
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
with:
|
||||
key: rpm-${{ matrix.mock_release }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: rpm-${{ matrix.mock_release }}-${{ secrets.CACHE_VERSION }}-build
|
||||
key: ${{ matrix.mock_release }}-rpm-${{ github.run_id }}
|
||||
restore-keys: ${{ matrix.mock_release }}-rpm
|
||||
max-size: 1G
|
||||
|
||||
- name: 📜 Set version variable
|
||||
@@ -515,7 +602,7 @@ jobs:
|
||||
- name: 🗜️ Create tarball from sources with dependencies
|
||||
run: tar --exclude-vcs -czf $GITHUB_WORKSPACE/imhex-$IMHEX_VERSION.tar.gz ImHex
|
||||
|
||||
- name: "✒️ Modify spec file: set version, use latest pattern language, enable online build"
|
||||
- name: ✒️ Modify spec file
|
||||
run: |
|
||||
sed -i \
|
||||
-e 's/Version: [0-9]*\.[0-9]*\.[0-9]*$/Version: ${{env.IMHEX_VERSION}}/g' \
|
||||
@@ -546,9 +633,9 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/mock
|
||||
key: ${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-mock-${{ github.run_id }}
|
||||
key: ${{ matrix.mock_release }}-mock-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
${{ matrix.mock_release }}-${{secrets.CACHE_VERSION }}-mock-
|
||||
${{ matrix.mock_release }}-mock
|
||||
|
||||
# Fedora cmake build (in imhex.spec)
|
||||
- name: 📦 Build RPM
|
||||
@@ -563,6 +650,7 @@ jobs:
|
||||
- name: ⬆️ Upload RPM
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: ${{ matrix.name }} ${{ matrix.release_num }} RPM x86_64
|
||||
path: |
|
||||
imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
79
.github/workflows/build_web.yml
vendored
Normal file
79
.github/workflows/build_web.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
name: Build for the web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["*"]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🌍 WebAssembly
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: 📁 Restore docker /cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cache
|
||||
key: build-web-cache
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2
|
||||
with:
|
||||
cache-source: cache
|
||||
cache-target: /cache
|
||||
|
||||
- name: 🛠️ Build using docker
|
||||
run: |
|
||||
docker buildx build . -f dist/web/Dockerfile --progress=plain --build-arg 'JOBS=4' --output out
|
||||
|
||||
- name: 🔨 Fix permissions
|
||||
run: |
|
||||
chmod -c -R +rX "out/" | while read line; do
|
||||
echo "::warning title=Invalid file permissions automatically fixed::$line"
|
||||
done
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
with:
|
||||
path: out/
|
||||
|
||||
# See https://github.com/actions/cache/issues/342#issuecomment-1711054115
|
||||
- name: 🗑️ Delete old cache
|
||||
continue-on-error: true
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
gh actions-cache delete "build-web-cache" --confirm
|
||||
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
name: 📃 Deploy to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: ${{ github.ref == 'refs/heads/master' && github.event.repository.fork == false }}
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: 🌍 Deploy
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
116
.github/workflows/release.yml
vendored
116
.github/workflows/release.yml
vendored
@@ -9,9 +9,52 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
release-common:
|
||||
release-update-repos:
|
||||
runs-on: ubuntu-latest
|
||||
name: Release Common
|
||||
name: Release Update Repos
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ImHex
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
run: |
|
||||
set -x
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
if [ "$project_version" != "$tag_version" ]; then
|
||||
echo "::warning::$project_version and $tag_version are not the same ! Refusing to populate release"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "IMHEX_VERSION=$project_version" >> $GITHUB_ENV
|
||||
|
||||
- name: 🎫 Create PatternLanguage release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{ env.IMHEX_VERSION }}
|
||||
repo: PatternLanguage
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: 🎫 Create ImHex-Patterns release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{ env.IMHEX_VERSION }}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
release-upload-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
name: Release Upload Artifacts
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -22,6 +65,7 @@ jobs:
|
||||
|
||||
- name: 📜 Verify version and set version variable
|
||||
run: |
|
||||
set -x
|
||||
project_version=`cat ImHex/VERSION`
|
||||
tag_version="${{github.event.release.tag_name}}"
|
||||
tag_version="${tag_version:1}"
|
||||
@@ -45,7 +89,8 @@ jobs:
|
||||
skip_unpack: true
|
||||
|
||||
- name: 🗜️ Unzip files when needed
|
||||
run: |
|
||||
run: |
|
||||
set -x
|
||||
for zipfile in ./*.zip
|
||||
do
|
||||
if [ `zipinfo -1 "$zipfile" | wc -l` -eq 1 ];
|
||||
@@ -60,8 +105,8 @@ jobs:
|
||||
|
||||
- name: 🟩 Rename artifacts when needed
|
||||
run: |
|
||||
mv "Windows Portable x86_64.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-x86_64.zip
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{env.IMHEX_VERSION}}-Windows-Portable-NoGPU-x86_64.zip
|
||||
mv "Windows Portable x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-x86_64.zip
|
||||
mv "Windows Portable NoGPU x86_64.zip" imhex-${{ env.IMHEX_VERSION }}-Windows-Portable-NoGPU-x86_64.zip
|
||||
|
||||
- name: ⬆️ Upload everything to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
@@ -70,16 +115,16 @@ jobs:
|
||||
|
||||
- name: ✒️ Prepare PKGBUILD
|
||||
run: |
|
||||
set -x
|
||||
cp ImHex/dist/Arch/PKGBUILD .
|
||||
|
||||
hash=`md5sum imhex-${{ env.IMHEX_VERSION }}-ArchLinux-x86_64.pkg.tar.zst | cut -d ' ' -f 1`
|
||||
|
||||
hash=`md5sum imhex-${{env.IMHEX_VERSION}}-ArchLinux.pkg.tar.zst-x86_64 | cut -d ' ' -f 1`
|
||||
|
||||
sed -i 's/%version%/${{env.IMHEX_VERSION}}/g' PKGBUILD
|
||||
sed -i 's/%version%/${{ env.IMHEX_VERSION }}/g' PKGBUILD
|
||||
sed -i "s/(SKIP)/($hash)/g" PKGBUILD
|
||||
|
||||
- name: ⬆️ Publish AUR package
|
||||
|
||||
# I couldn't make the condition in the env directly for some reason
|
||||
env:
|
||||
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
if: "${{ env.AUR_SSH_PRIVATE_KEY != '' }}"
|
||||
@@ -91,64 +136,25 @@ jobs:
|
||||
commit_username: iTrooz
|
||||
commit_email: itrooz@protonmail.com
|
||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||
commit_message: Bump to version ${{env.IMHEX_VERSION}}
|
||||
commit_message: Bump to version ${{ env.IMHEX_VERSION }}
|
||||
ssh_keyscan_types: rsa,dsa,ecdsa,ed25519
|
||||
|
||||
- name: 🎫 Create PatternLanguage release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: PatternLanguage
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: 🎫 Create ImHex-Patterns release
|
||||
uses: ncipollo/release-action@v1
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
tag: ImHex-v${{env.IMHEX_VERSION}}
|
||||
repo: ImHex-Patterns
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: ✉️ Update C++ Plugin Template
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
repository: WerWolv/ImHex-Cpp-Plugin-Template
|
||||
event_type: update_submodule
|
||||
|
||||
- name: ✉️ Update Rust Plugin Template
|
||||
uses: peter-evans/repository-dispatch@v2
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.RELEASE_TOKEN != '' }}"
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
repository: WerWolv/ImHex-Rust-Plugin-Template
|
||||
event_type: update_submodule
|
||||
|
||||
release-windows:
|
||||
name: Release Windows
|
||||
needs: release-common
|
||||
runs-on: windows-2022
|
||||
release-update-winget:
|
||||
name: Release update winget package
|
||||
needs: release-upload-artifacts
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: ⬇️ Download dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
iwr https://github.com/microsoft/winget-create/releases/download/v1.1.2.0/wingetcreate.exe -OutFile wingetcreate.exe
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
- name: ⬆️ Update winget manifest
|
||||
shell: pwsh
|
||||
env:
|
||||
WINGET_GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
if: "${{ env.WINGET_GITHUB_TOKEN != '' }}"
|
||||
run: |
|
||||
set -x
|
||||
$tagname = $env:GITHUB_REF.Replace("refs/tags/", "")
|
||||
$version = $tagname.Replace("v", "")
|
||||
$url = "https://github.com/WerWolv/ImHex/releases/download/${tagname}/imhex-${version}-Windows-x86_64.msi"
|
||||
|
||||
7
.github/workflows/tests.yml
vendored
7
.github/workflows/tests.yml
vendored
@@ -25,8 +25,8 @@ jobs:
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build
|
||||
key: ${{ runner.os }}-tests-build-${{ github.run_id }}
|
||||
restore-keys: ${{ runner.os }}-tests-build
|
||||
max-size: 50M
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-tests-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
key: ${{ runner.os }}-tests-build-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Install dependencies
|
||||
run: |
|
||||
@@ -44,6 +44,7 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ venv/
|
||||
*.mgc
|
||||
imgui.ini
|
||||
.DS_Store
|
||||
./CMakeUserPresets.json
|
||||
34
.gitmodules
vendored
34
.gitmodules
vendored
@@ -1,31 +1,35 @@
|
||||
[submodule "lib/external/nativefiledialog"]
|
||||
path = lib/external/nativefiledialog
|
||||
[submodule "lib/third_party/nativefiledialog"]
|
||||
path = lib/third_party/nativefiledialog
|
||||
url = https://github.com/btzy/nativefiledialog-extended
|
||||
ignore = dirty
|
||||
[submodule "lib/external/yara/yara"]
|
||||
path = lib/external/yara/yara
|
||||
[submodule "lib/third_party/yara/yara"]
|
||||
path = lib/third_party/yara/yara
|
||||
url = https://github.com/VirusTotal/yara
|
||||
ignore = dirty
|
||||
[submodule "lib/external/xdgpp"]
|
||||
path = lib/external/xdgpp
|
||||
[submodule "lib/third_party/xdgpp"]
|
||||
path = lib/third_party/xdgpp
|
||||
url = https://git.sr.ht/~danyspin97/xdgpp
|
||||
ignore = dirty
|
||||
[submodule "lib/external/fmt"]
|
||||
path = lib/external/fmt
|
||||
[submodule "lib/third_party/fmt"]
|
||||
path = lib/third_party/fmt
|
||||
url = https://github.com/fmtlib/fmt
|
||||
ignore = dirty
|
||||
[submodule "lib/external/curl"]
|
||||
path = lib/external/curl
|
||||
url = https://github.com/curl/curl
|
||||
ignore = dirty
|
||||
[submodule "lib/external/capstone"]
|
||||
path = lib/external/capstone
|
||||
[submodule "lib/third_party/capstone"]
|
||||
path = lib/third_party/capstone
|
||||
url = https://github.com/capstone-engine/capstone
|
||||
ignore = dirty
|
||||
[submodule "lib/third_party/jthread/jthread"]
|
||||
path = lib/third_party/jthread/jthread
|
||||
url = https://github.com/josuttis/jthread
|
||||
ignore = dirty
|
||||
|
||||
[submodule "lib/external/libromfs"]
|
||||
path = lib/external/libromfs
|
||||
url = https://github.com/WerWolv/libromfs
|
||||
ignore = dirty
|
||||
[submodule "lib/external/pattern_language"]
|
||||
path = lib/external/pattern_language
|
||||
url = https://github.com/WerWolv/PatternLanguage
|
||||
[submodule "lib/external/libwolv"]
|
||||
path = lib/external/libwolv
|
||||
url = https://github.com/WerWolv/libwolv
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# Options
|
||||
option(IMHEX_USE_BUNDLED_CA "Use the CA bundle in romfs instead of the system one" OFF)
|
||||
option(IMHEX_PLUGINS_IN_SHARE "Put the plugins in share/imhex/plugins instead of lib[..]/imhex/plugins" OFF)
|
||||
option(IMHEX_STRIP_RELEASE "Strip the release builds" ON)
|
||||
option(IMHEX_OFFLINE_BUILD "Enable offline build" OFF)
|
||||
@@ -9,6 +8,14 @@ option(IMHEX_IGNORE_BAD_CLONE "Disable the bad clone prevention checks" OFF)
|
||||
option(IMHEX_PATTERNS_PULL_MASTER "Download latest files from master branch of the ImHex-Patterns repo" OFF)
|
||||
option(IMHEX_IGNORE_BAD_COMPILER "Allow compiling with an unsupported compiler" OFF)
|
||||
option(IMHEX_USE_GTK_FILE_PICKER "Use GTK file picker instead of xdg-desktop-portals" OFF)
|
||||
option(IMHEX_DISABLE_STACKTRACE "Disables support for printing stack traces" OFF)
|
||||
option(IMHEX_BUNDLE_DOTNET "Bundle .NET runtime" ON)
|
||||
option(IMHEX_ENABLE_LTO "Enables Link Time Optimizations if possible" OFF)
|
||||
option(IMHEX_USE_DEFAULT_BUILD_SETTINGS "Use default build settings" OFF)
|
||||
option(IMHEX_STRICT_WARNINGS "Enable most available warnings and treat them as errors" ON)
|
||||
option(IMHEX_STATIC_LINK_PLUGINS "Statically link all plugins into the main executable" OFF)
|
||||
option(IMHEX_GENERATE_PACKAGE "Specify if a native package should be built. Only usable on Windows and MacOS" OFF)
|
||||
option(IMHEX_ENABLE_UNITY_BUILD "Enables building ImHex as a unity build." OFF)
|
||||
|
||||
# Basic compiler and cmake configurations
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
@@ -20,6 +27,7 @@ include("${IMHEX_BASE_FOLDER}/cmake/build_helpers.cmake")
|
||||
# Setup project
|
||||
loadVersion(IMHEX_VERSION)
|
||||
setVariableInParent(IMHEX_VERSION ${IMHEX_VERSION})
|
||||
configureCMake()
|
||||
project(imhex
|
||||
LANGUAGES C CXX VERSION ${IMHEX_VERSION}
|
||||
DESCRIPTION "The ImHex Hex Editor"
|
||||
@@ -35,20 +43,22 @@ verifyCompiler()
|
||||
set(PLUGINS
|
||||
builtin
|
||||
windows
|
||||
script_loader
|
||||
)
|
||||
|
||||
# Add various defines
|
||||
detectOS()
|
||||
detectArch()
|
||||
addVersionDefines()
|
||||
addDefines()
|
||||
configurePackingResources()
|
||||
setUninstallTarget()
|
||||
addBundledLibraries()
|
||||
|
||||
# Add ImHex sources
|
||||
add_custom_target(imhex_all ALL)
|
||||
|
||||
add_subdirectory(lib/libimhex)
|
||||
add_subdirectory(main)
|
||||
add_custom_target(imhex ALL DEPENDS main libimhex)
|
||||
|
||||
# Add unit tests
|
||||
enable_testing()
|
||||
@@ -56,3 +66,4 @@ add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
|
||||
# Configure packaging
|
||||
createPackage()
|
||||
generatePDBs()
|
||||
|
||||
44
CMakePresets.json
Normal file
44
CMakePresets.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"version": 2,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 20,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "base",
|
||||
"displayName": "Base",
|
||||
"description": "Base configuration for all builds",
|
||||
"hidden": true,
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_CXX_COMPILER": "g++",
|
||||
"IMHEX_PATTERNS_PULL_MASTER": "ON",
|
||||
"CMAKE_INSTALL_PREFIX": "./install",
|
||||
"USE_SYSTEM_CAPSTONE": "ON",
|
||||
"IMHEX_USE_DEFAULT_BUILD_SETTINGS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x86_64",
|
||||
"displayName": "x86_64 Build",
|
||||
"description": "x86_64 build",
|
||||
"inherits": [ "base" ]
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "x86_64",
|
||||
"description": "x86_64 build",
|
||||
"configurePreset": "x86_64",
|
||||
"targets": [ "imhex_all" ]
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
|
||||
]
|
||||
}
|
||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
Discord @WerWolv#1337.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -1,9 +1,30 @@
|
||||
# Hacking guide
|
||||
# Contribution guide
|
||||
|
||||
## Introduction
|
||||
|
||||
This document is a guide for developers who want to contribute to ImHex in any way. It contains information about the codebase, the build process and the general workflow.
|
||||
|
||||
## Making Changes
|
||||
|
||||
### Adding new features
|
||||
|
||||
If you'd like to add new features, the best way to start is by joining our Discord and telling us about your idea. We can then discuss the best way to implement it and how it should be integrated into ImHex or if it should be done in a separate plugin.
|
||||
|
||||
There are standalone plugin templates that use ImHex as a submodule. You can find them here:
|
||||
- https://github.com/WerWolv/ImHex-Cpp-Plugin-Template
|
||||
- https://github.com/WerWolv/ImHex-Rust-Plugin-Template
|
||||
|
||||
### Adding a new language
|
||||
|
||||
If you'd like to support a new language in ImHex, the best way is by using the `dist/langtool.py` tool. It will create the necessary file for you and help you fill them out.
|
||||
First, run the tool with `python3 dist/langtool.py create plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of your language. This will create a new file in the language directory.
|
||||
Afterwards follow the prompts of the program to populate the entire file. Once you're done, rerun cmake and rebuild ImHex. Your language should now be available in the settings.
|
||||
|
||||
### Updating an existing language
|
||||
|
||||
If you'd like to add missing keys to an existing language, you can also use the `dist/langtool.py` tool. Run it with `python3 dist/langtool.py translate plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of the language.
|
||||
This will one by one list all the missing translation keys that are present in the default translation file, and you can fill them in with the correct translation for your language.
|
||||
|
||||
## Codebase
|
||||
|
||||
ImHex is written in C++ and usually uses the latest compiler and standard library features available in gcc on all supported OSes. At the time of writing this is C++23.
|
||||
@@ -45,23 +66,3 @@ I personally use CLion for development since it makes configuring and building t
|
||||
### macOS
|
||||
- Install all dependencies using brew and the `dist/Brewfile` script.
|
||||
|
||||
## Making Changes
|
||||
|
||||
### Adding new features to ImHex
|
||||
|
||||
If you'd like to add new features, the best way to start is by joining our Discord and telling us about your idea. We can then discuss the best way to implement it and how it should be integrated into ImHex or if it should be done in a separate plugin.
|
||||
|
||||
There are standalone plugin templates that use ImHex as a submodule. You can find them here:
|
||||
- https://github.com/WerWolv/ImHex-Cpp-Plugin-Template
|
||||
- https://github.com/WerWolv/ImHex-Rust-Plugin-Template
|
||||
|
||||
### Adding a new language
|
||||
|
||||
If you'd like to support a new language in ImHex, the best way is by using the `dist/langtool.py` tool. It will create the necessary file for you and help you fill them out.
|
||||
First, run the tool with `python3 dist/langtool.py create plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of your language. This will create a new file in the language directory.
|
||||
Afterwards follow the prompts of the program to populate the entire file. Once you're done, rerun cmake and rebuild ImHex. Your language should now be available in the settings.
|
||||
|
||||
### Updating an existing language
|
||||
|
||||
If you'd like to add missing keys to an existing language, you can also use the `dist/langtool.py` tool. Run it with `python3 dist/langtool.py translate plugins/builtin/romfs/lang <iso_code>` where `<iso_code>` is the ISO 639-1 code of the language.
|
||||
This will one by one list all the missing translation keys that are present in the default translation file, and you can fill them in with the correct translation for your language.
|
||||
19
PLUGINS.md
Normal file
19
PLUGINS.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Plugins
|
||||
|
||||
ImHex is entirely built around the possibility to easily load plugins (most of it's features are actually implemented as a plugin!).
|
||||
|
||||
To install plugins, simply download the relevant `.hexplug` file and drop it in your `plugins` folder. The location of that folder can be found under `Help -> About -> ImHex Directories`.
|
||||
|
||||
## Available Plugins
|
||||
|
||||
(If you're developing a Plugin on your own, please feel free to add it to this list)
|
||||
|
||||
### Official Plugins
|
||||
- [Extra Hashes Plugin](https://github.com/WerWolv/ImHex-Hashes-Plugin)
|
||||
- Adds support for a variety of new hashes to the Hashes view including Blake, Adler32, Murmur and Tiger
|
||||
- [Discord RPC Plugin](https://github.com/WerWolv/ImHex-Plugin-DiscordRPC)
|
||||
- Adds support for Discord Rich Presence
|
||||
|
||||
### Third-Party Plugins
|
||||
- [Pcap Plugin](https://github.com/Professor-plum/ImHex-Plugin-Pcap)
|
||||
- Adds support for reading packet capture files
|
||||
31
README.md
31
README.md
@@ -25,6 +25,18 @@
|
||||
<a title="Translation" href="https://weblate.werwolv.net/projects/imhex/">
|
||||
<img alt="Translation" src="https://img.shields.io/weblate/progress/imhex?logo=weblate&logoColor=%23FFFFFF&server=https%3A%2F%2Fweblate.werwolv.net&style=for-the-badge">
|
||||
</a>
|
||||
<a title="Documentation" href="https://imhex.werwolv.net/docs">
|
||||
<img alt="Documentation" src="https://img.shields.io/badge/Docs-Available-brightgreen?logo=gitbook&logoColor=%23FFFFFF&style=for-the-badge">
|
||||
</a>
|
||||
<a title="Plugins" href="https://github.com/WerWolv/ImHex/blob/master/PLUGINS.md">
|
||||
<img alt="Plugins" src="https://img.shields.io/badge/Plugins-Supported-brightgreen?logo=stackedit&logoColor=%23FFFFFF&style=for-the-badge">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a title="Use the Web version of ImHex right in your browser!" href="https://web.imhex.werwolv.net">
|
||||
<img alt="Use the Web version of ImHex right in your browser!" src="resources/dist/common/try_online_banner.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Supporting
|
||||
@@ -114,7 +126,6 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
- Hexadecimal Color picker
|
||||
- Base converter
|
||||
- UNIX Permissions calculator
|
||||
- Anonfiles File upload tool
|
||||
- Wikipedia term definition finder
|
||||
- File utilities
|
||||
- File splitter
|
||||
@@ -127,7 +138,7 @@ The Pattern Language is the completely custom programming language developed for
|
||||
It allows you to define structures and data types in a C-like syntax and then use them to parse and highlight a file's content.
|
||||
|
||||
- Source Code: [Link](https://github.com/WerWolv/PatternLanguage/)
|
||||
- Documentation: [Link](https://imhex.werwolv.net/docs/)
|
||||
- Documentation: [Link](https://docs.werwolv.net/pattern-language/)
|
||||
|
||||
## Database
|
||||
|
||||
@@ -139,7 +150,14 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
|
||||
|
||||
To use ImHex, the following minimal system requirements need to be met:
|
||||
|
||||
- **OS**: Windows 7 or higher, macOS 10.15 (Catalina) or higher, "Modern" Linux (Ubuntu 22.04, Fedora 36/37, RHEL/AlmaLinux 9, and Arch Linux have official packages, other and older distributions can use the AppImage)
|
||||
- **OS**:
|
||||
- **Windows**: Windows 7 or higher (Windows 10/11 recommended)
|
||||
- **macOS**: macOS 11 (Big Sur) or higher,
|
||||
- **Linux**: "Modern" Linux. The following distributions have official releases available. Other distros are supported through the AppImage and Flatpak releases.
|
||||
- Ubuntu 22.04/23.04
|
||||
- Fedora 36/37
|
||||
- RHEL/AlmaLinux 9
|
||||
- Arch Linux
|
||||
- **CPU**: x86_64 (64 Bit)
|
||||
- **GPU**: OpenGL 3.0 or higher
|
||||
- Intel HD drivers are really buggy and often cause graphic artifacts
|
||||
@@ -162,6 +180,9 @@ All dependencies that aren't bundled, can be installed using the dependency inst
|
||||
|
||||
For more information, check out the [Compiling](/dist/compiling) guide.
|
||||
|
||||
## Contributing
|
||||
See [Contributing](/CONTRIBUTING.md)
|
||||
|
||||
## Plugin development
|
||||
|
||||
To develop plugins for ImHex, use one of the following two templates projects to get started. You then have access to the entirety of libimhex as well as the ImHex API and the Content Registry to interact with ImHex or to add new content.
|
||||
@@ -173,11 +194,11 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
|
||||
### Contributors
|
||||
|
||||
- [Mary](https://github.com/Thog) for her immense help porting ImHex to MacOS and help during development
|
||||
- [Mary](https://github.com/marysaka) for her immense help porting ImHex to MacOS and help during development
|
||||
- [Roblabla](https://github.com/Roblabla) for adding MSI Installer support to ImHex
|
||||
- [jam1garner](https://github.com/jam1garner) and [raytwo](https://github.com/raytwo) for their help with adding Rust support to plugins
|
||||
- [Mailaender](https://github.com/Mailaender) for getting ImHex onto Flathub
|
||||
- [iTrooz](https://github.com/iTrooz) for many improvements related to release packaging and the GitHub Action runners.
|
||||
- [iTrooz](https://github.com/iTrooz) for many improvements and new features to Imhex
|
||||
- Everybody else who has reported issues on Discord or GitHub that I had great conversations with :)
|
||||
|
||||
### Dependencies
|
||||
|
||||
10
SECURITY.md
Normal file
10
SECURITY.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Supported is generally only the latest version that can be downloaded from the Release tab. If you have issues, you might get instructed to use the Nightly release version instead.
|
||||
If you built ImHex yourself and experience issues that are not present in the version built by GitHub, you're on your own.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Any critical vulnerabilities can be reported through Discord (@werwolv).
|
||||
@@ -1,57 +1,49 @@
|
||||
include(FetchContent)
|
||||
|
||||
if(IMHEX_STRIP_RELEASE)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CPACK_STRIP_FILES TRUE)
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
add_link_options($<$<CONFIG:RELEASE>:-s>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(addVersionDefines)
|
||||
macro(addDefines)
|
||||
if (NOT IMHEX_VERSION)
|
||||
message(FATAL_ERROR "IMHEX_VERSION is not defined")
|
||||
endif ()
|
||||
|
||||
if (IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Get the latest abbreviated commit hash of the working branch
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%h
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
add_compile_definitions(GIT_COMMIT_HASH="${GIT_COMMIT_HASH}" GIT_BRANCH="${GIT_BRANCH}")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR} -DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH} ")
|
||||
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION})
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING})
|
||||
add_compile_definitions(NDEBUG)
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-Debug)
|
||||
add_compile_definitions(DEBUG _GLIBCXX_DEBUG _GLIBCXX_VERBOSE)
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-RelWithDebInfo)
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING})
|
||||
add_compile_definitions(NDEBUG)
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
||||
set(IMHEX_VERSION_STRING ${IMHEX_VERSION_STRING}-MinSizeRel)
|
||||
add_compile_definitions(NDEBUG)
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(IMHEX_VERSION="${IMHEX_VERSION_STRING}")
|
||||
|
||||
if (IMHEX_STATIC_LINK_PLUGINS)
|
||||
add_compile_definitions(IMHEX_STATIC_LINK_PLUGINS)
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
function(addDefineToSource SOURCE DEFINE)
|
||||
set_property(
|
||||
SOURCE ${SOURCE}
|
||||
APPEND
|
||||
PROPERTY COMPILE_DEFINITIONS "${DEFINE}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Detect current OS / System
|
||||
macro(detectOS)
|
||||
if (WIN32)
|
||||
@@ -59,8 +51,6 @@ macro(detectOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
|
||||
SET(IMHEX_USE_BUNDLED_CA ON)
|
||||
elseif (APPLE)
|
||||
add_compile_definitions(OS_MACOS)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
@@ -68,6 +58,8 @@ macro(detectOS)
|
||||
set(PLUGINS_INSTALL_LOCATION "plugins")
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
elseif (EMSCRIPTEN)
|
||||
add_compile_definitions(OS_WEB)
|
||||
elseif (UNIX AND NOT APPLE)
|
||||
add_compile_definitions(OS_LINUX)
|
||||
include(GNUInstallDirs)
|
||||
@@ -84,10 +76,6 @@ macro(detectOS)
|
||||
message(FATAL_ERROR "Unknown / unsupported system!")
|
||||
endif()
|
||||
|
||||
if(IMHEX_USE_BUNDLED_CA)
|
||||
add_compile_definitions(IMHEX_USE_BUNDLED_CA)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# Detect 32 vs. 64 bit system
|
||||
@@ -101,20 +89,16 @@ endmacro()
|
||||
|
||||
|
||||
macro(configurePackingResources)
|
||||
option (CREATE_PACKAGE "Create a package with CPack" OFF)
|
||||
|
||||
if (APPLE)
|
||||
option (CREATE_BUNDLE "Create a bundle on macOS" OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(APPLICATION_TYPE)
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/resource.rc")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-subsystem,windows")
|
||||
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
set(APPLICATION_TYPE WIN32)
|
||||
endif ()
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/resource.rc")
|
||||
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "imhex")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
set(CPACK_WIX_UPGRADE_GUID "05000E99-9659-42FD-A1CF-05C554B39285")
|
||||
set(CPACK_WIX_PRODUCT_ICON "${PROJECT_SOURCE_DIR}/resources/dist/windows/icon.ico")
|
||||
@@ -130,7 +114,7 @@ macro(configurePackingResources)
|
||||
elseif (APPLE)
|
||||
set (IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/dist/macos/AppIcon.icns")
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set(APPLICATION_TYPE MACOSX_BUNDLE)
|
||||
set_source_files_properties(${IMHEX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
set(MACOSX_BUNDLE_ICON_FILE "AppIcon.icns")
|
||||
@@ -139,16 +123,19 @@ macro(configurePackingResources)
|
||||
set(MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resources/dist/macos/Info.plist.in")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "net.WerWolv.ImHex")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}-${GIT_COMMIT_HASH}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}-${IMHEX_COMMIT_HASH_SHORT}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
|
||||
string(TIMESTAMP CURR_YEAR "%Y")
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2020 - ${CURR_YEAR} WerWolv. All rights reserved." )
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/ImHex.app")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/imhex.app")
|
||||
else ()
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/ImHex.app")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/imhex.app")
|
||||
endif()
|
||||
|
||||
set(PLUGINS_INSTALL_LOCATION "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
set(CMAKE_INSTALL_LIBDIR "${IMHEX_BUNDLE_PATH}/Contents/Frameworks")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -172,11 +159,9 @@ macro(createPackage)
|
||||
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
else ()
|
||||
if (WIN32)
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
elseif (APPLE)
|
||||
if (CREATE_BUNDLE)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:main>/${PLUGINS_INSTALL_LOCATION})
|
||||
if (APPLE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGINS_INSTALL_LOCATION})
|
||||
else ()
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
endif ()
|
||||
@@ -185,7 +170,7 @@ macro(createPackage)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_dependencies(imhex ${plugin})
|
||||
add_dependencies(imhex_all ${plugin})
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
@@ -208,11 +193,8 @@ macro(createPackage)
|
||||
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
|
||||
)
|
||||
|
||||
if(_u_deps)
|
||||
message(WARNING "There were unresolved dependencies for binary: \"${_u_deps}\"!")
|
||||
endif()
|
||||
if(_c_deps_FILENAMES)
|
||||
message(WARNING "There were conflicting dependencies for library: \"${_c_deps}\"!")
|
||||
message(WARNING "Conflicting dependencies for library: \"${_c_deps}\"!")
|
||||
endif()
|
||||
|
||||
foreach(_file ${_r_deps})
|
||||
@@ -248,7 +230,7 @@ macro(createPackage)
|
||||
|
||||
endif()
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
if (IMHEX_GENERATE_PACKAGE AND APPLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
@@ -256,7 +238,7 @@ macro(createPackage)
|
||||
set_property(TARGET main PROPERTY MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
|
||||
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET imhex POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
add_custom_command(TARGET imhex_all POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
|
||||
# FIXME: Remove this once we move/integrate the plugins directory.
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
@@ -269,18 +251,22 @@ macro(createPackage)
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${IMHEX_BUNDLE_PATH}")
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
postprocess_bundle(imhex main)
|
||||
postprocess_bundle(imhex_all main)
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/dist/macos/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/imhex.app/Contents/Info.plist")
|
||||
else()
|
||||
install(TARGETS main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(WIN32) # Forwarder is only needed on Windows
|
||||
install(TARGETS main-forwarder BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set (CPACK_BUNDLE_NAME "ImHex")
|
||||
set (CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/dist/macos/AppIcon.icns" )
|
||||
set (CPACK_BUNDLE_PLIST "${CMAKE_BINARY_DIR}/ImHex.app/Contents/Info.plist")
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
@@ -296,10 +282,79 @@ function(JOIN OUTPUT GLUE)
|
||||
set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(configureCMake)
|
||||
message(STATUS "Configuring ImHex v${IMHEX_VERSION}")
|
||||
|
||||
# Enable C and C++ languages
|
||||
enable_language(C CXX)
|
||||
|
||||
# Configure use of recommended build tools
|
||||
if (IMHEX_USE_DEFAULT_BUILD_SETTINGS)
|
||||
message(STATUS "Configuring CMake to use recommended build tools...")
|
||||
|
||||
find_program(CCACHE_PATH ccache)
|
||||
find_program(NINJA_PATH ninja)
|
||||
find_program(LD_LLD_PATH ld.lld)
|
||||
find_program(AR_LLVMLIBS_PATH llvm-ar)
|
||||
find_program(RANLIB_LLVMLIBS_PATH llvm-ranlib)
|
||||
|
||||
if (CCACHE_PATH)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PATH})
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PATH})
|
||||
else ()
|
||||
message(WARNING "ccache not found!")
|
||||
endif ()
|
||||
|
||||
if (AR_LLVMLIBS_PATH)
|
||||
set(CMAKE_AR ${AR_LLVMLIBS_PATH})
|
||||
else ()
|
||||
message(WARNING "llvm-ar not found, using default ar!")
|
||||
endif ()
|
||||
|
||||
if (RANLIB_LLVMLIBS_PATH)
|
||||
set(CMAKE_RANLIB ${RANLIB_LLVMLIBS_PATH})
|
||||
else ()
|
||||
message(WARNING "llvm-ranlib not found, using default ranlib!")
|
||||
endif ()
|
||||
|
||||
if (LD_LLD_PATH)
|
||||
set(CMAKE_LINKER ${LD_LLD_PATH})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=lld")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld")
|
||||
else ()
|
||||
message(WARNING "lld not found, using default linker!")
|
||||
endif ()
|
||||
|
||||
if (NINJA_PATH)
|
||||
set(CMAKE_GENERATOR Ninja)
|
||||
else ()
|
||||
message(WARNING "ninja not found, using default generator!")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Enable LTO if desired and supported
|
||||
if (IMHEX_ENABLE_LTO)
|
||||
include(CheckIPOSupported)
|
||||
|
||||
check_ipo_supported(RESULT result OUTPUT output_error)
|
||||
if (result)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
message(STATUS "LTO enabled!")
|
||||
else ()
|
||||
message(WARNING "LTO is not supported: ${output_error}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Some libraries we use set the BUILD_SHARED_LIBS variable to ON, which causes CMake to
|
||||
# display a warning about options being set using set() instead of option().
|
||||
# Explicitly set the policy to NEW to suppress the warning.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
endmacro()
|
||||
|
||||
macro(setDefaultBuiltTypeIfUnset)
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Using Release build type as it was left unset" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Using RelWithDebInfo build type as it was left unset" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "RelWithDebInfo")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -316,9 +371,9 @@ function(detectBadClone)
|
||||
return()
|
||||
endif()
|
||||
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*")
|
||||
file (GLOB EXTERNAL_DIRS "lib/external/*" "lib/third_party/*")
|
||||
foreach (EXTERNAL_DIR ${EXTERNAL_DIRS})
|
||||
file(GLOB RESULT "${EXTERNAL_DIR}/*")
|
||||
file(GLOB_RECURSE RESULT "${EXTERNAL_DIR}/*")
|
||||
list(LENGTH RESULT ENTRY_COUNT)
|
||||
if(ENTRY_COUNT LESS_EQUAL 1)
|
||||
message(FATAL_ERROR "External dependency ${EXTERNAL_DIR} is empty!\nMake sure to correctly clone ImHex using the --recurse-submodules git option or initialize the submodules manually.")
|
||||
@@ -333,8 +388,8 @@ function(verifyCompiler)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0.0")
|
||||
message(FATAL_ERROR "ImHex requires GCC 12.0.0 or newer. Please use the latest GCC version.")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "14.0.0")
|
||||
message(FATAL_ERROR "ImHex requires Clang 14.0.0 or newer. Please use the latest Clang version.")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "17.0.0")
|
||||
message(FATAL_ERROR "ImHex requires Clang 17.0.0 or newer. Please use the latest Clang version.")
|
||||
elseif (NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||
message(FATAL_ERROR "ImHex can only be compiled with GCC or Clang. ${CMAKE_CXX_COMPILER_ID} is not supported.")
|
||||
endif()
|
||||
@@ -361,7 +416,7 @@ function(downloadImHexPatternsFiles dest)
|
||||
FetchContent_Declare(
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG master
|
||||
GIT_TAG origin/master
|
||||
)
|
||||
|
||||
message(STATUS "Downloading ImHex-Patterns repo branch ${PATTERNS_BRANCH}...")
|
||||
@@ -376,18 +431,43 @@ function(downloadImHexPatternsFiles dest)
|
||||
if (EXISTS ${imhex_patterns_SOURCE_DIR})
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest} PATTERN "**/_schema.json" EXCLUDE)
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
endfunction()
|
||||
|
||||
macro(setupCompilerWarnings target)
|
||||
set(IMHEX_COMMON_FLAGS "-Wall -Wextra -Wpedantic -Werror")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_COMMON_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow")
|
||||
macro(setupCompilerFlags target)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
# Define strict compilation flags
|
||||
if (IMHEX_STRICT_WARNINGS)
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wall -Wextra -Wpedantic -Werror")
|
||||
endif()
|
||||
|
||||
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
|
||||
|
||||
# Disable some warnings
|
||||
set(IMHEX_C_CXX_FLAGS "-Wno-array-bounds -Wno-deprecated-declarations")
|
||||
|
||||
if (IMHEX_ENABLE_UNITY_BUILD AND WIN32)
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wa,-mbig-obj")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Disable some warnings for gcc
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow -Wno-dangling-reference")
|
||||
endif()
|
||||
|
||||
# Define emscripten-specific disabled warnings
|
||||
if (EMSCRIPTEN)
|
||||
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
|
||||
endif ()
|
||||
|
||||
# Set actual CMake flags
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_FLAGS} ${IMHEX_CXX_FLAGS}")
|
||||
set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${IMHEX_COMMON_FLAGS}")
|
||||
endmacro()
|
||||
|
||||
@@ -407,25 +487,31 @@ endmacro()
|
||||
macro(addBundledLibraries)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
set(EXTERN_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/external")
|
||||
set(EXTERNAL_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/external")
|
||||
set(THIRD_PARTY_LIBS_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/lib/third_party")
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/imgui)
|
||||
set_target_properties(imgui PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/imgui)
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/microtar EXCLUDE_FROM_ALL)
|
||||
set_target_properties(microtar PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/intervaltree EXCLUDE_FROM_ALL)
|
||||
set_target_properties(intervaltree PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/libwolv EXCLUDE_FROM_ALL)
|
||||
set_property(TARGET libwolv-types PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-utils PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-io PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-hash PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-containers PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-net PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libwolv-math_eval PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(XDGPP_INCLUDE_DIRS "${EXTERN_LIBS_FOLDER}/xdgpp")
|
||||
set(CURL_USE_MBEDTLS ON)
|
||||
set(BUILD_CURL_EXE OFF)
|
||||
set(XDGPP_INCLUDE_DIRS "${THIRD_PARTY_LIBS_FOLDER}/xdgpp")
|
||||
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
if(NOT USE_SYSTEM_FMT)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/fmt EXCLUDE_FROM_ALL)
|
||||
set_target_properties(fmt PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(FMT_LIBRARIES fmt::fmt-header-only)
|
||||
else()
|
||||
@@ -439,41 +525,39 @@ macro(addBundledLibraries)
|
||||
set(NFD_PORTAL ON CACHE BOOL "Use GTK for Linux file dialogs" FORCE)
|
||||
endif ()
|
||||
|
||||
if (NOT USE_SYSTEM_NFD)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
else()
|
||||
find_package(nfd)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
if (NOT EMSCRIPTEN)
|
||||
# curl
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.60.0)
|
||||
|
||||
# nfd
|
||||
if (NOT USE_SYSTEM_NFD)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
else()
|
||||
find_package(nfd)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_NLOHMANN_JSON)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nlohmann_json EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/nlohmann_json EXCLUDE_FROM_ALL)
|
||||
set(NLOHMANN_JSON_LIBRARIES nlohmann_json)
|
||||
else()
|
||||
find_package(nlohmann_json 3.10.2 REQUIRED)
|
||||
set(NLOHMANN_JSON_LIBRARIES nlohmann_json::nlohmann_json)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SYSTEM_CURL)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/curl EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libcurl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(LIBCURL_LIBRARIES libcurl)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.76.1)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_LLVM)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/llvm-demangle EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/llvm-demangle EXCLUDE_FROM_ALL)
|
||||
set_target_properties(LLVMDemangle PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
find_package(LLVM REQUIRED Demangle)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_YARA)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/yara EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/yara EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libyara PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(YARA_LIBRARIES libyara)
|
||||
else()
|
||||
@@ -482,7 +566,7 @@ macro(addBundledLibraries)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_MINIAUDIO)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/miniaudio EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/miniaudio EXCLUDE_FROM_ALL)
|
||||
set_target_properties(miniaudio PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(MINIAUDIO_LIBRARIES miniaudio)
|
||||
else()
|
||||
@@ -490,23 +574,37 @@ macro(addBundledLibraries)
|
||||
pkg_check_modules(miniaudio REQUIRED IMPORTED_TARGET miniaudio)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_JTHREAD)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/jthread EXCLUDE_FROM_ALL)
|
||||
set(JTHREAD_LIBRARIES jthread)
|
||||
else()
|
||||
find_path(JOSUTTIS_JTHREAD_INCLUDE_DIRS "condition_variable_any2.hpp")
|
||||
include_directories(${JOSUTTIS_JTHREAD_INCLUDE_DIRS})
|
||||
|
||||
add_library(jthread INTERFACE)
|
||||
target_include_directories(jthread INTERFACE ${JOSUTTIS_JTHREAD_INCLUDE_DIRS})
|
||||
set(JTHREAD_LIBRARIES jthread)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_CAPSTONE)
|
||||
set(CAPSTONE_BUILD_STATIC_RUNTIME OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Disable shared library building")
|
||||
set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Disable tests")
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/capstone EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/capstone EXCLUDE_FROM_ALL)
|
||||
set_target_properties(capstone PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
target_compile_options(capstone PRIVATE -Wno-unused-function)
|
||||
set(CAPSTONE_LIBRARIES "capstone")
|
||||
set(CAPSTONE_INCLUDE_DIRS ${EXTERN_LIBS_FOLDER}/capstone/include)
|
||||
set(CAPSTONE_INCLUDE_DIRS ${THIRD_PARTY_LIBS_FOLDER}/capstone/include)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(CAPSTONE 4.0.2 REQUIRED capstone)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
set(LIBPL_BUILD_CLI_AS_EXECUTABLE OFF)
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
find_package(mbedTLS 2.26.0 REQUIRED)
|
||||
find_package(mbedTLS 3.4.0 REQUIRED)
|
||||
|
||||
pkg_search_module(MAGIC libmagic>=5.39)
|
||||
if(NOT MAGIC_FOUND)
|
||||
@@ -515,25 +613,83 @@ macro(addBundledLibraries)
|
||||
set(MAGIC_INCLUDE_DIRS ${MAGIC_INCLUDEDIR})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
message(STATUS "StackWalk enabled!")
|
||||
set(LIBBACKTRACE_LIBRARIES DbgHelp.lib)
|
||||
else ()
|
||||
find_package(Backtrace)
|
||||
if (${Backtrace_FOUND})
|
||||
message(STATUS "Backtrace enabled! Header: ${Backtrace_HEADER}")
|
||||
if (NOT IMHEX_DISABLE_STACKTRACE)
|
||||
if (WIN32)
|
||||
message(STATUS "StackWalk enabled!")
|
||||
set(LIBBACKTRACE_LIBRARIES DbgHelp.lib)
|
||||
else ()
|
||||
find_package(Backtrace)
|
||||
if (${Backtrace_FOUND})
|
||||
message(STATUS "Backtrace enabled! Header: ${Backtrace_HEADER}")
|
||||
|
||||
if (Backtrace_HEADER STREQUAL "execinfo.h")
|
||||
set(LIBBACKTRACE_LIBRARIES)
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_EXECINFO)
|
||||
elseif (Backtrace_HEADER STREQUAL "backtrace.h")
|
||||
set(LIBBACKTRACE_LIBRARIES backtrace)
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_BACKTRACE)
|
||||
endif ()
|
||||
endif()
|
||||
if (Backtrace_HEADER STREQUAL "execinfo.h")
|
||||
set(LIBBACKTRACE_LIBRARIES ${Backtrace_LIBRARY})
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_EXECINFO)
|
||||
elseif (Backtrace_HEADER STREQUAL "backtrace.h")
|
||||
set(LIBBACKTRACE_LIBRARIES ${Backtrace_LIBRARY})
|
||||
set(LIBBACKTRACE_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
|
||||
add_compile_definitions(BACKTRACE_HEADER=\"${Backtrace_HEADER}\")
|
||||
add_compile_definitions(HEX_HAS_BACKTRACE)
|
||||
endif ()
|
||||
endif()
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
function(enableUnityBuild TARGET)
|
||||
if (IMHEX_ENABLE_UNITY_BUILD)
|
||||
set_target_properties(${TARGET} PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE BATCH)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
function(generatePDBs)
|
||||
if (NOT WIN32 OR CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
cv2pdb
|
||||
URL "https://github.com/rainers/cv2pdb/releases/download/v0.52/cv2pdb-0.52.zip"
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP ON
|
||||
)
|
||||
FetchContent_Populate(cv2pdb)
|
||||
|
||||
set(PDBS_TO_GENERATE main main-forwarder libimhex ${PLUGINS})
|
||||
add_custom_target(pdbs)
|
||||
foreach (PDB ${PDBS_TO_GENERATE})
|
||||
if (PDB STREQUAL "main")
|
||||
set(GENERATED_PDB imhex)
|
||||
elseif (PDB STREQUAL "main-forwarder")
|
||||
set(GENERATED_PDB imhex-gui)
|
||||
elseif (PDB STREQUAL "libimhex")
|
||||
set(GENERATED_PDB libimhex)
|
||||
else ()
|
||||
set(GENERATED_PDB plugins/${PDB})
|
||||
endif ()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb
|
||||
WORKING_DIRECTORY ${cv2pdb_SOURCE_DIR}
|
||||
COMMAND
|
||||
(${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb &&
|
||||
${cv2pdb_SOURCE_DIR}/cv2pdb64.exe
|
||||
$<TARGET_FILE:${PDB}>) || (exit 0)
|
||||
DEPENDS $<TARGET_FILE:${PDB}>
|
||||
COMMAND_EXPAND_LISTS)
|
||||
|
||||
target_sources(imhex_all PRIVATE ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/${GENERATED_PDB}.pdb DESTINATION ".")
|
||||
endforeach ()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(generateSDKDirectory)
|
||||
set(SDK_PATH "./sdk")
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/libimhex/include DESTINATION "${SDK_PATH}")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/cmake/modules/ImHexPlugin.cmake DESTINATION "${SDK_PATH}/cmake/modules")
|
||||
install(TARGETS libimhex ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
install(TARGETS libimhex RUNTIME DESTINATION "${SDK_PATH}/lib")
|
||||
endfunction()
|
||||
81
cmake/modules/FindCoreClrEmbed.cmake
Normal file
81
cmake/modules/FindCoreClrEmbed.cmake
Normal file
@@ -0,0 +1,81 @@
|
||||
set(CoreClrEmbed_FOUND FALSE)
|
||||
|
||||
set(CORECLR_ARCH "linux-x64")
|
||||
set(CORECLR_SUBARCH "x64")
|
||||
if (WIN32)
|
||||
set(CORECLR_ARCH "win-x64")
|
||||
endif()
|
||||
if (UNIX)
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
set(CORECLR_ARCH "linux-arm64")
|
||||
set(CORECLR_SUBARCH "arm64")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT DOTNET_EXECUTABLE)
|
||||
set(DOTNET_EXECUTABLE dotnet)
|
||||
endif ()
|
||||
|
||||
set(CORECLR_VERSION "8.0")
|
||||
|
||||
execute_process(COMMAND ${DOTNET_EXECUTABLE} "--list-runtimes" OUTPUT_VARIABLE CORECLR_LIST_RUNTIMES_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (CORECLR_LIST_RUNTIMES_OUTPUT STREQUAL "")
|
||||
message(STATUS "Unable to find any .NET runtimes")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
set(_ALL_RUNTIMES ${CORECLR_LIST_RUNTIMES_OUTPUT})
|
||||
string(REPLACE "\n" ";" _ALL_RUNTIMES_LIST ${_ALL_RUNTIMES})
|
||||
|
||||
foreach(X ${_ALL_RUNTIMES_LIST})
|
||||
string(REGEX MATCH "Microsoft\.NETCore\.App ([0-9]+)\.([0-9]+)\.([a-zA-Z0-9.-]+) [\[](.*)Microsoft\.NETCore\.App[\]]"
|
||||
CORECLR_VERSION_REGEX_MATCH ${X})
|
||||
|
||||
set(_RUNTIME_VERSION ${CMAKE_MATCH_1}.${CMAKE_MATCH_2})
|
||||
|
||||
if (CMAKE_MATCH_1 AND CMAKE_MATCH_4)
|
||||
if (${_RUNTIME_VERSION} STREQUAL ${CORECLR_VERSION})
|
||||
set(CORECLR_RUNTIME_VERSION ${_RUNTIME_VERSION})
|
||||
set(CORECLR_RUNTIME_VERSION_FULL ${CORECLR_VERSION}.${CMAKE_MATCH_3})
|
||||
set(CORECLR_RUNTIME_ROOT_PATH ${CMAKE_MATCH_4})
|
||||
message(STATUS "Found matching .NET runtime version '${CORECLR_RUNTIME_VERSION_FULL}' path='${CORECLR_RUNTIME_ROOT_PATH}'")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (CORECLR_RUNTIME_ROOT_PATH)
|
||||
get_filename_component(CORECLR_RUNTIME_ROOT_PATH ${CORECLR_RUNTIME_ROOT_PATH} DIRECTORY)
|
||||
endif()
|
||||
set(CoreClrEmbed_ROOT_PATH "${CORECLR_RUNTIME_ROOT_PATH}")
|
||||
|
||||
|
||||
file(GLOB _CORECLR_HOST_ARCH_PATH "${CORECLR_RUNTIME_ROOT_PATH}/packs/Microsoft.NETCore.App.Host.*-${CORECLR_SUBARCH}")
|
||||
if (_CORECLR_HOST_ARCH_PATH)
|
||||
get_filename_component(_CORECLR_HOST_ARCH_FILENAME ${_CORECLR_HOST_ARCH_PATH} NAME)
|
||||
string(REPLACE "Microsoft.NETCore.App.Host." "" _CORECLR_COMPUTED_ARCH "${_CORECLR_HOST_ARCH_FILENAME}")
|
||||
if (_CORECLR_COMPUTED_ARCH)
|
||||
set(CORECLR_ARCH "${_CORECLR_COMPUTED_ARCH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CORECLR_HOST_BASE_PATH "${CORECLR_RUNTIME_ROOT_PATH}/packs/Microsoft.NETCore.App.Host.${CORECLR_ARCH}/${CORECLR_RUNTIME_VERSION_FULL}")
|
||||
file(GLOB _CORECLR_FOUND_PATH ${CORECLR_HOST_BASE_PATH})
|
||||
if (_CORECLR_FOUND_PATH)
|
||||
set(CORECLR_NETHOST_ROOT "${_CORECLR_FOUND_PATH}/runtimes/${CORECLR_ARCH}/native")
|
||||
endif()
|
||||
|
||||
find_library(CoreClrEmbed_LIBRARY nethost PATHS
|
||||
${CORECLR_NETHOST_ROOT}
|
||||
)
|
||||
find_path(CoreClrEmbed_INCLUDE_DIR nethost.h PATHS
|
||||
${CORECLR_NETHOST_ROOT}
|
||||
)
|
||||
find_file(CoreClrEmbed_SHARED_LIBRARY nethost.dll nethost.so libnethost.so nethost.dylib libnethost.dylib PATHS
|
||||
${CORECLR_NETHOST_ROOT})
|
||||
|
||||
if (CoreClrEmbed_INCLUDE_DIR AND CoreClrEmbed_LIBRARY)
|
||||
set(CoreClrEmbed_FOUND TRUE)
|
||||
set(CoreClrEmbed_LIBRARIES "${CoreClrEmbed_LIBRARY}" CACHE STRING "CoreClrEmbed libraries" FORCE)
|
||||
set(CoreClrEmbed_SHARED_LIBRARIES "${CoreClrEmbed_SHARED_LIBRARY}" CACHE STRING "CoreClrEmbed shared libraries" FORCE)
|
||||
set(CoreClrEmbed_INCLUDE_DIRS "${CoreClrEmbed_INCLUDE_DIR}" CACHE STRING "CoreClrEmbed include directories" FORCE)
|
||||
endif()
|
||||
63
cmake/modules/ImHexPlugin.cmake
Normal file
63
cmake/modules/ImHexPlugin.cmake
Normal file
@@ -0,0 +1,63 @@
|
||||
macro(add_imhex_plugin)
|
||||
# Parse arguments
|
||||
set(options "")
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs SOURCES INCLUDES LIBRARIES)
|
||||
cmake_parse_arguments(IMHEX_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (IMHEX_STATIC_LINK_PLUGINS)
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE STATIC)
|
||||
|
||||
target_link_libraries(libimhex PUBLIC ${IMHEX_PLUGIN_NAME})
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/dist/web/plugin-bundle.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp @ONLY)
|
||||
target_sources(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/plugin-bundle.cpp)
|
||||
else()
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE MODULE)
|
||||
endif()
|
||||
|
||||
# Define new project for plugin
|
||||
project(${IMHEX_PLUGIN_NAME})
|
||||
|
||||
# Create a new shared library for the plugin source code
|
||||
add_library(${IMHEX_PLUGIN_NAME} ${IMHEX_PLUGIN_LIBRARY_TYPE} ${IMHEX_PLUGIN_SOURCES})
|
||||
|
||||
# Add include directories and link libraries
|
||||
target_include_directories(${IMHEX_PLUGIN_NAME} PUBLIC ${IMHEX_PLUGIN_INCLUDES})
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE libimhex ${FMT_LIBRARIES} ${IMHEX_PLUGIN_LIBRARIES})
|
||||
|
||||
# Add IMHEX_PROJECT_NAME and IMHEX_VERSION define
|
||||
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PROJECT_NAME="${IMHEX_PLUGIN_NAME}")
|
||||
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_VERSION="${IMHEX_VERSION_STRING}")
|
||||
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PLUGIN_NAME=${IMHEX_PLUGIN_NAME})
|
||||
|
||||
# Enable required compiler flags
|
||||
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
enableUnityBuild(${IMHEX_PLUGIN_NAME})
|
||||
setupCompilerFlags(${IMHEX_PLUGIN_NAME})
|
||||
|
||||
# Configure build properties
|
||||
set_target_properties(${IMHEX_PLUGIN_NAME}
|
||||
PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
|
||||
CXX_STANDARD 23
|
||||
PREFIX ""
|
||||
SUFFIX ".hexplug"
|
||||
)
|
||||
|
||||
# Setup a romfs for the plugin
|
||||
list(APPEND LIBROMFS_RESOURCE_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/romfs)
|
||||
set(LIBROMFS_PROJECT_NAME ${IMHEX_PLUGIN_NAME})
|
||||
add_subdirectory(${IMHEX_BASE_FOLDER}/lib/external/libromfs ${CMAKE_CURRENT_BINARY_DIR}/libromfs)
|
||||
set_target_properties(${LIBROMFS_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE ${LIBROMFS_LIBRARY})
|
||||
|
||||
# Add the new plugin to the main dependency list so it gets built by default
|
||||
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
||||
endmacro()
|
||||
|
||||
macro(add_romfs_resource input output)
|
||||
configure_file(${input} ${CMAKE_CURRENT_BINARY_DIR}/romfs/${output} COPYONLY)
|
||||
|
||||
list(APPEND LIBROMFS_RESOURCE_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/romfs)
|
||||
endmacro()
|
||||
@@ -15,13 +15,21 @@ if(CMAKE_GENERATOR)
|
||||
set(_POSTPROCESS_BUNDLE_MODULE_LOCATION "${CMAKE_CURRENT_LIST_FILE}")
|
||||
function(postprocess_bundle out_target in_target)
|
||||
add_custom_command(TARGET ${out_target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -DBUNDLE_PATH="$<TARGET_FILE_DIR:${in_target}>/../.." -DCODE_SIGN_CERTIFICATE_ID="${CODE_SIGN_CERTIFICATE_ID}"
|
||||
COMMAND ${CMAKE_COMMAND} -DBUNDLE_PATH="$<TARGET_FILE_DIR:${in_target}>/../.."
|
||||
-DCODE_SIGN_CERTIFICATE_ID="${CODE_SIGN_CERTIFICATE_ID}"
|
||||
-DEXTRA_BUNDLE_LIBRARY_PATHS="${EXTRA_BUNDLE_LIBRARY_PATHS}"
|
||||
-P "${_POSTPROCESS_BUNDLE_MODULE_LOCATION}"
|
||||
)
|
||||
endfunction()
|
||||
return()
|
||||
endif()
|
||||
|
||||
# IMHEX PATCH BEGIN
|
||||
# The function defined above doesn't keep in mind that if we are cross-compiling to MacOS, APPLE must be 1,
|
||||
# so we force it here (where else would this script be run anyway ? This seems to be MacOS-specific code)
|
||||
SET(APPLE 1)
|
||||
# IMHEX PATCHE END
|
||||
|
||||
get_filename_component(BUNDLE_PATH "${BUNDLE_PATH}" ABSOLUTE)
|
||||
message(STATUS "Fixing up application bundle: ${BUNDLE_PATH}")
|
||||
|
||||
@@ -29,13 +37,13 @@ message(STATUS "Fixing up application bundle: ${BUNDLE_PATH}")
|
||||
# Make sure to fix up any included ImHex plugin.
|
||||
file(GLOB_RECURSE extra_libs "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexplug")
|
||||
|
||||
message(STATUS "Fixing up application bundle: ${extra_dirs}")
|
||||
|
||||
# BundleUtilities doesn't support DYLD_FALLBACK_LIBRARY_PATH behavior, which
|
||||
# makes it sometimes break on libraries that do weird things with @rpath. Specify
|
||||
# equivalent search directories until https://gitlab.kitware.com/cmake/cmake/issues/16625
|
||||
# is fixed and in our minimum CMake version.
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib")
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib" ${EXTRA_BUNDLE_LIBRARY_PATHS})
|
||||
message(STATUS "Fixing up application bundle: ${extra_dirs}")
|
||||
|
||||
# BundleUtilities is overly verbose, so disable most of its messages
|
||||
function(message)
|
||||
|
||||
6
dist/AppImageBuilder.yml
vendored
6
dist/AppImageBuilder.yml
vendored
@@ -20,7 +20,7 @@ AppDir:
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates universe
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy multiverse
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-updates multiverse
|
||||
- sourceline: deb http://.archive.ubuntu.com/ubuntu/ jammy-backports main restricted
|
||||
- sourceline: deb http://us.archive.ubuntu.com/ubuntu/ jammy-backports main restricted
|
||||
universe multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu jammy-security universe
|
||||
@@ -38,8 +38,6 @@ AppDir:
|
||||
- libtinfo6:amd64
|
||||
files:
|
||||
include:
|
||||
- /lib/x86_64-linux-gnu/libGLX.so.0
|
||||
- /lib/x86_64-linux-gnu/libGLdispatch.so.0
|
||||
- /lib/x86_64-linux-gnu/libLLVM-13.so.1
|
||||
- /lib/x86_64-linux-gnu/libOpenGL.so.0
|
||||
- /lib/x86_64-linux-gnu/libX11.so.6
|
||||
@@ -64,6 +62,7 @@ AppDir:
|
||||
- /lib/x86_64-linux-gnu/libbsd.so.0
|
||||
- /lib/x86_64-linux-gnu/libcairo-gobject.so.2
|
||||
- /lib/x86_64-linux-gnu/libcairo.so.2
|
||||
- /lib/x86_64-linux-gnu/libcurl-gnutls.so.4
|
||||
- /lib/x86_64-linux-gnu/libdatrie.so.1
|
||||
- /lib/x86_64-linux-gnu/libedit.so.2
|
||||
- /lib/x86_64-linux-gnu/libelf.so.1
|
||||
@@ -76,7 +75,6 @@ AppDir:
|
||||
- /lib/x86_64-linux-gnu/libgdk-3.so.0
|
||||
- /lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libgio-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libglapi.so.0
|
||||
- /lib/x86_64-linux-gnu/libglfw.so.3
|
||||
- /lib/x86_64-linux-gnu/libglib-2.0.so.0
|
||||
- /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
|
||||
|
||||
6
dist/Arch/PKGBUILD
vendored
6
dist/Arch/PKGBUILD
vendored
@@ -1,4 +1,4 @@
|
||||
# Maintainer: iTrooz_ <itrooz at protonmail dot com>
|
||||
# Maintainer: iTrooz_ <aur at itrooz dot fr>
|
||||
# Contributor: Morten Linderud <foxboron@archlinux.org>
|
||||
|
||||
pkgname=imhex-bin
|
||||
@@ -8,7 +8,7 @@ pkgdesc="A Hex Editor for Reverse Engineers, Programmers and people who value th
|
||||
arch=("x86_64")
|
||||
url="https://github.com/WerWolv/ImHex"
|
||||
license=('GPL2')
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus xdg-desktop-portal curl fmt yara nlohmann-json)
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json)
|
||||
makedepends=(git)
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
@@ -25,5 +25,5 @@ package() {
|
||||
|
||||
install -d "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/imhex/"{constants,encodings,includes,magic,patterns} "$pkgdir/usr/share/imhex"
|
||||
cp -r "$srcdir/usr/share/"{applications,licenses} "$pkgdir/usr/share"
|
||||
cp -r "$srcdir/usr/share/"{applications,licenses,pixmaps} "$pkgdir/usr/share"
|
||||
}
|
||||
|
||||
2
dist/Brewfile
vendored
2
dist/Brewfile
vendored
@@ -5,6 +5,8 @@ brew "ccache"
|
||||
brew "freetype2"
|
||||
brew "libmagic"
|
||||
brew "pkg-config"
|
||||
brew "curl"
|
||||
brew "gcc@12"
|
||||
brew "llvm"
|
||||
brew "glfw"
|
||||
brew "ninja"
|
||||
3
dist/Dockerfile
vendored
3
dist/Dockerfile
vendored
@@ -1,6 +1,6 @@
|
||||
FROM archlinux:latest
|
||||
|
||||
LABEL maintainer="hey@werwolv.net" = WerWolv
|
||||
LABEL maintainer="hey@werwolv.net WerWolv"
|
||||
|
||||
# Install dependencies
|
||||
RUN pacman -Syy --needed --noconfirm
|
||||
@@ -14,6 +14,7 @@ RUN pacman -S --needed --noconfirm \
|
||||
file \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
curl \
|
||||
dbus \
|
||||
xdg-desktop-portal
|
||||
|
||||
|
||||
85
dist/appimage/Dockerfile
vendored
Normal file
85
dist/appimage/Dockerfile
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
FROM ubuntu:22.04 as build
|
||||
|
||||
# Used to invalidate layer cache but not mount cache
|
||||
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
|
||||
ARG UNIQUEKEY 1
|
||||
|
||||
COPY dist/get_deps_debian.sh /tmp
|
||||
RUN --mount=type=cache,target=/var/apt/cache <<EOF
|
||||
# Install apt dependencies
|
||||
set -xe
|
||||
|
||||
apt update
|
||||
|
||||
# general deps
|
||||
apt install -y ccache git wget
|
||||
# appimage tools deps
|
||||
apt install -y python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fuse ninja-build
|
||||
apt install -y squashfs-tools zsync
|
||||
|
||||
# imhex deps
|
||||
/tmp/get_deps_debian.sh
|
||||
EOF
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
# Download appimage-builder
|
||||
set -xe
|
||||
|
||||
mkdir -p /cache/bin
|
||||
wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /cache/bin/appimagetool || true
|
||||
chmod +x /cache/bin/appimagetool
|
||||
|
||||
pip3 install git+https://github.com/AppImageCrafters/appimage-builder@f38699e
|
||||
EOF
|
||||
|
||||
ENV PATH="/cache/bin/:${PATH}"
|
||||
|
||||
# Copy Imhex source
|
||||
COPY . /imhex
|
||||
|
||||
ARG LTO=ON
|
||||
ARG BUILD_TYPE=RelWithDebInfo
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_BRANCH
|
||||
WORKDIR /build
|
||||
SHELL ["bash", "-c"] # Ubuntu sh doesnt support string substitution
|
||||
RUN <<EOF
|
||||
# Prepare ImHex build
|
||||
set -xe
|
||||
|
||||
CC=gcc-12 CXX=g++-12 cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GIT_COMMIT_HASH::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GIT_COMMIT_HASH}" \
|
||||
-DIMHEX_COMMIT_BRANCH="${GIT_BRANCH}" \
|
||||
-DIMHEX_ENABLE_LTO=${LTO} \
|
||||
-DIMHEX_PLUGINS_IN_SHARE=ON \
|
||||
/imhex
|
||||
EOF
|
||||
|
||||
ENV CCACHE_DIR /cache/ccache
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
# Build Imhex
|
||||
set -xe
|
||||
|
||||
ccache -zs
|
||||
DESTDIR=AppDir ninja install
|
||||
ccache -s
|
||||
EOF
|
||||
|
||||
RUN <<EOF
|
||||
# Package ImHex as AppImage
|
||||
set -xe
|
||||
|
||||
export VERSION=$(cat /imhex/VERSION)
|
||||
appimage-builder --recipe /imhex/dist/AppImageBuilder.yml
|
||||
EOF
|
||||
|
||||
FROM scratch
|
||||
|
||||
# Copy build artifact
|
||||
COPY --from=build /build/*.AppImage /build/*.AppImage.zsync ./
|
||||
48
dist/compiling/docker.md
vendored
Normal file
48
dist/compiling/docker.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
For a TLDR of commands see [How to build](#How-to-build)
|
||||
|
||||
# Introduction
|
||||
|
||||
The original CI we used (vanilla Github Actions) was great for specifying what steps to execute to build packages. It could even do some custom steps with reusable actions. But it had problem: no local reproducibility. This meant that:
|
||||
- We couldn't test code properly locally, we were dependent on GitHub to do it
|
||||
- If something was wrong and we had to debug the build script, it was *long and painful* because we had to wait for Github runners to finish builds, and couldn't quickly iterate
|
||||
|
||||
To solve this, we are now trying to move the CI build script to docker containers (so using Dockerfiles)
|
||||
|
||||
# How to build
|
||||
|
||||
Commands are available in the [CI](../../.github/workflows/build.yml) and you should prefer copying them from there.
|
||||
But here is a general command that should work for every build we have:
|
||||
```
|
||||
docker buildx build . -f <DOCKERFILE_PATH> --progress plain --build-arg 'JOBS=4' --build-arg 'BUILD_TYPE=Debug' --build-context imhex=$(pwd) --output local
|
||||
```
|
||||
|
||||
where `<DOCKERFILE_PATH>` should be replaced by the wanted Dockerfile base d on the build you want to do:
|
||||
|
||||
| Wanted build | Dockerfile path |
|
||||
|--------------|-----------------------------|
|
||||
| MacOS M1 | dist/macOS/arm64.Dockerfile |
|
||||
| AppImage | dist/appimage/Dockerfile |
|
||||
| Web version | dist/web/Dockerfile |
|
||||
|
||||
We'll explain this command in the next section
|
||||
|
||||
# Useful knowledge about Docker builds
|
||||
|
||||
Docker-based builds work with a Dockerfile. You run the Dockerfile, it builds the package.
|
||||
|
||||
We are using a base environment (often given to us by dockerhub) (e.g. ubuntu:22.04) which is really just a root filesystem, and we then run shell commands in that env, just like a shell script
|
||||
|
||||
Docker-based builds have two kind of caches used:
|
||||
- layer cache, which mean that if a layer (instruction) hasn't been changed, and previous layers haven't changed, it will not be run again
|
||||
- a `COPY` layer will be invalidated if one of the file copied has changed
|
||||
- mount cache, which are per-instructions mounts that will be cached and restored in the next run. Mounts on different folders will not collide
|
||||
|
||||
Docker cache tends to grow very quickly when constantly making changes in the Dockerfile and rebuilding (a.k.a debugging what's going on), you can clear it with something like `docker system prune -a`
|
||||
|
||||
In the command saw earlier:
|
||||
- `.` is the base folder that the Dockerfile will be allowed to see
|
||||
- `-f <path>` is to specify the Dockerfile path
|
||||
- `--progress plain` is to allow you to see the output of instructions
|
||||
- `--build-arg <key>=<value>` is to allow to to specify arguments to the build (like -DKEY=VALUE in CMake)
|
||||
- `--build-context key=<folder>` is to specify folders other than the base folder that the Dockerfile is allowed to see
|
||||
- `--output <path>` is the path to write the output package to. If not specified, Docker will create an image as the output (probably not what you want)
|
||||
5
dist/compiling/macos.md
vendored
5
dist/compiling/macos.md
vendored
@@ -1,6 +1,6 @@
|
||||
### Compiling ImHex on macOS
|
||||
|
||||
On macOS, ImHex is built through regular GCC and AppleClang.
|
||||
On macOS, ImHex is built through regular GCC and LLVM clang.
|
||||
|
||||
1. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
|
||||
2. Install all the dependencies using `brew bundle --no-lock --file dist/Brewfile`
|
||||
@@ -17,8 +17,7 @@ PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/p
|
||||
MACOSX_DEPLOYMENT_TARGET="10.15" \
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCREATE_BUNDLE=ON \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
|
||||
15
dist/compiling/windows.md
vendored
15
dist/compiling/windows.md
vendored
@@ -7,22 +7,19 @@ On Windows, ImHex is built through [msys2 / mingw](https://www.msys2.org/)'s gcc
|
||||
3. Clone the repo using `git clone https://github.com/WerWolv/ImHex --recurse-submodules`
|
||||
4. Install all the dependencies using `./ImHex/dist/get_deps_msys2.sh`
|
||||
5. Build ImHex itself using the following commands:
|
||||
|
||||
```sh
|
||||
cd ImHex
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "MinGW Makefiles" \
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_C_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_CXX_FLAGS="-fuse-ld=lld" \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DRUST_PATH="$USERPROFILE/.cargo/bin/" \
|
||||
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
|
||||
..
|
||||
mingw32-make -j install
|
||||
ninja install
|
||||
```
|
||||
|
||||
ImHex will look for any extra resources either in various folders directly next to the executable or in `%localappdata%/imhex`
|
||||
|
||||
For low RAM-usage system, you can use `mingw32-make -j N install` instead, to reduce RAM usage at compile time. Where `N` is amount of jobs you are willling to run at once. Roughly ~1 GB of RAM usage per job.
|
||||
|
||||
5
dist/get_deps_archlinux.sh
vendored
5
dist/get_deps_archlinux.sh
vendored
@@ -9,8 +9,9 @@ pacman -S $@ --needed \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
dbus \
|
||||
xdg-desktop-portal \
|
||||
gtk3 \
|
||||
curl \
|
||||
fmt \
|
||||
yara \
|
||||
nlohmann-json
|
||||
nlohmann-json \
|
||||
ninja
|
||||
|
||||
5
dist/get_deps_debian.sh
vendored
5
dist/get_deps_debian.sh
vendored
@@ -13,7 +13,6 @@ apt install -y \
|
||||
lld \
|
||||
${PKGCONF:-} \
|
||||
cmake \
|
||||
make \
|
||||
ccache \
|
||||
libglfw3-dev \
|
||||
libglm-dev \
|
||||
@@ -21,4 +20,6 @@ apt install -y \
|
||||
libmbedtls-dev \
|
||||
libfreetype-dev \
|
||||
libdbus-1-dev \
|
||||
xdg-desktop-portal
|
||||
libcurl4-gnutls-dev \
|
||||
libgtk-3-dev \
|
||||
ninja-build
|
||||
|
||||
4
dist/get_deps_fedora.sh
vendored
4
dist/get_deps_fedora.sh
vendored
@@ -5,9 +5,11 @@ dnf install -y \
|
||||
dbus-devel \
|
||||
file-devel \
|
||||
freetype-devel \
|
||||
libcurl-devel \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mesa-libGL-devel \
|
||||
glfw-devel \
|
||||
lld \
|
||||
mbedtls-devel
|
||||
mbedtls-devel \
|
||||
gtk3-devel
|
||||
6
dist/get_deps_msys2.sh
vendored
6
dist/get_deps_msys2.sh
vendored
@@ -4,10 +4,12 @@ pacman -S --needed --noconfirm \
|
||||
mingw-w64-x86_64-gcc \
|
||||
mingw-w64-x86_64-lld \
|
||||
mingw-w64-x86_64-cmake \
|
||||
mingw-w64-x86_64-make \
|
||||
mingw-w64-x86_64-ccache \
|
||||
mingw-w64-x86_64-glfw \
|
||||
mingw-w64-x86_64-file \
|
||||
mingw-w64-x86_64-curl-winssl \
|
||||
mingw-w64-x86_64-mbedtls \
|
||||
mingw-w64-x86_64-freetype \
|
||||
mingw-w64-x86_64-dlfcn
|
||||
mingw-w64-x86_64-dlfcn \
|
||||
mingw-w64-x86_64-ninja \
|
||||
mingw-w64-x86_64-capstone
|
||||
|
||||
165
dist/macOS/arm64.Dockerfile
vendored
Normal file
165
dist/macOS/arm64.Dockerfile
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
# This base image is also known as "crosscompile". See arm64.crosscompile.Dockerfile
|
||||
FROM ghcr.io/itrooz/macos-crosscompile:clang17-nosdk as build
|
||||
|
||||
ENV MACOSX_DEPLOYMENT_TARGET 12.1
|
||||
|
||||
# -- DOWNLOADING STUFF
|
||||
|
||||
## Install make
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt update && apt install -y make
|
||||
|
||||
## fix environment
|
||||
### add install_name_tool for cmake command that won't have the right env set (see PostprocessBundle.cmake function postprocess_bundle())
|
||||
RUN cp /osxcross/build/cctools-port/cctools/misc/install_name_tool /usr/bin/install_name_tool
|
||||
### a cmake thing wants 'otool' and not '' apparently
|
||||
RUN cp /osxcross/target/bin/aarch64-apple-darwin23-otool /usr/bin/otool
|
||||
|
||||
## Clone glfw
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
git clone https://github.com/glfw/glfw /mnt/glfw
|
||||
fi
|
||||
EOF
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Download SDK is missing (it may have been removed from the image)
|
||||
set -xe
|
||||
if [ ! -d /osxcross/target/SDK/MacOSX14.0.sdk ]; then
|
||||
wget https://github.com/joseluisq/macosx-sdks/releases/download/14.0/MacOSX14.0.sdk.tar.xz -O /cache/MacOSX14.0.sdk.tar.xz -nc || true
|
||||
mkdir -p /osxcross/target/SDK
|
||||
tar -C /osxcross/target/SDK -xf /cache/MacOSX14.0.sdk.tar.xz
|
||||
fi
|
||||
EOF
|
||||
|
||||
|
||||
## Download libmagic
|
||||
### Clone libmagic
|
||||
RUN git clone https://github.com/file/file /mnt/file
|
||||
### Download libmagic dependencies
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ apt install -y libtool autoconf
|
||||
|
||||
# -- DOWNLOADING + BUILDING STUFF
|
||||
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE /cache/vcpkg
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Install dependencies with vcpkg
|
||||
set -xe
|
||||
|
||||
mkdir -p $VCPKG_DEFAULT_BINARY_CACHE
|
||||
|
||||
vcpkg install --triplet=arm-osx-mytriplet curl
|
||||
vcpkg install --triplet=arm-osx-mytriplet mbedtls
|
||||
vcpkg install --triplet=arm-osx-mytriplet freetype
|
||||
vcpkg install --triplet=arm-osx-mytriplet josuttis-jthread
|
||||
EOF
|
||||
|
||||
## Install glfw3 dep
|
||||
ARG CUSTOM_GLFW
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
echo "Flag confirmation: using custom GLFW for software rendering"
|
||||
else
|
||||
echo "Flag confirmation: using system GLFW"
|
||||
vcpkg install --triplet=arm-osx-mytriplet glfw3
|
||||
fi
|
||||
EOF
|
||||
|
||||
# -- BUILDING STUFF
|
||||
ARG JOBS 1
|
||||
ARG BUILD_TYPE Debug
|
||||
|
||||
## Build libmagic
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
ccache -zs
|
||||
set -xe
|
||||
|
||||
cd /mnt/file
|
||||
autoreconf -is
|
||||
|
||||
# when cross-compiling, libmagic needs to have an the same version installed in the system.
|
||||
# So we install it normally first
|
||||
./configure --prefix /usr
|
||||
make -j $JOBS install
|
||||
|
||||
# Now, we cross-compile it and install it in the libraries folder
|
||||
CC=/osxcross/target/bin/aarch64-apple-darwin23-clang CXX=/osxcross/target/bin/aarch64-apple-darwin23-clang++ ./configure --prefix /vcpkg/installed/arm-osx-mytriplet --host $OSXCROSS_HOST
|
||||
make -j $JOBS
|
||||
make install
|
||||
|
||||
ccache -s
|
||||
|
||||
EOF
|
||||
|
||||
## Patch glfw
|
||||
COPY --from=imhex /dist/macOS/0001-glfw-SW.patch /tmp
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
cd /mnt/glfw
|
||||
git apply /tmp/0001-glfw-SW.patch
|
||||
fi
|
||||
EOF
|
||||
|
||||
## Build glfw
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
if [ "$CUSTOM_GLFW" ]; then
|
||||
ccache -zs
|
||||
|
||||
cd /mnt/glfw
|
||||
mkdir build
|
||||
cd build
|
||||
CC=o64-gcc CXX=o64-g++ cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJC_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_INSTALL_PREFIX=/vcpkg/installed/arm-osx-mytriplet \
|
||||
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
||||
..
|
||||
ninja -j $JOBS install
|
||||
|
||||
ccache -s
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Build ImHex
|
||||
## Copy ImHex
|
||||
COPY --from=imhex / /mnt/ImHex
|
||||
## Patch ImHex with hacks
|
||||
# COPY toolchain.cmake.2 /osxcross/target/toolchain.cmake
|
||||
# Configure ImHex build
|
||||
RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/_deps \
|
||||
cd /mnt/ImHex && \
|
||||
# compilers
|
||||
CC=o64-clang CXX=o64-clang++ OBJC=/osxcross/target/bin/aarch64-apple-darwin23-clang OBJCXX=/osxcross/target/bin/aarch64-apple-darwin23-clang++ \
|
||||
cmake -G "Ninja" \
|
||||
`# ccache flags` \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
`# MacOS cross-compiling flags` \
|
||||
-DVCPKG_TARGET_TRIPLET=arm-osx-mytriplet -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/osxcross/target/toolchain.cmake -DCMAKE_OSX_SYSROOT=/osxcross/target/SDK/MacOSX14.0.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
||||
`# Override compilers for code generators` \
|
||||
-DNATIVE_CMAKE_C_COMPILER=/usr/bin/clang -DNATIVE_CMAKE_CXX_COMPILER=/usr/bin/clang++ \
|
||||
`# Normal ImHex flags` \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
`# other flags` \
|
||||
-DIMHEX_STRICT_WARNINGS=OFF \
|
||||
-B build
|
||||
## Build ImHex
|
||||
RUN --mount=type=cache,target=/cache --mount=type=cache,target=/mnt/ImHex/build/_deps <<EOF
|
||||
ccache -zs
|
||||
set -xe
|
||||
|
||||
cd /mnt/ImHex
|
||||
cmake --build build --parallel $JOBS
|
||||
|
||||
ccache -s
|
||||
EOF
|
||||
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /mnt/ImHex/build/imhex.app imhex.app
|
||||
96
dist/macOS/arm64.crosscompile.Dockerfile
vendored
Normal file
96
dist/macOS/arm64.crosscompile.Dockerfile
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# This image is is provided for reference, but a (probably more up to date) image should be available at https://github.com/iTrooz/macos-crosscompile
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV PATH $PATH:/osxcross/target/bin
|
||||
ENV LD_LIBRARY_PATH /osxcross/target/lib
|
||||
ENV OSXCROSS_SDK /osxcross/target/SDK/MacOSX14.0.sdk
|
||||
ENV OSXCROSS_TARGET darwin23
|
||||
ENV OSXCROSS_TARGET_DIR /osxcross/target
|
||||
ENV OSXCROSS_HOST aarch64-apple-darwin23
|
||||
|
||||
# -- DOWNLOADING STUFF
|
||||
|
||||
# Install common stuff
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ export DEBIAN_FRONTEND=noninteractive &&\
|
||||
export TZ=Etc/UTC &&\
|
||||
dpkg --add-architecture i386 &&\
|
||||
apt update &&\
|
||||
apt -y install lsb-release build-essential python3 python3-pip git wget zip unzip pkg-config curl ninja-build software-properties-common gnupg libssl-dev ccache
|
||||
|
||||
# Install clang 17
|
||||
RUN --mount=type=cache,target=/var/lib/apt/lists/ wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 17 &&\
|
||||
ln -s /usr/bin/clang-17 /usr/bin/clang &&\
|
||||
ln -s /usr/bin/clang++-17 /usr/bin/clang++
|
||||
|
||||
# Install vcpkg
|
||||
RUN cd / &&\
|
||||
git clone --depth 1 https://github.com/Microsoft/vcpkg.git vcpkg &&\
|
||||
cd /vcpkg &&\
|
||||
./bootstrap-vcpkg.sh -disableMetrics &&\
|
||||
ln -s /vcpkg/vcpkg /usr/bin/ &&\
|
||||
vcpkg install vcpkg-cmake &&\
|
||||
ln -s /vcpkg/downloads/tools/cmake-*/cmake-*/bin/cmake /usr/bin/
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Clone osxcross
|
||||
set -xe
|
||||
git clone https://github.com/tpoechtrager/osxcross /cache/osxcross || true
|
||||
cd /cache/osxcross
|
||||
git pull
|
||||
cp -r /cache/osxcross /osxcross
|
||||
EOF
|
||||
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
## Download SDK
|
||||
set -xe
|
||||
wget https://github.com/joseluisq/macosx-sdks/releases/download/14.0/MacOSX14.0.sdk.tar.xz -O /cache/MacOSX14.0.sdk.tar.xz -nc || true
|
||||
cp /cache/MacOSX14.0.sdk.tar.xz /osxcross/tarballs
|
||||
EOF
|
||||
|
||||
# Init stuff
|
||||
## setup ccache dir
|
||||
ENV CCACHE_DIR /cache/ccache
|
||||
|
||||
# Install triplet file
|
||||
COPY arm-osx-mytriplet.cmake /vcpkg/triplets/community
|
||||
|
||||
# -- BUILDING STUFF
|
||||
ARG JOBS 1
|
||||
|
||||
# Install osxcross
|
||||
## Build cross-compiler clang-17
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
set -xe
|
||||
ccache -zs
|
||||
|
||||
cd /osxcross
|
||||
UNATTENDED=1 CC=/usr/lib/ccache/clang-17 CXX=/usr/lib/ccache/clang++-17 ./build.sh
|
||||
|
||||
ccache -s
|
||||
EOF
|
||||
# Not needed, because we don't use gcc for cross-compiling anymore
|
||||
# ## Install dependencies for gcc-13
|
||||
# RUN apt install -y gcc g++ zlib1g-dev libmpc-dev libmpfr-dev libgmp-dev
|
||||
# ## Build cross-compiler gcc-13
|
||||
# RUN --mount=type=cache,target=/cache <<EOF
|
||||
# set -xe
|
||||
# ccache -zs
|
||||
|
||||
# cd /osxcross
|
||||
# UNATTENDED=1 CC=/usr/lib/ccache/gcc CXX=/usr/lib/ccache/g++ GCC_VERSION=13.2.0 ./build_gcc.sh
|
||||
|
||||
# ccache -s
|
||||
# EOF
|
||||
|
||||
ARG DELETE_SDK=1
|
||||
RUN <<EOF
|
||||
# Conditionally delete the SDK from the image
|
||||
set -xe
|
||||
|
||||
if [ "$DELETE_SDK" ]; then
|
||||
rm -r /osxcross/target/SDK
|
||||
echo "Deleted the SDK from the image"
|
||||
else
|
||||
echo "NOT deleting the SDK from the image"
|
||||
fi
|
||||
EOF
|
||||
25
dist/rpm/imhex.spec
vendored
25
dist/rpm/imhex.spec
vendored
@@ -4,7 +4,7 @@ Release: 0%{?dist}
|
||||
Summary: A hex editor for reverse engineers and programmers
|
||||
|
||||
License: GPL-2.0-only AND Zlib AND MIT AND Apache-2.0
|
||||
# imhex is gplv2. capstone is custom. nativefiledialog is Zlib. intervaltree is MIT
|
||||
# imhex is gplv2. capstone is custom. nativefiledialog is Zlib.
|
||||
# see license dir for full breakdown
|
||||
URL: https://imhex.werwolv.net/
|
||||
# We need the archive with deps bundled
|
||||
@@ -26,6 +26,7 @@ BuildRequires: llvm-devel
|
||||
BuildRequires: mbedtls-devel
|
||||
BuildRequires: yara-devel
|
||||
BuildRequires: nativefiledialog-extended-devel
|
||||
BuildRequires: dotnet-sdk-7.0
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: gcc-toolset-12
|
||||
%endif
|
||||
@@ -36,9 +37,6 @@ Provides: bundled(imgui)
|
||||
Provides: bundled(libromfs)
|
||||
Provides: bundled(microtar)
|
||||
Provides: bundled(libpl)
|
||||
# ImHex modified upstream intervaltree so we have to package it
|
||||
# https://github.com/ekg/intervaltree
|
||||
Provides: bundled(intervaltree) = 0.1
|
||||
Provides: bundled(xdgpp)
|
||||
|
||||
# ftbfs on these arches. armv7hl might compile when capstone 5.x
|
||||
@@ -63,7 +61,7 @@ same time ImHex is completely free and open source under the GPLv2 language.
|
||||
%prep
|
||||
%autosetup -n ImHex
|
||||
# remove bundled libs we aren't using
|
||||
rm -rf lib/external/{curl,fmt,llvm,nlohmann_json,yara}
|
||||
rm -rf lib/third_party/{fmt,nlohmann_json,yara}
|
||||
|
||||
%build
|
||||
%if 0%{?rhel}
|
||||
@@ -77,10 +75,10 @@ CXXFLAGS+=" -std=gnu++2b"
|
||||
-D IMHEX_OFFLINE_BUILD=ON \
|
||||
-D USE_SYSTEM_NLOHMANN_JSON=ON \
|
||||
-D USE_SYSTEM_FMT=ON \
|
||||
-D USE_SYSTEM_CURL=ON \
|
||||
-D USE_SYSTEM_LLVM=ON \
|
||||
-D USE_SYSTEM_YARA=ON \
|
||||
-D USE_SYSTEM_NFD=ON \
|
||||
-D IMHEX_USE_GTK_FILE_PICKER=ON \
|
||||
-D IMHEX_BUNDLE_DOTNET=OFF \
|
||||
# when capstone >= 5.x is released we should be able to build against \
|
||||
# system libs of it \
|
||||
# -D USE_SYSTEM_CAPSTONE=ON
|
||||
@@ -111,12 +109,11 @@ rm -f %{buildroot}%{_metainfodir}/net.werwolv.%{name}.appdata.xml
|
||||
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
|
||||
# install licenses
|
||||
cp -a lib/external/nativefiledialog/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/nativefiledialog-LICENSE
|
||||
cp -a lib/external/capstone/LICENSE.TXT %{buildroot}%{_datadir}/licenses/%{name}/capstone-LICENSE
|
||||
cp -a lib/external/capstone/suite/regress/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/capstone-regress-LICENSE
|
||||
cp -a lib/external/microtar/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/microtar-LICENSE
|
||||
cp -a lib/external/pattern_language/external/intervaltree/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/pattern-language-intervaltree-LICENSE
|
||||
cp -a lib/external/xdgpp/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/xdgpp-LICENSE
|
||||
cp -a lib/third_party/nativefiledialog/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/nativefiledialog-LICENSE
|
||||
cp -a lib/third_party/capstone/LICENSE.TXT %{buildroot}%{_datadir}/licenses/%{name}/capstone-LICENSE
|
||||
cp -a lib/third_party/capstone/suite/regress/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/capstone-regress-LICENSE
|
||||
cp -a lib/third_party/microtar/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/microtar-LICENSE
|
||||
cp -a lib/third_party/xdgpp/LICENSE %{buildroot}%{_datadir}/licenses/%{name}/xdgpp-LICENSE
|
||||
|
||||
|
||||
%files
|
||||
@@ -131,5 +128,3 @@ cp -a lib/external/xdgpp/LICENSE %{buildroot}%{
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Jan 01 1970 ImHex GitHub CI - 0.0.0-0
|
||||
- Build Package
|
||||
|
||||
89
dist/web/Dockerfile
vendored
Normal file
89
dist/web/Dockerfile
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
FROM emscripten/emsdk:latest as build
|
||||
|
||||
# Used to invalidate layer cache but not mount cache
|
||||
# See https://github.com/moby/moby/issues/41715#issuecomment-733976493
|
||||
ARG UNIQUEKEY 1
|
||||
|
||||
RUN apt update
|
||||
RUN apt install -y git ccache autoconf automake libtool cmake pkg-config
|
||||
|
||||
RUN <<EOF
|
||||
# Install vcpkg
|
||||
# Note: we are a patch on the libmagic port
|
||||
set -xe
|
||||
|
||||
git clone https://github.com/microsoft/vcpkg /vcpkg
|
||||
/vcpkg/bootstrap-vcpkg.sh
|
||||
sed -i 's/vcpkg_install_make(${EXTRA_ARGS})/vcpkg_install_make(${EXTRA_ARGS} SUBPATH src)/g' /vcpkg/ports/libmagic/portfile.cmake
|
||||
EOF
|
||||
|
||||
# Patch vcpkg build instructions to add -pthread
|
||||
RUN <<EOF
|
||||
set -xe
|
||||
|
||||
echo '
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
||||
' >> /emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
|
||||
EOF
|
||||
|
||||
ENV VCPKG_DEFAULT_BINARY_CACHE /cache/vcpkg
|
||||
RUN --mount=type=cache,target=/cache <<EOF
|
||||
# Install dependencies with vcpkg
|
||||
set -xe
|
||||
|
||||
mkdir -p $VCPKG_DEFAULT_BINARY_CACHE
|
||||
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten libmagic
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten freetype
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten mbedtls
|
||||
EOF
|
||||
|
||||
# Build ImHex
|
||||
ARG JOBS=4
|
||||
ENV CCACHE_DIR /cache/ccache
|
||||
|
||||
RUN mkdir /build
|
||||
WORKDIR /build
|
||||
RUN --mount=type=cache,target=/cache \
|
||||
--mount=type=bind,source=.,target=/imhex <<EOF
|
||||
|
||||
set -xe
|
||||
ccache -zs
|
||||
|
||||
cmake /imhex \
|
||||
-DIMHEX_OFFLINE_BUILD=ON \
|
||||
-DIMHEX_STATIC_LINK_PLUGINS=ON \
|
||||
-DNATIVE_CMAKE_C_COMPILER=gcc \
|
||||
-DNATIVE_CMAKE_CXX_COMPILER=g++ \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake \
|
||||
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
make -j $JOBS
|
||||
|
||||
cp /imhex/dist/web/source/* /build
|
||||
ccache -s
|
||||
EOF
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build [ \
|
||||
# ImHex \
|
||||
"/build/imhex.wasm", \
|
||||
"/build/imhex.js", \
|
||||
"/build/imhex.worker.js", \
|
||||
\
|
||||
# Static files \
|
||||
"/build/index.html", \
|
||||
"/build/style.css", \
|
||||
"/build/wasm-config.js", \
|
||||
"/build/enable-threads.js", \
|
||||
"/build/favicon.ico", \
|
||||
"/build/icon.png", \
|
||||
"/build/manifest.json", \
|
||||
\
|
||||
# Destination \
|
||||
"./" \
|
||||
]
|
||||
11
dist/web/plugin-bundle.cpp.in
vendored
Normal file
11
dist/web/plugin-bundle.cpp.in
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
extern "C" void forceLinkPlugin_@IMHEX_PLUGIN_NAME@();
|
||||
|
||||
struct StaticLoad {
|
||||
StaticLoad() {
|
||||
forceLinkPlugin_@IMHEX_PLUGIN_NAME@();
|
||||
}
|
||||
};
|
||||
|
||||
static StaticLoad staticLoad;
|
||||
15
dist/web/serve.py
vendored
Normal file
15
dist/web/serve.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import http.server
|
||||
import os
|
||||
|
||||
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
|
||||
def end_headers(self):
|
||||
self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
|
||||
self.send_header("Cross-Origin-Opener-Policy", "same-origin")
|
||||
http.server.SimpleHTTPRequestHandler.end_headers(self)
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(".")
|
||||
httpd = http.server.HTTPServer(("localhost", 9090), MyHttpRequestHandler)
|
||||
print(f"Serving {os.getcwd()} on http://{httpd.server_address[0]}:{httpd.server_address[1]}")
|
||||
httpd.serve_forever()
|
||||
79
dist/web/source/enable-threads.js
vendored
Normal file
79
dist/web/source/enable-threads.js
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// NOTE: This file creates a service worker that cross-origin-isolates the page (read more here: https://web.dev/coop-coep/) which allows us to use wasm threads.
|
||||
// Normally you would set the COOP and COEP headers on the server to do this, but Github Pages doesn't allow this, so this is a hack to do that.
|
||||
|
||||
/* Edited version of: coi-serviceworker v0.1.6 - Guido Zuidhof, licensed under MIT */
|
||||
// From here: https://github.com/gzuidhof/coi-serviceworker
|
||||
if(typeof window === 'undefined') {
|
||||
self.addEventListener("install", () => self.skipWaiting());
|
||||
self.addEventListener("activate", e => e.waitUntil(self.clients.claim()));
|
||||
|
||||
async function handleFetch(request) {
|
||||
if(request.cache === "only-if-cached" && request.mode !== "same-origin") {
|
||||
return;
|
||||
}
|
||||
|
||||
if(request.mode === "no-cors") { // We need to set `credentials` to "omit" for no-cors requests, per this comment: https://bugs.chromium.org/p/chromium/issues/detail?id=1309901#c7
|
||||
request = new Request(request.url, {
|
||||
cache: request.cache,
|
||||
credentials: "omit",
|
||||
headers: request.headers,
|
||||
integrity: request.integrity,
|
||||
destination: request.destination,
|
||||
keepalive: request.keepalive,
|
||||
method: request.method,
|
||||
mode: request.mode,
|
||||
redirect: request.redirect,
|
||||
referrer: request.referrer,
|
||||
referrerPolicy: request.referrerPolicy,
|
||||
signal: request.signal,
|
||||
});
|
||||
}
|
||||
|
||||
let r = await fetch(request).catch(e => console.error(e));
|
||||
|
||||
if(r.status === 0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
const headers = new Headers(r.headers);
|
||||
headers.set("Cross-Origin-Embedder-Policy", "require-corp"); // or: require-corp
|
||||
headers.set("Cross-Origin-Opener-Policy", "same-origin");
|
||||
|
||||
return new Response(r.body, { status: r.status, statusText: r.statusText, headers });
|
||||
}
|
||||
|
||||
self.addEventListener("fetch", function(e) {
|
||||
e.respondWith(handleFetch(e.request)); // respondWith must be executed synchonously (but can be passed a Promise)
|
||||
});
|
||||
|
||||
} else {
|
||||
(async function() {
|
||||
if(window.crossOriginIsolated !== false) return;
|
||||
|
||||
if (!('serviceWorker' in navigator)) {
|
||||
alert("Your browser doesn't support service workers.\nIf you're using Firefox, you need to not be in a private window.")
|
||||
}
|
||||
|
||||
let registration = await navigator.serviceWorker.register(window.document.currentScript.src).catch(e => console.error("COOP/COEP Service Worker failed to register:", e));
|
||||
if(registration) {
|
||||
console.log("COOP/COEP Service Worker registered", registration.scope);
|
||||
|
||||
registration.addEventListener("updatefound", () => {
|
||||
console.log("Reloading page to make use of updated COOP/COEP Service Worker.");
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
// If the registration is active, but it's not controlling the page
|
||||
if(registration.active && !navigator.serviceWorker.controller) {
|
||||
console.log("Reloading page to make use of COOP/COEP Service Worker.");
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
// Code to deregister:
|
||||
// let registrations = await navigator.serviceWorker.getRegistrations();
|
||||
// for(let registration of registrations) {
|
||||
// await registration.unregister();
|
||||
// }
|
||||
BIN
dist/web/source/favicon.ico
vendored
Normal file
BIN
dist/web/source/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 157 KiB |
74
dist/web/source/index.html
vendored
Normal file
74
dist/web/source/index.html
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>ImHex Web - Online Hex Editor</title>
|
||||
<meta name="title" content="ImHex">
|
||||
<meta name="description" content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://imhex.werwolv.net/">
|
||||
<meta property="og:title" content="ImHex Web - Online Hex Editor">
|
||||
<meta property="og:description">
|
||||
<meta name="description" content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<meta property="og:image" content="https://imhex.werwolv.net/assets/splash_wasm.png">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:url" content="https://imhex.werwolv.net/">
|
||||
<meta property="twitter:title" content="ImHex Web - Online Hex Editor">
|
||||
<meta property="twitter:description"
|
||||
content="A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.">
|
||||
<meta property="twitter:image" content="https://imhex.werwolv.net/assets/splash_wasm.png">
|
||||
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"alumni": "WerWolv",
|
||||
"email": "hey@werwolv.net",
|
||||
"founder": "WerWolv",
|
||||
"slogan": "A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.",
|
||||
"url": "https://imhex.werwolv.net",
|
||||
"logo": "https://imhex.werwolv.net/assets/logos/logo.png"
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "SoftwareApplication",
|
||||
"name": "ImHex Web",
|
||||
"operatingSystem": "Windows, MacOS, Linux",
|
||||
"applicationCategory": "DeveloperApplication",
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"price": "0",
|
||||
"priceCurrency": "USD"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<title>ImHex Web</title>
|
||||
<script src="enable-threads.js"></script>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<p id="loading_text">ImHex is loading...</p>
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
|
||||
<script type="text/javascript" src="wasm-config.js"></script>
|
||||
<script async type="text/javascript" src="imhex.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
20
dist/web/source/manifest.json
vendored
Normal file
20
dist/web/source/manifest.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "ImHex",
|
||||
"description": "🔍 A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.",
|
||||
"background_color": "#0F0F0F",
|
||||
"theme_color": "#0F0F0F",
|
||||
"categories": [
|
||||
"education",
|
||||
"productivity",
|
||||
"utilities"
|
||||
],
|
||||
"icons": [
|
||||
{
|
||||
"src": "icon.png",
|
||||
"type": "image/png",
|
||||
"sizes": "640x640"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone"
|
||||
}
|
||||
36
dist/web/source/style.css
vendored
Normal file
36
dist/web/source/style.css
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #121212;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.emscripten {
|
||||
padding-right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
border: 0px none;
|
||||
}
|
||||
|
||||
.canvas_full_screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#loading_text {
|
||||
color: #F0F0F0;
|
||||
font-size: 30px;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
70
dist/web/source/wasm-config.js
vendored
Normal file
70
dist/web/source/wasm-config.js
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
function glfwSetCursorCustom(wnd, shape) {
|
||||
let body = document.getElementsByTagName("body")[0]
|
||||
switch (shape) {
|
||||
case 0x00036001: // GLFW_ARROW_CURSOR
|
||||
body.style.cursor = "default";
|
||||
break;
|
||||
case 0x00036002: // GLFW_IBEAM_CURSOR
|
||||
body.style.cursor = "text";
|
||||
break;
|
||||
case 0x00036003: // GLFW_CROSSHAIR_CURSOR
|
||||
body.style.cursor = "crosshair";
|
||||
break;
|
||||
case 0x00036004: // GLFW_HAND_CURSOR
|
||||
body.style.cursor = "pointer";
|
||||
break;
|
||||
case 0x00036005: // GLFW_HRESIZE_CURSOR
|
||||
body.style.cursor = "ew-resize";
|
||||
break;
|
||||
case 0x00036006: // GLFW_VRESIZE_CURSOR
|
||||
body.style.cursor = "ns-resize";
|
||||
break;
|
||||
default:
|
||||
body.style.cursor = "default";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function glfwCreateStandardCursorCustom(shape) {
|
||||
return shape
|
||||
}
|
||||
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
onRuntimeInitialized: function() {
|
||||
// Triggered when the wasm module is loaded and ready to use.
|
||||
document.getElementById("loading_text").style.display = "none"
|
||||
document.getElementById("canvas").style.display = "initial"
|
||||
},
|
||||
print: (function() { })(),
|
||||
printErr: function(text) { },
|
||||
canvas: (function() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
// As a default initial behavior, pop up an alert when webgl context is lost. To make your
|
||||
// application robust, you may want to override this behavior before shipping!
|
||||
// See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
|
||||
canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
|
||||
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) { },
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies: function(left) { },
|
||||
instantiateWasm: function(imports, successCallback) {
|
||||
imports.env.glfwSetCursor = glfwSetCursorCustom
|
||||
imports.env.glfwCreateStandardCursor = glfwCreateStandardCursorCustom
|
||||
instantiateAsync(wasmBinary, wasmBinaryFile, imports, (result) => successCallback(result.instance, result.module));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
window.addEventListener('resize', js_resizeCanvas, false);
|
||||
function js_resizeCanvas() {
|
||||
let canvas = document.getElementById('canvas');
|
||||
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 0);
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
|
||||
canvas.classList.add("canvas_full_screen")
|
||||
}
|
||||
1
lib/external/capstone
vendored
1
lib/external/capstone
vendored
Submodule lib/external/capstone deleted from d5141c0478
1
lib/external/curl
vendored
1
lib/external/curl
vendored
Submodule lib/external/curl deleted from c12fb3ddaf
1
lib/external/fmt
vendored
1
lib/external/fmt
vendored
Submodule lib/external/fmt deleted from a33701196a
42
lib/external/imgui/CMakeLists.txt
vendored
42
lib/external/imgui/CMakeLists.txt
vendored
@@ -1,42 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(imgui)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
pkg_search_module(GLFW REQUIRED glfw3)
|
||||
|
||||
add_library(imgui OBJECT
|
||||
source/imgui.cpp
|
||||
source/imgui_demo.cpp
|
||||
source/imgui_draw.cpp
|
||||
source/imgui_freetype.cpp
|
||||
source/imgui_impl_glfw.cpp
|
||||
source/imgui_impl_opengl3.cpp
|
||||
source/imgui_tables.cpp
|
||||
source/imgui_widgets.cpp
|
||||
|
||||
source/cimgui.cpp
|
||||
|
||||
source/TextEditor.cpp
|
||||
|
||||
source/imnodes.cpp
|
||||
|
||||
source/implot.cpp
|
||||
source/implot_items.cpp
|
||||
source/implot_demo.cpp
|
||||
|
||||
source/fonts/fontawesome_font.c
|
||||
source/fonts/codicons_font.c
|
||||
source/fonts/unifont_font.c
|
||||
)
|
||||
|
||||
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
|
||||
target_include_directories(imgui PUBLIC include ${FREETYPE_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS} ${OpenGL_INCLUDE_DIRS})
|
||||
|
||||
target_link_directories(imgui PUBLIC ${GLFW_LIBRARY_DIRS} ${OpenGL_LIBRARY_DIRS})
|
||||
|
||||
target_link_libraries(imgui PUBLIC Freetype::Freetype ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
1980
lib/external/imgui/include/cimgui.h
vendored
1980
lib/external/imgui/include/cimgui.h
vendored
File diff suppressed because it is too large
Load Diff
7897
lib/external/imgui/include/stb_image.h
vendored
7897
lib/external/imgui/include/stb_image.h
vendored
File diff suppressed because it is too large
Load Diff
2746
lib/external/imgui/source/cimgui.cpp
vendored
2746
lib/external/imgui/source/cimgui.cpp
vendored
File diff suppressed because it is too large
Load Diff
1095
lib/external/imgui/source/fonts/codicons_font.c
vendored
1095
lib/external/imgui/source/fonts/codicons_font.c
vendored
File diff suppressed because it is too large
Load Diff
3025
lib/external/imgui/source/fonts/fontawesome_font.c
vendored
3025
lib/external/imgui/source/fonts/fontawesome_font.c
vendored
File diff suppressed because it is too large
Load Diff
116170
lib/external/imgui/source/fonts/unifont_font.c
vendored
116170
lib/external/imgui/source/fonts/unifont_font.c
vendored
File diff suppressed because it is too large
Load Diff
2428
lib/external/imgui/source/implot_items.cpp
vendored
2428
lib/external/imgui/source/implot_items.cpp
vendored
File diff suppressed because it is too large
Load Diff
9
lib/external/intervaltree/CMakeLists.txt
vendored
9
lib/external/intervaltree/CMakeLists.txt
vendored
@@ -1,9 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(intervaltree)
|
||||
|
||||
set(CMAKE_CXX_STANDARD20)
|
||||
|
||||
add_library(intervaltree INTERFACE)
|
||||
|
||||
target_include_directories(intervaltree INTERFACE include)
|
||||
target_compile_options(intervaltree INTERFACE "-DUSE_INTERVAL_TREE_NAMESPACE")
|
||||
37
lib/external/intervaltree/README.md
vendored
37
lib/external/intervaltree/README.md
vendored
@@ -1,37 +0,0 @@
|
||||
# intervaltree
|
||||
|
||||
## Overview
|
||||
|
||||
An interval tree can be used to efficiently find a set of numeric intervals overlapping or containing another interval.
|
||||
|
||||
This library provides a basic implementation of an interval tree using C++ templates, allowing the insertion of arbitrary types into the tree.
|
||||
|
||||
## Usage
|
||||
|
||||
Add `#include "IntervalTree.h"` to the source files in which you will use the interval tree.
|
||||
|
||||
To make an IntervalTree to contain objects of class T, use:
|
||||
|
||||
```c++
|
||||
vector<Interval<T> > intervals;
|
||||
T a, b, c;
|
||||
intervals.push_back(Interval<T>(2, 10, a));
|
||||
intervals.push_back(Interval<T>(3, 4, b));
|
||||
intervals.push_back(Interval<T>(20, 100, c));
|
||||
IntervalTree<T> tree;
|
||||
tree = IntervalTree<T>(intervals);
|
||||
```
|
||||
|
||||
Now, it's possible to query the tree and obtain a set of intervals which are contained within the start and stop coordinates.
|
||||
|
||||
```c++
|
||||
vector<Interval<T> > results;
|
||||
tree.findContained(start, stop, results);
|
||||
cout << "found " << results.size() << " overlapping intervals" << endl;
|
||||
```
|
||||
|
||||
The function IntervalTree::findOverlapping provides a method to find all those intervals which are contained or partially overlap the interval (start, stop).
|
||||
|
||||
### Author: Erik Garrison <erik.garrison@gmail.com>
|
||||
|
||||
### License: MIT
|
||||
325
lib/external/intervaltree/include/IntervalTree.h
vendored
325
lib/external/intervaltree/include/IntervalTree.h
vendored
@@ -1,325 +0,0 @@
|
||||
#ifndef __INTERVAL_TREE_H
|
||||
#define __INTERVAL_TREE_H
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
#ifdef USE_INTERVAL_TREE_NAMESPACE
|
||||
namespace interval_tree {
|
||||
#endif
|
||||
template <class Scalar, typename Value>
|
||||
class Interval {
|
||||
public:
|
||||
Scalar start;
|
||||
Scalar stop;
|
||||
Value value;
|
||||
Interval(const Scalar& s, const Scalar& e, const Value& v)
|
||||
: start(std::min(s, e))
|
||||
, stop(std::max(s, e))
|
||||
, value(v)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
Value intervalStart(const Interval<Scalar,Value>& i) {
|
||||
return i.start;
|
||||
}
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
Value intervalStop(const Interval<Scalar, Value>& i) {
|
||||
return i.stop;
|
||||
}
|
||||
|
||||
template <class Scalar, typename Value>
|
||||
std::ostream& operator<<(std::ostream& out, const Interval<Scalar, Value>& i) {
|
||||
out << "Interval(" << i.start << ", " << i.stop << "): " << i.value;
|
||||
return out;
|
||||
}
|
||||
|
||||
template <class Scalar, class Value>
|
||||
class IntervalTree {
|
||||
public:
|
||||
typedef Interval<Scalar, Value> interval;
|
||||
typedef std::vector<interval> interval_vector;
|
||||
|
||||
|
||||
struct IntervalStartCmp {
|
||||
bool operator()(const interval& a, const interval& b) {
|
||||
return a.start < b.start;
|
||||
}
|
||||
};
|
||||
|
||||
struct IntervalStopCmp {
|
||||
bool operator()(const interval& a, const interval& b) {
|
||||
return a.stop < b.stop;
|
||||
}
|
||||
};
|
||||
|
||||
IntervalTree()
|
||||
: left(nullptr)
|
||||
, right(nullptr)
|
||||
, center(0)
|
||||
{}
|
||||
|
||||
~IntervalTree() = default;
|
||||
|
||||
std::unique_ptr<IntervalTree> clone() const {
|
||||
return std::unique_ptr<IntervalTree>(new IntervalTree(*this));
|
||||
}
|
||||
|
||||
IntervalTree(const IntervalTree& other)
|
||||
: intervals(other.intervals),
|
||||
left(other.left ? other.left->clone() : nullptr),
|
||||
right(other.right ? other.right->clone() : nullptr),
|
||||
center(other.center)
|
||||
{}
|
||||
|
||||
IntervalTree& operator=(IntervalTree&&) = default;
|
||||
IntervalTree(IntervalTree&&) = default;
|
||||
|
||||
IntervalTree& operator=(const IntervalTree& other) {
|
||||
center = other.center;
|
||||
intervals = other.intervals;
|
||||
left = other.left ? other.left->clone() : nullptr;
|
||||
right = other.right ? other.right->clone() : nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IntervalTree(
|
||||
interval_vector&& ivals,
|
||||
std::size_t depth = 16,
|
||||
std::size_t minbucket = 64,
|
||||
std::size_t maxbucket = 512,
|
||||
Scalar leftextent = 0,
|
||||
Scalar rightextent = 0)
|
||||
: left(nullptr)
|
||||
, right(nullptr)
|
||||
{
|
||||
--depth;
|
||||
const auto minmaxStop = std::minmax_element(ivals.begin(), ivals.end(),
|
||||
IntervalStopCmp());
|
||||
const auto minmaxStart = std::minmax_element(ivals.begin(), ivals.end(),
|
||||
IntervalStartCmp());
|
||||
if (!ivals.empty()) {
|
||||
center = (minmaxStart.first->start + minmaxStop.second->stop) / 2;
|
||||
}
|
||||
if (leftextent == 0 && rightextent == 0) {
|
||||
// sort intervals by start
|
||||
std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
|
||||
} else {
|
||||
assert(std::is_sorted(ivals.begin(), ivals.end(), IntervalStartCmp()));
|
||||
}
|
||||
if (depth == 0 || (ivals.size() < minbucket && ivals.size() < maxbucket)) {
|
||||
std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
|
||||
intervals = std::move(ivals);
|
||||
assert(is_valid().first);
|
||||
return;
|
||||
} else {
|
||||
Scalar leftp = 0;
|
||||
Scalar rightp = 0;
|
||||
|
||||
if (leftextent || rightextent) {
|
||||
leftp = leftextent;
|
||||
rightp = rightextent;
|
||||
} else {
|
||||
leftp = ivals.front().start;
|
||||
rightp = std::max_element(ivals.begin(), ivals.end(),
|
||||
IntervalStopCmp())->stop;
|
||||
}
|
||||
|
||||
interval_vector lefts;
|
||||
interval_vector rights;
|
||||
|
||||
for (typename interval_vector::const_iterator i = ivals.begin();
|
||||
i != ivals.end(); ++i) {
|
||||
const interval& interval = *i;
|
||||
if (interval.stop < center) {
|
||||
lefts.push_back(interval);
|
||||
} else if (interval.start > center) {
|
||||
rights.push_back(interval);
|
||||
} else {
|
||||
assert(interval.start <= center);
|
||||
assert(center <= interval.stop);
|
||||
intervals.push_back(interval);
|
||||
}
|
||||
}
|
||||
|
||||
if (!lefts.empty()) {
|
||||
left.reset(new IntervalTree(std::move(lefts),
|
||||
depth, minbucket, maxbucket,
|
||||
leftp, center));
|
||||
}
|
||||
if (!rights.empty()) {
|
||||
right.reset(new IntervalTree(std::move(rights),
|
||||
depth, minbucket, maxbucket,
|
||||
center, rightp));
|
||||
}
|
||||
}
|
||||
assert(is_valid().first);
|
||||
}
|
||||
|
||||
// Call f on all intervals near the range [start, stop]:
|
||||
template <class UnaryFunction>
|
||||
void visit_near(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
if (!intervals.empty() && ! (stop < intervals.front().start)) {
|
||||
for (auto & i : intervals) {
|
||||
f(i);
|
||||
}
|
||||
}
|
||||
if (left && start <= center) {
|
||||
left->visit_near(start, stop, f);
|
||||
}
|
||||
if (right && stop >= center) {
|
||||
right->visit_near(start, stop, f);
|
||||
}
|
||||
}
|
||||
|
||||
// Call f on all intervals crossing pos
|
||||
template <class UnaryFunction>
|
||||
void visit_overlapping(const Scalar& pos, UnaryFunction f) const {
|
||||
visit_overlapping(pos, pos, f);
|
||||
}
|
||||
|
||||
// Call f on all intervals overlapping [start, stop]
|
||||
template <class UnaryFunction>
|
||||
void visit_overlapping(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
auto filterF = [&](const interval& interval) {
|
||||
if (interval.stop >= start && interval.start <= stop) {
|
||||
// Only apply f if overlapping
|
||||
f(interval);
|
||||
}
|
||||
};
|
||||
visit_near(start, stop, filterF);
|
||||
}
|
||||
|
||||
// Call f on all intervals contained within [start, stop]
|
||||
template <class UnaryFunction>
|
||||
void visit_contained(const Scalar& start, const Scalar& stop, UnaryFunction f) const {
|
||||
auto filterF = [&](const interval& interval) {
|
||||
if (start <= interval.start && interval.stop <= stop) {
|
||||
f(interval);
|
||||
}
|
||||
};
|
||||
visit_near(start, stop, filterF);
|
||||
}
|
||||
|
||||
interval_vector findOverlapping(const Scalar& start, const Scalar& stop) const {
|
||||
interval_vector result;
|
||||
visit_overlapping(start, stop,
|
||||
[&](const interval& interval) {
|
||||
result.emplace_back(interval);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
interval_vector findContained(const Scalar& start, const Scalar& stop) const {
|
||||
interval_vector result;
|
||||
visit_contained(start, stop,
|
||||
[&](const interval& interval) {
|
||||
result.push_back(interval);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
bool empty() const {
|
||||
if (left && !left->empty()) {
|
||||
return false;
|
||||
}
|
||||
if (!intervals.empty()) {
|
||||
return false;
|
||||
}
|
||||
if (right && !right->empty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class UnaryFunction>
|
||||
void visit_all(UnaryFunction f) const {
|
||||
if (left) {
|
||||
left->visit_all(f);
|
||||
}
|
||||
std::for_each(intervals.begin(), intervals.end(), f);
|
||||
if (right) {
|
||||
right->visit_all(f);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<Scalar, Scalar> extentBruitForce() const {
|
||||
struct Extent {
|
||||
std::pair<Scalar, Scalar> x = {std::numeric_limits<Scalar>::max(),
|
||||
std::numeric_limits<Scalar>::min() };
|
||||
void operator()(const interval & interval) {
|
||||
x.first = std::min(x.first, interval.start);
|
||||
x.second = std::max(x.second, interval.stop);
|
||||
}
|
||||
};
|
||||
Extent extent;
|
||||
|
||||
visit_all([&](const interval & interval) { extent(interval); });
|
||||
return extent.x;
|
||||
}
|
||||
|
||||
// Check all constraints.
|
||||
// If first is false, second is invalid.
|
||||
std::pair<bool, std::pair<Scalar, Scalar>> is_valid() const {
|
||||
const auto minmaxStop = std::minmax_element(intervals.begin(), intervals.end(),
|
||||
IntervalStopCmp());
|
||||
const auto minmaxStart = std::minmax_element(intervals.begin(), intervals.end(),
|
||||
IntervalStartCmp());
|
||||
|
||||
std::pair<bool, std::pair<Scalar, Scalar>> result = {true, { std::numeric_limits<Scalar>::max(),
|
||||
std::numeric_limits<Scalar>::min() }};
|
||||
if (!intervals.empty()) {
|
||||
result.second.first = std::min(result.second.first, minmaxStart.first->start);
|
||||
result.second.second = std::min(result.second.second, minmaxStop.second->stop);
|
||||
}
|
||||
if (left) {
|
||||
auto valid = left->is_valid();
|
||||
result.first &= valid.first;
|
||||
result.second.first = std::min(result.second.first, valid.second.first);
|
||||
result.second.second = std::min(result.second.second, valid.second.second);
|
||||
if (!result.first) { return result; }
|
||||
if (valid.second.second >= center) {
|
||||
result.first = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (right) {
|
||||
auto valid = right->is_valid();
|
||||
result.first &= valid.first;
|
||||
result.second.first = std::min(result.second.first, valid.second.first);
|
||||
result.second.second = std::min(result.second.second, valid.second.second);
|
||||
if (!result.first) { return result; }
|
||||
if (valid.second.first <= center) {
|
||||
result.first = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (!std::is_sorted(intervals.begin(), intervals.end(), IntervalStartCmp())) {
|
||||
result.first = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
left.reset();
|
||||
right.reset();
|
||||
intervals.clear();
|
||||
center = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
interval_vector intervals;
|
||||
std::unique_ptr<IntervalTree> left;
|
||||
std::unique_ptr<IntervalTree> right;
|
||||
Scalar center;
|
||||
};
|
||||
#ifdef USE_INTERVAL_TREE_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: 40cd303e92...04ba8ba5cd
1
lib/external/libwolv
vendored
Submodule
1
lib/external/libwolv
vendored
Submodule
Submodule lib/external/libwolv added at e4891c89b6
@@ -1,122 +0,0 @@
|
||||
//===--- StringView.h ----------------*- mode:c++;eval:(read-only-mode) -*-===//
|
||||
// Do not edit! See README.txt.
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// FIXME: Use std::string_view instead when we support C++17.
|
||||
// There are two copies of this file in the source tree. The one under
|
||||
// libcxxabi is the original and the one under llvm is the copy. Use
|
||||
// cp-to-llvm.sh to update the copy. See README.txt for more details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_STRINGVIEW_H
|
||||
#define LLVM_DEMANGLE_STRINGVIEW_H
|
||||
|
||||
#include "DemangleConfig.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
DEMANGLE_NAMESPACE_BEGIN
|
||||
|
||||
class StringView {
|
||||
const char *First;
|
||||
const char *Last;
|
||||
|
||||
public:
|
||||
static const size_t npos = ~size_t(0);
|
||||
|
||||
template <size_t N>
|
||||
StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
|
||||
StringView(const char *First_, const char *Last_)
|
||||
: First(First_), Last(Last_) {}
|
||||
StringView(const char *First_, size_t Len)
|
||||
: First(First_), Last(First_ + Len) {}
|
||||
StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
|
||||
StringView() : First(nullptr), Last(nullptr) {}
|
||||
|
||||
StringView substr(size_t Pos, size_t Len = npos) const {
|
||||
assert(Pos <= size());
|
||||
if (Len > size() - Pos)
|
||||
Len = size() - Pos;
|
||||
return StringView(begin() + Pos, Len);
|
||||
}
|
||||
|
||||
size_t find(char C, size_t From = 0) const {
|
||||
// Avoid calling memchr with nullptr.
|
||||
if (From < size()) {
|
||||
// Just forward to memchr, which is faster than a hand-rolled loop.
|
||||
if (const void *P = ::memchr(First + From, C, size() - From))
|
||||
return size_t(static_cast<const char *>(P) - First);
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
StringView dropFront(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First + N, Last);
|
||||
}
|
||||
|
||||
StringView dropBack(size_t N = 1) const {
|
||||
if (N >= size())
|
||||
N = size();
|
||||
return StringView(First, Last - N);
|
||||
}
|
||||
|
||||
char front() const {
|
||||
assert(!empty());
|
||||
return *begin();
|
||||
}
|
||||
|
||||
char back() const {
|
||||
assert(!empty());
|
||||
return *(end() - 1);
|
||||
}
|
||||
|
||||
char popFront() {
|
||||
assert(!empty());
|
||||
return *First++;
|
||||
}
|
||||
|
||||
bool consumeFront(char C) {
|
||||
if (!startsWith(C))
|
||||
return false;
|
||||
*this = dropFront(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool consumeFront(StringView S) {
|
||||
if (!startsWith(S))
|
||||
return false;
|
||||
*this = dropFront(S.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool startsWith(char C) const { return !empty() && *begin() == C; }
|
||||
|
||||
bool startsWith(StringView Str) const {
|
||||
if (Str.size() > size())
|
||||
return false;
|
||||
return std::strncmp(Str.begin(), begin(), Str.size()) == 0;
|
||||
}
|
||||
|
||||
const char &operator[](size_t Idx) const { return *(begin() + Idx); }
|
||||
|
||||
const char *begin() const { return First; }
|
||||
const char *end() const { return Last; }
|
||||
size_t size() const { return static_cast<size_t>(Last - First); }
|
||||
bool empty() const { return First == Last; }
|
||||
};
|
||||
|
||||
inline bool operator==(const StringView &LHS, const StringView &RHS) {
|
||||
return LHS.size() == RHS.size() &&
|
||||
std::strncmp(LHS.begin(), RHS.begin(), LHS.size()) == 0;
|
||||
}
|
||||
|
||||
DEMANGLE_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
7509
lib/external/miniaudio/include/miniaudio.h
vendored
7509
lib/external/miniaudio/include/miniaudio.h
vendored
File diff suppressed because it is too large
Load Diff
1
lib/external/nativefiledialog
vendored
1
lib/external/nativefiledialog
vendored
Submodule lib/external/nativefiledialog deleted from 6efc824070
@@ -1,78 +0,0 @@
|
||||
#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
|
||||
#include <cstdint> // int64_t, uint64_t
|
||||
#include <map> // map
|
||||
#include <memory> // allocator
|
||||
#include <string> // string
|
||||
#include <vector> // vector
|
||||
|
||||
/*!
|
||||
@brief namespace for Niels Lohmann
|
||||
@see https://github.com/nlohmann
|
||||
@since version 1.0.0
|
||||
*/
|
||||
namespace nlohmann
|
||||
{
|
||||
/*!
|
||||
@brief default JSONSerializer template argument
|
||||
|
||||
This serializer ignores the template arguments and uses ADL
|
||||
([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
|
||||
for serialization.
|
||||
*/
|
||||
template<typename T = void, typename SFINAE = void>
|
||||
struct adl_serializer;
|
||||
|
||||
template<template<typename U, typename V, typename... Args> class ObjectType =
|
||||
std::map,
|
||||
template<typename U, typename... Args> class ArrayType = std::vector,
|
||||
class StringType = std::string, class BooleanType = bool,
|
||||
class NumberIntegerType = std::int64_t,
|
||||
class NumberUnsignedType = std::uint64_t,
|
||||
class NumberFloatType = double,
|
||||
template<typename U> class AllocatorType = std::allocator,
|
||||
template<typename T, typename SFINAE = void> class JSONSerializer =
|
||||
adl_serializer,
|
||||
class BinaryType = std::vector<std::uint8_t>>
|
||||
class basic_json;
|
||||
|
||||
/*!
|
||||
@brief JSON Pointer
|
||||
|
||||
A JSON pointer defines a string syntax for identifying a specific value
|
||||
within a JSON document. It can be used with functions `at` and
|
||||
`operator[]`. Furthermore, JSON pointers are the base for JSON patches.
|
||||
|
||||
@sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
|
||||
|
||||
@since version 2.0.0
|
||||
*/
|
||||
template<typename BasicJsonType>
|
||||
class json_pointer;
|
||||
|
||||
/*!
|
||||
@brief default JSON class
|
||||
|
||||
This type is the default specialization of the @ref basic_json class which
|
||||
uses the standard template types.
|
||||
|
||||
@since version 1.0.0
|
||||
*/
|
||||
using json = basic_json<>;
|
||||
|
||||
template<class Key, class T, class IgnoredLess, class Allocator>
|
||||
struct ordered_map;
|
||||
|
||||
/*!
|
||||
@brief ordered JSON class
|
||||
|
||||
This type preserves the insertion order of object keys.
|
||||
|
||||
@since version 3.9.0
|
||||
*/
|
||||
using ordered_json = basic_json<nlohmann::ordered_map>;
|
||||
|
||||
} // namespace nlohmann
|
||||
|
||||
#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
|
||||
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 565df62329...b5de2d2f8a
1
lib/external/yara/yara
vendored
1
lib/external/yara/yara
vendored
Submodule lib/external/yara/yara deleted from ba94b4f8eb
@@ -5,39 +5,47 @@ set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
|
||||
set(LIBIMHEX_SOURCES
|
||||
source/api/event.cpp
|
||||
source/api/imhex_api.cpp
|
||||
source/api/content_registry.cpp
|
||||
source/api/task.cpp
|
||||
source/api/keybinding.cpp
|
||||
source/api/plugin_manager.cpp
|
||||
source/api/localization.cpp
|
||||
source/api/project_file_manager.cpp
|
||||
source/api/theme_manager.cpp
|
||||
source/api/imhex_api.cpp
|
||||
source/api/content_registry.cpp
|
||||
source/api/event_manager.cpp
|
||||
source/api/task_manager.cpp
|
||||
source/api/shortcut_manager.cpp
|
||||
source/api/plugin_manager.cpp
|
||||
source/api/project_file_manager.cpp
|
||||
source/api/theme_manager.cpp
|
||||
source/api/layout_manager.cpp
|
||||
source/api/achievement_manager.cpp
|
||||
source/api/localization_manager.cpp
|
||||
|
||||
source/data_processor/attribute.cpp
|
||||
source/data_processor/link.cpp
|
||||
source/data_processor/node.cpp
|
||||
source/data_processor/attribute.cpp
|
||||
source/data_processor/link.cpp
|
||||
source/data_processor/node.cpp
|
||||
|
||||
source/helpers/utils.cpp
|
||||
source/helpers/fs.cpp
|
||||
source/helpers/magic.cpp
|
||||
source/helpers/crypto.cpp
|
||||
source/helpers/net.cpp
|
||||
source/helpers/opengl.cpp
|
||||
source/helpers/file.cpp
|
||||
source/helpers/socket.cpp
|
||||
source/helpers/patches.cpp
|
||||
source/helpers/encoding_file.cpp
|
||||
source/helpers/logger.cpp
|
||||
source/helpers/stacktrace.cpp
|
||||
source/helpers/tar.cpp
|
||||
source/helpers/utils.cpp
|
||||
source/helpers/utils_linux.cpp
|
||||
source/helpers/fs.cpp
|
||||
source/helpers/magic.cpp
|
||||
source/helpers/crypto.cpp
|
||||
source/helpers/http_requests.cpp
|
||||
source/helpers/http_requests_native.cpp
|
||||
source/helpers/http_requests_emscripten.cpp
|
||||
source/helpers/opengl.cpp
|
||||
source/helpers/patches.cpp
|
||||
source/helpers/encoding_file.cpp
|
||||
source/helpers/logger.cpp
|
||||
source/helpers/stacktrace.cpp
|
||||
source/helpers/tar.cpp
|
||||
source/helpers/debugging.cpp
|
||||
|
||||
source/providers/provider.cpp
|
||||
source/providers/provider.cpp
|
||||
source/providers/undo/stack.cpp
|
||||
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
source/ui/view.cpp
|
||||
)
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
source/ui/view.cpp
|
||||
source/ui/popup.cpp
|
||||
|
||||
source/subcommands/subcommands.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
set(OSX_11_0_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk)
|
||||
@@ -49,22 +57,36 @@ if (APPLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES}
|
||||
source/helpers/fs_macos.m
|
||||
source/helpers/utils_macos.m)
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/utils_macos.m)
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
|
||||
add_library(libimhex SHARED ${LIBIMHEX_SOURCES})
|
||||
if (IMHEX_STATIC_LINK_PLUGINS)
|
||||
add_library(libimhex STATIC ${LIBIMHEX_SOURCES})
|
||||
else()
|
||||
add_library(libimhex SHARED ${LIBIMHEX_SOURCES})
|
||||
endif()
|
||||
|
||||
set_target_properties(libimhex PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
setupCompilerWarnings(libimhex)
|
||||
enableUnityBuild(libimhex)
|
||||
setupCompilerFlags(libimhex)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(libimhex)
|
||||
|
||||
target_include_directories(libimhex PUBLIC include ${XDGPP_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${YARA_INCLUDE_DIRS} ${LIBBACKTRACE_INCLUDE_DIRS})
|
||||
target_include_directories(libimhex PUBLIC include ${XDGPP_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIR} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${YARA_INCLUDE_DIRS} ${LIBBACKTRACE_INCLUDE_DIRS})
|
||||
target_link_directories(libimhex PUBLIC ${MBEDTLS_LIBRARY_DIR} ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
|
||||
|
||||
if (NOT EMSCRIPTEN)
|
||||
# curl is only used in non-emscripten builds
|
||||
target_include_directories(libimhex PUBLIC ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(libimhex PUBLIC ${LIBCURL_LIBRARIES})
|
||||
endif()
|
||||
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(libimhex PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
target_link_options(libimhex PRIVATE -Wl,--export-all-symbols)
|
||||
elseif (APPLE)
|
||||
find_library(FOUNDATION NAMES Foundation)
|
||||
@@ -72,4 +94,48 @@ elseif (APPLE)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(libimhex PRIVATE ${FMT_LIBRARIES})
|
||||
target_link_libraries(libimhex PUBLIC dl imgui ${NFD_LIBRARIES} magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${LIBCURL_LIBRARIES} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} libpl intervaltree ${MINIAUDIO_LIBRARIES})
|
||||
target_link_libraries(libimhex PUBLIC dl ${IMGUI_LIBRARIES} ${NFD_LIBRARIES} magic ${CAPSTONE_LIBRARIES} LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} plcli libpl libpl-gen ${MINIAUDIO_LIBRARIES} ${JTHREAD_LIBRARIES} wolv::utils wolv::io wolv::hash wolv::net wolv::containers wolv::math_eval)
|
||||
|
||||
set_property(TARGET libimhex PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||
|
||||
if (DEFINED IMHEX_COMMIT_HASH_LONG AND DEFINED IMHEX_COMMIT_HASH_SHORT AND DEFINED IMHEX_COMMIT_BRANCH)
|
||||
set(GIT_COMMIT_HASH_LONG "${IMHEX_COMMIT_HASH_LONG}")
|
||||
set(GIT_COMMIT_HASH_SHORT "${IMHEX_COMMIT_HASH_SHORT}")
|
||||
set(GIT_BRANCH "${IMHEX_COMMIT_BRANCH}")
|
||||
else()
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_BRANCH
|
||||
)
|
||||
|
||||
# Get the latest abbreviated commit hash of the working branch
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%h --abbrev=7
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH_SHORT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_HASH_SHORT
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%H
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH_LONG
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_HASH_LONG
|
||||
)
|
||||
endif ()
|
||||
|
||||
if ((NOT GIT_COMMIT_HASH_SHORT STREQUAL "") AND (NOT GIT_COMMIT_HASH_LONG STREQUAL "") AND (NOT GIT_BRANCH STREQUAL ""))
|
||||
addDefineToSource(source/api/imhex_api.cpp "GIT_COMMIT_HASH_SHORT=\"${GIT_COMMIT_HASH_SHORT}\"")
|
||||
addDefineToSource(source/api/imhex_api.cpp "GIT_COMMIT_HASH_LONG=\"${GIT_COMMIT_HASH_LONG}\"")
|
||||
addDefineToSource(source/api/imhex_api.cpp "GIT_BRANCH=\"${GIT_BRANCH}\"")
|
||||
endif ()
|
||||
|
||||
addDefineToSource(source/api/imhex_api.cpp "IMHEX_VERSION=\"${IMHEX_VERSION_STRING}\"")
|
||||
|
||||
add_dependencies(imhex_all libimhex)
|
||||
@@ -1,7 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/helpers/types.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
constexpr static const auto ImHexApiURL = "https://api.werwolv.net/imhex";
|
||||
constexpr static const auto GitHubApiURL = "https://api.github.com/repos/WerWolv/ImHex";
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
420
lib/libimhex/include/hex/api/achievement_manager.hpp
Normal file
420
lib/libimhex/include/hex/api/achievement_manager.hpp
Normal file
@@ -0,0 +1,420 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class AchievementManager;
|
||||
|
||||
class Achievement {
|
||||
public:
|
||||
explicit Achievement(std::string unlocalizedCategory, std::string unlocalizedName) : m_unlocalizedCategory(std::move(unlocalizedCategory)), m_unlocalizedName(std::move(unlocalizedName)) { }
|
||||
|
||||
/**
|
||||
* @brief Returns the unlocalized name of the achievement
|
||||
* @return Unlocalized name of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the unlocalized category of the achievement
|
||||
* @return Unlocalized category of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::string &getUnlocalizedCategory() const {
|
||||
return this->m_unlocalizedCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether the achievement is unlocked
|
||||
* @return Whether the achievement is unlocked
|
||||
*/
|
||||
[[nodiscard]] bool isUnlocked() const {
|
||||
return this->m_progress == this->m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the description of the achievement
|
||||
* @param description Description of the achievement
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setDescription(std::string description) {
|
||||
this->m_unlocalizedDescription = std::move(description);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a requirement to the achievement. The achievement will only be unlockable if all requirements are unlocked.
|
||||
* @param requirement Unlocalized name of the requirement
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addRequirement(std::string requirement) {
|
||||
this->m_requirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a visibility requirement to the achievement. The achievement will only be visible if all requirements are unlocked.
|
||||
* @param requirement Unlocalized name of the requirement
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addVisibilityRequirement(std::string requirement) {
|
||||
this->m_visibilityRequirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the achievement as blacked. Blacked achievements are visible but their name and description are hidden.
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setBlacked() {
|
||||
this->m_blacked = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the achievement as invisible. Invisible achievements are not visible at all.
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setInvisible() {
|
||||
this->m_invisible = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether the achievement is blacked
|
||||
* @return Whether the achievement is blacked
|
||||
*/
|
||||
[[nodiscard]] bool isBlacked() const {
|
||||
return this->m_blacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether the achievement is invisible
|
||||
* @return Whether the achievement is invisible
|
||||
*/
|
||||
[[nodiscard]] bool isInvisible() const {
|
||||
return this->m_invisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the list of requirements of the achievement
|
||||
* @return List of requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getRequirements() const {
|
||||
return this->m_requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the list of visibility requirements of the achievement
|
||||
* @return List of visibility requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getVisibilityRequirements() const {
|
||||
return this->m_visibilityRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the unlocalized description of the achievement
|
||||
* @return Unlocalized description of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::string &getUnlocalizedDescription() const {
|
||||
return this->m_unlocalizedDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the icon of the achievement
|
||||
* @return Icon of the achievement
|
||||
*/
|
||||
[[nodiscard]] const ImGuiExt::Texture &getIcon() const {
|
||||
if (this->m_iconData.empty())
|
||||
return this->m_icon;
|
||||
|
||||
if (this->m_icon.isValid())
|
||||
return m_icon;
|
||||
|
||||
this->m_icon = ImGuiExt::Texture(this->m_iconData.data(), this->m_iconData.size());
|
||||
|
||||
return this->m_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const std::byte> data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const u8> data) {
|
||||
this->m_iconData.assign(data.begin(), data.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::vector<u8> data) {
|
||||
this->m_iconData = std::move(data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon of the achievement
|
||||
* @param data Icon data
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(const std::vector<std::byte> &data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specifies the required progress to unlock the achievement. This is the number of times this achievement has to be triggered to unlock it. The default is 1.
|
||||
* @param progress Required progress
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setRequiredProgress(u32 progress) {
|
||||
this->m_maxProgress = progress;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the required progress to unlock the achievement
|
||||
* @return Required progress to unlock the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getRequiredProgress() const {
|
||||
return this->m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the current progress of the achievement
|
||||
* @return Current progress of the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getProgress() const {
|
||||
return this->m_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the callback to call when the achievement is clicked
|
||||
* @param callback Callback to call when the achievement is clicked
|
||||
*/
|
||||
void setClickCallback(const std::function<void(Achievement &)> &callback) {
|
||||
this->m_clickCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the callback to call when the achievement is clicked
|
||||
* @return Callback to call when the achievement is clicked
|
||||
*/
|
||||
[[nodiscard]] const std::function<void(Achievement &)> &getClickCallback() const {
|
||||
return this->m_clickCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether the achievement is temporary. Temporary achievements have been added by challenge projects for example and will be removed when the project is closed.
|
||||
* @return Whether the achievement is temporary
|
||||
*/
|
||||
[[nodiscard]] bool isTemporary() const {
|
||||
return this->m_temporary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets whether the achievement is unlocked
|
||||
* @param unlocked Whether the achievement is unlocked
|
||||
*/
|
||||
void setUnlocked(bool unlocked) {
|
||||
if (unlocked) {
|
||||
if (this->m_progress < this->m_maxProgress)
|
||||
this->m_progress++;
|
||||
} else {
|
||||
this->m_progress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void setProgress(u32 progress) {
|
||||
this->m_progress = progress;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedCategory, m_unlocalizedName;
|
||||
std::string m_unlocalizedDescription;
|
||||
|
||||
bool m_blacked = false;
|
||||
bool m_invisible = false;
|
||||
std::vector<std::string> m_requirements, m_visibilityRequirements;
|
||||
|
||||
std::function<void(Achievement &)> m_clickCallback;
|
||||
|
||||
std::vector<u8> m_iconData;
|
||||
mutable ImGuiExt::Texture m_icon;
|
||||
|
||||
u32 m_progress = 0;
|
||||
u32 m_maxProgress = 1;
|
||||
|
||||
bool m_temporary = false;
|
||||
|
||||
friend class AchievementManager;
|
||||
};
|
||||
|
||||
class AchievementManager {
|
||||
public:
|
||||
AchievementManager() = delete;
|
||||
|
||||
struct AchievementNode {
|
||||
Achievement *achievement;
|
||||
std::vector<AchievementNode*> children, parents;
|
||||
std::vector<AchievementNode*> visibilityParents;
|
||||
ImVec2 position;
|
||||
|
||||
[[nodiscard]] bool hasParents() const {
|
||||
return !this->parents.empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isUnlockable() const {
|
||||
return std::all_of(this->parents.begin(), this->parents.end(), [](auto &parent) { return parent->achievement->isUnlocked(); });
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isVisible() const {
|
||||
return std::all_of(this->visibilityParents.begin(), this->visibilityParents.end(), [](auto &parent) { return parent->achievement->isUnlocked(); });
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isUnlocked() const {
|
||||
return this->achievement->isUnlocked();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Adds a new achievement
|
||||
* @tparam T Type of the achievement
|
||||
* @param args Arguments to pass to the constructor of the achievement
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
template<std::derived_from<Achievement> T = Achievement>
|
||||
static Achievement& addAchievement(auto && ... args) {
|
||||
auto newAchievement = std::make_unique<T>(std::forward<decltype(args)>(args)...);
|
||||
|
||||
const auto &category = newAchievement->getUnlocalizedCategory();
|
||||
const auto &name = newAchievement->getUnlocalizedName();
|
||||
|
||||
auto [categoryIter, categoryInserted] = getAchievements().insert({ category, std::unordered_map<std::string, std::unique_ptr<Achievement>>{} });
|
||||
auto &[categoryKey, achievements] = *categoryIter;
|
||||
|
||||
auto [achievementIter, achievementInserted] = achievements.insert({ name, std::move(newAchievement) });
|
||||
auto &[achievementKey, achievement] = *achievementIter;
|
||||
|
||||
achievementAdded();
|
||||
|
||||
return *achievement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a new temporary achievement
|
||||
* @tparam T Type of the achievement
|
||||
* @param args Arguments to pass to the constructor of the achievement
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
template<std::derived_from<Achievement> T = Achievement>
|
||||
static Achievement& addTemporaryAchievement(auto && ... args) {
|
||||
auto &achievement = addAchievement<T>(std::forward<decltype(args)>(args)...);
|
||||
|
||||
achievement.m_temporary = true;
|
||||
|
||||
return achievement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlocks an achievement
|
||||
* @param unlocalizedCategory Unlocalized category of the achievement
|
||||
* @param unlocalizedName Unlocalized name of the achievement
|
||||
*/
|
||||
static void unlockAchievement(const std::string &unlocalizedCategory, const std::string &unlocalizedName);
|
||||
|
||||
/**
|
||||
* @brief Returns all registered achievements
|
||||
* @return All achievements
|
||||
*/
|
||||
static std::unordered_map<std::string, std::unordered_map<std::string, std::unique_ptr<Achievement>>>& getAchievements();
|
||||
|
||||
/**
|
||||
* @brief Returns all achievement start nodes
|
||||
* @note Start nodes are all nodes that don't have any parents
|
||||
* @param rebuild Whether to rebuild the list of start nodes
|
||||
* @return All achievement start nodes
|
||||
*/
|
||||
static std::unordered_map<std::string, std::vector<AchievementNode*>>& getAchievementStartNodes(bool rebuild = true);
|
||||
|
||||
/**
|
||||
* @brief Returns all achievement nodes
|
||||
* @param rebuild Whether to rebuild the list of nodes
|
||||
* @return All achievement nodes
|
||||
*/
|
||||
static std::unordered_map<std::string, std::list<AchievementNode>>& getAchievementNodes(bool rebuild = true);
|
||||
|
||||
/**
|
||||
* @brief Loads the progress of all achievements from the achievements save file
|
||||
*/
|
||||
static void loadProgress();
|
||||
|
||||
/**
|
||||
* @brief Stores the progress of all achievements to the achievements save file
|
||||
*/
|
||||
static void storeProgress();
|
||||
|
||||
/**
|
||||
* @brief Removes all registered achievements from the tree
|
||||
*/
|
||||
static void clear();
|
||||
|
||||
/**
|
||||
* @brief Removes all temporary achievements from the tree
|
||||
*/
|
||||
static void clearTemporary();
|
||||
|
||||
/**
|
||||
* \brief Returns the current progress of all achievements
|
||||
* \return A pair containing the number of unlocked achievements and the total number of achievements
|
||||
*/
|
||||
static std::pair<u32, u32> getProgress();
|
||||
|
||||
private:
|
||||
static void achievementAdded();
|
||||
};
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#define EVENT_DEF(event_name, ...) \
|
||||
struct event_name final : public hex::Event<__VA_ARGS__> { \
|
||||
constexpr static auto id = [] { return hex::EventId(); }(); \
|
||||
explicit event_name(Callback func) noexcept : Event(std::move(func)) { } \
|
||||
}
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class EventId {
|
||||
public:
|
||||
explicit constexpr EventId(const char *func = __builtin_FUNCTION(), u32 line = __builtin_LINE()) {
|
||||
this->m_hash = line ^ 987654321;
|
||||
for (auto c : std::string_view(func)) {
|
||||
this->m_hash = (this->m_hash >> 5) | (this->m_hash << 27);
|
||||
this->m_hash ^= c;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool operator==(const EventId &rhs) const = default;
|
||||
|
||||
private:
|
||||
u32 m_hash;
|
||||
};
|
||||
|
||||
struct EventBase {
|
||||
EventBase() noexcept = default;
|
||||
};
|
||||
|
||||
template<typename... Params>
|
||||
struct Event : public EventBase {
|
||||
using Callback = std::function<void(Params...)>;
|
||||
|
||||
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
|
||||
|
||||
void operator()(Params... params) const noexcept {
|
||||
this->m_func(params...);
|
||||
}
|
||||
|
||||
private:
|
||||
Callback m_func;
|
||||
};
|
||||
|
||||
class EventManager {
|
||||
public:
|
||||
using EventList = std::list<std::pair<EventId, EventBase *>>;
|
||||
|
||||
template<typename E>
|
||||
static EventList::iterator subscribe(typename E::Callback function) {
|
||||
return s_events.insert(s_events.end(), std::make_pair(E::id, new E(function)));
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void subscribe(void *token, typename E::Callback function) {
|
||||
s_tokenStore.insert(std::make_pair(token, subscribe<E>(function)));
|
||||
}
|
||||
|
||||
static void unsubscribe(EventList::iterator iter) noexcept {
|
||||
s_events.remove(*iter);
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void unsubscribe(void *token) noexcept {
|
||||
auto iter = std::find_if(s_tokenStore.begin(), s_tokenStore.end(), [&](auto &item) {
|
||||
return item.first == token && item.second->first == E::id;
|
||||
});
|
||||
|
||||
if (iter != s_tokenStore.end()) {
|
||||
s_events.remove(*iter->second);
|
||||
s_tokenStore.erase(iter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
static void post(auto &&...args) noexcept {
|
||||
for (const auto &[id, event] : s_events) {
|
||||
if (id == E::id)
|
||||
(*static_cast<E *const>(event))(std::forward<decltype(args)>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
static void clear() noexcept {
|
||||
s_events.clear();
|
||||
s_tokenStore.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::map<void *, EventList::iterator> s_tokenStore;
|
||||
static EventList s_events;
|
||||
};
|
||||
|
||||
/* Default Events */
|
||||
EVENT_DEF(EventFileLoaded, std::fs::path);
|
||||
EVENT_DEF(EventDataChanged);
|
||||
EVENT_DEF(EventHighlightingChanged);
|
||||
EVENT_DEF(EventWindowClosing, GLFWwindow *);
|
||||
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
|
||||
EVENT_DEF(EventSettingsChanged);
|
||||
EVENT_DEF(EventAbnormalTermination, int);
|
||||
EVENT_DEF(EventOSThemeChanged);
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
||||
EVENT_DEF(EventProviderOpened, prv::Provider *);
|
||||
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
|
||||
EVENT_DEF(EventProviderClosed, prv::Provider *);
|
||||
EVENT_DEF(EventProviderDeleted, prv::Provider *);
|
||||
EVENT_DEF(EventFrameBegin);
|
||||
EVENT_DEF(EventFrameEnd);
|
||||
EVENT_DEF(EventWindowInitialized);
|
||||
EVENT_DEF(EventSetTaskBarIconState, u32, u32, u32);
|
||||
|
||||
EVENT_DEF(RequestOpenWindow, std::string);
|
||||
EVENT_DEF(RequestSelectionChange, Region);
|
||||
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t);
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
EVENT_DEF(RequestUpdateWindowTitle);
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
EVENT_DEF(RequestRestartImHex);
|
||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||
EVENT_DEF(RequestChangeTheme, std::string);
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, hex::prv::Provider **);
|
||||
|
||||
EVENT_DEF(RequestShowInfoPopup, std::string);
|
||||
EVENT_DEF(RequestShowErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowFatalErrorPopup, std::string);
|
||||
EVENT_DEF(RequestShowYesNoQuestionPopup, std::string, std::function<void()>, std::function<void()>);
|
||||
EVENT_DEF(RequestShowFileChooserPopup, std::vector<std::fs::path>, std::vector<nfdfilteritem_t>, std::function<void(std::fs::path)>, bool);
|
||||
|
||||
}
|
||||
296
lib/libimhex/include/hex/api/event_manager.hpp
Normal file
296
lib/libimhex/include/hex/api/event_manager.hpp
Normal file
@@ -0,0 +1,296 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <functional>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <wolv/types/type_name.hpp>
|
||||
|
||||
#define EVENT_DEF_IMPL(event_name, event_name_string, should_log, ...) \
|
||||
struct event_name final : public hex::impl::Event<__VA_ARGS__> { \
|
||||
constexpr static auto Id = [] { return hex::impl::EventId(event_name_string); }(); \
|
||||
constexpr static auto ShouldLog = (should_log); \
|
||||
explicit event_name(Callback func) noexcept : Event(std::move(func)) { } \
|
||||
}
|
||||
|
||||
#define EVENT_DEF(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, true, __VA_ARGS__)
|
||||
#define EVENT_DEF_NO_LOG(event_name, ...) EVENT_DEF_IMPL(event_name, #event_name, false, __VA_ARGS__)
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
struct GLFWwindow;
|
||||
namespace hex { class Achievement; }
|
||||
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class EventId {
|
||||
public:
|
||||
explicit constexpr EventId(const char *eventName) {
|
||||
this->m_hash = 0x811C'9DC5;
|
||||
for (auto c : std::string_view(eventName)) {
|
||||
this->m_hash = (this->m_hash >> 5) | (this->m_hash << 27);
|
||||
this->m_hash ^= c;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool operator==(const EventId &other) const {
|
||||
return this->m_hash == other.m_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
u32 m_hash;
|
||||
};
|
||||
|
||||
struct EventBase {
|
||||
EventBase() noexcept = default;
|
||||
};
|
||||
|
||||
template<typename... Params>
|
||||
struct Event : EventBase {
|
||||
using Callback = std::function<void(Params...)>;
|
||||
|
||||
explicit Event(Callback func) noexcept : m_func(std::move(func)) { }
|
||||
|
||||
void operator()(Params... params) const noexcept {
|
||||
this->m_func(params...);
|
||||
}
|
||||
|
||||
private:
|
||||
Callback m_func;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept EventType = std::derived_from<T, EventBase>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief The EventManager allows subscribing to and posting events to different parts of the program.
|
||||
* To create a new event, use the EVENT_DEF macro. This will create a new event type with the given name and parameters
|
||||
*/
|
||||
class EventManager {
|
||||
public:
|
||||
using EventList = std::list<std::pair<impl::EventId, std::unique_ptr<impl::EventBase>>>;
|
||||
|
||||
/**
|
||||
* @brief Subscribes to an event
|
||||
* @tparam E Event
|
||||
* @param function Function to call when the event is posted
|
||||
* @return Token to unsubscribe from the event
|
||||
*/
|
||||
template<impl::EventType E>
|
||||
static EventList::iterator subscribe(typename E::Callback function) {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
auto &events = getEvents();
|
||||
return events.insert(events.end(), std::make_pair(E::Id, std::make_unique<E>(function)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to an event
|
||||
* @tparam E Event
|
||||
* @param token Unique token to register the event to. Later required to unsubscribe again
|
||||
* @param function Function to call when the event is posted
|
||||
*/
|
||||
template<impl::EventType E>
|
||||
static void subscribe(void *token, typename E::Callback function) {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
if (getTokenStore().contains(token)) {
|
||||
auto&& [begin, end] = getTokenStore().equal_range(token);
|
||||
auto eventRegistered = std::any_of(begin, end, [&](auto &item) {
|
||||
return item.second->first == E::Id;
|
||||
});
|
||||
if (eventRegistered) {
|
||||
log::fatal("The token '{}' has already registered the same event ('{}')", token, wolv::type::getTypeName<E>());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getTokenStore().insert({ token, subscribe<E>(function) });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from an event
|
||||
* @param token Token returned by subscribe
|
||||
*/
|
||||
static void unsubscribe(const EventList::iterator &token) noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
getEvents().erase(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from an event
|
||||
* @tparam E Event
|
||||
* @param token Token passed to subscribe
|
||||
*/
|
||||
template<impl::EventType E>
|
||||
static void unsubscribe(void *token) noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
auto &tokenStore = getTokenStore();
|
||||
auto iter = std::find_if(tokenStore.begin(), tokenStore.end(), [&](auto &item) {
|
||||
return item.first == token && item.second->first == E::Id;
|
||||
});
|
||||
|
||||
if (iter != tokenStore.end()) {
|
||||
getEvents().remove(*iter->second);
|
||||
tokenStore.erase(iter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts an event to all subscribers of it
|
||||
* @tparam E Event
|
||||
* @param args Arguments to pass to the event
|
||||
*/
|
||||
template<impl::EventType E>
|
||||
static void post(auto &&...args) noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
for (const auto &[id, event] : getEvents()) {
|
||||
if (id == E::Id) {
|
||||
try {
|
||||
(*static_cast<E *const>(event.get()))(std::forward<decltype(args)>(args)...);
|
||||
} catch (const std::exception &e) {
|
||||
log::error("Event '{}' threw {}: {}", wolv::type::getTypeName<decltype(e)>(), wolv::type::getTypeName<E>(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (DEBUG)
|
||||
if (E::ShouldLog)
|
||||
log::debug("Event posted: '{}'", wolv::type::getTypeName<E>());
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribe all subscribers from all events
|
||||
*/
|
||||
static void clear() noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
getEvents().clear();
|
||||
getTokenStore().clear();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::multimap<void *, EventList::iterator>& getTokenStore();
|
||||
static EventList& getEvents();
|
||||
static std::recursive_mutex& getEventMutex();
|
||||
};
|
||||
|
||||
/* Default Events */
|
||||
|
||||
/**
|
||||
* @brief Called when Imhex finished startup, and will enter the main window rendering loop
|
||||
*/
|
||||
EVENT_DEF(EventImHexStartupFinished);
|
||||
|
||||
EVENT_DEF(EventFileLoaded, std::fs::path);
|
||||
EVENT_DEF(EventDataChanged);
|
||||
EVENT_DEF(EventHighlightingChanged);
|
||||
EVENT_DEF(EventWindowClosing, GLFWwindow *);
|
||||
EVENT_DEF(EventRegionSelected, ImHexApi::HexEditor::ProviderRegion);
|
||||
EVENT_DEF(EventSettingsChanged);
|
||||
EVENT_DEF(EventAbnormalTermination, int);
|
||||
EVENT_DEF(EventThemeChanged);
|
||||
EVENT_DEF(EventOSThemeChanged);
|
||||
|
||||
/**
|
||||
* @brief Called when the provider is created.
|
||||
* This event is responsible for (optionally) initializing the provider and calling EventProviderOpened
|
||||
* (although the event can also be called manually without problem)
|
||||
*/
|
||||
EVENT_DEF(EventProviderCreated, prv::Provider *);
|
||||
EVENT_DEF(EventProviderChanged, prv::Provider *, prv::Provider *);
|
||||
|
||||
/**
|
||||
* @brief Called as a continuation of EventProviderCreated
|
||||
* this event is normally called immediately after EventProviderCreated successfully initialized the provider.
|
||||
* If no initialization (Provider::skipLoadInterface() has been set), this event should be called manually
|
||||
* If skipLoadInterface failed, this event is not called
|
||||
*
|
||||
* @note this is not related to Provider::open()
|
||||
*/
|
||||
EVENT_DEF(EventProviderOpened, prv::Provider *);
|
||||
EVENT_DEF(EventProviderClosing, prv::Provider *, bool *);
|
||||
EVENT_DEF(EventProviderClosed, prv::Provider *);
|
||||
EVENT_DEF(EventProviderDeleted, prv::Provider *);
|
||||
EVENT_DEF(EventProviderSaved, prv::Provider *);
|
||||
EVENT_DEF(EventWindowInitialized);
|
||||
EVENT_DEF(EventBookmarkCreated, ImHexApi::Bookmarks::Entry&);
|
||||
EVENT_DEF(EventPatchCreated, u64, u8, u8);
|
||||
EVENT_DEF(EventPatternEvaluating);
|
||||
EVENT_DEF(EventPatternExecuted, const std::string&);
|
||||
EVENT_DEF(EventPatternEditorChanged, const std::string&);
|
||||
EVENT_DEF(EventStoreContentDownloaded, const std::fs::path&);
|
||||
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
|
||||
EVENT_DEF(EventImHexClosing);
|
||||
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
||||
EVENT_DEF(EventSearchBoxClicked);
|
||||
|
||||
EVENT_DEF(EventProviderDataModified, prv::Provider *, u64, u64, const u8*);
|
||||
EVENT_DEF(EventProviderDataInserted, prv::Provider *, u64, u64);
|
||||
EVENT_DEF(EventProviderDataRemoved, prv::Provider *, u64, u64);
|
||||
|
||||
/**
|
||||
* @brief Called when a project has been loaded
|
||||
*/
|
||||
EVENT_DEF(EventProjectOpened);
|
||||
|
||||
EVENT_DEF_NO_LOG(EventFrameBegin);
|
||||
EVENT_DEF_NO_LOG(EventFrameEnd);
|
||||
EVENT_DEF_NO_LOG(EventSetTaskBarIconState, u32, u32, u32);
|
||||
|
||||
EVENT_DEF(RequestAddInitTask, std::string, bool, std::function<bool()>);
|
||||
EVENT_DEF(RequestAddExitTask, std::string, std::function<bool()>);
|
||||
EVENT_DEF(RequestOpenWindow, std::string);
|
||||
EVENT_DEF(RequestSelectionChange, Region);
|
||||
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
|
||||
EVENT_DEF(RequestRemoveBookmark, u64);
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestUpdateWindowTitle);
|
||||
EVENT_DEF(RequestCloseImHex, bool);
|
||||
EVENT_DEF(RequestRestartImHex);
|
||||
EVENT_DEF(RequestOpenFile, std::fs::path);
|
||||
EVENT_DEF(RequestChangeTheme, std::string);
|
||||
EVENT_DEF(RequestOpenPopup, std::string);
|
||||
|
||||
/**
|
||||
* @brief Creates a provider from it's unlocalized name, and add it to the provider list
|
||||
*/
|
||||
EVENT_DEF(RequestCreateProvider, std::string, bool, bool, hex::prv::Provider **);
|
||||
EVENT_DEF(RequestInitThemeHandlers);
|
||||
|
||||
EVENT_DEF(RequestOpenInfoPopup, const std::string);
|
||||
EVENT_DEF(RequestOpenErrorPopup, const std::string);
|
||||
EVENT_DEF(RequestOpenFatalPopup, const std::string);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send an event to the main Imhex instance
|
||||
*/
|
||||
EVENT_DEF(SendMessageToMainInstance, const std::string, const std::vector<u8>&);
|
||||
|
||||
/**
|
||||
* Move the data from all PerProvider instances from one provider to another.
|
||||
* The 'from' provider should not have any per provider data after this, and should be immediately deleted
|
||||
*/
|
||||
EVENT_DEF(MovePerProviderData, prv::Provider *, prv::Provider *);
|
||||
}
|
||||
@@ -2,20 +2,18 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/api/task.hpp>
|
||||
#include <hex/api/keybinding.hpp>
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
using ImGuiID = unsigned int;
|
||||
struct ImVec2;
|
||||
struct ImFontAtlas;
|
||||
struct ImFont;
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -25,13 +23,7 @@ namespace hex {
|
||||
|
||||
namespace ImHexApi {
|
||||
|
||||
namespace Common {
|
||||
|
||||
void closeImHex(bool noQuestions = false);
|
||||
void restartImHex();
|
||||
|
||||
}
|
||||
|
||||
/* Functions to query information from the Hex Editor and interact with it */
|
||||
namespace HexEditor {
|
||||
|
||||
using TooltipFunction = std::function<void(u64, const u8*, size_t)>;
|
||||
@@ -64,7 +56,7 @@ namespace hex {
|
||||
color_t m_color = 0x00;
|
||||
};
|
||||
|
||||
struct ProviderRegion : public Region {
|
||||
struct ProviderRegion : Region {
|
||||
prv::Provider *provider;
|
||||
|
||||
[[nodiscard]] prv::Provider *getProvider() const { return this->provider; }
|
||||
@@ -83,35 +75,135 @@ namespace hex {
|
||||
std::map<u32, Tooltip> &getTooltips();
|
||||
std::map<u32, TooltipFunction> &getTooltipFunctions();
|
||||
|
||||
void setCurrentSelection(std::optional<ProviderRegion> region);
|
||||
void setCurrentSelection(const std::optional<ProviderRegion> ®ion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a background color highlighting to the Hex Editor
|
||||
* @param region The region to highlight
|
||||
* @param color The color to use for the highlighting
|
||||
* @return Unique ID used to remove the highlighting again later
|
||||
*/
|
||||
u32 addBackgroundHighlight(const Region ®ion, color_t color);
|
||||
|
||||
/**
|
||||
* @brief Removes a background color highlighting from the Hex Editor
|
||||
* @param id The ID of the highlighting to remove
|
||||
*/
|
||||
void removeBackgroundHighlight(u32 id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a foreground color highlighting to the Hex Editor
|
||||
* @param region The region to highlight
|
||||
* @param color The color to use for the highlighting
|
||||
* @return Unique ID used to remove the highlighting again later
|
||||
*/
|
||||
u32 addForegroundHighlight(const Region ®ion, color_t color);
|
||||
|
||||
/**
|
||||
* @brief Removes a foreground color highlighting from the Hex Editor
|
||||
* @param id The ID of the highlighting to remove
|
||||
*/
|
||||
void removeForegroundHighlight(u32 id);
|
||||
|
||||
/**
|
||||
* @brief Adds a hover tooltip to the Hex Editor
|
||||
* @param region The region to add the tooltip to
|
||||
* @param value Text to display in the tooltip
|
||||
* @param color The color of the tooltip
|
||||
* @return Unique ID used to remove the tooltip again later
|
||||
*/
|
||||
u32 addTooltip(Region region, std::string value, color_t color);
|
||||
|
||||
/**
|
||||
* @brief Removes a hover tooltip from the Hex Editor
|
||||
* @param id The ID of the tooltip to remove
|
||||
*/
|
||||
void removeTooltip(u32 id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a background color highlighting to the Hex Editor using a callback function
|
||||
* @param function Function that draws the highlighting based on the hovered region
|
||||
* @return Unique ID used to remove the highlighting again later
|
||||
*/
|
||||
u32 addTooltipProvider(TooltipFunction function);
|
||||
|
||||
/**
|
||||
* @brief Removes a background color highlighting from the Hex Editor
|
||||
* @param id The ID of the highlighting to remove
|
||||
*/
|
||||
void removeTooltipProvider(u32 id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a background color highlighting to the Hex Editor using a callback function
|
||||
* @param function Function that draws the highlighting based on the hovered region
|
||||
* @return Unique ID used to remove the highlighting again later
|
||||
*/
|
||||
u32 addBackgroundHighlightingProvider(const impl::HighlightingFunction &function);
|
||||
|
||||
/**
|
||||
* @brief Removes a background color highlighting from the Hex Editor
|
||||
* @param id The ID of the highlighting to remove
|
||||
*/
|
||||
void removeBackgroundHighlightingProvider(u32 id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Adds a foreground color highlighting to the Hex Editor using a callback function
|
||||
* @param function Function that draws the highlighting based on the hovered region
|
||||
* @return Unique ID used to remove the highlighting again later
|
||||
*/
|
||||
u32 addForegroundHighlightingProvider(const impl::HighlightingFunction &function);
|
||||
|
||||
/**
|
||||
* @brief Removes a foreground color highlighting from the Hex Editor
|
||||
* @param id The ID of the highlighting to remove
|
||||
*/
|
||||
void removeForegroundHighlightingProvider(u32 id);
|
||||
|
||||
/**
|
||||
* @brief Checks if there's a valid selection in the Hex Editor right now
|
||||
*/
|
||||
bool isSelectionValid();
|
||||
|
||||
/**
|
||||
* @brief Clears the current selection in the Hex Editor
|
||||
*/
|
||||
void clearSelection();
|
||||
|
||||
/**
|
||||
* @brief Gets the current selection in the Hex Editor
|
||||
* @return The current selection
|
||||
*/
|
||||
std::optional<ProviderRegion> getSelection();
|
||||
|
||||
/**
|
||||
* @brief Sets the current selection in the Hex Editor
|
||||
* @param region The region to select
|
||||
* @param provider The provider to select the region in
|
||||
*/
|
||||
void setSelection(const Region ®ion, prv::Provider *provider = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Sets the current selection in the Hex Editor
|
||||
* @param region The region to select
|
||||
*/
|
||||
void setSelection(const ProviderRegion ®ion);
|
||||
|
||||
/**
|
||||
* @brief Sets the current selection in the Hex Editor
|
||||
* @param address The address to select
|
||||
* @param size The size of the selection
|
||||
* @param provider The provider to select the region in
|
||||
*/
|
||||
void setSelection(u64 address, size_t size, prv::Provider *provider = nullptr);
|
||||
|
||||
}
|
||||
|
||||
/* Functions to interact with Bookmarks */
|
||||
namespace Bookmarks {
|
||||
|
||||
struct Entry {
|
||||
@@ -121,68 +213,158 @@ namespace hex {
|
||||
std::string comment;
|
||||
u32 color;
|
||||
bool locked;
|
||||
u64 id;
|
||||
};
|
||||
|
||||
void add(u64 address, size_t size, const std::string &name, const std::string &comment, color_t color = 0x00000000);
|
||||
/**
|
||||
* @brief Adds a new bookmark
|
||||
* @param address The address of the bookmark
|
||||
* @param size The size of the bookmark
|
||||
* @param name The name of the bookmark
|
||||
* @param comment The comment of the bookmark
|
||||
* @param color The color of the bookmark or 0x00 for the default color
|
||||
* @return Bookmark ID
|
||||
*/
|
||||
u64 add(u64 address, size_t size, const std::string &name, const std::string &comment, color_t color = 0x00000000);
|
||||
|
||||
/**
|
||||
* @brief Adds a new bookmark
|
||||
* @param region The region of the bookmark
|
||||
* @param name The name of the bookmark
|
||||
* @param comment The comment of the bookmark
|
||||
* @param color The color of the bookmark or 0x00 for the default color
|
||||
* @return Bookmark ID
|
||||
*/
|
||||
u64 add(Region region, const std::string &name, const std::string &comment, color_t color = 0x00000000);
|
||||
|
||||
/**
|
||||
* @brief Removes a bookmark
|
||||
* @param id The ID of the bookmark to remove
|
||||
*/
|
||||
void remove(u64 id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods about the providers
|
||||
* @note the "current provider" or "currently selected provider" refers to the currently selected provider in the UI;
|
||||
* the provider the user is actually editing.
|
||||
*/
|
||||
namespace Provider {
|
||||
|
||||
namespace impl {
|
||||
|
||||
void resetClosingProvider();
|
||||
prv::Provider* getClosingProvider();
|
||||
const std::vector<prv::Provider*>& getClosingProviders();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the currently selected data provider
|
||||
* @return The currently selected data provider, or nullptr is there is none
|
||||
*/
|
||||
prv::Provider *get();
|
||||
|
||||
/**
|
||||
* @brief Gets a list of all currently loaded data providers
|
||||
* @return The currently loaded data providers
|
||||
*/
|
||||
const std::vector<prv::Provider *> &getProviders();
|
||||
|
||||
/**
|
||||
* @brief Sets the currently selected data provider
|
||||
* @param index Index of the provider to select
|
||||
*/
|
||||
void setCurrentProvider(u32 index);
|
||||
|
||||
/**
|
||||
* @brief Gets the index of the currently selected data provider
|
||||
* @return Index of the selected provider
|
||||
*/
|
||||
i64 getCurrentProviderIndex();
|
||||
|
||||
/**
|
||||
* @brief Checks whether the currently selected data provider is valid
|
||||
* @return Whether the currently selected data provider is valid
|
||||
*/
|
||||
bool isValid();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Marks the **currently selected** data provider as dirty
|
||||
*/
|
||||
void markDirty();
|
||||
|
||||
/**
|
||||
* @brief Marks **all data providers** as clean
|
||||
*/
|
||||
void resetDirty();
|
||||
|
||||
/**
|
||||
* @brief Checks whether **any of the data providers** is dirty
|
||||
* @return Whether any data provider is dirty
|
||||
*/
|
||||
bool isDirty();
|
||||
|
||||
void add(prv::Provider *provider, bool skipLoadInterface = false);
|
||||
|
||||
/**
|
||||
* @brief Adds a newly created provider to the list of providers, and mark it as the selected one.
|
||||
* @param provider The provider to add
|
||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||
* @param select Whether to select the provider after adding it
|
||||
*/
|
||||
void add(prv::Provider *provider, bool skipLoadInterface = false, bool select = true);
|
||||
|
||||
/**
|
||||
* @brief Creates a new provider and adds it to the list of providers
|
||||
* @tparam T The type of the provider to create
|
||||
* @param args Arguments to pass to the provider's constructor
|
||||
*/
|
||||
template<std::derived_from<prv::Provider> T>
|
||||
void add(auto &&...args) {
|
||||
add(new T(std::forward<decltype(args)>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a provider from the list of providers
|
||||
* @param provider The provider to remove
|
||||
* @param noQuestions Whether to skip asking the user for confirmation
|
||||
*/
|
||||
void remove(prv::Provider *provider, bool noQuestions = false);
|
||||
|
||||
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface = false);
|
||||
/**
|
||||
* @brief Creates a new provider using its unlocalized name and add it to the list of providers
|
||||
* @param unlocalizedName The unlocalized name of the provider to create
|
||||
* @param skipLoadInterface Whether to skip the provider's loading interface (see property documentation)
|
||||
* @param select Whether to select the provider after adding it
|
||||
*/
|
||||
prv::Provider* createProvider(const std::string &unlocalizedName, bool skipLoadInterface = false, bool select = true);
|
||||
|
||||
}
|
||||
|
||||
/* Functions to interact with various ImHex system settings */
|
||||
namespace System {
|
||||
|
||||
namespace impl {
|
||||
bool isMainInstance();
|
||||
|
||||
void setMainWindowPosition(u32 x, u32 y);
|
||||
namespace impl {
|
||||
void setMainInstanceStatus(bool status);
|
||||
|
||||
void setMainWindowPosition(i32 x, i32 y);
|
||||
void setMainWindowSize(u32 width, u32 height);
|
||||
void setMainDockSpaceId(ImGuiID id);
|
||||
|
||||
void setGlobalScale(float scale);
|
||||
void setNativeScale(float scale);
|
||||
|
||||
void setProgramArguments(int argc, char **argv, char **envp);
|
||||
|
||||
void setBorderlessWindowMode(bool enabled);
|
||||
|
||||
void setCustomFontPath(const std::filesystem::path &path);
|
||||
void setFontSize(float size);
|
||||
|
||||
void setGPUVendor(const std::string &vendor);
|
||||
|
||||
void setPortableVersion(bool enabled);
|
||||
|
||||
void addInitArgument(const std::string &key, const std::string &value = { });
|
||||
|
||||
}
|
||||
|
||||
struct ProgramArguments {
|
||||
@@ -203,38 +385,254 @@ namespace hex {
|
||||
Error
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Closes ImHex
|
||||
* @param noQuestions Whether to skip asking the user for confirmation
|
||||
*/
|
||||
void closeImHex(bool noQuestions = false);
|
||||
|
||||
/**
|
||||
* @brief Restarts ImHex
|
||||
*/
|
||||
void restartImHex();
|
||||
|
||||
/**
|
||||
* @brief Sets the progress bar in the task bar
|
||||
* @param state The state of the progress bar
|
||||
* @param type The type of the progress bar progress
|
||||
* @param progress The progress of the progress bar
|
||||
*/
|
||||
void setTaskBarProgress(TaskProgressState state, TaskProgressType type, u32 progress);
|
||||
|
||||
const ProgramArguments &getProgramArguments();
|
||||
std::optional<std::u8string> getProgramArgument(int index);
|
||||
|
||||
/**
|
||||
* @brief Gets the current target FPS
|
||||
* @return The current target FPS
|
||||
*/
|
||||
float getTargetFPS();
|
||||
|
||||
/**
|
||||
* @brief Sets the target FPS
|
||||
* @param fps The target FPS
|
||||
*/
|
||||
void setTargetFPS(float fps);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the current global scale
|
||||
* @return The current global scale
|
||||
*/
|
||||
float getGlobalScale();
|
||||
|
||||
/**
|
||||
* @brief Gets the current native scale
|
||||
* @return The current native scale
|
||||
*/
|
||||
float getNativeScale();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the current main window position
|
||||
* @return Position of the main window
|
||||
*/
|
||||
ImVec2 getMainWindowPosition();
|
||||
|
||||
/**
|
||||
* @brief Gets the current main window size
|
||||
* @return Size of the main window
|
||||
*/
|
||||
ImVec2 getMainWindowSize();
|
||||
|
||||
/**
|
||||
* @brief Gets the current main dock space ID
|
||||
* @return ID of the main dock space
|
||||
*/
|
||||
ImGuiID getMainDockSpaceId();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if borderless window mode is enabled currently
|
||||
* @return Whether borderless window mode is enabled
|
||||
*/
|
||||
bool isBorderlessWindowModeEnabled();
|
||||
|
||||
/**
|
||||
* @brief Gets the init arguments passed to ImHex from the splash screen
|
||||
* @return Init arguments
|
||||
*/
|
||||
std::map<std::string, std::string> &getInitArguments();
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
const std::filesystem::path &getCustomFontPath();
|
||||
float getFontSize();
|
||||
|
||||
/**
|
||||
* @brief Sets if ImHex should follow the system theme
|
||||
* @param enabled Whether to follow the system theme
|
||||
*/
|
||||
void enableSystemThemeDetection(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex follows the system theme
|
||||
* @return Whether ImHex follows the system theme
|
||||
*/
|
||||
bool usesSystemThemeDetection();
|
||||
|
||||
const std::vector<std::filesystem::path> &getAdditionalFolderPaths();
|
||||
|
||||
/**
|
||||
* @brief Gets the currently set additional folder paths
|
||||
* @return The currently set additional folder paths
|
||||
*/
|
||||
std::vector<std::filesystem::path> &getAdditionalFolderPaths();
|
||||
|
||||
/**
|
||||
* @brief Sets the additional folder paths
|
||||
* @param paths The additional folder paths
|
||||
*/
|
||||
void setAdditionalFolderPaths(const std::vector<std::filesystem::path> &paths);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the current GPU vendor
|
||||
* @return The current GPU vendor
|
||||
*/
|
||||
const std::string &getGPUVendor();
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex is running in portable mode
|
||||
* @return Whether ImHex is running in portable mode
|
||||
*/
|
||||
bool isPortableVersion();
|
||||
|
||||
/**
|
||||
* @brief Gets the current Operating System name
|
||||
* @return Operating System name
|
||||
*/
|
||||
std::string getOSName();
|
||||
|
||||
/**
|
||||
* @brief Gets the current Operating System version
|
||||
* @return Operating System version
|
||||
*/
|
||||
std::string getOSVersion();
|
||||
|
||||
/**
|
||||
* @brief Gets the current CPU architecture
|
||||
* @return CPU architecture
|
||||
*/
|
||||
std::string getArchitecture();
|
||||
|
||||
/**
|
||||
* @brief Gets the current ImHex version
|
||||
* @return ImHex version
|
||||
*/
|
||||
std::string getImHexVersion(bool withBuildType = true);
|
||||
|
||||
/**
|
||||
* @brief Gets the current git commit hash
|
||||
* @param longHash Whether to return the full hash or the shortened version
|
||||
* @return Git commit hash
|
||||
*/
|
||||
std::string getCommitHash(bool longHash = false);
|
||||
|
||||
/**
|
||||
* @brief Gets the current git commit branch
|
||||
* @return Git commit branch
|
||||
*/
|
||||
std::string getCommitBranch();
|
||||
|
||||
/**
|
||||
* @brief Checks if ImHex was built in debug mode
|
||||
* @return True if ImHex was built in debug mode, false otherwise
|
||||
*/
|
||||
bool isDebugBuild();
|
||||
|
||||
enum class UpdateType {
|
||||
Stable,
|
||||
Nightly
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Triggers the update process
|
||||
* @param updateType The update channel
|
||||
* @return If the update process was successfully started
|
||||
*/
|
||||
bool updateImHex(UpdateType updateType);
|
||||
|
||||
void addStartupTask(const std::string &name, bool async, const std::function<bool()> &function);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cross-instance messaging system
|
||||
* This allows you to send messages to the "main" instance of ImHex running, from any other instance
|
||||
*/
|
||||
namespace Messaging {
|
||||
|
||||
namespace impl {
|
||||
using MessagingHandler = std::function<void(const std::vector<u8> &)>;
|
||||
|
||||
std::map<std::string, MessagingHandler> &getHandlers();
|
||||
|
||||
void runHandler(const std::string &eventName, const std::vector<u8> &args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register the handler for this specific event name
|
||||
*/
|
||||
void registerHandler(const std::string &eventName, const impl::MessagingHandler &handler);
|
||||
}
|
||||
|
||||
namespace Fonts {
|
||||
|
||||
struct GlyphRange { u16 begin, end; };
|
||||
struct Offset { float x, y; };
|
||||
|
||||
struct Font {
|
||||
std::string name;
|
||||
std::vector<u8> fontData;
|
||||
std::vector<GlyphRange> glyphRanges;
|
||||
Offset offset;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
std::vector<Font>& getFonts();
|
||||
|
||||
void setCustomFontPath(const std::fs::path &path);
|
||||
void setFontSize(float size);
|
||||
void setFontAtlas(ImFontAtlas *fontAtlas);
|
||||
|
||||
void setFonts(ImFont *bold, ImFont *italic);
|
||||
}
|
||||
|
||||
GlyphRange glyph(const char *glyph);
|
||||
GlyphRange glyph(u32 codepoint);
|
||||
GlyphRange range(const char *glyphBegin, const char *glyphEnd);
|
||||
GlyphRange range(u32 codepointBegin, u32 codepointEnd);
|
||||
|
||||
void loadFont(const std::fs::path &path, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0);
|
||||
void loadFont(const std::string &name, const std::span<const u8> &data, const std::vector<GlyphRange> &glyphRanges = {}, Offset offset = {}, u32 flags = 0);
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
|
||||
ImFont* Bold();
|
||||
ImFont* Italic();
|
||||
|
||||
/**
|
||||
* @brief Gets the current custom font path
|
||||
* @return The current custom font path
|
||||
*/
|
||||
std::filesystem::path &getCustomFontPath();
|
||||
|
||||
/**
|
||||
* @brief Gets the current font size
|
||||
* @return The current font size
|
||||
*/
|
||||
float getFontSize();
|
||||
|
||||
/**
|
||||
* @brief Gets the current font atlas
|
||||
* @return Current font atlas
|
||||
*/
|
||||
ImFontAtlas* getFontAtlas();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class View;
|
||||
|
||||
enum class Keys
|
||||
{
|
||||
Space = GLFW_KEY_SPACE,
|
||||
Apostrophe = GLFW_KEY_APOSTROPHE,
|
||||
Comma = GLFW_KEY_COMMA,
|
||||
Minus = GLFW_KEY_MINUS,
|
||||
Period = GLFW_KEY_PERIOD,
|
||||
Slash = GLFW_KEY_SLASH,
|
||||
Num0 = GLFW_KEY_0,
|
||||
Num1 = GLFW_KEY_1,
|
||||
Num2 = GLFW_KEY_2,
|
||||
Num3 = GLFW_KEY_3,
|
||||
Num4 = GLFW_KEY_4,
|
||||
Num5 = GLFW_KEY_5,
|
||||
Num6 = GLFW_KEY_6,
|
||||
Num7 = GLFW_KEY_7,
|
||||
Num8 = GLFW_KEY_8,
|
||||
Num9 = GLFW_KEY_9,
|
||||
Semicolon = GLFW_KEY_SEMICOLON,
|
||||
Equals = GLFW_KEY_EQUAL,
|
||||
A = GLFW_KEY_A,
|
||||
B = GLFW_KEY_B,
|
||||
C = GLFW_KEY_C,
|
||||
D = GLFW_KEY_D,
|
||||
E = GLFW_KEY_E,
|
||||
F = GLFW_KEY_F,
|
||||
G = GLFW_KEY_G,
|
||||
H = GLFW_KEY_H,
|
||||
I = GLFW_KEY_I,
|
||||
J = GLFW_KEY_J,
|
||||
K = GLFW_KEY_K,
|
||||
L = GLFW_KEY_L,
|
||||
M = GLFW_KEY_M,
|
||||
N = GLFW_KEY_N,
|
||||
O = GLFW_KEY_O,
|
||||
P = GLFW_KEY_P,
|
||||
Q = GLFW_KEY_Q,
|
||||
R = GLFW_KEY_R,
|
||||
S = GLFW_KEY_S,
|
||||
T = GLFW_KEY_T,
|
||||
U = GLFW_KEY_U,
|
||||
V = GLFW_KEY_V,
|
||||
W = GLFW_KEY_W,
|
||||
X = GLFW_KEY_X,
|
||||
Y = GLFW_KEY_Y,
|
||||
Z = GLFW_KEY_Z,
|
||||
LeftBracket = GLFW_KEY_LEFT_BRACKET,
|
||||
Backslash = GLFW_KEY_BACKSLASH,
|
||||
RightBracket = GLFW_KEY_RIGHT_BRACKET,
|
||||
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
|
||||
World1 = GLFW_KEY_WORLD_1,
|
||||
World2 = GLFW_KEY_WORLD_2,
|
||||
Escape = GLFW_KEY_ESCAPE,
|
||||
Enter = GLFW_KEY_ENTER,
|
||||
Tab = GLFW_KEY_TAB,
|
||||
Backspace = GLFW_KEY_BACKSPACE,
|
||||
Insert = GLFW_KEY_INSERT,
|
||||
Delete = GLFW_KEY_DELETE,
|
||||
Right = GLFW_KEY_RIGHT,
|
||||
Left = GLFW_KEY_LEFT,
|
||||
Down = GLFW_KEY_DOWN,
|
||||
Up = GLFW_KEY_UP,
|
||||
PageUp = GLFW_KEY_PAGE_UP,
|
||||
PageDown = GLFW_KEY_PAGE_DOWN,
|
||||
Home = GLFW_KEY_HOME,
|
||||
End = GLFW_KEY_END,
|
||||
CapsLock = GLFW_KEY_CAPS_LOCK,
|
||||
ScrollLock = GLFW_KEY_SCROLL_LOCK,
|
||||
NumLock = GLFW_KEY_NUM_LOCK,
|
||||
PrintScreen = GLFW_KEY_PRINT_SCREEN,
|
||||
Pause = GLFW_KEY_PAUSE,
|
||||
F1 = GLFW_KEY_F1,
|
||||
F2 = GLFW_KEY_F2,
|
||||
F3 = GLFW_KEY_F3,
|
||||
F4 = GLFW_KEY_F4,
|
||||
F5 = GLFW_KEY_F5,
|
||||
F6 = GLFW_KEY_F6,
|
||||
F7 = GLFW_KEY_F7,
|
||||
F8 = GLFW_KEY_F8,
|
||||
F9 = GLFW_KEY_F9,
|
||||
F10 = GLFW_KEY_F10,
|
||||
F11 = GLFW_KEY_F11,
|
||||
F12 = GLFW_KEY_F12,
|
||||
F13 = GLFW_KEY_F13,
|
||||
F14 = GLFW_KEY_F14,
|
||||
F15 = GLFW_KEY_F15,
|
||||
F16 = GLFW_KEY_F16,
|
||||
F17 = GLFW_KEY_F17,
|
||||
F18 = GLFW_KEY_F18,
|
||||
F19 = GLFW_KEY_F19,
|
||||
F20 = GLFW_KEY_F20,
|
||||
F21 = GLFW_KEY_F21,
|
||||
F22 = GLFW_KEY_F22,
|
||||
F23 = GLFW_KEY_F23,
|
||||
F24 = GLFW_KEY_F24,
|
||||
F25 = GLFW_KEY_F25,
|
||||
KeyPad0 = GLFW_KEY_KP_0,
|
||||
KeyPad1 = GLFW_KEY_KP_1,
|
||||
KeyPad2 = GLFW_KEY_KP_2,
|
||||
KeyPad3 = GLFW_KEY_KP_3,
|
||||
KeyPad4 = GLFW_KEY_KP_4,
|
||||
KeyPad5 = GLFW_KEY_KP_5,
|
||||
KeyPad6 = GLFW_KEY_KP_6,
|
||||
KeyPad7 = GLFW_KEY_KP_7,
|
||||
KeyPad8 = GLFW_KEY_KP_8,
|
||||
KeyPad9 = GLFW_KEY_KP_9,
|
||||
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
|
||||
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
|
||||
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
|
||||
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
|
||||
KeyPadAdd = GLFW_KEY_KP_ADD,
|
||||
KeyPadEnter = GLFW_KEY_KP_ENTER,
|
||||
KeyPadEqual = GLFW_KEY_KP_EQUAL,
|
||||
Menu = GLFW_KEY_MENU,
|
||||
};
|
||||
|
||||
|
||||
class Key {
|
||||
public:
|
||||
constexpr Key(Keys key) : m_key(static_cast<u32>(key)) { }
|
||||
|
||||
auto operator<=>(const Key &) const = default;
|
||||
|
||||
private:
|
||||
u32 m_key;
|
||||
};
|
||||
|
||||
class Shortcut {
|
||||
public:
|
||||
Shortcut() = default;
|
||||
Shortcut(Keys key) : m_keys({ key }) { }
|
||||
|
||||
Shortcut operator+(const Key &other) const {
|
||||
Shortcut result = *this;
|
||||
result.m_keys.insert(other);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shortcut &operator+=(const Key &other) {
|
||||
this->m_keys.insert(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const Shortcut &other) const {
|
||||
return this->m_keys < other.m_keys;
|
||||
}
|
||||
|
||||
bool operator==(const Shortcut &other) const {
|
||||
return this->m_keys == other.m_keys;
|
||||
}
|
||||
|
||||
private:
|
||||
friend Shortcut operator+(const Key &lhs, const Key &rhs);
|
||||
|
||||
std::set<Key> m_keys;
|
||||
};
|
||||
|
||||
inline Shortcut operator+(const Key &lhs, const Key &rhs) {
|
||||
Shortcut result;
|
||||
result.m_keys = { lhs, rhs };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr static auto CTRL = Key(static_cast<Keys>(0x1000'0000));
|
||||
constexpr static auto ALT = Key(static_cast<Keys>(0x2000'0000));
|
||||
constexpr static auto SHIFT = Key(static_cast<Keys>(0x4000'0000));
|
||||
constexpr static auto SUPER = Key(static_cast<Keys>(0x8000'0000));
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
constexpr static auto CTRLCMD = SUPER;
|
||||
|
||||
constexpr static auto CTRL_NAME = "CTRL";
|
||||
constexpr static auto ALT_NAME = "OPT";
|
||||
constexpr static auto SHIFT_NAME = "SHIFT";
|
||||
constexpr static auto SUPER_NAME = "CMD";
|
||||
constexpr static auto CTRLCMD_NAME = SUPER_NAME;
|
||||
#else
|
||||
constexpr static auto CTRLCMD = CTRL;
|
||||
|
||||
constexpr static auto CTRL_NAME = "CTRL";
|
||||
constexpr static auto ALT_NAME = "ALT";
|
||||
constexpr static auto SHIFT_NAME = "SHIFT";
|
||||
constexpr static auto SUPER_NAME = "SUPER";
|
||||
constexpr static auto CTRLCMD_NAME = CTRL_NAME;
|
||||
#endif
|
||||
|
||||
class ShortcutManager {
|
||||
public:
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const std::function<void()> &callback);
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const std::function<void()> &callback);
|
||||
|
||||
static void process(View *currentView, bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode);
|
||||
static void processGlobals(bool ctrl, bool alt, bool shift, bool super, u32 keyCode);
|
||||
|
||||
static void clearShortcuts();
|
||||
|
||||
private:
|
||||
static std::map<Shortcut, std::function<void()>> s_globalShortcuts;
|
||||
};
|
||||
|
||||
}
|
||||
62
lib/libimhex/include/hex/api/layout_manager.hpp
Normal file
62
lib/libimhex/include/hex/api/layout_manager.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class LayoutManager {
|
||||
public:
|
||||
struct Layout {
|
||||
std::string name;
|
||||
std::fs::path path;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Save the current layout
|
||||
* @param name Name of the layout
|
||||
*/
|
||||
static void save(const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Load a layout from a file
|
||||
* @param path Path to the layout file
|
||||
*/
|
||||
static void load(const std::fs::path &path);
|
||||
|
||||
/**
|
||||
* @brief Load a layout from a string
|
||||
* @param content Layout string
|
||||
*/
|
||||
static void loadString(const std::string &content);
|
||||
|
||||
/**
|
||||
* @brief Get a list of all layouts
|
||||
* @return List of all added layouts
|
||||
*/
|
||||
static std::vector<Layout> getLayouts();
|
||||
|
||||
/**
|
||||
* @brief Handles loading of layouts if needed
|
||||
* @note This function should only be called by ImHex
|
||||
*/
|
||||
static void process();
|
||||
|
||||
/**
|
||||
* @brief Reload all layouts
|
||||
*/
|
||||
static void reload();
|
||||
|
||||
/**
|
||||
* @brief Reset the layout manager
|
||||
*/
|
||||
static void reset();
|
||||
|
||||
private:
|
||||
LayoutManager() = default;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class LanguageDefinition {
|
||||
public:
|
||||
explicit LanguageDefinition(std::map<std::string, std::string> &&entries);
|
||||
|
||||
[[nodiscard]] const std::map<std::string, std::string> &getEntries() const;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> m_entries;
|
||||
};
|
||||
|
||||
class LangEntry {
|
||||
public:
|
||||
explicit LangEntry(const char *unlocalizedString);
|
||||
explicit LangEntry(std::string unlocalizedString);
|
||||
explicit LangEntry(std::string_view unlocalizedString);
|
||||
|
||||
operator std::string() const;
|
||||
operator std::string_view() const;
|
||||
operator const char *() const;
|
||||
|
||||
[[nodiscard]] const std::string &get() const;
|
||||
|
||||
static void loadLanguage(const std::string &language);
|
||||
static const std::map<std::string, std::string> &getSupportedLanguages();
|
||||
|
||||
static void setFallbackLanguage(const std::string &language);
|
||||
static const std::string &getFallbackLanguage();
|
||||
|
||||
static void resetLanguageStrings();
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedString;
|
||||
|
||||
static std::string s_fallbackLanguage;
|
||||
static std::map<std::string, std::string> s_currStrings;
|
||||
};
|
||||
|
||||
std::string operator+(const std::string &&left, const LangEntry &&right);
|
||||
std::string operator+(const LangEntry &&left, const std::string &&right);
|
||||
std::string operator+(const std::string_view &&left, const LangEntry &&right);
|
||||
std::string operator+(const LangEntry &&left, const std::string_view &&right);
|
||||
std::string operator+(const char *left, const LangEntry &&right);
|
||||
std::string operator+(const LangEntry &&left, const char *right);
|
||||
std::string operator+(const LangEntry &&left, const LangEntry &&right);
|
||||
|
||||
inline LangEntry operator""_lang(const char *string, size_t) {
|
||||
return LangEntry(string);
|
||||
}
|
||||
|
||||
}
|
||||
71
lib/libimhex/include/hex/api/localization_manager.hpp
Normal file
71
lib/libimhex/include/hex/api/localization_manager.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace LocalizationManager {
|
||||
|
||||
class LanguageDefinition {
|
||||
public:
|
||||
explicit LanguageDefinition(std::map<std::string, std::string> &&entries);
|
||||
|
||||
[[nodiscard]] const std::map<std::string, std::string> &getEntries() const;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> m_entries;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
void setFallbackLanguage(const std::string &language);
|
||||
void resetLanguageStrings();
|
||||
}
|
||||
|
||||
void loadLanguage(const std::string &language);
|
||||
|
||||
[[nodiscard]] const std::map<std::string, std::string> &getSupportedLanguages();
|
||||
[[nodiscard]] const std::string &getFallbackLanguage();
|
||||
[[nodiscard]] const std::string &getSelectedLanguage();
|
||||
}
|
||||
|
||||
class Lang {
|
||||
public:
|
||||
explicit Lang(const char *unlocalizedString);
|
||||
explicit Lang(std::string unlocalizedString);
|
||||
explicit Lang(std::string_view unlocalizedString);
|
||||
|
||||
[[nodiscard]] operator std::string() const;
|
||||
[[nodiscard]] operator std::string_view() const;
|
||||
[[nodiscard]] operator const char *() const;
|
||||
|
||||
[[nodiscard]] const std::string &get() const;
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedString;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::string operator+(const std::string &&left, const Lang &&right);
|
||||
[[nodiscard]] std::string operator+(const Lang &&left, const std::string &&right);
|
||||
[[nodiscard]] std::string operator+(const std::string_view &&left, const Lang &&right);
|
||||
[[nodiscard]] std::string operator+(const Lang &&left, const std::string_view &&right);
|
||||
[[nodiscard]] std::string operator+(const char *left, const Lang &&right);
|
||||
[[nodiscard]] std::string operator+(const Lang &&left, const char *right);
|
||||
[[nodiscard]] std::string operator+(const Lang &&left, const Lang &&right);
|
||||
|
||||
[[nodiscard]] inline Lang operator""_lang(const char *string, size_t) {
|
||||
return Lang(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
struct fmt::formatter<hex::Lang> : fmt::formatter<std::string_view> {
|
||||
template<typename FormatContext>
|
||||
auto format(const hex::Lang &entry, FormatContext &ctx) {
|
||||
return fmt::formatter<std::string_view>::format(entry.get(), ctx);
|
||||
}
|
||||
};
|
||||
@@ -1,25 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
struct ImGuiContext;
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct SubCommand {
|
||||
std::string commandKey;
|
||||
std::string commandDesc;
|
||||
std::function<void(const std::vector<std::string>&)> callback;
|
||||
};
|
||||
|
||||
struct PluginFunctions {
|
||||
using InitializePluginFunc = void (*)();
|
||||
using GetPluginNameFunc = const char *(*)();
|
||||
using GetPluginAuthorFunc = const char *(*)();
|
||||
using GetPluginDescriptionFunc = const char *(*)();
|
||||
using GetCompatibleVersionFunc = const char *(*)();
|
||||
using SetImGuiContextFunc = void (*)(ImGuiContext *);
|
||||
using IsBuiltinPluginFunc = bool (*)();
|
||||
using GetSubCommandsFunc = void* (*)();
|
||||
|
||||
InitializePluginFunc initializePluginFunction = nullptr;
|
||||
GetPluginNameFunc getPluginNameFunction = nullptr;
|
||||
GetPluginAuthorFunc getPluginAuthorFunction = nullptr;
|
||||
GetPluginDescriptionFunc getPluginDescriptionFunction = nullptr;
|
||||
GetCompatibleVersionFunc getCompatibleVersionFunction = nullptr;
|
||||
SetImGuiContextFunc setImGuiContextFunction = nullptr;
|
||||
IsBuiltinPluginFunc isBuiltinPluginFunction = nullptr;
|
||||
GetSubCommandsFunc getSubCommandsFunction = nullptr;
|
||||
};
|
||||
|
||||
class Plugin {
|
||||
public:
|
||||
explicit Plugin(const std::fs::path &path);
|
||||
explicit Plugin(PluginFunctions functions);
|
||||
|
||||
Plugin(const Plugin &) = delete;
|
||||
Plugin(Plugin &&other) noexcept;
|
||||
~Plugin();
|
||||
@@ -36,39 +57,22 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] bool isLoaded() const;
|
||||
|
||||
private:
|
||||
using InitializePluginFunc = void (*)();
|
||||
using GetPluginNameFunc = const char *(*)();
|
||||
using GetPluginAuthorFunc = const char *(*)();
|
||||
using GetPluginDescriptionFunc = const char *(*)();
|
||||
using GetCompatibleVersionFunc = const char *(*)();
|
||||
using SetImGuiContextFunc = void (*)(ImGuiContext *);
|
||||
using IsBuiltinPluginFunc = bool (*)();
|
||||
[[nodiscard]] std::span<SubCommand> getSubCommands() const;
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
HMODULE m_handle = nullptr;
|
||||
#else
|
||||
void *m_handle = nullptr;
|
||||
#endif
|
||||
private:
|
||||
uintptr_t m_handle = 0;
|
||||
std::fs::path m_path;
|
||||
|
||||
mutable bool m_initialized = false;
|
||||
|
||||
InitializePluginFunc m_initializePluginFunction = nullptr;
|
||||
GetPluginNameFunc m_getPluginNameFunction = nullptr;
|
||||
GetPluginAuthorFunc m_getPluginAuthorFunction = nullptr;
|
||||
GetPluginDescriptionFunc m_getPluginDescriptionFunction = nullptr;
|
||||
GetCompatibleVersionFunc m_getCompatibleVersionFunction = nullptr;
|
||||
SetImGuiContextFunc m_setImGuiContextFunction = nullptr;
|
||||
IsBuiltinPluginFunc m_isBuiltinPluginFunction = nullptr;
|
||||
PluginFunctions m_functions = {};
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] auto getPluginFunction(const std::string &symbol) {
|
||||
return reinterpret_cast<T>(this->getPluginFunction(symbol));
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] void *getPluginFunction(const std::string &symbol);
|
||||
[[nodiscard]] void *getPluginFunction(const std::string &symbol) const;
|
||||
};
|
||||
|
||||
class PluginManager {
|
||||
@@ -79,13 +83,10 @@ namespace hex {
|
||||
static void unload();
|
||||
static void reload();
|
||||
|
||||
static const auto &getPlugins() {
|
||||
return PluginManager::s_plugins;
|
||||
}
|
||||
static void addPlugin(PluginFunctions functions);
|
||||
|
||||
private:
|
||||
static std::fs::path s_pluginFolder;
|
||||
static std::vector<Plugin> s_plugins;
|
||||
static std::vector<Plugin> &getPlugins();
|
||||
static std::vector<std::fs::path> &getPluginPaths();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,65 +1,125 @@
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/helpers/tar.hpp>
|
||||
|
||||
/**
|
||||
* @brief Project file manager
|
||||
*
|
||||
* The project file manager is used to load and store project files. It is used by all features of ImHex
|
||||
* that want to store any data to a Project File.
|
||||
*
|
||||
*/
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
class ProjectFile {
|
||||
public:
|
||||
struct Handler {
|
||||
using Function = std::function<bool(const std::fs::path &, Tar &tar)>;
|
||||
std::fs::path basePath;
|
||||
bool required;
|
||||
Function load, store;
|
||||
|
||||
std::fs::path basePath; //< Base path for where to store the files in the project file
|
||||
bool required; //< If true, ImHex will display an error if this handler fails to load or store data
|
||||
Function load, store; //< Functions to load and store data
|
||||
};
|
||||
|
||||
struct ProviderHandler {
|
||||
using Function = std::function<bool(prv::Provider *provider, const std::fs::path &, Tar &tar)>;
|
||||
std::fs::path basePath;
|
||||
bool required;
|
||||
Function load, store;
|
||||
|
||||
std::fs::path basePath; //< Base path for where to store the files in the project file
|
||||
bool required; //< If true, ImHex will display an error if this handler fails to load or store data
|
||||
Function load, store; //< Functions to load and store data
|
||||
};
|
||||
|
||||
static bool load(const std::fs::path &filePath);
|
||||
static bool store(std::optional<std::fs::path> filePath = std::nullopt);
|
||||
/**
|
||||
* @brief Set implementations for loading and restoring a project
|
||||
*
|
||||
* @param loadFun function to use to load a project in ImHex
|
||||
* @param storeFun function to use to store a project to disk
|
||||
*/
|
||||
static void setProjectFunctions(
|
||||
const std::function<bool(const std::fs::path&)> &loadFun,
|
||||
const std::function<bool(std::optional<std::fs::path>, bool)> &storeFun
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Load a project file
|
||||
*
|
||||
* @param filePath Path to the project file
|
||||
* @return true if the project file was loaded successfully
|
||||
* @return false if the project file was not loaded successfully
|
||||
*/
|
||||
static bool load(const std::fs::path &filePath);
|
||||
|
||||
/**
|
||||
* @brief Store a project file
|
||||
*
|
||||
* @param filePath Path to the project file
|
||||
* @param updateLocation update the project location so subssequent saves will save there
|
||||
* @return true if the project file was stored successfully
|
||||
* @return false if the project file was not stored successfully
|
||||
*/
|
||||
static bool store(std::optional<std::fs::path> filePath = std::nullopt, bool updateLocation = true);
|
||||
|
||||
/**
|
||||
* @brief Check if a project file is currently loaded
|
||||
*
|
||||
* @return true if a project file is currently loaded
|
||||
* @return false if no project file is currently loaded
|
||||
*/
|
||||
static bool hasPath();
|
||||
|
||||
/**
|
||||
* @brief Clear the currently loaded project file
|
||||
*/
|
||||
static void clearPath();
|
||||
|
||||
/**
|
||||
* @brief Get the path to the currently loaded project file
|
||||
* @return Path to the currently loaded project file
|
||||
*/
|
||||
static std::fs::path getPath();
|
||||
|
||||
/**
|
||||
* @brief Set the path to the currently loaded project file
|
||||
* @param path Path to the currently loaded project file
|
||||
*/
|
||||
static void setPath(const std::fs::path &path);
|
||||
|
||||
/**
|
||||
* @brief Register a handler for storing and loading global data from a project file
|
||||
*
|
||||
* @param handler The handler to register
|
||||
*/
|
||||
static void registerHandler(const Handler &handler) {
|
||||
getHandlers().push_back(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a handler for storing and loading per-provider data from a project file
|
||||
*
|
||||
* @param handler The handler to register
|
||||
*/
|
||||
static void registerPerProviderHandler(const ProviderHandler &handler) {
|
||||
getProviderHandlers().push_back(handler);
|
||||
}
|
||||
|
||||
static std::vector<Handler>& getHandlers() {
|
||||
return s_handlers;
|
||||
}
|
||||
/**
|
||||
* @brief Get the list of registered handlers
|
||||
* @return List of registered handlers
|
||||
*/
|
||||
static std::vector<Handler>& getHandlers();
|
||||
|
||||
static std::vector<ProviderHandler>& getProviderHandlers() {
|
||||
return s_providerHandlers;
|
||||
}
|
||||
/**
|
||||
* @brief Get the list of registered per-provider handlers
|
||||
* @return List of registered per-provider handlers
|
||||
*/
|
||||
static std::vector<ProviderHandler>& getProviderHandlers();
|
||||
|
||||
private:
|
||||
ProjectFile() = default;
|
||||
|
||||
static std::fs::path s_currProjectPath;
|
||||
static std::vector<Handler> s_handlers;
|
||||
static std::vector<ProviderHandler> s_providerHandlers;
|
||||
};
|
||||
|
||||
}
|
||||
454
lib/libimhex/include/hex/api/shortcut_manager.hpp
Normal file
454
lib/libimhex/include/hex/api/shortcut_manager.hpp
Normal file
@@ -0,0 +1,454 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class View;
|
||||
|
||||
enum class Keys {
|
||||
Space = GLFW_KEY_SPACE,
|
||||
Apostrophe = GLFW_KEY_APOSTROPHE,
|
||||
Comma = GLFW_KEY_COMMA,
|
||||
Minus = GLFW_KEY_MINUS,
|
||||
Period = GLFW_KEY_PERIOD,
|
||||
Slash = GLFW_KEY_SLASH,
|
||||
Num0 = GLFW_KEY_0,
|
||||
Num1 = GLFW_KEY_1,
|
||||
Num2 = GLFW_KEY_2,
|
||||
Num3 = GLFW_KEY_3,
|
||||
Num4 = GLFW_KEY_4,
|
||||
Num5 = GLFW_KEY_5,
|
||||
Num6 = GLFW_KEY_6,
|
||||
Num7 = GLFW_KEY_7,
|
||||
Num8 = GLFW_KEY_8,
|
||||
Num9 = GLFW_KEY_9,
|
||||
Semicolon = GLFW_KEY_SEMICOLON,
|
||||
Equals = GLFW_KEY_EQUAL,
|
||||
A = GLFW_KEY_A,
|
||||
B = GLFW_KEY_B,
|
||||
C = GLFW_KEY_C,
|
||||
D = GLFW_KEY_D,
|
||||
E = GLFW_KEY_E,
|
||||
F = GLFW_KEY_F,
|
||||
G = GLFW_KEY_G,
|
||||
H = GLFW_KEY_H,
|
||||
I = GLFW_KEY_I,
|
||||
J = GLFW_KEY_J,
|
||||
K = GLFW_KEY_K,
|
||||
L = GLFW_KEY_L,
|
||||
M = GLFW_KEY_M,
|
||||
N = GLFW_KEY_N,
|
||||
O = GLFW_KEY_O,
|
||||
P = GLFW_KEY_P,
|
||||
Q = GLFW_KEY_Q,
|
||||
R = GLFW_KEY_R,
|
||||
S = GLFW_KEY_S,
|
||||
T = GLFW_KEY_T,
|
||||
U = GLFW_KEY_U,
|
||||
V = GLFW_KEY_V,
|
||||
W = GLFW_KEY_W,
|
||||
X = GLFW_KEY_X,
|
||||
Y = GLFW_KEY_Y,
|
||||
Z = GLFW_KEY_Z,
|
||||
LeftBracket = GLFW_KEY_LEFT_BRACKET,
|
||||
Backslash = GLFW_KEY_BACKSLASH,
|
||||
RightBracket = GLFW_KEY_RIGHT_BRACKET,
|
||||
GraveAccent = GLFW_KEY_GRAVE_ACCENT,
|
||||
World1 = GLFW_KEY_WORLD_1,
|
||||
World2 = GLFW_KEY_WORLD_2,
|
||||
Escape = GLFW_KEY_ESCAPE,
|
||||
Enter = GLFW_KEY_ENTER,
|
||||
Tab = GLFW_KEY_TAB,
|
||||
Backspace = GLFW_KEY_BACKSPACE,
|
||||
Insert = GLFW_KEY_INSERT,
|
||||
Delete = GLFW_KEY_DELETE,
|
||||
Right = GLFW_KEY_RIGHT,
|
||||
Left = GLFW_KEY_LEFT,
|
||||
Down = GLFW_KEY_DOWN,
|
||||
Up = GLFW_KEY_UP,
|
||||
PageUp = GLFW_KEY_PAGE_UP,
|
||||
PageDown = GLFW_KEY_PAGE_DOWN,
|
||||
Home = GLFW_KEY_HOME,
|
||||
End = GLFW_KEY_END,
|
||||
CapsLock = GLFW_KEY_CAPS_LOCK,
|
||||
ScrollLock = GLFW_KEY_SCROLL_LOCK,
|
||||
NumLock = GLFW_KEY_NUM_LOCK,
|
||||
PrintScreen = GLFW_KEY_PRINT_SCREEN,
|
||||
Pause = GLFW_KEY_PAUSE,
|
||||
F1 = GLFW_KEY_F1,
|
||||
F2 = GLFW_KEY_F2,
|
||||
F3 = GLFW_KEY_F3,
|
||||
F4 = GLFW_KEY_F4,
|
||||
F5 = GLFW_KEY_F5,
|
||||
F6 = GLFW_KEY_F6,
|
||||
F7 = GLFW_KEY_F7,
|
||||
F8 = GLFW_KEY_F8,
|
||||
F9 = GLFW_KEY_F9,
|
||||
F10 = GLFW_KEY_F10,
|
||||
F11 = GLFW_KEY_F11,
|
||||
F12 = GLFW_KEY_F12,
|
||||
F13 = GLFW_KEY_F13,
|
||||
F14 = GLFW_KEY_F14,
|
||||
F15 = GLFW_KEY_F15,
|
||||
F16 = GLFW_KEY_F16,
|
||||
F17 = GLFW_KEY_F17,
|
||||
F18 = GLFW_KEY_F18,
|
||||
F19 = GLFW_KEY_F19,
|
||||
F20 = GLFW_KEY_F20,
|
||||
F21 = GLFW_KEY_F21,
|
||||
F22 = GLFW_KEY_F22,
|
||||
F23 = GLFW_KEY_F23,
|
||||
F24 = GLFW_KEY_F24,
|
||||
F25 = GLFW_KEY_F25,
|
||||
KeyPad0 = GLFW_KEY_KP_0,
|
||||
KeyPad1 = GLFW_KEY_KP_1,
|
||||
KeyPad2 = GLFW_KEY_KP_2,
|
||||
KeyPad3 = GLFW_KEY_KP_3,
|
||||
KeyPad4 = GLFW_KEY_KP_4,
|
||||
KeyPad5 = GLFW_KEY_KP_5,
|
||||
KeyPad6 = GLFW_KEY_KP_6,
|
||||
KeyPad7 = GLFW_KEY_KP_7,
|
||||
KeyPad8 = GLFW_KEY_KP_8,
|
||||
KeyPad9 = GLFW_KEY_KP_9,
|
||||
KeyPadDecimal = GLFW_KEY_KP_DECIMAL,
|
||||
KeyPadDivide = GLFW_KEY_KP_DIVIDE,
|
||||
KeyPadMultiply = GLFW_KEY_KP_MULTIPLY,
|
||||
KeyPadSubtract = GLFW_KEY_KP_SUBTRACT,
|
||||
KeyPadAdd = GLFW_KEY_KP_ADD,
|
||||
KeyPadEnter = GLFW_KEY_KP_ENTER,
|
||||
KeyPadEqual = GLFW_KEY_KP_EQUAL,
|
||||
Menu = GLFW_KEY_MENU,
|
||||
};
|
||||
|
||||
|
||||
class Key {
|
||||
public:
|
||||
constexpr Key() = default;
|
||||
constexpr Key(Keys key) : m_key(static_cast<u32>(key)) { }
|
||||
|
||||
auto operator<=>(const Key &) const = default;
|
||||
|
||||
[[nodiscard]] constexpr u32 getKeyCode() const { return this->m_key; }
|
||||
private:
|
||||
u32 m_key = 0;
|
||||
};
|
||||
|
||||
|
||||
constexpr static auto CTRL = Key(static_cast<Keys>(0x0100'0000));
|
||||
constexpr static auto ALT = Key(static_cast<Keys>(0x0200'0000));
|
||||
constexpr static auto SHIFT = Key(static_cast<Keys>(0x0400'0000));
|
||||
constexpr static auto SUPER = Key(static_cast<Keys>(0x0800'0000));
|
||||
constexpr static auto CurrentView = Key(static_cast<Keys>(0x1000'0000));
|
||||
constexpr static auto AllowWhileTyping = Key(static_cast<Keys>(0x2000'0000));
|
||||
|
||||
#if defined (OS_MACOS)
|
||||
constexpr static auto CTRLCMD = SUPER;
|
||||
#else
|
||||
constexpr static auto CTRLCMD = CTRL;
|
||||
#endif
|
||||
|
||||
class Shortcut {
|
||||
public:
|
||||
Shortcut() = default;
|
||||
Shortcut(Keys key) : m_keys({ key }) { }
|
||||
explicit Shortcut(std::set<Key> keys) : m_keys(std::move(keys)) { }
|
||||
Shortcut(const Shortcut &other) = default;
|
||||
Shortcut(Shortcut &&) noexcept = default;
|
||||
|
||||
Shortcut& operator=(const Shortcut &other) = default;
|
||||
|
||||
Shortcut& operator=(Shortcut &&) noexcept = default;
|
||||
|
||||
constexpr static inline auto None = Keys(0);
|
||||
|
||||
Shortcut operator+(const Key &other) const {
|
||||
Shortcut result = *this;
|
||||
result.m_keys.insert(other);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shortcut &operator+=(const Key &other) {
|
||||
this->m_keys.insert(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const Shortcut &other) const {
|
||||
return this->m_keys < other.m_keys;
|
||||
}
|
||||
|
||||
bool operator==(const Shortcut &other) const {
|
||||
auto thisKeys = this->m_keys;
|
||||
auto otherKeys = other.m_keys;
|
||||
|
||||
thisKeys.erase(CurrentView);
|
||||
thisKeys.erase(AllowWhileTyping);
|
||||
otherKeys.erase(CurrentView);
|
||||
otherKeys.erase(AllowWhileTyping);
|
||||
|
||||
return thisKeys == otherKeys;
|
||||
}
|
||||
|
||||
bool isLocal() const {
|
||||
return this->m_keys.contains(CurrentView);
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
std::string result;
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
constexpr static auto CTRL_NAME = "CTRL";
|
||||
constexpr static auto ALT_NAME = "OPT";
|
||||
constexpr static auto SHIFT_NAME = "SHIFT";
|
||||
constexpr static auto SUPER_NAME = "CMD";
|
||||
#else
|
||||
constexpr static auto CTRL_NAME = "CTRL";
|
||||
constexpr static auto ALT_NAME = "ALT";
|
||||
constexpr static auto SHIFT_NAME = "SHIFT";
|
||||
constexpr static auto SUPER_NAME = "SUPER";
|
||||
#endif
|
||||
|
||||
constexpr static auto Concatination = " + ";
|
||||
|
||||
auto keys = this->m_keys;
|
||||
if (keys.erase(CTRL) > 0) {
|
||||
result += CTRL_NAME;
|
||||
result += Concatination;
|
||||
}
|
||||
if (keys.erase(ALT) > 0) {
|
||||
result += ALT_NAME;
|
||||
result += Concatination;
|
||||
}
|
||||
if (keys.erase(SHIFT) > 0) {
|
||||
result += SHIFT_NAME;
|
||||
result += Concatination;
|
||||
}
|
||||
if (keys.erase(SUPER) > 0) {
|
||||
result += SUPER_NAME;
|
||||
result += Concatination;
|
||||
}
|
||||
keys.erase(CurrentView);
|
||||
|
||||
for (const auto &key : keys) {
|
||||
switch (Keys(key.getKeyCode())) {
|
||||
case Keys::Space: result += "SPACE"; break;
|
||||
case Keys::Apostrophe: result += "'"; break;
|
||||
case Keys::Comma: result += ","; break;
|
||||
case Keys::Minus: result += "-"; break;
|
||||
case Keys::Period: result += "."; break;
|
||||
case Keys::Slash: result += "/"; break;
|
||||
case Keys::Num0: result += "0"; break;
|
||||
case Keys::Num1: result += "1"; break;
|
||||
case Keys::Num2: result += "2"; break;
|
||||
case Keys::Num3: result += "3"; break;
|
||||
case Keys::Num4: result += "4"; break;
|
||||
case Keys::Num5: result += "5"; break;
|
||||
case Keys::Num6: result += "6"; break;
|
||||
case Keys::Num7: result += "7"; break;
|
||||
case Keys::Num8: result += "8"; break;
|
||||
case Keys::Num9: result += "9"; break;
|
||||
case Keys::Semicolon: result += ";"; break;
|
||||
case Keys::Equals: result += "="; break;
|
||||
case Keys::A: result += "A"; break;
|
||||
case Keys::B: result += "B"; break;
|
||||
case Keys::C: result += "C"; break;
|
||||
case Keys::D: result += "D"; break;
|
||||
case Keys::E: result += "E"; break;
|
||||
case Keys::F: result += "F"; break;
|
||||
case Keys::G: result += "G"; break;
|
||||
case Keys::H: result += "H"; break;
|
||||
case Keys::I: result += "I"; break;
|
||||
case Keys::J: result += "J"; break;
|
||||
case Keys::K: result += "K"; break;
|
||||
case Keys::L: result += "L"; break;
|
||||
case Keys::M: result += "M"; break;
|
||||
case Keys::N: result += "N"; break;
|
||||
case Keys::O: result += "O"; break;
|
||||
case Keys::P: result += "P"; break;
|
||||
case Keys::Q: result += "Q"; break;
|
||||
case Keys::R: result += "R"; break;
|
||||
case Keys::S: result += "S"; break;
|
||||
case Keys::T: result += "T"; break;
|
||||
case Keys::U: result += "U"; break;
|
||||
case Keys::V: result += "V"; break;
|
||||
case Keys::W: result += "W"; break;
|
||||
case Keys::X: result += "X"; break;
|
||||
case Keys::Y: result += "Y"; break;
|
||||
case Keys::Z: result += "Z"; break;
|
||||
case Keys::LeftBracket: result += "["; break;
|
||||
case Keys::Backslash: result += "\\"; break;
|
||||
case Keys::RightBracket: result += "]"; break;
|
||||
case Keys::GraveAccent: result += "`"; break;
|
||||
case Keys::World1: result += "WORLD1"; break;
|
||||
case Keys::World2: result += "WORLD2"; break;
|
||||
case Keys::Escape: result += "ESC"; break;
|
||||
case Keys::Enter: result += "ENTER"; break;
|
||||
case Keys::Tab: result += "TAB"; break;
|
||||
case Keys::Backspace: result += "BACKSPACE"; break;
|
||||
case Keys::Insert: result += "INSERT"; break;
|
||||
case Keys::Delete: result += "DELETE"; break;
|
||||
case Keys::Right: result += "RIGHT"; break;
|
||||
case Keys::Left: result += "LEFT"; break;
|
||||
case Keys::Down: result += "DOWN"; break;
|
||||
case Keys::Up: result += "UP"; break;
|
||||
case Keys::PageUp: result += "PAGEUP"; break;
|
||||
case Keys::PageDown: result += "PAGEDOWN"; break;
|
||||
case Keys::Home: result += "HOME"; break;
|
||||
case Keys::End: result += "END"; break;
|
||||
case Keys::CapsLock: result += "CAPSLOCK"; break;
|
||||
case Keys::ScrollLock: result += "SCROLLLOCK"; break;
|
||||
case Keys::NumLock: result += "NUMLOCK"; break;
|
||||
case Keys::PrintScreen: result += "PRINTSCREEN"; break;
|
||||
case Keys::Pause: result += "PAUSE"; break;
|
||||
case Keys::F1: result += "F1"; break;
|
||||
case Keys::F2: result += "F2"; break;
|
||||
case Keys::F3: result += "F3"; break;
|
||||
case Keys::F4: result += "F4"; break;
|
||||
case Keys::F5: result += "F5"; break;
|
||||
case Keys::F6: result += "F6"; break;
|
||||
case Keys::F7: result += "F7"; break;
|
||||
case Keys::F8: result += "F8"; break;
|
||||
case Keys::F9: result += "F9"; break;
|
||||
case Keys::F10: result += "F10"; break;
|
||||
case Keys::F11: result += "F11"; break;
|
||||
case Keys::F12: result += "F12"; break;
|
||||
case Keys::F13: result += "F13"; break;
|
||||
case Keys::F14: result += "F14"; break;
|
||||
case Keys::F15: result += "F15"; break;
|
||||
case Keys::F16: result += "F16"; break;
|
||||
case Keys::F17: result += "F17"; break;
|
||||
case Keys::F18: result += "F18"; break;
|
||||
case Keys::F19: result += "F19"; break;
|
||||
case Keys::F20: result += "F20"; break;
|
||||
case Keys::F21: result += "F21"; break;
|
||||
case Keys::F22: result += "F22"; break;
|
||||
case Keys::F23: result += "F23"; break;
|
||||
case Keys::F24: result += "F24"; break;
|
||||
case Keys::F25: result += "F25"; break;
|
||||
case Keys::KeyPad0: result += "KP0"; break;
|
||||
case Keys::KeyPad1: result += "KP1"; break;
|
||||
case Keys::KeyPad2: result += "KP2"; break;
|
||||
case Keys::KeyPad3: result += "KP3"; break;
|
||||
case Keys::KeyPad4: result += "KP4"; break;
|
||||
case Keys::KeyPad5: result += "KP5"; break;
|
||||
case Keys::KeyPad6: result += "KP6"; break;
|
||||
case Keys::KeyPad7: result += "KP7"; break;
|
||||
case Keys::KeyPad8: result += "KP8"; break;
|
||||
case Keys::KeyPad9: result += "KP9"; break;
|
||||
case Keys::KeyPadDecimal: result += "KPDECIMAL"; break;
|
||||
case Keys::KeyPadDivide: result += "KPDIVIDE"; break;
|
||||
case Keys::KeyPadMultiply: result += "KPMULTIPLY"; break;
|
||||
case Keys::KeyPadSubtract: result += "KPSUBTRACT"; break;
|
||||
case Keys::KeyPadAdd: result += "KPADD"; break;
|
||||
case Keys::KeyPadEnter: result += "KPENTER"; break;
|
||||
case Keys::KeyPadEqual: result += "KPEQUAL"; break;
|
||||
case Keys::Menu: result += "MENU"; break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
result += " + ";
|
||||
}
|
||||
|
||||
if (result.ends_with(" + "))
|
||||
result = result.substr(0, result.size() - 3);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::set<Key>& getKeys() const { return this->m_keys; }
|
||||
|
||||
private:
|
||||
friend Shortcut operator+(const Key &lhs, const Key &rhs);
|
||||
|
||||
std::set<Key> m_keys;
|
||||
};
|
||||
|
||||
inline Shortcut operator+(const Key &lhs, const Key &rhs) {
|
||||
Shortcut result;
|
||||
result.m_keys = { lhs, rhs };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The ShortcutManager handles global and view-specific shortcuts.
|
||||
* New shortcuts can be constructed using the + operator on Key objects. For example: CTRL + ALT + Keys::A
|
||||
*/
|
||||
class ShortcutManager {
|
||||
public:
|
||||
using Callback = std::function<void()>;
|
||||
struct ShortcutEntry {
|
||||
Shortcut shortcut;
|
||||
std::string unlocalizedName;
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Add a global shortcut. Global shortcuts can be triggered regardless of what view is currently focused
|
||||
* @param shortcut The shortcut to add.
|
||||
* @param unlocalizedName The unlocalized name of the shortcut
|
||||
* @param callback The callback to call when the shortcut is triggered.
|
||||
*/
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const std::string &unlocalizedName, const Callback &callback);
|
||||
|
||||
/**
|
||||
* @brief Add a view-specific shortcut. View-specific shortcuts can only be triggered when the specified view is focused.
|
||||
* @param view The view to add the shortcut to.
|
||||
* @param shortcut The shortcut to add.
|
||||
* @param unlocalizedName The unlocalized name of the shortcut
|
||||
* @param callback The callback to call when the shortcut is triggered.
|
||||
*/
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const std::string &unlocalizedName, const Callback &callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Process a key event. This should be called from the main loop.
|
||||
* @param currentView Current view to process
|
||||
* @param ctrl Whether the CTRL key is pressed
|
||||
* @param alt Whether the ALT key is pressed
|
||||
* @param shift Whether the SHIFT key is pressed
|
||||
* @param super Whether the SUPER key is pressed
|
||||
* @param focused Whether the current view is focused
|
||||
* @param keyCode The key code of the key that was pressed
|
||||
*/
|
||||
static void process(const std::unique_ptr<View> ¤tView, bool ctrl, bool alt, bool shift, bool super, bool focused, u32 keyCode);
|
||||
|
||||
/**
|
||||
* @brief Process a key event. This should be called from the main loop.
|
||||
* @param ctrl Whether the CTRL key is pressed
|
||||
* @param alt Whether the ALT key is pressed
|
||||
* @param shift Whether the SHIFT key is pressed
|
||||
* @param super Whether the SUPER key is pressed
|
||||
* @param keyCode The key code of the key that was pressed
|
||||
*/
|
||||
static void processGlobals(bool ctrl, bool alt, bool shift, bool super, u32 keyCode);
|
||||
|
||||
/**
|
||||
* @brief Clear all shortcuts
|
||||
*/
|
||||
static void clearShortcuts();
|
||||
|
||||
static void resumeShortcuts();
|
||||
static void pauseShortcuts();
|
||||
|
||||
[[nodiscard]] static std::optional<Shortcut> getPreviousShortcut();
|
||||
|
||||
[[nodiscard]] static std::vector<ShortcutEntry> getGlobalShortcuts();
|
||||
[[nodiscard]] static std::vector<ShortcutEntry> getViewShortcuts(View *view);
|
||||
|
||||
[[nodiscard]] static bool updateShortcut(const Shortcut &oldShortcut, const Shortcut &newShortcut, View *view = nullptr);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -5,18 +5,21 @@
|
||||
#include <cstdio>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <jthread.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class TaskHolder;
|
||||
class TaskManager;
|
||||
|
||||
/**
|
||||
* @brief A type representing a running asynchronous task
|
||||
*/
|
||||
class Task {
|
||||
public:
|
||||
Task() = default;
|
||||
@@ -26,14 +29,38 @@ namespace hex {
|
||||
Task(Task &&other) noexcept;
|
||||
~Task();
|
||||
|
||||
/**
|
||||
* @brief Updates the current process value of the task
|
||||
* @param value Current value
|
||||
*/
|
||||
void update(u64 value = 0);
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum value of the task
|
||||
* @param value Maximum value of the task
|
||||
*/
|
||||
void setMaxValue(u64 value);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interrupts the task
|
||||
* For regular Tasks, this just throws an exception to stop the task.
|
||||
* If a custom interrupt callback is set, an exception is thrown and the callback is called.
|
||||
*/
|
||||
void interrupt();
|
||||
|
||||
/**
|
||||
* @brief Sets a callback that is called when the task is interrupted
|
||||
* @param callback Callback to be called
|
||||
*/
|
||||
void setInterruptCallback(std::function<void()> callback);
|
||||
|
||||
[[nodiscard]] bool isBackgroundTask() const;
|
||||
[[nodiscard]] bool isFinished() const;
|
||||
[[nodiscard]] bool hadException() const;
|
||||
[[nodiscard]] bool wasInterrupted() const;
|
||||
[[nodiscard]] bool shouldInterrupt() const;
|
||||
|
||||
void clearException();
|
||||
[[nodiscard]] std::string getExceptionMessage() const;
|
||||
|
||||
@@ -41,10 +68,6 @@ namespace hex {
|
||||
[[nodiscard]] u64 getValue() const;
|
||||
[[nodiscard]] u64 getMaxValue() const;
|
||||
|
||||
void interrupt();
|
||||
|
||||
void setInterruptCallback(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
void finish();
|
||||
void interruption();
|
||||
@@ -72,6 +95,9 @@ namespace hex {
|
||||
friend class TaskManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A type holding a weak reference to a Task
|
||||
*/
|
||||
class TaskHolder {
|
||||
public:
|
||||
TaskHolder() = default;
|
||||
@@ -82,11 +108,16 @@ namespace hex {
|
||||
[[nodiscard]] bool wasInterrupted() const;
|
||||
[[nodiscard]] bool shouldInterrupt() const;
|
||||
|
||||
void interrupt();
|
||||
[[nodiscard]] u32 getProgress() const;
|
||||
|
||||
void interrupt() const;
|
||||
private:
|
||||
std::weak_ptr<Task> m_task;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Task Manager is responsible for running and managing asynchronous tasks
|
||||
*/
|
||||
class TaskManager {
|
||||
public:
|
||||
TaskManager() = delete;
|
||||
@@ -96,31 +127,44 @@ namespace hex {
|
||||
|
||||
constexpr static auto NoProgress = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates a new asynchronous task that gets displayed in the Task Manager in the footer
|
||||
* @param name Name of the task
|
||||
* @param maxValue Maximum value of the task
|
||||
* @param function Function to be executed
|
||||
* @return A TaskHolder holding a weak reference to the task
|
||||
*/
|
||||
static TaskHolder createTask(std::string name, u64 maxValue, std::function<void(Task &)> function);
|
||||
|
||||
/**
|
||||
* @brief Creates a new asynchronous task that does not get displayed in the Task Manager
|
||||
* @param name Name of the task
|
||||
* @param function Function to be executed
|
||||
* @return A TaskHolder holding a weak reference to the task
|
||||
*/
|
||||
static TaskHolder createBackgroundTask(std::string name, std::function<void(Task &)> function);
|
||||
|
||||
/**
|
||||
* @brief Creates a new synchronous task that will execute the given function at the start of the next frame
|
||||
* @param function Function to be executed
|
||||
*/
|
||||
static void doLater(const std::function<void()> &function);
|
||||
|
||||
/**
|
||||
* @brief Creates a callback that will be executed when all tasks are finished
|
||||
* @param function Function to be executed
|
||||
*/
|
||||
static void runWhenTasksFinished(const std::function<void()> &function);
|
||||
|
||||
static void collectGarbage();
|
||||
|
||||
static size_t getRunningTaskCount();
|
||||
static size_t getRunningBackgroundTaskCount();
|
||||
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
||||
|
||||
static void doLater(const std::function<void()> &function);
|
||||
static std::list<std::shared_ptr<Task>> &getRunningTasks();
|
||||
static void runDeferredCalls();
|
||||
|
||||
static void runWhenTasksFinished(const std::function<void()> &function);
|
||||
private:
|
||||
static std::mutex s_deferredCallsMutex, s_tasksFinishedMutex;
|
||||
|
||||
static std::list<std::shared_ptr<Task>> s_tasks;
|
||||
static std::list<std::shared_ptr<Task>> s_taskQueue;
|
||||
static std::list<std::function<void()>> s_deferredCalls;
|
||||
static std::list<std::function<void()>> s_tasksFinishedCallbacks;
|
||||
|
||||
static std::mutex s_queueMutex;
|
||||
static std::condition_variable s_jobCondVar;
|
||||
static std::vector<std::jthread> s_workers;
|
||||
|
||||
static void runner(const std::stop_token &stopToken);
|
||||
};
|
||||
|
||||
@@ -4,34 +4,85 @@
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace hex::api {
|
||||
namespace hex {
|
||||
|
||||
/**
|
||||
* @brief The Theme Manager takes care of loading and applying themes
|
||||
*/
|
||||
class ThemeManager {
|
||||
public:
|
||||
constexpr static auto NativeTheme = "Native";
|
||||
|
||||
using ColorMap = std::map<std::string, u32>;
|
||||
|
||||
struct Style {
|
||||
std::variant<ImVec2*, float*> value;
|
||||
float min;
|
||||
float max;
|
||||
bool needsScaling;
|
||||
};
|
||||
using StyleMap = std::map<std::string, Style>;
|
||||
|
||||
/**
|
||||
* @brief Changes the current theme to the one with the given name
|
||||
* @param name Name of the theme to change to
|
||||
*/
|
||||
static void changeTheme(std::string name);
|
||||
|
||||
/**
|
||||
* @brief Adds a theme from json data
|
||||
* @param content JSON data of the theme
|
||||
*/
|
||||
static void addTheme(const std::string &content);
|
||||
static void addThemeHandler(const std::string &name, const std::function<void(std::string, std::string)> &handler);
|
||||
static void addStyleHandler(const std::string &name, const std::function<void(std::string, std::string)> &handler);
|
||||
|
||||
/**
|
||||
* @brief Adds a theme handler to handle color values loaded from a theme file
|
||||
* @param name Name of the handler
|
||||
* @param colorMap Map of color names to their respective constants
|
||||
* @param getFunction Function to get the color value of a constant
|
||||
* @param setFunction Function to set the color value of a constant
|
||||
*/
|
||||
static void addThemeHandler(const std::string &name, const ColorMap &colorMap, const std::function<ImColor(u32)> &getFunction, const std::function<void(u32, ImColor)> &setFunction);
|
||||
|
||||
/**
|
||||
* @brief Adds a style handler to handle style values loaded from a theme file
|
||||
* @param name Name of the handler
|
||||
* @param styleMap Map of style names to their respective constants
|
||||
*/
|
||||
static void addStyleHandler(const std::string &name, const StyleMap &styleMap);
|
||||
|
||||
|
||||
static std::vector<std::string> getThemeNames();
|
||||
static const std::string &getThemeImagePostfix();
|
||||
static const std::string &getImageTheme();
|
||||
|
||||
static std::optional<ImColor> parseColorString(const std::string &colorString);
|
||||
|
||||
static nlohmann::json exportCurrentTheme(const std::string &name);
|
||||
|
||||
static void reset();
|
||||
|
||||
|
||||
public:
|
||||
struct ThemeHandler {
|
||||
ColorMap colorMap;
|
||||
std::function<ImColor(u32)> getFunction;
|
||||
std::function<void(u32, ImColor)> setFunction;
|
||||
};
|
||||
|
||||
struct StyleHandler {
|
||||
StyleMap styleMap;
|
||||
};
|
||||
|
||||
static std::map<std::string, ThemeHandler>& getThemeHandlers();
|
||||
static std::map<std::string, StyleHandler>& getStyleHandlers();
|
||||
|
||||
private:
|
||||
ThemeManager() = default;
|
||||
|
||||
static std::map<std::string, nlohmann::json> s_themes;
|
||||
static std::map<std::string, std::function<void(std::string, std::string)>> s_themeHandlers, s_styleHandlers;
|
||||
static std::string s_imagePostfix;
|
||||
};
|
||||
|
||||
}
|
||||
4
lib/libimhex/include/hex/api_urls.hpp
Normal file
4
lib/libimhex/include/hex/api_urls.hpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
constexpr static auto ImHexApiURL = "https://api.werwolv.net/imhex";
|
||||
constexpr static auto GitHubApiURL = "https://api.github.com/repos/WerWolv/ImHex";
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
@@ -51,10 +50,7 @@ namespace hex::dp {
|
||||
|
||||
[[nodiscard]] std::vector<u8>& getDefaultData() { return this->m_defaultData; }
|
||||
|
||||
static void setIdCounter(int id) {
|
||||
if (id > Attribute::s_idCounter)
|
||||
Attribute::s_idCounter = id;
|
||||
}
|
||||
static void setIdCounter(int id);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
namespace hex::dp {
|
||||
|
||||
class Link {
|
||||
@@ -14,10 +12,7 @@ namespace hex::dp {
|
||||
[[nodiscard]] int getFromId() const { return this->m_from; }
|
||||
[[nodiscard]] int getToId() const { return this->m_to; }
|
||||
|
||||
static void setIdCounter(int id) {
|
||||
if (id > Link::s_idCounter)
|
||||
Link::s_idCounter = id;
|
||||
}
|
||||
static void setIdCounter(int id);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
#include <hex/data_processor/attribute.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
@@ -68,18 +69,15 @@ namespace hex::dp {
|
||||
return this->m_position;
|
||||
}
|
||||
|
||||
static void setIdCounter(int id) {
|
||||
if (id > Node::s_idCounter)
|
||||
Node::s_idCounter = id;
|
||||
}
|
||||
static void setIdCounter(int id);
|
||||
|
||||
const std::vector<u8>& getBufferOnInput(u32 index);
|
||||
const i128& getIntegerOnInput(u32 index);
|
||||
const long double& getFloatOnInput(u32 index);
|
||||
const double& getFloatOnInput(u32 index);
|
||||
|
||||
void setBufferOnOutput(u32 index, const std::vector<u8> &data);
|
||||
void setBufferOnOutput(u32 index, std::span<const u8> data);
|
||||
void setIntegerOnOutput(u32 index, i128 integer);
|
||||
void setFloatOnOutput(u32 index, long double floatingPoint);
|
||||
void setFloatOnOutput(u32 index, double floatingPoint);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
@@ -113,6 +111,10 @@ namespace hex::dp {
|
||||
throwNodeError("Recursion detected!");
|
||||
}
|
||||
|
||||
void unmarkInputProcessed(u32 index) {
|
||||
this->m_processedInputs.erase(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
[[noreturn]] void throwNodeError(const std::string &message) {
|
||||
throw NodeError { this, message };
|
||||
|
||||
103
lib/libimhex/include/hex/helpers/binary_pattern.hpp
Normal file
103
lib/libimhex/include/hex/helpers/binary_pattern.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class BinaryPattern {
|
||||
public:
|
||||
struct Pattern {
|
||||
u8 mask, value;
|
||||
};
|
||||
|
||||
BinaryPattern() = default;
|
||||
explicit BinaryPattern(const std::string &pattern) : m_patterns(parseBinaryPatternString(pattern)) { }
|
||||
|
||||
[[nodiscard]] bool isValid() const { return !this->m_patterns.empty(); }
|
||||
|
||||
[[nodiscard]] bool matches(const std::vector<u8> &bytes) const {
|
||||
if (bytes.size() < this->m_patterns.size())
|
||||
return false;
|
||||
|
||||
for (u32 i = 0; i < this->m_patterns.size(); i++) {
|
||||
if (!this->matchesByte(bytes[i], i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool matchesByte(u8 byte, u32 offset) const {
|
||||
const auto &pattern = this->m_patterns[offset];
|
||||
|
||||
return (byte & pattern.mask) == pattern.value;
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t getSize() const {
|
||||
return this->m_patterns.size();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::vector<Pattern> parseBinaryPatternString(std::string string) {
|
||||
std::vector<Pattern> result;
|
||||
|
||||
if (string.length() < 2)
|
||||
return { };
|
||||
|
||||
bool inString = false;
|
||||
while (string.length() > 0) {
|
||||
Pattern pattern = { 0, 0 };
|
||||
if (string.starts_with("\"")) {
|
||||
inString = !inString;
|
||||
string = string.substr(1);
|
||||
continue;
|
||||
} else if (inString) {
|
||||
pattern = { 0xFF, u8(string.front()) };
|
||||
string = string.substr(1);
|
||||
} else if (string.starts_with("??")) {
|
||||
pattern = { 0x00, 0x00 };
|
||||
string = string.substr(2);
|
||||
} else if ((std::isxdigit(string.front()) || string.front() == '?') && string.length() >= 2) {
|
||||
const auto hex = string.substr(0, 2);
|
||||
|
||||
for (const auto &c : hex) {
|
||||
pattern.mask <<= 4;
|
||||
pattern.value <<= 4;
|
||||
|
||||
if (std::isxdigit(c)) {
|
||||
pattern.mask |= 0x0F;
|
||||
|
||||
if (auto hexValue = hex::hexCharToValue(c); hexValue.has_value())
|
||||
pattern.value |= hexValue.value();
|
||||
else
|
||||
return { };
|
||||
} else if (c != '?') {
|
||||
return { };
|
||||
}
|
||||
}
|
||||
|
||||
string = string.substr(2);
|
||||
} else if (std::isspace(string.front())) {
|
||||
string = string.substr(1);
|
||||
continue;
|
||||
} else {
|
||||
return { };
|
||||
}
|
||||
|
||||
result.push_back(pattern);
|
||||
}
|
||||
|
||||
if (inString)
|
||||
return { };
|
||||
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
std::vector<Pattern> m_patterns;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
@@ -16,8 +14,9 @@ namespace hex {
|
||||
concept has_size = sizeof(T) == Size;
|
||||
|
||||
template<typename T>
|
||||
class Cloneable {
|
||||
class ICloneable {
|
||||
public:
|
||||
virtual ~ICloneable() = default;
|
||||
[[nodiscard]] virtual std::unique_ptr<T> clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -16,9 +15,9 @@ namespace hex::crypt {
|
||||
void initialize();
|
||||
void exit();
|
||||
|
||||
u8 crc8(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
|
||||
u16 crc16(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
|
||||
u32 crc32(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorout, bool reflectIn, bool reflectOut);
|
||||
u8 crc8(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorOut, bool reflectIn, bool reflectOut);
|
||||
u16 crc16(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorOut, bool reflectIn, bool reflectOut);
|
||||
u32 crc32(prv::Provider *&data, u64 offset, size_t size, u32 polynomial, u32 init, u32 xorOut, bool reflectIn, bool reflectOut);
|
||||
|
||||
std::array<u8, 16> md5(prv::Provider *&data, u64 offset, size_t size);
|
||||
std::array<u8, 20> sha1(prv::Provider *&data, u64 offset, size_t size);
|
||||
|
||||
47
lib/libimhex/include/hex/helpers/debugging.hpp
Normal file
47
lib/libimhex/include/hex/helpers/debugging.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <wolv/utils/preproc.hpp>
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define DBG_DEFINE_DEBUG_VARIABLE(type, name) \
|
||||
static type name; \
|
||||
hex::dbg::impl::drawDebugVariable(name, WOLV_STRINGIFY(name));
|
||||
#else
|
||||
#define DBG_DEFINE_DEBUG_VARIABLE(type, name) \
|
||||
static_assert(false, "Debug variables are only intended for use during development.");
|
||||
#endif
|
||||
|
||||
namespace hex::dbg {
|
||||
|
||||
namespace impl {
|
||||
bool &getDebugWindowState();
|
||||
|
||||
template<typename T>
|
||||
static void drawDebugVariable(T &variable, std::string_view name) {
|
||||
if (!getDebugWindowState())
|
||||
return;
|
||||
|
||||
if (ImGui::Begin("Debug Variables", &getDebugWindowState(), ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
using Type = std::remove_cvref_t<T>;
|
||||
if constexpr (std::same_as<Type, bool>) {
|
||||
ImGui::Checkbox(name.data(), &variable);
|
||||
} else if constexpr (std::integral<Type> || std::floating_point<Type>) {
|
||||
ImGui::InputScalar(name.data(), ImGuiExt::getImGuiDataType<Type>(), &variable);
|
||||
} else if constexpr (std::same_as<Type, ImVec2>) {
|
||||
ImGui::InputFloat2(name.data(), &variable.x);
|
||||
} else if constexpr (std::same_as<Type, std::string>) {
|
||||
ImGui::InputText(name.data(), variable);
|
||||
} else if constexpr (std::same_as<Type, ImColor>) {
|
||||
ImGui::ColorEdit4(name.data(), &variable.Value.x, ImGuiColorEditFlags_AlphaBar);
|
||||
} else {
|
||||
static_assert(hex::always_false<Type>::value, "Unsupported type");
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,25 +8,32 @@ namespace hex {
|
||||
|
||||
enum class Architecture : i32
|
||||
{
|
||||
ARM,
|
||||
ARM64,
|
||||
MIPS,
|
||||
X86,
|
||||
PPC,
|
||||
SPARC,
|
||||
SYSZ,
|
||||
XCORE,
|
||||
M68K,
|
||||
TMS320C64X,
|
||||
M680X,
|
||||
EVM,
|
||||
MOS65XX,
|
||||
WASM,
|
||||
BPF,
|
||||
RISCV,
|
||||
ARM = CS_ARCH_ARM,
|
||||
ARM64 = CS_ARCH_ARM64,
|
||||
MIPS = CS_ARCH_MIPS,
|
||||
X86 = CS_ARCH_X86,
|
||||
PPC = CS_ARCH_PPC,
|
||||
SPARC = CS_ARCH_SPARC,
|
||||
SYSZ = CS_ARCH_SYSZ,
|
||||
XCORE = CS_ARCH_XCORE,
|
||||
M68K = CS_ARCH_M68K,
|
||||
TMS320C64X = CS_ARCH_TMS320C64X,
|
||||
M680X = CS_ARCH_M680X,
|
||||
EVM = CS_ARCH_EVM,
|
||||
|
||||
MAX,
|
||||
MIN = ARM
|
||||
#if CS_API_MAJOR >= 5
|
||||
WASM = CS_ARCH_WASM,
|
||||
RISCV = CS_ARCH_RISCV,
|
||||
MOS65XX = CS_ARCH_MOS65XX,
|
||||
BPF = CS_ARCH_BPF,
|
||||
SH = CS_ARCH_SH,
|
||||
TRICORE = CS_ARCH_TRICORE,
|
||||
MAX = TRICORE,
|
||||
# else
|
||||
MAX = EVM,
|
||||
#endif
|
||||
|
||||
MIN = ARM
|
||||
};
|
||||
|
||||
class Disassembler {
|
||||
@@ -35,20 +42,46 @@ namespace hex {
|
||||
return static_cast<cs_arch>(architecture);
|
||||
}
|
||||
|
||||
static inline bool isSupported(Architecture architecture) {
|
||||
static bool isSupported(Architecture architecture) {
|
||||
return cs_support(toCapstoneArchitecture(architecture));
|
||||
}
|
||||
|
||||
constexpr static const char *const ArchitectureNames[] = { "ARM32", "ARM64", "MIPS", "x86", "PowerPC", "Sparc", "SystemZ", "XCore", "68K", "TMS320C64x", "680X", "Ethereum", "MOS65XX", "WebAssembly", "Berkeley Packet Filter", "RISC-V" };
|
||||
constexpr static auto ArchitectureNames = []{
|
||||
std::array<const char *, static_cast<u32>(Architecture::MAX) + 1> names = { };
|
||||
|
||||
static inline i32 getArchitectureSupportedCount() {
|
||||
names[CS_ARCH_ARM] = "ARM";
|
||||
names[CS_ARCH_ARM64] = "AArch64";
|
||||
names[CS_ARCH_MIPS] = "MIPS";
|
||||
names[CS_ARCH_X86] = "Intel x86";
|
||||
names[CS_ARCH_PPC] = "PowerPC";
|
||||
names[CS_ARCH_SPARC] = "SPARC";
|
||||
names[CS_ARCH_SYSZ] = "SystemZ";
|
||||
names[CS_ARCH_XCORE] = "XCore";
|
||||
names[CS_ARCH_M68K] = "Motorola 68K";
|
||||
names[CS_ARCH_TMS320C64X] = "TMS320C64x";
|
||||
names[CS_ARCH_M680X] = "M680X";
|
||||
names[CS_ARCH_EVM] = "Ethereum Virtual Machine";
|
||||
|
||||
#if CS_API_MAJOR >= 5
|
||||
names[CS_ARCH_WASM] = "WebAssembly";
|
||||
names[CS_ARCH_RISCV] = "RISC-V";
|
||||
names[CS_ARCH_MOS65XX] = "MOS Technology 65xx";
|
||||
names[CS_ARCH_BPF] = "Berkeley Packet Filter";
|
||||
names[CS_ARCH_SH] = "SuperH";
|
||||
names[CS_ARCH_TRICORE] = "Tricore";
|
||||
#endif
|
||||
|
||||
return names;
|
||||
}();
|
||||
|
||||
static i32 getArchitectureSupportedCount() {
|
||||
static i32 supportedCount = -1;
|
||||
|
||||
if (supportedCount != -1) {
|
||||
return supportedCount;
|
||||
}
|
||||
|
||||
for (supportedCount = static_cast<i32>(Architecture::MIN); supportedCount < static_cast<i32>(Architecture::MAX); supportedCount++) {
|
||||
for (supportedCount = static_cast<i32>(Architecture::MIN); supportedCount < static_cast<i32>(Architecture::MAX) + 1; supportedCount++) {
|
||||
if (!cs_support(supportedCount)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include <vector>
|
||||
#include <span>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/file.hpp>
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -19,20 +18,33 @@ namespace hex {
|
||||
Thingy
|
||||
};
|
||||
|
||||
EncodingFile() = default;
|
||||
EncodingFile();
|
||||
EncodingFile(const EncodingFile &other);
|
||||
EncodingFile(EncodingFile &&other) noexcept;
|
||||
EncodingFile(Type type, const std::fs::path &path);
|
||||
EncodingFile(Type type, const std::string &content);
|
||||
|
||||
EncodingFile& operator=(const EncodingFile &other);
|
||||
EncodingFile& operator=(EncodingFile &&other) noexcept;
|
||||
|
||||
[[nodiscard]] std::pair<std::string_view, size_t> getEncodingFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getEncodingLengthFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getLongestSequence() const { return this->m_longestSequence; }
|
||||
|
||||
[[nodiscard]] bool valid() const { return this->m_valid; }
|
||||
|
||||
[[nodiscard]] const std::string& getTableContent() const { return this->m_tableContent; }
|
||||
|
||||
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
||||
|
||||
private:
|
||||
void parseThingyFile(fs::File &file);
|
||||
void parse(const std::string &content);
|
||||
|
||||
bool m_valid = false;
|
||||
|
||||
std::map<size_t, std::map<std::vector<u8>, std::string>> m_mapping;
|
||||
std::string m_name;
|
||||
std::string m_tableContent;
|
||||
std::unique_ptr<std::map<size_t, std::map<std::vector<u8>, std::string>>> m_mapping;
|
||||
size_t m_longestSequence = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
#define off64_t off_t
|
||||
#define fopen64 fopen
|
||||
#define fseeko64 fseek
|
||||
#define ftello64 ftell
|
||||
#define ftruncate64 ftruncate
|
||||
#endif
|
||||
|
||||
namespace hex::fs {
|
||||
|
||||
class File {
|
||||
public:
|
||||
enum class Mode
|
||||
{
|
||||
Read,
|
||||
Write,
|
||||
Create
|
||||
};
|
||||
|
||||
explicit File(const std::fs::path &path, Mode mode) noexcept;
|
||||
File() noexcept;
|
||||
File(const File &) = delete;
|
||||
File(File &&other) noexcept;
|
||||
|
||||
~File();
|
||||
|
||||
File &operator=(File &&other) noexcept;
|
||||
|
||||
|
||||
[[nodiscard]] bool isValid() const {
|
||||
return this->m_file != nullptr && fs::exists(this->m_path) && !fs::isDirectory(this->m_path);
|
||||
}
|
||||
|
||||
void seek(u64 offset);
|
||||
void close();
|
||||
|
||||
size_t readBuffer(u8 *buffer, size_t size);
|
||||
std::vector<u8> readBytes(size_t numBytes = 0);
|
||||
std::string readString(size_t numBytes = 0);
|
||||
std::u8string readU8String(size_t numBytes = 0);
|
||||
|
||||
void write(const u8 *buffer, size_t size);
|
||||
void write(const std::vector<u8> &bytes);
|
||||
void write(const std::string &string);
|
||||
void write(const std::u8string &string);
|
||||
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
void setSize(u64 size);
|
||||
|
||||
void flush();
|
||||
bool remove();
|
||||
|
||||
auto getHandle() { return this->m_file; }
|
||||
const std::fs::path &getPath() { return this->m_path; }
|
||||
|
||||
void disableBuffering();
|
||||
|
||||
private:
|
||||
FILE *m_file;
|
||||
std::fs::path m_path;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -2,18 +2,12 @@
|
||||
|
||||
#include <string_view>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename... Args>
|
||||
inline std::string format(std::string_view format, Args... args) {
|
||||
std::string format(std::string_view format, Args... args) {
|
||||
return fmt::format(fmt::runtime(format), args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void print(std::string_view format, Args... args) {
|
||||
fmt::print(fmt::runtime(format), args...);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,89 +2,34 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
|
||||
#include <nfd.hpp>
|
||||
|
||||
namespace std::fs {
|
||||
using namespace std::filesystem;
|
||||
}
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
namespace hex::fs {
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool exists(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::exists(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool createDirectories(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::create_directories(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool isRegularFile(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::is_regular_file(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool copyFile(const std::fs::path &from, const std::fs::path &to, std::fs::copy_options = std::fs::copy_options::none) {
|
||||
std::error_code error;
|
||||
return std::filesystem::copy_file(from, to, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool isDirectory(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::is_directory(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool remove(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::remove(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline bool removeAll(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
return std::filesystem::remove_all(path, error) && !error;
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline uintmax_t getFileSize(const std::fs::path &path) {
|
||||
std::error_code error;
|
||||
auto size = std::filesystem::file_size(path, error);
|
||||
|
||||
if (error) return 0;
|
||||
else return size;
|
||||
}
|
||||
|
||||
static inline bool isSubPath(const std::fs::path& base, const std::fs::path& destination) {
|
||||
const auto relative = std::fs::relative(destination, base).u8string();
|
||||
|
||||
return relative.size() == 1 || (relative[0] != '.' && relative[1] != '.');
|
||||
}
|
||||
|
||||
bool isPathWritable(const std::fs::path &path);
|
||||
|
||||
std::fs::path toShortPath(const std::fs::path &path);
|
||||
|
||||
enum class DialogMode {
|
||||
Open,
|
||||
Save,
|
||||
Folder
|
||||
};
|
||||
|
||||
void setFileBrowserErrorCallback(const std::function<void()> &callback);
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath = {}, bool multiple = false);
|
||||
struct ItemFilter {
|
||||
// Human-friendly name
|
||||
std::string name;
|
||||
// Extensions that constitute this filter
|
||||
std::string spec;
|
||||
};
|
||||
|
||||
void setFileBrowserErrorCallback(const std::function<void(const std::string&)> &callback);
|
||||
bool openFileBrowser(DialogMode mode, const std::vector<ItemFilter> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath = {}, bool multiple = false);
|
||||
|
||||
void openFileExternal(const std::fs::path &filePath);
|
||||
void openFolderExternal(const std::fs::path &dirPath);
|
||||
void openFolderWithSelectionExternal(const std::fs::path &selectedFilePath);
|
||||
|
||||
enum class ImHexPath : u32 {
|
||||
Patterns = 0,
|
||||
@@ -103,12 +48,16 @@ namespace hex::fs {
|
||||
Themes,
|
||||
Libraries,
|
||||
Nodes,
|
||||
Layouts,
|
||||
|
||||
END
|
||||
};
|
||||
|
||||
std::optional<std::fs::path> getExecutablePath();
|
||||
bool isPathWritable(const std::fs::path &path);
|
||||
|
||||
std::vector<std::fs::path> getDefaultPaths(ImHexPath path, bool listNonExisting = false);
|
||||
|
||||
// Temporarily expose these for the migration function
|
||||
std::vector<std::fs::path> getDataPaths();
|
||||
std::vector<std::fs::path> appendPath(std::vector<std::fs::path> paths, const std::fs::path &folder);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
extern "C" char * getMacExecutableDirectoryPath();
|
||||
extern "C" char * getMacApplicationSupportDirectoryPath();
|
||||
|
||||
extern "C" void macFree(void *ptr);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user