mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-31 05:15:55 -05:00
Compare commits
486 Commits
m1_cross_c
...
v1.32.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1edb1b896 | ||
|
|
b27e63586e | ||
|
|
d2bd5b5640 | ||
|
|
f91505ff09 | ||
|
|
464495987a | ||
|
|
27aef75e54 | ||
|
|
70e3b4dd1a | ||
|
|
556fd2bbc3 | ||
|
|
0097d1782e | ||
|
|
f03bdc5f45 | ||
|
|
ebf379f7c1 | ||
|
|
cd72ff1f84 | ||
|
|
eca41cac16 | ||
|
|
a8e2e132d1 | ||
|
|
499711b9af | ||
|
|
b0eec3a844 | ||
|
|
24e90f0f20 | ||
|
|
ff48d37598 | ||
|
|
c402d58685 | ||
|
|
ed8934882e | ||
|
|
62093a8dd8 | ||
|
|
4a5f1038e0 | ||
|
|
8cb833eca9 | ||
|
|
e2b7a69fc8 | ||
|
|
950eaea8af | ||
|
|
b22d90f9ca | ||
|
|
b76e7ff678 | ||
|
|
9c386e949d | ||
|
|
2b1688be31 | ||
|
|
3d9de1aaa6 | ||
|
|
5a0a5ad445 | ||
|
|
038b98eacf | ||
|
|
3592d17c93 | ||
|
|
4cbd84671c | ||
|
|
c3c9603ea1 | ||
|
|
af63b42eaf | ||
|
|
2f7da91a73 | ||
|
|
8fcf08132e | ||
|
|
db72ba295a | ||
|
|
2d7a6a7cb5 | ||
|
|
390b5a7925 | ||
|
|
5ca6ed30b4 | ||
|
|
9685b39969 | ||
|
|
03dc26d2d4 | ||
|
|
b64bb3bec9 | ||
|
|
8d3530a4f3 | ||
|
|
83b1416797 | ||
|
|
5adeac6bbc | ||
|
|
f44b44a881 | ||
|
|
1ed978f22e | ||
|
|
7ed06ae515 | ||
|
|
63042dbba8 | ||
|
|
144d8d8ed4 | ||
|
|
99ba47a554 | ||
|
|
0462dab170 | ||
|
|
258481b0ba | ||
|
|
cb35f456ed | ||
|
|
686f8f43c3 | ||
|
|
99dcd0a020 | ||
|
|
3c6f52f5ea | ||
|
|
874619f62e | ||
|
|
74b5c93caf | ||
|
|
ec45d1f564 | ||
|
|
42a75fe133 | ||
|
|
e414c1cf1e | ||
|
|
1cf692cecf | ||
|
|
af5b871383 | ||
|
|
37d60411bb | ||
|
|
d7ba2e7171 | ||
|
|
215be9255e | ||
|
|
9d0fd1f5b6 | ||
|
|
4e0a93fc20 | ||
|
|
a0fddd2953 | ||
|
|
40e66313a9 | ||
|
|
87155f98b3 | ||
|
|
483325990c | ||
|
|
83fa024fab | ||
|
|
96fe608d60 | ||
|
|
52192a3b26 | ||
|
|
75e575fc01 | ||
|
|
98bc89cb39 | ||
|
|
d2d244ebc7 | ||
|
|
9952854b53 | ||
|
|
3bb079216c | ||
|
|
b845dbb882 | ||
|
|
7eb92c68de | ||
|
|
24f8ce9d7f | ||
|
|
343e98c99a | ||
|
|
bc76eee847 | ||
|
|
91ae8ba410 | ||
|
|
e2489151f3 | ||
|
|
9066891ce2 | ||
|
|
65e2f1b5af | ||
|
|
020efefb25 | ||
|
|
83f8370e2a | ||
|
|
61accd9569 | ||
|
|
8a428df7df | ||
|
|
de6bb5dfb9 | ||
|
|
80561001b8 | ||
|
|
33d077e997 | ||
|
|
fe24db7c57 | ||
|
|
61bfe10bc2 | ||
|
|
84bfd10416 | ||
|
|
538e79183c | ||
|
|
ec64952cb4 | ||
|
|
b934ca6ad3 | ||
|
|
0da6c03a8f | ||
|
|
a54cbca6d2 | ||
|
|
ad8e3e38f0 | ||
|
|
ffc1aa6a91 | ||
|
|
6ee1e72021 | ||
|
|
5bc8e5c57c | ||
|
|
d48acf7fef | ||
|
|
72260b5323 | ||
|
|
e84b8cb96d | ||
|
|
adcaad791a | ||
|
|
b0490cfbbc | ||
|
|
86231d0154 | ||
|
|
6163f6c4a0 | ||
|
|
e3e117a14e | ||
|
|
e2ae567b9f | ||
|
|
a0c2dc43f7 | ||
|
|
f47163c4ad | ||
|
|
e951359a46 | ||
|
|
bf6b2db0cb | ||
|
|
1ea8269dec | ||
|
|
9bd1970371 | ||
|
|
5b3ae56912 | ||
|
|
2b5789631f | ||
|
|
a6025e72fb | ||
|
|
96db2074c6 | ||
|
|
c7ab4a4569 | ||
|
|
dd4be3b772 | ||
|
|
8fe490ed03 | ||
|
|
eb21a5992f | ||
|
|
a3f1a5b0a9 | ||
|
|
71763d108b | ||
|
|
dc9ab135c8 | ||
|
|
3dd33d0966 | ||
|
|
1cb2e0d765 | ||
|
|
b34fb2d225 | ||
|
|
4973556fc8 | ||
|
|
2948e57242 | ||
|
|
521ee5fe2d | ||
|
|
478d6118d8 | ||
|
|
1b43270ae9 | ||
|
|
ec4fdc44ef | ||
|
|
91f49e2c6e | ||
|
|
6bc4a7242e | ||
|
|
eeab529bfa | ||
|
|
d798713c60 | ||
|
|
edc4b18975 | ||
|
|
450c93e029 | ||
|
|
c1abbfad7d | ||
|
|
d2d36c2211 | ||
|
|
aaaa02dbd0 | ||
|
|
a844fb3731 | ||
|
|
8f83fe5135 | ||
|
|
978558649e | ||
|
|
3b5efb37e9 | ||
|
|
90abe982ed | ||
|
|
7a0680c2cb | ||
|
|
71dd349044 | ||
|
|
f2a795c51e | ||
|
|
7ad7ea061c | ||
|
|
a315ecb831 | ||
|
|
c3d99e29dc | ||
|
|
f90f4b00a8 | ||
|
|
b1aa4fd3f8 | ||
|
|
b5df20d7c6 | ||
|
|
b58463bbaf | ||
|
|
b71a776770 | ||
|
|
78ef5b0d07 | ||
|
|
c1f76be3b7 | ||
|
|
2ebd3c6f35 | ||
|
|
003f9619c3 | ||
|
|
710ceedf3d | ||
|
|
5b77f511d3 | ||
|
|
f000b6bc0a | ||
|
|
346f1362c6 | ||
|
|
92043a3d23 | ||
|
|
3bc5295eae | ||
|
|
5bcfe37b4e | ||
|
|
1a8a9e53e1 | ||
|
|
c32dad75cd | ||
|
|
045733d188 | ||
|
|
f618e634e9 | ||
|
|
1b457dae7d | ||
|
|
690b0df932 | ||
|
|
e080164305 | ||
|
|
1e4bb8c91e | ||
|
|
17a7621342 | ||
|
|
ce27cb11a5 | ||
|
|
b84b82c416 | ||
|
|
623e074ba0 | ||
|
|
91230ba438 | ||
|
|
cc4d61f8f5 | ||
|
|
7a4358a5ec | ||
|
|
e6796d1458 | ||
|
|
1ba34c233e | ||
|
|
ef7898ea8d | ||
|
|
e49c3182ce | ||
|
|
c58c3dd311 | ||
|
|
7738f8c831 | ||
|
|
27cd3cc83a | ||
|
|
2f5e04d07f | ||
|
|
15af0726f1 | ||
|
|
a60a45fb9d | ||
|
|
df03ba3883 | ||
|
|
09a148b8a5 | ||
|
|
350635d464 | ||
|
|
cf13404254 | ||
|
|
878f45dd80 | ||
|
|
48bc0985d9 | ||
|
|
e9bca123c2 | ||
|
|
6df3a9243f | ||
|
|
f1b40d0500 | ||
|
|
0cbaf40747 | ||
|
|
54c5d9debb | ||
|
|
411884966b | ||
|
|
ef25542220 | ||
|
|
b4813660b5 | ||
|
|
f08d1e265c | ||
|
|
470bc8a049 | ||
|
|
5c84ef5f72 | ||
|
|
8ab85a2af1 | ||
|
|
7f69f8bcdb | ||
|
|
3a016da549 | ||
|
|
7b3e13c748 | ||
|
|
f5cbcce112 | ||
|
|
5f8c813aa7 | ||
|
|
f68202a098 | ||
|
|
bfb2c6ab5f | ||
|
|
00a24bc84b | ||
|
|
9ba6d7ee1e | ||
|
|
60ff62d018 | ||
|
|
5d24f1b691 | ||
|
|
370ca740e3 | ||
|
|
ba8430d9e7 | ||
|
|
0b71568d97 | ||
|
|
37ac1b66dd | ||
|
|
1be9e8c5b1 | ||
|
|
c6b9b947fb | ||
|
|
a1ef567ecd | ||
|
|
2b22a15e8c | ||
|
|
760b8c7a88 | ||
|
|
13145bba03 | ||
|
|
f9a9ed4846 | ||
|
|
d5a40d46bc | ||
|
|
19f3da556c | ||
|
|
e8f0a3bd23 | ||
|
|
08fd09064a | ||
|
|
caee764af3 | ||
|
|
eae3cd99ee | ||
|
|
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 |
@@ -65,4 +65,5 @@ readability-*,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-identifier-naming,
|
||||
-readability-qualified-auto'
|
||||
*-include-cleaner,
|
||||
-readability-qualified-auto'
|
||||
|
||||
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
cmake-build-*/
|
||||
build*/
|
||||
|
||||
local/
|
||||
**/Dockerfile
|
||||
9
.gdbinit
9
.gdbinit
@@ -6,4 +6,11 @@ skip -rfu ^__gnu_debug::
|
||||
skip -rfu ^ImGui::
|
||||
|
||||
# Trigger breakpoint when execution reaches triggerSafeShutdown()
|
||||
break triggerSafeShutdown
|
||||
break triggerSafeShutdown
|
||||
|
||||
# Print backtrace after execution jumped to an invalid address
|
||||
define fixbt
|
||||
set $pc = *(void **)$rsp
|
||||
set $rsp = $rsp + 8
|
||||
bt
|
||||
end
|
||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1 +1,4 @@
|
||||
lib/external/** linguist-vendored
|
||||
lib/external/** linguist-vendored
|
||||
|
||||
dist/*.sh eol=lf
|
||||
dist/**/*Dockerfile eol=lf
|
||||
1
.github/workflows/analysis.yml
vendored
1
.github/workflows/analysis.yml
vendored
@@ -46,6 +46,7 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
189
.github/workflows/build.yml
vendored
189
.github/workflows/build.yml
vendored
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Set version variable
|
||||
run: |
|
||||
@@ -72,13 +72,14 @@ jobs:
|
||||
# Windows cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
|
||||
-DCMAKE_INSTALL_PREFIX="$PWD/install" \
|
||||
-DCREATE_PACKAGE=ON \
|
||||
-DIMHEX_GENERATE_PACKAGE=ON \
|
||||
-DIMHEX_USE_DEFAULT_BUILD_SETTINGS=ON \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
@@ -94,15 +95,17 @@ jobs:
|
||||
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
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Installer x86_64
|
||||
path: |
|
||||
imhex-*.msi
|
||||
|
||||
- name: ⬆️ Upload Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
@@ -110,14 +113,16 @@ 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
|
||||
mv opengl32.dll build/install
|
||||
|
||||
- name: ⬆️ Upload NoGPU Portable ZIP
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Windows Portable NoGPU x86_64
|
||||
path: |
|
||||
build/install/*
|
||||
@@ -132,18 +137,10 @@ jobs:
|
||||
include:
|
||||
- suffix: "-NoGPU"
|
||||
custom_glfw: true
|
||||
toolchain_file: ""
|
||||
needs_update: true
|
||||
- suffix: ""
|
||||
custom_glfw: false
|
||||
toolchain_file: ""
|
||||
needs_update: true
|
||||
- suffix: "-ARM"
|
||||
custom_glfw: false
|
||||
toolchain_file: "dist/macOS/macos_arm_toolchain.cmake"
|
||||
needs_update: true
|
||||
|
||||
name: 🍎 macOS 11.0${{matrix.suffix}}
|
||||
name: 🍎 macOS 12.0${{matrix.suffix}}
|
||||
|
||||
steps:
|
||||
- name: 🧰 Checkout
|
||||
@@ -169,13 +166,10 @@ jobs:
|
||||
build/CMakeCache.txt
|
||||
key: ${{ runner.os }}-${{ matrix.suffix }}-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: ⬇️ Update brew packages
|
||||
if: ${{matrix.needs_update}}
|
||||
run: |
|
||||
brew update
|
||||
|
||||
- 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
|
||||
|
||||
@@ -187,7 +181,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 🧰 Checkout glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
@@ -200,6 +194,7 @@ jobs:
|
||||
- name: ⬇️ Patch and install custom glfw
|
||||
if: ${{matrix.custom_glfw}}
|
||||
run: |
|
||||
set -x
|
||||
cd glfw
|
||||
git apply ../dist/macOS/0001-glfw-SW.patch
|
||||
|
||||
@@ -219,24 +214,21 @@ jobs:
|
||||
# MacOS cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=$(brew --prefix llvm)/bin/clang \
|
||||
CXX=$(brew --prefix llvm)/bin/clang++ \
|
||||
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}} \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${{matrix.toolchain_file}}" \
|
||||
-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 \
|
||||
-DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
|
||||
-DNATIVE_CMAKE_C_COMPILER="$(brew --prefix gcc@12)/bin/gcc-12" \
|
||||
-DNATIVE_CMAKE_CXX_COMPILER="$(brew --prefix gcc@12)/bin/g++-12" \
|
||||
-DIMHEX_PATTERNS_PULL_MASTER=ON \
|
||||
-DIMHEX_COMMIT_HASH_SHORT="${GITHUB_SHA::7}" \
|
||||
-DIMHEX_COMMIT_HASH_LONG="${GITHUB_SHA}" \
|
||||
@@ -246,14 +238,109 @@ jobs:
|
||||
ninja package
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: macOS DMG${{matrix.suffix}} x86_64
|
||||
path: build/*.dmg
|
||||
|
||||
macos-arm64-build:
|
||||
runs-on: ubuntu-22.04
|
||||
name: 🍎 macOS 12.1 arm64
|
||||
outputs:
|
||||
IMHEX_VERSION: ${{ steps.build.outputs.IMHEX_VERSION }}
|
||||
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
|
||||
id: build
|
||||
run: |
|
||||
echo "IMHEX_VERSION=`cat VERSION`" >> $GITHUB_OUTPUT
|
||||
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@v4
|
||||
with:
|
||||
name: macos_arm64_intermediate
|
||||
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 || true
|
||||
|
||||
macos-arm64-package:
|
||||
runs-on: macos-12
|
||||
name: 🍎 macOS 12.1 arm64 Packaging
|
||||
needs: macos-arm64-build
|
||||
env:
|
||||
IMHEX_VERSION: ${{ needs.macos-arm64-build.outputs.IMHEX_VERSION }}
|
||||
steps:
|
||||
- name: ⬇️ Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: macos_arm64_intermediate
|
||||
path: out
|
||||
|
||||
- name: 🗑️ Delete artifact
|
||||
uses: geekyeggo/delete-artifact@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: macos_arm64_intermediate
|
||||
|
||||
- name: ✒️ Fix Signature
|
||||
run: |
|
||||
set -x
|
||||
cd out
|
||||
codesign --remove-signature ImHex.app
|
||||
codesign --force --deep --sign - ImHex.app
|
||||
|
||||
- name: 📁 Fix permissions
|
||||
run: |
|
||||
set -x
|
||||
cd out
|
||||
chmod -R 755 ImHex.app/
|
||||
|
||||
- name: 📦 Create DMG
|
||||
run: |
|
||||
set -x
|
||||
mkdir bundle
|
||||
mv out/ImHex.app bundle
|
||||
cd bundle
|
||||
ln -s /Applications Applications
|
||||
cd ..
|
||||
hdiutil create -volname "ImHex" -srcfolder bundle -ov -format UDZO imhex-${{env.IMHEX_VERSION}}-macOS-arm64.dmg
|
||||
|
||||
- name: ⬆️ Upload DMG
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: macOS DMG arm64
|
||||
path: ./*.dmg
|
||||
|
||||
# Ubuntu build
|
||||
ubuntu:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Ubuntu
|
||||
@@ -299,17 +386,13 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
|
||||
- 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
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
# Ubuntu cmake build
|
||||
- name: 🛠️ Build
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
git config --global --add safe.directory '*'
|
||||
mkdir -p build
|
||||
cd build
|
||||
@@ -319,9 +402,9 @@ jobs:
|
||||
-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_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 \
|
||||
-DDOTNET_EXECUTABLE="dotnet" \
|
||||
@@ -339,8 +422,9 @@ jobs:
|
||||
mv build/DebDir.deb imhex-${{env.IMHEX_VERSION}}-Ubuntu-${{ matrix.release_num }}-x86_64.deb
|
||||
|
||||
- name: ⬆️ Upload DEB
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Ubuntu ${{ matrix.release_num }} DEB x86_64
|
||||
path: '*.deb'
|
||||
|
||||
@@ -374,14 +458,16 @@ jobs:
|
||||
|
||||
|
||||
- name: ⬆️ Upload AppImage
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage x86_64
|
||||
path: 'out/*.AppImage'
|
||||
|
||||
- name: ⬆️ Upload AppImage zsync
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: Linux AppImage zsync x86_64
|
||||
path: 'out/*.AppImage.zsync'
|
||||
|
||||
@@ -414,7 +500,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
@@ -433,6 +519,7 @@ jobs:
|
||||
# ArchLinux cmake build
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc CXX=g++ cmake -G "Ninja" \
|
||||
@@ -465,6 +552,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
|
||||
@@ -480,8 +568,9 @@ jobs:
|
||||
mv *.pkg.tar.zst imhex-${{env.IMHEX_VERSION}}-ArchLinux-x86_64.pkg.tar.zst
|
||||
|
||||
- name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
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
|
||||
@@ -496,14 +585,14 @@ jobs:
|
||||
mock_release: rawhide
|
||||
release_num: rawhide
|
||||
mock_config: fedora-rawhide
|
||||
- name: Fedora
|
||||
mock_release: f39
|
||||
release_num: 39
|
||||
mock_config: fedora-39
|
||||
- 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: RHEL-AlmaLinux
|
||||
mock_release: epel9
|
||||
release_num: 9
|
||||
@@ -536,6 +625,7 @@ jobs:
|
||||
|
||||
- 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 \
|
||||
@@ -544,7 +634,7 @@ jobs:
|
||||
- name: ⬇️ Install .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
dotnet-version: '8.0.100'
|
||||
|
||||
- name: 📜 Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
@@ -606,8 +696,9 @@ jobs:
|
||||
$GITHUB_WORKSPACE/imhex-${{env.IMHEX_VERSION}}-${{matrix.name}}-${{matrix.release_num}}-x86_64.rpm
|
||||
|
||||
- name: ⬆️ Upload RPM
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
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
|
||||
|
||||
6
.github/workflows/build_web.yml
vendored
6
.github/workflows/build_web.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cache
|
||||
key: build-web-cache
|
||||
key: web-cmakecache-${{ hashFiles('**/CMakeLists.txt') }}
|
||||
|
||||
- name: 🐳 Inject /cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v2.1.2
|
||||
@@ -43,9 +43,7 @@ jobs:
|
||||
|
||||
- name: 🔨 Fix permissions
|
||||
run: |
|
||||
chmod -c -R +rX "out/" | while read line; do
|
||||
echo "::warning title=Invalid file permissions automatically fixed::$line"
|
||||
done
|
||||
chmod -c -R +rX "out/"
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -21,6 +21,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}"
|
||||
@@ -64,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}"
|
||||
@@ -87,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 ];
|
||||
@@ -112,6 +115,7 @@ 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`
|
||||
|
||||
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -44,6 +44,7 @@ jobs:
|
||||
|
||||
- name: 🛠️ Build
|
||||
run: |
|
||||
set -x
|
||||
mkdir -p build
|
||||
cd build
|
||||
CC=gcc-12 CXX=g++-12 cmake \
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,9 +3,11 @@
|
||||
|
||||
cmake-build-*/
|
||||
build*/
|
||||
local/
|
||||
venv/
|
||||
|
||||
*.mgc
|
||||
imgui.ini
|
||||
.DS_Store
|
||||
./CMakeUserPresets.json
|
||||
./CMakeUserPresets.json
|
||||
Brewfile.lock.json
|
||||
27
.gitmodules
vendored
27
.gitmodules
vendored
@@ -1,25 +1,25 @@
|
||||
[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/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/external/jthread/jthread"]
|
||||
path = lib/external/jthread/jthread
|
||||
[submodule "lib/third_party/jthread/jthread"]
|
||||
path = lib/third_party/jthread/jthread
|
||||
url = https://github.com/josuttis/jthread
|
||||
ignore = dirty
|
||||
|
||||
@@ -33,3 +33,6 @@
|
||||
path = lib/external/libwolv
|
||||
url = https://github.com/WerWolv/libwolv
|
||||
|
||||
[submodule "lib/third_party/HashLibPlus"]
|
||||
path = lib/third_party/HashLibPlus
|
||||
url = https://github.com/WerWolv/HashLibPlus
|
||||
|
||||
@@ -14,6 +14,8 @@ 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)
|
||||
@@ -37,17 +39,13 @@ setDefaultBuiltTypeIfUnset()
|
||||
detectBadClone()
|
||||
verifyCompiler()
|
||||
|
||||
# List plugin names here. Project name must match folder name
|
||||
set(PLUGINS
|
||||
builtin
|
||||
windows
|
||||
script_loader
|
||||
)
|
||||
detectBundledPlugins()
|
||||
|
||||
# Add various defines
|
||||
detectOS()
|
||||
detectArch()
|
||||
addDefines()
|
||||
|
||||
# Configure packaging and install targets
|
||||
configurePackingResources()
|
||||
setUninstallTarget()
|
||||
addBundledLibraries()
|
||||
@@ -62,6 +60,7 @@ add_subdirectory(main)
|
||||
enable_testing()
|
||||
add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
|
||||
# Configure packaging
|
||||
# Configure more resources that will be added to the install package
|
||||
createPackage()
|
||||
generatePDBs()
|
||||
generateSDKDirectory()
|
||||
290
README.md
290
README.md
@@ -51,86 +51,259 @@ If you like my work, please consider supporting me on GitHub Sponsors, Patreon o
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
<details>
|
||||
<summary><strong>More Screenshots</strong></summary>
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
</details>
|
||||
|
||||
## Features
|
||||
|
||||
- Featureful hex view
|
||||
<details>
|
||||
<summary><strong>Featureful hex view</strong></summary>
|
||||
|
||||
- Byte patching
|
||||
- Patch management
|
||||
- Copy bytes as feature
|
||||
- Infinite Undo/Redo
|
||||
- "Copy bytes as..."
|
||||
- Bytes
|
||||
- Hex string
|
||||
- C, C++, C#, Rust, Python, Java & JavaScript array
|
||||
- ASCII-Art hex view
|
||||
- HTML self-contained div
|
||||
- String and hex search
|
||||
- Colorful highlighting
|
||||
- Simple string and hex search
|
||||
- Goto from start, end and current cursor position
|
||||
- Custom C++-like pattern language for parsing highlighting a file's content
|
||||
- Automatic loading based on MIME type
|
||||
- arrays, pointers, structs, unions, enums, bitfields, namespaces, little and big endian support, conditionals and much more!
|
||||
- Colorful highlighting
|
||||
- Configurable foreground highlighting rules
|
||||
- Background highlighting using patterns, find results and bookmarks
|
||||
- Displaying data as a list of many different types
|
||||
- Hexadecimal integers (8, 16, 32, 64 bit)
|
||||
- Signed and unsigned decimal integers (8, 16, 32, 64 bit)
|
||||
- Floats (16, 32, 64 bit)
|
||||
- RGBA8 Colors
|
||||
- HexII
|
||||
- Binary
|
||||
- Decoding data as ASCII and custom encodings
|
||||
- Built-in support for UTF-8, UTF-16, ShiftJIS, most Windows encodings and many more
|
||||
- Paged data view
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Custom C++-like pattern language for parsing highlighting a file's content</strong></summary>
|
||||
|
||||
- Automatic loading based on MIME types and magic values
|
||||
- Arrays, pointers, structs, unions, enums, bitfields, namespaces, little and big endian support, conditionals and much more!
|
||||
- Useful error messages, syntax highlighting and error marking
|
||||
- Doesn't burn out your retinas when used in late-night sessions
|
||||
- Dark mode by default, but a light mode is available as well
|
||||
- Data importing
|
||||
- Support for visualizing many different types of data
|
||||
- Images
|
||||
- Audio
|
||||
- 3D Models
|
||||
- Coordinates
|
||||
- Time stamps
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Theming support</strong></summary>
|
||||
|
||||
- Doesn't burn out your retinas when used in late-night sessions
|
||||
- Dark mode by default, but a light mode is available as well
|
||||
- Customizable colors and styles for all UI elements through shareable theme files
|
||||
- Support for custom fonts
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Importing and Exporting data</strong></summary>
|
||||
|
||||
- Base64 files
|
||||
- IPS and IPS32 patches
|
||||
- Data exporting
|
||||
- IPS and IPS32 patches
|
||||
- Data inspector allowing interpretation of data as many different types (little and big endian)
|
||||
- Huge file support with fast and efficient loading
|
||||
- String search
|
||||
- Copying of strings
|
||||
- Copying of demangled strings
|
||||
- File hashing support
|
||||
- CRC16 and CRC32 with custom initial values and polynomials
|
||||
- MD4, MD5
|
||||
- SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
|
||||
- Disassembler supporting many architectures (frontend for Capstone)
|
||||
- ARM32 (ARM, Thumb, Cortex-M, AArch32)
|
||||
- ARM64
|
||||
- MIPS (MIPS32, MIPS64, MIPS32R6, Micro)
|
||||
- x86 (16-bit, 32-bit, 64-bit)
|
||||
- PowerPC (32-bit, 64-bit)
|
||||
- SPARC
|
||||
- IBM SystemZ
|
||||
- xCORE
|
||||
- M68K
|
||||
- TMS320C64X
|
||||
- M680X
|
||||
- Ethereum
|
||||
- RISC-V
|
||||
- WebAssembly
|
||||
- MOS65XX
|
||||
- Berkeley Packet Filter
|
||||
- Bookmarks
|
||||
- Region highlighting
|
||||
- Comments
|
||||
- Data Analyzer
|
||||
- Markdown reports
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data Inspector</strong></summary>
|
||||
|
||||
- Interpreting data as many different types with endianess, decimal, hexadecimal and octal support and bit inversion
|
||||
- Unsigned and signed integers (8, 16, 24, 32, 48, 64 bit)
|
||||
- Floats (16, 32, 64 bit)
|
||||
- Signed and Unsigned LEB128
|
||||
- ASCII, Wide and UTF-8 characters and strings
|
||||
- time32_t, time64_t, DOS date and time
|
||||
- GUIDs
|
||||
- RGBA8 and RGB65 Colors
|
||||
- Copying and modifying bytes through the inspector
|
||||
- Adding new data types through the pattern language
|
||||
- Support for hiding rows that aren't used
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Node-based data pre-processor</strong></summary>
|
||||
|
||||
- Modify, decrypt and decode data before it's being displayed in the hex editor
|
||||
- Modify data without touching the underlying source
|
||||
- Support for adding custom nodes
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Loading data from many different data sources</strong></summary>
|
||||
|
||||
- Local Files
|
||||
- Support for huge files with fast and efficient loading
|
||||
- Raw Disks
|
||||
- Loading data from raw disks and partitions
|
||||
- GDB Server
|
||||
- Access the RAM of a running process or embedded devices through GDB
|
||||
- Intel Hex and Motorola SREC data
|
||||
- Process Memory
|
||||
- Inspect the entire address space of a running process
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data searching</strong></summary>
|
||||
|
||||
- Support for searching the entire file or only a selection
|
||||
- String extraction
|
||||
- Option to specify minimum length and character set (lower case, upper case, digits, symbols)
|
||||
- Option to specify encoding (ASCII, UTF-8, UTF-16 big and little endian)
|
||||
- Sequence search
|
||||
- Search for a sequence of bytes or characters
|
||||
- Option to ignore character case
|
||||
- Regex search
|
||||
- Search for strings using regular expressions
|
||||
- Binary Pattern
|
||||
- Search for sequences of bytes with optional wildcards
|
||||
- Numeric Value search
|
||||
- Search for signed/unsigned integers and floats
|
||||
- Search for ranges of values
|
||||
- Option to specify size and endianess
|
||||
- Option to ignore unaligned values
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Data hashing support</strong></summary>
|
||||
|
||||
- Many different algorithms available
|
||||
- CRC8, CRC16 and CRC32 with custom initial values and polynomials
|
||||
- Many default polynomials available
|
||||
- MD5
|
||||
- SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
|
||||
- Adler32
|
||||
- AP
|
||||
- BKDR
|
||||
- Bernstein, Bernstein1
|
||||
- DEK, DJB, ELF, FNV1, FNV1a, JS, PJW, RS, SDBM
|
||||
- OneAtTime, Rotating, ShiftAndXor, SuperFast
|
||||
- Murmur2_32, MurmurHash3_x86_32, MurmurHash3_x86_128, MurmurHash3_x64_128
|
||||
- SipHash64, SipHash128
|
||||
- XXHash32, XXHash64
|
||||
- Tiger, Tiger2
|
||||
- Blake2B, Blake2S
|
||||
- Hashing of specific regions of the loaded data
|
||||
- Hashing of arbitrary strings
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Diffing support</strong></summary>
|
||||
|
||||
- Compare data of different data sources
|
||||
- Difference highlighting
|
||||
- Table view of differences
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Integrated disassembler</strong></summary>
|
||||
|
||||
- Support for all architectures supported by Capstone
|
||||
- ARM32 (ARM, Thumb, Cortex-M, AArch32)
|
||||
- ARM64
|
||||
- MIPS (MIPS32, MIPS64, MIPS32R6, Micro)
|
||||
- x86 (16-bit, 32-bit, 64-bit)
|
||||
- PowerPC (32-bit, 64-bit)
|
||||
- SPARC
|
||||
- IBM SystemZ
|
||||
- xCORE
|
||||
- M68K
|
||||
- TMS320C64X
|
||||
- M680X
|
||||
- Ethereum
|
||||
- RISC-V
|
||||
- WebAssembly
|
||||
- MOS65XX
|
||||
- Berkeley Packet Filter
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Bookmarks</strong></summary>
|
||||
|
||||
- Support for bookmarks with custom names and colors
|
||||
- Highlighting of bookmarked region in the hex editor
|
||||
- Jump to bookmarks
|
||||
- Open content of bookmark in a new tab
|
||||
- Add comments to bookmarks
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Featureful data analyzer and visualizer</strong></summary>
|
||||
|
||||
- File magic-based file parser and MIME type database
|
||||
- Byte distribution graph
|
||||
- Byte type distribution graph
|
||||
- Entropy graph
|
||||
- Highest and average entropy
|
||||
- Encrypted / Compressed file detection
|
||||
- Built-in Content Store
|
||||
- Download all files found in the database directly from within ImHex
|
||||
- Yara Rules support
|
||||
- Quickly scan a file for vulnerabilities with official yara rules
|
||||
- Helpful tools
|
||||
- Itanium and MSVC demangler
|
||||
- Digram and Layered distribution graphs
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>YARA Rule support</strong></summary>
|
||||
|
||||
- Scan a file for vulnerabilities with official yara rules
|
||||
- Highlight matches in the hex editor
|
||||
- Jump to matches
|
||||
- Apply multiple rules at once
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Helpful tools</strong></summary>
|
||||
|
||||
- Itanium, MSVC, Rust and D-Lang demangler based on LLVM
|
||||
- ASCII table
|
||||
- Regex replacer
|
||||
- Mathematical expression evaluator (Calculator)
|
||||
- Hexadecimal Color picker
|
||||
- Graphing calculator
|
||||
- Hexadecimal Color picker with support for many different formats
|
||||
- Base converter
|
||||
- Byte swapper
|
||||
- UNIX Permissions calculator
|
||||
- Wikipedia term definition finder
|
||||
- File utilities
|
||||
- File splitter
|
||||
- File combiner
|
||||
- File shredder
|
||||
- IEEE754 Float visualizer
|
||||
- Division by invariant multiplication calculator
|
||||
- TCP Client/Server
|
||||
- Euclidean algorithm calculator
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Built-in Content updater</strong></summary>
|
||||
|
||||
- Download all files found in the database directly from within ImHex
|
||||
- Pattern files for decoding various file formats
|
||||
- Libraries for the pattern language
|
||||
- Magic files for file type detection
|
||||
- Custom data processor nodes
|
||||
- Custom encodings
|
||||
- Custom themes
|
||||
- Yara rules
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Modern Interface</strong></summary>
|
||||
|
||||
- Support for multiple workspaces
|
||||
- Support for custom layouts
|
||||
- Detachable windows
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Easy to get started</strong></summary>
|
||||
|
||||
- Support for many different languages
|
||||
- Simplified mode for beginners
|
||||
- Extensive documentation
|
||||
- Many example files available on [the Database](https://github.com/WerWolv/ImHex-Patterns)
|
||||
- Achievements guiding you through the features of ImHex
|
||||
- Interactive tutorials
|
||||
</details>
|
||||
|
||||
## Pattern Language
|
||||
|
||||
@@ -148,7 +321,13 @@ For format patterns, libraries, magic and constant files, check out the [ImHex-P
|
||||
|
||||
## Requirements
|
||||
|
||||
To use ImHex, the following minimal system requirements need to be met:
|
||||
To use ImHex, the following minimal system requirements need to be met.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> ImHex requires a GPU with OpenGL 3.0 support in general.
|
||||
> There are releases available (with the `-NoGPU` suffix) that are software rendered and don't require a GPU, however these can be a lot slower than the GPU accelerated versions.
|
||||
>
|
||||
> If possible at all, make ImHex use the dedicated GPU on your system instead of the integrated one (especially Intel HD GPUs are known to cause issues).
|
||||
|
||||
- **OS**:
|
||||
- **Windows**: Windows 7 or higher (Windows 10/11 recommended)
|
||||
@@ -175,8 +354,9 @@ To compile ImHex on any platform, GCC (or Clang) is required with a version that
|
||||
On macOS, Clang is also required to compile some ObjC code.
|
||||
All releases are being built using latest available GCC.
|
||||
|
||||
Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
> [!NOTE]
|
||||
> Many dependencies are bundled into the repository using submodules so make sure to clone it using the `--recurse-submodules` option.
|
||||
> All dependencies that aren't bundled, can be installed using the dependency installer scripts found in the `/dist` folder.
|
||||
|
||||
For more information, check out the [Compiling](/dist/compiling) guide.
|
||||
|
||||
@@ -198,7 +378,7 @@ To develop plugins for ImHex, use one of the following two templates projects to
|
||||
- [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
|
||||
|
||||
@@ -7,4 +7,4 @@ If you built ImHex yourself and experience issues that are not present in the ve
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Any critical vulnerabilities can be reported through Discord @WerWolv#1337
|
||||
Any critical vulnerabilities can be reported through Discord (@werwolv).
|
||||
|
||||
@@ -68,8 +68,10 @@ macro(detectOS)
|
||||
set(PLUGINS_INSTALL_LOCATION "share/imhex/plugins")
|
||||
else()
|
||||
set(PLUGINS_INSTALL_LOCATION "${CMAKE_INSTALL_LIBDIR}/imhex/plugins")
|
||||
# Warning : Do not work with portable versions such as appimage (because the path is hardcoded)
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex") # "plugins" will be appended from the app
|
||||
|
||||
# Add System plugin location for plugins to be loaded from
|
||||
# IMPORTANT: This does not work for Sandboxed or portable builds such as the Flatpak or AppImage release
|
||||
add_compile_definitions(SYSTEM_PLUGINS_LOCATION="${CMAKE_INSTALL_FULL_LIBDIR}/imhex")
|
||||
endif()
|
||||
|
||||
else ()
|
||||
@@ -78,25 +80,7 @@ macro(detectOS)
|
||||
|
||||
endmacro()
|
||||
|
||||
# Detect 32 vs. 64 bit system
|
||||
macro(detectArch)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_compile_definitions(ARCH_64_BIT)
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
add_compile_definitions(ARCH_32_BIT)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(configurePackingResources)
|
||||
set(IMHEX_FORCE_LINK_PLUGINS "")
|
||||
|
||||
option (CREATE_PACKAGE "Create a package with CPack" OFF)
|
||||
|
||||
if (APPLE)
|
||||
option (CREATE_BUNDLE "Create a bundle on macOS" OFF)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
set(APPLICATION_TYPE WIN32)
|
||||
@@ -104,7 +88,7 @@ macro(configurePackingResources)
|
||||
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/resource.rc")
|
||||
|
||||
if (CREATE_PACKAGE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
set(CPACK_PACKAGE_NAME "ImHex")
|
||||
set(CPACK_PACKAGE_VENDOR "WerWolv")
|
||||
@@ -116,13 +100,14 @@ macro(configurePackingResources)
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ImHex")
|
||||
set_property(INSTALL "$<TARGET_FILE_NAME:main>"
|
||||
PROPERTY CPACK_START_MENU_SHORTCUTS "ImHex"
|
||||
)
|
||||
)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/resources/dist/windows/LICENSE.rtf")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set (IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/dist/macos/AppIcon.icns")
|
||||
elseif (APPLE OR ${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(IMHEX_ICON "${IMHEX_BASE_FOLDER}/resources/dist/macos/AppIcon.icns")
|
||||
set(BUNDLE_NAME "imhex.app")
|
||||
|
||||
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")
|
||||
@@ -137,9 +122,9 @@ macro(configurePackingResources)
|
||||
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}/${BUNDLE_NAME}")
|
||||
else ()
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/ImHex.app")
|
||||
set (IMHEX_BUNDLE_PATH "${CMAKE_BINARY_DIR}/${BUNDLE_NAME}")
|
||||
endif()
|
||||
|
||||
set(PLUGINS_INSTALL_LOCATION "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
@@ -155,30 +140,28 @@ macro(createPackage)
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
add_subdirectory("plugins/${plugin}")
|
||||
if (TARGET ${plugin})
|
||||
get_target_property(IS_RUST_PROJECT ${plugin} RUST_PROJECT)
|
||||
|
||||
set_target_properties(${plugin} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
if (IS_RUST_PROJECT)
|
||||
set_target_properties(${plugin} PROPERTIES CARGO_BUILD_TARGET_DIR ${CMAKE_BINARY_DIR}/plugins)
|
||||
|
||||
get_target_property(PLUGIN_LOCATION ${plugin} LOCATION)
|
||||
|
||||
install(FILES "${PLUGIN_LOCATION}/../${plugin}.hexplug" DESTINATION "${PLUGINS_INSTALL_LOCATION}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
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 ()
|
||||
else ()
|
||||
if (WIN32)
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
elseif (APPLE)
|
||||
if (CREATE_BUNDLE)
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGINS_INSTALL_LOCATION})
|
||||
get_target_property(target_type ${plugin} TYPE)
|
||||
if (target_type STREQUAL "SHARED_LIBRARY")
|
||||
install(TARGETS ${plugin} RUNTIME DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
else ()
|
||||
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins)
|
||||
endif ()
|
||||
else ()
|
||||
install(TARGETS ${plugin} LIBRARY DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${plugin} LIBRARY DESTINATION ${PLUGINS_INSTALL_LOCATION})
|
||||
endif ()
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
add_dependencies(imhex_all ${plugin})
|
||||
endif ()
|
||||
@@ -190,12 +173,17 @@ macro(createPackage)
|
||||
# Install binaries directly in the prefix, usually C:\Program Files\ImHex.
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
|
||||
set(PLUGIN_TARGET_FILES "")
|
||||
foreach (plugin IN LISTS PLUGINS)
|
||||
list(APPEND PLUGIN_TARGET_FILES "$<TARGET_FILE:${plugin}>")
|
||||
endforeach ()
|
||||
|
||||
# Grab all dynamically linked dependencies.
|
||||
INSTALL(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
INSTALL(CODE "LIST(APPEND DEP_FOLDERS \${PY_PARENT})")
|
||||
install(CODE "set(CMAKE_INSTALL_BINDIR \"${CMAKE_INSTALL_BINDIR}\")")
|
||||
install(CODE "set(PLUGIN_TARGET_FILES \"${PLUGIN_TARGET_FILES}\")")
|
||||
install(CODE [[
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
EXECUTABLES $<TARGET_FILE:builtin> $<TARGET_FILE:libimhex> $<TARGET_FILE:main>
|
||||
EXECUTABLES ${PLUGIN_TARGET_FILES} $<TARGET_FILE:libimhex> $<TARGET_FILE:main>
|
||||
RESOLVED_DEPENDENCIES_VAR _r_deps
|
||||
UNRESOLVED_DEPENDENCIES_VAR _u_deps
|
||||
CONFLICTING_DEPENDENCIES_PREFIX _c_deps
|
||||
@@ -222,60 +210,70 @@ macro(createPackage)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/dist/DEBIAN/control.in ${CMAKE_BINARY_DIR}/DEBIAN/control)
|
||||
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_PREFIX}/share/licenses/imhex)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/imhex.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/icon.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps RENAME imhex.png)
|
||||
install(FILES "$<TARGET_FILE:libimhex>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
downloadImHexPatternsFiles("./share/imhex")
|
||||
|
||||
|
||||
# install AppStream file
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/net.werwolv.imhex.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
|
||||
# install symlink for the old standard name
|
||||
file(CREATE_LINK net.werwolv.imhex.metainfo.xml ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml SYMBOLIC)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/net.werwolv.imhex.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
|
||||
endif()
|
||||
|
||||
if (CREATE_BUNDLE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
set_property(TARGET main PROPERTY MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
|
||||
if (APPLE)
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
include(PostprocessBundle)
|
||||
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET imhex_all POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
set_target_properties(libimhex PROPERTIES SOVERSION ${IMHEX_VERSION})
|
||||
|
||||
# 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")
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
set_property(TARGET main PROPERTY MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_INFO_PLIST})
|
||||
|
||||
downloadImHexPatternsFiles("${IMHEX_BUNDLE_PATH}/Contents/MacOS")
|
||||
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
install(TARGETS main BUNDLE DESTINATION ".")
|
||||
install(FILES $<TARGET_FILE:main> DESTINATION "${IMHEX_BUNDLE_PATH}")
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET imhex_all POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $<TARGET_FILE:main>)
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
postprocess_bundle(imhex_all main)
|
||||
add_custom_target(build-time-make-plugins-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
add_custom_target(build-time-make-resources-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
|
||||
# Enforce DragNDrop packaging.
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
downloadImHexPatternsFiles("${IMHEX_BUNDLE_PATH}/Contents/MacOS")
|
||||
|
||||
install(FILES ${IMHEX_ICON} DESTINATION "${IMHEX_BUNDLE_PATH}/Contents/Resources")
|
||||
install(TARGETS main BUNDLE DESTINATION ".")
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
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}/${BUNDLE_NAME}/Contents/Info.plist")
|
||||
|
||||
# Sign the bundle
|
||||
find_program(CODESIGN_PATH codesign)
|
||||
if (CODESIGN_PATH)
|
||||
add_custom_command(TARGET imhex_all POST_BUILD COMMAND ${CODESIGN_PATH} --force --deep --sign - ${CMAKE_BINARY_DIR}/${BUNDLE_NAME})
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS main RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(WIN32) # Forwarder is only needed on Windows
|
||||
if (TARGET updater)
|
||||
install(TARGETS updater RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
if (TARGET main-forwarder)
|
||||
install(TARGETS main-forwarder BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CREATE_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")
|
||||
if (IMHEX_GENERATE_PACKAGE)
|
||||
set(CPACK_BUNDLE_NAME "ImHex")
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
@@ -297,10 +295,6 @@ macro(configureCMake)
|
||||
# Enable C and C++ languages
|
||||
enable_language(C CXX)
|
||||
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
message(STATUS "ImHex is being Cross-Compiled for ${CMAKE_SYSTEM_NAME}!")
|
||||
endif ()
|
||||
|
||||
# Configure use of recommended build tools
|
||||
if (IMHEX_USE_DEFAULT_BUILD_SETTINGS)
|
||||
message(STATUS "Configuring CMake to use recommended build tools...")
|
||||
@@ -384,7 +378,7 @@ 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_RECURSE RESULT "${EXTERNAL_DIR}/*")
|
||||
list(LENGTH RESULT ENTRY_COUNT)
|
||||
@@ -408,6 +402,35 @@ function(verifyCompiler)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(detectBundledPlugins)
|
||||
file(GLOB PLUGINS_DIRS "plugins/*")
|
||||
|
||||
if (NOT DEFINED IMHEX_INCLUDE_PLUGINS)
|
||||
foreach(PLUGIN_DIR ${PLUGINS_DIRS})
|
||||
if (EXISTS "${PLUGIN_DIR}/CMakeLists.txt")
|
||||
get_filename_component(PLUGIN_NAME ${PLUGIN_DIR} NAME)
|
||||
if (NOT (${PLUGIN_NAME} IN_LIST IMHEX_EXCLUDE_PLUGINS))
|
||||
list(APPEND PLUGINS ${PLUGIN_NAME})
|
||||
endif ()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(PLUGINS ${IMHEX_INCLUDE_PLUGINS})
|
||||
endif()
|
||||
|
||||
foreach(PLUGIN_NAME ${PLUGINS})
|
||||
message(STATUS "Enabled bundled plugin '${PLUGIN_NAME}'")
|
||||
endforeach()
|
||||
|
||||
if (NOT PLUGINS)
|
||||
message(FATAL_ERROR "No bundled plugins enabled")
|
||||
endif()
|
||||
|
||||
if (NOT ("builtin" IN_LIST PLUGINS))
|
||||
message(FATAL_ERROR "The 'builtin' plugin is required for ImHex to work!")
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
macro(setVariableInParent variable value)
|
||||
get_directory_property(hasParent PARENT_DIRECTORY)
|
||||
|
||||
@@ -427,9 +450,9 @@ function(downloadImHexPatternsFiles dest)
|
||||
endif ()
|
||||
|
||||
FetchContent_Declare(
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG origin/master
|
||||
imhex_patterns
|
||||
GIT_REPOSITORY https://github.com/WerWolv/ImHex-Patterns.git
|
||||
GIT_TAG origin/master
|
||||
)
|
||||
|
||||
message(STATUS "Downloading ImHex-Patterns repo branch ${PATTERNS_BRANCH}...")
|
||||
@@ -442,7 +465,7 @@ function(downloadImHexPatternsFiles dest)
|
||||
endif ()
|
||||
|
||||
if (EXISTS ${imhex_patterns_SOURCE_DIR})
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic)
|
||||
set(PATTERNS_FOLDERS_TO_INSTALL constants encodings includes patterns magic nodes)
|
||||
foreach (FOLDER ${PATTERNS_FOLDERS_TO_INSTALL})
|
||||
install(DIRECTORY "${imhex_patterns_SOURCE_DIR}/${FOLDER}" DESTINATION ${dest} PATTERN "**/_schema.json" EXCLUDE)
|
||||
endforeach ()
|
||||
@@ -452,23 +475,40 @@ endfunction()
|
||||
|
||||
macro(setupCompilerFlags target)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
|
||||
# Define strict compilation flags
|
||||
if (IMHEX_STRICT_WARNINGS)
|
||||
set(IMHEX_COMMON_FLAGS "-Wall -Wextra -Wpedantic -Werror")
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -Wall -Wextra -Wpedantic -Werror")
|
||||
endif()
|
||||
|
||||
set(IMHEX_C_FLAGS "${IMHEX_COMMON_FLAGS} -Wno-array-bounds -Wno-deprecated-declarations")
|
||||
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_C_FLAGS "${IMHEX_C_FLAGS} -Wno-restrict -Wno-stringop-overread -Wno-stringop-overflow -Wno-dangling-reference")
|
||||
if (UNIX AND NOT APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(IMHEX_COMMON_FLAGS "${IMHEX_COMMON_FLAGS} -rdynamic")
|
||||
endif()
|
||||
|
||||
set(IMHEX_CXX_FLAGS "-fexceptions -frtti")
|
||||
|
||||
# Disable some warnings
|
||||
set(IMHEX_C_CXX_FLAGS "-Wno-unknown-warning-option -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_FLAGS "${IMHEX_C_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
|
||||
set(IMHEX_C_CXX_FLAGS "${IMHEX_C_CXX_FLAGS} -pthread -Wno-dollar-in-identifier-extension -Wno-pthreads-mem-growth")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${IMHEX_CXX_FLAGS} ${IMHEX_C_FLAGS}")
|
||||
# Set actual CMake flags
|
||||
set_target_properties(${target} PROPERTIES COMPILE_FLAGS "${IMHEX_COMMON_FLAGS} ${IMHEX_C_CXX_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()
|
||||
|
||||
@@ -476,42 +516,43 @@ endmacro()
|
||||
macro(setUninstallTarget)
|
||||
if(NOT TARGET uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
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}/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)
|
||||
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(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()
|
||||
@@ -532,7 +573,7 @@ macro(addBundledLibraries)
|
||||
|
||||
# nfd
|
||||
if (NOT USE_SYSTEM_NFD)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${THIRD_PARTY_LIBS_FOLDER}/nativefiledialog EXCLUDE_FROM_ALL)
|
||||
set_target_properties(nfd PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(NFD_LIBRARIES nfd)
|
||||
else()
|
||||
@@ -542,7 +583,7 @@ macro(addBundledLibraries)
|
||||
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)
|
||||
@@ -550,32 +591,14 @@ macro(addBundledLibraries)
|
||||
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)
|
||||
set_target_properties(libyara PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(YARA_LIBRARIES libyara)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_MINIAUDIO)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/miniaudio EXCLUDE_FROM_ALL)
|
||||
set_target_properties(miniaudio PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set(MINIAUDIO_LIBRARIES miniaudio)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(miniaudio REQUIRED IMPORTED_TARGET miniaudio)
|
||||
endif()
|
||||
|
||||
if (NOT USE_SYSTEM_JTHREAD)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/jthread EXCLUDE_FROM_ALL)
|
||||
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")
|
||||
@@ -586,22 +609,8 @@ macro(addBundledLibraries)
|
||||
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)
|
||||
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)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_search_module(CAPSTONE 4.0.2 REQUIRED capstone)
|
||||
endif()
|
||||
|
||||
set(LIBPL_BUILD_CLI_AS_EXECUTABLE OFF)
|
||||
add_subdirectory(${EXTERN_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpl PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
find_package(mbedTLS 3.4.0 REQUIRED)
|
||||
@@ -638,6 +647,12 @@ macro(addBundledLibraries)
|
||||
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()
|
||||
@@ -667,9 +682,11 @@ function(generatePDBs)
|
||||
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)
|
||||
(
|
||||
${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)
|
||||
|
||||
@@ -680,10 +697,33 @@ function(generatePDBs)
|
||||
endfunction()
|
||||
|
||||
function(generateSDKDirectory)
|
||||
set(SDK_PATH "./sdk")
|
||||
if (WIN32)
|
||||
set(SDK_PATH "./sdk")
|
||||
elseif (APPLE)
|
||||
set(SDK_PATH "${BUNDLE_NAME}/Contents/Resources/sdk")
|
||||
else()
|
||||
set(SDK_PATH "share/imhex/sdk")
|
||||
endif()
|
||||
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/libimhex DESTINATION "${SDK_PATH}/lib")
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/external DESTINATION "${SDK_PATH}/lib")
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/imgui DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
if (NOT USE_SYSTEM_FMT)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/fmt DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
endif()
|
||||
if (NOT USE_SYSTEM_NLOHMANN_JSON)
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/lib/third_party/nlohmann_json DESTINATION "${SDK_PATH}/lib/third_party")
|
||||
endif()
|
||||
|
||||
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(FILES ${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake DESTINATION "${SDK_PATH}/cmake")
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/sdk/ DESTINATION "${SDK_PATH}")
|
||||
install(TARGETS libimhex ARCHIVE DESTINATION "${SDK_PATH}/lib")
|
||||
install(TARGETS libimhex RUNTIME DESTINATION "${SDK_PATH}/lib")
|
||||
install(TARGETS libimhex LIBRARY DESTINATION "${SDK_PATH}/lib")
|
||||
endfunction()
|
||||
|
||||
function(addIncludesFromLibrary target library)
|
||||
get_target_property(library_include_dirs ${library} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
target_include_directories(${target} PRIVATE ${library_include_dirs})
|
||||
endfunction()
|
||||
@@ -16,7 +16,7 @@ if (NOT DOTNET_EXECUTABLE)
|
||||
set(DOTNET_EXECUTABLE dotnet)
|
||||
endif ()
|
||||
|
||||
set(CORECLR_VERSION "7.0")
|
||||
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 "")
|
||||
@@ -75,7 +75,7 @@ find_file(CoreClrEmbed_SHARED_LIBRARY nethost.dll nethost.so libnethost.so netho
|
||||
|
||||
if (CoreClrEmbed_INCLUDE_DIR AND CoreClrEmbed_LIBRARY)
|
||||
set(CoreClrEmbed_FOUND TRUE)
|
||||
set(CoreClrEmbed_LIBRARIES "${CoreClrEmbed_LIBRARY}")
|
||||
set(CoreClrEmbed_SHARED_LIBRARIES "${CoreClrEmbed_SHARED_LIBRARY}")
|
||||
set(CoreClrEmbed_INCLUDE_DIRS "${CoreClrEmbed_INCLUDE_DIR}")
|
||||
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()
|
||||
@@ -1,10 +1,15 @@
|
||||
macro(add_imhex_plugin)
|
||||
# Parse arguments
|
||||
set(options "")
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs SOURCES INCLUDES LIBRARIES)
|
||||
set(options LIBRARY_PLUGIN)
|
||||
set(oneValueArgs NAME IMHEX_VERSION)
|
||||
set(multiValueArgs SOURCES INCLUDES LIBRARIES FEATURES)
|
||||
cmake_parse_arguments(IMHEX_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (IMHEX_PLUGIN_IMHEX_VERSION)
|
||||
message(STATUS "Compiling plugin ${IMHEX_PLUGIN_NAME} for ImHex Version ${IMHEX_PLUGIN_IMHEX_VERSION}")
|
||||
set(IMHEX_VERSION_STRING "${IMHEX_PLUGIN_IMHEX_VERSION}")
|
||||
endif()
|
||||
|
||||
if (IMHEX_STATIC_LINK_PLUGINS)
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE STATIC)
|
||||
|
||||
@@ -12,8 +17,15 @@ macro(add_imhex_plugin)
|
||||
|
||||
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)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
||||
else()
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE SHARED)
|
||||
if (IMHEX_PLUGIN_LIBRARY_PLUGIN)
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE SHARED)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexpluglib")
|
||||
else()
|
||||
set(IMHEX_PLUGIN_LIBRARY_TYPE MODULE)
|
||||
set(IMHEX_PLUGIN_SUFFIX ".hexplug")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Define new project for plugin
|
||||
@@ -24,7 +36,8 @@ macro(add_imhex_plugin)
|
||||
|
||||
# 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})
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE libimhex ${IMHEX_PLUGIN_LIBRARIES} ${FMT_LIBRARIES} imgui_all_includes libwolv)
|
||||
addIncludesFromLibrary(${IMHEX_PLUGIN_NAME} libpl)
|
||||
|
||||
# Add IMHEX_PROJECT_NAME and IMHEX_VERSION define
|
||||
target_compile_definitions(${IMHEX_PLUGIN_NAME} PRIVATE IMHEX_PROJECT_NAME="${IMHEX_PLUGIN_NAME}")
|
||||
@@ -33,6 +46,7 @@ macro(add_imhex_plugin)
|
||||
|
||||
# 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
|
||||
@@ -41,7 +55,7 @@ macro(add_imhex_plugin)
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins
|
||||
CXX_STANDARD 23
|
||||
PREFIX ""
|
||||
SUFFIX ".hexplug"
|
||||
SUFFIX ${IMHEX_PLUGIN_SUFFIX}
|
||||
)
|
||||
|
||||
# Setup a romfs for the plugin
|
||||
@@ -51,12 +65,38 @@ macro(add_imhex_plugin)
|
||||
set_target_properties(${LIBROMFS_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(${IMHEX_PLUGIN_NAME} PRIVATE ${LIBROMFS_LIBRARY})
|
||||
|
||||
foreach(feature ${IMHEX_PLUGIN_FEATURES})
|
||||
string(TOUPPER ${feature} feature)
|
||||
add_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=0)
|
||||
endforeach()
|
||||
|
||||
# Add the new plugin to the main dependency list so it gets built by default
|
||||
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
||||
if (TARGET imhex_all)
|
||||
add_dependencies(imhex_all ${IMHEX_PLUGIN_NAME})
|
||||
endif()
|
||||
|
||||
if (IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
install(TARGETS ${IMHEX_PLUGIN_NAME} DESTINATION ".")
|
||||
|
||||
# Fix rpath
|
||||
if (APPLE)
|
||||
set_target_properties(${IMHEX_PLUGIN_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks")
|
||||
endif()
|
||||
endif()
|
||||
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()
|
||||
|
||||
macro (enable_plugin_feature feature)
|
||||
string(TOUPPER ${feature} feature)
|
||||
if (NOT (feature IN_LIST IMHEX_PLUGIN_FEATURES))
|
||||
message(FATAL_ERROR "Feature ${feature} is not enabled for plugin ${IMHEX_PLUGIN_NAME}")
|
||||
endif()
|
||||
|
||||
remove_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=0)
|
||||
add_definitions(-DIMHEX_PLUGIN_${IMHEX_PLUGIN_NAME}_FEATURE_${feature}=1)
|
||||
endmacro()
|
||||
@@ -24,31 +24,38 @@ if(CMAKE_GENERATOR)
|
||||
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}")
|
||||
|
||||
|
||||
# Make sure to fix up any included ImHex plugin.
|
||||
file(GLOB_RECURSE extra_libs "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexplug")
|
||||
file(GLOB_RECURSE plugins "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexplug")
|
||||
file(GLOB_RECURSE plugin_libs "${BUNDLE_PATH}/Contents/MacOS/plugins/*.hexpluglib")
|
||||
|
||||
|
||||
# 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" ${EXTRA_BUNDLE_LIBRARY_PATHS})
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib" ${EXTRA_BUNDLE_LIBRARY_PATHS} "${BUNDLE_PATH}/Contents/MacOS/plugins")
|
||||
message(STATUS "Fixing up application bundle: ${extra_dirs}")
|
||||
|
||||
# BundleUtilities is overly verbose, so disable most of its messages
|
||||
function(message)
|
||||
if(NOT ARGV MATCHES "^STATUS;")
|
||||
_message(${ARGV})
|
||||
endif()
|
||||
endfunction()
|
||||
#function(message)
|
||||
# if(NOT ARGV MATCHES "^STATUS;")
|
||||
# _message(${ARGV})
|
||||
# endif()
|
||||
#endfunction()
|
||||
|
||||
include(BundleUtilities)
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}")
|
||||
fixup_bundle("${BUNDLE_PATH}" "${plugins};${plugin_libs}" "${extra_dirs}")
|
||||
|
||||
if (CODE_SIGN_CERTIFICATE_ID)
|
||||
# Hack around Apple Silicon signing bugs by copying the real app, signing it and moving it back.
|
||||
|
||||
48
cmake/sdk/CMakeLists.txt
Normal file
48
cmake/sdk/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(ImHexSDK)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/build_helpers.cmake")
|
||||
|
||||
set(IMHEX_BASE_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
|
||||
include(ImHexPlugin)
|
||||
|
||||
function(add_subdirectory_if_exists folder)
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${folder}/CMakeLists.txt")
|
||||
add_subdirectory("${folder}" EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set(IMHEX_EXTERNAL_PLUGIN_BUILD ON PARENT_SCOPE)
|
||||
set(IMHEX_EXTERNAL_PLUGIN_BUILD ON)
|
||||
add_custom_target(imhex_all)
|
||||
|
||||
add_subdirectory(lib/third_party/imgui EXCLUDE_FROM_ALL)
|
||||
|
||||
set(FMT_INSTALL OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory_if_exists(lib/third_party/fmt)
|
||||
set(FMT_LIBRARIES fmt::fmt-header-only PARENT_SCOPE)
|
||||
|
||||
add_subdirectory_if_exists(lib/third_party/nlohmann_json)
|
||||
|
||||
add_subdirectory(lib/external/libwolv EXCLUDE_FROM_ALL)
|
||||
|
||||
set(LIBPL_ENABLE_CLI OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(lib/external/pattern_language EXCLUDE_FROM_ALL)
|
||||
|
||||
add_subdirectory(lib/libimhex)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.dll"
|
||||
IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/liblibimhex.dll.a"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
elseif (APPLE)
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.dylib"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
else()
|
||||
set_target_properties(libimhex PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex.so"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/lib/libimhex/include")
|
||||
endif()
|
||||
60
cmake/sdk/template/CMakeLists.txt
Normal file
60
cmake/sdk/template/CMakeLists.txt
Normal file
@@ -0,0 +1,60 @@
|
||||
# ImHex Plugin Template
|
||||
# =====================
|
||||
|
||||
# This is the official CMake template for making your own ImHex plugins
|
||||
# To use this template, copy the file into its own directory and modify it to your needs
|
||||
# For the most part, this is a regular CMake project with some extra functions provided by the ImHex SDK
|
||||
#
|
||||
# [NOTE FOR NON-C++ PLUGINS]
|
||||
# The template is laid out for a C++ plugin, however you can write your plugin in any language you want
|
||||
# and just make the plugin statically link against your code. The only thing that's required is a .cpp file with
|
||||
# the IMHEX_PLUGIN_SETUP() macro used in it. This macro is used to setup the plugin and register it with ImHex
|
||||
#
|
||||
# [CMAKE FUNCTIONS]
|
||||
# add_imhex_plugin(): Registers a new plugin
|
||||
# NAME: The name of the plugin
|
||||
# IMHEX_VERSION: The ImHex version this plugin is compatible with. If unset, the plugin will be loaded on all versions (this may not work though)
|
||||
# SOURCES: Source files of the plugin
|
||||
# INCLUDES: Include directories of the plugin
|
||||
# LIBRARIES: Libraries to link against
|
||||
# FEATURES: Optional features that can be enabled or disabled
|
||||
# LIBRARY_PLUGIN: If set, turns this plugin into a library plugin. Library plugins can be linked against by other plugins
|
||||
#
|
||||
# add_romfs_resource(filePath romfsPath): Adds a file to the romfs of the plugin
|
||||
# The RomFS is a virtual filesystem whose files can be accessed by the plugin using the functions in the `romfs::` namespace
|
||||
# This function is used to add a single file to the romfs. You can however also simply create a `romfs` directory in your plugin directory and place your files and folders in there
|
||||
# filePath: The path to the file on the disk
|
||||
# romfsPath: The path to the file in the romfs
|
||||
#
|
||||
# enable_plugin_feature(feature): Enables a plugin feature
|
||||
# Features are optional parts of the plugin that may or may not be available depending on build settings
|
||||
# When a feature is enabled, `IMHEX_FEATURE_ENABLED(feature)` will be defined to true. Otherwise, it will be defined to false
|
||||
# Use the `IMHEX_PLUGIN_FEATURES` macro in the main plugin file to define names to each feature and have them be listed in the plugin list
|
||||
# feature: The name of the feature to enable
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(ImHexPlugin)
|
||||
|
||||
# Include the ImHex SDK
|
||||
# For this to work, you need to set the IMHEX_SDK_PATH environment variable to the path of the ImHex SDK
|
||||
#
|
||||
# On Windows, the SDK is next to the ImHex executable
|
||||
# On Linux, the SDK is usually in /usr/share/imhex/sdk but this may vary depending on your distribution
|
||||
# On MacOS, the SDK is located inside of the ImHex.app bundle under ImHex.app/Contents/Resources/sdk
|
||||
if (NOT EXISTS $ENV{IMHEX_SDK_PATH})
|
||||
message(FATAL_ERROR "The IMHEX_SDK_PATH environment variable is not set")
|
||||
endif()
|
||||
add_subdirectory($ENV{IMHEX_SDK_PATH} ImHexSDK)
|
||||
|
||||
# Register the plugin
|
||||
# This will configure everything you need to make your plugin work
|
||||
# Modify the arguments to your needs. Right now it defines a plugin called `example_plugin`
|
||||
# with a single source file called `example_plugin.cpp` in the `source` directory
|
||||
# By default you have access to the libimhex library to interact with ImHex
|
||||
# as well as libwolv, libromfs, libfmt and ImGui, but you can link against any libraries you want
|
||||
add_imhex_plugin(
|
||||
NAME
|
||||
example_plugin
|
||||
SOURCES
|
||||
source/example_plugin.cpp
|
||||
)
|
||||
11
cmake/sdk/template/source/example_plugin.cpp
Normal file
11
cmake/sdk/template/source/example_plugin.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <hex/plugin.hpp>
|
||||
|
||||
// Browse through the headers in lib/libimhex/include/hex/api/ to see what you can do with the API.
|
||||
// Most important ones are <hex/api/imhex_api.hpp> and <hex/api/content_registry.hpp>
|
||||
|
||||
// This is the main entry point of your plugin. The code in the body of this construct will be executed
|
||||
// when ImHex starts up and loads the plugin.
|
||||
// The strings in the header are used to display information about the plugin in the UI.
|
||||
IMHEX_PLUGIN_SETUP("Example Plugin", "Author", "Description") {
|
||||
// Put your init code here
|
||||
}
|
||||
5
dist/Arch/PKGBUILD
vendored
5
dist/Arch/PKGBUILD
vendored
@@ -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 gtk3 curl fmt yara nlohmann-json)
|
||||
depends=(glfw mbedtls freetype2 libglvnd dbus gtk3 curl fmt yara nlohmann-json zlib bzip2 xz zstd)
|
||||
makedepends=(git)
|
||||
provides=(imhex)
|
||||
conflicts=(imhex)
|
||||
@@ -17,9 +17,10 @@ md5sums=(SKIP)
|
||||
|
||||
package() {
|
||||
install -Dm755 "$srcdir/usr/bin/imhex" "$pkgdir/usr/bin/imhex"
|
||||
install -Dm755 "$srcdir/usr/bin/imhex-updater" "$pkgdir/usr/bin/imhex-updater"
|
||||
install -Dm644 "$srcdir/usr/lib/libimhex.so.$pkgver" "$pkgdir/usr/lib/libimhex.so.$pkgver"
|
||||
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug; do
|
||||
for plugin in "$srcdir/usr/lib/imhex/plugins/"*.hexplug*; do
|
||||
install -Dm644 "$plugin" "$pkgdir/usr/lib/imhex/plugins/${plugin##*/}"
|
||||
done
|
||||
|
||||
|
||||
6
dist/Brewfile
vendored
6
dist/Brewfile
vendored
@@ -9,4 +9,8 @@ brew "curl"
|
||||
brew "gcc@12"
|
||||
brew "llvm"
|
||||
brew "glfw"
|
||||
brew "ninja"
|
||||
brew "ninja"
|
||||
brew "zlib"
|
||||
brew "xz"
|
||||
brew "bzip2"
|
||||
brew "zstd"
|
||||
2
dist/DEBIAN/control.in
vendored
2
dist/DEBIAN/control.in
vendored
@@ -4,7 +4,7 @@ Section: editors
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
License: GNU GPL-2
|
||||
Depends: libglfw3, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Depends: libglfw3 | libglfw3-wayland, libmagic1, libmbedtls14, libfreetype6, libopengl0, libdbus-1-3, xdg-desktop-portal
|
||||
Maintainer: WerWolv <hey@werwolv.net>
|
||||
Description: ImHex Hex Editor
|
||||
A Hex Editor for Reverse Engineers, Programmers and
|
||||
|
||||
4
dist/ImHex-9999.ebuild
vendored
4
dist/ImHex-9999.ebuild
vendored
@@ -24,5 +24,9 @@ RDEPEND="${DEPEND}
|
||||
dev-cpp/nlohmann_json
|
||||
dbus
|
||||
xdg-desktop-portal
|
||||
sys-libs/zlib
|
||||
app-arch/bzip2
|
||||
app-arch/lzma
|
||||
app-arch/zstd
|
||||
"
|
||||
BDEPEND="${DEPEND}"
|
||||
|
||||
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)
|
||||
3
dist/compiling/macos.md
vendored
3
dist/compiling/macos.md
vendored
@@ -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 \
|
||||
|
||||
30
dist/get_deps_archlinux.sh
vendored
30
dist/get_deps_archlinux.sh
vendored
@@ -1,17 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
pacman -S $@ --needed \
|
||||
cmake \
|
||||
gcc \
|
||||
lld \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
dbus \
|
||||
gtk3 \
|
||||
curl \
|
||||
fmt \
|
||||
yara \
|
||||
cmake \
|
||||
gcc \
|
||||
lld \
|
||||
glfw \
|
||||
file \
|
||||
mbedtls \
|
||||
freetype2 \
|
||||
dbus \
|
||||
gtk3 \
|
||||
curl \
|
||||
fmt \
|
||||
yara \
|
||||
nlohmann-json \
|
||||
ninja
|
||||
ninja \
|
||||
zlib \
|
||||
bzip2 \
|
||||
xz \
|
||||
zstd
|
||||
|
||||
6
dist/get_deps_debian.sh
vendored
6
dist/get_deps_debian.sh
vendored
@@ -22,4 +22,8 @@ apt install -y \
|
||||
libdbus-1-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
libgtk-3-dev \
|
||||
ninja-build
|
||||
ninja-build \
|
||||
zlib1g-dev \
|
||||
libbz2-dev \
|
||||
liblzma-dev \
|
||||
libzstd-dev
|
||||
|
||||
6
dist/get_deps_fedora.sh
vendored
6
dist/get_deps_fedora.sh
vendored
@@ -12,4 +12,8 @@ dnf install -y \
|
||||
glfw-devel \
|
||||
lld \
|
||||
mbedtls-devel \
|
||||
gtk3-devel
|
||||
gtk3-devel \
|
||||
libzstd-devel \
|
||||
zlib-devel \
|
||||
bzip2-devel \
|
||||
xz-devel
|
||||
6
dist/get_deps_msys2.sh
vendored
6
dist/get_deps_msys2.sh
vendored
@@ -12,4 +12,8 @@ pacman -S --needed --noconfirm \
|
||||
mingw-w64-x86_64-freetype \
|
||||
mingw-w64-x86_64-dlfcn \
|
||||
mingw-w64-x86_64-ninja \
|
||||
mingw-w64-x86_64-capstone
|
||||
mingw-w64-x86_64-capstone \
|
||||
mingw-w64-x86_64-zlib \
|
||||
mingw-w64-x86_64-bzip2 \
|
||||
mingw-w64-x86_64-xz \
|
||||
mingw-w64-x86_64-zstd
|
||||
|
||||
173
dist/macOS/arm64.Dockerfile
vendored
Normal file
173
dist/macOS/arm64.Dockerfile
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
# 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
|
||||
vcpkg install --triplet=arm-osx-mytriplet zlib
|
||||
vcpkg install --triplet=arm-osx-mytriplet bzip2
|
||||
vcpkg install --triplet=arm-osx-mytriplet liblzma
|
||||
vcpkg install --triplet=arm-osx-mytriplet zstd
|
||||
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
|
||||
|
||||
RUN mkdir -p /vcpkg/installed/arm-osx-mytriplet/lib/pkgconfig
|
||||
RUN mkdir -p /osxcross/target/macports/pkgs/vcpkg/installed/arm-osx-mytriplet/lib/pkgconfig
|
||||
|
||||
## 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 \
|
||||
-DCMAKE_INSTALL_PREFIX=/mnt/ImHex/build/install \
|
||||
-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 --target install
|
||||
|
||||
ccache -s
|
||||
EOF
|
||||
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /mnt/ImHex/build/install/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
|
||||
4
dist/macOS/macos_arm_toolchain.cmake
vendored
4
dist/macOS/macos_arm_toolchain.cmake
vendored
@@ -1,4 +0,0 @@
|
||||
set(CMAKE_SYSTEM_NAME Darwin)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
||||
set(CMAKE_OSX_ARCHITECTURES arm64 CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_OSX_SYSROOT macosx CACHE INTERNAL "" FORCE)
|
||||
6
dist/msys2/PKGBUILD
vendored
6
dist/msys2/PKGBUILD
vendored
@@ -16,7 +16,11 @@ makedepends=("${MINGW_PACKAGE_PREFIX}-gcc"
|
||||
"${MINGW_PACKAGE_PREFIX}-file"
|
||||
"${MINGW_PACKAGE_PREFIX}-mbedtls"
|
||||
"${MINGW_PACKAGE_PREFIX}-polly"
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype")
|
||||
"${MINGW_PACKAGE_PREFIX}-freetype"
|
||||
"${MINGW_PACKAGE_PREFIX}-zlib"
|
||||
"${MINGW_PACKAGE_PREFIX}-bzip2"
|
||||
"${MINGW_PACKAGE_PREFIX}-xz"
|
||||
"${MINGW_PACKAGE_PREFIX}-zstd")
|
||||
|
||||
source=()
|
||||
sha256sums=()
|
||||
|
||||
43
dist/net.werwolv.ImHex.yaml
vendored
43
dist/net.werwolv.ImHex.yaml
vendored
@@ -12,49 +12,10 @@ finish-args:
|
||||
- --device=all
|
||||
|
||||
modules:
|
||||
- name: libiconv
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
|
||||
sha256: e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04
|
||||
|
||||
- name: glfw
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- -DBUILD_SHARED_LIBS:BOOL=ON
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/glfw/glfw/releases/download/3.3.2/glfw-3.3.2.zip
|
||||
sha256: 08a33a512f29d7dbf78eab39bd7858576adcc95228c9efe8e4bc5f0f3261efc7
|
||||
cleanup:
|
||||
- /include
|
||||
- /lib/pkgconfig
|
||||
|
||||
- name: mbedtls
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
- -DCMAKE_C_FLAGS=-fPIC
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/ARMmbed/mbedtls/archive/refs/tags/v2.27.0.tar.gz
|
||||
sha256: 2a07856e541f0e5f6eaee4f78018c52f25bd244ed76f9020dea54a8b02cac6ea
|
||||
|
||||
- name: nlohmann-json
|
||||
buildsystem: cmake-ninja
|
||||
builddir: true
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- -DBUILD_TESTING=OFF
|
||||
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/nlohmann/json/archive/v3.9.1.tar.gz
|
||||
sha256: 4cf0df69731494668bdd6460ed8cb269b68de9c19ad8c27abc24cd72605b2d5b
|
||||
|
||||
- name: imhex
|
||||
buildsystem: cmake
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
sources:
|
||||
- type: git
|
||||
|
||||
17
dist/rpm/imhex.spec
vendored
17
dist/rpm/imhex.spec
vendored
@@ -27,6 +27,10 @@ BuildRequires: mbedtls-devel
|
||||
BuildRequires: yara-devel
|
||||
BuildRequires: nativefiledialog-extended-devel
|
||||
BuildRequires: dotnet-sdk-7.0
|
||||
BuildRequires: libzstd-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: bzip2-devel
|
||||
BuildRequires: xz-devel
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: gcc-toolset-12
|
||||
%endif
|
||||
@@ -61,7 +65,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}
|
||||
@@ -109,17 +113,18 @@ 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/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
|
||||
%license %{_datadir}/licenses/%{name}/
|
||||
%doc README.md
|
||||
%{_bindir}/imhex
|
||||
%{_bindir}/imhex-updater
|
||||
%{_datadir}/pixmaps/%{name}.png
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_libdir}/libimhex.so*
|
||||
|
||||
7
dist/web/Dockerfile
vendored
7
dist/web/Dockerfile
vendored
@@ -37,6 +37,10 @@ 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
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten zlib
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten bzip2
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten liblzma
|
||||
/vcpkg/vcpkg install --triplet=wasm32-emscripten zstd
|
||||
EOF
|
||||
|
||||
# Build ImHex
|
||||
@@ -54,6 +58,7 @@ ccache -zs
|
||||
cmake /imhex \
|
||||
-DIMHEX_OFFLINE_BUILD=ON \
|
||||
-DIMHEX_STATIC_LINK_PLUGINS=ON \
|
||||
-DIMHEX_EXCLUDE_PLUGINS="script_loader" \
|
||||
-DNATIVE_CMAKE_C_COMPILER=gcc \
|
||||
-DNATIVE_CMAKE_CXX_COMPILER=g++ \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
@@ -83,6 +88,8 @@ COPY --from=build [ \
|
||||
"/build/favicon.ico", \
|
||||
"/build/icon.png", \
|
||||
"/build/manifest.json", \
|
||||
"/build/robots.txt", \
|
||||
"/build/sitemap.xml", \
|
||||
\
|
||||
# Destination \
|
||||
"./" \
|
||||
|
||||
51
dist/web/source/index.html
vendored
51
dist/web/source/index.html
vendored
@@ -1,23 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<meta charset="utf-8">
|
||||
<title>ImHex Web - Free Online Hex Editor for Reverse Engineers</title>
|
||||
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<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">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- 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.">
|
||||
<meta name="description" content="Free and extremely powerful Online Hex Editor for your Web Browser. ImHex is a free and open source Hex Editor for Reverse Engineers and Developers and Data Analysts.">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="apple-touch-icon" href="icon.png">
|
||||
|
||||
<!-- 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 -->
|
||||
@@ -28,9 +27,7 @@
|
||||
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" />
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
@@ -60,15 +57,41 @@
|
||||
}
|
||||
</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>
|
||||
<div id="loading" class="centered">
|
||||
<img src="https://raw.githubusercontent.com/WerWolv/ImHex/master/plugins/builtin/romfs/assets/dark/banner.png" id="logo" alt="ImHex Logo">
|
||||
<h1>A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.</h1>
|
||||
<h2>Available both natively and on the web</h2>
|
||||
<h5>ImHex runs directly in your web browser with the help of Emscripten and WebAssembly.</h5>
|
||||
|
||||
<div style="height: 50%">
|
||||
<div style="height: 30%"> </div>
|
||||
<h2 id="not_working">
|
||||
Not loading in your Browser? <a href="https://imhex.werwolv.net">Try the native version</a>
|
||||
</h2>
|
||||
<div style="height: 50%"></div>
|
||||
</div>
|
||||
|
||||
<div class="loading_ripple">
|
||||
<div class="lds-ripple"><div></div><div></div></div>
|
||||
</div>
|
||||
|
||||
<div style="height: 10%">
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<a href="https://imhex.werwolv.net">Homepage</a>
|
||||
<p>Made with ♥️ by the ImHex Team</p>
|
||||
<a href="https://github.com/WerWolv/ImHex">GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<script src="wasm-config.js"></script>
|
||||
<script async src="imhex.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
4
dist/web/source/robots.txt
vendored
Normal file
4
dist/web/source/robots.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://imhex.werwolv.net/sitemap.xml
|
||||
14
dist/web/source/sitemap.xml
vendored
Normal file
14
dist/web/source/sitemap.xml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset
|
||||
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||
|
||||
<url>
|
||||
<loc>https://web.imhex.werwolv.net/</loc>
|
||||
<lastmod>2023-12-07T22:53:06+00:00</lastmod>
|
||||
</url>
|
||||
|
||||
|
||||
</urlset>
|
||||
123
dist/web/source/style.css
vendored
123
dist/web/source/style.css
vendored
@@ -1,6 +1,6 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
margin: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -16,21 +16,120 @@ body {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
border: 0px none;
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
.canvas_full_screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#loading_text {
|
||||
h1, h2, h5 {
|
||||
color: #F0F0F0;
|
||||
font-size: 30px;
|
||||
font-size: 20px;
|
||||
font-family: monospace;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 60px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 15px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-top: 0;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#not_working {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#not_working.visible {
|
||||
opacity: 1;
|
||||
transition: opacity 2s ease;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #7893ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-shadow: #3a4677 0 0 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
color: #F0F0F0;
|
||||
background-color: #0A0A0A;
|
||||
padding: 10px;
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 10%;
|
||||
}
|
||||
|
||||
.centered {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.lds-ripple {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.lds-ripple div {
|
||||
position: absolute;
|
||||
border: 4px solid #fff;
|
||||
opacity: 1;
|
||||
border-radius: 50%;
|
||||
animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
|
||||
}
|
||||
.lds-ripple div:nth-child(2) {
|
||||
animation-delay: -0.5s;
|
||||
}
|
||||
@keyframes lds-ripple {
|
||||
0% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
4.9% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
5% {
|
||||
top: 36px;
|
||||
left: 36px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
16
dist/web/source/wasm-config.js
vendored
16
dist/web/source/wasm-config.js
vendored
@@ -30,16 +30,22 @@ function glfwCreateStandardCursorCustom(shape) {
|
||||
return shape
|
||||
}
|
||||
|
||||
var notWorkingTimer = setTimeout(() => {
|
||||
document.getElementById("not_working").classList.add("visible")
|
||||
}, 5000);
|
||||
|
||||
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("loading").style.display = "none"
|
||||
document.getElementById("canvas").style.display = "initial"
|
||||
|
||||
clearTimeout(notWorkingTimer);
|
||||
},
|
||||
print: (function() { })(),
|
||||
printErr: function(text) { },
|
||||
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
|
||||
@@ -67,4 +73,10 @@ function js_resizeCanvas() {
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||
|
||||
canvas.classList.add("canvas_full_screen")
|
||||
|
||||
if (GLFW.active && GLFW.active.windowPosFunc) {
|
||||
getWasmTableEntry(GLFW.active.windowPosFunc)(GLFW.active.id, GLFW.active.x, GLFW.active.y);
|
||||
}
|
||||
|
||||
GLFW.onWindowSizeChanged();
|
||||
}
|
||||
1
lib/external/fmt
vendored
1
lib/external/fmt
vendored
Submodule lib/external/fmt deleted from f918289363
40
lib/external/imgui/CMakeLists.txt
vendored
40
lib/external/imgui/CMakeLists.txt
vendored
@@ -1,40 +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
|
||||
include/misc/freetype/imgui_freetype.cpp # TODO move source and includes in the same directory
|
||||
source/imgui_impl_glfw.cpp
|
||||
source/imgui_impl_opengl3.cpp
|
||||
source/imgui_tables.cpp
|
||||
source/imgui_widgets.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
|
||||
)
|
||||
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imgui_config.h")
|
||||
target_compile_options(imgui PRIVATE -Wno-unknown-warning-option)
|
||||
|
||||
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})
|
||||
1015
lib/external/imgui/include/fonts/fontawesome_font.h
vendored
1015
lib/external/imgui/include/fonts/fontawesome_font.h
vendored
File diff suppressed because it is too large
Load Diff
9
lib/external/imgui/include/imgui_config.h
vendored
9
lib/external/imgui/include/imgui_config.h
vendored
@@ -1,9 +0,0 @@
|
||||
// ImGui config (check imconfig.h for more information about these definitions)
|
||||
#pragma once
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
#define IMGUI_ENABLE_FREETYPE
|
||||
#define ImDrawIdx unsigned int
|
||||
#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
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
2
lib/external/libromfs
vendored
2
lib/external/libromfs
vendored
Submodule lib/external/libromfs updated: c42309b7c4...0a72f7bb33
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: 7e306b0e0a...7efd66f817
@@ -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
|
||||
1
lib/external/nativefiledialog
vendored
1
lib/external/nativefiledialog
vendored
Submodule lib/external/nativefiledialog deleted from 800f58283f
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
Submodule lib/external/pattern_language updated: 6eb5556104...78cdc3e7fd
@@ -5,17 +5,19 @@ 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/event_manager.cpp
|
||||
source/api/task_manager.cpp
|
||||
source/api/shortcut_manager.cpp
|
||||
source/api/plugin_manager.cpp
|
||||
source/api/localization.cpp
|
||||
source/api/project_file_manager.cpp
|
||||
source/api/theme_manager.cpp
|
||||
source/api/layout_manager.cpp
|
||||
source/api/workspace_manager.cpp
|
||||
source/api/achievement_manager.cpp
|
||||
source/api/localization_manager.cpp
|
||||
source/api/tutorial_manager.cpp
|
||||
|
||||
source/data_processor/attribute.cpp
|
||||
source/data_processor/link.cpp
|
||||
@@ -33,15 +35,17 @@ set(LIBIMHEX_SOURCES
|
||||
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/memory_provider.cpp
|
||||
source/providers/undo/stack.cpp
|
||||
|
||||
source/ui/imgui_imhex_extensions.cpp
|
||||
source/ui/view.cpp
|
||||
source/ui/popup.cpp
|
||||
source/ui/toast.cpp
|
||||
|
||||
source/subcommands/subcommands.cpp
|
||||
)
|
||||
@@ -59,40 +63,51 @@ if (APPLE)
|
||||
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/utils_macos.m)
|
||||
endif ()
|
||||
|
||||
add_compile_definitions(IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
|
||||
if (IMHEX_STATIC_LINK_PLUGINS)
|
||||
add_library(libimhex STATIC ${LIBIMHEX_SOURCES})
|
||||
if (IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
add_library(libimhex IMPORTED SHARED GLOBAL)
|
||||
set(LIBIMHEX_LIBRARY_TYPE INTERFACE)
|
||||
else()
|
||||
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(LIBIMHEX_LIBRARY_TYPE PUBLIC)
|
||||
target_compile_definitions(libimhex PRIVATE IMHEX_PROJECT_NAME="${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
set_target_properties(libimhex PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
enableUnityBuild(libimhex)
|
||||
setupCompilerFlags(libimhex)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(libimhex)
|
||||
|
||||
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})
|
||||
target_include_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} include ${XDGPP_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIR} ${MAGIC_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${LIBBACKTRACE_INCLUDE_DIRS})
|
||||
target_link_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${MBEDTLS_LIBRARY_DIR} ${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})
|
||||
target_include_directories(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${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)
|
||||
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
|
||||
endif ()
|
||||
if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
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)
|
||||
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
|
||||
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} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} plcli libpl libpl-gen ${MINIAUDIO_LIBRARIES} ${JTHREAD_LIBRARIES} libwolv-utils libwolv-io libwolv-hash libwolv-net libwolv-containers)
|
||||
target_link_libraries(libimhex PRIVATE microtar libpl plcli libpl-gen libwolv ${NFD_LIBRARIES} magic dl ${NLOHMANN_JSON_LIBRARIES} ${MBEDTLS_LIBRARIES} ${LIBBACKTRACE_LIBRARIES} ${JTHREAD_LIBRARIES})
|
||||
target_link_libraries(libimhex PUBLIC ${IMGUI_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(libimhex ${LIBIMHEX_LIBRARY_TYPE} ${NLOHMANN_JSON_LIBRARIES} imgui_all_includes ${FMT_LIBRARIES})
|
||||
|
||||
set_property(TARGET libimhex PROPERTY INTERPROCEDURAL_OPTIMIZATION FALSE)
|
||||
|
||||
@@ -108,6 +123,7 @@ else()
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_BRANCH
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
# Get the latest abbreviated commit hash of the working branch
|
||||
@@ -117,6 +133,7 @@ else()
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH_SHORT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_HASH_SHORT
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
execute_process(
|
||||
@@ -125,6 +142,7 @@ else()
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH_LONG
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE RESULT_HASH_LONG
|
||||
ERROR_QUIET
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <span>
|
||||
|
||||
#include <hex/api/event.hpp>
|
||||
#include <imgui.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -18,22 +21,22 @@ namespace hex {
|
||||
|
||||
class Achievement {
|
||||
public:
|
||||
explicit Achievement(std::string unlocalizedCategory, std::string unlocalizedName) : m_unlocalizedCategory(std::move(unlocalizedCategory)), m_unlocalizedName(std::move(unlocalizedName)) { }
|
||||
explicit Achievement(UnlocalizedString unlocalizedCategory, UnlocalizedString 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;
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
return 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;
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedCategory() const {
|
||||
return m_unlocalizedCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,7 +44,7 @@ namespace hex {
|
||||
* @return Whether the achievement is unlocked
|
||||
*/
|
||||
[[nodiscard]] bool isUnlocked() const {
|
||||
return this->m_progress == this->m_maxProgress;
|
||||
return m_progress == m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +53,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setDescription(std::string description) {
|
||||
this->m_unlocalizedDescription = std::move(description);
|
||||
m_unlocalizedDescription = std::move(description);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -61,7 +64,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addRequirement(std::string requirement) {
|
||||
this->m_requirements.emplace_back(std::move(requirement));
|
||||
m_requirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -72,7 +75,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& addVisibilityRequirement(std::string requirement) {
|
||||
this->m_visibilityRequirements.emplace_back(std::move(requirement));
|
||||
m_visibilityRequirements.emplace_back(std::move(requirement));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -82,7 +85,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setBlacked() {
|
||||
this->m_blacked = true;
|
||||
m_blacked = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -92,7 +95,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setInvisible() {
|
||||
this->m_invisible = true;
|
||||
m_invisible = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -102,7 +105,7 @@ namespace hex {
|
||||
* @return Whether the achievement is blacked
|
||||
*/
|
||||
[[nodiscard]] bool isBlacked() const {
|
||||
return this->m_blacked;
|
||||
return m_blacked;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +113,7 @@ namespace hex {
|
||||
* @return Whether the achievement is invisible
|
||||
*/
|
||||
[[nodiscard]] bool isInvisible() const {
|
||||
return this->m_invisible;
|
||||
return m_invisible;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +121,7 @@ namespace hex {
|
||||
* @return List of requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getRequirements() const {
|
||||
return this->m_requirements;
|
||||
return m_requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,31 +129,31 @@ namespace hex {
|
||||
* @return List of visibility requirements of the achievement
|
||||
*/
|
||||
[[nodiscard]] const std::vector<std::string> &getVisibilityRequirements() const {
|
||||
return this->m_visibilityRequirements;
|
||||
return 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;
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedDescription() const {
|
||||
return m_unlocalizedDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the icon of the achievement
|
||||
* @return Icon of the achievement
|
||||
*/
|
||||
[[nodiscard]] const ImGui::Texture &getIcon() const {
|
||||
if (this->m_iconData.empty())
|
||||
return this->m_icon;
|
||||
|
||||
if (this->m_icon.isValid())
|
||||
[[nodiscard]] const ImGuiExt::Texture &getIcon() const {
|
||||
if (m_iconData.empty())
|
||||
return m_icon;
|
||||
|
||||
this->m_icon = ImGui::Texture(reinterpret_cast<const u8*>(this->m_iconData.data()), this->m_iconData.size());
|
||||
if (m_icon.isValid())
|
||||
return m_icon;
|
||||
|
||||
return this->m_icon;
|
||||
m_icon = ImGuiExt::Texture(m_iconData.data(), m_iconData.size(), ImGuiExt::Texture::Filter::Linear);
|
||||
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,9 +162,9 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const std::byte> data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -172,7 +175,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::span<const u8> data) {
|
||||
this->m_iconData.assign(data.begin(), data.end());
|
||||
m_iconData.assign(data.begin(), data.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -183,7 +186,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(std::vector<u8> data) {
|
||||
this->m_iconData = std::move(data);
|
||||
m_iconData = std::move(data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -194,9 +197,9 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setIcon(const std::vector<std::byte> &data) {
|
||||
this->m_iconData.reserve(data.size());
|
||||
m_iconData.reserve(data.size());
|
||||
for (auto &byte : data)
|
||||
this->m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
m_iconData.emplace_back(static_cast<u8>(byte));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -207,7 +210,7 @@ namespace hex {
|
||||
* @return Reference to the achievement
|
||||
*/
|
||||
Achievement& setRequiredProgress(u32 progress) {
|
||||
this->m_maxProgress = progress;
|
||||
m_maxProgress = progress;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -217,7 +220,7 @@ namespace hex {
|
||||
* @return Required progress to unlock the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getRequiredProgress() const {
|
||||
return this->m_maxProgress;
|
||||
return m_maxProgress;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +228,7 @@ namespace hex {
|
||||
* @return Current progress of the achievement
|
||||
*/
|
||||
[[nodiscard]] u32 getProgress() const {
|
||||
return this->m_progress;
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +236,7 @@ namespace hex {
|
||||
* @param callback Callback to call when the achievement is clicked
|
||||
*/
|
||||
void setClickCallback(const std::function<void(Achievement &)> &callback) {
|
||||
this->m_clickCallback = callback;
|
||||
m_clickCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +244,7 @@ namespace hex {
|
||||
* @return Callback to call when the achievement is clicked
|
||||
*/
|
||||
[[nodiscard]] const std::function<void(Achievement &)> &getClickCallback() const {
|
||||
return this->m_clickCallback;
|
||||
return m_clickCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +252,7 @@ namespace hex {
|
||||
* @return Whether the achievement is temporary
|
||||
*/
|
||||
[[nodiscard]] bool isTemporary() const {
|
||||
return this->m_temporary;
|
||||
return m_temporary;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,21 +261,21 @@ namespace hex {
|
||||
*/
|
||||
void setUnlocked(bool unlocked) {
|
||||
if (unlocked) {
|
||||
if (this->m_progress < this->m_maxProgress)
|
||||
this->m_progress++;
|
||||
if (m_progress < m_maxProgress)
|
||||
m_progress++;
|
||||
} else {
|
||||
this->m_progress = 0;
|
||||
m_progress = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void setProgress(u32 progress) {
|
||||
this->m_progress = progress;
|
||||
m_progress = progress;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedCategory, m_unlocalizedName;
|
||||
std::string m_unlocalizedDescription;
|
||||
UnlocalizedString m_unlocalizedCategory, m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedDescription;
|
||||
|
||||
bool m_blacked = false;
|
||||
bool m_invisible = false;
|
||||
@@ -281,7 +284,7 @@ namespace hex {
|
||||
std::function<void(Achievement &)> m_clickCallback;
|
||||
|
||||
std::vector<u8> m_iconData;
|
||||
mutable ImGui::Texture m_icon;
|
||||
mutable ImGuiExt::Texture m_icon;
|
||||
|
||||
u32 m_progress = 0;
|
||||
u32 m_maxProgress = 1;
|
||||
@@ -350,7 +353,7 @@ namespace hex {
|
||||
*/
|
||||
template<std::derived_from<Achievement> T = Achievement>
|
||||
static Achievement& addTemporaryAchievement(auto && ... args) {
|
||||
auto &achievement = addAchievement(std::forward<decltype(args)>(args)...);
|
||||
auto &achievement = addAchievement<T>(std::forward<decltype(args)>(args)...);
|
||||
|
||||
achievement.m_temporary = true;
|
||||
|
||||
@@ -362,7 +365,7 @@ namespace hex {
|
||||
* @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);
|
||||
static void unlockAchievement(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName);
|
||||
|
||||
/**
|
||||
* @brief Returns all registered achievements
|
||||
@@ -405,6 +408,12 @@ namespace hex {
|
||||
*/
|
||||
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();
|
||||
};
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
#include <pl/pattern_language.hpp>
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <jthread.hpp>
|
||||
|
||||
#include <pl/pattern_language.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
using ImGuiDataType = int;
|
||||
using ImGuiInputTextFlags = int;
|
||||
@@ -28,7 +22,7 @@ struct ImColor;
|
||||
namespace hex {
|
||||
|
||||
class View;
|
||||
class LanguageDefinition;
|
||||
class Shortcut;
|
||||
|
||||
namespace dp {
|
||||
class Node;
|
||||
@@ -37,6 +31,10 @@ namespace hex {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
namespace LocalizationManager {
|
||||
class LanguageDefinition;
|
||||
}
|
||||
|
||||
/*
|
||||
The Content Registry is the heart of all features in ImHex that are in some way extendable by Plugins.
|
||||
It allows you to add/register new content that will be picked up and used by the ImHex core or by other
|
||||
@@ -63,32 +61,32 @@ namespace hex {
|
||||
friend class Widget;
|
||||
|
||||
Interface& requiresRestart() {
|
||||
this->m_requiresRestart = true;
|
||||
m_requiresRestart = true;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setEnabledCallback(std::function<bool()> callback) {
|
||||
this->m_enabledCallback = std::move(callback);
|
||||
m_enabledCallback = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setChangedCallback(std::function<void(Widget&)> callback) {
|
||||
this->m_changedCallback = std::move(callback);
|
||||
m_changedCallback = std::move(callback);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interface& setTooltip(const std::string &tooltip) {
|
||||
this->m_tooltip = tooltip;
|
||||
m_tooltip = tooltip;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Widget& getWidget() const {
|
||||
return *this->m_widget;
|
||||
return *m_widget;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -103,34 +101,34 @@ namespace hex {
|
||||
|
||||
[[nodiscard]]
|
||||
bool doesRequireRestart() const {
|
||||
return this->m_interface.m_requiresRestart;
|
||||
return m_interface.m_requiresRestart;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
bool isEnabled() const {
|
||||
return !this->m_interface.m_enabledCallback || this->m_interface.m_enabledCallback();
|
||||
return !m_interface.m_enabledCallback || m_interface.m_enabledCallback();
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
const std::optional<std::string>& getTooltip() const {
|
||||
return this->m_interface.m_tooltip;
|
||||
return m_interface.m_tooltip;
|
||||
}
|
||||
|
||||
void onChanged() {
|
||||
if (this->m_interface.m_changedCallback)
|
||||
this->m_interface.m_changedCallback(*this);
|
||||
if (m_interface.m_changedCallback)
|
||||
m_interface.m_changedCallback(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Interface& getInterface() {
|
||||
return this->m_interface;
|
||||
return m_interface;
|
||||
}
|
||||
|
||||
private:
|
||||
Interface m_interface = Interface(this);
|
||||
};
|
||||
|
||||
class Checkbox : public Widget {
|
||||
class Checkbox : public Widget {
|
||||
public:
|
||||
explicit Checkbox(bool defaultValue) : m_value(defaultValue) { }
|
||||
|
||||
@@ -139,11 +137,12 @@ namespace hex {
|
||||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] bool isChecked() const { return this->m_value; }
|
||||
[[nodiscard]] bool isChecked() const { return m_value; }
|
||||
|
||||
private:
|
||||
bool m_value;
|
||||
};
|
||||
|
||||
class SliderInteger : public Widget {
|
||||
public:
|
||||
SliderInteger(i32 defaultValue, i32 min, i32 max) : m_value(defaultValue), m_min(min), m_max(max) { }
|
||||
@@ -152,13 +151,14 @@ namespace hex {
|
||||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] i32 getValue() const { return this->m_value; }
|
||||
[[nodiscard]] i32 getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
i32 m_min, m_max;
|
||||
};
|
||||
class SliderFloat : public Widget {
|
||||
|
||||
class SliderFloat : public Widget {
|
||||
public:
|
||||
SliderFloat(float defaultValue, float min, float max) : m_value(defaultValue), m_min(min), m_max(max) { }
|
||||
bool draw(const std::string &name) override;
|
||||
@@ -166,13 +166,14 @@ namespace hex {
|
||||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]] float getValue() const { return this->m_value; }
|
||||
[[nodiscard]] float getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
float m_value;
|
||||
float m_min, m_max;
|
||||
};
|
||||
class ColorPicker : public Widget {
|
||||
|
||||
class ColorPicker : public Widget {
|
||||
public:
|
||||
explicit ColorPicker(ImColor defaultColor);
|
||||
|
||||
@@ -184,9 +185,10 @@ namespace hex {
|
||||
[[nodiscard]] ImColor getColor() const;
|
||||
|
||||
private:
|
||||
std::array<float, 4> m_value;
|
||||
std::array<float, 4> m_value{};
|
||||
};
|
||||
class DropDown : public Widget {
|
||||
|
||||
class DropDown : public Widget {
|
||||
public:
|
||||
explicit DropDown(const std::vector<std::string> &items, const std::vector<nlohmann::json> &settingsValues, const nlohmann::json &defaultItem) : m_items(items), m_settingsValues(settingsValues), m_defaultItem(defaultItem) { }
|
||||
|
||||
@@ -205,7 +207,8 @@ namespace hex {
|
||||
|
||||
int m_value = -1;
|
||||
};
|
||||
class TextBox : public Widget {
|
||||
|
||||
class TextBox : public Widget {
|
||||
public:
|
||||
explicit TextBox(std::string defaultValue) : m_value(std::move(defaultValue)) { }
|
||||
|
||||
@@ -215,43 +218,52 @@ namespace hex {
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]]
|
||||
const std::string& getValue() const { return this->m_value; }
|
||||
const std::string& getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
};
|
||||
class FilePicker : public Widget {
|
||||
|
||||
class FilePicker : public Widget {
|
||||
public:
|
||||
bool draw(const std::string &name) override;
|
||||
|
||||
void load(const nlohmann::json &data) override;
|
||||
nlohmann::json store() override;
|
||||
|
||||
[[nodiscard]]
|
||||
std::fs::path getPath() const { return this->m_value; }
|
||||
[[nodiscard]] std::fs::path getPath() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
class Label : public Widget {
|
||||
public:
|
||||
bool draw(const std::string &name) override;
|
||||
|
||||
void load(const nlohmann::json &) override {}
|
||||
nlohmann::json store() override { return {}; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct Entry {
|
||||
std::string unlocalizedName;
|
||||
UnlocalizedString unlocalizedName;
|
||||
std::unique_ptr<Widgets::Widget> widget;
|
||||
};
|
||||
|
||||
struct SubCategory {
|
||||
std::string unlocalizedName;
|
||||
UnlocalizedString unlocalizedName;
|
||||
std::vector<Entry> entries;
|
||||
};
|
||||
|
||||
struct Category {
|
||||
std::string unlocalizedName;
|
||||
std::string unlocalizedDescription;
|
||||
UnlocalizedString unlocalizedName;
|
||||
UnlocalizedString unlocalizedDescription;
|
||||
std::vector<SubCategory> subCategories;
|
||||
};
|
||||
|
||||
@@ -260,14 +272,14 @@ namespace hex {
|
||||
void clear();
|
||||
|
||||
std::vector<Category> &getSettings();
|
||||
nlohmann::json& getSetting(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &defaultValue);
|
||||
nlohmann::json& getSetting(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &defaultValue);
|
||||
nlohmann::json &getSettingsData();
|
||||
|
||||
Widgets::Widget* add(const std::string &unlocalizedCategory, const std::string &unlocalizedSubCategory, const std::string &unlocalizedName, std::unique_ptr<Widgets::Widget> &&widget);
|
||||
Widgets::Widget* add(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedSubCategory, const UnlocalizedString &unlocalizedName, std::unique_ptr<Widgets::Widget> &&widget);
|
||||
}
|
||||
|
||||
template<std::derived_from<Widgets::Widget> T>
|
||||
Widgets::Widget::Interface& add(const std::string &unlocalizedCategory, const std::string &unlocalizedSubCategory, const std::string &unlocalizedName, auto && ... args) {
|
||||
Widgets::Widget::Interface& add(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedSubCategory, const UnlocalizedString &unlocalizedName, auto && ... args) {
|
||||
return impl::add(
|
||||
unlocalizedCategory,
|
||||
unlocalizedSubCategory,
|
||||
@@ -276,10 +288,10 @@ namespace hex {
|
||||
)->getInterface();
|
||||
}
|
||||
|
||||
void setCategoryDescription(const std::string &unlocalizedCategory, const std::string &unlocalizedDescription);
|
||||
void setCategoryDescription(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedDescription);
|
||||
|
||||
nlohmann::json read(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &defaultValue);
|
||||
void write(const std::string &unlocalizedCategory, const std::string &unlocalizedName, const nlohmann::json &value);
|
||||
[[nodiscard]] nlohmann::json read(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &defaultValue);
|
||||
void write(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, const nlohmann::json &value);
|
||||
}
|
||||
|
||||
/* Command Palette Command Registry. Allows adding of new commands to the command palette */
|
||||
@@ -304,7 +316,7 @@ namespace hex {
|
||||
struct Entry {
|
||||
Type type;
|
||||
std::string command;
|
||||
std::string unlocalizedDescription;
|
||||
UnlocalizedString unlocalizedDescription;
|
||||
DisplayCallback displayCallback;
|
||||
ExecuteCallback executeCallback;
|
||||
};
|
||||
@@ -316,8 +328,8 @@ namespace hex {
|
||||
DisplayCallback displayCallback;
|
||||
};
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<impl::Handler> &getHandlers();
|
||||
std::vector<Entry> &getEntries();
|
||||
std::vector<Handler> &getHandlers();
|
||||
|
||||
}
|
||||
|
||||
@@ -332,7 +344,7 @@ namespace hex {
|
||||
void add(
|
||||
Type type,
|
||||
const std::string &command,
|
||||
const std::string &unlocalizedDescription,
|
||||
const UnlocalizedString &unlocalizedDescription,
|
||||
const impl::DisplayCallback &displayCallback,
|
||||
const impl::ExecuteCallback &executeCallback = [](auto) {});
|
||||
|
||||
@@ -340,7 +352,6 @@ namespace hex {
|
||||
* @brief Adds a new command handler to the command palette
|
||||
* @param type The type of the command
|
||||
* @param command The command to add
|
||||
* @param unlocalizedDescription The description of the command
|
||||
* @param queryCallback The callback that will be called when the command palette wants to load the name and callback items
|
||||
* @param displayCallback The callback that will be called when the command is displayed in the command palette
|
||||
*/
|
||||
@@ -376,7 +387,7 @@ namespace hex {
|
||||
std::map<std::string, Visualizer> &getVisualizers();
|
||||
std::map<std::string, Visualizer> &getInlineVisualizers();
|
||||
std::map<std::string, pl::api::PragmaHandler> &getPragmas();
|
||||
std::vector<impl::FunctionDefinition> &getFunctions();
|
||||
std::vector<FunctionDefinition> &getFunctions();
|
||||
|
||||
}
|
||||
|
||||
@@ -429,19 +440,19 @@ namespace hex {
|
||||
* @brief Adds a new visualizer to the pattern language
|
||||
* @note Visualizers are extensions to the [[hex::visualize]] attribute, used to visualize data
|
||||
* @param name The name of the visualizer
|
||||
* @param func The function callback
|
||||
* @param function The function callback
|
||||
* @param parameterCount The amount of parameters the function takes
|
||||
*/
|
||||
void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &func, pl::api::FunctionParameterCount parameterCount);
|
||||
void addVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount);
|
||||
|
||||
/**
|
||||
* @brief Adds a new inline visualizer to the pattern language
|
||||
* @note Inline visualizers are extensions to the [[hex::inline_visualize]] attribute, used to visualize data
|
||||
* @param name The name of the visualizer
|
||||
* @param func The function callback
|
||||
* @param function The function callback
|
||||
* @param parameterCount The amount of parameters the function takes
|
||||
*/
|
||||
void addInlineVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &func, pl::api::FunctionParameterCount parameterCount);
|
||||
void addInlineVisualizer(const std::string &name, const impl::VisualizerFunctionCallback &function, pl::api::FunctionParameterCount parameterCount);
|
||||
|
||||
}
|
||||
|
||||
@@ -471,7 +482,7 @@ namespace hex {
|
||||
* @param unlocalizedName The unlocalized name of the view
|
||||
* @return The view if it exists, nullptr otherwise
|
||||
*/
|
||||
View* getViewByName(const std::string &unlocalizedName);
|
||||
View* getViewByName(const UnlocalizedString &unlocalizedName);
|
||||
}
|
||||
|
||||
/* Tools Registry. Allows adding new entries to the tools window */
|
||||
@@ -487,7 +498,7 @@ namespace hex {
|
||||
bool detached;
|
||||
};
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<Entry> &getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -496,7 +507,7 @@ namespace hex {
|
||||
* @param unlocalizedName The unlocalized name of the tool
|
||||
* @param function The function that will be called to draw the tool
|
||||
*/
|
||||
void add(const std::string &unlocalizedName, const impl::Callback &function);
|
||||
void add(const UnlocalizedString &unlocalizedName, const impl::Callback &function);
|
||||
}
|
||||
|
||||
/* Data Inspector Registry. Allows adding of new types to the data inspector */
|
||||
@@ -516,14 +527,14 @@ namespace hex {
|
||||
using GeneratorFunction = std::function<DisplayFunction(const std::vector<u8> &, std::endian, NumberDisplayStyle)>;
|
||||
|
||||
struct Entry {
|
||||
std::string unlocalizedName;
|
||||
UnlocalizedString unlocalizedName;
|
||||
size_t requiredSize;
|
||||
size_t maxSize;
|
||||
impl::GeneratorFunction generatorFunction;
|
||||
std::optional<impl::EditingFunction> editingFunction;
|
||||
GeneratorFunction generatorFunction;
|
||||
std::optional<EditingFunction> editingFunction;
|
||||
};
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<Entry> &getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -534,7 +545,7 @@ namespace hex {
|
||||
* @param displayGeneratorFunction The function that will be called to generate the display function
|
||||
* @param editingFunction The function that will be called to edit the data
|
||||
*/
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
void add(const UnlocalizedString &unlocalizedName, size_t requiredSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
|
||||
/**
|
||||
* @brief Adds a new entry to the data inspector
|
||||
@@ -544,7 +555,7 @@ namespace hex {
|
||||
* @param displayGeneratorFunction The function that will be called to generate the display function
|
||||
* @param editingFunction The function that will be called to edit the data
|
||||
*/
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, size_t maxSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
void add(const UnlocalizedString &unlocalizedName, size_t requiredSize, size_t maxSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
}
|
||||
|
||||
/* Data Processor Node Registry. Allows adding new processor nodes to be used in the data processor */
|
||||
@@ -555,14 +566,14 @@ namespace hex {
|
||||
using CreatorFunction = std::function<std::unique_ptr<dp::Node>()>;
|
||||
|
||||
struct Entry {
|
||||
std::string category;
|
||||
std::string name;
|
||||
UnlocalizedString unlocalizedCategory;
|
||||
UnlocalizedString unlocalizedName;
|
||||
CreatorFunction creatorFunction;
|
||||
};
|
||||
|
||||
void add(const Entry &entry);
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<Entry> &getEntries();
|
||||
}
|
||||
|
||||
|
||||
@@ -575,10 +586,10 @@ namespace hex {
|
||||
* @param args Arguments passed to the constructor of the node
|
||||
*/
|
||||
template<std::derived_from<dp::Node> T, typename... Args>
|
||||
void add(const std::string &unlocalizedCategory, const std::string &unlocalizedName, Args &&...args) {
|
||||
void add(const UnlocalizedString &unlocalizedCategory, const UnlocalizedString &unlocalizedName, Args &&...args) {
|
||||
add(impl::Entry {
|
||||
unlocalizedCategory.c_str(),
|
||||
unlocalizedName.c_str(),
|
||||
unlocalizedCategory,
|
||||
unlocalizedName,
|
||||
[=, ...args = std::forward<Args>(args)] mutable {
|
||||
auto node = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
node->setUnlocalizedName(unlocalizedName);
|
||||
@@ -594,7 +605,7 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
/* Language Registry. Allows together with the LangEntry class and the _lang user defined literal to add new languages */
|
||||
/* Language Registry. Allows together with the Lang class and the _lang user defined literal to add new languages */
|
||||
namespace Language {
|
||||
|
||||
/**
|
||||
@@ -606,7 +617,7 @@ namespace hex {
|
||||
namespace impl {
|
||||
|
||||
std::map<std::string, std::string> &getLanguages();
|
||||
std::map<std::string, std::vector<LanguageDefinition>> &getLanguageDefinitions();
|
||||
std::map<std::string, std::vector<LocalizationManager::LanguageDefinition>> &getLanguageDefinitions();
|
||||
|
||||
}
|
||||
|
||||
@@ -623,12 +634,13 @@ namespace hex {
|
||||
using ClickCallback = std::function<void()>;
|
||||
|
||||
struct MainMenuItem {
|
||||
std::string unlocalizedName;
|
||||
UnlocalizedString unlocalizedName;
|
||||
};
|
||||
|
||||
struct MenuItem {
|
||||
std::vector<std::string> unlocalizedNames;
|
||||
Shortcut shortcut;
|
||||
std::vector<UnlocalizedString> unlocalizedNames;
|
||||
std::unique_ptr<Shortcut> shortcut;
|
||||
View *view;
|
||||
MenuCallback callback;
|
||||
EnabledCallback enabledCallback;
|
||||
};
|
||||
@@ -636,25 +648,26 @@ namespace hex {
|
||||
struct SidebarItem {
|
||||
std::string icon;
|
||||
DrawCallback callback;
|
||||
EnabledCallback enabledCallback;
|
||||
};
|
||||
|
||||
struct TitleBarButton {
|
||||
std::string icon;
|
||||
std::string unlocalizedTooltip;
|
||||
UnlocalizedString unlocalizedTooltip;
|
||||
ClickCallback callback;
|
||||
};
|
||||
|
||||
constexpr static auto SeparatorValue = "$SEPARATOR$";
|
||||
constexpr static auto SubMenuValue = "$SUBMENU$";
|
||||
|
||||
std::multimap<u32, impl::MainMenuItem> &getMainMenuItems();
|
||||
std::multimap<u32, impl::MenuItem> &getMenuItems();
|
||||
std::multimap<u32, MainMenuItem> &getMainMenuItems();
|
||||
std::multimap<u32, MenuItem> &getMenuItems();
|
||||
|
||||
std::vector<impl::DrawCallback> &getWelcomeScreenEntries();
|
||||
std::vector<impl::DrawCallback> &getFooterItems();
|
||||
std::vector<impl::DrawCallback> &getToolbarItems();
|
||||
std::vector<impl::SidebarItem> &getSidebarItems();
|
||||
std::vector<impl::TitleBarButton> &getTitleBarButtons();
|
||||
std::vector<DrawCallback> &getWelcomeScreenEntries();
|
||||
std::vector<DrawCallback> &getFooterItems();
|
||||
std::vector<DrawCallback> &getToolbarItems();
|
||||
std::vector<SidebarItem> &getSidebarItems();
|
||||
std::vector<TitleBarButton> &getTitleBarButtons();
|
||||
|
||||
}
|
||||
|
||||
@@ -663,7 +676,7 @@ namespace hex {
|
||||
* @param unlocalizedName The unlocalized name of the entry
|
||||
* @param priority The priority of the entry. Lower values are displayed first
|
||||
*/
|
||||
void registerMainMenuItem(const std::string &unlocalizedName, u32 priority);
|
||||
void registerMainMenuItem(const UnlocalizedString &unlocalizedName, u32 priority);
|
||||
|
||||
/**
|
||||
* @brief Adds a new main menu entry
|
||||
@@ -674,7 +687,7 @@ namespace hex {
|
||||
* @param enabledCallback The function to call to determine if the entry is enabled
|
||||
* @param view The view to use for the entry. If nullptr, the shortcut will work globally
|
||||
*/
|
||||
void addMenuItem(const std::vector<std::string> &unlocalizedMainMenuNames, u32 priority, const Shortcut &shortcut, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback = []{ return true; }, View *view = nullptr);
|
||||
void addMenuItem(const std::vector<UnlocalizedString> &unlocalizedMainMenuNames, u32 priority, const Shortcut &shortcut, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback = []{ return true; }, View *view = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Adds a new main menu sub-menu entry
|
||||
@@ -682,16 +695,15 @@ namespace hex {
|
||||
* @param priority The priority of the entry. Lower values are displayed first
|
||||
* @param function The function to call when the entry is clicked
|
||||
* @param enabledCallback The function to call to determine if the entry is enabled
|
||||
* @param view The view to use for the entry. If nullptr, the shortcut will work globally
|
||||
*/
|
||||
void addMenuItemSubMenu(std::vector<std::string> unlocalizedMainMenuNames, u32 priority, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback = []{ return true; });
|
||||
void addMenuItemSubMenu(std::vector<UnlocalizedString> unlocalizedMainMenuNames, u32 priority, const impl::MenuCallback &function, const impl::EnabledCallback& enabledCallback = []{ return true; });
|
||||
|
||||
/**
|
||||
* @brief Adds a new main menu separator
|
||||
* @param unlocalizedMainMenuNames The unlocalized names of the main menu entries
|
||||
* @param priority The priority of the entry. Lower values are displayed first
|
||||
*/
|
||||
void addMenuItemSeparator(std::vector<std::string> unlocalizedMainMenuNames, u32 priority);
|
||||
void addMenuItemSeparator(std::vector<UnlocalizedString> unlocalizedMainMenuNames, u32 priority);
|
||||
|
||||
|
||||
/**
|
||||
@@ -716,8 +728,9 @@ namespace hex {
|
||||
* @brief Adds a new sidebar item
|
||||
* @param icon The icon to use for the item
|
||||
* @param function The function to call to draw the item
|
||||
* @param enabledCallback The function
|
||||
*/
|
||||
void addSidebarItem(const std::string &icon, const impl::DrawCallback &function);
|
||||
void addSidebarItem(const std::string &icon, const impl::DrawCallback &function, const impl::EnabledCallback &enabledCallback = []{ return true; });
|
||||
|
||||
/**
|
||||
* @brief Adds a new title bar button
|
||||
@@ -725,7 +738,7 @@ namespace hex {
|
||||
* @param unlocalizedTooltip The unlocalized tooltip to use for the button
|
||||
* @param function The function to call when the button is clicked
|
||||
*/
|
||||
void addTitleBarButton(const std::string &icon, const std::string &unlocalizedTooltip, const impl::ClickCallback &function);
|
||||
void addTitleBarButton(const std::string &icon, const UnlocalizedString &unlocalizedTooltip, const impl::ClickCallback &function);
|
||||
|
||||
}
|
||||
|
||||
@@ -734,7 +747,10 @@ namespace hex {
|
||||
|
||||
namespace impl {
|
||||
|
||||
void addProviderName(const std::string &unlocalizedName);
|
||||
void addProviderName(const UnlocalizedString &unlocalizedName);
|
||||
|
||||
using ProviderCreationFunction = prv::Provider*(*)();
|
||||
void add(const std::string &typeName, ProviderCreationFunction creationFunction);
|
||||
|
||||
std::vector<std::string> &getEntries();
|
||||
|
||||
@@ -745,19 +761,12 @@ namespace hex {
|
||||
* @tparam T The provider type that extends hex::prv::Provider
|
||||
* @param addToList Whether to display the provider in the Other Providers list in the welcome screen and File menu
|
||||
*/
|
||||
template<std::derived_from<hex::prv::Provider> T>
|
||||
template<std::derived_from<prv::Provider> T>
|
||||
void add(bool addToList = true) {
|
||||
auto typeName = T().getTypeName();
|
||||
|
||||
(void)EventManager::subscribe<RequestCreateProvider>([expectedName = typeName](const std::string &name, bool skipLoadInterface, bool selectProvider, hex::prv::Provider **provider) {
|
||||
if (name != expectedName) return;
|
||||
|
||||
prv::Provider *newProvider = new T();
|
||||
|
||||
hex::ImHexApi::Provider::add(newProvider, skipLoadInterface, selectProvider);
|
||||
|
||||
if (provider != nullptr)
|
||||
*provider = newProvider;
|
||||
impl::add(typeName, [] -> prv::Provider* {
|
||||
return new T();
|
||||
});
|
||||
|
||||
if (addToList)
|
||||
@@ -773,11 +782,11 @@ namespace hex {
|
||||
|
||||
using Callback = std::function<std::string(prv::Provider *provider, u64 address, size_t size)>;
|
||||
struct Entry {
|
||||
std::string unlocalizedName;
|
||||
UnlocalizedString unlocalizedName;
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<Entry> &getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -787,7 +796,7 @@ namespace hex {
|
||||
* @param unlocalizedName The unlocalized name of the formatter
|
||||
* @param callback The function to call to format the data
|
||||
*/
|
||||
void add(const std::string &unlocalizedName, const impl::Callback &callback);
|
||||
void add(const UnlocalizedString &unlocalizedName, const impl::Callback &callback);
|
||||
|
||||
}
|
||||
|
||||
@@ -802,7 +811,7 @@ namespace hex {
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
std::vector<Entry> &getEntries();
|
||||
|
||||
}
|
||||
|
||||
@@ -820,7 +829,7 @@ namespace hex {
|
||||
|
||||
class DataVisualizer {
|
||||
public:
|
||||
DataVisualizer(std::string unlocalizedName, u16 bytesPerCell, u16 maxCharsPerCell)
|
||||
DataVisualizer(UnlocalizedString unlocalizedName, u16 bytesPerCell, u16 maxCharsPerCell)
|
||||
: m_unlocalizedName(std::move(unlocalizedName)),
|
||||
m_bytesPerCell(bytesPerCell),
|
||||
m_maxCharsPerCell(maxCharsPerCell) { }
|
||||
@@ -830,10 +839,10 @@ namespace hex {
|
||||
virtual void draw(u64 address, const u8 *data, size_t size, bool upperCase) = 0;
|
||||
virtual bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) = 0;
|
||||
|
||||
[[nodiscard]] u16 getBytesPerCell() const { return this->m_bytesPerCell; }
|
||||
[[nodiscard]] u16 getMaxCharsPerCell() const { return this->m_maxCharsPerCell; }
|
||||
[[nodiscard]] u16 getBytesPerCell() const { return m_bytesPerCell; }
|
||||
[[nodiscard]] u16 getMaxCharsPerCell() const { return m_maxCharsPerCell; }
|
||||
|
||||
[[nodiscard]] const std::string& getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
[[nodiscard]] const UnlocalizedString& getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
|
||||
protected:
|
||||
const static int TextInputFlags;
|
||||
@@ -842,7 +851,7 @@ namespace hex {
|
||||
bool drawDefaultTextEditingTextBox(u64 address, std::string &data, ImGuiInputTextFlags flags) const;
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
u16 m_bytesPerCell;
|
||||
u16 m_maxCharsPerCell;
|
||||
};
|
||||
@@ -858,7 +867,6 @@ namespace hex {
|
||||
/**
|
||||
* @brief Adds a new cell data visualizer
|
||||
* @tparam T The data visualizer type that extends hex::DataVisualizer
|
||||
* @param unlocalizedName The unlocalized name of the data visualizer
|
||||
* @param args The arguments to pass to the constructor of the data visualizer
|
||||
*/
|
||||
template<std::derived_from<DataVisualizer> T, typename... Args>
|
||||
@@ -871,7 +879,7 @@ namespace hex {
|
||||
* @param unlocalizedName Unlocalized name of the data visualizer
|
||||
* @return The data visualizer, or nullptr if it doesn't exist
|
||||
*/
|
||||
std::shared_ptr<DataVisualizer> getVisualizerByName(const std::string &unlocalizedName);
|
||||
std::shared_ptr<DataVisualizer> getVisualizerByName(const UnlocalizedString &unlocalizedName);
|
||||
|
||||
}
|
||||
|
||||
@@ -880,7 +888,7 @@ namespace hex {
|
||||
|
||||
class Hash {
|
||||
public:
|
||||
explicit Hash(std::string unlocalizedName) : m_unlocalizedName(std::move(unlocalizedName)) {}
|
||||
explicit Hash(UnlocalizedString unlocalizedName) : m_unlocalizedName(std::move(unlocalizedName)) {}
|
||||
virtual ~Hash() = default;
|
||||
|
||||
class Function {
|
||||
@@ -892,20 +900,20 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
[[nodiscard]] Hash *getType() { return this->m_type; }
|
||||
[[nodiscard]] const Hash *getType() const { return this->m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return this->m_name; }
|
||||
[[nodiscard]] Hash *getType() { return m_type; }
|
||||
[[nodiscard]] const Hash *getType() const { return m_type; }
|
||||
[[nodiscard]] const std::string &getName() const { return m_name; }
|
||||
|
||||
const std::vector<u8>& get(const Region& region, prv::Provider *provider) {
|
||||
if (this->m_cache.empty()) {
|
||||
this->m_cache = this->m_callback(region, provider);
|
||||
if (m_cache.empty()) {
|
||||
m_cache = m_callback(region, provider);
|
||||
}
|
||||
|
||||
return this->m_cache;
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->m_cache.clear();
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -922,8 +930,8 @@ namespace hex {
|
||||
[[nodiscard]] virtual nlohmann::json store() const = 0;
|
||||
virtual void load(const nlohmann::json &json) = 0;
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const {
|
||||
return this->m_unlocalizedName;
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const {
|
||||
return m_unlocalizedName;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -932,7 +940,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
@@ -955,23 +963,19 @@ namespace hex {
|
||||
|
||||
}
|
||||
|
||||
/* Background Service Registry. Allows adding new background services */
|
||||
namespace BackgroundServices {
|
||||
|
||||
namespace impl {
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
struct Service {
|
||||
std::string name;
|
||||
std::jthread thread;
|
||||
};
|
||||
|
||||
std::vector<Service> &getServices();
|
||||
void stopServices();
|
||||
}
|
||||
|
||||
void registerService(const std::string &unlocalizedName, const impl::Callback &callback);
|
||||
void registerService(const UnlocalizedString &unlocalizedName, const impl::Callback &callback);
|
||||
}
|
||||
|
||||
/* Network Communication Interface Registry. Allows adding new communication interface endpoints */
|
||||
namespace CommunicationInterface {
|
||||
|
||||
namespace impl {
|
||||
@@ -983,6 +987,43 @@ namespace hex {
|
||||
void registerNetworkEndpoint(const std::string &endpoint, const impl::NetworkCallback &callback);
|
||||
|
||||
}
|
||||
|
||||
/* Experiments Registry. Allows adding new experiments */
|
||||
namespace Experiments {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct Experiment {
|
||||
UnlocalizedString unlocalizedName, unlocalizedDescription;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
std::map<std::string, Experiment> &getExperiments();
|
||||
}
|
||||
|
||||
void addExperiment(const std::string &experimentName, const UnlocalizedString &unlocalizedName, const UnlocalizedString &unlocalizedDescription = "");
|
||||
void enableExperiement(const std::string &experimentName, bool enabled);
|
||||
|
||||
[[nodiscard]] bool isExperimentEnabled(const std::string &experimentName);
|
||||
}
|
||||
|
||||
namespace Reports {
|
||||
|
||||
namespace impl {
|
||||
|
||||
using Callback = std::function<std::string(prv::Provider*)>;
|
||||
|
||||
struct ReportGenerator {
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
std::vector<ReportGenerator>& getGenerators();
|
||||
|
||||
}
|
||||
|
||||
void addReportProvider(impl::Callback callback);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,12 +13,18 @@
|
||||
|
||||
#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_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)) { } \
|
||||
\
|
||||
static EventManager::EventList::iterator subscribe(Event::Callback function) { return EventManager::subscribe<event_name>(function); } \
|
||||
static void subscribe(void *token, Event::Callback function) { EventManager::subscribe<event_name>(token, function); } \
|
||||
static void unsubscribe(const EventManager::EventList::iterator &token) noexcept { EventManager::unsubscribe(token); } \
|
||||
static void unsubscribe(void *token) noexcept { EventManager::unsubscribe<event_name>(token); } \
|
||||
static void post(auto &&...args) noexcept { EventManager::post<event_name>(std::forward<decltype(args)>(args)...); } \
|
||||
};
|
||||
|
||||
#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__)
|
||||
@@ -26,7 +32,10 @@
|
||||
|
||||
/* Forward declarations */
|
||||
struct GLFWwindow;
|
||||
namespace hex { class Achievement; }
|
||||
namespace hex {
|
||||
class Achievement;
|
||||
class View;
|
||||
}
|
||||
|
||||
|
||||
namespace hex {
|
||||
@@ -36,15 +45,15 @@ namespace hex {
|
||||
class EventId {
|
||||
public:
|
||||
explicit constexpr EventId(const char *eventName) {
|
||||
this->m_hash = 0x811C'9DC5;
|
||||
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;
|
||||
m_hash = (m_hash >> 5) | (m_hash << 27);
|
||||
m_hash ^= c;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool operator==(const EventId &other) const {
|
||||
return this->m_hash == other.m_hash;
|
||||
return m_hash == other.m_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -56,13 +65,13 @@ namespace hex {
|
||||
};
|
||||
|
||||
template<typename... Params>
|
||||
struct Event : public EventBase {
|
||||
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...);
|
||||
m_func(params...);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -91,6 +100,8 @@ namespace hex {
|
||||
*/
|
||||
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)));
|
||||
}
|
||||
@@ -103,6 +114,8 @@ namespace hex {
|
||||
*/
|
||||
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) {
|
||||
@@ -114,7 +127,7 @@ namespace hex {
|
||||
}
|
||||
}
|
||||
|
||||
getTokenStore().insert(std::make_pair(token, subscribe<E>(function)));
|
||||
getTokenStore().insert({ token, subscribe<E>(function) });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,6 +135,8 @@ namespace hex {
|
||||
* @param token Token returned by subscribe
|
||||
*/
|
||||
static void unsubscribe(const EventList::iterator &token) noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
getEvents().erase(token);
|
||||
}
|
||||
|
||||
@@ -132,6 +147,8 @@ namespace hex {
|
||||
*/
|
||||
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;
|
||||
@@ -151,9 +168,15 @@ namespace hex {
|
||||
*/
|
||||
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) {
|
||||
(*static_cast<E *const>(event.get()))(std::forward<decltype(args)>(args)...);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +190,8 @@ namespace hex {
|
||||
* @brief Unsubscribe all subscribers from all events
|
||||
*/
|
||||
static void clear() noexcept {
|
||||
std::scoped_lock lock(getEventMutex());
|
||||
|
||||
getEvents().clear();
|
||||
getTokenStore().clear();
|
||||
}
|
||||
@@ -174,6 +199,7 @@ namespace hex {
|
||||
private:
|
||||
static std::multimap<void *, EventList::iterator>& getTokenStore();
|
||||
static EventList& getEvents();
|
||||
static std::recursive_mutex& getEventMutex();
|
||||
};
|
||||
|
||||
/* Default Events */
|
||||
@@ -224,6 +250,12 @@ namespace hex {
|
||||
EVENT_DEF(EventStoreContentRemoved, const std::fs::path&);
|
||||
EVENT_DEF(EventImHexClosing);
|
||||
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
||||
EVENT_DEF(EventSearchBoxClicked, u32);
|
||||
EVENT_DEF(EventViewOpened, View*);
|
||||
|
||||
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
|
||||
@@ -234,10 +266,14 @@ namespace hex {
|
||||
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);
|
||||
EVENT_DEF(RequestAddBookmark, Region, std::string, std::string, color_t, u64*);
|
||||
EVENT_DEF(RequestRemoveBookmark, u64);
|
||||
EVENT_DEF(RequestSetPatternLanguageCode, std::string);
|
||||
EVENT_DEF(RequestRunPatternCode);
|
||||
EVENT_DEF(RequestLoadPatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestSavePatternLanguageFile, std::fs::path);
|
||||
EVENT_DEF(RequestUpdateWindowTitle);
|
||||
@@ -253,11 +289,6 @@ namespace hex {
|
||||
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
|
||||
*/
|
||||
@@ -1,21 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <map>
|
||||
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/api/keybinding.hpp>
|
||||
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
using ImGuiID = unsigned int;
|
||||
struct ImVec2;
|
||||
struct ImFontAtlas;
|
||||
struct ImFont;
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -35,8 +34,8 @@ namespace hex {
|
||||
Highlighting() = default;
|
||||
Highlighting(Region region, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return this->m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return this->m_color; }
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
@@ -48,9 +47,9 @@ namespace hex {
|
||||
Tooltip() = default;
|
||||
Tooltip(Region region, std::string value, color_t color);
|
||||
|
||||
[[nodiscard]] const Region &getRegion() const { return this->m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return this->m_color; }
|
||||
[[nodiscard]] const std::string &getValue() const { return this->m_value; }
|
||||
[[nodiscard]] const Region &getRegion() const { return m_region; }
|
||||
[[nodiscard]] const color_t &getColor() const { return m_color; }
|
||||
[[nodiscard]] const std::string &getValue() const { return m_value; }
|
||||
|
||||
private:
|
||||
Region m_region = {};
|
||||
@@ -58,7 +57,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; }
|
||||
@@ -77,7 +76,7 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,6 +214,7 @@ namespace hex {
|
||||
std::string comment;
|
||||
u32 color;
|
||||
bool locked;
|
||||
u64 id;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -224,8 +224,25 @@ namespace hex {
|
||||
* @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
|
||||
*/
|
||||
void add(u64 address, size_t size, const std::string &name, const std::string &comment, color_t color = 0x00000000);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@@ -239,7 +256,7 @@ namespace hex {
|
||||
namespace impl {
|
||||
|
||||
void resetClosingProvider();
|
||||
prv::Provider* getClosingProvider();
|
||||
const std::vector<prv::Provider*>& getClosingProviders();
|
||||
|
||||
}
|
||||
|
||||
@@ -320,8 +337,9 @@ namespace hex {
|
||||
* @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);
|
||||
prv::Provider* createProvider(const UnlocalizedString &unlocalizedName, bool skipLoadInterface = false, bool select = true);
|
||||
|
||||
}
|
||||
|
||||
@@ -342,14 +360,13 @@ namespace hex {
|
||||
|
||||
void setBorderlessWindowMode(bool enabled);
|
||||
|
||||
void setCustomFontPath(const std::fs::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 = { });
|
||||
|
||||
void setLastFrameTime(double time);
|
||||
}
|
||||
|
||||
struct ProgramArguments {
|
||||
@@ -447,21 +464,6 @@ namespace hex {
|
||||
*/
|
||||
std::map<std::string, std::string> &getInitArguments();
|
||||
|
||||
constexpr static float DefaultFontSize = 13.0;
|
||||
|
||||
/**
|
||||
* @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 Sets if ImHex should follow the system theme
|
||||
* @param enabled Whether to follow the system theme
|
||||
@@ -522,7 +524,7 @@ namespace hex {
|
||||
* @brief Gets the current ImHex version
|
||||
* @return ImHex version
|
||||
*/
|
||||
std::string getImHexVersion();
|
||||
std::string getImHexVersion(bool withBuildType = true);
|
||||
|
||||
/**
|
||||
* @brief Gets the current git commit hash
|
||||
@@ -548,7 +550,16 @@ namespace hex {
|
||||
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);
|
||||
|
||||
double getLastFrameTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -571,6 +582,63 @@ namespace hex {
|
||||
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,13 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -30,11 +25,17 @@ namespace hex {
|
||||
*/
|
||||
static void load(const std::fs::path &path);
|
||||
|
||||
/**
|
||||
* @brief Saves the current layout to a string
|
||||
* @return String containing the layout
|
||||
*/
|
||||
static std::string saveToString();
|
||||
|
||||
/**
|
||||
* @brief Load a layout from a string
|
||||
* @param content Layout string
|
||||
*/
|
||||
static void loadString(const std::string &content);
|
||||
static void loadFromString(const std::string &content);
|
||||
|
||||
/**
|
||||
* @brief Get a list of all layouts
|
||||
@@ -58,6 +59,23 @@ namespace hex {
|
||||
*/
|
||||
static void reset();
|
||||
|
||||
/**
|
||||
* @brief Checks is the current layout is locked
|
||||
*/
|
||||
static bool isLayoutLocked();
|
||||
|
||||
/**
|
||||
* @brief Locks or unlocks the current layout
|
||||
* @note If the layout is locked, it cannot be modified by the user anymore
|
||||
* @param locked True to lock the layout, false to unlock it
|
||||
*/
|
||||
static void lockLayout(bool locked);
|
||||
|
||||
/**
|
||||
* @brief Closes all views
|
||||
*/
|
||||
static void closeAllViews();
|
||||
|
||||
private:
|
||||
LayoutManager() = default;
|
||||
};
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
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();
|
||||
|
||||
static const std::string &getSelectedLanguage();
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedString;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
struct fmt::formatter<hex::LangEntry> : fmt::formatter<std::string_view> {
|
||||
template<typename FormatContext>
|
||||
auto format(const hex::LangEntry &entry, FormatContext &ctx) {
|
||||
return fmt::formatter<std::string_view>::format(entry.get(), ctx);
|
||||
}
|
||||
};
|
||||
111
lib/libimhex/include/hex/api/localization_manager.hpp
Normal file
111
lib/libimhex/include/hex/api/localization_manager.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#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();
|
||||
}
|
||||
|
||||
struct UnlocalizedString;
|
||||
|
||||
class Lang {
|
||||
public:
|
||||
explicit Lang(const char *unlocalizedString);
|
||||
explicit Lang(const std::string &unlocalizedString);
|
||||
explicit Lang(const UnlocalizedString &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);
|
||||
}
|
||||
|
||||
|
||||
struct UnlocalizedString {
|
||||
public:
|
||||
UnlocalizedString() = default;
|
||||
UnlocalizedString(auto && arg) : m_unlocalizedString(std::forward<decltype(arg)>(arg)) {
|
||||
static_assert(!std::same_as<std::remove_cvref_t<decltype(arg)>, Lang>, "Expected a unlocalized name, got a localized one!");
|
||||
}
|
||||
|
||||
[[nodiscard]] operator std::string() const {
|
||||
return m_unlocalizedString;
|
||||
}
|
||||
|
||||
[[nodiscard]] operator std::string_view() const {
|
||||
return m_unlocalizedString;
|
||||
}
|
||||
|
||||
[[nodiscard]] operator const char *() const {
|
||||
return m_unlocalizedString.c_str();
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::string &get() const {
|
||||
return m_unlocalizedString;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const {
|
||||
return m_unlocalizedString.empty();
|
||||
}
|
||||
|
||||
auto operator<=>(const UnlocalizedString &) const = default;
|
||||
auto operator<=>(const std::string &other) const {
|
||||
return m_unlocalizedString <=> other;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_unlocalizedString;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
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,18 +1,11 @@
|
||||
#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>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
struct ImGuiContext;
|
||||
|
||||
@@ -24,8 +17,14 @@ namespace hex {
|
||||
std::function<void(const std::vector<std::string>&)> callback;
|
||||
};
|
||||
|
||||
struct Feature {
|
||||
std::string name;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct PluginFunctions {
|
||||
using InitializePluginFunc = void (*)();
|
||||
using InitializeLibraryFunc = void (*)();
|
||||
using GetPluginNameFunc = const char *(*)();
|
||||
using GetPluginAuthorFunc = const char *(*)();
|
||||
using GetPluginDescriptionFunc = const char *(*)();
|
||||
@@ -33,8 +32,10 @@ namespace hex {
|
||||
using SetImGuiContextFunc = void (*)(ImGuiContext *);
|
||||
using IsBuiltinPluginFunc = bool (*)();
|
||||
using GetSubCommandsFunc = void* (*)();
|
||||
using GetFeaturesFunc = void* (*)();
|
||||
|
||||
InitializePluginFunc initializePluginFunction = nullptr;
|
||||
InitializeLibraryFunc initializeLibraryFunction = nullptr;
|
||||
GetPluginNameFunc getPluginNameFunction = nullptr;
|
||||
GetPluginAuthorFunc getPluginAuthorFunction = nullptr;
|
||||
GetPluginDescriptionFunc getPluginDescriptionFunction = nullptr;
|
||||
@@ -42,17 +43,21 @@ namespace hex {
|
||||
SetImGuiContextFunc setImGuiContextFunction = nullptr;
|
||||
IsBuiltinPluginFunc isBuiltinPluginFunction = nullptr;
|
||||
GetSubCommandsFunc getSubCommandsFunction = nullptr;
|
||||
GetFeaturesFunc getFeaturesFunction = nullptr;
|
||||
};
|
||||
|
||||
class Plugin {
|
||||
public:
|
||||
explicit Plugin(const std::fs::path &path);
|
||||
explicit Plugin(PluginFunctions functions);
|
||||
explicit Plugin(const PluginFunctions &functions);
|
||||
|
||||
Plugin(const Plugin &) = delete;
|
||||
Plugin(Plugin &&other) noexcept;
|
||||
~Plugin();
|
||||
|
||||
Plugin& operator=(const Plugin &) = delete;
|
||||
Plugin& operator=(Plugin &&other) noexcept;
|
||||
|
||||
[[nodiscard]] bool initializePlugin() const;
|
||||
[[nodiscard]] std::string getPluginName() const;
|
||||
[[nodiscard]] std::string getPluginAuthor() const;
|
||||
@@ -63,16 +68,16 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] const std::fs::path &getPath() const;
|
||||
|
||||
[[nodiscard]] bool isValid() const;
|
||||
[[nodiscard]] bool isLoaded() const;
|
||||
|
||||
[[nodiscard]] std::span<SubCommand> getSubCommands() const;
|
||||
[[nodiscard]] std::span<Feature> getFeatures() const;
|
||||
|
||||
[[nodiscard]] bool isLibraryPlugin() const;
|
||||
|
||||
private:
|
||||
#if defined(OS_WINDOWS)
|
||||
HMODULE m_handle = nullptr;
|
||||
#else
|
||||
void *m_handle = nullptr;
|
||||
#endif
|
||||
uintptr_t m_handle = 0;
|
||||
std::fs::path m_path;
|
||||
|
||||
mutable bool m_initialized = false;
|
||||
@@ -84,8 +89,7 @@ namespace hex {
|
||||
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 {
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
#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>
|
||||
|
||||
/**
|
||||
@@ -21,6 +11,10 @@
|
||||
*/
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
class ProjectFile {
|
||||
public:
|
||||
struct Handler {
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
struct ImGuiWindow;
|
||||
|
||||
namespace hex {
|
||||
@@ -133,13 +135,14 @@ namespace hex {
|
||||
|
||||
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; }
|
||||
[[nodiscard]] constexpr u32 getKeyCode() const { return m_key; }
|
||||
private:
|
||||
u32 m_key;
|
||||
u32 m_key = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -160,8 +163,15 @@ namespace hex {
|
||||
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;
|
||||
|
||||
const static inline auto None = Keys(0);
|
||||
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;
|
||||
@@ -171,21 +181,29 @@ namespace hex {
|
||||
}
|
||||
|
||||
Shortcut &operator+=(const Key &other) {
|
||||
this->m_keys.insert(other);
|
||||
m_keys.insert(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator<(const Shortcut &other) const {
|
||||
return this->m_keys < other.m_keys;
|
||||
return m_keys < other.m_keys;
|
||||
}
|
||||
|
||||
bool operator==(const Shortcut &other) const {
|
||||
return this->m_keys == other.m_keys;
|
||||
auto thisKeys = 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);
|
||||
return m_keys.contains(CurrentView);
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
@@ -205,7 +223,7 @@ namespace hex {
|
||||
|
||||
constexpr static auto Concatination = " + ";
|
||||
|
||||
auto keys = this->m_keys;
|
||||
auto keys = m_keys;
|
||||
if (keys.erase(CTRL) > 0) {
|
||||
result += CTRL_NAME;
|
||||
result += Concatination;
|
||||
@@ -351,6 +369,8 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::set<Key>& getKeys() const { return m_keys; }
|
||||
|
||||
private:
|
||||
friend Shortcut operator+(const Key &lhs, const Key &rhs);
|
||||
|
||||
@@ -370,21 +390,29 @@ namespace hex {
|
||||
*/
|
||||
class ShortcutManager {
|
||||
public:
|
||||
using Callback = std::function<void()>;
|
||||
struct ShortcutEntry {
|
||||
Shortcut shortcut;
|
||||
UnlocalizedString 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::function<void()> &callback);
|
||||
static void addGlobalShortcut(const Shortcut &shortcut, const UnlocalizedString &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::function<void()> &callback);
|
||||
static void addShortcut(View *view, const Shortcut &shortcut, const UnlocalizedString &unlocalizedName, const Callback &callback);
|
||||
|
||||
|
||||
/**
|
||||
@@ -413,6 +441,16 @@ namespace hex {
|
||||
* @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(const View *view);
|
||||
|
||||
[[nodiscard]] static bool updateShortcut(const Shortcut &oldShortcut, const Shortcut &newShortcut, View *view = nullptr);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,19 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#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;
|
||||
@@ -25,7 +21,7 @@ namespace hex {
|
||||
class Task {
|
||||
public:
|
||||
Task() = default;
|
||||
Task(std::string unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
|
||||
Task(UnlocalizedString unlocalizedName, u64 maxValue, bool background, std::function<void(Task &)> function);
|
||||
|
||||
Task(const Task&) = delete;
|
||||
Task(Task &&other) noexcept;
|
||||
@@ -66,7 +62,7 @@ namespace hex {
|
||||
void clearException();
|
||||
[[nodiscard]] std::string getExceptionMessage() const;
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName();
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName();
|
||||
[[nodiscard]] u64 getValue() const;
|
||||
[[nodiscard]] u64 getMaxValue() const;
|
||||
|
||||
@@ -78,7 +74,7 @@ namespace hex {
|
||||
private:
|
||||
mutable std::mutex m_mutex;
|
||||
|
||||
std::string m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
std::atomic<u64> m_currValue = 0, m_maxValue = 0;
|
||||
std::function<void()> m_interruptCallback;
|
||||
std::function<void(Task &)> m_function;
|
||||
@@ -112,16 +108,11 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] u32 getProgress() const;
|
||||
|
||||
void interrupt();
|
||||
void interrupt() const;
|
||||
private:
|
||||
std::weak_ptr<Task> m_task;
|
||||
};
|
||||
|
||||
struct Timer {
|
||||
std::chrono::time_point<std::chrono::steady_clock> elapseTime;
|
||||
std::function<void()> callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Task Manager is responsible for running and managing asynchronous tasks
|
||||
*/
|
||||
@@ -163,24 +154,16 @@ namespace hex {
|
||||
*/
|
||||
static void runWhenTasksFinished(const std::function<void()> &function);
|
||||
|
||||
/**
|
||||
* @brief Creates a callback that will be executed after the given time
|
||||
* @param duration Time to wait
|
||||
* @param function Function to be executed
|
||||
*/
|
||||
static void doAfter(std::chrono::duration<i64> duration, 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 std::list<Timer> &getTimers();
|
||||
static void runDeferredCalls();
|
||||
|
||||
private:
|
||||
static void runner(const std::stop_token &stopToken);
|
||||
static TaskHolder createTask(std::string name, u64 maxValue, bool background, std::function<void(Task &)> function);
|
||||
};
|
||||
|
||||
}
|
||||
175
lib/libimhex/include/hex/api/tutorial_manager.hpp
Normal file
175
lib/libimhex/include/hex/api/tutorial_manager.hpp
Normal file
@@ -0,0 +1,175 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <variant>
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class TutorialManager {
|
||||
public:
|
||||
enum class Position : u8 {
|
||||
None = 0,
|
||||
Top = 1,
|
||||
Bottom = 2,
|
||||
Left = 4,
|
||||
Right = 8
|
||||
};
|
||||
|
||||
struct Tutorial {
|
||||
Tutorial() = delete;
|
||||
Tutorial(const UnlocalizedString &unlocalizedName, const UnlocalizedString &unlocalizedDescription) :
|
||||
m_unlocalizedName(unlocalizedName),
|
||||
m_unlocalizedDescription(unlocalizedDescription) { }
|
||||
|
||||
struct Step {
|
||||
explicit Step(Tutorial *parent) : m_parent(parent) { }
|
||||
|
||||
/**
|
||||
* @brief Adds a highlighting with text to a specific element
|
||||
* @param unlocalizedText Unlocalized text to display next to the highlighting
|
||||
* @param ids ID of the element to highlight
|
||||
* @return Current step
|
||||
*/
|
||||
Step& addHighlight(const UnlocalizedString &unlocalizedText, std::initializer_list<std::variant<Lang, std::string, int>> &&ids);
|
||||
|
||||
/**
|
||||
* @brief Adds a highlighting to a specific element
|
||||
* @param ids ID of the element to highlight
|
||||
* @return Current step
|
||||
*/
|
||||
Step& addHighlight(std::initializer_list<std::variant<Lang, std::string, int>> &&ids);
|
||||
|
||||
/**
|
||||
* @brief Sets the text that will be displayed in the tutorial message box
|
||||
* @param unlocalizedTitle Title of the message box
|
||||
* @param unlocalizedMessage Main message of the message box
|
||||
* @param position Position of the message box
|
||||
* @return Current step
|
||||
*/
|
||||
Step& setMessage(const UnlocalizedString &unlocalizedTitle, const UnlocalizedString &unlocalizedMessage, Position position = Position::None);
|
||||
|
||||
/**
|
||||
* @brief Allows this step to be skipped by clicking on the advance button
|
||||
* @return Current step
|
||||
*/
|
||||
Step& allowSkip();
|
||||
|
||||
Step& onAppear(std::function<void()> callback);
|
||||
Step& onComplete(std::function<void()> callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if this step is the current step
|
||||
* @return True if this step is the current step
|
||||
*/
|
||||
bool isCurrent() const;
|
||||
|
||||
/**
|
||||
* @brief Completes this step if it is the current step
|
||||
*/
|
||||
void complete() const;
|
||||
|
||||
private:
|
||||
struct Highlight {
|
||||
UnlocalizedString unlocalizedText;
|
||||
std::vector<std::variant<Lang, std::string, int>> highlightIds;
|
||||
};
|
||||
|
||||
struct Message {
|
||||
Position position;
|
||||
UnlocalizedString unlocalizedTitle;
|
||||
UnlocalizedString unlocalizedMessage;
|
||||
bool allowSkip;
|
||||
};
|
||||
|
||||
private:
|
||||
void addHighlights() const;
|
||||
void removeHighlights() const;
|
||||
|
||||
void advance(i32 steps = 1) const;
|
||||
|
||||
friend class TutorialManager;
|
||||
|
||||
Tutorial *m_parent;
|
||||
std::vector<Highlight> m_highlights;
|
||||
std::optional<Message> m_message;
|
||||
std::function<void()> m_onAppear, m_onComplete;
|
||||
};
|
||||
|
||||
Step& addStep();
|
||||
|
||||
const UnlocalizedString& getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
const UnlocalizedString& getUnlocalizedDescription() const { return m_unlocalizedDescription; }
|
||||
|
||||
private:
|
||||
friend class TutorialManager;
|
||||
|
||||
void start();
|
||||
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedDescription;
|
||||
std::list<Step> m_steps;
|
||||
decltype(m_steps)::iterator m_currentStep, m_latestStep;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets a list of all tutorials
|
||||
* @return List of all tutorials
|
||||
*/
|
||||
static const std::map<std::string, Tutorial>& getTutorials();
|
||||
|
||||
/**
|
||||
* @brief Gets the currently running tutorial
|
||||
* @return Iterator pointing to the current tutorial
|
||||
*/
|
||||
static std::map<std::string, Tutorial>::iterator getCurrentTutorial();
|
||||
|
||||
/**
|
||||
* @brief Creates a new tutorial that can be started later
|
||||
* @param unlocalizedName Name of the tutorial
|
||||
* @param unlocalizedDescription
|
||||
* @return Reference to created tutorial
|
||||
*/
|
||||
static Tutorial& createTutorial(const UnlocalizedString &unlocalizedName, const UnlocalizedString &unlocalizedDescription);
|
||||
|
||||
/**
|
||||
* @brief Starts the tutorial with the given name
|
||||
* @param unlocalizedName Name of tutorial to start
|
||||
*/
|
||||
static void startTutorial(const UnlocalizedString &unlocalizedName);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Draws the tutorial
|
||||
* @note This function should only be called by the main GUI
|
||||
*/
|
||||
static void drawTutorial();
|
||||
|
||||
/**
|
||||
* @brief Resets the tutorial manager
|
||||
*/
|
||||
static void reset();
|
||||
|
||||
private:
|
||||
TutorialManager() = delete;
|
||||
|
||||
static void drawHighlights();
|
||||
static void drawMessageBox(std::optional<Tutorial::Step::Message> message);
|
||||
};
|
||||
|
||||
inline TutorialManager::Position operator|(TutorialManager::Position a, TutorialManager::Position b) {
|
||||
return static_cast<TutorialManager::Position>(static_cast<u8>(a) | static_cast<u8>(b));
|
||||
}
|
||||
|
||||
inline TutorialManager::Position operator&(TutorialManager::Position a, TutorialManager::Position b) {
|
||||
return static_cast<TutorialManager::Position>(static_cast<u8>(a) & static_cast<u8>(b));
|
||||
}
|
||||
|
||||
}
|
||||
37
lib/libimhex/include/hex/api/workspace_manager.hpp
Normal file
37
lib/libimhex/include/hex/api/workspace_manager.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
class WorkspaceManager {
|
||||
public:
|
||||
struct Workspace {
|
||||
std::string layout;
|
||||
std::fs::path path;
|
||||
};
|
||||
|
||||
static void createWorkspace(const std::string &name, const std::string &layout = "");
|
||||
static void switchWorkspace(const std::string &name);
|
||||
|
||||
static void importFromFile(const std::fs::path &path);
|
||||
static bool exportToFile(std::fs::path path = {}, std::string workspaceName = {});
|
||||
|
||||
static const auto& getWorkspaces() { return s_workspaces; }
|
||||
static const auto& getCurrentWorkspace() { return s_currentWorkspace; }
|
||||
|
||||
static void reset();
|
||||
|
||||
static void process();
|
||||
|
||||
private:
|
||||
WorkspaceManager() = default;
|
||||
|
||||
static std::map<std::string, Workspace> s_workspaces;
|
||||
static decltype(s_workspaces)::iterator s_currentWorkspace, s_previousWorkspace;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,2 +1,4 @@
|
||||
constexpr static const auto ImHexApiURL = "https://api.werwolv.net/imhex";
|
||||
constexpr static const auto GitHubApiURL = "https://api.github.com/repos/WerWolv/ImHex";
|
||||
#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,8 @@
|
||||
#pragma once
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
@@ -24,32 +25,32 @@ namespace hex::dp {
|
||||
Out
|
||||
};
|
||||
|
||||
Attribute(IOType ioType, Type type, std::string unlocalizedName);
|
||||
Attribute(IOType ioType, Type type, UnlocalizedString unlocalizedName);
|
||||
~Attribute();
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] IOType getIOType() const { return this->m_ioType; }
|
||||
[[nodiscard]] Type getType() const { return this->m_type; }
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
[[nodiscard]] IOType getIOType() const { return m_ioType; }
|
||||
[[nodiscard]] Type getType() const { return m_type; }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
|
||||
void addConnectedAttribute(int linkId, Attribute *to) { this->m_connectedAttributes.insert({ linkId, to }); }
|
||||
void removeConnectedAttribute(int linkId) { this->m_connectedAttributes.erase(linkId); }
|
||||
[[nodiscard]] std::map<int, Attribute *> &getConnectedAttributes() { return this->m_connectedAttributes; }
|
||||
void addConnectedAttribute(int linkId, Attribute *to) { m_connectedAttributes.insert({ linkId, to }); }
|
||||
void removeConnectedAttribute(int linkId) { m_connectedAttributes.erase(linkId); }
|
||||
[[nodiscard]] std::map<int, Attribute *> &getConnectedAttributes() { return m_connectedAttributes; }
|
||||
|
||||
[[nodiscard]] Node *getParentNode() const { return this->m_parentNode; }
|
||||
[[nodiscard]] Node *getParentNode() const { return m_parentNode; }
|
||||
|
||||
[[nodiscard]] std::vector<u8>& getOutputData() {
|
||||
if (!this->m_outputData.empty())
|
||||
return this->m_outputData;
|
||||
if (!m_outputData.empty())
|
||||
return m_outputData;
|
||||
else
|
||||
return this->m_defaultData;
|
||||
return m_defaultData;
|
||||
}
|
||||
|
||||
void clearOutputData() { this->m_outputData.clear(); }
|
||||
void clearOutputData() { m_outputData.clear(); }
|
||||
|
||||
[[nodiscard]] std::vector<u8>& getDefaultData() { return this->m_defaultData; }
|
||||
[[nodiscard]] std::vector<u8>& getDefaultData() { return m_defaultData; }
|
||||
|
||||
static void setIdCounter(int id);
|
||||
|
||||
@@ -57,7 +58,7 @@ namespace hex::dp {
|
||||
int m_id;
|
||||
IOType m_ioType;
|
||||
Type m_type;
|
||||
std::string m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedName;
|
||||
std::map<int, Attribute *> m_connectedAttributes;
|
||||
Node *m_parentNode = nullptr;
|
||||
|
||||
@@ -65,7 +66,9 @@ namespace hex::dp {
|
||||
std::vector<u8> m_defaultData;
|
||||
|
||||
friend class Node;
|
||||
void setParentNode(Node *node) { this->m_parentNode = node; }
|
||||
void setParentNode(Node *node) { m_parentNode = node; }
|
||||
|
||||
static int s_idCounter;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
namespace hex::dp {
|
||||
|
||||
class Link {
|
||||
public:
|
||||
Link(int from, int to);
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] int getFromId() const { return this->m_from; }
|
||||
[[nodiscard]] int getToId() const { return this->m_to; }
|
||||
[[nodiscard]] int getFromId() const { return m_from; }
|
||||
[[nodiscard]] int getToId() const { return m_to; }
|
||||
|
||||
static void setIdCounter(int id);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
int m_from, m_to;
|
||||
|
||||
static int s_idCounter;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
#include <hex/data_processor/attribute.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
@@ -21,24 +22,24 @@ namespace hex::dp {
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node(std::string unlocalizedTitle, std::vector<Attribute> attributes);
|
||||
Node(UnlocalizedString unlocalizedTitle, std::vector<Attribute> attributes);
|
||||
|
||||
virtual ~Node() = default;
|
||||
|
||||
[[nodiscard]] int getId() const { return this->m_id; }
|
||||
void setId(int id) { this->m_id = id; }
|
||||
[[nodiscard]] int getId() const { return m_id; }
|
||||
void setId(int id) { m_id = id; }
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedName() const { return this->m_unlocalizedName; }
|
||||
void setUnlocalizedName(const std::string &unlocalizedName) { this->m_unlocalizedName = unlocalizedName; }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedName() const { return m_unlocalizedName; }
|
||||
void setUnlocalizedName(const UnlocalizedString &unlocalizedName) { m_unlocalizedName = unlocalizedName; }
|
||||
|
||||
[[nodiscard]] const std::string &getUnlocalizedTitle() const { return this->m_unlocalizedTitle; }
|
||||
void setUnlocalizedTitle(std::string title) { this->m_unlocalizedTitle = std::move(title); }
|
||||
[[nodiscard]] const UnlocalizedString &getUnlocalizedTitle() const { return m_unlocalizedTitle; }
|
||||
void setUnlocalizedTitle(std::string title) { m_unlocalizedTitle = std::move(title); }
|
||||
|
||||
[[nodiscard]] std::vector<Attribute> &getAttributes() { return this->m_attributes; }
|
||||
[[nodiscard]] const std::vector<Attribute> &getAttributes() const { return this->m_attributes; }
|
||||
[[nodiscard]] std::vector<Attribute> &getAttributes() { return m_attributes; }
|
||||
[[nodiscard]] const std::vector<Attribute> &getAttributes() const { return m_attributes; }
|
||||
|
||||
void setCurrentOverlay(prv::Overlay *overlay) {
|
||||
this->m_overlay = overlay;
|
||||
m_overlay = overlay;
|
||||
}
|
||||
|
||||
virtual void drawNode() { }
|
||||
@@ -53,20 +54,20 @@ namespace hex::dp {
|
||||
};
|
||||
|
||||
void resetOutputData() {
|
||||
for (auto &attribute : this->m_attributes)
|
||||
for (auto &attribute : m_attributes)
|
||||
attribute.clearOutputData();
|
||||
}
|
||||
|
||||
void resetProcessedInputs() {
|
||||
this->m_processedInputs.clear();
|
||||
m_processedInputs.clear();
|
||||
}
|
||||
|
||||
void setPosition(ImVec2 pos) {
|
||||
this->m_position = pos;
|
||||
m_position = pos;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getPosition() const {
|
||||
return this->m_position;
|
||||
return m_position;
|
||||
}
|
||||
|
||||
static void setIdCounter(int id);
|
||||
@@ -81,12 +82,14 @@ namespace hex::dp {
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
std::string m_unlocalizedTitle, m_unlocalizedName;
|
||||
UnlocalizedString m_unlocalizedTitle, m_unlocalizedName;
|
||||
std::vector<Attribute> m_attributes;
|
||||
std::set<u32> m_processedInputs;
|
||||
prv::Overlay *m_overlay = nullptr;
|
||||
ImVec2 m_position;
|
||||
|
||||
static int s_idCounter;
|
||||
|
||||
Attribute& getAttribute(u32 index) {
|
||||
if (index >= this->getAttributes().size())
|
||||
throw std::runtime_error("Attribute index out of bounds!");
|
||||
@@ -104,13 +107,13 @@ namespace hex::dp {
|
||||
}
|
||||
|
||||
void markInputProcessed(u32 index) {
|
||||
const auto &[iter, inserted] = this->m_processedInputs.insert(index);
|
||||
const auto &[iter, inserted] = m_processedInputs.insert(index);
|
||||
if (!inserted)
|
||||
throwNodeError("Recursion detected!");
|
||||
}
|
||||
|
||||
void unmarkInputProcessed(u32 index) {
|
||||
this->m_processedInputs.erase(index);
|
||||
m_processedInputs.erase(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -121,9 +124,9 @@ namespace hex::dp {
|
||||
void setOverlayData(u64 address, const std::vector<u8> &data);
|
||||
|
||||
void setAttributes(std::vector<Attribute> attributes) {
|
||||
this->m_attributes = std::move(attributes);
|
||||
m_attributes = std::move(attributes);
|
||||
|
||||
for (auto &attr : this->m_attributes)
|
||||
for (auto &attr : m_attributes)
|
||||
attr.setParentNode(this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,13 +17,13 @@ namespace hex {
|
||||
BinaryPattern() = default;
|
||||
explicit BinaryPattern(const std::string &pattern) : m_patterns(parseBinaryPatternString(pattern)) { }
|
||||
|
||||
[[nodiscard]] bool isValid() const { return !this->m_patterns.empty(); }
|
||||
[[nodiscard]] bool isValid() const { return !m_patterns.empty(); }
|
||||
|
||||
[[nodiscard]] bool matches(const std::vector<u8> &bytes) const {
|
||||
if (bytes.size() < this->m_patterns.size())
|
||||
if (bytes.size() < m_patterns.size())
|
||||
return false;
|
||||
|
||||
for (u32 i = 0; i < this->m_patterns.size(); i++) {
|
||||
for (u32 i = 0; i < m_patterns.size(); i++) {
|
||||
if (!this->matchesByte(bytes[i], i))
|
||||
return false;
|
||||
}
|
||||
@@ -32,13 +32,13 @@ namespace hex {
|
||||
}
|
||||
|
||||
[[nodiscard]] bool matchesByte(u8 byte, u32 offset) const {
|
||||
const auto &pattern = this->m_patterns[offset];
|
||||
const auto &pattern = m_patterns[offset];
|
||||
|
||||
return (byte & pattern.mask) == pattern.value;
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t getSize() const {
|
||||
return this->m_patterns.size();
|
||||
[[nodiscard]] u64 getSize() const {
|
||||
return m_patterns.size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
@@ -18,6 +16,7 @@ namespace hex {
|
||||
template<typename T>
|
||||
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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <wolv/types/static_string.hpp>
|
||||
#include <wolv/utils/preproc.hpp>
|
||||
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
@@ -30,9 +29,9 @@ namespace hex::dbg {
|
||||
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(), ImGui::getImGuiDataType<Type>(), &variable);
|
||||
ImGui::DragScalar(name.data(), ImGuiExt::getImGuiDataType<Type>(), &variable);
|
||||
} else if constexpr (std::same_as<Type, ImVec2>) {
|
||||
ImGui::InputFloat2(name.data(), &variable.x);
|
||||
ImGui::DragFloat2(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>) {
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
#include <vector>
|
||||
#include <span>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <wolv/io/file.hpp>
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -22,22 +20,22 @@ namespace hex {
|
||||
|
||||
EncodingFile();
|
||||
EncodingFile(const EncodingFile &other);
|
||||
EncodingFile(EncodingFile &&other);
|
||||
EncodingFile(EncodingFile &&other) noexcept;
|
||||
EncodingFile(Type type, const std::fs::path &path);
|
||||
EncodingFile(Type type, const std::string &path);
|
||||
EncodingFile(Type type, const std::string &content);
|
||||
|
||||
EncodingFile& operator=(const EncodingFile &other);
|
||||
EncodingFile& operator=(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]] size_t getLongestSequence() const { return m_longestSequence; }
|
||||
|
||||
[[nodiscard]] bool valid() const { return this->m_valid; }
|
||||
[[nodiscard]] bool valid() const { return m_valid; }
|
||||
|
||||
[[nodiscard]] const std::string& getTableContent() const { return this->m_tableContent; }
|
||||
[[nodiscard]] const std::string& getTableContent() const { return m_tableContent; }
|
||||
|
||||
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
||||
[[nodiscard]] const std::string& getName() const { return m_name; }
|
||||
|
||||
private:
|
||||
void parse(const std::string &content);
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
|
||||
#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...);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
@@ -39,6 +38,7 @@ namespace hex::fs {
|
||||
Plugins,
|
||||
Yara,
|
||||
Config,
|
||||
Backups,
|
||||
Resources,
|
||||
Constants,
|
||||
Encodings,
|
||||
@@ -50,6 +50,7 @@ namespace hex::fs {
|
||||
Libraries,
|
||||
Nodes,
|
||||
Layouts,
|
||||
Workspaces,
|
||||
|
||||
END
|
||||
};
|
||||
|
||||
@@ -7,15 +7,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
#include <wolv/io/file.hpp>
|
||||
#include <wolv/utils/core.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
#if defined(OS_WEB)
|
||||
#include <emscripten/fetch.h>
|
||||
@@ -25,6 +18,8 @@
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
typedef void CURL;
|
||||
|
||||
namespace hex {
|
||||
|
||||
class HttpRequest {
|
||||
@@ -36,7 +31,7 @@ namespace hex {
|
||||
explicit ResultBase(u32 statusCode) : m_statusCode(statusCode), m_valid(true) { }
|
||||
|
||||
[[nodiscard]] u32 getStatusCode() const {
|
||||
return this->m_statusCode;
|
||||
return m_statusCode;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isSuccess() const {
|
||||
@@ -44,7 +39,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isValid() const {
|
||||
return this->m_valid;
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -60,7 +55,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]]
|
||||
const T& getData() const {
|
||||
return this->m_data;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -77,34 +72,35 @@ namespace hex {
|
||||
|
||||
HttpRequest& operator=(HttpRequest &&other) noexcept;
|
||||
|
||||
static void setProxy(std::string proxy);
|
||||
static void setProxyState(bool enabled);
|
||||
static void setProxyUrl(std::string proxy);
|
||||
|
||||
void setMethod(std::string method) {
|
||||
this->m_method = std::move(method);
|
||||
m_method = std::move(method);
|
||||
}
|
||||
|
||||
void setUrl(std::string url) {
|
||||
this->m_url = std::move(url);
|
||||
m_url = std::move(url);
|
||||
}
|
||||
|
||||
void addHeader(std::string key, std::string value) {
|
||||
this->m_headers[std::move(key)] = std::move(value);
|
||||
m_headers[std::move(key)] = std::move(value);
|
||||
}
|
||||
|
||||
void setBody(std::string body) {
|
||||
this->m_body = std::move(body);
|
||||
m_body = std::move(body);
|
||||
}
|
||||
|
||||
void setTimeout(u32 timeout) {
|
||||
this->m_timeout = timeout;
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
float getProgress() const {
|
||||
return this->m_progress;
|
||||
return m_progress;
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
this->m_canceled = true;
|
||||
m_canceled = true;
|
||||
}
|
||||
|
||||
template<typename T = std::string>
|
||||
@@ -121,9 +117,9 @@ namespace hex {
|
||||
template<typename T = std::string>
|
||||
std::future<Result<T>> execute();
|
||||
|
||||
std::string urlEncode(const std::string &input);
|
||||
static std::string urlEncode(const std::string &input);
|
||||
|
||||
std::string urlDecode(const std::string &input);
|
||||
static std::string urlDecode(const std::string &input);
|
||||
|
||||
protected:
|
||||
void setDefaultConfig();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include<future>
|
||||
#include <future>
|
||||
|
||||
#include <emscripten/fetch.h>
|
||||
|
||||
@@ -44,24 +44,24 @@ namespace hex {
|
||||
|
||||
template<typename T>
|
||||
HttpRequest::Result<T> HttpRequest::executeImpl(std::vector<u8> &data) {
|
||||
strcpy(this->m_attr.requestMethod, this->m_method.c_str());
|
||||
this->m_attr.attributes = EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
||||
strcpy(m_attr.requestMethod, m_method.c_str());
|
||||
m_attr.attributes = EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
||||
|
||||
if (!this->m_body.empty()) {
|
||||
this->m_attr.requestData = this->m_body.c_str();
|
||||
this->m_attr.requestDataSize = this->m_body.size();
|
||||
if (!m_body.empty()) {
|
||||
m_attr.requestData = m_body.c_str();
|
||||
m_attr.requestDataSize = m_body.size();
|
||||
}
|
||||
|
||||
std::vector<const char*> headers;
|
||||
for (auto it = this->m_headers.begin(); it != this->m_headers.end(); it++) {
|
||||
for (auto it = m_headers.begin(); it != m_headers.end(); it++) {
|
||||
headers.push_back(it->first.c_str());
|
||||
headers.push_back(it->second.c_str());
|
||||
}
|
||||
headers.push_back(nullptr);
|
||||
this->m_attr.requestHeaders = headers.data();
|
||||
m_attr.requestHeaders = headers.data();
|
||||
|
||||
// Send request
|
||||
emscripten_fetch_t* fetch = emscripten_fetch(&this->m_attr, this->m_url.c_str());
|
||||
emscripten_fetch_t* fetch = emscripten_fetch(&m_attr, m_url.c_str());
|
||||
|
||||
data.resize(fetch->numBytes);
|
||||
std::copy(fetch->data, fetch->data + fetch->numBytes, data.begin());
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include<string>
|
||||
#include<future>
|
||||
#include <string>
|
||||
#include <future>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename T>
|
||||
@@ -13,8 +18,8 @@ namespace hex {
|
||||
std::vector<u8> response;
|
||||
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToFile);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &file);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToFile);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &file);
|
||||
|
||||
return this->executeImpl<T>(response);
|
||||
});
|
||||
@@ -25,39 +30,39 @@ namespace hex {
|
||||
return std::async(std::launch::async, [this, path, mimeName]{
|
||||
auto fileName = wolv::util::toUTF8String(path.filename());
|
||||
|
||||
curl_mime *mime = curl_mime_init(this->m_curl);
|
||||
curl_mime *mime = curl_mime_init(m_curl);
|
||||
curl_mimepart *part = curl_mime_addpart(mime);
|
||||
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
|
||||
curl_mime_data_cb(part, file.getSize(),
|
||||
[](char *buffer, size_t size, size_t nitems, void *arg) -> size_t {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
auto handle = static_cast<FILE*>(arg);
|
||||
|
||||
return fread(buffer, size, nitems, file);
|
||||
return fread(buffer, size, nitems, handle);
|
||||
},
|
||||
[](void *arg, curl_off_t offset, int origin) -> int {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
auto handle = static_cast<FILE*>(arg);
|
||||
|
||||
if (fseek(file, offset, origin) != 0)
|
||||
if (fseek(handle, offset, origin) != 0)
|
||||
return CURL_SEEKFUNC_CANTSEEK;
|
||||
else
|
||||
return CURL_SEEKFUNC_OK;
|
||||
},
|
||||
[](void *arg) {
|
||||
auto file = static_cast<FILE*>(arg);
|
||||
auto handle = static_cast<FILE*>(arg);
|
||||
|
||||
fclose(file);
|
||||
fclose(handle);
|
||||
},
|
||||
file.getHandle());
|
||||
curl_mime_filename(part, fileName.c_str());
|
||||
curl_mime_name(part, mimeName.c_str());
|
||||
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_MIMEPOST, mime);
|
||||
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
@@ -66,7 +71,7 @@ namespace hex {
|
||||
template<typename T>
|
||||
std::future<HttpRequest::Result<T>> HttpRequest::uploadFile(std::vector<u8> data, const std::string &mimeName, const std::fs::path &fileName) {
|
||||
return std::async(std::launch::async, [this, data = std::move(data), mimeName, fileName]{
|
||||
curl_mime *mime = curl_mime_init(this->m_curl);
|
||||
curl_mime *mime = curl_mime_init(m_curl);
|
||||
curl_mimepart *part = curl_mime_addpart(mime);
|
||||
|
||||
curl_mime_data(part, reinterpret_cast<const char *>(data.data()), data.size());
|
||||
@@ -74,11 +79,11 @@ namespace hex {
|
||||
curl_mime_filename(part, fileNameStr.c_str());
|
||||
curl_mime_name(part, mimeName.c_str());
|
||||
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_MIMEPOST, mime);
|
||||
curl_easy_setopt(m_curl, CURLOPT_MIMEPOST, mime);
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
@@ -89,8 +94,8 @@ namespace hex {
|
||||
return std::async(std::launch::async, [this] {
|
||||
|
||||
std::vector<u8> responseData;
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, writeToVector);
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &responseData);
|
||||
|
||||
return this->executeImpl<T>(responseData);
|
||||
});
|
||||
@@ -98,33 +103,33 @@ namespace hex {
|
||||
|
||||
template<typename T>
|
||||
HttpRequest::Result<T> HttpRequest::executeImpl(std::vector<u8> &data) {
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_URL, this->m_url.c_str());
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_CUSTOMREQUEST, this->m_method.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_URL, m_url.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, m_method.c_str());
|
||||
|
||||
setDefaultConfig();
|
||||
|
||||
if (!this->m_body.empty()) {
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_POSTFIELDS, this->m_body.c_str());
|
||||
if (!m_body.empty()) {
|
||||
curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, m_body.c_str());
|
||||
}
|
||||
|
||||
curl_slist *headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Cache-Control: no-cache");
|
||||
ON_SCOPE_EXIT { curl_slist_free_all(headers); };
|
||||
|
||||
for (auto &[key, value] : this->m_headers) {
|
||||
for (auto &[key, value] : m_headers) {
|
||||
std::string header = hex::format("{}: {}", key, value);
|
||||
headers = curl_slist_append(headers, header.c_str());
|
||||
}
|
||||
curl_easy_setopt(this->m_curl, CURLOPT_HTTPHEADER, headers);
|
||||
curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
{
|
||||
std::scoped_lock lock(this->m_transmissionMutex);
|
||||
std::scoped_lock lock(m_transmissionMutex);
|
||||
|
||||
auto result = curl_easy_perform(this->m_curl);
|
||||
auto result = curl_easy_perform(m_curl);
|
||||
if (result != CURLE_OK){
|
||||
char *url = nullptr;
|
||||
curl_easy_getinfo(this->m_curl, CURLINFO_EFFECTIVE_URL, &url);
|
||||
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", this->m_method, url, u32(result), curl_easy_strerror(result));
|
||||
curl_easy_getinfo(m_curl, CURLINFO_EFFECTIVE_URL, &url);
|
||||
log::error("Http request '{0} {1}' failed with error {2}: '{3}'", m_method, url, u32(result), curl_easy_strerror(result));
|
||||
checkProxyErrors();
|
||||
|
||||
return { };
|
||||
@@ -132,7 +137,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
long statusCode = 0;
|
||||
curl_easy_getinfo(this->m_curl, CURLINFO_RESPONSE_CODE, &statusCode);
|
||||
curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &statusCode);
|
||||
|
||||
return Result<T>(statusCode, { data.begin(), data.end() });
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
inline void unused(auto && ... x) {
|
||||
void unused(auto && ... x) {
|
||||
((void)x, ...);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,19 @@ namespace hex::literals {
|
||||
|
||||
/* Byte literals */
|
||||
|
||||
constexpr static inline unsigned long long operator""_Bytes(unsigned long long bytes) noexcept {
|
||||
constexpr static unsigned long long operator""_Bytes(unsigned long long bytes) noexcept {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
constexpr static inline unsigned long long operator""_KiB(unsigned long long kiB) noexcept {
|
||||
constexpr static unsigned long long operator""_KiB(unsigned long long kiB) noexcept {
|
||||
return operator""_Bytes(kiB * 1024);
|
||||
}
|
||||
|
||||
constexpr static inline unsigned long long operator""_MiB(unsigned long long MiB) noexcept {
|
||||
constexpr static unsigned long long operator""_MiB(unsigned long long MiB) noexcept {
|
||||
return operator""_KiB(MiB * 1024);
|
||||
}
|
||||
|
||||
constexpr static inline unsigned long long operator""_GiB(unsigned long long GiB) noexcept {
|
||||
constexpr static unsigned long long operator""_GiB(unsigned long long GiB) noexcept {
|
||||
return operator""_MiB(GiB * 1024);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/color.h>
|
||||
#include <fmt/chrono.h>
|
||||
|
||||
#include <wolv/io/file.hpp>
|
||||
|
||||
@@ -30,64 +28,46 @@ namespace hex::log {
|
||||
};
|
||||
|
||||
std::vector<LogEntry>& getLogEntries();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
[[maybe_unused]] void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level) {
|
||||
const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
|
||||
|
||||
fmt::print(dest, "[{0:%H:%M:%S}] ", now);
|
||||
|
||||
if (impl::isRedirected())
|
||||
fmt::print(dest, "{0} ", level);
|
||||
else
|
||||
fmt::print(dest, ts, "{0} ", level);
|
||||
|
||||
fmt::print(dest, "[{0}] ", IMHEX_PROJECT_NAME);
|
||||
|
||||
constexpr static auto ProjectNameLength = std::char_traits<char>::length(IMHEX_PROJECT_NAME);
|
||||
fmt::print(dest, "{}", std::string(ProjectNameLength > 10 ? 0 : 10 - ProjectNameLength, ' '));
|
||||
}
|
||||
[[maybe_unused]] void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName);
|
||||
|
||||
[[maybe_unused]] void print(const fmt::text_style &ts, const std::string &level, const std::string &fmt, auto && ... args) {
|
||||
std::scoped_lock lock(impl::g_loggerMutex);
|
||||
std::scoped_lock lock(g_loggerMutex);
|
||||
|
||||
auto dest = impl::getDestination();
|
||||
printPrefix(dest, ts, level);
|
||||
auto dest = getDestination();
|
||||
printPrefix(dest, ts, level, IMHEX_PROJECT_NAME);
|
||||
|
||||
auto message = fmt::format(fmt::runtime(fmt), args...);
|
||||
fmt::print(dest, "{}\n", message);
|
||||
fflush(dest);
|
||||
|
||||
impl::getLogEntries().push_back({ IMHEX_PROJECT_NAME, level, std::move(message) });
|
||||
getLogEntries().push_back({ IMHEX_PROJECT_NAME, level, std::move(message) });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[[maybe_unused]] void debug(const std::string &fmt, auto && ... args) {
|
||||
#if defined(DEBUG)
|
||||
hex::log::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
|
||||
hex::log::impl::print(fg(fmt::color::light_green) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
|
||||
#else
|
||||
impl::getLogEntries().push_back({ IMHEX_PROJECT_NAME, "[DEBUG]", fmt::format(fmt::runtime(fmt), args...) });
|
||||
#endif
|
||||
}
|
||||
|
||||
[[maybe_unused]] void info(const std::string &fmt, auto && ... args) {
|
||||
hex::log::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ", fmt, args...);
|
||||
hex::log::impl::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ", fmt, args...);
|
||||
}
|
||||
|
||||
[[maybe_unused]] void warn(const std::string &fmt, auto && ... args) {
|
||||
hex::log::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ", fmt, args...);
|
||||
hex::log::impl::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ", fmt, args...);
|
||||
}
|
||||
|
||||
[[maybe_unused]] void error(const std::string &fmt, auto && ... args) {
|
||||
hex::log::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR]", fmt, args...);
|
||||
hex::log::impl::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR]", fmt, args...);
|
||||
}
|
||||
|
||||
[[maybe_unused]] void fatal(const std::string &fmt, auto && ... args) {
|
||||
hex::log::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL]", fmt, args...);
|
||||
hex::log::impl::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL]", fmt, args...);
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,9 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
using Patches = std::map<u64, u8>;
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
enum class IPSError {
|
||||
AddressOutOfRange,
|
||||
@@ -19,9 +21,22 @@ namespace hex {
|
||||
MissingEOF
|
||||
};
|
||||
|
||||
wolv::util::Expected<std::vector<u8>, IPSError> generateIPSPatch(const Patches &patches);
|
||||
wolv::util::Expected<std::vector<u8>, IPSError> generateIPS32Patch(const Patches &patches);
|
||||
class Patches {
|
||||
public:
|
||||
Patches() = default;
|
||||
Patches(std::map<u64, u8> &&patches) : m_patches(std::move(patches)) {}
|
||||
|
||||
wolv::util::Expected<Patches, IPSError> loadIPSPatch(const std::vector<u8> &ipsPatch);
|
||||
wolv::util::Expected<Patches, IPSError> loadIPS32Patch(const std::vector<u8> &ipsPatch);
|
||||
static wolv::util::Expected<Patches, IPSError> fromProvider(hex::prv::Provider *provider);
|
||||
static wolv::util::Expected<Patches, IPSError> fromIPSPatch(const std::vector<u8> &ipsPatch);
|
||||
static wolv::util::Expected<Patches, IPSError> fromIPS32Patch(const std::vector<u8> &ipsPatch);
|
||||
|
||||
wolv::util::Expected<std::vector<u8>, IPSError> toIPSPatch() const;
|
||||
wolv::util::Expected<std::vector<u8>, IPSError> toIPS32Patch() const;
|
||||
|
||||
const auto& get() const { return m_patches; }
|
||||
auto& get() { return m_patches; }
|
||||
|
||||
private:
|
||||
std::map<u64, u8> m_patches;
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <microtar.h>
|
||||
#include <memory>
|
||||
|
||||
struct mtar_t;
|
||||
|
||||
namespace hex {
|
||||
|
||||
@@ -30,30 +32,30 @@ namespace hex {
|
||||
* @brief get the error string explaining the error that occured when opening the file.
|
||||
* This error is a combination of the tar error and the native file open error
|
||||
*/
|
||||
std::string getOpenErrorString();
|
||||
std::string getOpenErrorString() const;
|
||||
|
||||
[[nodiscard]] std::vector<u8> readVector(const std::fs::path &path);
|
||||
[[nodiscard]] std::string readString(const std::fs::path &path);
|
||||
[[nodiscard]] std::vector<u8> readVector(const std::fs::path &path) const;
|
||||
[[nodiscard]] std::string readString(const std::fs::path &path) const;
|
||||
|
||||
void writeVector(const std::fs::path &path, const std::vector<u8> &data);
|
||||
void writeString(const std::fs::path &path, const std::string &data);
|
||||
void writeVector(const std::fs::path &path, const std::vector<u8> &data) const;
|
||||
void writeString(const std::fs::path &path, const std::string &data) const;
|
||||
|
||||
[[nodiscard]] std::vector<std::fs::path> listEntries(const std::fs::path &basePath = "/");
|
||||
[[nodiscard]] bool contains(const std::fs::path &path);
|
||||
[[nodiscard]] std::vector<std::fs::path> listEntries(const std::fs::path &basePath = "/") const;
|
||||
[[nodiscard]] bool contains(const std::fs::path &path) const;
|
||||
|
||||
void extract(const std::fs::path &path, const std::fs::path &outputPath);
|
||||
void extractAll(const std::fs::path &outputPath);
|
||||
void extract(const std::fs::path &path, const std::fs::path &outputPath) const;
|
||||
void extractAll(const std::fs::path &outputPath) const;
|
||||
|
||||
[[nodiscard]] bool isValid() const { return this->m_valid; }
|
||||
[[nodiscard]] bool isValid() const { return m_valid; }
|
||||
|
||||
private:
|
||||
mtar_t m_ctx = { };
|
||||
std::unique_ptr<mtar_t> m_ctx;
|
||||
std::fs::path m_path;
|
||||
|
||||
bool m_valid = false;
|
||||
|
||||
// These will be updated when the constructor is called
|
||||
int m_tarOpenErrno = MTAR_ESUCCESS;
|
||||
int m_tarOpenErrno = 0;
|
||||
int m_fileOpenErrno = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,12 @@ namespace hex {
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getStartAddress() const { return this->address; }
|
||||
[[nodiscard]] constexpr u64 getEndAddress() const { return this->address + this->size - 1;}
|
||||
[[nodiscard]] constexpr u64 getEndAddress() const {
|
||||
if (this->size == 0)
|
||||
return this->address;
|
||||
else
|
||||
return this->address + this->size - 1;
|
||||
}
|
||||
[[nodiscard]] constexpr size_t getSize() const { return this->size; }
|
||||
|
||||
[[nodiscard]] constexpr bool operator==(const Region &other) const {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <hex/helpers/intrinsics.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
@@ -19,10 +18,20 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#elif defined(OS_LINUX)
|
||||
#include <hex/helpers/utils_linux.hpp>
|
||||
#endif
|
||||
|
||||
struct ImVec2;
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] std::vector<T> sampleData(const std::vector<T> &data, size_t count) {
|
||||
size_t stride = std::max(1.0, double(data.size()) / count);
|
||||
@@ -54,6 +63,9 @@ namespace hex {
|
||||
[[nodiscard]] std::string to_string(u128 value);
|
||||
[[nodiscard]] std::string to_string(i128 value);
|
||||
|
||||
[[nodiscard]] std::string toLower(std::string string);
|
||||
[[nodiscard]] std::string toUpper(std::string string);
|
||||
|
||||
[[nodiscard]] std::vector<u8> parseHexString(std::string string);
|
||||
[[nodiscard]] std::optional<u8> parseBinaryString(const std::string &string);
|
||||
[[nodiscard]] std::string toByteString(u64 bytes);
|
||||
@@ -66,7 +78,9 @@ namespace hex {
|
||||
[[nodiscard]] std::string encodeByteString(const std::vector<u8> &bytes);
|
||||
[[nodiscard]] std::vector<u8> decodeByteString(const std::string &string);
|
||||
|
||||
[[nodiscard]] constexpr inline u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
||||
std::wstring utf8ToUtf16(const std::string& utf8);
|
||||
|
||||
[[nodiscard]] constexpr u64 extract(u8 from, u8 to, const std::unsigned_integral auto &value) {
|
||||
if (from < to) std::swap(from, to);
|
||||
|
||||
using ValueType = std::remove_cvref_t<decltype(value)>;
|
||||
@@ -90,13 +104,13 @@ namespace hex {
|
||||
return (value & mask) >> to;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline i128 signExtend(size_t numBits, i128 value) {
|
||||
[[nodiscard]] constexpr i128 signExtend(size_t numBits, i128 value) {
|
||||
i128 mask = 1ULL << (numBits - 1);
|
||||
return (value ^ mask) - mask;
|
||||
}
|
||||
|
||||
template<std::integral T>
|
||||
[[nodiscard]] constexpr inline T swapBitOrder(size_t numBits, T value) {
|
||||
[[nodiscard]] constexpr T swapBitOrder(size_t numBits, T value) {
|
||||
T result = 0x00;
|
||||
|
||||
for (size_t bit = 0; bit < numBits; bit++) {
|
||||
@@ -107,14 +121,14 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline size_t strnlen(const char *s, size_t n) {
|
||||
[[nodiscard]] constexpr size_t strnlen(const char *s, size_t n) {
|
||||
size_t i = 0;
|
||||
while (i < n && s[i] != '\x00') i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
template<size_t Size>
|
||||
template<size_t>
|
||||
struct SizeTypeImpl { };
|
||||
|
||||
template<>
|
||||
@@ -215,7 +229,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] inline std::vector<u8> parseByteString(const std::string &string) {
|
||||
auto byteString = std::string(string);
|
||||
byteString.erase(std::remove(byteString.begin(), byteString.end(), ' '), byteString.end());
|
||||
std::erase(byteString, ' ');
|
||||
|
||||
if ((byteString.length() % 2) != 0) return {};
|
||||
|
||||
@@ -230,11 +244,11 @@ namespace hex {
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string toBinaryString(std::unsigned_integral auto number) {
|
||||
[[nodiscard]] std::string toBinaryString(std::unsigned_integral auto number) {
|
||||
if (number == 0) return "0";
|
||||
|
||||
std::string result;
|
||||
for (i16 bit = hex::bit_width(number) - 1; bit >= 0; bit--)
|
||||
for (i16 bit = hex::bit_width(number) - 1; bit >= 0; bit -= 1)
|
||||
result += (number & (0b1 << bit)) == 0 ? '0' : '1';
|
||||
|
||||
return result;
|
||||
@@ -287,4 +301,7 @@ namespace hex {
|
||||
|
||||
[[nodiscard]] std::optional<std::fs::path> getInitialFilePath();
|
||||
|
||||
[[nodiscard]] std::string generateHexView(u64 offset, u64 size, prv::Provider *provider);
|
||||
[[nodiscard]] std::string generateHexView(u64 offset, const std::vector<u8> &data);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#if defined(OS_MACOS)
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
extern "C" {
|
||||
|
||||
void errorMessageMacos(const char *message);
|
||||
@@ -9,6 +11,8 @@
|
||||
bool isMacosSystemDarkModeEnabled();
|
||||
float getBackingScaleFactor();
|
||||
|
||||
void setupMacosWindowStyle(GLFWwindow *window);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
|
||||
#include <wolv/utils/string.hpp>
|
||||
#include <wolv/utils/preproc.hpp>
|
||||
|
||||
@@ -22,29 +23,57 @@
|
||||
* Name, Author and Description will be displayed in the in the plugin list on the Welcome screen.
|
||||
*/
|
||||
#define IMHEX_PLUGIN_SETUP(name, author, description) IMHEX_PLUGIN_SETUP_IMPL(name, author, description)
|
||||
#define IMHEX_LIBRARY_SETUP() IMHEX_LIBRARY_SETUP_IMPL()
|
||||
|
||||
#define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginName() { return name; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getCompatibleVersion() { return IMHEX_VERSION; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \
|
||||
ImGui::SetCurrentContext(ctx); \
|
||||
GImGui = ctx; \
|
||||
} \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializePlugin(); \
|
||||
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
|
||||
hex::PluginManager::addPlugin(hex::PluginFunctions { \
|
||||
initializePlugin, \
|
||||
getPluginName, \
|
||||
getPluginAuthor, \
|
||||
getPluginDescription, \
|
||||
getCompatibleVersion, \
|
||||
setImGuiContext, \
|
||||
nullptr, \
|
||||
nullptr \
|
||||
}); \
|
||||
} \
|
||||
#define IMHEX_LIBRARY_SETUP_IMPL() \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary(); \
|
||||
static auto WOLV_TOKEN_CONCAT(libraryInitializer_, IMHEX_PLUGIN_NAME) = [] { \
|
||||
initializeLibrary(); \
|
||||
hex::log::info("Library plugin '{}' initialized successfully", WOLV_STRINGIFY(IMHEX_PLUGIN_NAME)); \
|
||||
return 0; \
|
||||
}(); \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \
|
||||
ImGui::SetCurrentContext(ctx); \
|
||||
GImGui = ctx; \
|
||||
} \
|
||||
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
|
||||
hex::PluginManager::addPlugin(hex::PluginFunctions { \
|
||||
nullptr, \
|
||||
initializeLibrary, \
|
||||
nullptr, \
|
||||
nullptr, \
|
||||
nullptr, \
|
||||
nullptr, \
|
||||
setImGuiContext, \
|
||||
nullptr, \
|
||||
nullptr \
|
||||
}); \
|
||||
} \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializeLibrary()
|
||||
|
||||
#define IMHEX_PLUGIN_SETUP_IMPL(name, author, description) \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginName() { return name; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginAuthor() { return author; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getPluginDescription() { return description; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX const char *getCompatibleVersion() { return IMHEX_VERSION; } \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void setImGuiContext(ImGuiContext *ctx) { \
|
||||
ImGui::SetCurrentContext(ctx); \
|
||||
GImGui = ctx; \
|
||||
} \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializePlugin(); \
|
||||
extern "C" [[gnu::visibility("default")]] void WOLV_TOKEN_CONCAT(forceLinkPlugin_, IMHEX_PLUGIN_NAME)() { \
|
||||
hex::PluginManager::addPlugin(hex::PluginFunctions { \
|
||||
initializePlugin, \
|
||||
nullptr, \
|
||||
getPluginName, \
|
||||
getPluginAuthor, \
|
||||
getPluginDescription, \
|
||||
getCompatibleVersion, \
|
||||
setImGuiContext, \
|
||||
nullptr, \
|
||||
nullptr \
|
||||
}); \
|
||||
} \
|
||||
IMHEX_PLUGIN_VISIBILITY_PREFIX void initializePlugin()
|
||||
|
||||
/**
|
||||
@@ -63,3 +92,12 @@
|
||||
return &g_subCommands; \
|
||||
} \
|
||||
std::vector<hex::SubCommand> g_subCommands
|
||||
|
||||
#define IMHEX_FEATURE_ENABLED(feature) WOLV_TOKEN_CONCAT(WOLV_TOKEN_CONCAT(WOLV_TOKEN_CONCAT(IMHEX_PLUGIN_, IMHEX_PLUGIN_NAME), _FEATURE_), feature)
|
||||
#define IMHEX_PLUGIN_FEATURES() IMHEX_PLUGIN_FEATURES_IMPL()
|
||||
#define IMHEX_PLUGIN_FEATURES_IMPL() \
|
||||
extern std::vector<hex::Feature> g_features; \
|
||||
extern "C" [[gnu::visibility("default")]] void* getFeatures() { \
|
||||
return &g_features; \
|
||||
} \
|
||||
std::vector<hex::Feature> g_features
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/helpers/literals.hpp>
|
||||
|
||||
@@ -20,7 +17,7 @@ namespace hex::prv {
|
||||
public:
|
||||
using BufferedReader::BufferedReader;
|
||||
|
||||
ProviderReader(Provider *provider, size_t bufferSize = 0x100000) : BufferedReader(provider, provider->getActualSize(), bufferSize) {
|
||||
explicit ProviderReader(Provider *provider, size_t bufferSize = 0x100000) : BufferedReader(provider, provider->getActualSize(), bufferSize) {
|
||||
this->setEndAddress(provider->getBaseAddress() + provider->getActualSize() - 1);
|
||||
this->seek(provider->getBaseAddress());
|
||||
}
|
||||
|
||||
46
lib/libimhex/include/hex/providers/memory_provider.hpp
Normal file
46
lib/libimhex/include/hex/providers/memory_provider.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
/**
|
||||
* This is a simple mock provider that can be used to pass in-memory data to APIs that require a provider.
|
||||
* It's NOT a provider that can be loaded by the user.
|
||||
*/
|
||||
class MemoryProvider : public hex::prv::Provider {
|
||||
public:
|
||||
MemoryProvider() = default;
|
||||
explicit MemoryProvider(std::vector<u8> data) : m_data(std::move(data)) { }
|
||||
~MemoryProvider() override = default;
|
||||
|
||||
[[nodiscard]] bool isAvailable() const override { return true; }
|
||||
[[nodiscard]] bool isReadable() const override { return true; }
|
||||
[[nodiscard]] bool isWritable() const override { return true; }
|
||||
[[nodiscard]] bool isResizable() const override { return true; }
|
||||
[[nodiscard]] bool isSavable() const override { return m_name.empty(); }
|
||||
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
|
||||
|
||||
[[nodiscard]] bool open() override;
|
||||
void close() override { }
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
[[nodiscard]] u64 getActualSize() const override { return m_data.size(); }
|
||||
|
||||
void resizeRaw(u64 newSize) override;
|
||||
void insertRaw(u64 offset, u64 size) override;
|
||||
void removeRaw(u64 offset, u64 size) override;
|
||||
|
||||
[[nodiscard]] std::string getName() const override { return ""; }
|
||||
|
||||
[[nodiscard]] std::string getTypeName() const override { return "MemoryProvider"; }
|
||||
private:
|
||||
void renameFile();
|
||||
|
||||
private:
|
||||
std::vector<u8> m_data;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -10,11 +10,11 @@ namespace hex::prv {
|
||||
public:
|
||||
Overlay() = default;
|
||||
|
||||
void setAddress(u64 address) { this->m_address = address; }
|
||||
[[nodiscard]] u64 getAddress() const { return this->m_address; }
|
||||
void setAddress(u64 address) { m_address = address; }
|
||||
[[nodiscard]] u64 getAddress() const { return m_address; }
|
||||
|
||||
[[nodiscard]] u64 getSize() const { return this->m_data.size(); }
|
||||
[[nodiscard]] std::vector<u8> &getData() { return this->m_data; }
|
||||
[[nodiscard]] u64 getSize() const { return m_data.size(); }
|
||||
[[nodiscard]] std::vector<u8> &getData() { return m_data; }
|
||||
|
||||
private:
|
||||
u64 m_address = 0;
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/providers/overlay.hpp>
|
||||
#include <hex/helpers/fs.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <hex/providers/undo_redo/stack.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
|
||||
@@ -31,7 +33,7 @@ namespace hex::prv {
|
||||
std::function<void()> callback;
|
||||
};
|
||||
|
||||
constexpr static size_t MaxPageSize = 0x1000'0000;
|
||||
constexpr static u64 MaxPageSize = 0xFFFF'FFFF'FFFF'FFFF;
|
||||
|
||||
Provider();
|
||||
virtual ~Provider();
|
||||
@@ -106,7 +108,7 @@ namespace hex::prv {
|
||||
* @param size number of bytes to read
|
||||
* @param overlays apply overlays and patches is true. Same as readRaw() if false
|
||||
*/
|
||||
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
|
||||
void read(u64 offset, void *buffer, size_t size, bool overlays = true);
|
||||
|
||||
/**
|
||||
* @brief Write data to the patches of this provider. Will not directly modify provider.
|
||||
@@ -114,7 +116,7 @@ namespace hex::prv {
|
||||
* @param buffer buffer to take data to write from
|
||||
* @param size number of bytes to write
|
||||
*/
|
||||
virtual void write(u64 offset, const void *buffer, size_t size);
|
||||
void write(u64 offset, const void *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Read data from this provider, without applying overlays and patches
|
||||
@@ -135,7 +137,7 @@ namespace hex::prv {
|
||||
* @brief Get the full size of the data in this provider
|
||||
* @return The size of the entire available data of this provider
|
||||
*/
|
||||
[[nodiscard]] virtual size_t getActualSize() const = 0;
|
||||
[[nodiscard]] virtual u64 getActualSize() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets the type name of this provider
|
||||
@@ -154,28 +156,24 @@ namespace hex::prv {
|
||||
*/
|
||||
[[nodiscard]] virtual std::string getName() const = 0;
|
||||
|
||||
void resize(u64 newSize);
|
||||
void insert(u64 offset, u64 size);
|
||||
void remove(u64 offset, u64 size);
|
||||
|
||||
|
||||
virtual void resize(size_t newSize);
|
||||
virtual void insert(u64 offset, size_t size);
|
||||
virtual void remove(u64 offset, size_t size);
|
||||
virtual void resizeRaw(u64 newSize) { hex::unused(newSize); }
|
||||
virtual void insertRaw(u64 offset, u64 size) { hex::unused(offset, size); }
|
||||
virtual void removeRaw(u64 offset, u64 size) { hex::unused(offset, size); }
|
||||
|
||||
virtual void save();
|
||||
virtual void saveAs(const std::fs::path &path);
|
||||
|
||||
|
||||
void applyOverlays(u64 offset, void *buffer, size_t size);
|
||||
|
||||
[[nodiscard]] std::map<u64, u8> &getPatches();
|
||||
[[nodiscard]] const std::map<u64, u8> &getPatches() const;
|
||||
void applyPatches();
|
||||
|
||||
[[nodiscard]] Overlay *newOverlay();
|
||||
void deleteOverlay(Overlay *overlay);
|
||||
[[nodiscard]] const std::list<std::unique_ptr<Overlay>> &getOverlays();
|
||||
void applyOverlays(u64 offset, void *buffer, size_t size) const;
|
||||
[[nodiscard]] const std::list<std::unique_ptr<Overlay>> &getOverlays() const;
|
||||
|
||||
[[nodiscard]] size_t getPageSize() const;
|
||||
void setPageSize(size_t pageSize);
|
||||
[[nodiscard]] u64 getPageSize() const;
|
||||
void setPageSize(u64 pageSize);
|
||||
|
||||
[[nodiscard]] u32 getPageCount() const;
|
||||
[[nodiscard]] u32 getCurrentPage() const;
|
||||
@@ -184,15 +182,12 @@ namespace hex::prv {
|
||||
virtual void setBaseAddress(u64 address);
|
||||
[[nodiscard]] virtual u64 getBaseAddress() const;
|
||||
[[nodiscard]] virtual u64 getCurrentPageAddress() const;
|
||||
[[nodiscard]] virtual size_t getSize() const;
|
||||
[[nodiscard]] virtual u64 getSize() const;
|
||||
[[nodiscard]] virtual std::optional<u32> getPageOfAddress(u64 address) const;
|
||||
|
||||
[[nodiscard]] virtual std::vector<Description> getDataDescription() const;
|
||||
[[nodiscard]] virtual std::variant<std::string, i128> queryInformation(const std::string &category, const std::string &argument);
|
||||
|
||||
void addPatch(u64 offset, const void *buffer, size_t size, bool createUndo = false);
|
||||
void createUndoPoint();
|
||||
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
@@ -212,26 +207,33 @@ namespace hex::prv {
|
||||
[[nodiscard]] u32 getID() const;
|
||||
void setID(u32 id);
|
||||
|
||||
[[nodiscard]] virtual nlohmann::json storeSettings(nlohmann::json settings = { }) const;
|
||||
[[nodiscard]] virtual nlohmann::json storeSettings(nlohmann::json settings) const;
|
||||
virtual void loadSettings(const nlohmann::json &settings);
|
||||
|
||||
void markDirty(bool dirty = true) { this->m_dirty = dirty; }
|
||||
[[nodiscard]] bool isDirty() const { return this->m_dirty; }
|
||||
void markDirty(bool dirty = true) { m_dirty = dirty; }
|
||||
[[nodiscard]] bool isDirty() const { return m_dirty; }
|
||||
|
||||
[[nodiscard]] virtual std::pair<Region, bool> getRegionValidity(u64 address) const;
|
||||
|
||||
void skipLoadInterface() { this->m_skipLoadInterface = true; }
|
||||
[[nodiscard]] bool shouldSkipLoadInterface() const { return this->m_skipLoadInterface; }
|
||||
void skipLoadInterface() { m_skipLoadInterface = true; }
|
||||
[[nodiscard]] bool shouldSkipLoadInterface() const { return m_skipLoadInterface; }
|
||||
|
||||
void setErrorMessage(const std::string &errorMessage) { this->m_errorMessage = errorMessage; }
|
||||
[[nodiscard]] const std::string& getErrorMessage() const { return this->m_errorMessage; }
|
||||
void setErrorMessage(const std::string &errorMessage) { m_errorMessage = errorMessage; }
|
||||
[[nodiscard]] const std::string& getErrorMessage() const { return m_errorMessage; }
|
||||
|
||||
template<std::derived_from<undo::Operation> T>
|
||||
bool addUndoableOperation(auto && ... args) {
|
||||
return m_undoRedoStack.add<T>(std::forward<decltype(args)...>(args)...);
|
||||
}
|
||||
|
||||
[[nodiscard]] undo::Stack& getUndoStack() { return m_undoRedoStack; }
|
||||
|
||||
protected:
|
||||
u32 m_currPage = 0;
|
||||
u64 m_baseAddress = 0;
|
||||
|
||||
std::list<std::map<u64, u8>> m_patches;
|
||||
decltype(m_patches)::iterator m_currPatches;
|
||||
undo::Stack m_undoRedoStack;
|
||||
|
||||
std::list<std::unique_ptr<Overlay>> m_overlays;
|
||||
|
||||
u32 m_id;
|
||||
@@ -253,7 +255,7 @@ namespace hex::prv {
|
||||
|
||||
std::string m_errorMessage;
|
||||
|
||||
size_t m_pageSize = MaxPageSize;
|
||||
u64 m_pageSize = MaxPageSize;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/api/imhex_api.hpp>
|
||||
#include <hex/api/event.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
|
||||
#include <concepts>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class PerProvider {
|
||||
public:
|
||||
@@ -17,7 +19,7 @@ namespace hex {
|
||||
PerProvider(const PerProvider&) = delete;
|
||||
PerProvider(PerProvider&&) = delete;
|
||||
PerProvider& operator=(const PerProvider&) = delete;
|
||||
PerProvider& operator=(PerProvider&&) = delete;
|
||||
PerProvider& operator=(PerProvider &&) = delete;
|
||||
|
||||
PerProvider(T data) : m_data({ { ImHexApi::Provider::get(), std::move(data) } }) { this->onCreate(); }
|
||||
|
||||
@@ -32,19 +34,19 @@ namespace hex {
|
||||
}
|
||||
|
||||
T& get(prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
return this->m_data[provider];
|
||||
return m_data[provider];
|
||||
}
|
||||
|
||||
const T& get(prv::Provider *provider = ImHexApi::Provider::get()) const {
|
||||
return this->m_data[provider];
|
||||
return m_data.at(provider);
|
||||
}
|
||||
|
||||
void set(const T &data, prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
this->m_data[provider] = data;
|
||||
m_data[provider] = data;
|
||||
}
|
||||
|
||||
void set(T &&data, prv::Provider *provider = ImHexApi::Provider::get()) {
|
||||
this->m_data[provider] = std::move(data);
|
||||
m_data[provider] = std::move(data);
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
@@ -71,20 +73,20 @@ namespace hex {
|
||||
|
||||
private:
|
||||
void onCreate() {
|
||||
EventManager::subscribe<EventProviderOpened>(this, [this](prv::Provider *provider) {
|
||||
this->m_data.emplace(provider, T());
|
||||
EventProviderOpened::subscribe(this, [this](prv::Provider *provider) {
|
||||
m_data.emplace(provider, T());
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventProviderDeleted>(this, [this](prv::Provider *provider){
|
||||
this->m_data.erase(provider);
|
||||
EventProviderDeleted::subscribe(this, [this](prv::Provider *provider){
|
||||
m_data.erase(provider);
|
||||
});
|
||||
|
||||
EventManager::subscribe<EventImHexClosing>(this, [this] {
|
||||
this->m_data.clear();
|
||||
EventImHexClosing::subscribe(this, [this] {
|
||||
m_data.clear();
|
||||
});
|
||||
|
||||
// Moves the data of this PerProvider instance from one provider to another
|
||||
EventManager::subscribe<MovePerProviderData>(this, [this](prv::Provider *from, prv::Provider *to) {
|
||||
MovePerProviderData::subscribe(this, [this](prv::Provider *from, prv::Provider *to) {
|
||||
// Get the value from the old provider, (removes it from the map)
|
||||
auto node = m_data.extract(from);
|
||||
|
||||
@@ -92,18 +94,19 @@ namespace hex {
|
||||
if (node.empty()) return;
|
||||
|
||||
// Delete the value from the new provider, that we want to replace
|
||||
this->m_data.erase(to);
|
||||
m_data.erase(to);
|
||||
|
||||
// Re-insert it with the key of the new provider
|
||||
node.key() = to;
|
||||
this->m_data.insert(std::move(node));
|
||||
m_data.insert(std::move(node));
|
||||
});
|
||||
}
|
||||
|
||||
void onDestroy() {
|
||||
EventManager::unsubscribe<EventProviderOpened>(this);
|
||||
EventManager::unsubscribe<EventProviderDeleted>(this);
|
||||
EventManager::unsubscribe<EventImHexClosing>(this);
|
||||
EventProviderOpened::unsubscribe(this);
|
||||
EventProviderDeleted::unsubscribe(this);
|
||||
EventImHexClosing::unsubscribe(this);
|
||||
MovePerProviderData::unsubscribe(this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <hex/helpers/concepts.hpp>
|
||||
|
||||
namespace hex::prv {
|
||||
class Provider;
|
||||
}
|
||||
|
||||
namespace hex::prv::undo {
|
||||
|
||||
class Operation : public ICloneable<Operation> {
|
||||
public:
|
||||
virtual ~Operation() = default;
|
||||
|
||||
virtual void undo(Provider *provider) = 0;
|
||||
virtual void redo(Provider *provider) = 0;
|
||||
|
||||
[[nodiscard]] virtual Region getRegion() const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::string format() const = 0;
|
||||
[[nodiscard]] virtual std::vector<std::string> formatContent() const {
|
||||
return { };
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual bool shouldHighlight() const { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user