mirror of
https://github.com/OpenMW/openmw.git
synced 2025-08-16 07:14:07 +00:00
Compare commits
1223 commits
openmw-49-
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
9610be7c8a | ||
|
2b403b38be | ||
|
ac2627a7b7 | ||
|
8622dacaea | ||
|
8c18c8460f | ||
|
72bf7673f4 | ||
|
488f73c5da | ||
|
a049f3c3a8 | ||
|
8073c59898 | ||
|
450f907166 | ||
|
bc2f948abe | ||
|
111d6620a6 | ||
|
50ebf304c7 | ||
|
1b5450557e | ||
|
fe48e2c9ae | ||
|
a418e05869 | ||
|
3a9a83b107 | ||
|
9f2ad18549 | ||
|
475e5522ed | ||
|
943966d59a | ||
|
3d954ed720 | ||
|
046c0a64f2 | ||
|
548fb5fecb | ||
|
40f26a9495 | ||
|
944985e1ce | ||
|
0acde006a0 | ||
|
5e30e45700 | ||
|
d58545ca39 | ||
|
cae36d6eec | ||
|
e226963d0d | ||
|
32e463945e | ||
|
37c4277b92 | ||
|
30bd014bd7 | ||
|
9db9df95e2 | ||
|
4749ddf586 | ||
|
cb0316e6be | ||
|
1ffcd3f213 | ||
|
cffb045767 | ||
|
6d0f05e97b | ||
|
87819b3e0d | ||
|
596ee3e8fa | ||
|
7f3bc4884e | ||
|
d4bc9696e9 | ||
|
ace1f7f3d0 | ||
|
33ea16655b | ||
|
8ea5448112 | ||
|
9426a36f5a | ||
|
f5d866894e | ||
|
a1d9cbd47c | ||
|
8f8723e2fc | ||
|
80a29ab57b | ||
|
41e2282501 | ||
|
2bb1c4810d | ||
|
363a6e0aa0 | ||
|
d05bb877fe | ||
|
1b34248ef6 | ||
|
a7ba54c361 | ||
|
a30b4ad615 | ||
|
b5f87a9d50 | ||
|
23fb414fd4 | ||
|
7ff139e7b1 | ||
|
d46e68a4d5 | ||
|
dd654e62f8 | ||
|
25adab1526 | ||
|
2b88a620f5 | ||
|
a085036a92 | ||
|
60d5e4d30b | ||
|
8c3757a324 | ||
|
5ad9010e07 | ||
|
34d297969e | ||
|
e4cc3adc98 | ||
|
dd801a55e2 | ||
|
d68b774c10 | ||
|
d121b606b6 | ||
|
a69b67a2b1 | ||
|
4344dc6e00 | ||
|
aca6532044 | ||
|
c293c76bd7 | ||
|
8e76a0ab06 | ||
|
ef2332eb37 | ||
|
493f70a661 | ||
|
e74167c7b7 | ||
|
1a886db951 | ||
|
4337ed7683 | ||
|
7a5fe778bc | ||
|
aa545467fd | ||
|
4c5118a24b | ||
|
2ab87f2d22 | ||
|
b2746a7b4b | ||
|
0c4da49c74 | ||
|
ef3f52d6a4 | ||
|
aae81264a2 | ||
|
afb7f1da54 | ||
|
c71448359b | ||
|
99ae52e94c | ||
|
cc2ec85244 | ||
|
a0585949a9 | ||
|
4a2f85cfde | ||
|
c77a849e9e | ||
|
485517cf64 | ||
|
0d7efaa2e3 | ||
|
d7a411cc72 | ||
|
3bf62235ba | ||
|
b6b4e4f102 | ||
|
7569273b33 | ||
|
555a10f50c | ||
|
b9a28dab3e | ||
|
fa290956c8 | ||
|
ccb4ca49ca | ||
|
c276f850dc | ||
|
286c4d9101 | ||
|
2abed374f9 | ||
|
7c4ed3c11d | ||
|
ae9c42e0a0 | ||
|
7e9d4795ba | ||
|
3147aea0ed | ||
|
d40a78e8ac | ||
|
31abd366ff | ||
|
7c665643ad | ||
|
5203f300e2 | ||
|
e87b95f642 | ||
|
eeca0b13b0 | ||
|
a2bc1569e0 | ||
|
5ea3cca83b | ||
|
c89f88c4e6 | ||
|
550b0c985f | ||
|
05f0b4cdbd | ||
|
cc68316f72 | ||
|
978d8668f4 | ||
|
dbd92e6844 | ||
|
4c4d6078d8 | ||
|
1986891e79 | ||
|
c139680ce3 | ||
|
f2cfaac4b8 | ||
|
1fbbaefb47 | ||
|
5209685783 | ||
|
64a45f8aeb | ||
|
6464e2a11b | ||
|
abb381a163 | ||
|
5e64015aa9 | ||
|
2cd4b643d0 | ||
|
05d67ef412 | ||
|
0b5c8271e0 | ||
|
929a65126a | ||
|
0801e0512d | ||
|
b160cee0b7 | ||
|
2a8dc56619 | ||
|
2e5836a748 | ||
|
d49a6a119b | ||
|
f453ce27a0 | ||
|
666f154082 | ||
|
04f42f12e1 | ||
|
645eb81133 | ||
|
59aba3ae7e | ||
|
a134f8d882 | ||
|
5de1ae7b24 | ||
|
23e3d0b49a | ||
|
b792bc0ee2 | ||
|
405388b89f | ||
|
27e1a842a0 | ||
|
34eb3d485d | ||
|
2efa76052f | ||
|
aae21c6f53 | ||
|
bc05628fa8 | ||
|
75845bf863 | ||
|
ee540039a1 | ||
|
24c7d2f075 | ||
|
62492c7738 | ||
|
442e8796b4 | ||
|
27ee192354 | ||
|
aefa0ec1c4 | ||
|
57280eaf9d | ||
|
399ec4eccc | ||
|
582b409f7f | ||
|
5d5d14a5a6 | ||
|
b0e8544d58 | ||
|
0e8ca0cf19 | ||
|
b7fe1a6eb2 | ||
|
b937b0271f | ||
|
45a7040bc7 | ||
|
7c3fa3c89f | ||
|
ebcacf04bc | ||
|
70207750f2 | ||
|
395f6811c9 | ||
|
176dab5b3d | ||
|
e304ceb449 | ||
|
4efc8bf99d | ||
|
0a8373987d | ||
|
7b9958247a | ||
|
31580ffb71 | ||
|
dc2ff4bfa2 | ||
|
272e6fabf9 | ||
|
9870605aab | ||
|
2d5ec48892 | ||
|
f6a6a33c59 | ||
|
ee501d8d0d | ||
|
e77ee5c20f | ||
|
2051d5cbef | ||
|
af58da58fd | ||
|
d3309e0a8d | ||
|
7637ca536b | ||
|
7aeff7e473 | ||
|
02102eeeca | ||
|
c8aa644111 | ||
|
aae954643c | ||
|
c6f381f1c4 | ||
|
8682ea522f | ||
|
ec0c76d2f3 | ||
|
c5d74818eb | ||
|
4433e3c2de | ||
|
5dfda0090b | ||
|
3f1ac1848c | ||
|
927b2bcceb | ||
|
50f5bc51c6 | ||
|
de68310992 | ||
|
7f6fe15b10 | ||
|
bdb3387bff | ||
|
2bce45260c | ||
|
8deb050ea2 | ||
|
1896375380 | ||
|
3c3f36679e | ||
|
de057cc030 | ||
|
984582b586 | ||
|
360c801b73 | ||
|
24c7a3f1ce | ||
|
2a0ff5626c | ||
|
80dd2ea6da | ||
|
8a2888fa00 | ||
|
94b460389b | ||
|
d3328552e8 | ||
|
ed32e4405a | ||
|
b961007345 | ||
|
9f10269ecc | ||
|
e692025579 | ||
|
534d6b3ae9 | ||
|
7c46635a5a | ||
|
ae909d7685 | ||
|
c79b39cf0d | ||
|
20bd1491a7 | ||
|
4a3ffb2073 | ||
|
4ca9cac784 | ||
|
b3fe84a560 | ||
|
ab03e01127 | ||
|
b4a753812e | ||
|
defd1edb6f | ||
|
c0b230b742 | ||
|
c015599356 | ||
|
fb19a0da91 | ||
|
5b5ed21f20 | ||
|
b9ae89e032 | ||
|
95fc66bccd | ||
|
855b236ee8 | ||
|
730a62effc | ||
|
a560aceb2a | ||
|
cbb96e0fc2 | ||
|
a599825bf8 | ||
|
714c128947 | ||
|
45e08f62a1 | ||
|
b8fec360c3 | ||
|
f1447207b2 | ||
|
3f54d3e569 | ||
|
27adbf0cde | ||
|
d20a56517b | ||
|
6be96da6a4 | ||
|
d595d9f3b8 | ||
|
f52d9ad977 | ||
|
e3c9e6fe2b | ||
|
8d7218c118 | ||
|
ad996393f1 | ||
|
437f22ed72 | ||
|
092d9a4c62 | ||
|
f8a96fae24 | ||
|
be54521cfa | ||
|
52b785f726 | ||
|
5dddf9153d | ||
|
acfe9b6785 | ||
|
362c1a7ebe | ||
|
d1b03734b3 | ||
|
324bdf8f7a | ||
|
d401dd2441 | ||
|
044c556f0e | ||
|
125bbdc118 | ||
|
896d6fd01e | ||
|
d899454f36 | ||
|
b2cc549585 | ||
|
2b1cd1deb8 | ||
|
93cde36b09 | ||
|
30cfb42ed1 | ||
|
c30964feb2 | ||
|
28851411a3 | ||
|
9845f76583 | ||
|
2b4b532745 | ||
|
01fa3cc4e6 | ||
|
0f0a402ead | ||
|
6114a01ad4 | ||
|
ef50578a62 | ||
|
b0bdd68e7c | ||
|
29f1c7c68f | ||
|
f8d9149e4f | ||
|
c2ad1df030 | ||
|
dcac39aefd | ||
|
10602a0412 | ||
|
8bf9b205b7 | ||
|
39cc893639 | ||
|
1dfa2629f0 | ||
|
35eed68269 | ||
|
d34aee6257 | ||
|
b2bb12cd19 | ||
|
c098f2ccde | ||
|
614062d387 | ||
|
bf327adc93 | ||
|
152d87a6b3 | ||
|
7f28b33cf1 | ||
|
82b1d1b78e | ||
|
412134da99 | ||
|
22232e8710 | ||
|
f7238cd043 | ||
|
9370b41636 | ||
|
bef2948062 | ||
|
c53b1bf2c0 | ||
|
a73b803592 | ||
|
0abbf91477 | ||
|
4a0c998f53 | ||
|
93cb69b012 | ||
|
6796121305 | ||
|
7d5a9a2e2f | ||
|
c90ae89381 | ||
|
eba063ac23 | ||
|
b61d8fb585 | ||
|
3b42874797 | ||
|
0006cb22e2 | ||
|
eb67d1a1fb | ||
|
e1847d2670 | ||
|
f45053ad25 | ||
|
bd6254b6df | ||
|
446a4452d3 | ||
|
183652e51d | ||
|
6dadf5de75 | ||
|
418879bada | ||
|
f9c7dc0b20 | ||
|
281dea527f | ||
|
3899260eea | ||
|
a7a47f3ea9 | ||
|
ab8e17196f | ||
|
4f827b6336 | ||
|
f50c275133 | ||
|
400c5a6dba | ||
|
931555c7ff | ||
|
d602e9ff7a | ||
|
3b7b97c58c | ||
|
8826d5cb0e | ||
|
4adb9bd8ac | ||
|
cf24063226 | ||
|
a3a1b6d11f | ||
|
9e2927f734 | ||
|
af6634ee57 | ||
|
b8381f6e62 | ||
|
a296fa2b40 | ||
|
6f9b813bd1 | ||
|
a12a0916ed | ||
|
9dd028b260 | ||
|
64fef724a6 | ||
|
4f60284a35 | ||
|
a03a2a5ff2 | ||
|
1b240c7dd6 | ||
|
a894481fd7 | ||
|
6a02e6a4bc | ||
|
682f00bcff | ||
|
445cf1742d | ||
|
b53cb085c9 | ||
|
119a87b7f4 | ||
|
79d86bf2bd | ||
|
2cb7d6c392 | ||
|
85fdf2011a | ||
|
42109fc811 | ||
|
4f95ca4196 | ||
|
79c689784b | ||
|
c80b3d26b9 | ||
|
2dbe30ed5c | ||
|
bb1214ed69 | ||
|
11947286d9 | ||
|
87e41425bb | ||
|
cef1807536 | ||
|
61ebb4b259 | ||
|
1abaf706c8 | ||
|
ced135bc87 | ||
|
943cd765e7 | ||
|
8ec4fcbf30 | ||
|
05b12ac879 | ||
|
4150f5fad6 | ||
|
843a6487cc | ||
|
6629a186b1 | ||
|
084e4a3155 | ||
|
622cbd5288 | ||
|
3600a5c716 | ||
|
2504550c6f | ||
|
6dd10f1666 | ||
|
def31cfb05 | ||
|
d2c78ee88c | ||
|
403b5d19e0 | ||
|
463de2d791 | ||
|
f5e66f3e24 | ||
|
eb7af832e4 | ||
|
a4af037293 | ||
|
bcfe06d85a | ||
|
4e5e8e7889 | ||
|
e9081fec9f | ||
|
3e711c30db | ||
|
f4ff683905 | ||
|
77c30a68c9 | ||
|
869881d227 | ||
|
fe7970421f | ||
|
f5de0d1c40 | ||
|
25d9c80067 | ||
|
1ce7110a9e | ||
|
73ffe7f62b | ||
|
b075428513 | ||
|
e04f0a8bd6 | ||
|
d100867bce | ||
|
6d74a4607c | ||
|
a00e5ec828 | ||
|
7bc507eb58 | ||
|
b958dc7297 | ||
|
f64f53341b | ||
|
dca83c2500 | ||
|
3789070ea2 | ||
|
064b8d3f9b | ||
|
f3420bd1bd | ||
|
d46f034e5d | ||
|
9a637563cd | ||
|
759739ecca | ||
|
3ec04f4ba7 | ||
|
a68107712c | ||
|
8b44b95830 | ||
|
0892357230 | ||
|
e9a9659abc | ||
|
3135e2e479 | ||
|
c691c72cec | ||
|
c0276b6890 | ||
|
10dba7cda7 | ||
|
f87d6818b7 | ||
|
ede768532c | ||
|
f56d6e4c1e | ||
|
c61d4783e6 | ||
|
21367a6127 | ||
|
1331318002 | ||
|
0c4af81a69 | ||
|
36604777f2 | ||
|
3f352b2470 | ||
|
d5e3703aa8 | ||
|
83a37fecea | ||
|
e4f0723a90 | ||
|
40e9b2d707 | ||
|
2ce697a366 | ||
|
3a05ddb982 | ||
|
b170500183 | ||
|
952abf5557 | ||
|
fdc392435f | ||
|
e349fa248a | ||
|
abe0467915 | ||
|
db22706e8e | ||
|
ba361302a1 | ||
|
ce666db34f | ||
|
f0e9df4de2 | ||
|
1206688494 | ||
|
d29c01be26 | ||
|
c541cb96cc | ||
|
67795543a2 | ||
|
6a9b2d3302 | ||
|
c4a4c435f1 | ||
|
abbbeefdbd | ||
|
eb9096baf4 | ||
|
0b192c4485 | ||
|
a109052296 | ||
|
555721141d | ||
|
d207c2251f | ||
|
0e1ed078e9 | ||
|
73a3033e0f | ||
|
30140d9548 | ||
|
565b199380 | ||
|
83903455f9 | ||
|
4b98520266 | ||
|
34194f9c08 | ||
|
2e1f3d5d2c | ||
|
6c70c403be | ||
|
2db36c49b5 | ||
|
09ed5bb234 | ||
|
3df695df4a | ||
|
23dc226dff | ||
|
a77a8904e5 | ||
|
266702e729 | ||
|
89d6f59388 | ||
|
45c187028f | ||
|
df5625a1e3 | ||
|
c232ad55b4 | ||
|
86d81af199 | ||
|
3405d5017e | ||
|
a5e23f5fd3 | ||
|
3574cd552c | ||
|
d455ff5f5e | ||
|
779840deea | ||
|
9b8a383e8d | ||
|
c253590338 | ||
|
7143115e57 | ||
|
1b9802472d | ||
|
c7e3f9b0cf | ||
|
da32ccee50 | ||
|
b6f3b2760a | ||
|
bf92e551a7 | ||
|
a51afbeaa8 | ||
|
0655e7988e | ||
|
da71ec6e49 | ||
|
390589795c | ||
|
30a852bb88 | ||
|
2db9b91c10 | ||
|
a6503233a6 | ||
|
dfa3b5f7ed | ||
|
e577257ec4 | ||
|
0f26270f66 | ||
|
e4a6db1b84 | ||
|
38efdd2fd8 | ||
|
fdcf9f773c | ||
|
ffec2e8d74 | ||
|
b29850f4c6 | ||
|
4bf43665c4 | ||
|
28f3b4a530 | ||
|
3504e85051 | ||
|
424a62187a | ||
|
ed8b9742ae | ||
|
b3105e9382 | ||
|
30e5e17e4c | ||
|
fce73395e5 | ||
|
7f11579d39 | ||
|
57f8355bac | ||
|
30dae411d0 | ||
|
57bb6f2e2f | ||
|
284be88b95 | ||
|
937c020e58 | ||
|
190a1266a1 | ||
|
2d2df30f80 | ||
|
bcb27fff6a | ||
|
f8c8b9b433 | ||
|
15a525676c | ||
|
0ac0c62091 | ||
|
04d73cf195 | ||
|
ce0ae47478 | ||
|
64284063b3 | ||
|
ec3357ff3f | ||
|
28de55df6a | ||
|
bc78aa4198 | ||
|
a5b8db70a4 | ||
|
1a08565a20 | ||
|
d0af16c5db | ||
|
b2228de0b7 | ||
|
3d75dec73d | ||
|
94507567da | ||
|
9013ed16f0 | ||
|
99a6a04c70 | ||
|
8379c31f13 | ||
|
088b2d1bbc | ||
|
ee33424c20 | ||
|
ffac1cdf3c | ||
|
b1f32c8cee | ||
|
9fe420e562 | ||
|
593988e82b | ||
|
7f34e52a11 | ||
|
6a1f8b3f69 | ||
|
5d8c349899 | ||
|
44fb923d7b | ||
|
dbc732231f | ||
|
0aca34c02b | ||
|
32f59c16aa | ||
|
a6cf359820 | ||
|
d40c4855b1 | ||
|
ea147d78ed | ||
|
206d38f3d7 | ||
|
66b5623bc9 | ||
|
18ad2db59c | ||
|
a0e0b3c65b | ||
|
733dfbb89d | ||
|
982962c608 | ||
|
29177bccb8 | ||
|
7cc25d8916 | ||
|
7cf74c570e | ||
|
3767b60512 | ||
|
00e6e855f1 | ||
|
53feb29a5b | ||
|
75b4682cd7 | ||
|
66befc67d9 | ||
|
b5b5aa4331 | ||
|
2309aeec70 | ||
|
6f48a6f1bf | ||
|
f5e24804ce | ||
|
7c1dbdd191 | ||
|
c3a5ad4328 | ||
|
d756b02d68 | ||
|
acb554faac | ||
|
2dc0d8abca | ||
|
00e7439533 | ||
|
dca8c7c163 | ||
|
0027a5bcab | ||
|
e4439806ed | ||
|
eb4d3b7224 | ||
|
10f86c67fe | ||
|
4520eb077d | ||
|
cb0b44e0b2 | ||
|
5a292624a5 | ||
|
5c60168b16 | ||
|
681a95b89f | ||
|
c948171d5f | ||
|
612411e492 | ||
|
be13b1d085 | ||
|
fa8ba57ab3 | ||
|
e2e8a02a26 | ||
|
9228f90f46 | ||
|
aa652a20f0 | ||
|
5ba0b3ab52 | ||
|
149587dda4 | ||
|
583af381a6 | ||
|
32f13816f8 | ||
|
0a9c3ce96f | ||
|
48bc9e5dd2 | ||
|
47aa0b27ff | ||
|
ceac11d6df | ||
|
aa3e991352 | ||
|
f6bff53398 | ||
|
917b08e05d | ||
|
5ef947e14f | ||
|
a29f4b3ba0 | ||
|
59eb7b9888 | ||
|
0a44112dcc | ||
|
0d308eae3e | ||
|
48e386bf90 | ||
|
c9f6bdb6e0 | ||
|
514174ffc4 | ||
|
feeb15d1ff | ||
|
179341b221 | ||
|
450f587844 | ||
|
33ca7da731 | ||
|
2619859786 | ||
|
50f8bc721d | ||
|
d31ac93c69 | ||
|
9347fe5c4a | ||
|
2ffc44c31f | ||
|
2b0e5c3cc1 | ||
|
5ab73f5ecb | ||
|
ac7b3e9de9 | ||
|
c89b2b0c60 | ||
|
675146bd8b | ||
|
eca9b84f39 | ||
|
2ff497c3e5 | ||
|
cbb50c001b | ||
|
8ed5d84ff7 | ||
|
c4506d2d67 | ||
|
13f1b76a25 | ||
|
fdc878d766 | ||
|
759cea3051 | ||
|
164563f522 | ||
|
d49a42037a | ||
|
937f2bd441 | ||
|
88b43cabec | ||
|
5777a3cc3f | ||
|
493827285b | ||
|
ce8f81a6a7 | ||
|
8301dafad1 | ||
|
50e3c9d500 | ||
|
4bbc5710fb | ||
|
a524b3c9b0 | ||
|
fb5fa6ce18 | ||
|
c41f034a23 | ||
|
adc4698c44 | ||
|
faa9af4428 | ||
|
12f3596220 | ||
|
139bde6420 | ||
|
0f551c8233 | ||
|
608831265c | ||
|
acd4e77a85 | ||
|
3ff7dedfd1 | ||
|
0589b57a47 | ||
|
8367604331 | ||
|
9380233ab7 | ||
|
143c14c556 | ||
|
190680a3a9 | ||
|
2905ed5fb1 | ||
|
74c9da78d3 | ||
|
ac400f0ebc | ||
|
3abc86be73 | ||
|
320b2cf55e | ||
|
b1326e4554 | ||
|
3bdf57f7c1 | ||
|
79f18effdd | ||
|
39917f1ebe | ||
|
8b56415597 | ||
|
cc5540039e | ||
|
1ac407f32b | ||
|
0e68e36aa7 | ||
|
3207f3a387 | ||
|
732fb4affe | ||
|
03e4735b19 | ||
|
3e0685e4a6 | ||
|
effb3de2a7 | ||
|
76e2c77517 | ||
|
4ede868ed2 | ||
|
8de0ccc82c | ||
|
7c76387ffe | ||
|
5d0986e812 | ||
|
6671c12ad2 | ||
|
47453b307a | ||
|
f3128f9c7b | ||
|
8954f45867 | ||
|
fc772744d2 | ||
|
3d07b63ad8 | ||
|
940e73a356 | ||
|
ea02c69186 | ||
|
4182279f72 | ||
|
dcf0c6e314 | ||
|
901c6b94a6 | ||
|
c711179b8f | ||
|
378093791b | ||
|
8917103bf3 | ||
|
336275292e | ||
|
3b962e3fd4 | ||
|
22a0dce4a6 | ||
|
fe68a098ea | ||
|
1521d5195a | ||
|
283be9f4f0 | ||
|
910690c7e5 | ||
|
71d334fe79 | ||
|
d500f801cc | ||
|
bee9716262 | ||
|
5938ba528f | ||
|
50e5863749 | ||
|
b0fb0024bc | ||
|
37e0566745 | ||
|
323ee5f79d | ||
|
f7b8091117 | ||
|
276e0e6765 | ||
|
9a28216cda | ||
|
acbc0a9b8f | ||
|
fa0b3a04df | ||
|
efbef1ec96 | ||
|
dab2538e0c | ||
|
638ceb73b7 | ||
|
23a6208537 | ||
|
4e32e9f127 | ||
|
b7a1f76f4d | ||
|
cd1bd0eeaf | ||
|
d81c666a2c | ||
|
45d73957c1 | ||
|
733631a771 | ||
|
36941bf4e9 | ||
|
49a651761f | ||
|
e649498f06 | ||
|
4032f4e06c | ||
|
8439ac1b4e | ||
|
766b8f3145 | ||
|
5cc5307c10 | ||
|
4a6d2465b4 | ||
|
30b27c966f | ||
|
323e83784f | ||
|
f84983a5d4 | ||
|
1de86f95ac | ||
|
f9af61f096 | ||
|
21cf7bb397 | ||
|
2ce4571c3a | ||
|
132ff5294c | ||
|
522a572032 | ||
|
49865b1aa1 | ||
|
8d7bdc2e61 | ||
|
302d92561d | ||
|
6d89ae1a75 | ||
|
0a03403277 | ||
|
8d545a43d5 | ||
|
ef651ee187 | ||
|
e7305e7c97 | ||
|
780a4904bd | ||
|
0502366be9 | ||
|
b4ede02cce | ||
|
019af35278 | ||
|
f085717aef | ||
|
45a51bceb2 | ||
|
be0cbb7277 | ||
|
e01b8d372c | ||
|
b988190fba | ||
|
d8c764ba5a | ||
|
5163214878 | ||
|
d2e7da0c19 | ||
|
1e3ddee291 | ||
|
a179001052 | ||
|
0df8869f59 | ||
|
47b3674bac | ||
|
57ae097257 | ||
|
4e2e8d1a81 | ||
|
7347f4f4e3 | ||
|
9010a5bb32 | ||
|
f6b06057fa | ||
|
8094761c3e | ||
|
81720892f9 | ||
|
ba9d85dc30 | ||
|
be32cbb413 | ||
|
0ca6bc012c | ||
|
de158a476c | ||
|
ea70f2b5c2 | ||
|
1c242425b0 | ||
|
85742a190a | ||
|
b1989ffdf7 | ||
|
b2a5ded929 | ||
|
dc68f28a40 | ||
|
267ce1ec9b | ||
|
178f216317 | ||
|
c05d2d1d38 | ||
|
360abd9b90 | ||
|
093b562f58 | ||
|
0d96d71be6 | ||
|
c35e0d7336 | ||
|
2dfe1ef7b1 | ||
|
ae676e1d70 | ||
|
e2cf80e3a6 | ||
|
a824993a60 | ||
|
a6d03717cb | ||
|
cf258821b4 | ||
|
a74b6690a7 | ||
|
43b5176367 | ||
|
e50822d1d2 | ||
|
6da6b9b98f | ||
|
8ae193abe8 | ||
|
1fff2f0199 | ||
|
21286aa376 | ||
|
51f9ce890e | ||
|
6bb92c0589 | ||
|
ea71a0bb4f | ||
|
df237b5f9b | ||
|
2aa9847b24 | ||
|
263863f3f2 | ||
|
7113cef501 | ||
|
ecc9e8f5cd | ||
|
79a2735e19 | ||
|
65155a6e6a | ||
|
95ed6b51da | ||
|
63a533cd51 | ||
|
e3a9b71bb9 | ||
|
2dc1d8fed7 | ||
|
cbe74cdab4 | ||
|
3dfc3d7022 | ||
|
d3c7904e64 | ||
|
5276d7bab2 | ||
|
6185683ca3 | ||
|
2d532100eb | ||
|
40441a065a | ||
|
9929c35021 | ||
|
4e8a713819 | ||
|
d18413f63a | ||
|
0c6c71f6cb | ||
|
ed03babb08 | ||
|
e7976a544a | ||
|
f7a33d24e2 | ||
|
af27e9e5d6 | ||
|
451d68461c | ||
|
b0d389319c | ||
|
32169155bb | ||
|
f67aae086a | ||
|
274434e0d6 | ||
|
14b0c9afbe | ||
|
8060a89bf6 | ||
|
d2f1eeff98 | ||
|
71fd8b8840 | ||
|
cd745c7df3 | ||
|
25fa9484d3 | ||
|
d6ed416402 | ||
|
b7b6a41aec | ||
|
fa3e8ea74d | ||
|
45de167b6b | ||
|
d6c23f7664 | ||
|
cf26020ed6 | ||
|
3eec24b2a6 | ||
|
f1c34ea7b1 | ||
|
d759418f01 | ||
|
8a10de5fed | ||
|
86783e8758 | ||
|
2df7ded814 | ||
|
42ca8e31eb | ||
|
a8334a237b | ||
|
192cf1535b | ||
|
b5aaf4ca30 | ||
|
5cf8191cea | ||
|
e3daff7b17 | ||
|
e8b0ee874f | ||
|
2342dbe0f5 | ||
|
6ef3c089bf | ||
|
157e8c763c | ||
|
3955428f87 | ||
|
9387f50f77 | ||
|
5ffcd21eee | ||
|
0fc22b2b2d | ||
|
b7a7936dd6 | ||
|
30da6dc508 | ||
|
5e3a49ade5 | ||
|
ba0a579371 | ||
|
b7a48e1d78 | ||
|
2c6d11f95e | ||
|
23c733ef94 | ||
|
f03f242e4a | ||
|
f36401438f | ||
|
47fff7f998 | ||
|
0aad0d379a | ||
|
a144793753 | ||
|
f80d46dc94 | ||
|
045640303f | ||
|
f32d62def8 | ||
|
f15cc663ae | ||
|
33a6189f7a | ||
|
e01291ec4a | ||
|
b006cb9846 | ||
|
a7a072e3f8 | ||
|
52b3e0688a | ||
|
c0694d3c0e | ||
|
f7f5665588 | ||
|
89d6408587 | ||
|
54eea09a9e | ||
|
8c2ecc2a88 | ||
|
f055ccf5ba | ||
|
6d97ea01b2 | ||
|
0251b7c820 | ||
|
77e17743f7 | ||
|
65bab3858a | ||
|
9a72ecb61c | ||
|
9aff9cb48e | ||
|
07be682b88 | ||
|
fa52fea59b | ||
|
a78bdee941 | ||
|
4bad7a3074 | ||
|
83162477ec | ||
|
c4a87cfe4d | ||
|
8f415ceab6 | ||
|
b2620c861a | ||
|
5e7761bef1 | ||
|
1e200ed048 | ||
|
c9ce93a22f | ||
|
9756d3d84f | ||
|
4c5db612f0 | ||
|
3b42d02cfc | ||
|
80166cddd0 | ||
|
be298f78cb | ||
|
bb88becc2b | ||
|
58c4e0ddf7 | ||
|
2970913d55 | ||
|
fc86878922 | ||
|
b4e0590a10 | ||
|
a8824b46a8 | ||
|
9ea1afedcc | ||
|
087349a3e5 | ||
|
8966b5292b | ||
|
2bcbb2d01c | ||
|
4297ef2f97 | ||
|
883f9e5049 | ||
|
1f724cc336 | ||
|
77bd2250b0 | ||
|
1d736bcf79 | ||
|
d1196ea667 | ||
|
71aa11404c | ||
|
4a18c23e2d | ||
|
0d27dc2336 | ||
|
87014016a2 | ||
|
57c40bc052 | ||
|
9e80c27002 | ||
|
0e76a6edb5 | ||
|
a37758a165 | ||
|
36e34426bb | ||
|
7a0e3aaf11 | ||
|
c7f6de472f | ||
|
52281a5e32 | ||
|
72e73784fb | ||
|
b5f8a0ecdb | ||
|
a5826b75e0 | ||
|
875a45837a | ||
|
891d6fd0ba | ||
|
55107e0913 | ||
|
897b502b0f | ||
|
cbf0760adf | ||
|
58fcc8f66d | ||
|
011dfb305c | ||
|
fc4cc3255d | ||
|
f487a6332b | ||
|
0247082e19 | ||
|
80d6f020ed | ||
|
c7c95c5a85 | ||
|
1948ab21f7 | ||
|
ca3a286cc4 | ||
|
ab5070328d | ||
|
23522ed314 | ||
|
b4d5013679 | ||
|
5ef2cf23b3 | ||
|
4b94b6f678 | ||
|
8ee0c9e7be | ||
|
19725473d7 | ||
|
aed135a7c0 | ||
|
928bbed09b | ||
|
626d7b2282 | ||
|
bdf025a532 | ||
|
a9870bbcde | ||
|
15ceee4b1a | ||
|
0547f09bf0 | ||
|
e20d52d23c | ||
|
05c624bc34 | ||
|
5a42db3256 | ||
|
e2e7b58b3a | ||
|
22c01b22c1 | ||
|
085e5d1988 | ||
|
6f89d38b78 | ||
|
4707c7e2fc | ||
|
115fc08904 | ||
|
c0a05f5d13 | ||
|
042c4b2b9d | ||
|
f80283422f | ||
|
972995d124 | ||
|
0d5e9ef85f | ||
|
87d77a6882 | ||
|
c1c8769742 | ||
|
271ab2e109 | ||
|
583620e607 | ||
|
6dd2cac3ec | ||
|
6aed2d8284 | ||
|
84f471ce5c | ||
|
deb070389f | ||
|
f7f148a6ca | ||
|
a5a6f33578 | ||
|
d74a0edb82 | ||
|
396cd1c727 | ||
|
31fcc5e126 | ||
|
22172f3b0e | ||
|
b68935e917 | ||
|
e512a8e74f | ||
|
48572e4c96 | ||
|
1d1ae1c906 | ||
|
586467540b | ||
|
37dc1a6a76 | ||
|
15162a734d | ||
|
ec77ec299d | ||
|
ea8369eff0 | ||
|
096759435a | ||
|
894ea4ba62 | ||
|
d6b61f1f54 | ||
|
e779f115ef | ||
|
428044abe2 | ||
|
bd1c2a11d7 | ||
|
0c4c202998 | ||
|
8419116cae | ||
|
8a0f513094 | ||
|
1667b11564 | ||
|
b29d89bd6a | ||
|
211a5e5bda | ||
|
2ed14de41f | ||
|
d826962eaa | ||
|
962ef91e25 | ||
|
ed62f9b12b | ||
|
973282e471 | ||
|
7bad2864d9 | ||
|
1237746549 | ||
|
7254bb74a4 | ||
|
3af2091b28 | ||
|
621a0a15a3 | ||
|
c34b0f90d7 | ||
|
e098770ba2 | ||
|
7c45a564a1 | ||
|
da388c93eb | ||
|
d609bd1ab1 | ||
|
15f4368fe6 | ||
|
3901084cc2 | ||
|
a5580718f7 | ||
|
065a388632 | ||
|
71a6b26b4f | ||
|
0a49c5f71e | ||
|
0eb2ced072 | ||
|
9a6807f862 | ||
|
468724075e | ||
|
3523ba564a | ||
|
1629ea32f7 | ||
|
17938cdb7e | ||
|
86426aa87b | ||
|
a61ce111a5 | ||
|
11c2fd9e3d | ||
|
b6be7cdd56 | ||
|
caef91d261 | ||
|
72aefbf191 | ||
|
747771ac5e | ||
|
5f413e7b4d | ||
|
2ebdc43bbe | ||
|
536325e0ba | ||
|
cbcd4f6acd | ||
|
9570b29a0a | ||
|
166852254f | ||
|
f8be5fdd2a | ||
|
652113c46d | ||
|
ada48d9021 | ||
|
7112217adc | ||
|
87a2f776b7 | ||
|
73811b45b1 | ||
|
88cac9b0fa | ||
|
d13f108779 | ||
|
57fb334a6e | ||
|
7fb5d4f47a | ||
|
88c673de51 | ||
|
51258662b5 | ||
|
d6916c35bc | ||
|
8634b6c3ac | ||
|
e5e21eef20 | ||
|
057c85b710 | ||
|
241a24564a | ||
|
cd3980eca4 | ||
|
c2744a1846 | ||
|
8d0dcb774f | ||
|
b5a2a4e52d | ||
|
887e1c04ef | ||
|
4db41c2111 | ||
|
e4ae0c9a95 | ||
|
e5f6b77c29 | ||
|
2b5d076ff8 | ||
|
2ca1850ea9 | ||
|
9a35e3f64d | ||
|
34a5eb7512 | ||
|
fdba5d4cb7 | ||
|
ced142da92 | ||
|
71ef86078c | ||
|
e5ad1cd214 | ||
|
9f85e51934 | ||
|
569ed4559f | ||
|
5354a5f786 | ||
|
c691917172 | ||
|
73bb17009e | ||
|
3f63700e99 | ||
|
51d73e37df | ||
|
a49a900a7b | ||
|
01ea2ad08c | ||
|
8cb1838c4a | ||
|
2892e19c43 | ||
|
0e19b1dd75 | ||
|
f800f63ee5 | ||
|
5776eea1b0 | ||
|
5f92d520ee | ||
|
9bf6a15ff5 | ||
|
c5a1ca7c3e | ||
|
59edf4750b | ||
|
7a9c2d5e88 | ||
|
981ca957c1 | ||
|
8b62f02523 | ||
|
c298210844 | ||
|
f80c7b2355 | ||
|
124ada8d14 | ||
|
95312139d5 | ||
|
8bbb46b52c | ||
|
918a6352e4 | ||
|
5b18edf938 | ||
|
888415059c | ||
|
1e0bdcc270 | ||
|
97717e6fce | ||
|
990096ff9b | ||
|
82307d4e6b | ||
|
61e2117e9d | ||
|
b0e9df0139 | ||
|
f0cee09b7c | ||
|
6e9d15f91d | ||
|
62d1cdcdac | ||
|
fd358396fc | ||
|
24468fd965 | ||
|
c8fe596fc4 | ||
|
c50d8195bb | ||
|
7670afcba1 | ||
|
dc3264a3a5 | ||
|
1bb3198b71 | ||
|
d400c0959c | ||
|
ec2c031792 | ||
|
3a98b945a8 | ||
|
a6676fd6f3 | ||
|
73bb281f34 | ||
|
f891a7c3b3 | ||
|
614ca25d3b | ||
|
74018162c7 | ||
|
3e3dfac4e0 | ||
|
dad22cb672 | ||
|
cf7e276a6a | ||
|
72cbf61b43 | ||
|
fc850cfe69 | ||
|
ac9505b536 | ||
|
89426af94a | ||
|
a3e19f9bb7 | ||
|
dd16c87080 | ||
|
b997386cd3 | ||
|
7df74664e4 | ||
|
3793ff8be8 | ||
|
5d5595cc5b | ||
|
8b911ce3eb | ||
|
0254feefe3 | ||
|
07cc2a72bb | ||
|
835ad09657 | ||
|
cd53cbbea2 | ||
|
5b788baa35 | ||
|
04689334c5 | ||
|
d71e4ec9f0 | ||
|
6ede5635b3 | ||
|
602a429a68 | ||
|
3b05ec0ab1 | ||
|
1a9e29844b | ||
|
ad8f6e5eb6 | ||
|
63e3b8f41b | ||
|
19793c21b4 | ||
|
86d56a0b1a | ||
|
782c274d86 | ||
|
d2610973dd | ||
|
3405dbab6d | ||
|
5626d925e3 | ||
|
c1960635d2 | ||
|
eaf9488ba0 | ||
|
cfa1ad0b33 | ||
|
0f9be64904 | ||
|
7d2dd3422d | ||
|
a645ec0910 | ||
|
3b50bcfb3a | ||
|
84c497b1fb | ||
|
33553c0cf7 | ||
|
e345fca99a | ||
|
88fe079f95 | ||
|
40cba7962c | ||
|
3ef2084f80 |
1113 changed files with 62015 additions and 17791 deletions
28
.clang-tidy
28
.clang-tidy
|
@ -1,18 +1,22 @@
|
||||||
Checks: >
|
Checks: >
|
||||||
-*,
|
-*,
|
||||||
boost-*,
|
|
||||||
portability-*,
|
portability-*,
|
||||||
|
-portability-template-virtual-member-function,
|
||||||
clang-analyzer-*,
|
clang-analyzer-*,
|
||||||
-clang-analyzer-optin*,
|
-clang-analyzer-optin.*,
|
||||||
-clang-analyzer-cplusplus.NewDeleteLeaks,
|
-clang-analyzer-cplusplus.NewDeleteLeaks,
|
||||||
|
-clang-analyzer-cplusplus.NewDelete,
|
||||||
-clang-analyzer-core.CallAndMessage,
|
-clang-analyzer-core.CallAndMessage,
|
||||||
-modernize-avoid-bind
|
modernize-avoid-bind,
|
||||||
WarningsAsErrors: >
|
readability-identifier-naming
|
||||||
-*,
|
WarningsAsErrors: '*'
|
||||||
boost-*,
|
HeaderFilterRegex: '(apps|components)/'
|
||||||
portability-*,
|
CheckOptions:
|
||||||
clang-analyzer-*,
|
- key: readability-identifier-naming.ConceptCase
|
||||||
-clang-analyzer-optin*,
|
value: CamelCase
|
||||||
-clang-analyzer-cplusplus.NewDeleteLeaks,
|
- key: readability-identifier-naming.NamespaceCase
|
||||||
-clang-analyzer-core.CallAndMessage
|
value: CamelCase
|
||||||
HeaderFilterRegex: '^(apps|components)'
|
- key: readability-identifier-naming.NamespaceIgnoredRegexp
|
||||||
|
value: 'bpo|osg(DB|FX|Particle|Shadow|Viewer|Util)?'
|
||||||
|
- key: readability-identifier-naming.LocalVariableCase
|
||||||
|
value: camelBack
|
||||||
|
|
9
.github/workflows/push.yml
vendored
9
.github/workflows/push.yml
vendored
|
@ -73,7 +73,7 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Building Dependencies
|
- name: Install Building Dependencies
|
||||||
run: CI/before_install.osx.sh
|
run: CI/before_install.macos.sh
|
||||||
|
|
||||||
- name: Prime ccache
|
- name: Prime ccache
|
||||||
uses: hendrikmuhs/ccache-action@v1
|
uses: hendrikmuhs/ccache-action@v1
|
||||||
|
@ -82,11 +82,9 @@ jobs:
|
||||||
max-size: 1000M
|
max-size: 1000M
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: CI/before_script.osx.sh
|
run: CI/before_script.macos.sh
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: CI/macos/build.sh
|
||||||
cd build
|
|
||||||
make -j $(sysctl -n hw.logicalcpu) package
|
|
||||||
|
|
||||||
Output-Envs:
|
Output-Envs:
|
||||||
name: Read .env file and expose it as output
|
name: Read .env file and expose it as output
|
||||||
|
@ -106,7 +104,6 @@ jobs:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
image:
|
image:
|
||||||
- "2019"
|
|
||||||
- "2022"
|
- "2022"
|
||||||
|
|
||||||
uses: ./.github/workflows/windows.yml
|
uses: ./.github/workflows/windows.yml
|
||||||
|
|
30
.github/workflows/windows.yml
vendored
30
.github/workflows/windows.yml
vendored
|
@ -4,9 +4,13 @@ on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
image:
|
image:
|
||||||
description: MSVC image (2019/2022)
|
description: Window Server image
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
msvc:
|
||||||
|
description: MSVC version (2019/2022)
|
||||||
|
default: "2022"
|
||||||
|
type: string
|
||||||
vcpkg-deps-tag:
|
vcpkg-deps-tag:
|
||||||
description: Git tag of our deps
|
description: Git tag of our deps
|
||||||
required: true
|
required: true
|
||||||
|
@ -45,7 +49,7 @@ jobs:
|
||||||
- name: Download prebuilt vcpkg packages
|
- name: Download prebuilt vcpkg packages
|
||||||
working-directory: ${{ github.workspace }}/deps
|
working-directory: ${{ github.workspace }}/deps
|
||||||
run: |
|
run: |
|
||||||
$MANIFEST = "vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}.txt"
|
$MANIFEST = "vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}.txt"
|
||||||
curl --fail --retry 3 -L -o "$MANIFEST" "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/$MANIFEST"
|
curl --fail --retry 3 -L -o "$MANIFEST" "https://gitlab.com/OpenMW/openmw-deps/-/raw/main/windows/$MANIFEST"
|
||||||
$lines = Get-Content "$MANIFEST"
|
$lines = Get-Content "$MANIFEST"
|
||||||
$URL = $lines[0]
|
$URL = $lines[0]
|
||||||
|
@ -61,7 +65,7 @@ jobs:
|
||||||
|
|
||||||
- name: Extract archived prebuilt vcpkg packages
|
- name: Extract archived prebuilt vcpkg packages
|
||||||
working-directory: ${{ github.workspace }}/deps
|
working-directory: ${{ github.workspace }}/deps
|
||||||
run: 7z x -y -ovcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }} $env:archive
|
run: 7z x -y -ovcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }} $env:archive
|
||||||
|
|
||||||
- name: Cache Qt
|
- name: Cache Qt
|
||||||
id: qt-cache
|
id: qt-cache
|
||||||
|
@ -94,12 +98,12 @@ jobs:
|
||||||
-B ${{ github.workspace }}/build
|
-B ${{ github.workspace }}/build
|
||||||
-G Ninja
|
-G Ninja
|
||||||
-D CMAKE_BUILD_TYPE=${{ inputs.build-type }}
|
-D CMAKE_BUILD_TYPE=${{ inputs.build-type }}
|
||||||
-D CMAKE_TOOLCHAIN_FILE='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/scripts/buildsystems/vcpkg.cmake'
|
-D CMAKE_TOOLCHAIN_FILE='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/scripts/buildsystems/vcpkg.cmake'
|
||||||
-D CMAKE_PREFIX_PATH='${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64'
|
-D CMAKE_PREFIX_PATH='${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64'
|
||||||
${{ inputs.package && '-D CMAKE_CXX_FLAGS_RELEASE="/O2 /Ob2 /DNDEBUG /Zi"' || '' }}
|
${{ inputs.package && '-D CMAKE_CXX_FLAGS_RELEASE="/O2 /Ob2 /DNDEBUG /Zi"' || '' }}
|
||||||
${{ inputs.package && '-D "CMAKE_EXE_LINKER_FLAGS_RELEASE=/DEBUG /INCREMENTAL:NO"' || '' }}
|
${{ inputs.package && '-D "CMAKE_EXE_LINKER_FLAGS_RELEASE=/DEBUG /INCREMENTAL:NO"' || '' }}
|
||||||
-D LuaJit_INCLUDE_DIR='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/include/luajit'
|
-D LuaJit_INCLUDE_DIR='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/include/luajit'
|
||||||
-D LuaJit_LIBRARY='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/lib/lua51.lib'
|
-D LuaJit_LIBRARY='${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/lib/lua51.lib'
|
||||||
-D BUILD_BENCHMARKS=${{ ! inputs.package }}
|
-D BUILD_BENCHMARKS=${{ ! inputs.package }}
|
||||||
-D BUILD_COMPONENTS_TESTS=${{ ! inputs.package }}
|
-D BUILD_COMPONENTS_TESTS=${{ ! inputs.package }}
|
||||||
-D BUILD_OPENMW_TESTS=${{ ! inputs.package }}
|
-D BUILD_OPENMW_TESTS=${{ ! inputs.package }}
|
||||||
|
@ -114,9 +118,9 @@ jobs:
|
||||||
|
|
||||||
- name: Copy missing DLLs
|
- name: Copy missing DLLs
|
||||||
run: |
|
run: |
|
||||||
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/Release/MyGUIEngine.dll ${{ github.workspace }}/build
|
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/Release/MyGUIEngine.dll ${{ github.workspace }}/build
|
||||||
cp -Filter *.dll -Recurse ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/osgPlugins-3.6.5 ${{ github.workspace }}/build
|
cp -Filter *.dll -Recurse ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/osgPlugins-3.6.5 ${{ github.workspace }}/build
|
||||||
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.image }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/*.dll ${{ github.workspace }}/build
|
cp ${{ github.workspace }}/deps/vcpkg-x64-${{ inputs.msvc }}-${{ inputs.vcpkg-deps-tag }}/installed/x64-windows/bin/*.dll ${{ github.workspace }}/build
|
||||||
|
|
||||||
- name: Copy Qt DLLs
|
- name: Copy Qt DLLs
|
||||||
working-directory: ${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64
|
working-directory: ${{ github.workspace }}/deps/Qt/6.6.3/msvc2019_64
|
||||||
|
@ -172,7 +176,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
job_url=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json jobs --jq '.jobs[] | select(.name == "windows-${{ inputs.image }}") | .url')
|
job_url=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json jobs --jq '.jobs[] | select(.name == "windows-${{ inputs.msvc }}") | .url')
|
||||||
printf "Ref ${{ github.ref }}\nJob ${job_url}\nCommit ${{ github.sha }}\n" > install/CI-ID.txt
|
printf "Ref ${{ github.ref }}\nJob ${job_url}\nCommit ${{ github.sha }}\n" > install/CI-ID.txt
|
||||||
cp install/CI-ID.txt pdb/CI-ID.txt
|
cp install/CI-ID.txt pdb/CI-ID.txt
|
||||||
cp install/CI-ID.txt SymStore/CI-ID.txt
|
cp install/CI-ID.txt SymStore/CI-ID.txt
|
||||||
|
@ -180,19 +184,19 @@ jobs:
|
||||||
- name: Store OpenMW archived pdb files
|
- name: Store OpenMW archived pdb files
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: openmw-windows-${{ inputs.image }}-pdb-${{ github.sha }}
|
name: openmw-windows-${{ inputs.msvc }}-pdb-${{ github.sha }}
|
||||||
path: ${{ github.workspace }}/pdb/*
|
path: ${{ github.workspace }}/pdb/*
|
||||||
|
|
||||||
- name: Store OpenMW build artifacts
|
- name: Store OpenMW build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: openmw-windows-${{ inputs.image }}-${{ github.sha }}
|
name: openmw-windows-${{ inputs.msvc }}-${{ github.sha }}
|
||||||
path: ${{ github.workspace }}/install/*
|
path: ${{ github.workspace }}/install/*
|
||||||
|
|
||||||
- name: Store symbol server artifacts
|
- name: Store symbol server artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: openmw-windows-${{ inputs.image }}-sym-store-${{ github.sha }}
|
name: openmw-windows-${{ inputs.msvc }}-sym-store-${{ github.sha }}
|
||||||
path: ${{ github.workspace }}/SymStore/*
|
path: ${{ github.workspace }}/SymStore/*
|
||||||
|
|
||||||
- name: Upload to symbol server
|
- name: Upload to symbol server
|
||||||
|
|
226
.gitlab-ci.yml
226
.gitlab-ci.yml
|
@ -9,6 +9,8 @@ stages:
|
||||||
- test
|
- test
|
||||||
|
|
||||||
workflow:
|
workflow:
|
||||||
|
auto_cancel:
|
||||||
|
on_new_commit: interruptible
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
||||||
|
@ -27,14 +29,14 @@ variables:
|
||||||
.Ubuntu_Image:
|
.Ubuntu_Image:
|
||||||
tags:
|
tags:
|
||||||
- saas-linux-medium-amd64
|
- saas-linux-medium-amd64
|
||||||
image: ubuntu:22.04
|
image: ubuntu:24.04
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"
|
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
|
||||||
Ubuntu_GCC_preprocess:
|
Ubuntu_GCC_preprocess:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_preprocess.ubuntu_22.04.v1
|
key: Ubuntu_GCC_preprocess.ubuntu_24.04.v1
|
||||||
paths:
|
paths:
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
- .cache/pip/
|
- .cache/pip/
|
||||||
|
@ -43,9 +45,12 @@ Ubuntu_GCC_preprocess:
|
||||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh openmw-deps openmw-deps-dynamic gcc_preprocess
|
- CI/install_debian_deps.sh openmw-deps openmw-deps-dynamic gcc_preprocess
|
||||||
- pip3 install --user click termtables
|
- pip3 install --user --break-system-packages click termtables
|
||||||
script:
|
script:
|
||||||
- CI/ubuntu_gcc_preprocess.sh
|
- CI/ubuntu_gcc_preprocess.sh
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
|
||||||
|
|
||||||
.Ubuntu:
|
.Ubuntu:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
|
@ -56,6 +61,7 @@ Ubuntu_GCC_preprocess:
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
variables:
|
||||||
CMAKE_EXE_LINKER_FLAGS: -fuse-ld=mold
|
CMAKE_EXE_LINKER_FLAGS: -fuse-ld=mold
|
||||||
|
OPENMW_CXX_FLAGS: "-Werror -Werror=implicit-fallthrough"
|
||||||
script:
|
script:
|
||||||
- df -h
|
- df -h
|
||||||
- export CCACHE_BASEDIR="`pwd`"
|
- export CCACHE_BASEDIR="`pwd`"
|
||||||
|
@ -76,9 +82,9 @@ Ubuntu_GCC_preprocess:
|
||||||
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi
|
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi
|
||||||
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_esm_refid_benchmark; fi
|
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_esm_refid_benchmark; fi
|
||||||
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_settings_access_benchmark; fi
|
- if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_settings_access_benchmark; fi
|
||||||
- ccache -s
|
- ccache -svv
|
||||||
- df -h
|
- df -h
|
||||||
- if [[ "${BUILD_WITH_CODE_COVERAGE}" ]]; then gcovr --xml-pretty --exclude-unreachable-branches --print-summary --root "${CI_PROJECT_DIR}" -j $(nproc) -o ../coverage.xml; fi
|
- if [[ "${BUILD_WITH_CODE_COVERAGE}" ]]; then ~/.local/bin/gcovr --xml-pretty --exclude-unreachable-branches --gcov-ignore-parse-errors=negative_hits.warn_once_per_file --print-summary --root "${CI_PROJECT_DIR}" -j $(nproc) -o ../coverage.xml; fi
|
||||||
- ls | grep -v -e '^extern$' -e '^install$' -e '^components-tests.xml$' -e '^openmw-tests.xml$' -e '^openmw-cs-tests.xml$' | xargs -I '{}' rm -rf './{}'
|
- ls | grep -v -e '^extern$' -e '^install$' -e '^components-tests.xml$' -e '^openmw-tests.xml$' -e '^openmw-cs-tests.xml$' | xargs -I '{}' rm -rf './{}'
|
||||||
- cd ..
|
- cd ..
|
||||||
- df -h
|
- df -h
|
||||||
|
@ -93,19 +99,20 @@ Ubuntu_GCC_preprocess:
|
||||||
Coverity:
|
Coverity:
|
||||||
tags:
|
tags:
|
||||||
- saas-linux-medium-amd64
|
- saas-linux-medium-amd64
|
||||||
image: ubuntu:22.04
|
image: ubuntu:24.04
|
||||||
stage: build
|
stage: build
|
||||||
|
interruptible: false
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||||
cache:
|
cache:
|
||||||
key: Coverity.ubuntu_22.04.v1
|
key: Coverity.ubuntu_24.04.v1
|
||||||
paths:
|
paths:
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
- ccache/
|
- ccache/
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 2G
|
CCACHE_SIZE: 2G
|
||||||
CC: clang-12
|
CC: clang
|
||||||
CXX: clang++-12
|
CXX: clang++
|
||||||
CMAKE_BUILD_TYPE: Debug
|
CMAKE_BUILD_TYPE: Debug
|
||||||
CMAKE_CXX_FLAGS_DEBUG: -O0
|
CMAKE_CXX_FLAGS_DEBUG: -O0
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -121,23 +128,40 @@ Coverity:
|
||||||
- ccache -z -M "${CCACHE_SIZE}"
|
- ccache -z -M "${CCACHE_SIZE}"
|
||||||
- CI/before_script.linux.sh
|
- CI/before_script.linux.sh
|
||||||
- cov-analysis-linux64-*/bin/cov-configure --template --comptype prefix --compiler ccache
|
- cov-analysis-linux64-*/bin/cov-configure --template --comptype prefix --compiler ccache
|
||||||
# Remove the specific targets and build everything once we can do it under 3h
|
|
||||||
- cov-analysis-linux64-*/bin/cov-build --dir cov-int cmake --build build -- -j $(nproc)
|
- cov-analysis-linux64-*/bin/cov-build --dir cov-int cmake --build build -- -j $(nproc)
|
||||||
- ccache -s
|
- ccache -svv
|
||||||
after_script:
|
|
||||||
- tar cfz cov-int.tar.gz cov-int
|
- tar cfz cov-int.tar.gz cov-int
|
||||||
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
|
- echo "OPENMW_JOB_ID=$CI_JOB_ID" >> build.env
|
||||||
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
|
||||||
--form file=@cov-int.tar.gz --form version="$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA"
|
|
||||||
--form description="CI_COMMIT_SHORT_SHA / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
|
||||||
artifacts:
|
artifacts:
|
||||||
|
expire_in: 1 day
|
||||||
paths:
|
paths:
|
||||||
- /builds/OpenMW/openmw/cov-int/build-log.txt
|
- /builds/OpenMW/openmw/cov-int/build-log.txt
|
||||||
|
- /builds/OpenMW/openmw/cov-int.tar.gz
|
||||||
|
reports:
|
||||||
|
dotenv: build.env
|
||||||
|
|
||||||
|
Coverity_Upload:
|
||||||
|
image: ubuntu:24.04
|
||||||
|
stage: build
|
||||||
|
interruptible: false
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
before_script:
|
||||||
|
- CI/install_debian_deps.sh coverity_upload
|
||||||
|
script:
|
||||||
|
- echo "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$OPENMW_JOB_ID/artifacts/cov-int.tar.gz"
|
||||||
|
- curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
|
||||||
|
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
||||||
|
--form version="$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA"
|
||||||
|
--form description="CI_COMMIT_SHORT_SHA / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
||||||
|
--form url="$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/$OPENMW_JOB_ID/artifacts/cov-int.tar.gz"
|
||||||
|
needs:
|
||||||
|
- Coverity
|
||||||
|
|
||||||
Ubuntu_GCC:
|
Ubuntu_GCC:
|
||||||
extends: .Ubuntu
|
extends: .Ubuntu
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC.ubuntu_22.04.v1
|
key: Ubuntu_GCC.ubuntu_24.04.v1
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
|
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
|
||||||
variables:
|
variables:
|
||||||
|
@ -150,18 +174,20 @@ Ubuntu_GCC:
|
||||||
Ubuntu_GCC_asan:
|
Ubuntu_GCC_asan:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_asan.ubuntu_22.04.v1
|
key: Ubuntu_GCC_asan.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CMAKE_BUILD_TYPE: Debug
|
CMAKE_BUILD_TYPE: Debug
|
||||||
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
|
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
|
||||||
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
|
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
|
||||||
BUILD_OPENMW_ONLY: 1
|
BUILD_OPENMW_ONLY: 1
|
||||||
|
# Disable -Werror due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
|
||||||
|
OPENMW_CXX_FLAGS: ""
|
||||||
|
|
||||||
Clang_Format:
|
Clang_Format:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
stage: checks
|
stage: checks
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang_Format.ubuntu_22.04.v1
|
key: Ubuntu_Clang_Format.ubuntu_24.04.v1
|
||||||
paths:
|
paths:
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
variables:
|
variables:
|
||||||
|
@ -177,11 +203,11 @@ Lupdate:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
stage: checks
|
stage: checks
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_lupdate.ubuntu_22.04.v1
|
key: Ubuntu_lupdate.ubuntu_24.04.v1
|
||||||
paths:
|
paths:
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
variables:
|
variables:
|
||||||
LUPDATE: lupdate
|
LUPDATE: /usr/lib/qt6/bin/lupdate
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh openmw-qt-translations
|
- CI/install_debian_deps.sh openmw-qt-translations
|
||||||
script:
|
script:
|
||||||
|
@ -203,7 +229,7 @@ Teal:
|
||||||
Ubuntu_GCC_Debug:
|
Ubuntu_GCC_Debug:
|
||||||
extends: .Ubuntu
|
extends: .Ubuntu
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_Debug.ubuntu_22.04.v2
|
key: Ubuntu_GCC_Debug.ubuntu_24.04.v2
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
|
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic
|
||||||
variables:
|
variables:
|
||||||
|
@ -219,7 +245,7 @@ Ubuntu_GCC_Debug:
|
||||||
Ubuntu_GCC_tests:
|
Ubuntu_GCC_tests:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -228,12 +254,12 @@ Ubuntu_GCC_tests:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
.Ubuntu_GCC_tests_Debug:
|
.Ubuntu_GCC_tests_Debug:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests_Debug.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests_Debug.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -244,12 +270,12 @@ Ubuntu_GCC_tests:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
Ubuntu_GCC_tests_asan:
|
Ubuntu_GCC_tests_asan:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests_asan.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests_asan.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -257,17 +283,22 @@ Ubuntu_GCC_tests_asan:
|
||||||
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
|
CMAKE_CXX_FLAGS_DEBUG: -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak
|
||||||
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
|
CMAKE_EXE_LINKER_FLAGS: -fsanitize=address -fsanitize=pointer-subtract -fsanitize=leak -fuse-ld=mold
|
||||||
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
|
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
|
||||||
|
# Disable -Werror due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
|
||||||
|
OPENMW_CXX_FLAGS: ""
|
||||||
artifacts:
|
artifacts:
|
||||||
paths: []
|
paths: []
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
|
||||||
|
|
||||||
Ubuntu_GCC_tests_ubsan:
|
Ubuntu_GCC_tests_ubsan:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests_ubsan.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests_ubsan.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -279,12 +310,15 @@ Ubuntu_GCC_tests_ubsan:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
|
||||||
|
|
||||||
.Ubuntu_GCC_tests_tsan:
|
.Ubuntu_GCC_tests_tsan:
|
||||||
extends: Ubuntu_GCC
|
extends: Ubuntu_GCC
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests_tsan.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests_tsan.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -297,16 +331,20 @@ Ubuntu_GCC_tests_ubsan:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
Ubuntu_GCC_tests_coverage:
|
Ubuntu_GCC_tests_coverage:
|
||||||
extends: .Ubuntu_GCC_tests_Debug
|
extends: .Ubuntu_GCC_tests_Debug
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_tests_coverage.ubuntu_22.04.v1
|
key: Ubuntu_GCC_tests_coverage.ubuntu_24.04.v1
|
||||||
|
paths:
|
||||||
|
- .cache/pip
|
||||||
variables:
|
variables:
|
||||||
BUILD_WITH_CODE_COVERAGE: 1
|
BUILD_WITH_CODE_COVERAGE: 1
|
||||||
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic openmw-coverage
|
- CI/install_debian_deps.sh gcc openmw-deps openmw-deps-dynamic openmw-coverage
|
||||||
|
- pipx install gcovr
|
||||||
coverage: /^\s*lines:\s*\d+.\d+\%/
|
coverage: /^\s*lines:\s*\d+.\d+\%/
|
||||||
artifacts:
|
artifacts:
|
||||||
paths: []
|
paths: []
|
||||||
|
@ -316,7 +354,10 @@ Ubuntu_GCC_tests_coverage:
|
||||||
coverage_report:
|
coverage_report:
|
||||||
coverage_format: cobertura
|
coverage_format: cobertura
|
||||||
path: coverage.xml
|
path: coverage.xml
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
|
||||||
|
|
||||||
.Ubuntu_Static_Deps:
|
.Ubuntu_Static_Deps:
|
||||||
extends: Ubuntu_Clang
|
extends: Ubuntu_Clang
|
||||||
|
@ -328,7 +369,7 @@ Ubuntu_GCC_tests_coverage:
|
||||||
- "CI/**/*"
|
- "CI/**/*"
|
||||||
- ".gitlab-ci.yml"
|
- ".gitlab-ci.yml"
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Static_Deps.ubuntu_22.04.v1
|
key: Ubuntu_Static_Deps.ubuntu_24.04.v1
|
||||||
paths:
|
paths:
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
- ccache/
|
- ccache/
|
||||||
|
@ -345,7 +386,7 @@ Ubuntu_GCC_tests_coverage:
|
||||||
.Ubuntu_Static_Deps_tests:
|
.Ubuntu_Static_Deps_tests:
|
||||||
extends: .Ubuntu_Static_Deps
|
extends: .Ubuntu_Static_Deps
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Static_Deps_tests.ubuntu_22.04.v1
|
key: Ubuntu_Static_Deps_tests.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -357,14 +398,14 @@ Ubuntu_GCC_tests_coverage:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
Ubuntu_Clang:
|
Ubuntu_Clang:
|
||||||
extends: .Ubuntu
|
extends: .Ubuntu
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic
|
- CI/install_debian_deps.sh clang openmw-deps openmw-deps-dynamic
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang.ubuntu_22.04.v2
|
key: Ubuntu_Clang.ubuntu_24.04.v2
|
||||||
variables:
|
variables:
|
||||||
CC: clang
|
CC: clang
|
||||||
CXX: clang++
|
CXX: clang++
|
||||||
|
@ -377,7 +418,7 @@ Ubuntu_Clang:
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic
|
- CI/install_debian_deps.sh clang clang-tidy openmw-deps openmw-deps-dynamic
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang_Tidy.ubuntu_22.04.v1
|
key: Ubuntu_Clang_Tidy.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CMAKE_BUILD_TYPE: Debug
|
CMAKE_BUILD_TYPE: Debug
|
||||||
CMAKE_CXX_FLAGS_DEBUG: -O0
|
CMAKE_CXX_FLAGS_DEBUG: -O0
|
||||||
|
@ -388,15 +429,19 @@ Ubuntu_Clang:
|
||||||
- mkdir -pv "${CCACHE_DIR}"
|
- mkdir -pv "${CCACHE_DIR}"
|
||||||
- ccache -z -M "${CCACHE_SIZE}"
|
- ccache -z -M "${CCACHE_SIZE}"
|
||||||
- CI/before_script.linux.sh
|
- CI/before_script.linux.sh
|
||||||
|
- cp extern/.clang-tidy build/.clang-tidy
|
||||||
- cd build
|
- cd build
|
||||||
- find . -name *.o -exec touch {} \;
|
- find . -name *.o -exec touch {} \;
|
||||||
- cmake --build . -- -j $(nproc) ${BUILD_TARGETS}
|
- cmake --build . -- -j $(nproc) ${BUILD_TARGETS}
|
||||||
- ccache -s
|
- ccache -svv
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- build/
|
- build/
|
||||||
expire_in: 12h
|
expire_in: 12h
|
||||||
timeout: 3h
|
timeout: 3h
|
||||||
|
rules:
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ID != "7107382"
|
||||||
|
|
||||||
Ubuntu_Clang_Tidy_components:
|
Ubuntu_Clang_Tidy_components:
|
||||||
extends: .Ubuntu_Clang_Tidy_Base
|
extends: .Ubuntu_Clang_Tidy_Base
|
||||||
|
@ -409,7 +454,7 @@ Ubuntu_Clang_Tidy_openmw:
|
||||||
needs:
|
needs:
|
||||||
- Ubuntu_Clang_Tidy_components
|
- Ubuntu_Clang_Tidy_components
|
||||||
variables:
|
variables:
|
||||||
BUILD_TARGETS: openmw
|
BUILD_TARGETS: openmw openmw-tests
|
||||||
timeout: 3h
|
timeout: 3h
|
||||||
|
|
||||||
Ubuntu_Clang_Tidy_openmw-cs:
|
Ubuntu_Clang_Tidy_openmw-cs:
|
||||||
|
@ -425,13 +470,13 @@ Ubuntu_Clang_Tidy_other:
|
||||||
needs:
|
needs:
|
||||||
- Ubuntu_Clang_Tidy_components
|
- Ubuntu_Clang_Tidy_components
|
||||||
variables:
|
variables:
|
||||||
BUILD_TARGETS: bsatool esmtool openmw-launcher openmw-iniimporter openmw-essimporter openmw-wizard niftest components-tests openmw-tests openmw-cs-tests openmw-navmeshtool openmw-bulletobjecttool
|
BUILD_TARGETS: components-tests bsatool esmtool openmw-launcher openmw-iniimporter openmw-essimporter openmw-wizard niftest openmw-navmeshtool openmw-bulletobjecttool
|
||||||
timeout: 3h
|
timeout: 3h
|
||||||
|
|
||||||
.Ubuntu_Clang_tests:
|
.Ubuntu_Clang_tests:
|
||||||
extends: Ubuntu_Clang
|
extends: Ubuntu_Clang
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang_tests.ubuntu_22.04.v1
|
key: Ubuntu_Clang_tests.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -440,12 +485,12 @@ Ubuntu_Clang_Tidy_other:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
Ubuntu_Clang_tests_Debug:
|
Ubuntu_Clang_tests_Debug:
|
||||||
extends: Ubuntu_Clang
|
extends: Ubuntu_Clang
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang_tests_Debug.ubuntu_22.04.v1
|
key: Ubuntu_Clang_tests_Debug.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 1G
|
CCACHE_SIZE: 1G
|
||||||
BUILD_TESTS_ONLY: 1
|
BUILD_TESTS_ONLY: 1
|
||||||
|
@ -455,21 +500,21 @@ Ubuntu_Clang_tests_Debug:
|
||||||
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
|
||||||
when: always
|
when: always
|
||||||
reports:
|
reports:
|
||||||
junit: build/*_tests.xml
|
junit: build/*-tests.xml
|
||||||
|
|
||||||
.Ubuntu_integration_tests_base:
|
.Ubuntu_integration_tests_base:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
stage: test
|
stage: test
|
||||||
variables:
|
variables:
|
||||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||||
EXAMPLE_SUITE_REVISION: f51b832e033429a7cdc520e0e48d7dfdb9141caa
|
EXAMPLE_SUITE_REVISION: 3e01d10e073474a886a9efe3658088db14869627
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- .cache/pip
|
- .cache/pip
|
||||||
- apt-cache/
|
- apt-cache/
|
||||||
before_script:
|
before_script:
|
||||||
- CI/install_debian_deps.sh $OPENMW_DEPS
|
- CI/install_debian_deps.sh $OPENMW_DEPS
|
||||||
- pip3 install --user numpy matplotlib termtables click
|
- pip3 install --user --break-system-packages numpy matplotlib termtables click
|
||||||
script:
|
script:
|
||||||
- CI/run_integration_tests.sh
|
- CI/run_integration_tests.sh
|
||||||
after_script:
|
after_script:
|
||||||
|
@ -480,7 +525,7 @@ Ubuntu_Clang_integration_tests:
|
||||||
needs:
|
needs:
|
||||||
- Ubuntu_Clang
|
- Ubuntu_Clang
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_Clang_integration_tests.ubuntu_22.04.v2
|
key: Ubuntu_Clang_integration_tests.ubuntu_24.04.v2
|
||||||
variables:
|
variables:
|
||||||
OPENMW_DEPS: openmw-integration-tests
|
OPENMW_DEPS: openmw-integration-tests
|
||||||
|
|
||||||
|
@ -489,27 +534,35 @@ Ubuntu_GCC_integration_tests_asan:
|
||||||
needs:
|
needs:
|
||||||
- Ubuntu_GCC_asan
|
- Ubuntu_GCC_asan
|
||||||
cache:
|
cache:
|
||||||
key: Ubuntu_GCC_integration_tests_asan.ubuntu_22.04.v1
|
key: Ubuntu_GCC_integration_tests_asan.ubuntu_24.04.v1
|
||||||
variables:
|
variables:
|
||||||
OPENMW_DEPS: openmw-integration-tests libasan6
|
OPENMW_DEPS: openmw-integration-tests libasan
|
||||||
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0
|
ASAN_OPTIONS: halt_on_error=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_leaks=0
|
||||||
|
|
||||||
.MacOS:
|
.MacOS:
|
||||||
stage: build
|
stage: build
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PROJECT_ID == "7107382"
|
- if: $CI_PROJECT_ID != "7107382"
|
||||||
|
when: never
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||||
|
when: manual
|
||||||
|
- if: $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "schedule"
|
||||||
|
image: macos-15-xcode-16
|
||||||
|
tags:
|
||||||
|
- saas-macos-medium-m1
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- ccache/
|
- ccache/
|
||||||
script:
|
script:
|
||||||
- CI/before_install.osx.sh
|
- CI/before_install.macos.sh
|
||||||
- export CCACHE_BASEDIR="$(pwd)"
|
- export CCACHE_BASEDIR="$(pwd)"
|
||||||
- export CCACHE_DIR="$(pwd)/ccache"
|
- export CCACHE_DIR="$(pwd)/ccache"
|
||||||
- mkdir -pv "${CCACHE_DIR}"
|
- mkdir -pv "${CCACHE_DIR}"
|
||||||
- ccache -z -M "${CCACHE_SIZE}"
|
- CI/macos/ccache_prep.sh
|
||||||
- CI/before_script.osx.sh
|
- CI/before_script.macos.sh
|
||||||
- cd build; make -j $(sysctl -n hw.logicalcpu) package
|
- CI/macos/build.sh
|
||||||
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${CI_COMMIT_REF_NAME##*/}.dmg"; done
|
- cd build
|
||||||
|
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${DMG_IDENTIFIER}_${CI_COMMIT_REF_NAME##*/}.dmg"; done
|
||||||
- |
|
- |
|
||||||
if [[ -n "${AWS_ACCESS_KEY_ID}" ]]; then
|
if [[ -n "${AWS_ACCESS_KEY_ID}" ]]; then
|
||||||
echo "[default]" > ~/.s3cfg
|
echo "[default]" > ~/.s3cfg
|
||||||
|
@ -524,20 +577,33 @@ Ubuntu_GCC_integration_tests_asan:
|
||||||
s3cmd put "${dmg}" s3://openmw-artifacts/${artifactDirectory}
|
s3cmd put "${dmg}" s3://openmw-artifacts/${artifactDirectory}
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
- ccache -s
|
- ../CI/macos/ccache_save.sh
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- build/OpenMW-*.dmg
|
- build/OpenMW-*.dmg
|
||||||
|
|
||||||
macOS14_Xcode15_arm64:
|
macOS15_Xcode16_amd64:
|
||||||
extends: .MacOS
|
extends: .MacOS
|
||||||
image: macos-14-xcode-15
|
|
||||||
tags:
|
|
||||||
- saas-macos-medium-m1
|
|
||||||
cache:
|
cache:
|
||||||
key: macOS14_Xcode15_arm64.v1
|
key: macOS15_Xcode16_amd64.v1
|
||||||
variables:
|
variables:
|
||||||
CCACHE_SIZE: 3G
|
CCACHE_SIZE: 3G
|
||||||
|
DMG_IDENTIFIER: amd64
|
||||||
|
MACOS_AMD64: true
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
HOMEBREW_NO_EMOJI: true
|
||||||
|
HOMEBREW_NO_INSTALL_CLEANUP: true
|
||||||
|
|
||||||
|
macOS15_Xcode16_arm64:
|
||||||
|
extends: .MacOS
|
||||||
|
cache:
|
||||||
|
key: macOS15_Xcode16_arm64.v1
|
||||||
|
variables:
|
||||||
|
DMG_IDENTIFIER: arm64
|
||||||
|
CCACHE_SIZE: 3G
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
|
HOMEBREW_NO_EMOJI: true
|
||||||
|
HOMEBREW_NO_INSTALL_CLEANUP: true
|
||||||
|
|
||||||
.Compress_And_Upload_Symbols_Base:
|
.Compress_And_Upload_Symbols_Base:
|
||||||
extends: .Ubuntu_Image
|
extends: .Ubuntu_Image
|
||||||
|
@ -632,12 +698,16 @@ macOS14_Xcode15_arm64:
|
||||||
- |
|
- |
|
||||||
if (Get-ChildItem -Recurse *.pdb) {
|
if (Get-ChildItem -Recurse *.pdb) {
|
||||||
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
|
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
||||||
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
}
|
}
|
||||||
Push-Location ..
|
Push-Location ..
|
||||||
..\CI\Store-Symbols.ps1 -SkipCompress
|
..\CI\Store-Symbols.ps1 -SkipCompress
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
|
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
Pop-Location
|
Pop-Location
|
||||||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||||
}
|
}
|
||||||
|
@ -645,13 +715,20 @@ macOS14_Xcode15_arm64:
|
||||||
- |
|
- |
|
||||||
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
||||||
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
|
}
|
||||||
|
- |
|
||||||
|
if ($executables) {
|
||||||
|
foreach ($exe in $executables.Split(',')) {
|
||||||
|
& .\$exe
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
|
|
||||||
after_script:
|
after_script:
|
||||||
- Get-Volume
|
- Get-Volume
|
||||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||||
cache:
|
cache:
|
||||||
key: ninja-2022-v11
|
key: ninja-2022-v13
|
||||||
paths:
|
paths:
|
||||||
- ccache
|
- ccache
|
||||||
- deps
|
- deps
|
||||||
|
@ -779,12 +856,16 @@ macOS14_Xcode15_arm64:
|
||||||
- |
|
- |
|
||||||
if (Get-ChildItem -Recurse *.pdb) {
|
if (Get-ChildItem -Recurse *.pdb) {
|
||||||
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
|
7z a -tzip "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" '*.pdb' CI-ID.txt
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
||||||
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_symbols.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
}
|
}
|
||||||
Push-Location ..
|
Push-Location ..
|
||||||
..\CI\Store-Symbols.ps1 -SkipCompress
|
..\CI\Store-Symbols.ps1 -SkipCompress
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
|
7z a -tzip "..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}_${CI_JOB_ID}_sym_store.zip"))" '.\SymStore\*' $config\CI-ID.txt
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
Pop-Location
|
Pop-Location
|
||||||
Get-ChildItem -Recurse *.pdb | Remove-Item
|
Get-ChildItem -Recurse *.pdb | Remove-Item
|
||||||
}
|
}
|
||||||
|
@ -792,13 +873,20 @@ macOS14_Xcode15_arm64:
|
||||||
- |
|
- |
|
||||||
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
if (Test-Path env:AWS_ACCESS_KEY_ID) {
|
||||||
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
aws --endpoint-url https://rgw.ctrl-c.liu.se s3 cp "..\..\$(Make-SafeFileName("OpenMW_MSVC2022_64_${config}_${CI_COMMIT_REF_NAME}.zip"))" s3://openmw-artifacts/${artifactDirectory}
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
|
}
|
||||||
|
- |
|
||||||
|
if ($executables) {
|
||||||
|
foreach ($exe in $executables.Split(',')) {
|
||||||
|
& .\$exe
|
||||||
|
if(!$?) { Exit $LASTEXITCODE }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
- if ($executables) { foreach ($exe in $executables.Split(',')) { & .\$exe } }
|
|
||||||
after_script:
|
after_script:
|
||||||
- Get-Volume
|
- Get-Volume
|
||||||
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
- Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log
|
||||||
cache:
|
cache:
|
||||||
key: msbuild-2022-v11
|
key: msbuild-2022-v13
|
||||||
paths:
|
paths:
|
||||||
- deps
|
- deps
|
||||||
- MSVC2022_64/deps/Qt
|
- MSVC2022_64/deps/Qt
|
||||||
|
@ -899,7 +987,7 @@ Windows_MSBuild_CacheInit:
|
||||||
- cd build
|
- cd build
|
||||||
- cmake --build . -- -j $(nproc)
|
- cmake --build . -- -j $(nproc)
|
||||||
# - cmake --install . # no one uses builds anyway, disable until 'no space left' is resolved
|
# - cmake --install . # no one uses builds anyway, disable until 'no space left' is resolved
|
||||||
- ccache -s
|
- ccache -svv
|
||||||
- df -h
|
- df -h
|
||||||
- ls | grep -v -e '^extern$' -e '^install$' | xargs -I '{}' rm -rf './{}'
|
- ls | grep -v -e '^extern$' -e '^install$' | xargs -I '{}' rm -rf './{}'
|
||||||
- cd ..
|
- cd ..
|
||||||
|
@ -927,7 +1015,7 @@ Windows_MSBuild_CacheInit:
|
||||||
paths:
|
paths:
|
||||||
- .cache/pip
|
- .cache/pip
|
||||||
before_script:
|
before_script:
|
||||||
- pip3 install --user requests click discord_webhook
|
- pip3 install --user --break-system-packages requests click discord_webhook
|
||||||
script:
|
script:
|
||||||
- scripts/find_missing_merge_requests.py --project_id=$CI_PROJECT_ID --ignored_mrs_path=$CI_PROJECT_DIR/.resubmitted_merge_requests.txt
|
- scripts/find_missing_merge_requests.py --project_id=$CI_PROJECT_ID --ignored_mrs_path=$CI_PROJECT_DIR/.resubmitted_merge_requests.txt
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,4 @@ python:
|
||||||
build:
|
build:
|
||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
tools:
|
tools:
|
||||||
python: "3.8"
|
python: "3.9"
|
||||||
|
|
|
@ -10,7 +10,8 @@ If you feel your name is missing from this list, please add it to `AUTHORS.md`.
|
||||||
Programmers
|
Programmers
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Bret Curtis (psi29a) - Project leader 2019-present
|
Alexey Dobrokhotov (Capo) - Project leader 2025-present
|
||||||
|
Bret Curtis (psi29a) - Project leader 2019-2025
|
||||||
Marc Zinnschlag (Zini) - Project leader 2010-2018
|
Marc Zinnschlag (Zini) - Project leader 2010-2018
|
||||||
Nicolay Korslund - Project leader 2008-2010
|
Nicolay Korslund - Project leader 2008-2010
|
||||||
scrawl - Top contributor
|
scrawl - Top contributor
|
||||||
|
@ -49,10 +50,10 @@ Programmers
|
||||||
Berulacks
|
Berulacks
|
||||||
Bo Svensson
|
Bo Svensson
|
||||||
Britt Mathis (galdor557)
|
Britt Mathis (galdor557)
|
||||||
Capostrophic
|
|
||||||
Carl Maxwell
|
Carl Maxwell
|
||||||
cc9cii
|
cc9cii
|
||||||
Cédric Mocquillon
|
Cédric Mocquillon
|
||||||
|
Charles Horn
|
||||||
Chris Boyce (slothlife)
|
Chris Boyce (slothlife)
|
||||||
Chris Robinson (KittyCat)
|
Chris Robinson (KittyCat)
|
||||||
Chris Vigil
|
Chris Vigil
|
||||||
|
@ -196,7 +197,7 @@ Programmers
|
||||||
Qlonever
|
Qlonever
|
||||||
Radu-Marius Popovici (rpopovici)
|
Radu-Marius Popovici (rpopovici)
|
||||||
Rafael Moura (dhustkoder)
|
Rafael Moura (dhustkoder)
|
||||||
Randy Davin (Kindi)
|
Randy Davin (Kuyondo)
|
||||||
rdimesio
|
rdimesio
|
||||||
rexelion
|
rexelion
|
||||||
riothamus
|
riothamus
|
||||||
|
@ -232,6 +233,7 @@ Programmers
|
||||||
Tess (tescoShoppah)
|
Tess (tescoShoppah)
|
||||||
thegriglat
|
thegriglat
|
||||||
Thomas Luppi (Digmaster)
|
Thomas Luppi (Digmaster)
|
||||||
|
Tim Hagberg (hazardMan)
|
||||||
tlmullis
|
tlmullis
|
||||||
trav
|
trav
|
||||||
tri4ng1e
|
tri4ng1e
|
||||||
|
|
107
CHANGELOG.md
107
CHANGELOG.md
|
@ -1,3 +1,97 @@
|
||||||
|
0.50.0
|
||||||
|
------
|
||||||
|
|
||||||
|
Bug #2967: Inventory windows don't update when changing items by script
|
||||||
|
Bug #4437: Transformations for NiSkinInstance are ignored
|
||||||
|
Bug #4885: Disable in dialogue result script causes a crash
|
||||||
|
Bug #5331: Pathfinding works incorrectly when actor is moved from one interior cell to another
|
||||||
|
Bug #6029: Hostile NPCs are perfectly aware of a player character with a 75% Chameleon effect
|
||||||
|
Bug #6039: Next Spell keybind fails while selected enchanted item has multiple copies
|
||||||
|
Bug #6573: Editor: Selection behaves incorrectly on high-DPI displays
|
||||||
|
Bug #6792: Birth sign info box has no line breaks
|
||||||
|
Bug #7371: Equipping item from inventory does not play a Down sound when equipping fails
|
||||||
|
Bug #7622: Player's marksman weapons don't work on close actors underwater
|
||||||
|
Bug #7649: The sound and vfx of resisted enchanted items' magic still play
|
||||||
|
Bug #7693: I.ItemUsage should return an item to the selected stack if equipping/consumption is denied
|
||||||
|
Bug #7740: Magic items in the HUD aren't composited correctly
|
||||||
|
Bug #7799: Picking up ingredients while object paging active grid is on may cause a hiccup
|
||||||
|
Bug #7871: Kwama Queen doesn't start combat with player
|
||||||
|
Bug #7979: Paralyzed NPCs battlecry
|
||||||
|
Bug #8012: Startcombat and Stopcombat do not affect music in the menu mode
|
||||||
|
Bug #8245: The console command ShowVars does not list global mwscripts
|
||||||
|
Bug #8265: Topics are linked incorrectly
|
||||||
|
Bug #8303: On target spells cast by non-actors should fire underwater
|
||||||
|
Bug #8309: RemoveSpell should instantly remove the spell's effects
|
||||||
|
Bug #8318: Missing global variables are not handled gracefully in dialogue conditions
|
||||||
|
Bug #8333: Quest status subrecords should not actually cause parsing to skip remaining data
|
||||||
|
Bug #8340: Multi-effect enchantments are too expensive
|
||||||
|
Bug #8341: Repeat shader visitor passes discard parallax
|
||||||
|
Bug #8349: Travel to non-existent cell causes persistent black screen
|
||||||
|
Bug #8359: Some quick keys menu related issues
|
||||||
|
Bug #8371: Silence affects powers
|
||||||
|
Bug #8375: Moon phase cycle doesn't match Morrowind
|
||||||
|
Bug #8383: Casting bound helm or boots on beast races doesn't cleanup properly
|
||||||
|
Bug #8385: Russian encoding broken with locale parameters and calendar
|
||||||
|
Bug #8399: Jail skill increases don't count as progress towards the next level
|
||||||
|
Bug #8404: Prevent merchant equipping breaks on lights
|
||||||
|
Bug #8408: OpenMW doesn't report all the potential resting hindrances
|
||||||
|
Bug #8414: Waterwalking works when collision is disabled
|
||||||
|
Bug #8431: Behaviour of removed items from a container is buggy
|
||||||
|
Bug #8432: Changing to and from an interior cell doesn't update collision
|
||||||
|
Bug #8433: Wandering NPCs are not capable of avoiding easy obstacles
|
||||||
|
Bug #8436: Spell selection in a pinned spellbook window doesn't update
|
||||||
|
Bug #8437: Pinned inventory window's pin button doesn't look pressed
|
||||||
|
Bug #8446: Travel prices are strangely inconsistent
|
||||||
|
Bug #8447: Werewolf swimming animation breaks in third person perspective
|
||||||
|
Bug #8459: Changing magic effect base cost doesn't change spell price
|
||||||
|
Bug #8466: Showmap "" reveals nameless cells
|
||||||
|
Bug #8485: Witchwither disease and probably other common diseases don't work correctly
|
||||||
|
Bug #8490: Normals on Water disappear when Water Shader is Enabled but Refraction is Disabled
|
||||||
|
Bug #8500: OpenMW Alarm behaviour doesn't match morrowind.exe
|
||||||
|
Bug #8519: Multiple bounty is sometimes assigned to player when detected during a pickpocketing action
|
||||||
|
Bug #8540: Magic resistance is applied to effects without a magnitude
|
||||||
|
Bug #8557: Charm's disposition changes capped on 100, uncapped below 0
|
||||||
|
Bug #8582: addScript-attached local scripts start out inactive
|
||||||
|
Bug #8584: Spacing of service menu list entries is inconsistent
|
||||||
|
Bug #8585: Dialogue topic list doesn't have enough padding
|
||||||
|
Bug #8587: Minor INI importer problems
|
||||||
|
Bug #8593: Render targets do not generate mipmaps
|
||||||
|
Bug #8598: Post processing shaders don't interact with the vfs correctly
|
||||||
|
Bug #8599: Non-ASCII paths in BSA files don't work
|
||||||
|
Bug #8606: Floating point imprecision can mess with container capacity
|
||||||
|
Bug #8609: The crosshair is too large
|
||||||
|
Bug #8610: Terrain normal maps using NormalGL format instead of NormalDX
|
||||||
|
Bug #8612: Using aiactivate on an ingredient when graphical herbalism is enabled triggers non-stop pickup sounds
|
||||||
|
Bug #8614: Lua garbage collection fails to remove unused data
|
||||||
|
Bug #8615: Rest/wait time progress speed is different from vanilla
|
||||||
|
Bug #8620: Create/CloneCommand can reuse refNums, causing severe issues in-game
|
||||||
|
Bug #8650: Some plants turn invisible when being called types.Container.inventory(cont):isResolved()
|
||||||
|
Feature #2522: Support quick item transfer
|
||||||
|
Feature #3740: Gamepad GUI Mode
|
||||||
|
Feature #3769: Allow GetSpellEffects on enchantments
|
||||||
|
Feature #6000: Oblivion terrain rendering
|
||||||
|
Feature #6976: [Lua] Weather API
|
||||||
|
Feature #7813: Add audio doppler for 3d sounds
|
||||||
|
Feature #7966: Add Lua read access to TES3 player's journal records
|
||||||
|
Feature #8077: Save settings changes when clicking "ok"/closing the window
|
||||||
|
Feature #8112: Expose landscape record data to Lua
|
||||||
|
Feature #8113: Support extended selection in autodetected subdirectory dialog
|
||||||
|
Feature #8139: Editor: Redesign the selection markers
|
||||||
|
Feature #8285: Expose list of active shaders in postprocessing API
|
||||||
|
Feature #8290: Show player gold in Spellmaking
|
||||||
|
Feature #8313: Show the character name in the savegame details
|
||||||
|
Feature #8320: Add access mwscript source text to lua api
|
||||||
|
Feature #8334: Lua: AddTopic equivalent
|
||||||
|
Feature #8355: Lua: Window visibility checking in interfaces.UI
|
||||||
|
Feature #8509: FillJournal script instruction
|
||||||
|
Feature #8579: Bulk (un)indentation in mwscript editor
|
||||||
|
Feature #8580: Sort characters in the save loading menu
|
||||||
|
Feature #8597: Lua: Add more built-in event handlers
|
||||||
|
Feature #8629: Expose path grid data to Lua
|
||||||
|
Feature #8642: Partially dehardcode on-hit mechanics
|
||||||
|
Feature #8654: Allow lua world.createRecord to create NPC records
|
||||||
|
Task #8578: Drop support for Qt5
|
||||||
|
|
||||||
0.49.0
|
0.49.0
|
||||||
------
|
------
|
||||||
|
|
||||||
|
@ -35,7 +129,6 @@
|
||||||
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
|
Bug #5977: Fatigueless NPCs' corpse underwater changes animation on game load
|
||||||
Bug #6025: Subrecords cannot overlap records
|
Bug #6025: Subrecords cannot overlap records
|
||||||
Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex
|
Bug #6027: Collisionshape becomes spiderweb-like when the mesh is too complex
|
||||||
Bug #6097: Level Progress Tooltip Sometimes Not Updated
|
|
||||||
Bug #6146: Lua command `actor:setEquipment` doesn't trigger mwscripts when equipping or unequipping a scripted item
|
Bug #6146: Lua command `actor:setEquipment` doesn't trigger mwscripts when equipping or unequipping a scripted item
|
||||||
Bug #6156: 1ft Charm or Sound magic effect vfx doesn't work properly
|
Bug #6156: 1ft Charm or Sound magic effect vfx doesn't work properly
|
||||||
Bug #6190: Unintuitive sun specularity time of day dependence
|
Bug #6190: Unintuitive sun specularity time of day dependence
|
||||||
|
@ -228,6 +321,17 @@
|
||||||
Bug #8252: Plugin dependencies are not required to be loaded
|
Bug #8252: Plugin dependencies are not required to be loaded
|
||||||
Bug #8295: Post-processing chain is case-sensitive
|
Bug #8295: Post-processing chain is case-sensitive
|
||||||
Bug #8299: Crash while smoothing landscape
|
Bug #8299: Crash while smoothing landscape
|
||||||
|
Bug #8364: Crash when clicking scrollbar without handle (divide by zero)
|
||||||
|
Bug #8378: Korean bitmap fonts are unusable
|
||||||
|
Bug #8439: Creatures without models can crash the game
|
||||||
|
Bug #8441: Freeze when using video main menu replacers
|
||||||
|
Bug #8445: Launcher crashes on exit when cell name loading thread is still running
|
||||||
|
Bug #8462: Crashes when resizing the window on macOS
|
||||||
|
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
|
||||||
|
Bug #8503: Camera does not handle NaN gracefully
|
||||||
|
Bug #8541: Lua: util.color:asHex produces wrong output for some colors
|
||||||
|
Bug #8567: Token replacement does not work via CLI and relative paths passed via the command line are not relative to the CWD
|
||||||
|
Bug #8576: Crash on exit when unresolving containers with scripted items
|
||||||
Feature #1415: Infinite fall failsafe
|
Feature #1415: Infinite fall failsafe
|
||||||
Feature #2566: Handle NAM9 records for manual cell references
|
Feature #2566: Handle NAM9 records for manual cell references
|
||||||
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking
|
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking
|
||||||
|
@ -392,6 +496,7 @@
|
||||||
Bug #6066: Addtopic "return" does not work from within script. No errors thrown
|
Bug #6066: Addtopic "return" does not work from within script. No errors thrown
|
||||||
Bug #6067: ESP loader fails for certain subrecord orders
|
Bug #6067: ESP loader fails for certain subrecord orders
|
||||||
Bug #6087: Bound items added directly to the inventory disappear if their corresponding spell effect ends
|
Bug #6087: Bound items added directly to the inventory disappear if their corresponding spell effect ends
|
||||||
|
Bug #6097: Level Progress Tooltip Sometimes Not Updated
|
||||||
Bug #6101: Disarming trapped unlocked owned objects isn't considered a crime
|
Bug #6101: Disarming trapped unlocked owned objects isn't considered a crime
|
||||||
Bug #6107: Fatigue is incorrectly recalculated when fortify effect is applied or removed
|
Bug #6107: Fatigue is incorrectly recalculated when fortify effect is applied or removed
|
||||||
Bug #6109: Crash when playing a custom made menu_background file
|
Bug #6109: Crash when playing a custom made menu_background file
|
||||||
|
|
7
CI/before_install.macos.sh
Executable file
7
CI/before_install.macos.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
./CI/macos/before_install.amd64.sh
|
||||||
|
else
|
||||||
|
./CI/macos/before_install.arm64.sh
|
||||||
|
fi
|
|
@ -1,30 +0,0 @@
|
||||||
#!/bin/sh -ex
|
|
||||||
|
|
||||||
export HOMEBREW_NO_EMOJI=1
|
|
||||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
|
||||||
export HOMEBREW_AUTOREMOVE=1
|
|
||||||
|
|
||||||
brew tap --repair
|
|
||||||
brew update --quiet
|
|
||||||
|
|
||||||
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd
|
|
||||||
|
|
||||||
command -v ccache >/dev/null 2>&1 || brew install ccache
|
|
||||||
command -v cmake >/dev/null 2>&1 || brew install cmake
|
|
||||||
command -v qmake >/dev/null 2>&1 || brew install qt@5
|
|
||||||
export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"
|
|
||||||
|
|
||||||
# Install deps
|
|
||||||
brew install openal-soft icu4c yaml-cpp sqlite
|
|
||||||
|
|
||||||
ccache --version
|
|
||||||
cmake --version
|
|
||||||
qmake --version
|
|
||||||
|
|
||||||
if [[ "${MACOS_AMD64}" ]]; then
|
|
||||||
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
|
|
||||||
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null
|
|
||||||
else
|
|
||||||
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
|
|
||||||
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null
|
|
||||||
fi
|
|
|
@ -17,7 +17,7 @@ declare -a CMAKE_CONF_OPTS=(
|
||||||
-DBUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-OFF}"
|
-DBUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-OFF}"
|
||||||
-DUSE_SYSTEM_TINYXML=ON
|
-DUSE_SYSTEM_TINYXML=ON
|
||||||
-DOPENMW_USE_SYSTEM_RECASTNAVIGATION=ON
|
-DOPENMW_USE_SYSTEM_RECASTNAVIGATION=ON
|
||||||
-DOPENMW_CXX_FLAGS="-Werror -Werror=implicit-fallthrough" # flags specific to OpenMW project
|
-DOPENMW_CXX_FLAGS="${OPENMW_CXX_FLAGS}" # flags specific to OpenMW project
|
||||||
)
|
)
|
||||||
|
|
||||||
if [[ "${CMAKE_EXE_LINKER_FLAGS}" ]]; then
|
if [[ "${CMAKE_EXE_LINKER_FLAGS}" ]]; then
|
||||||
|
@ -38,7 +38,7 @@ fi
|
||||||
|
|
||||||
if [[ $CI_CLANG_TIDY ]]; then
|
if [[ $CI_CLANG_TIDY ]]; then
|
||||||
CMAKE_CONF_OPTS+=(
|
CMAKE_CONF_OPTS+=(
|
||||||
-DCMAKE_CXX_CLANG_TIDY="clang-tidy;--warnings-as-errors=*"
|
-DCMAKE_CXX_CLANG_TIDY=clang-tidy
|
||||||
-DBUILD_COMPONENTS_TESTS=ON
|
-DBUILD_COMPONENTS_TESTS=ON
|
||||||
-DBUILD_OPENMW_TESTS=ON
|
-DBUILD_OPENMW_TESTS=ON
|
||||||
-DBUILD_OPENCS_TESTS=ON
|
-DBUILD_OPENCS_TESTS=ON
|
||||||
|
|
77
CI/before_script.macos.sh
Executable file
77
CI/before_script.macos.sh
Executable file
|
@ -0,0 +1,77 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Silence a git warning
|
||||||
|
git config --global advice.detachedHead false
|
||||||
|
|
||||||
|
rm -fr build
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
|
||||||
|
DEPENDENCIES_ROOT="/tmp/openmw-deps"
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
QT_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix qt@6)
|
||||||
|
ICU_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix icu4c)
|
||||||
|
OPENAL_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix openal-soft)
|
||||||
|
CCACHE_EXECUTABLE=$(arch -x86_64 /usr/local/bin/brew --prefix ccache)/bin/ccache
|
||||||
|
else
|
||||||
|
QT_PATH=$(brew --prefix qt@6)
|
||||||
|
ICU_PATH=$(brew --prefix icu4c)
|
||||||
|
OPENAL_PATH=$(brew --prefix openal-soft)
|
||||||
|
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -a CMAKE_CONF_OPTS=(
|
||||||
|
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
|
||||||
|
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
|
||||||
|
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
|
||||||
|
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
|
||||||
|
-D CMAKE_C_COMPILER="clang"
|
||||||
|
-D CMAKE_CXX_COMPILER="clang++"
|
||||||
|
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
|
||||||
|
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
|
||||||
|
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
|
||||||
|
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
|
||||||
|
-D ICU_ROOT="$ICU_PATH"
|
||||||
|
-D OPENMW_OSX_DEPLOYMENT=TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
declare -a BUILD_OPTS=(
|
||||||
|
-D BUILD_OPENMW=TRUE
|
||||||
|
-D BUILD_OPENCS=TRUE
|
||||||
|
-D BUILD_ESMTOOL=TRUE
|
||||||
|
-D BUILD_BSATOOL=TRUE
|
||||||
|
-D BUILD_ESSIMPORTER=TRUE
|
||||||
|
-D BUILD_NIFTEST=TRUE
|
||||||
|
-D BUILD_NAVMESHTOOL=TRUE
|
||||||
|
-D BUILD_BULLETOBJECTTOOL=TRUE
|
||||||
|
-G"Unix Makefiles"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
CMAKE_CONF_OPTS+=(
|
||||||
|
-D CMAKE_OSX_ARCHITECTURES="x86_64"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
|
||||||
|
CMAKE_CONF_OPTS+=(
|
||||||
|
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
CMAKE_CONF_OPTS+=(
|
||||||
|
-D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
arch -x86_64 cmake \
|
||||||
|
"${CMAKE_CONF_OPTS[@]}" \
|
||||||
|
"${BUILD_OPTS[@]}" \
|
||||||
|
..
|
||||||
|
else
|
||||||
|
cmake \
|
||||||
|
"${CMAKE_CONF_OPTS[@]}" \
|
||||||
|
"${BUILD_OPTS[@]}" \
|
||||||
|
..
|
||||||
|
fi
|
|
@ -377,6 +377,8 @@ case $VS_VERSION in
|
||||||
MSVC_DISPLAY_YEAR="2022"
|
MSVC_DISPLAY_YEAR="2022"
|
||||||
|
|
||||||
QT_MSVC_YEAR="2019"
|
QT_MSVC_YEAR="2019"
|
||||||
|
|
||||||
|
VCPKG_TRIPLET="x64-windows"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
16|16.0|2019 )
|
16|16.0|2019 )
|
||||||
|
@ -386,6 +388,8 @@ case $VS_VERSION in
|
||||||
MSVC_DISPLAY_YEAR="2019"
|
MSVC_DISPLAY_YEAR="2019"
|
||||||
|
|
||||||
QT_MSVC_YEAR="2019"
|
QT_MSVC_YEAR="2019"
|
||||||
|
|
||||||
|
VCPKG_TRIPLET="x64-windows-2019"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
15|15.0|2017 )
|
15|15.0|2017 )
|
||||||
|
@ -546,7 +550,7 @@ fi
|
||||||
QT_VER='6.6.3'
|
QT_VER='6.6.3'
|
||||||
AQT_VERSION='v3.1.15'
|
AQT_VERSION='v3.1.15'
|
||||||
|
|
||||||
VCPKG_TAG="2024-11-10"
|
VCPKG_TAG="2025-07-23"
|
||||||
VCPKG_PATH="vcpkg-x64-${VS_VERSION:?}-${VCPKG_TAG:?}"
|
VCPKG_PATH="vcpkg-x64-${VS_VERSION:?}-${VCPKG_TAG:?}"
|
||||||
VCPKG_PDB_PATH="vcpkg-x64-${VS_VERSION:?}-pdb-${VCPKG_TAG:?}"
|
VCPKG_PDB_PATH="vcpkg-x64-${VS_VERSION:?}-pdb-${VCPKG_TAG:?}"
|
||||||
VCPKG_MANIFEST="${VCPKG_PATH:?}.txt"
|
VCPKG_MANIFEST="${VCPKG_PATH:?}.txt"
|
||||||
|
@ -633,16 +637,16 @@ printf "vcpkg packages ${VCPKG_TAG:?}... "
|
||||||
fi
|
fi
|
||||||
|
|
||||||
add_cmake_opts -DCMAKE_TOOLCHAIN_FILE="$(real_pwd)/${VCPKG_PATH:?}/scripts/buildsystems/vcpkg.cmake"
|
add_cmake_opts -DCMAKE_TOOLCHAIN_FILE="$(real_pwd)/${VCPKG_PATH:?}/scripts/buildsystems/vcpkg.cmake"
|
||||||
add_cmake_opts -DLuaJit_INCLUDE_DIR="$(real_pwd)/${VCPKG_PATH:?}/installed/x64-windows/include/luajit"
|
add_cmake_opts -DLuaJit_INCLUDE_DIR="$(real_pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/include/luajit"
|
||||||
add_cmake_opts -DLuaJit_LIBRARY="$(real_pwd)/${VCPKG_PATH:?}/installed/x64-windows/lib/lua51.lib"
|
add_cmake_opts -DLuaJit_LIBRARY="$(real_pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/lib/lua51.lib"
|
||||||
|
|
||||||
for CONFIGURATION in ${CONFIGURATIONS[@]}; do
|
for CONFIGURATION in ${CONFIGURATIONS[@]}; do
|
||||||
if [[ ${CONFIGURATION:?} == "Debug" ]]; then
|
if [[ ${CONFIGURATION:?} == "Debug" ]]; then
|
||||||
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/x64-windows/debug/bin"
|
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/debug/bin"
|
||||||
|
|
||||||
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Debug/MyGUIEngine_d.dll"
|
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Debug/MyGUIEngine_d.dll"
|
||||||
else
|
else
|
||||||
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/x64-windows/bin"
|
VCPKG_DLL_BIN="$(pwd)/${VCPKG_PATH:?}/installed/${VCPKG_TRIPLET}/bin"
|
||||||
|
|
||||||
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Release/MyGUIEngine.dll"
|
add_runtime_dlls ${CONFIGURATION:?} "${VCPKG_DLL_BIN:?}/Release/MyGUIEngine.dll"
|
||||||
fi
|
fi
|
||||||
|
@ -704,17 +708,12 @@ printf "Qt ${QT_VER}... "
|
||||||
DLLSUFFIX=""
|
DLLSUFFIX=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${QT_MAJOR_VER}" -eq 6 ]; then
|
add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,OpenGLWidgets,Widgets,Svg}${DLLSUFFIX}.dll
|
||||||
add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,OpenGLWidgets,Widgets,Svg}${DLLSUFFIX}.dll
|
|
||||||
|
|
||||||
# Since Qt 6.7.0 plugin is called "qmodernwindowsstyle"
|
# Since Qt 6.7.0 plugin is called "qmodernwindowsstyle"
|
||||||
if [ "${QT_MINOR_VER}" -ge 7 ]; then
|
if [ "${QT_MINOR_VER}" -ge 7 ]; then
|
||||||
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qmodernwindowsstyle${DLLSUFFIX}.dll"
|
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qmodernwindowsstyle${DLLSUFFIX}.dll"
|
||||||
else
|
|
||||||
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
add_runtime_dlls $CONFIGURATION "$(pwd)/bin/Qt${QT_MAJOR_VER}"{Core,Gui,Network,OpenGL,Widgets,Svg}${DLLSUFFIX}.dll
|
|
||||||
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll"
|
add_qt_style_dlls $CONFIGURATION "$(pwd)/plugins/styles/qwindowsvistastyle${DLLSUFFIX}.dll"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
# Silence a git warning
|
|
||||||
git config --global advice.detachedHead false
|
|
||||||
|
|
||||||
rm -fr build
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
|
|
||||||
DEPENDENCIES_ROOT="/tmp/openmw-deps"
|
|
||||||
|
|
||||||
QT_PATH=$(brew --prefix qt@5)
|
|
||||||
ICU_PATH=$(brew --prefix icu4c)
|
|
||||||
OPENAL_PATH=$(brew --prefix openal-soft)
|
|
||||||
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
|
|
||||||
|
|
||||||
declare -a CMAKE_CONF_OPTS=(
|
|
||||||
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
|
|
||||||
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
|
|
||||||
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
|
|
||||||
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
|
|
||||||
-D CMAKE_C_COMPILER="clang"
|
|
||||||
-D CMAKE_CXX_COMPILER="clang++"
|
|
||||||
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
|
|
||||||
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
|
|
||||||
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
|
|
||||||
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
|
|
||||||
-D ICU_ROOT="$ICU_PATH"
|
|
||||||
-D OPENMW_OSX_DEPLOYMENT=TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
|
|
||||||
CMAKE_CONF_OPTS+=(
|
|
||||||
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
|
||||||
)
|
|
||||||
else
|
|
||||||
CMAKE_CONF_OPTS+=(
|
|
||||||
-D CMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
|
|
||||||
cmake \
|
|
||||||
"${CMAKE_CONF_OPTS[@]}" \
|
|
||||||
-D BUILD_OPENMW=TRUE \
|
|
||||||
-D BUILD_OPENCS=TRUE \
|
|
||||||
-D BUILD_ESMTOOL=TRUE \
|
|
||||||
-D BUILD_BSATOOL=TRUE \
|
|
||||||
-D BUILD_ESSIMPORTER=TRUE \
|
|
||||||
-D BUILD_NIFTEST=TRUE \
|
|
||||||
-D BUILD_NAVMESHTOOL=TRUE \
|
|
||||||
-D BUILD_BULLETOBJECTTOOL=TRUE \
|
|
||||||
-G"Unix Makefiles" \
|
|
||||||
..
|
|
|
@ -1,7 +1,6 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
git ls-files -- ':(exclude)extern/' '*.cpp' '*.hpp' '*.h' |
|
git ls-files -- ':(exclude)extern/' '*.cpp' '*.hpp' '*.h' |
|
||||||
grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' |
|
grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' &&
|
||||||
grep -vFf CI/file_name_exceptions.txt &&
|
|
||||||
( echo 'File names do not follow the naming convention, see https://wiki.openmw.org/index.php?title=Naming_Conventions#Files'; exit -1 )
|
( echo 'File names do not follow the naming convention, see https://wiki.openmw.org/index.php?title=Naming_Conventions#Files'; exit -1 )
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
apps/openmw/android_main.cpp
|
|
||||||
apps/openmw/mwsound/efx-presets.h
|
|
||||||
apps/openmw/mwsound/ffmpeg_decoder.cpp
|
|
||||||
apps/openmw/mwsound/ffmpeg_decoder.hpp
|
|
||||||
apps/openmw/mwsound/openal_output.cpp
|
|
||||||
apps/openmw/mwsound/openal_output.hpp
|
|
||||||
apps/openmw/mwsound/sound_buffer.cpp
|
|
||||||
apps/openmw/mwsound/sound_buffer.hpp
|
|
||||||
apps/openmw/mwsound/sound_decoder.hpp
|
|
||||||
apps/openmw/mwsound/sound_output.hpp
|
|
||||||
apps/components_tests/esm/test_fixed_string.cpp
|
|
||||||
apps/components_tests/files/conversion_tests.cpp
|
|
||||||
apps/components_tests/lua/test_async.cpp
|
|
||||||
apps/components_tests/lua/test_configuration.cpp
|
|
||||||
apps/components_tests/lua/test_l10n.cpp
|
|
||||||
apps/components_tests/lua/test_lua.cpp
|
|
||||||
apps/components_tests/lua/test_scriptscontainer.cpp
|
|
||||||
apps/components_tests/lua/test_serialization.cpp
|
|
||||||
apps/components_tests/lua/test_storage.cpp
|
|
||||||
apps/components_tests/lua/test_ui_content.cpp
|
|
||||||
apps/components_tests/lua/test_utilpackage.cpp
|
|
||||||
apps/components_tests/lua/test_inputactions.cpp
|
|
||||||
apps/components_tests/lua/test_yaml.cpp
|
|
||||||
apps/components_tests/misc/test_endianness.cpp
|
|
||||||
apps/components_tests/misc/test_resourcehelpers.cpp
|
|
||||||
apps/components_tests/misc/test_stringops.cpp
|
|
||||||
apps/openmw_tests/mwdialogue/test_keywordsearch.cpp
|
|
||||||
apps/openmw_tests/mwscript/test_scripts.cpp
|
|
||||||
apps/openmw_tests/mwscript/test_utils.hpp
|
|
||||||
apps/openmw_tests/mwworld/test_store.cpp
|
|
||||||
components/bsa/bsa_file.cpp
|
|
||||||
components/bsa/bsa_file.hpp
|
|
||||||
components/crashcatcher/windows_crashcatcher.cpp
|
|
||||||
components/crashcatcher/windows_crashcatcher.hpp
|
|
||||||
components/crashcatcher/windows_crashmonitor.cpp
|
|
||||||
components/crashcatcher/windows_crashmonitor.hpp
|
|
||||||
components/crashcatcher/windows_crashshm.hpp
|
|
||||||
components/fx/lexer_types.hpp
|
|
||||||
components/fx/parse_constants.hpp
|
|
||||||
components/platform/file.posix.cpp
|
|
||||||
components/platform/file.stdio.cpp
|
|
||||||
components/platform/file.win32.cpp
|
|
||||||
components/sdlutil/gl4es_init.cpp
|
|
||||||
components/sdlutil/gl4es_init.h
|
|
||||||
components/to_utf8/gen_iconv.cpp
|
|
||||||
components/to_utf8/tables_gen.hpp
|
|
||||||
components/to_utf8/to_utf8.cpp
|
|
||||||
components/to_utf8/to_utf8.hpp
|
|
|
@ -1 +1 @@
|
||||||
VCPKG_DEPS_TAG=2024-11-10
|
VCPKG_DEPS_TAG=2025-07-23
|
||||||
|
|
|
@ -11,7 +11,8 @@ print_help() {
|
||||||
declare -rA GROUPED_DEPS=(
|
declare -rA GROUPED_DEPS=(
|
||||||
[gcc]="binutils gcc build-essential cmake ccache curl unzip git pkg-config mold"
|
[gcc]="binutils gcc build-essential cmake ccache curl unzip git pkg-config mold"
|
||||||
[clang]="binutils clang make cmake ccache curl unzip git pkg-config mold"
|
[clang]="binutils clang make cmake ccache curl unzip git pkg-config mold"
|
||||||
[coverity]="binutils clang-12 make cmake ccache curl unzip git pkg-config"
|
[coverity]="binutils clang make cmake ccache curl unzip git pkg-config file"
|
||||||
|
[coverity_upload]="curl"
|
||||||
[gcc_preprocess]="
|
[gcc_preprocess]="
|
||||||
binutils
|
binutils
|
||||||
build-essential
|
build-essential
|
||||||
|
@ -33,10 +34,10 @@ declare -rA GROUPED_DEPS=(
|
||||||
libboost-system-dev libboost-iostreams-dev
|
libboost-system-dev libboost-iostreams-dev
|
||||||
|
|
||||||
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
|
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
|
||||||
libsdl2-dev libqt5opengl5-dev qttools5-dev qttools5-dev-tools libopenal-dev
|
libsdl2-dev libqt6opengl6-dev qt6-tools-dev qt6-tools-dev-tools libopenal-dev
|
||||||
libunshield-dev libtinyxml-dev libbullet-dev liblz4-dev libpng-dev libjpeg-dev
|
libunshield-dev libtinyxml-dev libbullet-dev liblz4-dev libpng-dev libjpeg-dev
|
||||||
libluajit-5.1-dev librecast-dev libsqlite3-dev ca-certificates libicu-dev
|
libluajit-5.1-dev librecast-dev libsqlite3-dev ca-certificates libicu-dev
|
||||||
libyaml-cpp-dev libqt5svg5 libqt5svg5-dev
|
libyaml-cpp-dev libqt6svg6 libqt6svg6-dev
|
||||||
"
|
"
|
||||||
|
|
||||||
# These dependencies can alternatively be built and linked statically.
|
# These dependencies can alternatively be built and linked statically.
|
||||||
|
@ -57,22 +58,22 @@ declare -rA GROUPED_DEPS=(
|
||||||
libsdl2-dev libboost-system-dev libboost-filesystem-dev libgl-dev
|
libsdl2-dev libboost-system-dev libboost-filesystem-dev libgl-dev
|
||||||
"
|
"
|
||||||
|
|
||||||
[openmw-coverage]="gcovr"
|
[openmw-coverage]="pipx"
|
||||||
|
|
||||||
[openmw-integration-tests]="
|
[openmw-integration-tests]="
|
||||||
ca-certificates
|
ca-certificates
|
||||||
gdb
|
gdb
|
||||||
git
|
git
|
||||||
git-lfs
|
git-lfs
|
||||||
libavcodec58
|
libavcodec60
|
||||||
libavformat58
|
libavformat60
|
||||||
libavutil56
|
libavutil58
|
||||||
libboost-iostreams1.74.0
|
libboost-iostreams1.83.0
|
||||||
libboost-program-options1.74.0
|
libboost-program-options1.83.0
|
||||||
libboost-system1.74.0
|
libboost-system1.83.0
|
||||||
libbullet3.24
|
libbullet3.24
|
||||||
libcollada-dom2.5-dp0
|
libcollada-dom2.5-dp0
|
||||||
libicu70
|
libicu74
|
||||||
libjpeg8
|
libjpeg8
|
||||||
libluajit-5.1-2
|
libluajit-5.1-2
|
||||||
liblz4-1
|
liblz4-1
|
||||||
|
@ -80,19 +81,19 @@ declare -rA GROUPED_DEPS=(
|
||||||
libopenal1
|
libopenal1
|
||||||
libopenscenegraph161
|
libopenscenegraph161
|
||||||
libpng16-16
|
libpng16-16
|
||||||
libqt5opengl5
|
libqt6opengl6
|
||||||
librecast1
|
librecast1
|
||||||
libsdl2-2.0-0
|
libsdl2-2.0-0
|
||||||
libsqlite3-0
|
libsqlite3-0
|
||||||
libswresample3
|
libswresample4
|
||||||
libswscale5
|
libswscale7
|
||||||
libtinyxml2.6.2v5
|
libtinyxml2.6.2v5
|
||||||
libyaml-cpp0.8
|
libyaml-cpp0.8
|
||||||
python3-pip
|
python3-pip
|
||||||
xvfb
|
xvfb
|
||||||
"
|
"
|
||||||
|
|
||||||
[libasan6]="libasan6"
|
[libasan]="libasan8"
|
||||||
|
|
||||||
[android]="binutils build-essential cmake ccache curl unzip git pkg-config"
|
[android]="binutils build-essential cmake ccache curl unzip git pkg-config"
|
||||||
|
|
||||||
|
@ -102,8 +103,8 @@ declare -rA GROUPED_DEPS=(
|
||||||
"
|
"
|
||||||
|
|
||||||
[openmw-qt-translations]="
|
[openmw-qt-translations]="
|
||||||
qttools5-dev
|
qt6-tools-dev
|
||||||
qttools5-dev-tools
|
qt6-tools-dev-tools
|
||||||
git-core
|
git-core
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
|
@ -126,10 +127,24 @@ export APT_CACHE_DIR="${PWD}/apt-cache"
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
set -x
|
set -x
|
||||||
mkdir -pv "$APT_CACHE_DIR"
|
mkdir -pv "$APT_CACHE_DIR"
|
||||||
apt-get update -yqq
|
|
||||||
|
while true; do
|
||||||
|
apt-get update -yqq && break
|
||||||
|
done
|
||||||
|
|
||||||
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends software-properties-common gnupg >/dev/null
|
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends software-properties-common gnupg >/dev/null
|
||||||
add-apt-repository -y ppa:openmw/openmw
|
|
||||||
add-apt-repository -y ppa:openmw/openmw-daily
|
while true; do
|
||||||
add-apt-repository -y ppa:openmw/staging
|
add-apt-repository -y ppa:openmw/openmw && break
|
||||||
|
done
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
add-apt-repository -y ppa:openmw/openmw-daily && break
|
||||||
|
done
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
add-apt-repository -y ppa:openmw/staging && break
|
||||||
|
done
|
||||||
|
|
||||||
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends "${deps[@]}" >/dev/null
|
apt-get -qq -o dir::cache::archives="$APT_CACHE_DIR" install -y --no-install-recommends "${deps[@]}" >/dev/null
|
||||||
apt list --installed
|
apt list --installed
|
||||||
|
|
8
CI/macos/before_install.amd64.sh
Executable file
8
CI/macos/before_install.amd64.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
|
|
||||||
|
arch -x86_64 /usr/local/bin/brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd ccache cmake qt@6 openal-soft icu4c yaml-cpp sqlite
|
||||||
|
|
||||||
|
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
|
||||||
|
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null
|
9
CI/macos/before_install.arm64.sh
Executable file
9
CI/macos/before_install.arm64.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
brew tap --repair
|
||||||
|
brew update --quiet
|
||||||
|
|
||||||
|
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd ccache cmake qt@6 openal-soft icu4c yaml-cpp sqlite
|
||||||
|
|
||||||
|
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
|
||||||
|
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null
|
9
CI/macos/build.sh
Executable file
9
CI/macos/build.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
arch -x86_64 make -j $(sysctl -n hw.logicalcpu) package
|
||||||
|
else
|
||||||
|
make -j $(sysctl -n hw.logicalcpu) package
|
||||||
|
fi
|
7
CI/macos/ccache_prep.sh
Executable file
7
CI/macos/ccache_prep.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
arch -x86_64 ccache -z -M "${CCACHE_SIZE}"
|
||||||
|
else
|
||||||
|
ccache -z -M "${CCACHE_SIZE}"
|
||||||
|
fi
|
7
CI/macos/ccache_save.sh
Executable file
7
CI/macos/ccache_save.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
if [[ "${MACOS_AMD64}" ]]; then
|
||||||
|
arch -x86_64 ccache -svv
|
||||||
|
else
|
||||||
|
ccache -svv
|
||||||
|
fi
|
|
@ -9,7 +9,7 @@ git checkout FETCH_HEAD
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24x60' \
|
xvfb-run --auto-servernum --server-args='-screen 0 640x480x24x60' \
|
||||||
scripts/integration_tests.py --omw build/install/bin/openmw --workdir integration_tests_output example-suite/
|
scripts/integration_tests.py --verbose --omw build/install/bin/openmw --workdir integration_tests_output example-suite/
|
||||||
|
|
||||||
ls integration_tests_output/*.osg_stats.log | while read v; do
|
ls integration_tests_output/*.osg_stats.log | while read v; do
|
||||||
scripts/osg_stats.py --stats '.*' --regexp_match < "${v}"
|
scripts/osg_stats.py --stats '.*' --regexp_match < "${v}"
|
||||||
|
|
154
CMakeLists.txt
154
CMakeLists.txt
|
@ -80,10 +80,10 @@ endif()
|
||||||
message(STATUS "Configuring OpenMW...")
|
message(STATUS "Configuring OpenMW...")
|
||||||
|
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 49)
|
set(OPENMW_VERSION_MINOR 50)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
set(OPENMW_LUA_API_REVISION 70)
|
set(OPENMW_LUA_API_REVISION 92)
|
||||||
set(OPENMW_POSTPROCESSING_API_REVISION 2)
|
set(OPENMW_POSTPROCESSING_API_REVISION 3)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
set(OPENMW_VERSION_TAGHASH "")
|
set(OPENMW_VERSION_TAGHASH "")
|
||||||
|
@ -249,12 +249,8 @@ endif()
|
||||||
find_package(LZ4 REQUIRED)
|
find_package(LZ4 REQUIRED)
|
||||||
|
|
||||||
if (USE_QT)
|
if (USE_QT)
|
||||||
find_package(QT REQUIRED COMPONENTS Core NAMES Qt6 Qt5)
|
find_package(QT REQUIRED COMPONENTS Core NAMES Qt6)
|
||||||
if (QT_VERSION_MAJOR VERSION_EQUAL 5)
|
find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets LinguistTools Svg REQUIRED)
|
||||||
find_package(Qt5 5.15 COMPONENTS Core Widgets Network OpenGL LinguistTools Svg REQUIRED)
|
|
||||||
else()
|
|
||||||
find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets LinguistTools Svg REQUIRED)
|
|
||||||
endif()
|
|
||||||
message(STATUS "Using Qt${QT_VERSION}")
|
message(STATUS "Using Qt${QT_VERSION}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -466,7 +462,7 @@ find_package(Boost 1.70.0 CONFIG REQUIRED COMPONENTS ${BOOST_COMPONENTS} OPTIONA
|
||||||
if(OPENMW_USE_SYSTEM_MYGUI)
|
if(OPENMW_USE_SYSTEM_MYGUI)
|
||||||
find_package(MyGUI 3.4.3 REQUIRED)
|
find_package(MyGUI 3.4.3 REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
find_package(SDL2 2.0.10 REQUIRED)
|
find_package(SDL2 2.0.20 REQUIRED)
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
|
|
||||||
|
@ -590,25 +586,10 @@ if(OPENMW_LTO_BUILD)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
set(OPENMW_CXX_FLAGS "-Wall -Wextra -Wundef -Wextra-semi -Wno-unused-parameter -pedantic -Wno-long-long -Wnon-virtual-dtor -Wunused ${OPENMW_CXX_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
|
||||||
|
endif()
|
||||||
if (APPLE)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
|
|
||||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 3.6)
|
|
||||||
set(OPENMW_CXX_FLAGS "${OPENMW_CXX_FLAGS} -Wno-potentially-evaluated-expression")
|
|
||||||
endif ()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
|
||||||
set(OPENMW_CXX_FLAGS "${OPENMW_CXX_FLAGS} -Wno-unused-but-set-parameter -Wduplicated-branches -Wduplicated-cond -Wlogical-op")
|
|
||||||
endif()
|
|
||||||
endif (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
|
||||||
|
|
||||||
# Extern
|
# Extern
|
||||||
|
|
||||||
|
@ -619,8 +600,42 @@ if (BUILD_OPENCS OR BUILD_OPENCS_TESTS)
|
||||||
add_subdirectory (extern/osgQt)
|
add_subdirectory (extern/osgQt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||||
|
add_compile_options("/W4")
|
||||||
|
|
||||||
|
set(WARNINGS_DISABLE
|
||||||
|
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
||||||
|
4127 # Conditional expression is constant
|
||||||
|
4996 # Function was declared deprecated
|
||||||
|
5054 # Deprecated operations between enumerations of different types caused by Qt headers
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(d ${WARNINGS_DISABLE})
|
||||||
|
add_compile_options("/wd${d}")
|
||||||
|
endforeach(d)
|
||||||
|
|
||||||
|
if(OPENMW_MSVC_WERROR)
|
||||||
|
add_compile_options("/WX")
|
||||||
|
endif()
|
||||||
|
else ()
|
||||||
|
add_compile_options("-Wall" "-Wextra" "-Wundef" "-Wextra-semi" "-Wno-unused-parameter" "-pedantic" "-Wno-long-long" "-Wnon-virtual-dtor" "-Wunused")
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.6 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 3.6)
|
||||||
|
add_compile_options("-Wno-potentially-evaluated-expression")
|
||||||
|
endif ()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
||||||
|
add_compile_options("-Wno-unused-but-set-parameter" "-Wduplicated-branches" "-Wduplicated-cond" "-Wlogical-op")
|
||||||
|
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105438
|
||||||
|
add_compile_options("-Wno-array-bounds")
|
||||||
|
endif()
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (OPENMW_CXX_FLAGS)
|
if (OPENMW_CXX_FLAGS)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMW_CXX_FLAGS}")
|
separate_arguments(OPENMW_CXX_FLAGS NATIVE_COMMAND "${OPENMW_CXX_FLAGS}")
|
||||||
|
add_compile_options(${OPENMW_CXX_FLAGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Components
|
# Components
|
||||||
|
@ -710,87 +725,9 @@ if (WIN32)
|
||||||
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Play a bit with the warning levels
|
|
||||||
|
|
||||||
set(WARNINGS "/W4")
|
|
||||||
|
|
||||||
set(WARNINGS_DISABLE
|
|
||||||
4100 # Unreferenced formal parameter (-Wunused-parameter)
|
|
||||||
4127 # Conditional expression is constant
|
|
||||||
4996 # Function was declared deprecated
|
|
||||||
5054 # Deprecated operations between enumerations of different types caused by Qt headers
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach(d ${WARNINGS_DISABLE})
|
|
||||||
list(APPEND WARNINGS "/wd${d}")
|
|
||||||
endforeach(d)
|
|
||||||
|
|
||||||
if(OPENMW_MSVC_WERROR)
|
|
||||||
list(APPEND WARNINGS "/WX")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_compile_options(components PRIVATE ${WARNINGS})
|
|
||||||
target_compile_options(osg-ffmpeg-videoplayer PRIVATE ${WARNINGS})
|
|
||||||
|
|
||||||
if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920)
|
if (MSVC_VERSION GREATER_EQUAL 1915 AND MSVC_VERSION LESS 1920)
|
||||||
target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE)
|
target_compile_definitions(components INTERFACE _ENABLE_EXTENDED_ALIGNED_STORAGE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_BSATOOL)
|
|
||||||
target_compile_options(bsatool PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_ESMTOOL)
|
|
||||||
target_compile_options(esmtool PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_ESSIMPORTER)
|
|
||||||
target_compile_options(openmw-essimporter PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_LAUNCHER)
|
|
||||||
target_compile_options(openmw-launcher PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_MWINIIMPORTER)
|
|
||||||
target_compile_options(openmw-iniimporter PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_OPENCS)
|
|
||||||
target_compile_options(openmw-cs PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_OPENMW)
|
|
||||||
target_compile_options(openmw PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_WIZARD)
|
|
||||||
target_compile_options(openmw-wizard PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_COMPONENTS_TESTS)
|
|
||||||
target_compile_options(components-tests PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_BENCHMARKS)
|
|
||||||
target_compile_options(openmw_detournavigator_navmeshtilescache_benchmark PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_NAVMESHTOOL)
|
|
||||||
target_compile_options(openmw-navmeshtool PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_BULLETOBJECTTOOL)
|
|
||||||
target_compile_options(openmw-bulletobjecttool PRIVATE ${WARNINGS} ${MT_BUILD})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_OPENCS_TESTS)
|
|
||||||
target_compile_options(openmw-cs-tests PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_OPENMW_TESTS)
|
|
||||||
target_compile_options(openmw-tests PRIVATE ${WARNINGS})
|
|
||||||
endif()
|
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
# TODO: At some point release builds should not use the console but rather write to a log file
|
# TODO: At some point release builds should not use the console but rather write to a log file
|
||||||
|
@ -860,7 +797,6 @@ if (OPENMW_OSX_DEPLOYMENT AND APPLE)
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
|
||||||
include(BundleUtilities)
|
include(BundleUtilities)
|
||||||
cmake_minimum_required(VERSION 3.1)
|
|
||||||
" COMPONENT Runtime)
|
" COMPONENT Runtime)
|
||||||
|
|
||||||
set(ABSOLUTE_PLUGINS "")
|
set(ABSOLUTE_PLUGINS "")
|
||||||
|
|
|
@ -5,7 +5,7 @@ OpenMW is an open-source open-world RPG game engine that supports playing Morrow
|
||||||
|
|
||||||
OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
|
OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
|
||||||
|
|
||||||
* Version: 0.49.0
|
* Version: 0.50.0
|
||||||
* License: GPLv3 (see [LICENSE](https://gitlab.com/OpenMW/openmw/-/raw/master/LICENSE) for more information)
|
* License: GPLv3 (see [LICENSE](https://gitlab.com/OpenMW/openmw/-/raw/master/LICENSE) for more information)
|
||||||
* Website: https://www.openmw.org
|
* Website: https://www.openmw.org
|
||||||
* IRC: #openmw on irc.libera.chat
|
* IRC: #openmw on irc.libera.chat
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace
|
||||||
generateKeys(std::back_inserter(keys), keys.size() * (100 - hitPercentage) / 100, random);
|
generateKeys(std::back_inserter(keys), keys.size() * (100 - hitPercentage) / 100, random);
|
||||||
std::size_t n = 0;
|
std::size_t n = 0;
|
||||||
|
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
const auto& key = keys[n++ % keys.size()];
|
const auto& key = keys[n++ % keys.size()];
|
||||||
auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh);
|
auto result = cache.get(key.mAgentBounds, key.mTilePosition, key.mRecastMesh);
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace
|
||||||
std::minstd_rand random;
|
std::minstd_rand random;
|
||||||
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
|
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(refIds[i].serialize());
|
benchmark::DoNotOptimize(refIds[i].serialize());
|
||||||
if (++i >= refIds.size())
|
if (++i >= refIds.size())
|
||||||
|
@ -118,7 +118,7 @@ namespace
|
||||||
std::vector<std::string> serializedRefIds
|
std::vector<std::string> serializedRefIds
|
||||||
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serialize(); });
|
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serialize(); });
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(ESM::RefId::deserialize(serializedRefIds[i]));
|
benchmark::DoNotOptimize(ESM::RefId::deserialize(serializedRefIds[i]));
|
||||||
if (++i >= serializedRefIds.size())
|
if (++i >= serializedRefIds.size())
|
||||||
|
@ -131,7 +131,7 @@ namespace
|
||||||
std::minstd_rand random;
|
std::minstd_rand random;
|
||||||
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
|
std::vector<ESM::RefId> refIds = generateStringRefIds(state.range(0), random);
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(refIds[i].serializeText());
|
benchmark::DoNotOptimize(refIds[i].serializeText());
|
||||||
if (++i >= refIds.size())
|
if (++i >= refIds.size())
|
||||||
|
@ -145,7 +145,7 @@ namespace
|
||||||
std::vector<std::string> serializedRefIds
|
std::vector<std::string> serializedRefIds
|
||||||
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serializeText(); });
|
= generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serializeText(); });
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
||||||
if (++i >= serializedRefIds.size())
|
if (++i >= serializedRefIds.size())
|
||||||
|
@ -158,7 +158,7 @@ namespace
|
||||||
std::minstd_rand random;
|
std::minstd_rand random;
|
||||||
std::vector<ESM::RefId> refIds = generateGeneratedRefIds(random);
|
std::vector<ESM::RefId> refIds = generateGeneratedRefIds(random);
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(refIds[i].serializeText());
|
benchmark::DoNotOptimize(refIds[i].serializeText());
|
||||||
if (++i >= refIds.size())
|
if (++i >= refIds.size())
|
||||||
|
@ -172,7 +172,7 @@ namespace
|
||||||
std::vector<std::string> serializedRefIds
|
std::vector<std::string> serializedRefIds
|
||||||
= generateSerializedGeneratedRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
= generateSerializedGeneratedRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
||||||
if (++i >= serializedRefIds.size())
|
if (++i >= serializedRefIds.size())
|
||||||
|
@ -185,7 +185,7 @@ namespace
|
||||||
std::minstd_rand random;
|
std::minstd_rand random;
|
||||||
std::vector<ESM::RefId> refIds = generateIndexRefIds(random);
|
std::vector<ESM::RefId> refIds = generateIndexRefIds(random);
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(refIds[i].serializeText());
|
benchmark::DoNotOptimize(refIds[i].serializeText());
|
||||||
if (++i >= refIds.size())
|
if (++i >= refIds.size())
|
||||||
|
@ -199,7 +199,7 @@ namespace
|
||||||
std::vector<std::string> serializedRefIds
|
std::vector<std::string> serializedRefIds
|
||||||
= generateSerializedIndexRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
= generateSerializedIndexRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
||||||
if (++i >= serializedRefIds.size())
|
if (++i >= serializedRefIds.size())
|
||||||
|
@ -212,7 +212,7 @@ namespace
|
||||||
std::minstd_rand random;
|
std::minstd_rand random;
|
||||||
std::vector<ESM::RefId> refIds = generateESM3ExteriorCellRefIds(random);
|
std::vector<ESM::RefId> refIds = generateESM3ExteriorCellRefIds(random);
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(refIds[i].serializeText());
|
benchmark::DoNotOptimize(refIds[i].serializeText());
|
||||||
if (++i >= refIds.size())
|
if (++i >= refIds.size())
|
||||||
|
@ -226,7 +226,7 @@ namespace
|
||||||
std::vector<std::string> serializedRefIds
|
std::vector<std::string> serializedRefIds
|
||||||
= generateSerializedESM3ExteriorCellRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
= generateSerializedESM3ExteriorCellRefIds(random, [](ESM::RefId v) { return v.serializeText(); });
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
benchmark::DoNotOptimize(ESM::RefId::deserializeText(serializedRefIds[i]));
|
||||||
if (++i >= serializedRefIds.size())
|
if (++i >= serializedRefIds.size())
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace
|
||||||
{
|
{
|
||||||
void settingsManager(benchmark::State& state)
|
void settingsManager(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::Manager::getFloat("sky blending start", "Fog"));
|
benchmark::DoNotOptimize(Settings::Manager::getFloat("sky blending start", "Fog"));
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace
|
||||||
|
|
||||||
void settingsManager2(benchmark::State& state)
|
void settingsManager2(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
|
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
|
||||||
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
|
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
|
||||||
|
@ -26,7 +26,7 @@ namespace
|
||||||
|
|
||||||
void settingsManager3(benchmark::State& state)
|
void settingsManager3(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
|
benchmark::DoNotOptimize(Settings::Manager::getFloat("near clip", "Camera"));
|
||||||
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
|
benchmark::DoNotOptimize(Settings::Manager::getBool("transparent postpass", "Post Processing"));
|
||||||
|
@ -36,7 +36,7 @@ namespace
|
||||||
|
|
||||||
void localStatic(benchmark::State& state)
|
void localStatic(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
static float v = Settings::Manager::getFloat("sky blending start", "Fog");
|
static float v = Settings::Manager::getFloat("sky blending start", "Fog");
|
||||||
benchmark::DoNotOptimize(v);
|
benchmark::DoNotOptimize(v);
|
||||||
|
@ -45,7 +45,7 @@ namespace
|
||||||
|
|
||||||
void localStatic2(benchmark::State& state)
|
void localStatic2(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
||||||
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
||||||
|
@ -56,7 +56,7 @@ namespace
|
||||||
|
|
||||||
void localStatic3(benchmark::State& state)
|
void localStatic3(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
static float v1 = Settings::Manager::getFloat("near clip", "Camera");
|
||||||
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
static bool v2 = Settings::Manager::getBool("transparent postpass", "Post Processing");
|
||||||
|
@ -69,7 +69,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorage(benchmark::State& state)
|
void settingsStorage(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
float v = Settings::fog().mSkyBlendingStart.get();
|
float v = Settings::fog().mSkyBlendingStart.get();
|
||||||
benchmark::DoNotOptimize(v);
|
benchmark::DoNotOptimize(v);
|
||||||
|
@ -78,7 +78,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorage2(benchmark::State& state)
|
void settingsStorage2(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
||||||
float v2 = Settings::camera().mNearClip.get();
|
float v2 = Settings::camera().mNearClip.get();
|
||||||
|
@ -89,7 +89,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorage3(benchmark::State& state)
|
void settingsStorage3(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
bool v1 = Settings::postProcessing().mTransparentPostpass.get();
|
||||||
float v2 = Settings::camera().mNearClip.get();
|
float v2 = Settings::camera().mNearClip.get();
|
||||||
|
@ -102,7 +102,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorageGet(benchmark::State& state)
|
void settingsStorageGet(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::get<float>("Fog", "sky blending start"));
|
benchmark::DoNotOptimize(Settings::get<float>("Fog", "sky blending start"));
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorageGet2(benchmark::State& state)
|
void settingsStorageGet2(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
|
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
|
||||||
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));
|
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));
|
||||||
|
@ -119,7 +119,7 @@ namespace
|
||||||
|
|
||||||
void settingsStorageGet3(benchmark::State& state)
|
void settingsStorageGet3(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state)
|
for ([[maybe_unused]] auto _ : state)
|
||||||
{
|
{
|
||||||
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
|
benchmark::DoNotOptimize(Settings::get<bool>("Post Processing", "transparent postpass"));
|
||||||
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));
|
benchmark::DoNotOptimize(Settings::get<float>("Camera", "near clip"));
|
||||||
|
|
|
@ -75,8 +75,8 @@ Allowed options)");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
|
bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
|
||||||
bpo::store(valid_opts, variables);
|
bpo::store(validOpts, variables);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <components/resource/niffilemanager.hpp>
|
#include <components/resource/niffilemanager.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/vfs/registerarchives.hpp>
|
#include <components/vfs/registerarchives.hpp>
|
||||||
|
@ -53,8 +53,6 @@ namespace
|
||||||
|
|
||||||
bpo::options_description makeOptionsDescription()
|
bpo::options_description makeOptionsDescription()
|
||||||
{
|
{
|
||||||
using Fallback::FallbackMap;
|
|
||||||
|
|
||||||
bpo::options_description result;
|
bpo::options_description result;
|
||||||
auto addOption = result.add_options();
|
auto addOption = result.add_options();
|
||||||
addOption("help", "print help message");
|
addOption("help", "print help message");
|
||||||
|
@ -87,7 +85,8 @@ namespace
|
||||||
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||||
"\n\twin1252 - Western European (Latin) alphabet, used by default");
|
"\n\twin1252 - Western European (Latin) alphabet, used by default");
|
||||||
|
|
||||||
addOption("fallback", bpo::value<FallbackMap>()->default_value(FallbackMap(), "")->multitoken()->composing(),
|
addOption("fallback",
|
||||||
|
bpo::value<Fallback::FallbackMap>()->default_value(Fallback::FallbackMap(), "")->multitoken()->composing(),
|
||||||
"fallback values");
|
"fallback values");
|
||||||
|
|
||||||
Files::ConfigurationManager::addCommonOptions(result);
|
Files::ConfigurationManager::addCommonOptions(result);
|
||||||
|
@ -126,6 +125,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
Files::ConfigurationManager config;
|
Files::ConfigurationManager config;
|
||||||
|
config.processPaths(variables, std::filesystem::current_path());
|
||||||
config.readConfiguration(variables, desc);
|
config.readConfiguration(variables, desc);
|
||||||
|
|
||||||
Debug::setupLogging(config.getLogPath(), applicationName);
|
Debug::setupLogging(config.getLogPath(), applicationName);
|
||||||
|
@ -155,7 +155,7 @@ namespace
|
||||||
|
|
||||||
VFS::Manager vfs;
|
VFS::Manager vfs;
|
||||||
|
|
||||||
VFS::registerArchives(&vfs, fileCollections, archives, true);
|
VFS::registerArchives(&vfs, fileCollections, archives, true, &encoder.getStatelessEncoder());
|
||||||
|
|
||||||
Settings::Manager::load(config);
|
Settings::Manager::load(config);
|
||||||
|
|
||||||
|
|
|
@ -4,29 +4,28 @@ include_directories(SYSTEM ${GMOCK_INCLUDE_DIRS})
|
||||||
file(GLOB UNITTEST_SRC_FILES
|
file(GLOB UNITTEST_SRC_FILES
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
esm/test_fixed_string.cpp
|
esm/testfixedstring.cpp
|
||||||
esm/variant.cpp
|
|
||||||
esm/testrefid.cpp
|
esm/testrefid.cpp
|
||||||
|
esm/variant.cpp
|
||||||
|
|
||||||
lua/test_lua.cpp
|
lua/testasync.cpp
|
||||||
lua/test_scriptscontainer.cpp
|
lua/testconfiguration.cpp
|
||||||
lua/test_utilpackage.cpp
|
lua/testinputactions.cpp
|
||||||
lua/test_serialization.cpp
|
lua/testl10n.cpp
|
||||||
lua/test_configuration.cpp
|
lua/testlua.cpp
|
||||||
lua/test_l10n.cpp
|
lua/testscriptscontainer.cpp
|
||||||
lua/test_storage.cpp
|
lua/testserialization.cpp
|
||||||
lua/test_async.cpp
|
lua/teststorage.cpp
|
||||||
lua/test_inputactions.cpp
|
lua/testuicontent.cpp
|
||||||
lua/test_yaml.cpp
|
lua/testutilpackage.cpp
|
||||||
|
lua/testyaml.cpp
|
||||||
lua/test_ui_content.cpp
|
|
||||||
|
|
||||||
misc/compression.cpp
|
misc/compression.cpp
|
||||||
misc/progressreporter.cpp
|
misc/progressreporter.cpp
|
||||||
misc/test_endianness.cpp
|
misc/testendianness.cpp
|
||||||
misc/test_resourcehelpers.cpp
|
|
||||||
misc/test_stringops.cpp
|
|
||||||
misc/testmathutil.cpp
|
misc/testmathutil.cpp
|
||||||
|
misc/testresourcehelpers.cpp
|
||||||
|
misc/teststringops.cpp
|
||||||
|
|
||||||
nifloader/testbulletnifloader.cpp
|
nifloader/testbulletnifloader.cpp
|
||||||
|
|
||||||
|
@ -64,8 +63,8 @@ file(GLOB UNITTEST_SRC_FILES
|
||||||
esmloader/esmdata.cpp
|
esmloader/esmdata.cpp
|
||||||
esmloader/record.cpp
|
esmloader/record.cpp
|
||||||
|
|
||||||
|
files/conversiontests.cpp
|
||||||
files/hash.cpp
|
files/hash.cpp
|
||||||
files/conversion_tests.cpp
|
|
||||||
|
|
||||||
toutf8/toutf8.cpp
|
toutf8/toutf8.cpp
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
#include <components/detournavigator/makenavmesh.hpp>
|
#include <components/detournavigator/makenavmesh.hpp>
|
||||||
#include <components/detournavigator/navmeshdbutils.hpp>
|
#include <components/detournavigator/navmeshdbutils.hpp>
|
||||||
#include <components/detournavigator/serialization.hpp>
|
#include <components/detournavigator/serialization.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
#include <components/loadinglistener/loadinglistener.hpp>
|
#include <components/loadinglistener/loadinglistener.hpp>
|
||||||
|
#include <components/testing/util.hpp>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
#include <BulletCollision/CollisionShapes/btBoxShape.h>
|
||||||
|
|
||||||
|
@ -372,6 +374,106 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_recast_mesh)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteRecastMeshToFile = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
|
||||||
|
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_TRUE(std::filesystem::exists(dir / "0.0.recastmesh.obj"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_recast_mesh_with_revision)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteRecastMeshToFile = true;
|
||||||
|
mSettings.mEnableRecastMeshFileNameRevision = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
|
||||||
|
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_TRUE(std::filesystem::exists(dir / "0.0.recastmesh.1.2.obj"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, writing_recast_mesh_to_absent_file_should_not_fail_tile_generation)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteRecastMeshToFile = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDir() / "absent";
|
||||||
|
mSettings.mRecastMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_NE(navMeshCacheItem->lockConst()->getImpl().getTileRefAt(0, 0, 0), 0u);
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_navmesh)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteNavMeshToFile = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
|
||||||
|
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_TRUE(std::filesystem::exists(dir / "all_tiles_navmesh.bin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, should_write_debug_navmesh_with_revision)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteNavMeshToFile = true;
|
||||||
|
mSettings.mEnableNavMeshFileNameRevision = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDirPath("DetourNavigatorAsyncNavMeshUpdaterTest");
|
||||||
|
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_TRUE(std::filesystem::exists(dir / "all_tiles_navmesh.1.1.bin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorAsyncNavMeshUpdaterTest, writing_navmesh_to_absent_file_should_not_fail_tile_generation)
|
||||||
|
{
|
||||||
|
mRecastMeshManager.setWorldspace(mWorldspace, nullptr);
|
||||||
|
addHeightFieldPlane(mRecastMeshManager);
|
||||||
|
mSettings.mEnableWriteNavMeshToFile = true;
|
||||||
|
const std::filesystem::path dir = TestingOpenMW::outputDir() / "absent";
|
||||||
|
mSettings.mNavMeshPathPrefix = Files::pathToUnicodeString(dir) + "/";
|
||||||
|
Log(Debug::Verbose) << mSettings.mRecastMeshPathPrefix;
|
||||||
|
AsyncNavMeshUpdater updater(mSettings, mRecastMeshManager, mOffMeshConnectionsManager, nullptr);
|
||||||
|
const auto navMeshCacheItem = std::make_shared<GuardedNavMeshCacheItem>(1, mSettings);
|
||||||
|
const std::map<TilePosition, ChangeType> changedTiles{ { TilePosition{ 0, 0 }, ChangeType::add } };
|
||||||
|
updater.post(mAgentBounds, navMeshCacheItem, mPlayerTile, mWorldspace, changedTiles);
|
||||||
|
updater.wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
EXPECT_NE(navMeshCacheItem->lockConst()->getImpl().getTileRefAt(0, 0, 0), 0u);
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(dir));
|
||||||
|
}
|
||||||
|
|
||||||
struct DetourNavigatorSpatialJobQueueTest : Test
|
struct DetourNavigatorSpatialJobQueueTest : Test
|
||||||
{
|
{
|
||||||
const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, osg::Vec3f(1, 1, 1) };
|
const AgentBounds mAgentBounds{ CollisionShapeType::Aabb, osg::Vec3f(1, 1, 1) };
|
||||||
|
|
|
@ -139,7 +139,7 @@ namespace
|
||||||
|
|
||||||
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
|
TEST_F(DetourNavigatorNavigatorTest, find_path_for_empty_should_return_empty)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::NavMeshNotFound);
|
Status::NavMeshNotFound);
|
||||||
EXPECT_EQ(mPath, std::deque<osg::Vec3f>());
|
EXPECT_EQ(mPath, std::deque<osg::Vec3f>());
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ namespace
|
||||||
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
|
TEST_F(DetourNavigatorNavigatorTest, find_path_for_existing_agent_with_no_navmesh_should_throw_exception)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::StartPolygonNotFound);
|
Status::StartPolygonNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ namespace
|
||||||
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
mNavigator->removeAgent(mAgentBounds);
|
mNavigator->removeAgent(mAgentBounds);
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::StartPolygonNotFound);
|
Status::StartPolygonNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ namespace
|
||||||
updateGuard.reset();
|
updateGuard.reset();
|
||||||
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -194,7 +194,7 @@ namespace
|
||||||
updateGuard.reset();
|
updateGuard.reset();
|
||||||
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mStart, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mStart, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath, ElementsAre(Vec3fEq(56.66666412353515625, 460, 1.99998295307159423828125))) << mPath;
|
EXPECT_THAT(mPath, ElementsAre(Vec3fEq(56.66666412353515625, 460, 1.99998295307159423828125))) << mPath;
|
||||||
|
@ -218,7 +218,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -237,7 +237,7 @@ namespace
|
||||||
|
|
||||||
mPath.clear();
|
mPath.clear();
|
||||||
mOut = std::back_inserter(mPath);
|
mOut = std::back_inserter(mPath);
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -265,7 +265,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -285,7 +285,7 @@ namespace
|
||||||
|
|
||||||
mPath.clear();
|
mPath.clear();
|
||||||
mOut = std::back_inserter(mPath);
|
mOut = std::back_inserter(mPath);
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -318,7 +318,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -386,7 +386,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -421,7 +421,7 @@ namespace
|
||||||
mEnd.x() = 256;
|
mEnd.x() = 256;
|
||||||
mEnd.z() = 300;
|
mEnd.z() = 300;
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -453,8 +453,8 @@ namespace
|
||||||
mStart.x() = 256;
|
mStart.x() = 256;
|
||||||
mEnd.x() = 256;
|
mEnd.x() = 256;
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance,
|
||||||
findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
{}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -487,8 +487,8 @@ namespace
|
||||||
mStart.x() = 256;
|
mStart.x() = 256;
|
||||||
mEnd.x() = 256;
|
mEnd.x() = 256;
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance,
|
||||||
findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_swim | Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
{}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -520,7 +520,7 @@ namespace
|
||||||
mStart.x() = 256;
|
mStart.x() = 256;
|
||||||
mEnd.x() = 256;
|
mEnd.x() = 256;
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -549,7 +549,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -577,7 +577,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -658,7 +658,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -781,7 +781,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
mNavigator->wait(WaitConditionType::requiredTilesPresent, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -806,7 +806,7 @@ namespace
|
||||||
mNavigator->update(mPlayerPosition, nullptr);
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
Status::PartialPath);
|
Status::PartialPath);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -834,7 +834,7 @@ namespace
|
||||||
|
|
||||||
const float endTolerance = 1000.0f;
|
const float endTolerance = 1000.0f;
|
||||||
|
|
||||||
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, mOut),
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, mStart, mEnd, Flag_walk, mAreaCosts, endTolerance, {}, mOut),
|
||||||
Status::Success);
|
Status::Success);
|
||||||
|
|
||||||
EXPECT_THAT(mPath,
|
EXPECT_THAT(mPath,
|
||||||
|
@ -979,6 +979,146 @@ namespace
|
||||||
EXPECT_EQ(usedNavMeshTiles, 854);
|
EXPECT_EQ(usedNavMeshTiles, 854);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_around_steep_mountains)
|
||||||
|
{
|
||||||
|
const std::array<float, 5 * 5> heightfieldData{ {
|
||||||
|
0, 0, 0, 0, 0, // row 0
|
||||||
|
0, 0, 0, 0, 0, // row 1
|
||||||
|
0, 0, 1000, 0, 0, // row 2
|
||||||
|
0, 0, 1000, 0, 0, // row 3
|
||||||
|
0, 0, 0, 0, 0, // row 4
|
||||||
|
} };
|
||||||
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
|
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
|
||||||
|
|
||||||
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
|
const osg::Vec3f start(56, 56, 12);
|
||||||
|
const osg::Vec3f end(464, 464, 12);
|
||||||
|
|
||||||
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
|
Status::Success);
|
||||||
|
|
||||||
|
EXPECT_THAT(mPath,
|
||||||
|
ElementsAre( //
|
||||||
|
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
|
||||||
|
Vec3fEq(396.666656494140625, 79.33331298828125, 11.33333301544189453125),
|
||||||
|
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
|
||||||
|
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
|
||||||
|
<< mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_around_steep_cliffs)
|
||||||
|
{
|
||||||
|
const std::array<float, 5 * 5> heightfieldData{ {
|
||||||
|
0, 0, 0, 0, 0, // row 0
|
||||||
|
0, 0, 0, 0, 0, // row 1
|
||||||
|
0, 0, -1000, 0, 0, // row 2
|
||||||
|
0, 0, -1000, 0, 0, // row 3
|
||||||
|
0, 0, 0, 0, 0, // row 4
|
||||||
|
} };
|
||||||
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
|
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
|
||||||
|
|
||||||
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
|
const osg::Vec3f start(56, 56, 12);
|
||||||
|
const osg::Vec3f end(464, 464, 12);
|
||||||
|
|
||||||
|
EXPECT_EQ(findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, {}, mOut),
|
||||||
|
Status::Success);
|
||||||
|
|
||||||
|
EXPECT_THAT(mPath,
|
||||||
|
ElementsAre( //
|
||||||
|
Vec3fEq(56.66664886474609375, 56.66664886474609375, 8.66659259796142578125),
|
||||||
|
Vec3fEq(385.33331298828125, 79.33331298828125, 8.66659259796142578125),
|
||||||
|
Vec3fEq(430.666656494140625, 124.66664886474609375, 8.66659259796142578125),
|
||||||
|
Vec3fEq(463.999969482421875, 463.999969482421875, 8.66659259796142578125)))
|
||||||
|
<< mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavigatorTest, find_path_should_return_path_with_checkpoints)
|
||||||
|
{
|
||||||
|
const std::array<float, 5 * 5> heightfieldData{ {
|
||||||
|
0, 0, 0, 0, 0, // row 0
|
||||||
|
0, 0, 0, 0, 0, // row 1
|
||||||
|
0, 0, 1000, 0, 0, // row 2
|
||||||
|
0, 0, 1000, 0, 0, // row 3
|
||||||
|
0, 0, 0, 0, 0, // row 4
|
||||||
|
} };
|
||||||
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
|
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
|
||||||
|
|
||||||
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
|
const std::vector<osg::Vec3f> checkpoints = {
|
||||||
|
osg::Vec3f(400, 70, 12),
|
||||||
|
};
|
||||||
|
|
||||||
|
const osg::Vec3f start(56, 56, 12);
|
||||||
|
const osg::Vec3f end(464, 464, 12);
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, checkpoints, mOut),
|
||||||
|
Status::Success);
|
||||||
|
|
||||||
|
EXPECT_THAT(mPath,
|
||||||
|
ElementsAre( //
|
||||||
|
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
|
||||||
|
Vec3fEq(400, 70, 11.33333301544189453125),
|
||||||
|
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
|
||||||
|
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
|
||||||
|
<< mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavigatorTest, find_path_should_skip_unreachable_checkpoints)
|
||||||
|
{
|
||||||
|
const std::array<float, 5 * 5> heightfieldData{ {
|
||||||
|
0, 0, 0, 0, 0, // row 0
|
||||||
|
0, 0, 0, 0, 0, // row 1
|
||||||
|
0, 0, 1000, 0, 0, // row 2
|
||||||
|
0, 0, 1000, 0, 0, // row 3
|
||||||
|
0, 0, 0, 0, 0, // row 4
|
||||||
|
} };
|
||||||
|
const HeightfieldSurface surface = makeSquareHeightfieldSurface(heightfieldData);
|
||||||
|
const int cellSize = heightfieldTileSize * static_cast<int>(surface.mSize - 1);
|
||||||
|
|
||||||
|
ASSERT_TRUE(mNavigator->addAgent(mAgentBounds));
|
||||||
|
mNavigator->addHeightfield(mCellPosition, cellSize, surface, nullptr);
|
||||||
|
mNavigator->update(mPlayerPosition, nullptr);
|
||||||
|
mNavigator->wait(WaitConditionType::allJobsDone, &mListener);
|
||||||
|
|
||||||
|
const std::vector<osg::Vec3f> checkpoints = {
|
||||||
|
osg::Vec3f(400, 70, 10000),
|
||||||
|
osg::Vec3f(256, 256, 1000),
|
||||||
|
osg::Vec3f(-1000, -1000, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
const osg::Vec3f start(56, 56, 12);
|
||||||
|
const osg::Vec3f end(464, 464, 12);
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
findPath(*mNavigator, mAgentBounds, start, end, Flag_walk, mAreaCosts, mEndTolerance, checkpoints, mOut),
|
||||||
|
Status::Success);
|
||||||
|
|
||||||
|
EXPECT_THAT(mPath,
|
||||||
|
ElementsAre( //
|
||||||
|
Vec3fEq(56.66664886474609375, 56.66664886474609375, 11.33333301544189453125),
|
||||||
|
Vec3fEq(396.666656494140625, 79.33331298828125, 11.33333301544189453125),
|
||||||
|
Vec3fEq(430.666656494140625, 113.33331298828125, 11.33333301544189453125),
|
||||||
|
Vec3fEq(463.999969482421875, 463.999969482421875, 11.33333301544189453125)))
|
||||||
|
<< mPath;
|
||||||
|
}
|
||||||
|
|
||||||
struct DetourNavigatorNavigatorNotSupportedAgentBoundsTest : TestWithParam<AgentBounds>
|
struct DetourNavigatorNavigatorNotSupportedAgentBoundsTest : TestWithParam<AgentBounds>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,19 +74,20 @@ namespace
|
||||||
|
|
||||||
TEST(EsmFixedString, empty_strings)
|
TEST(EsmFixedString, empty_strings)
|
||||||
{
|
{
|
||||||
|
constexpr std::string_view someStr = "some string";
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("4 bytes");
|
SCOPED_TRACE("4 bytes");
|
||||||
ESM::NAME empty = ESM::NAME();
|
ESM::NAME empty = ESM::NAME();
|
||||||
EXPECT_TRUE(empty == "");
|
EXPECT_TRUE(empty == "");
|
||||||
EXPECT_TRUE(empty == static_cast<uint32_t>(0));
|
EXPECT_TRUE(empty == static_cast<uint32_t>(0));
|
||||||
EXPECT_TRUE(empty != "some string");
|
EXPECT_TRUE(empty != someStr);
|
||||||
EXPECT_TRUE(empty != static_cast<uint32_t>(42));
|
EXPECT_TRUE(empty != static_cast<uint32_t>(42));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("32 bytes");
|
SCOPED_TRACE("32 bytes");
|
||||||
ESM::NAME32 empty = ESM::NAME32();
|
ESM::NAME32 empty = ESM::NAME32();
|
||||||
EXPECT_TRUE(empty == "");
|
EXPECT_TRUE(empty == "");
|
||||||
EXPECT_TRUE(empty != "some string");
|
EXPECT_TRUE(empty != someStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,4 +88,31 @@ namespace
|
||||||
EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
|
EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ESM3ReadersCacheWithContentFile, CachedSizeAndName)
|
||||||
|
{
|
||||||
|
ESM::ReadersCache readers(2);
|
||||||
|
{
|
||||||
|
readers.get(0)->openRaw(std::make_unique<std::istringstream>("123"), "closed0.omwaddon");
|
||||||
|
readers.get(1)->openRaw(std::make_unique<std::istringstream>("12345"), "closed1.omwaddon");
|
||||||
|
readers.get(2)->openRaw(std::make_unique<std::istringstream>("1234567"), "free.omwaddon");
|
||||||
|
}
|
||||||
|
auto busy = readers.get(3);
|
||||||
|
busy->openRaw(std::make_unique<std::istringstream>("123456789"), "busy.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(0), 3);
|
||||||
|
EXPECT_EQ(readers.getName(0), "closed0.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(1), 5);
|
||||||
|
EXPECT_EQ(readers.getName(1), "closed1.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(2), 7);
|
||||||
|
EXPECT_EQ(readers.getName(2), "free.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(3), 9);
|
||||||
|
EXPECT_EQ(readers.getName(3), "busy.omwaddon");
|
||||||
|
|
||||||
|
// not-yet-seen indices give zero for their size
|
||||||
|
EXPECT_EQ(readers.getFileSize(4), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -723,7 +723,7 @@ namespace ESM
|
||||||
TEST_P(Esm3SaveLoadRecordTest, landShouldNotChange)
|
TEST_P(Esm3SaveLoadRecordTest, landShouldNotChange)
|
||||||
{
|
{
|
||||||
LandRecordData data;
|
LandRecordData data;
|
||||||
std::iota(data.mHeights.begin(), data.mHeights.end(), 1);
|
std::iota(data.mHeights.begin(), data.mHeights.end(), 1.0f);
|
||||||
std::for_each(data.mHeights.begin(), data.mHeights.end(), [](float& v) { v *= Land::sHeightScale; });
|
std::for_each(data.mHeights.begin(), data.mHeights.end(), [](float& v) { v *= Land::sHeightScale; });
|
||||||
data.mMinHeight = *std::min_element(data.mHeights.begin(), data.mHeights.end());
|
data.mMinHeight = *std::min_element(data.mHeights.begin(), data.mHeights.end());
|
||||||
data.mMaxHeight = *std::max_element(data.mHeights.begin(), data.mHeights.end());
|
data.mMaxHeight = *std::max_element(data.mHeights.begin(), data.mHeights.end());
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <components/esmloader/load.hpp>
|
#include <components/esmloader/load.hpp>
|
||||||
#include <components/files/collections.hpp>
|
#include <components/files/collections.hpp>
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace
|
||||||
|
|
||||||
TEST(FilesGetHash, shouldClearErrors)
|
TEST(FilesGetHash, shouldClearErrors)
|
||||||
{
|
{
|
||||||
const auto fileName = temporaryFilePath("fileName");
|
const auto fileName = outputFilePath("fileName");
|
||||||
std::string content;
|
std::string content;
|
||||||
std::fill_n(std::back_inserter(content), 1, 'a');
|
std::fill_n(std::back_inserter(content), 1, 'a');
|
||||||
std::istringstream stream(content);
|
std::istringstream stream(content);
|
||||||
|
@ -41,7 +41,7 @@ namespace
|
||||||
|
|
||||||
TEST_P(FilesGetHash, shouldReturnHashForStringStream)
|
TEST_P(FilesGetHash, shouldReturnHashForStringStream)
|
||||||
{
|
{
|
||||||
const auto fileName = temporaryFilePath("fileName");
|
const auto fileName = outputFilePath("fileName");
|
||||||
std::string content;
|
std::string content;
|
||||||
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
std::fill_n(std::back_inserter(content), GetParam().mSize, 'a');
|
||||||
std::istringstream stream(content);
|
std::istringstream stream(content);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
using namespace fx::Lexer;
|
using namespace Fx::Lexer;
|
||||||
|
|
||||||
struct LexerTest : Test
|
struct LexerTest : Test
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace
|
||||||
)" };
|
)" };
|
||||||
|
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
using namespace fx;
|
using namespace Fx;
|
||||||
|
|
||||||
struct TechniqueTest : Test
|
struct TechniqueTest : Test
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,8 @@ namespace
|
||||||
|
|
||||||
void compile(const std::string& name)
|
void compile(const std::string& name)
|
||||||
{
|
{
|
||||||
mTechnique = std::make_unique<Technique>(*mVFS.get(), mImageManager, name, 1, 1, true, true);
|
mTechnique = std::make_unique<Technique>(
|
||||||
|
*mVFS.get(), mImageManager, Technique::makeFileName(name), name, 1, 1, true, true);
|
||||||
mTechnique->compile();
|
mTechnique->compile();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,10 +38,10 @@ namespace
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
LuaUtil::InputAction::Registry registry;
|
LuaUtil::InputAction::Registry registry;
|
||||||
LuaUtil::InputAction::Info a({ "a", LuaUtil::InputAction::Type::Boolean, "test", "a_name", "a_description",
|
LuaUtil::InputAction::Info a({ "a", LuaUtil::InputAction::Type::Boolean, "test", "a_name", "a_description",
|
||||||
sol::make_object(lua, false) });
|
sol::make_object(lua, false), false });
|
||||||
registry.insert(a);
|
registry.insert(a);
|
||||||
LuaUtil::InputAction::Info b({ "b", LuaUtil::InputAction::Type::Boolean, "test", "b_name", "b_description",
|
LuaUtil::InputAction::Info b({ "b", LuaUtil::InputAction::Type::Boolean, "test", "b_name", "b_description",
|
||||||
sol::make_object(lua, false) });
|
sol::make_object(lua, false), false });
|
||||||
registry.insert(b);
|
registry.insert(b);
|
||||||
LuaUtil::Callback bindA({ lua.load("return function() return true end")(), sol::table(lua, sol::create) });
|
LuaUtil::Callback bindA({ lua.load("return function() return true end")(), sol::table(lua, sol::create) });
|
||||||
LuaUtil::Callback bindBToA(
|
LuaUtil::Callback bindBToA(
|
|
@ -24,6 +24,8 @@ namespace
|
||||||
constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml");
|
constexpr VFS::Path::NormalizedView test2EnPath("l10n/test2/en.yaml");
|
||||||
constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml");
|
constexpr VFS::Path::NormalizedView test3EnPath("l10n/test3/en.yaml");
|
||||||
constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml");
|
constexpr VFS::Path::NormalizedView test3DePath("l10n/test3/de.yaml");
|
||||||
|
constexpr VFS::Path::NormalizedView test4RuPath("l10n/test4/ru.yaml");
|
||||||
|
constexpr VFS::Path::NormalizedView test4EnPath("l10n/test4/en.yaml");
|
||||||
|
|
||||||
VFSTestFile invalidScript("not a script");
|
VFSTestFile invalidScript("not a script");
|
||||||
VFSTestFile incorrectScript(
|
VFSTestFile incorrectScript(
|
||||||
|
@ -69,6 +71,16 @@ currency: "You have {money, number, currency}"
|
||||||
VFSTestFile test2En(R"X(
|
VFSTestFile test2En(R"X(
|
||||||
good_morning: "Morning!"
|
good_morning: "Morning!"
|
||||||
you_have_arrows: "Arrows count: {count}"
|
you_have_arrows: "Arrows count: {count}"
|
||||||
|
)X");
|
||||||
|
|
||||||
|
VFSTestFile test4Ru(R"X(
|
||||||
|
skill_increase: "Ваш навык {навык} увеличился до {value}"
|
||||||
|
acrobatics: "Акробатика"
|
||||||
|
)X");
|
||||||
|
|
||||||
|
VFSTestFile test4En(R"X(
|
||||||
|
stat_increase: "Your {stat} has increased to {value}"
|
||||||
|
speed: "Speed"
|
||||||
)X");
|
)X");
|
||||||
|
|
||||||
struct LuaL10nTest : Test
|
struct LuaL10nTest : Test
|
||||||
|
@ -80,6 +92,8 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
{ test2EnPath, &test2En },
|
{ test2EnPath, &test2En },
|
||||||
{ test3EnPath, &test1En },
|
{ test3EnPath, &test1En },
|
||||||
{ test3DePath, &test1De },
|
{ test3DePath, &test1De },
|
||||||
|
{ test4RuPath, &test4Ru },
|
||||||
|
{ test4EnPath, &test4En },
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaUtil::ScriptsConfiguration mCfg;
|
LuaUtil::ScriptsConfiguration mCfg;
|
||||||
|
@ -91,7 +105,7 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
lua.protectedCall([&](LuaUtil::LuaView& view) {
|
lua.protectedCall([&](LuaUtil::LuaView& view) {
|
||||||
sol::state_view& l = view.sol();
|
sol::state_view& l = view.sol();
|
||||||
internal::CaptureStdout();
|
internal::CaptureStdout();
|
||||||
l10n::Manager l10nManager(mVFS.get());
|
L10n::Manager l10nManager(mVFS.get());
|
||||||
l10nManager.setPreferredLocales({ "de", "en" });
|
l10nManager.setPreferredLocales({ "de", "en" });
|
||||||
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
|
EXPECT_THAT(internal::GetCapturedStdout(), "Preferred locales: gmst de en\n");
|
||||||
|
|
||||||
|
@ -169,6 +183,18 @@ you_have_arrows: "Arrows count: {count}"
|
||||||
l.safe_script("t3 = l10n('Test3', 'de')");
|
l.safe_script("t3 = l10n('Test3', 'de')");
|
||||||
l10nManager.setPreferredLocales({ "en" });
|
l10nManager.setPreferredLocales({ "en" });
|
||||||
EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!");
|
EXPECT_EQ(get<std::string>(l, "t3('Hello {name}!', {name='World'})"), "Hallo World!");
|
||||||
|
|
||||||
|
// Test that formatting arguments use a correct encoding
|
||||||
|
l.safe_script("t4 = l10n('Test4', 'ru')");
|
||||||
|
l10nManager.setPreferredLocales({ "ru", "en" });
|
||||||
|
EXPECT_EQ(get<std::string>(l, "t4('skill_increase', {навык='Акробатика', value=100})"),
|
||||||
|
"Ваш навык Акробатика увеличился до 100");
|
||||||
|
EXPECT_EQ(get<std::string>(l, "t4('skill_increase', {навык=t4('acrobatics'), value=100})"),
|
||||||
|
"Ваш навык Акробатика увеличился до 100");
|
||||||
|
EXPECT_EQ(get<std::string>(l, "t4('stat_increase', {stat='Speed', value=100})"),
|
||||||
|
"Your Speed has increased to 100");
|
||||||
|
EXPECT_EQ(get<std::string>(l, "t4('stat_increase', {stat=t4('speed'), value=100})"),
|
||||||
|
"Your Speed has increased to 100");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -285,17 +285,17 @@ CUSTOM: customdata.lua
|
||||||
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
||||||
|
|
||||||
sol::state_view sol = mLua.unsafeState();
|
sol::state_view sol = mLua.unsafeState();
|
||||||
std::string X0 = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
std::string x0 = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||||
std::string X1 = LuaUtil::serialize(sol.create_table_with("x", 1.5));
|
std::string x1 = LuaUtil::serialize(sol.create_table_with("x", 1.5));
|
||||||
|
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.receiveEvent("SomeEvent", X1);
|
scripts.receiveEvent("SomeEvent", x1);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(), "");
|
EXPECT_EQ(internal::GetCapturedStdout(), "");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.receiveEvent("Event1", X1);
|
scripts.receiveEvent("Event1", x1);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test2.lua]:\t event1 1.5\n"
|
"Test[test2.lua]:\t event1 1.5\n"
|
||||||
"Test[stopevent.lua]:\t event1 1.5\n"
|
"Test[stopevent.lua]:\t event1 1.5\n"
|
||||||
|
@ -303,21 +303,21 @@ CUSTOM: customdata.lua
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.receiveEvent("Event2", X1);
|
scripts.receiveEvent("Event2", x1);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test2.lua]:\t event2 1.5\n"
|
"Test[test2.lua]:\t event2 1.5\n"
|
||||||
"Test[test1.lua]:\t event2 1.5\n");
|
"Test[test1.lua]:\t event2 1.5\n");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.receiveEvent("Event1", X0);
|
scripts.receiveEvent("Event1", x0);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test2.lua]:\t event1 0.5\n"
|
"Test[test2.lua]:\t event1 0.5\n"
|
||||||
"Test[stopevent.lua]:\t event1 0.5\n");
|
"Test[stopevent.lua]:\t event1 0.5\n");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.receiveEvent("Event2", X0);
|
scripts.receiveEvent("Event2", x0);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test2.lua]:\t event2 0.5\n"
|
"Test[test2.lua]:\t event2 0.5\n"
|
||||||
"Test[test1.lua]:\t event2 0.5\n");
|
"Test[test1.lua]:\t event2 0.5\n");
|
||||||
|
@ -333,12 +333,12 @@ CUSTOM: customdata.lua
|
||||||
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
EXPECT_TRUE(scripts.addCustomScript(getId(test2Path)));
|
||||||
|
|
||||||
sol::state_view sol = mLua.unsafeState();
|
sol::state_view sol = mLua.unsafeState();
|
||||||
std::string X = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
std::string x = LuaUtil::serialize(sol.create_table_with("x", 0.5));
|
||||||
|
|
||||||
{
|
{
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.update(1.5f);
|
scripts.update(1.5f);
|
||||||
scripts.receiveEvent("Event1", X);
|
scripts.receiveEvent("Event1", x);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test1.lua]:\t update 1.5\n"
|
"Test[test1.lua]:\t update 1.5\n"
|
||||||
"Test[test2.lua]:\t update 1.5\n"
|
"Test[test2.lua]:\t update 1.5\n"
|
||||||
|
@ -352,7 +352,7 @@ CUSTOM: customdata.lua
|
||||||
scripts.removeScript(stopEventScriptId);
|
scripts.removeScript(stopEventScriptId);
|
||||||
EXPECT_FALSE(scripts.hasScript(stopEventScriptId));
|
EXPECT_FALSE(scripts.hasScript(stopEventScriptId));
|
||||||
scripts.update(1.5f);
|
scripts.update(1.5f);
|
||||||
scripts.receiveEvent("Event1", X);
|
scripts.receiveEvent("Event1", x);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test1.lua]:\t update 1.5\n"
|
"Test[test1.lua]:\t update 1.5\n"
|
||||||
"Test[test2.lua]:\t update 1.5\n"
|
"Test[test2.lua]:\t update 1.5\n"
|
||||||
|
@ -363,7 +363,7 @@ CUSTOM: customdata.lua
|
||||||
testing::internal::CaptureStdout();
|
testing::internal::CaptureStdout();
|
||||||
scripts.removeScript(getId(test1Path));
|
scripts.removeScript(getId(test1Path));
|
||||||
scripts.update(1.5f);
|
scripts.update(1.5f);
|
||||||
scripts.receiveEvent("Event1", X);
|
scripts.receiveEvent("Event1", x);
|
||||||
EXPECT_EQ(internal::GetCapturedStdout(),
|
EXPECT_EQ(internal::GetCapturedStdout(),
|
||||||
"Test[test2.lua]:\t update 1.5\n"
|
"Test[test2.lua]:\t update 1.5\n"
|
||||||
"Test[test2.lua]:\t event1 0.5\n");
|
"Test[test2.lua]:\t event1 0.5\n");
|
||||||
|
@ -638,8 +638,9 @@ CUSTOM: customdata.lua
|
||||||
sol::object deserialized = LuaUtil::deserialize(lua.sol(), data2.mScripts[0].mData, &serializer1);
|
sol::object deserialized = LuaUtil::deserialize(lua.sol(), data2.mScripts[0].mData, &serializer1);
|
||||||
EXPECT_TRUE(deserialized.is<sol::table>());
|
EXPECT_TRUE(deserialized.is<sol::table>());
|
||||||
sol::table table = deserialized;
|
sol::table table = deserialized;
|
||||||
for (const auto& [key, value] : table)
|
if (!table.empty())
|
||||||
{
|
{
|
||||||
|
const auto [key, value] = *table.cbegin();
|
||||||
EXPECT_TRUE(key.is<ESM::RefNum>());
|
EXPECT_TRUE(key.is<ESM::RefNum>());
|
||||||
EXPECT_TRUE(value.is<ESM::RefNum>());
|
EXPECT_TRUE(value.is<ESM::RefNum>());
|
||||||
EXPECT_EQ(key.as<ESM::RefNum>(), (ESM::RefNum{ 42, 34 }));
|
EXPECT_EQ(key.as<ESM::RefNum>(), (ESM::RefNum{ 42, 34 }));
|
|
@ -171,10 +171,10 @@ namespace
|
||||||
|
|
||||||
std::string serialized = LuaUtil::serialize(table);
|
std::string serialized = LuaUtil::serialize(table);
|
||||||
EXPECT_EQ(serialized.size(), 139);
|
EXPECT_EQ(serialized.size(), 139);
|
||||||
sol::table res_table = LuaUtil::deserialize(lua, serialized);
|
sol::table resTable = LuaUtil::deserialize(lua, serialized);
|
||||||
sol::table res_readonly_table = LuaUtil::deserialize(lua, serialized, nullptr, true);
|
sol::table resReadonlyTable = LuaUtil::deserialize(lua, serialized, nullptr, true);
|
||||||
|
|
||||||
for (auto t : { res_table, res_readonly_table })
|
for (auto t : { resTable, resReadonlyTable })
|
||||||
{
|
{
|
||||||
EXPECT_EQ(t.get<int>("aa"), 1);
|
EXPECT_EQ(t.get<int>("aa"), 1);
|
||||||
EXPECT_EQ(t.get<bool>("ab"), true);
|
EXPECT_EQ(t.get<bool>("ab"), true);
|
||||||
|
@ -185,8 +185,8 @@ namespace
|
||||||
EXPECT_EQ(t.get<osg::Vec2f>(2), osg::Vec2f(2, 1));
|
EXPECT_EQ(t.get<osg::Vec2f>(2), osg::Vec2f(2, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
lua["t"] = res_table;
|
lua["t"] = resTable;
|
||||||
lua["ro_t"] = res_readonly_table;
|
lua["ro_t"] = resReadonlyTable;
|
||||||
EXPECT_NO_THROW(lua.safe_script("t.x = 5"));
|
EXPECT_NO_THROW(lua.safe_script("t.x = 5"));
|
||||||
EXPECT_NO_THROW(lua.safe_script("t.nested.x = 5"));
|
EXPECT_NO_THROW(lua.safe_script("t.nested.x = 5"));
|
||||||
EXPECT_ERROR(lua.safe_script("ro_t.x = 5"), "userdata value");
|
EXPECT_ERROR(lua.safe_script("ro_t.x = 5"), "userdata value");
|
|
@ -9,22 +9,33 @@ namespace
|
||||||
{
|
{
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
|
|
||||||
|
struct LuaUtilPackageTest : Test
|
||||||
|
{
|
||||||
|
LuaUtil::LuaState mLuaState{ nullptr, nullptr };
|
||||||
|
|
||||||
|
LuaUtilPackageTest()
|
||||||
|
{
|
||||||
|
mLuaState.addInternalLibSearchPath(
|
||||||
|
std::filesystem::path{ OPENMW_PROJECT_SOURCE_DIR } / "components" / "lua");
|
||||||
|
sol::state_view sol = mLuaState.unsafeState();
|
||||||
|
sol["util"] = LuaUtil::initUtilPackage(sol);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T get(sol::state& lua, const std::string& luaCode)
|
T get(sol::state_view& lua, const std::string& luaCode)
|
||||||
{
|
{
|
||||||
return lua.safe_script("return " + luaCode).get<T>();
|
return lua.safe_script("return " + luaCode).get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getAsString(sol::state& lua, std::string luaCode)
|
std::string getAsString(sol::state_view& lua, std::string luaCode)
|
||||||
{
|
{
|
||||||
return LuaUtil::toString(lua.safe_script("return " + luaCode));
|
return LuaUtil::toString(lua.safe_script("return " + luaCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, Vector2)
|
TEST_F(LuaUtilPackageTest, Vector2)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua.safe_script("v = util.vector2(3, 4)");
|
lua.safe_script("v = util.vector2(3, 4)");
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 3);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 3);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 4);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 4);
|
||||||
|
@ -55,11 +66,9 @@ namespace
|
||||||
EXPECT_TRUE(get<bool>(lua, "swizzle['01'] == util.vector2(0, 1) and swizzle['0y'] == util.vector2(0, 2)"));
|
EXPECT_TRUE(get<bool>(lua, "swizzle['01'] == util.vector2(0, 1) and swizzle['0y'] == util.vector2(0, 2)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, Vector3)
|
TEST_F(LuaUtilPackageTest, Vector3)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua.safe_script("v = util.vector3(5, 12, 13)");
|
lua.safe_script("v = util.vector3(5, 12, 13)");
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
|
||||||
|
@ -94,11 +103,9 @@ namespace
|
||||||
get<bool>(lua, "swizzle['001'] == util.vector3(0, 0, 1) and swizzle['0yx'] == util.vector3(0, 2, 1)"));
|
get<bool>(lua, "swizzle['001'] == util.vector3(0, 0, 1) and swizzle['0yx'] == util.vector3(0, 2, 1)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, Vector4)
|
TEST_F(LuaUtilPackageTest, Vector4)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua.safe_script("v = util.vector4(5, 12, 13, 15)");
|
lua.safe_script("v = util.vector4(5, 12, 13, 15)");
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), 5);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 12);
|
||||||
|
@ -136,11 +143,9 @@ namespace
|
||||||
lua, "swizzle['0001'] == util.vector4(0, 0, 0, 1) and swizzle['0yx1'] == util.vector4(0, 2, 1, 1)"));
|
lua, "swizzle['0001'] == util.vector4(0, 0, 0, 1) and swizzle['0yx1'] == util.vector4(0, 2, 1, 1)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, Color)
|
TEST_F(LuaUtilPackageTest, Color)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua.safe_script("brown = util.color.rgba(0.75, 0.25, 0, 1)");
|
lua.safe_script("brown = util.color.rgba(0.75, 0.25, 0, 1)");
|
||||||
EXPECT_EQ(get<std::string>(lua, "tostring(brown)"), "(0.75, 0.25, 0, 1)");
|
EXPECT_EQ(get<std::string>(lua, "tostring(brown)"), "(0.75, 0.25, 0, 1)");
|
||||||
lua.safe_script("blue = util.color.rgb(0, 1, 0, 1)");
|
lua.safe_script("blue = util.color.rgb(0, 1, 0, 1)");
|
||||||
|
@ -155,11 +160,9 @@ namespace
|
||||||
EXPECT_TRUE(get<bool>(lua, "red:asRgb() == util.vector3(1, 0, 0)"));
|
EXPECT_TRUE(get<bool>(lua, "red:asRgb() == util.vector3(1, 0, 0)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, Transform)
|
TEST_F(LuaUtilPackageTest, Transform)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua["T"] = lua["util"]["transform"];
|
lua["T"] = lua["util"]["transform"];
|
||||||
lua["v"] = lua["util"]["vector3"];
|
lua["v"] = lua["util"]["vector3"];
|
||||||
EXPECT_ERROR(lua.safe_script("T.identity = nil"), "attempt to index");
|
EXPECT_ERROR(lua.safe_script("T.identity = nil"), "attempt to index");
|
||||||
|
@ -191,11 +194,9 @@ namespace
|
||||||
EXPECT_LT(get<float>(lua, "(rz_move_rx:inverse() * v(0, 1, 2) - v(1, 2, 3)):length()"), 1e-6);
|
EXPECT_LT(get<float>(lua, "(rz_move_rx:inverse() * v(0, 1, 2) - v(1, 2, 3)):length()"), 1e-6);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LuaUtilPackageTest, UtilityFunctions)
|
TEST_F(LuaUtilPackageTest, UtilityFunctions)
|
||||||
{
|
{
|
||||||
sol::state lua;
|
sol::state_view lua = mLuaState.unsafeState();
|
||||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string);
|
|
||||||
lua["util"] = LuaUtil::initUtilPackage(lua);
|
|
||||||
lua.safe_script("v = util.vector2(1, 0):rotate(math.rad(120))");
|
lua.safe_script("v = util.vector2(1, 0):rotate(math.rad(120))");
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), -0.5f);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.x"), -0.5f);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 0.86602539f);
|
EXPECT_FLOAT_EQ(get<float>(lua, "v.y"), 0.86602539f);
|
||||||
|
@ -203,6 +204,10 @@ namespace
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(0.1, 0, 1.5)"), 0.1f);
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(0.1, 0, 1.5)"), 0.1f);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(-0.1, 0, 1.5)"), 0);
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(-0.1, 0, 1.5)"), 0);
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(2.1, 0, 1.5)"), 1.5f);
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.clamp(2.1, 0, 1.5)"), 1.5f);
|
||||||
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.round(2.1)"), 2.0f);
|
||||||
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.round(-2.1)"), -2.0f);
|
||||||
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.remap(5, 0, 10, 0, 100)"), 50.0f);
|
||||||
|
EXPECT_FLOAT_EQ(get<float>(lua, "util.remap(-5, 0, 10, 0, 100)"), -50.0f);
|
||||||
lua.safe_script("t = util.makeReadOnly({x = 1})");
|
lua.safe_script("t = util.makeReadOnly({x = 1})");
|
||||||
EXPECT_FLOAT_EQ(get<float>(lua, "t.x"), 1);
|
EXPECT_FLOAT_EQ(get<float>(lua, "t.x"), 1);
|
||||||
EXPECT_ERROR(lua.safe_script("t.y = 2"), "userdata value");
|
EXPECT_ERROR(lua.safe_script("t.y = 2"), "userdata value");
|
|
@ -2,6 +2,7 @@
|
||||||
#include <components/misc/strings/conversion.hpp>
|
#include <components/misc/strings/conversion.hpp>
|
||||||
#include <components/settings/parser.hpp>
|
#include <components/settings/parser.hpp>
|
||||||
#include <components/settings/values.hpp>
|
#include <components/settings/values.hpp>
|
||||||
|
#include <components/testing/util.hpp>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
@ -24,5 +25,9 @@ int main(int argc, char** argv)
|
||||||
Settings::StaticValues::init();
|
Settings::StaticValues::init();
|
||||||
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
|
const int result = RUN_ALL_TESTS();
|
||||||
|
if (result == 0)
|
||||||
|
std::filesystem::remove_all(TestingOpenMW::outputDir());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Misc
|
||||||
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesXZQuat[] = {
|
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesXZQuat[] = {
|
||||||
{
|
{
|
||||||
osg::Quat(1, 0, 0, 0),
|
osg::Quat(1, 0, 0, 0),
|
||||||
osg::Vec3f(0, 0, osg::PI),
|
osg::Vec3f(0, 0, osg::PIf),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 1, 0, 0),
|
osg::Quat(0, 1, 0, 0),
|
||||||
|
@ -59,7 +59,7 @@ namespace Misc
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 0, 1, 0),
|
osg::Quat(0, 0, 1, 0),
|
||||||
osg::Vec3f(0, 0, osg::PI),
|
osg::Vec3f(0, 0, osg::PIf),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 0, 0, 1),
|
osg::Quat(0, 0, 0, 1),
|
||||||
|
@ -128,15 +128,15 @@ namespace Misc
|
||||||
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesZYXQuat[] = {
|
const std::pair<osg::Quat, osg::Vec3f> eulerAnglesZYXQuat[] = {
|
||||||
{
|
{
|
||||||
osg::Quat(1, 0, 0, 0),
|
osg::Quat(1, 0, 0, 0),
|
||||||
osg::Vec3f(osg::PI, 0, 0),
|
osg::Vec3f(osg::PIf, 0, 0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 1, 0, 0),
|
osg::Quat(0, 1, 0, 0),
|
||||||
osg::Vec3f(osg::PI, 0, osg::PI),
|
osg::Vec3f(osg::PIf, 0, osg::PIf),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 0, 1, 0),
|
osg::Quat(0, 0, 1, 0),
|
||||||
osg::Vec3f(0, 0, osg::PI),
|
osg::Vec3f(0, 0, osg::PIf),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
osg::Quat(0, 0, 0, 1),
|
osg::Quat(0, 0, 0, 1),
|
||||||
|
|
|
@ -26,6 +26,15 @@ namespace
|
||||||
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({});
|
std::unique_ptr<VFS::Manager> mVFS = TestingOpenMW::createTestVFS({});
|
||||||
constexpr VFS::Path::NormalizedView path("sound/foo.wav");
|
constexpr VFS::Path::NormalizedView path("sound/foo.wav");
|
||||||
EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/foo.mp3");
|
EXPECT_EQ(correctSoundPath(path, *mVFS), "sound/foo.mp3");
|
||||||
|
|
||||||
|
auto correctESM4SoundPath = [](auto path, auto* vfs) {
|
||||||
|
return Misc::ResourceHelpers::correctResourcePath({ { "sound" } }, path, vfs, ".mp3");
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_EQ(correctESM4SoundPath("foo.WAV", mVFS.get()), "sound\\foo.mp3");
|
||||||
|
EXPECT_EQ(correctESM4SoundPath("SOUND/foo.WAV", mVFS.get()), "sound\\foo.mp3");
|
||||||
|
EXPECT_EQ(correctESM4SoundPath("DATA\\SOUND\\foo.WAV", mVFS.get()), "sound\\foo.mp3");
|
||||||
|
EXPECT_EQ(correctESM4SoundPath("\\Data/Sound\\foo.WAV", mVFS.get()), "sound\\foo.mp3");
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
|
@ -16,7 +16,7 @@ namespace
|
||||||
ShaderManager mManager;
|
ShaderManager mManager;
|
||||||
ShaderManager::DefineMap mDefines;
|
ShaderManager::DefineMap mDefines;
|
||||||
|
|
||||||
ShaderManagerTest() { mManager.setShaderPath("tests_output"); }
|
ShaderManagerTest() { mManager.setShaderPath(TestingOpenMW::outputDir()); }
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
void withShaderFile(const std::string& content, F&& f)
|
void withShaderFile(const std::string& content, F&& f)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <components/misc/strings/conversion.hpp>
|
#include <components/misc/strings/conversion.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,9 @@ Allowed options)");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
|
bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(all).positional(p).run();
|
||||||
|
|
||||||
bpo::store(valid_opts, variables);
|
bpo::store(validOpts, variables);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -215,8 +215,6 @@ int main(int argc, char** argv)
|
||||||
std::cerr << "ERROR: " << e.what() << std::endl;
|
std::cerr << "ERROR: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "labels.hpp"
|
#include "labels.hpp"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
|
||||||
#include <components/esm3/dialoguecondition.hpp>
|
#include <components/esm3/dialoguecondition.hpp>
|
||||||
#include <components/esm3/loadalch.hpp>
|
#include <components/esm3/loadalch.hpp>
|
||||||
#include <components/esm3/loadbody.hpp>
|
#include <components/esm3/loadbody.hpp>
|
||||||
|
@ -16,8 +18,6 @@
|
||||||
#include <components/esm3/loadspel.hpp>
|
#include <components/esm3/loadspel.hpp>
|
||||||
#include <components/esm3/loadweap.hpp>
|
#include <components/esm3/loadweap.hpp>
|
||||||
|
|
||||||
#include <components/misc/strings/format.hpp>
|
|
||||||
|
|
||||||
std::string_view bodyPartLabel(int idx)
|
std::string_view bodyPartLabel(int idx)
|
||||||
{
|
{
|
||||||
if (idx >= 0 && idx <= 26)
|
if (idx >= 0 && idx <= 26)
|
||||||
|
@ -675,7 +675,7 @@ std::string bodyPartFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::BodyPart::BPF_Female | ESM::BodyPart::BPF_NotPlayable));
|
int unused = (0xFFFFFFFF ^ (ESM::BodyPart::BPF_Female | ESM::BodyPart::BPF_NotPlayable));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ std::string cellFlags(int flags)
|
||||||
^ (ESM::Cell::HasWater | ESM::Cell::Interior | ESM::Cell::NoSleep | ESM::Cell::QuasiEx | 0x00000040));
|
^ (ESM::Cell::HasWater | ESM::Cell::Interior | ESM::Cell::NoSleep | ESM::Cell::QuasiEx | 0x00000040));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,7 +717,7 @@ std::string containerFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::Container::Unknown | ESM::Container::Organic | ESM::Container::Respawn));
|
int unused = (0xFFFFFFFF ^ (ESM::Container::Unknown | ESM::Container::Organic | ESM::Container::Respawn));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +747,7 @@ std::string creatureFlags(int flags)
|
||||||
| ESM::Creature::Bipedal | ESM::Creature::Respawn | ESM::Creature::Weapon | ESM::Creature::Essential));
|
| ESM::Creature::Bipedal | ESM::Creature::Respawn | ESM::Creature::Weapon | ESM::Creature::Essential));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%02X)", flags);
|
properties += std::format("(0x{:02X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,7 +760,7 @@ std::string enchantmentFlags(int flags)
|
||||||
properties += "Autocalc ";
|
properties += "Autocalc ";
|
||||||
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,7 +778,7 @@ std::string landFlags(std::uint32_t flags)
|
||||||
int unused = 0xFFFFFFFF ^ (ESM::Land::Flag_HeightsNormals | ESM::Land::Flag_Colors | ESM::Land::Flag_Textures);
|
int unused = 0xFFFFFFFF ^ (ESM::Land::Flag_HeightsNormals | ESM::Land::Flag_Colors | ESM::Land::Flag_Textures);
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ std::string itemListFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::ItemLevList::AllLevels | ESM::ItemLevList::Each));
|
int unused = (0xFFFFFFFF ^ (ESM::ItemLevList::AllLevels | ESM::ItemLevList::Each));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ std::string creatureListFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
|
int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels);
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,7 +840,7 @@ std::string lightFlags(int flags)
|
||||||
| ESM::Light::Pulse | ESM::Light::PulseSlow | ESM::Light::Negative | ESM::Light::OffDefault));
|
| ESM::Light::Pulse | ESM::Light::PulseSlow | ESM::Light::Negative | ESM::Light::OffDefault));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +888,7 @@ std::string magicEffectFlags(int flags)
|
||||||
|
|
||||||
if (flags & 0xFFFC0000)
|
if (flags & 0xFFFC0000)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ std::string npcFlags(int flags)
|
||||||
= (0xFF ^ (ESM::NPC::Base | ESM::NPC::Autocalc | ESM::NPC::Female | ESM::NPC::Respawn | ESM::NPC::Essential));
|
= (0xFF ^ (ESM::NPC::Base | ESM::NPC::Autocalc | ESM::NPC::Female | ESM::NPC::Respawn | ESM::NPC::Essential));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%02X)", flags);
|
properties += std::format("(0x{:02X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,7 +930,7 @@ std::string raceFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::Race::Playable | ESM::Race::Beast));
|
int unused = (0xFFFFFFFF ^ (ESM::Race::Playable | ESM::Race::Beast));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,7 +948,7 @@ std::string spellFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::Spell::F_Autocalc | ESM::Spell::F_PCStart | ESM::Spell::F_Always));
|
int unused = (0xFFFFFFFF ^ (ESM::Spell::F_Autocalc | ESM::Spell::F_PCStart | ESM::Spell::F_Always));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,7 +967,7 @@ std::string weaponFlags(int flags)
|
||||||
int unused = (0xFFFFFFFF ^ (ESM::Weapon::Magical | ESM::Weapon::Silver));
|
int unused = (0xFFFFFFFF ^ (ESM::Weapon::Magical | ESM::Weapon::Silver));
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,7 +987,7 @@ std::string recordFlags(uint32_t flags)
|
||||||
int unused = ~(ESM::FLAG_Deleted | ESM::FLAG_Persistent | ESM::FLAG_Ignored | ESM::FLAG_Blocked);
|
int unused = ~(ESM::FLAG_Deleted | ESM::FLAG_Persistent | ESM::FLAG_Ignored | ESM::FLAG_Blocked);
|
||||||
if (flags & unused)
|
if (flags & unused)
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,6 +1000,6 @@ std::string potionFlags(int flags)
|
||||||
properties += "Autocalc ";
|
properties += "Autocalc ";
|
||||||
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
||||||
properties += "Invalid ";
|
properties += "Invalid ";
|
||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += std::format("(0x{:08X})", flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
#include "labels.hpp"
|
#include "labels.hpp"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -8,15 +9,13 @@
|
||||||
#include <components/esm3/cellstate.hpp>
|
#include <components/esm3/cellstate.hpp>
|
||||||
#include <components/esm3/esmreader.hpp>
|
#include <components/esm3/esmreader.hpp>
|
||||||
#include <components/misc/strings/conversion.hpp>
|
#include <components/misc/strings/conversion.hpp>
|
||||||
#include <components/misc/strings/format.hpp>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
void printAIPackage(const ESM::AIPackage& p)
|
void printAIPackage(const ESM::AIPackage& p)
|
||||||
{
|
{
|
||||||
std::cout << " AI Type: " << aiTypeLabel(p.mType) << " (" << Misc::StringUtils::format("0x%08X", p.mType)
|
std::cout << std::format(" AI Type: {} (0x{:08X})\n", aiTypeLabel(p.mType), std::uint32_t(p.mType));
|
||||||
<< ")" << std::endl;
|
|
||||||
if (p.mType == ESM::AI_Wander)
|
if (p.mType == ESM::AI_Wander)
|
||||||
{
|
{
|
||||||
std::cout << " Distance: " << p.mWander.mDistance << std::endl;
|
std::cout << " Distance: " << p.mWander.mDistance << std::endl;
|
||||||
|
@ -51,7 +50,7 @@ namespace
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << " BadPackage: " << Misc::StringUtils::format("0x%08X", p.mType) << std::endl;
|
std::cout << std::format(" BadPackage: 0x{:08X}\n", std::uint32_t(p.mType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p.mCellName.empty())
|
if (!p.mCellName.empty())
|
||||||
|
@ -60,81 +59,81 @@ namespace
|
||||||
|
|
||||||
std::string ruleString(const ESM::DialogueCondition& ss)
|
std::string ruleString(const ESM::DialogueCondition& ss)
|
||||||
{
|
{
|
||||||
std::string_view type_str = "INVALID";
|
std::string_view typeStr = "INVALID";
|
||||||
std::string_view func_str;
|
std::string_view funcStr;
|
||||||
|
|
||||||
switch (ss.mFunction)
|
switch (ss.mFunction)
|
||||||
{
|
{
|
||||||
case ESM::DialogueCondition::Function_Global:
|
case ESM::DialogueCondition::Function_Global:
|
||||||
type_str = "Global";
|
typeStr = "Global";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_Local:
|
case ESM::DialogueCondition::Function_Local:
|
||||||
type_str = "Local";
|
typeStr = "Local";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_Journal:
|
case ESM::DialogueCondition::Function_Journal:
|
||||||
type_str = "Journal";
|
typeStr = "Journal";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_Item:
|
case ESM::DialogueCondition::Function_Item:
|
||||||
type_str = "Item count";
|
typeStr = "Item count";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_Dead:
|
case ESM::DialogueCondition::Function_Dead:
|
||||||
type_str = "Dead";
|
typeStr = "Dead";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotId:
|
case ESM::DialogueCondition::Function_NotId:
|
||||||
type_str = "Not ID";
|
typeStr = "Not ID";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotFaction:
|
case ESM::DialogueCondition::Function_NotFaction:
|
||||||
type_str = "Not Faction";
|
typeStr = "Not Faction";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotClass:
|
case ESM::DialogueCondition::Function_NotClass:
|
||||||
type_str = "Not Class";
|
typeStr = "Not Class";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotRace:
|
case ESM::DialogueCondition::Function_NotRace:
|
||||||
type_str = "Not Race";
|
typeStr = "Not Race";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotCell:
|
case ESM::DialogueCondition::Function_NotCell:
|
||||||
type_str = "Not Cell";
|
typeStr = "Not Cell";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Function_NotLocal:
|
case ESM::DialogueCondition::Function_NotLocal:
|
||||||
type_str = "Not Local";
|
typeStr = "Not Local";
|
||||||
func_str = ss.mVariable;
|
funcStr = ss.mVariable;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
type_str = "Function";
|
typeStr = "Function";
|
||||||
func_str = ruleFunction(ss.mFunction);
|
funcStr = ruleFunction(ss.mFunction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view oper_str = "??";
|
std::string_view operStr = "??";
|
||||||
switch (ss.mComparison)
|
switch (ss.mComparison)
|
||||||
{
|
{
|
||||||
case ESM::DialogueCondition::Comp_Eq:
|
case ESM::DialogueCondition::Comp_Eq:
|
||||||
oper_str = "==";
|
operStr = "==";
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Comp_Ne:
|
case ESM::DialogueCondition::Comp_Ne:
|
||||||
oper_str = "!=";
|
operStr = "!=";
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Comp_Gt:
|
case ESM::DialogueCondition::Comp_Gt:
|
||||||
oper_str = "> ";
|
operStr = "> ";
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Comp_Ge:
|
case ESM::DialogueCondition::Comp_Ge:
|
||||||
oper_str = ">=";
|
operStr = ">=";
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Comp_Ls:
|
case ESM::DialogueCondition::Comp_Ls:
|
||||||
oper_str = "< ";
|
operStr = "< ";
|
||||||
break;
|
break;
|
||||||
case ESM::DialogueCondition::Comp_Le:
|
case ESM::DialogueCondition::Comp_Le:
|
||||||
oper_str = "<=";
|
operStr = "<=";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -143,8 +142,7 @@ namespace
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
std::visit([&](auto value) { stream << value; }, ss.mValue);
|
std::visit([&](auto value) { stream << value; }, ss.mValue);
|
||||||
|
|
||||||
std::string result
|
std::string result = std::format("{:<12} {:<32} {:2} {}", typeStr, funcStr, operStr, stream.str());
|
||||||
= Misc::StringUtils::format("%-12s %-32s %2s %s", type_str, func_str, oper_str, stream.str());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,12 +174,10 @@ namespace
|
||||||
{
|
{
|
||||||
for (const ESM::Transport::Dest& dest : transport)
|
for (const ESM::Transport::Dest& dest : transport)
|
||||||
{
|
{
|
||||||
std::cout << " Destination Position: " << Misc::StringUtils::format("%12.3f", dest.mPos.pos[0]) << ","
|
std::cout << std::format(" Destination Position: ({:12.3f},{:12.3f},{:12.3f})\n", dest.mPos.pos[0],
|
||||||
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[1]) << ","
|
dest.mPos.pos[1], dest.mPos.pos[2]);
|
||||||
<< Misc::StringUtils::format("%12.3f", dest.mPos.pos[2]) << ")" << std::endl;
|
std::cout << std::format(" Destination Rotation: ({:9.6f},{:9.6f},{:9.6f})\n", dest.mPos.rot[0],
|
||||||
std::cout << " Destination Rotation: " << Misc::StringUtils::format("%9.6f", dest.mPos.rot[0]) << ","
|
dest.mPos.rot[1], dest.mPos.rot[2]);
|
||||||
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[1]) << ","
|
|
||||||
<< Misc::StringUtils::format("%9.6f", dest.mPos.rot[2]) << ")" << std::endl;
|
|
||||||
if (!dest.mCellName.empty())
|
if (!dest.mCellName.empty())
|
||||||
std::cout << " Destination Cell: " << dest.mCellName << std::endl;
|
std::cout << " Destination Cell: " << dest.mCellName << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +579,7 @@ namespace EsmTool
|
||||||
std::cout << " Water Level: " << mData.mWater << std::endl;
|
std::cout << " Water Level: " << mData.mWater << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl;
|
std::cout << std::format(" Map Color: 0x{:08X}\n", mData.mMapColor);
|
||||||
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl;
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +590,7 @@ namespace EsmTool
|
||||||
std::cout << " Name: " << mData.mName << std::endl;
|
std::cout << " Name: " << mData.mName << std::endl;
|
||||||
std::cout << " Description: " << mData.mDescription << std::endl;
|
std::cout << " Description: " << mData.mDescription << std::endl;
|
||||||
std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl;
|
std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl;
|
||||||
std::cout << " AI Services: " << Misc::StringUtils::format("0x%08X", mData.mData.mServices) << std::endl;
|
std::cout << std::format(" AI Services: 0x{:08X}\n", mData.mData.mServices);
|
||||||
for (size_t i = 0; i < mData.mData.mAttribute.size(); ++i)
|
for (size_t i = 0; i < mData.mData.mAttribute.size(); ++i)
|
||||||
std::cout << " Attribute" << (i + 1) << ": " << attributeLabel(mData.mData.mAttribute[i]) << " ("
|
std::cout << " Attribute" << (i + 1) << ": " << attributeLabel(mData.mData.mAttribute[i]) << " ("
|
||||||
<< mData.mData.mAttribute[i] << ")" << std::endl;
|
<< mData.mData.mAttribute[i] << ")" << std::endl;
|
||||||
|
@ -642,8 +638,7 @@ namespace EsmTool
|
||||||
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl;
|
||||||
std::cout << " Weight: " << mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mWeight << std::endl;
|
||||||
for (const ESM::ContItem& item : mData.mInventory.mList)
|
for (const ESM::ContItem& item : mData.mInventory.mList)
|
||||||
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
|
std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
|
||||||
<< " Item: " << item.mItem << std::endl;
|
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,8 +675,7 @@ namespace EsmTool
|
||||||
std::cout << " Gold: " << mData.mData.mGold << std::endl;
|
std::cout << " Gold: " << mData.mData.mGold << std::endl;
|
||||||
|
|
||||||
for (const ESM::ContItem& item : mData.mInventory.mList)
|
for (const ESM::ContItem& item : mData.mInventory.mList)
|
||||||
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
|
std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
|
||||||
<< " Item: " << item.mItem << std::endl;
|
|
||||||
|
|
||||||
for (const auto& spell : mData.mSpells.mList)
|
for (const auto& spell : mData.mSpells.mList)
|
||||||
std::cout << " Spell: " << spell << std::endl;
|
std::cout << " Spell: " << spell << std::endl;
|
||||||
|
@ -693,7 +687,7 @@ namespace EsmTool
|
||||||
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
|
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
|
||||||
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
|
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
|
||||||
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
|
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
|
||||||
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl;
|
std::cout << std::format(" AI Services:0x{:08X}\n", mData.mAiData.mServices);
|
||||||
|
|
||||||
for (const ESM::AIPackage& package : mData.mAiPackage.mList)
|
for (const ESM::AIPackage& package : mData.mAiPackage.mList)
|
||||||
printAIPackage(package);
|
printAIPackage(package);
|
||||||
|
@ -1068,8 +1062,7 @@ namespace EsmTool
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const ESM::ContItem& item : mData.mInventory.mList)
|
for (const ESM::ContItem& item : mData.mInventory.mList)
|
||||||
std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount)
|
std::cout << std::format(" Inventory: Count: {:4d} Item: ", item.mCount) << item.mItem << std::endl;
|
||||||
<< " Item: " << item.mItem << std::endl;
|
|
||||||
|
|
||||||
for (const auto& spell : mData.mSpells.mList)
|
for (const auto& spell : mData.mSpells.mList)
|
||||||
std::cout << " Spell: " << spell << std::endl;
|
std::cout << " Spell: " << spell << std::endl;
|
||||||
|
@ -1081,7 +1074,7 @@ namespace EsmTool
|
||||||
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
|
std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl;
|
||||||
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
|
std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl;
|
||||||
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
|
std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl;
|
||||||
std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl;
|
std::cout << std::format(" AI Services:0x{:08X}\n", mData.mAiData.mServices);
|
||||||
|
|
||||||
for (const ESM::AIPackage& package : mData.mAiPackage.mList)
|
for (const ESM::AIPackage& package : mData.mAiPackage.mList)
|
||||||
printAIPackage(package);
|
printAIPackage(package);
|
||||||
|
@ -1192,8 +1185,8 @@ namespace EsmTool
|
||||||
std::cout << " Variable: " << variable << std::endl;
|
std::cout << " Variable: " << variable << std::endl;
|
||||||
|
|
||||||
std::cout << " ByteCode: ";
|
std::cout << " ByteCode: ";
|
||||||
for (const unsigned char& byte : mData.mScriptData)
|
for (unsigned char byte : mData.mScriptData)
|
||||||
std::cout << Misc::StringUtils::format("%02X", (int)(byte));
|
std::cout << std::format("{:02X}", byte);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (mPrintPlain)
|
if (mPrintPlain)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <components/esm4/readerutils.hpp>
|
#include <components/esm4/readerutils.hpp>
|
||||||
#include <components/esm4/records.hpp>
|
#include <components/esm4/records.hpp>
|
||||||
#include <components/esm4/typetraits.hpp>
|
#include <components/esm4/typetraits.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
namespace EsmTool
|
namespace EsmTool
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace ESSImport
|
||||||
scriptedAnim.mAbsolute = true;
|
scriptedAnim.mAbsolute = true;
|
||||||
// Neither loop count nor queueing seems to be supported by the ess format.
|
// Neither loop count nor queueing seems to be supported by the ess format.
|
||||||
scriptedAnim.mLoopCount = std::numeric_limits<size_t>::max();
|
scriptedAnim.mLoopCount = std::numeric_limits<size_t>::max();
|
||||||
state.mScriptedAnims.push_back(scriptedAnim);
|
state.mScriptedAnims.push_back(std::move(scriptedAnim));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// TODO: Handle 0xFF index, which seems to be used for finished animations.
|
// TODO: Handle 0xFF index, which seems to be used for finished animations.
|
||||||
|
|
|
@ -303,7 +303,7 @@ namespace ESSImport
|
||||||
marker.mWorldY = notepos[1];
|
marker.mWorldY = notepos[1];
|
||||||
marker.mNote = std::move(note);
|
marker.mNote = std::move(note);
|
||||||
marker.mCell = cell.mId;
|
marker.mCell = cell.mId;
|
||||||
mMarkers.push_back(marker);
|
mMarkers.push_back(std::move(marker));
|
||||||
}
|
}
|
||||||
|
|
||||||
newcell.mRefs = std::move(cellrefs);
|
newcell.mRefs = std::move(cellrefs);
|
||||||
|
|
|
@ -181,14 +181,14 @@ namespace ESSImport
|
||||||
public:
|
public:
|
||||||
void read(ESM::ESMReader& esm) override
|
void read(ESM::ESMReader& esm) override
|
||||||
{
|
{
|
||||||
ESM::Class class_;
|
ESM::Class classRecord;
|
||||||
bool isDeleted = false;
|
bool isDeleted = false;
|
||||||
|
|
||||||
class_.load(esm, isDeleted);
|
classRecord.load(esm, isDeleted);
|
||||||
if (class_.mId == "NEWCLASSID_CHARGEN")
|
if (classRecord.mId == "NEWCLASSID_CHARGEN")
|
||||||
mContext->mCustomPlayerClassName = class_.mName;
|
mContext->mCustomPlayerClassName = classRecord.mName;
|
||||||
|
|
||||||
mRecords[class_.mId] = class_;
|
mRecords[classRecord.mId] = classRecord;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,10 +249,10 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory;
|
ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory;
|
||||||
|
|
||||||
for (size_t i = 0; i < invState.mItems.size(); ++i)
|
for (uint32_t i = 0; i < static_cast<uint32_t>(invState.mItems.size()); ++i)
|
||||||
{
|
{
|
||||||
// FIXME: in case of conflict (multiple items with this refID) use the already equipped one?
|
// FIXME: in case of conflict (multiple items with this refID) use the already equipped one?
|
||||||
if (invState.mItems[i].mRef.mRefID == ESM::RefId::stringRefId(refr.mActorData.mSelectedEnchantItem))
|
if (invState.mItems[i].mRef.mRefID == refr.mActorData.mSelectedEnchantItem)
|
||||||
invState.mSelectedEnchantItem = i;
|
invState.mSelectedEnchantItem = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,12 +260,12 @@ namespace ESSImport
|
||||||
void write(ESM::ESMWriter& esm) override
|
void write(ESM::ESMWriter& esm) override
|
||||||
{
|
{
|
||||||
esm.startRecord(ESM::REC_ASPL);
|
esm.startRecord(ESM::REC_ASPL);
|
||||||
esm.writeHNString("ID__", mSelectedSpell);
|
esm.writeHNRefId("ID__", mSelectedSpell);
|
||||||
esm.endRecord(ESM::REC_ASPL);
|
esm.endRecord(ESM::REC_ASPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mSelectedSpell;
|
ESM::RefId mSelectedSpell;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertPCDT : public Converter
|
class ConvertPCDT : public Converter
|
||||||
|
@ -374,16 +374,16 @@ namespace ESSImport
|
||||||
void write(ESM::ESMWriter& esm) override
|
void write(ESM::ESMWriter& esm) override
|
||||||
{
|
{
|
||||||
esm.startRecord(ESM::REC_DCOU);
|
esm.startRecord(ESM::REC_DCOU);
|
||||||
for (auto it = mKillCounter.begin(); it != mKillCounter.end(); ++it)
|
for (const auto& [id, count] : mKillCounter)
|
||||||
{
|
{
|
||||||
esm.writeHNString("ID__", it->first);
|
esm.writeHNRefId("ID__", id);
|
||||||
esm.writeHNT("COUN", it->second);
|
esm.writeHNT("COUN", count);
|
||||||
}
|
}
|
||||||
esm.endRecord(ESM::REC_DCOU);
|
esm.endRecord(ESM::REC_DCOU);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, int> mKillCounter;
|
std::map<ESM::RefId, int> mKillCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConvertFACT : public Converter
|
class ConvertFACT : public Converter
|
||||||
|
@ -584,7 +584,7 @@ namespace ESSImport
|
||||||
script.load(esm);
|
script.load(esm);
|
||||||
ESM::GlobalScript out;
|
ESM::GlobalScript out;
|
||||||
convertSCPT(script, out);
|
convertSCPT(script, out);
|
||||||
mScripts.push_back(out);
|
mScripts.push_back(std::move(out));
|
||||||
}
|
}
|
||||||
void write(ESM::ESMWriter& esm) override
|
void write(ESM::ESMWriter& esm) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,8 +75,8 @@ namespace ESSImport
|
||||||
// to change them ingame
|
// to change them ingame
|
||||||
int mCombatStats[3][2];
|
int mCombatStats[3][2];
|
||||||
|
|
||||||
std::string mSelectedSpell;
|
ESM::RefId mSelectedSpell;
|
||||||
std::string mSelectedEnchantItem;
|
ESM::RefId mSelectedEnchantItem;
|
||||||
|
|
||||||
SCRI mSCRI;
|
SCRI mSCRI;
|
||||||
|
|
||||||
|
|
|
@ -107,12 +107,12 @@ namespace ESSImport
|
||||||
|
|
||||||
if (esm.isNextSub("WNAM"))
|
if (esm.isNextSub("WNAM"))
|
||||||
{
|
{
|
||||||
std::string id = esm.getHString();
|
ESM::RefId spellRefId = esm.getRefId();
|
||||||
|
|
||||||
if (esm.isNextSub("XNAM"))
|
if (esm.isNextSub("XNAM"))
|
||||||
mActorData.mSelectedEnchantItem = esm.getHString();
|
mActorData.mSelectedEnchantItem = esm.getRefId();
|
||||||
else
|
else
|
||||||
mActorData.mSelectedSpell = std::move(id);
|
mActorData.mSelectedSpell = std::move(spellRefId);
|
||||||
|
|
||||||
if (esm.isNextSub("YNAM"))
|
if (esm.isNextSub("YNAM"))
|
||||||
esm.skipHSub(); // 4 byte, 0
|
esm.skipHSub(); // 4 byte, 0
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#include <components/misc/constants.hpp>
|
#include <components/misc/constants.hpp>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include "importercontext.hpp"
|
#include "importercontext.hpp"
|
||||||
|
|
||||||
|
@ -136,9 +136,9 @@ namespace ESSImport
|
||||||
sub.mName = esm.retSubName().toString();
|
sub.mName = esm.retSubName().toString();
|
||||||
sub.mData.resize(esm.getSubSize());
|
sub.mData.resize(esm.getSubSize());
|
||||||
esm.getExact(sub.mData.data(), sub.mData.size());
|
esm.getExact(sub.mData.data(), sub.mData.size());
|
||||||
rec.mSubrecords.push_back(sub);
|
rec.mSubrecords.push_back(std::move(sub));
|
||||||
}
|
}
|
||||||
file.mRecords.push_back(rec);
|
file.mRecords.push_back(std::move(rec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,19 @@ namespace ESSImport
|
||||||
|
|
||||||
void INFO::load(ESM::ESMReader& esm)
|
void INFO::load(ESM::ESMReader& esm)
|
||||||
{
|
{
|
||||||
mInfo = esm.getHNString("INAM");
|
if (esm.peekNextSub("XNAM"))
|
||||||
|
{
|
||||||
|
// TODO: Support older saves by turning XNAM into a RefId.
|
||||||
|
// XNAM is probably the number of the topic response within the topic record's linked list.
|
||||||
|
// Resolving this value will likely require loading Morrowind.esm.
|
||||||
|
|
||||||
|
esm.getSubName();
|
||||||
|
esm.skipHSub();
|
||||||
|
mInfo = ESM::RefId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mInfo = esm.getHNRefId("INAM");
|
||||||
|
|
||||||
mActorRefId = esm.getHNString("ACDT");
|
mActorRefId = esm.getHNString("ACDT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class ESMReader;
|
class ESMReader;
|
||||||
|
@ -13,7 +15,7 @@ namespace ESSImport
|
||||||
|
|
||||||
struct INFO
|
struct INFO
|
||||||
{
|
{
|
||||||
std::string mInfo;
|
ESM::RefId mInfo;
|
||||||
std::string mActorRefId;
|
std::string mActorRefId;
|
||||||
|
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace ESSImport
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!separateStacks)
|
if (!separateStacks)
|
||||||
mItems.push_back(item);
|
mItems.push_back(std::move(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
// equipped items
|
// equipped items
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
while (esm.isNextSub("KNAM"))
|
while (esm.isNextSub("KNAM"))
|
||||||
{
|
{
|
||||||
std::string refId = esm.getHString();
|
ESM::RefId refId = esm.getRefId();
|
||||||
int32_t count;
|
int32_t count;
|
||||||
esm.getHNT(count, "CNAM");
|
esm.getHNT(count, "CNAM");
|
||||||
mKillCounter[refId] = count;
|
mKillCounter[refId] = count;
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
@ -18,8 +19,7 @@ namespace ESSImport
|
||||||
{
|
{
|
||||||
void load(ESM::ESMReader& esm);
|
void load(ESM::ESMReader& esm);
|
||||||
|
|
||||||
/// RefId, kill count
|
std::map<ESM::RefId, int32_t> mKillCounter;
|
||||||
std::map<std::string, int32_t> mKillCounter;
|
|
||||||
|
|
||||||
int32_t mWerewolfKills;
|
int32_t mWerewolfKills;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace ESSImport
|
||||||
unsigned char xnam; // sentinel
|
unsigned char xnam; // sentinel
|
||||||
esm.getHNT(xnam, "XNAM");
|
esm.getHNT(xnam, "XNAM");
|
||||||
|
|
||||||
mActiveSpells.push_back(spell);
|
mActiveSpells.push_back(std::move(spell));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
bpo::options_description desc(R"(Syntax: openmw-essimporter <options> infile.ess outfile.omwsave
|
bpo::options_description desc(R"(Syntax: openmw-essimporter <options> infile.ess outfile.omwsave
|
||||||
Allowed options)");
|
Allowed options)");
|
||||||
bpo::positional_options_description p_desc;
|
bpo::positional_options_description positionalDesc;
|
||||||
auto addOption = desc.add_options();
|
auto addOption = desc.add_options();
|
||||||
addOption("help,h", "produce help message");
|
addOption("help,h", "produce help message");
|
||||||
addOption("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file");
|
addOption("mwsave,m", bpo::value<Files::MaybeQuotedPath>(), "morrowind .ess save file");
|
||||||
|
@ -23,12 +23,13 @@ Allowed options)");
|
||||||
addOption("compare,c", "compare two .ess files");
|
addOption("compare,c", "compare two .ess files");
|
||||||
addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"),
|
addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"),
|
||||||
"encoding of the save file");
|
"encoding of the save file");
|
||||||
p_desc.add("mwsave", 1).add("output", 1);
|
positionalDesc.add("mwsave", 1).add("output", 1);
|
||||||
Files::ConfigurationManager::addCommonOptions(desc);
|
Files::ConfigurationManager::addCommonOptions(desc);
|
||||||
|
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
|
|
||||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run();
|
bpo::parsed_options parsed
|
||||||
|
= bpo::command_line_parser(argc, argv).options(desc).positional(positionalDesc).run();
|
||||||
bpo::store(parsed, variables);
|
bpo::store(parsed, variables);
|
||||||
|
|
||||||
if (variables.count("help") || !variables.count("mwsave") || !variables.count("output"))
|
if (variables.count("help") || !variables.count("mwsave") || !variables.count("output"))
|
||||||
|
@ -40,6 +41,7 @@ Allowed options)");
|
||||||
bpo::notify(variables);
|
bpo::notify(variables);
|
||||||
|
|
||||||
Files::ConfigurationManager cfgManager(true);
|
Files::ConfigurationManager cfgManager(true);
|
||||||
|
cfgManager.processPaths(variables, std::filesystem::current_path());
|
||||||
cfgManager.readConfiguration(variables, desc);
|
cfgManager.readConfiguration(variables, desc);
|
||||||
|
|
||||||
const auto& essFile = variables["mwsave"].as<Files::MaybeQuotedPath>();
|
const auto& essFile = variables["mwsave"].as<Files::MaybeQuotedPath>();
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
#include <QProgressDialog>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -37,8 +39,6 @@
|
||||||
#include "utils/profilescombobox.hpp"
|
#include "utils/profilescombobox.hpp"
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
|
|
||||||
#include "ui_directorypicker.h"
|
|
||||||
|
|
||||||
const char* Launcher::DataFilesPage::mDefaultContentListName = "Default";
|
const char* Launcher::DataFilesPage::mDefaultContentListName = "Default";
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -153,13 +153,16 @@ namespace Launcher
|
||||||
Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
||||||
Config::LauncherSettings& launcherSettings, MainDialog* parent)
|
Config::LauncherSettings& launcherSettings, MainDialog* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
, mDirectoryPickerDialog(new QDialog(this))
|
||||||
, mMainDialog(parent)
|
, mMainDialog(parent)
|
||||||
, mCfgMgr(cfg)
|
, mCfgMgr(cfg)
|
||||||
, mGameSettings(gameSettings)
|
, mGameSettings(gameSettings)
|
||||||
, mLauncherSettings(launcherSettings)
|
, mLauncherSettings(launcherSettings)
|
||||||
, mNavMeshToolInvoker(new Process::ProcessInvoker(this))
|
, mNavMeshToolInvoker(new Process::ProcessInvoker(this))
|
||||||
|
, mReloadCellsThread(&DataFilesPage::reloadCells, this)
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
mDirectoryPicker.setupUi(mDirectoryPickerDialog);
|
||||||
setObjectName("DataFilesPage");
|
setObjectName("DataFilesPage");
|
||||||
mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true);
|
mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true);
|
||||||
const QString encoding = mGameSettings.value("encoding", { "win1252" }).value;
|
const QString encoding = mGameSettings.value("encoding", { "win1252" }).value;
|
||||||
|
@ -200,8 +203,24 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C
|
||||||
// the addons and don't want to get signals of the system doing it during startup.
|
// the addons and don't want to get signals of the system doing it during startup.
|
||||||
connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this,
|
connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this,
|
||||||
&DataFilesPage::slotAddonDataChanged);
|
&DataFilesPage::slotAddonDataChanged);
|
||||||
|
|
||||||
|
mReloadCellsTimer = new QTimer(this);
|
||||||
|
mReloadCellsTimer->setSingleShot(true);
|
||||||
|
mReloadCellsTimer->setInterval(200);
|
||||||
|
connect(mReloadCellsTimer, &QTimer::timeout, this, &DataFilesPage::onReloadCellsTimerTimeout);
|
||||||
|
|
||||||
// Call manually to indicate all changes to addon data during startup.
|
// Call manually to indicate all changes to addon data during startup.
|
||||||
slotAddonDataChanged();
|
onReloadCellsTimerTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
Launcher::DataFilesPage::~DataFilesPage()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::lock_guard lock(mReloadCellsMutex);
|
||||||
|
mAbortReloadCells = true;
|
||||||
|
mStartReloadCells.notify_one();
|
||||||
|
}
|
||||||
|
mReloadCellsThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::buildView()
|
void Launcher::DataFilesPage::buildView()
|
||||||
|
@ -247,6 +266,7 @@ void Launcher::DataFilesPage::buildView()
|
||||||
|
|
||||||
buildArchiveContextMenu();
|
buildArchiveContextMenu();
|
||||||
buildDataFilesContextMenu();
|
buildDataFilesContextMenu();
|
||||||
|
buildDirectoryPickerContextMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotCopySelectedItemsPaths()
|
void Launcher::DataFilesPage::slotCopySelectedItemsPaths()
|
||||||
|
@ -279,8 +299,10 @@ void Launcher::DataFilesPage::buildArchiveContextMenu()
|
||||||
&DataFilesPage::slotShowArchiveContextMenu);
|
&DataFilesPage::slotShowArchiveContextMenu);
|
||||||
|
|
||||||
mArchiveContextMenu = new QMenu(ui.archiveListWidget);
|
mArchiveContextMenu = new QMenu(ui.archiveListWidget);
|
||||||
mArchiveContextMenu->addAction(tr("&Check Selected"), this, SLOT(slotCheckMultiSelectedItems()));
|
mArchiveContextMenu->addAction(tr("&Check Selected"), this,
|
||||||
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this, SLOT(slotUncheckMultiSelectedItems()));
|
[this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Checked); });
|
||||||
|
mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(ui.archiveListWidget, Qt::Unchecked); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
||||||
|
@ -295,6 +317,18 @@ void Launcher::DataFilesPage::buildDataFilesContextMenu()
|
||||||
tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths);
|
tr("&Open Path in File Explorer"), this, &Launcher::DataFilesPage::slotOpenSelectedItemsPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::buildDirectoryPickerContextMenu()
|
||||||
|
{
|
||||||
|
connect(mDirectoryPicker.dirListWidget, &QListWidget::customContextMenuRequested, this,
|
||||||
|
&DataFilesPage::slotShowDirectoryPickerContextMenu);
|
||||||
|
|
||||||
|
mDirectoryPickerMenu = new QMenu(mDirectoryPicker.dirListWidget);
|
||||||
|
mDirectoryPickerMenu->addAction(tr("&Check Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Checked); });
|
||||||
|
mDirectoryPickerMenu->addAction(tr("&Uncheck Selected"), this,
|
||||||
|
[this]() { setCheckStateForMultiSelectedItems(mDirectoryPicker.dirListWidget, Qt::Unchecked); });
|
||||||
|
}
|
||||||
|
|
||||||
bool Launcher::DataFilesPage::loadSettings()
|
bool Launcher::DataFilesPage::loadSettings()
|
||||||
{
|
{
|
||||||
ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB());
|
ui.navMeshMaxSizeSpinBox->setValue(getMaxNavMeshDbFileSizeMiB());
|
||||||
|
@ -351,9 +385,17 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
||||||
if (!resourcesVfs.isEmpty())
|
if (!resourcesVfs.isEmpty())
|
||||||
directories.insert(0, { resourcesVfs });
|
directories.insert(0, { resourcesVfs });
|
||||||
|
|
||||||
|
QIcon containsDataIcon(":/images/openmw-plugin.png");
|
||||||
|
|
||||||
|
QProgressDialog progressBar("Adding data directories", {}, 0, static_cast<int>(directories.size()), this);
|
||||||
|
progressBar.setWindowModality(Qt::WindowModal);
|
||||||
|
|
||||||
std::unordered_set<QString> visitedDirectories;
|
std::unordered_set<QString> visitedDirectories;
|
||||||
for (const Config::SettingValue& currentDir : directories)
|
for (qsizetype i = 0; i < directories.size(); ++i)
|
||||||
{
|
{
|
||||||
|
progressBar.setValue(static_cast<int>(i));
|
||||||
|
|
||||||
|
const Config::SettingValue& currentDir = directories.at(i);
|
||||||
if (!visitedDirectories.insert(currentDir.value).second)
|
if (!visitedDirectories.insert(currentDir.value).second)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -402,7 +444,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
||||||
// Add a "data file" icon if the directory contains a content file
|
// Add a "data file" icon if the directory contains a content file
|
||||||
if (mSelector->containsDataFiles(currentDir.value))
|
if (mSelector->containsDataFiles(currentDir.value))
|
||||||
{
|
{
|
||||||
item->setIcon(QIcon(":/images/openmw-plugin.png"));
|
item->setIcon(containsDataIcon);
|
||||||
|
|
||||||
tooltip << tr("Contains content file(s)");
|
tooltip << tr("Contains content file(s)");
|
||||||
}
|
}
|
||||||
|
@ -416,6 +458,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
||||||
}
|
}
|
||||||
item->setToolTip(tooltip.join('\n'));
|
item->setToolTip(tooltip.join('\n'));
|
||||||
}
|
}
|
||||||
|
progressBar.setValue(progressBar.maximum());
|
||||||
mSelector->sortFiles();
|
mSelector->sortFiles();
|
||||||
|
|
||||||
QList<Config::SettingValue> selectedArchives = mGameSettings.getArchiveList();
|
QList<Config::SettingValue> selectedArchives = mGameSettings.getArchiveList();
|
||||||
|
@ -765,7 +808,7 @@ void Launcher::DataFilesPage::addSubdirectories(bool append)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString rootPath = QFileDialog::getExistingDirectory(
|
QString rootPath = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select Directory"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::Option::ReadOnly);
|
this, tr("Select Directory"), {}, QFileDialog::ShowDirsOnly | QFileDialog::Option::ReadOnly);
|
||||||
|
|
||||||
if (rootPath.isEmpty())
|
if (rootPath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -793,28 +836,22 @@ void Launcher::DataFilesPage::addSubdirectories(bool append)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog dialog;
|
mDirectoryPicker.dirListWidget->clear();
|
||||||
Ui::SelectSubdirs select;
|
|
||||||
|
|
||||||
select.setupUi(&dialog);
|
|
||||||
|
|
||||||
for (const auto& dir : subdirs)
|
for (const auto& dir : subdirs)
|
||||||
{
|
{
|
||||||
if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty())
|
if (!ui.directoryListWidget->findItems(dir, Qt::MatchFixedString).isEmpty())
|
||||||
continue;
|
continue;
|
||||||
const auto lastRow = select.dirListWidget->count();
|
QListWidgetItem* newDir = new QListWidgetItem(dir, mDirectoryPicker.dirListWidget);
|
||||||
select.dirListWidget->addItem(dir);
|
newDir->setCheckState(Qt::Unchecked);
|
||||||
select.dirListWidget->item(lastRow)->setCheckState(Qt::Unchecked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.show();
|
if (mDirectoryPickerDialog->exec() == QDialog::Rejected)
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Rejected)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < select.dirListWidget->count(); ++i)
|
for (int i = 0; i < mDirectoryPicker.dirListWidget->count(); ++i)
|
||||||
{
|
{
|
||||||
const auto* dir = select.dirListWidget->item(i);
|
const auto* dir = mDirectoryPicker.dirListWidget->item(i);
|
||||||
if (dir->checkState() == Qt::Checked)
|
if (dir->checkState() == Qt::Checked)
|
||||||
{
|
{
|
||||||
ui.directoryListWidget->insertItem(selectedRow, dir->text());
|
ui.directoryListWidget->insertItem(selectedRow, dir->text());
|
||||||
|
@ -865,38 +902,35 @@ void Launcher::DataFilesPage::removeDirectory()
|
||||||
refreshDataFilesView();
|
refreshDataFilesView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos)
|
||||||
|
{
|
||||||
|
QPoint globalPos = list->viewport()->mapToGlobal(pos);
|
||||||
|
menu->exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos)
|
void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = ui.archiveListWidget->viewport()->mapToGlobal(pos);
|
showContextMenu(mArchiveContextMenu, ui.archiveListWidget, pos);
|
||||||
mArchiveContextMenu->exec(globalPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos)
|
void Launcher::DataFilesPage::slotShowDataFilesContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = ui.directoryListWidget->viewport()->mapToGlobal(pos);
|
showContextMenu(mDataFilesContextMenu, ui.directoryListWidget, pos);
|
||||||
mDataFilesContextMenu->exec(globalPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(bool checked)
|
void Launcher::DataFilesPage::slotShowDirectoryPickerContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
Qt::CheckState checkState = checked ? Qt::Checked : Qt::Unchecked;
|
showContextMenu(mDirectoryPickerMenu, mDirectoryPicker.dirListWidget, pos);
|
||||||
|
}
|
||||||
|
|
||||||
for (QListWidgetItem* selectedItem : ui.archiveListWidget->selectedItems())
|
void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState)
|
||||||
|
{
|
||||||
|
for (QListWidgetItem* selectedItem : list->selectedItems())
|
||||||
{
|
{
|
||||||
selectedItem->setCheckState(checkState);
|
selectedItem->setCheckState(checkState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotUncheckMultiSelectedItems()
|
|
||||||
{
|
|
||||||
setCheckStateForMultiSelectedItems(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotCheckMultiSelectedItems()
|
|
||||||
{
|
|
||||||
setCheckStateForMultiSelectedItems(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step)
|
void Launcher::DataFilesPage::moveSources(QListWidget* sourceList, int step)
|
||||||
{
|
{
|
||||||
const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0);
|
const QList<QPair<int, QListWidgetItem*>> sortedItems = sortedSelectedItems(sourceList, step > 0);
|
||||||
|
@ -981,32 +1015,66 @@ bool Launcher::DataFilesPage::showDeleteMessageBox(const QString& text)
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotAddonDataChanged()
|
void Launcher::DataFilesPage::slotAddonDataChanged()
|
||||||
{
|
{
|
||||||
QStringList selectedFiles = selectedFilePaths();
|
mReloadCellsTimer->start();
|
||||||
if (previousSelectedFiles != selectedFiles)
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::onReloadCellsTimerTimeout()
|
||||||
|
{
|
||||||
|
const ContentSelectorModel::ContentFileList items = mSelector->selectedFiles();
|
||||||
|
QStringList selectedFiles;
|
||||||
|
for (const ContentSelectorModel::EsmFile* item : items)
|
||||||
|
selectedFiles.append(item->filePath());
|
||||||
|
|
||||||
|
if (mSelectedFiles != selectedFiles)
|
||||||
{
|
{
|
||||||
previousSelectedFiles = selectedFiles;
|
const std::lock_guard lock(mReloadCellsMutex);
|
||||||
// Loading cells for core Morrowind + Expansions takes about 0.2 seconds, which is enough to cause a
|
mSelectedFiles = std::move(selectedFiles);
|
||||||
// barely perceptible UI lag. Splitting into its own thread to alleviate that.
|
mReloadCells = true;
|
||||||
std::thread loadCellsThread(&DataFilesPage::reloadCells, this, selectedFiles);
|
mStartReloadCells.notify_one();
|
||||||
loadCellsThread.detach();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mutex lock to run reloadCells synchronously.
|
void Launcher::DataFilesPage::reloadCells()
|
||||||
static std::mutex reloadCellsMutex;
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::reloadCells(QStringList selectedFiles)
|
|
||||||
{
|
{
|
||||||
// Use a mutex lock so that we can prevent two threads from executing the rest of this code at the same time
|
QStringList selectedFiles;
|
||||||
// Based on https://stackoverflow.com/a/5429695/531762
|
std::unique_lock lock(mReloadCellsMutex);
|
||||||
std::unique_lock<std::mutex> lock(reloadCellsMutex);
|
|
||||||
|
|
||||||
// The following code will run only if there is not another thread currently running it
|
while (true)
|
||||||
CellNameLoader cellNameLoader;
|
{
|
||||||
QSet<QString> set = cellNameLoader.getCellNames(selectedFiles);
|
mStartReloadCells.wait(lock);
|
||||||
QStringList cellNamesList(set.begin(), set.end());
|
|
||||||
std::sort(cellNamesList.begin(), cellNamesList.end());
|
if (mAbortReloadCells)
|
||||||
emit signalLoadedCellsChanged(cellNamesList);
|
return;
|
||||||
|
|
||||||
|
if (!std::exchange(mReloadCells, false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QStringList newSelectedFiles = mSelectedFiles;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
QStringList filteredFiles;
|
||||||
|
for (const QString& v : newSelectedFiles)
|
||||||
|
if (QFile::exists(v))
|
||||||
|
filteredFiles.append(v);
|
||||||
|
|
||||||
|
if (selectedFiles != filteredFiles)
|
||||||
|
{
|
||||||
|
selectedFiles = std::move(filteredFiles);
|
||||||
|
|
||||||
|
CellNameLoader cellNameLoader;
|
||||||
|
QSet<QString> set = cellNameLoader.getCellNames(selectedFiles);
|
||||||
|
QStringList cellNamesList(set.begin(), set.end());
|
||||||
|
std::sort(cellNamesList.begin(), cellNamesList.end());
|
||||||
|
|
||||||
|
emit signalLoadedCellsChanged(std::move(cellNamesList));
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
if (mAbortReloadCells)
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::startNavMeshTool()
|
void Launcher::DataFilesPage::startNavMeshTool()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define DATAFILESPAGE_H
|
#define DATAFILESPAGE_H
|
||||||
|
|
||||||
#include "ui_datafilespage.h"
|
#include "ui_datafilespage.h"
|
||||||
|
#include "ui_directorypicker.h"
|
||||||
|
|
||||||
#include <components/process/processinvoker.hpp>
|
#include <components/process/processinvoker.hpp>
|
||||||
|
|
||||||
|
@ -10,9 +11,14 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
class QSortFilterProxyModel;
|
||||||
class QAbstractItemModel;
|
class QAbstractItemModel;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
|
@ -41,12 +47,16 @@ namespace Launcher
|
||||||
|
|
||||||
ContentSelectorView::ContentSelector* mSelector;
|
ContentSelectorView::ContentSelector* mSelector;
|
||||||
Ui::DataFilesPage ui;
|
Ui::DataFilesPage ui;
|
||||||
|
QDialog* mDirectoryPickerDialog;
|
||||||
|
Ui::SelectSubdirs mDirectoryPicker;
|
||||||
QMenu* mArchiveContextMenu;
|
QMenu* mArchiveContextMenu;
|
||||||
QMenu* mDataFilesContextMenu;
|
QMenu* mDataFilesContextMenu;
|
||||||
|
QMenu* mDirectoryPickerMenu;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
|
||||||
Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr);
|
Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr);
|
||||||
|
~DataFilesPage();
|
||||||
|
|
||||||
QAbstractItemModel* profilesModel() const;
|
QAbstractItemModel* profilesModel() const;
|
||||||
|
|
||||||
|
@ -81,8 +91,7 @@ namespace Launcher
|
||||||
|
|
||||||
void slotShowArchiveContextMenu(const QPoint& pos);
|
void slotShowArchiveContextMenu(const QPoint& pos);
|
||||||
void slotShowDataFilesContextMenu(const QPoint& pos);
|
void slotShowDataFilesContextMenu(const QPoint& pos);
|
||||||
void slotCheckMultiSelectedItems();
|
void slotShowDirectoryPickerContextMenu(const QPoint& pos);
|
||||||
void slotUncheckMultiSelectedItems();
|
|
||||||
|
|
||||||
void on_newProfileAction_triggered();
|
void on_newProfileAction_triggered();
|
||||||
void on_cloneProfileAction_triggered();
|
void on_cloneProfileAction_triggered();
|
||||||
|
@ -119,7 +128,7 @@ namespace Launcher
|
||||||
Config::LauncherSettings& mLauncherSettings;
|
Config::LauncherSettings& mLauncherSettings;
|
||||||
|
|
||||||
QString mPreviousProfile;
|
QString mPreviousProfile;
|
||||||
QStringList previousSelectedFiles;
|
QStringList mSelectedFiles;
|
||||||
QString mDataLocal;
|
QString mDataLocal;
|
||||||
QStringList mKnownArchives;
|
QStringList mKnownArchives;
|
||||||
QStringList mNewDataDirs;
|
QStringList mNewDataDirs;
|
||||||
|
@ -127,12 +136,21 @@ namespace Launcher
|
||||||
Process::ProcessInvoker* mNavMeshToolInvoker;
|
Process::ProcessInvoker* mNavMeshToolInvoker;
|
||||||
NavMeshToolProgress mNavMeshToolProgress;
|
NavMeshToolProgress mNavMeshToolProgress;
|
||||||
|
|
||||||
|
bool mReloadCells = false;
|
||||||
|
bool mAbortReloadCells = false;
|
||||||
|
std::mutex mReloadCellsMutex;
|
||||||
|
std::condition_variable mStartReloadCells;
|
||||||
|
std::thread mReloadCellsThread;
|
||||||
|
QTimer* mReloadCellsTimer;
|
||||||
|
|
||||||
void addArchive(const QString& name, Qt::CheckState selected, int row = -1);
|
void addArchive(const QString& name, Qt::CheckState selected, int row = -1);
|
||||||
void addArchivesFromDir(const QString& dir);
|
void addArchivesFromDir(const QString& dir);
|
||||||
void buildView();
|
void buildView();
|
||||||
void buildArchiveContextMenu();
|
void buildArchiveContextMenu();
|
||||||
void buildDataFilesContextMenu();
|
void buildDataFilesContextMenu();
|
||||||
void setCheckStateForMultiSelectedItems(bool checked);
|
void buildDirectoryPickerContextMenu();
|
||||||
|
void showContextMenu(QMenu* menu, QListWidget* list, const QPoint& pos);
|
||||||
|
void setCheckStateForMultiSelectedItems(QListWidget* list, Qt::CheckState checkState);
|
||||||
void setProfile(int index, bool savePrevious);
|
void setProfile(int index, bool savePrevious);
|
||||||
void setProfile(const QString& previous, const QString& current, bool savePrevious);
|
void setProfile(const QString& previous, const QString& current, bool savePrevious);
|
||||||
void removeProfile(const QString& profile);
|
void removeProfile(const QString& profile);
|
||||||
|
@ -140,7 +158,8 @@ namespace Launcher
|
||||||
void addProfile(const QString& profile, bool setAsCurrent);
|
void addProfile(const QString& profile, bool setAsCurrent);
|
||||||
void checkForDefaultProfile();
|
void checkForDefaultProfile();
|
||||||
void populateFileViews(const QString& contentModelName);
|
void populateFileViews(const QString& contentModelName);
|
||||||
void reloadCells(QStringList selectedFiles);
|
void onReloadCellsTimerTimeout();
|
||||||
|
void reloadCells();
|
||||||
void refreshDataFilesView();
|
void refreshDataFilesView();
|
||||||
void updateNavMeshProgress(int minDataSize);
|
void updateNavMeshProgress(int minDataSize);
|
||||||
void slotCopySelectedItemsPaths();
|
void slotCopySelectedItemsPaths();
|
||||||
|
|
|
@ -242,11 +242,36 @@ void Launcher::GraphicsPage::handleWindowModeChange(Settings::WindowMode mode)
|
||||||
{
|
{
|
||||||
if (mode == Settings::WindowMode::Fullscreen || mode == Settings::WindowMode::WindowedFullscreen)
|
if (mode == Settings::WindowMode::Fullscreen || mode == Settings::WindowMode::WindowedFullscreen)
|
||||||
{
|
{
|
||||||
|
QString customSizeMessage = tr("Custom window size is available only in Windowed mode.");
|
||||||
|
QString windowBorderMessage = tr("Window border is available only in Windowed mode.");
|
||||||
|
|
||||||
standardRadioButton->toggle();
|
standardRadioButton->toggle();
|
||||||
customRadioButton->setEnabled(false);
|
customRadioButton->setEnabled(false);
|
||||||
customWidthSpinBox->setEnabled(false);
|
customWidthSpinBox->setEnabled(false);
|
||||||
customHeightSpinBox->setEnabled(false);
|
customHeightSpinBox->setEnabled(false);
|
||||||
windowBorderCheckBox->setEnabled(false);
|
windowBorderCheckBox->setEnabled(false);
|
||||||
|
windowBorderCheckBox->setToolTip(windowBorderMessage);
|
||||||
|
customWidthSpinBox->setToolTip(customSizeMessage);
|
||||||
|
customHeightSpinBox->setToolTip(customSizeMessage);
|
||||||
|
customRadioButton->setToolTip(customSizeMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == Settings::WindowMode::Fullscreen)
|
||||||
|
{
|
||||||
|
resolutionComboBox->setEnabled(true);
|
||||||
|
resolutionComboBox->setToolTip("");
|
||||||
|
standardRadioButton->setToolTip("");
|
||||||
|
}
|
||||||
|
else if (mode == Settings::WindowMode::WindowedFullscreen)
|
||||||
|
{
|
||||||
|
QString fullScreenMessage = tr("Windowed Fullscreen mode always uses the native display resolution.");
|
||||||
|
|
||||||
|
resolutionComboBox->setEnabled(false);
|
||||||
|
resolutionComboBox->setToolTip(fullScreenMessage);
|
||||||
|
standardRadioButton->setToolTip(fullScreenMessage);
|
||||||
|
|
||||||
|
// Assume that a first item is a native screen resolution
|
||||||
|
resolutionComboBox->setCurrentIndex(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -254,6 +279,13 @@ void Launcher::GraphicsPage::handleWindowModeChange(Settings::WindowMode mode)
|
||||||
customWidthSpinBox->setEnabled(true);
|
customWidthSpinBox->setEnabled(true);
|
||||||
customHeightSpinBox->setEnabled(true);
|
customHeightSpinBox->setEnabled(true);
|
||||||
windowBorderCheckBox->setEnabled(true);
|
windowBorderCheckBox->setEnabled(true);
|
||||||
|
resolutionComboBox->setEnabled(true);
|
||||||
|
resolutionComboBox->setToolTip("");
|
||||||
|
standardRadioButton->setToolTip("");
|
||||||
|
windowBorderCheckBox->setToolTip("");
|
||||||
|
customWidthSpinBox->setToolTip("");
|
||||||
|
customHeightSpinBox->setToolTip("");
|
||||||
|
customRadioButton->setToolTip("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,11 +88,7 @@ void Launcher::ImportPage::on_importerButton_clicked()
|
||||||
// Create the file if it doesn't already exist, else the importer will fail
|
// Create the file if it doesn't already exist, else the importer will fail
|
||||||
auto path = mCfgMgr.getUserConfigPath();
|
auto path = mCfgMgr.getUserConfigPath();
|
||||||
path /= "openmw.cfg";
|
path /= "openmw.cfg";
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
#else
|
|
||||||
QFile file(Files::pathToQString(path));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ int runLauncher(int argc, char* argv[])
|
||||||
resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string());
|
resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string());
|
||||||
}
|
}
|
||||||
|
|
||||||
l10n::installQtTranslations(app, "launcher", resourcesPath);
|
L10n::installQtTranslations(app, "launcher", resourcesPath);
|
||||||
|
|
||||||
Launcher::MainDialog mainWin(configurationManager);
|
Launcher::MainDialog mainWin(configurationManager);
|
||||||
|
|
||||||
|
|
|
@ -497,11 +497,7 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game settings
|
// Game settings
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
QFile file(userPath / Files::openmwCfgFile);
|
QFile file(userPath / Files::openmwCfgFile);
|
||||||
#else
|
|
||||||
QFile file(Files::getUserConfigPathQString(mCfgMgr));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
|
||||||
{
|
{
|
||||||
|
|
|
@ -163,8 +163,6 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
loadSettingInt(Settings::physics().mAsyncNumThreads, *physicsThreadsSpinBox);
|
loadSettingInt(Settings::physics().mAsyncNumThreads, *physicsThreadsSpinBox);
|
||||||
loadSettingBool(
|
loadSettingBool(
|
||||||
Settings::game().mAllowActorsToFollowOverWaterSurface, *allowNPCToFollowOverWaterSurfaceCheckBox);
|
Settings::game().mAllowActorsToFollowOverWaterSurface, *allowNPCToFollowOverWaterSurfaceCheckBox);
|
||||||
loadSettingBool(
|
|
||||||
Settings::game().mUnarmedCreatureAttacksDamageArmor, *unarmedCreatureAttacksDamageArmorCheckBox);
|
|
||||||
loadSettingInt(Settings::game().mActorCollisionShapeType, *actorCollisonShapeTypeComboBox);
|
loadSettingInt(Settings::game().mActorCollisionShapeType, *actorCollisonShapeTypeComboBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +291,7 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
||||||
|
dopplerSpinBox->setValue(Settings::sound().mDopplerFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
@ -304,6 +303,9 @@ bool Launcher::SettingsPage::loadSettings()
|
||||||
loadSettingBool(Settings::gui().mColorTopicEnable, *changeDialogTopicsCheckBox);
|
loadSettingBool(Settings::gui().mColorTopicEnable, *changeDialogTopicsCheckBox);
|
||||||
showOwnedComboBox->setCurrentIndex(Settings::game().mShowOwned);
|
showOwnedComboBox->setCurrentIndex(Settings::game().mShowOwned);
|
||||||
loadSettingBool(Settings::gui().mStretchMenuBackground, *stretchBackgroundCheckBox);
|
loadSettingBool(Settings::gui().mStretchMenuBackground, *stretchBackgroundCheckBox);
|
||||||
|
connect(controllerMenusCheckBox, &QCheckBox::toggled, this, &SettingsPage::slotControllerMenusToggled);
|
||||||
|
loadSettingBool(Settings::gui().mControllerMenus, *controllerMenusCheckBox);
|
||||||
|
loadSettingBool(Settings::gui().mControllerTooltips, *controllerMenuTooltipsCheckBox);
|
||||||
loadSettingBool(Settings::map().mAllowZooming, *useZoomOnMapCheckBox);
|
loadSettingBool(Settings::map().mAllowZooming, *useZoomOnMapCheckBox);
|
||||||
loadSettingBool(Settings::game().mGraphicHerbalism, *graphicHerbalismCheckBox);
|
loadSettingBool(Settings::game().mGraphicHerbalism, *graphicHerbalismCheckBox);
|
||||||
scalingSpinBox->setValue(Settings::gui().mScalingFactor);
|
scalingSpinBox->setValue(Settings::gui().mScalingFactor);
|
||||||
|
@ -373,8 +375,6 @@ void Launcher::SettingsPage::saveSettings()
|
||||||
saveSettingInt(*physicsThreadsSpinBox, Settings::physics().mAsyncNumThreads);
|
saveSettingInt(*physicsThreadsSpinBox, Settings::physics().mAsyncNumThreads);
|
||||||
saveSettingBool(
|
saveSettingBool(
|
||||||
*allowNPCToFollowOverWaterSurfaceCheckBox, Settings::game().mAllowActorsToFollowOverWaterSurface);
|
*allowNPCToFollowOverWaterSurfaceCheckBox, Settings::game().mAllowActorsToFollowOverWaterSurface);
|
||||||
saveSettingBool(
|
|
||||||
*unarmedCreatureAttacksDamageArmorCheckBox, Settings::game().mUnarmedCreatureAttacksDamageArmor);
|
|
||||||
saveSettingInt(*actorCollisonShapeTypeComboBox, Settings::game().mActorCollisionShapeType);
|
saveSettingInt(*actorCollisonShapeTypeComboBox, Settings::game().mActorCollisionShapeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +486,8 @@ void Launcher::SettingsPage::saveSettings()
|
||||||
|
|
||||||
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
||||||
Settings::sound().mCameraListener.set(cCameraListener);
|
Settings::sound().mCameraListener.set(cCameraListener);
|
||||||
|
|
||||||
|
Settings::sound().mDopplerFactor.set(dopplerSpinBox->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface Changes
|
// Interface Changes
|
||||||
|
@ -497,6 +499,8 @@ void Launcher::SettingsPage::saveSettings()
|
||||||
saveSettingBool(*changeDialogTopicsCheckBox, Settings::gui().mColorTopicEnable);
|
saveSettingBool(*changeDialogTopicsCheckBox, Settings::gui().mColorTopicEnable);
|
||||||
saveSettingInt(*showOwnedComboBox, Settings::game().mShowOwned);
|
saveSettingInt(*showOwnedComboBox, Settings::game().mShowOwned);
|
||||||
saveSettingBool(*stretchBackgroundCheckBox, Settings::gui().mStretchMenuBackground);
|
saveSettingBool(*stretchBackgroundCheckBox, Settings::gui().mStretchMenuBackground);
|
||||||
|
saveSettingBool(*controllerMenusCheckBox, Settings::gui().mControllerMenus);
|
||||||
|
saveSettingBool(*controllerMenuTooltipsCheckBox, Settings::gui().mControllerTooltips);
|
||||||
saveSettingBool(*useZoomOnMapCheckBox, Settings::map().mAllowZooming);
|
saveSettingBool(*useZoomOnMapCheckBox, Settings::map().mAllowZooming);
|
||||||
saveSettingBool(*graphicHerbalismCheckBox, Settings::game().mGraphicHerbalism);
|
saveSettingBool(*graphicHerbalismCheckBox, Settings::game().mGraphicHerbalism);
|
||||||
Settings::gui().mScalingFactor.set(scalingSpinBox->value());
|
Settings::gui().mScalingFactor.set(scalingSpinBox->value());
|
||||||
|
@ -555,6 +559,11 @@ void Launcher::SettingsPage::slotAnimSourcesToggled(bool checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::slotControllerMenusToggled(bool checked)
|
||||||
|
{
|
||||||
|
controllerMenuTooltipsCheckBox->setEnabled(checked);
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::SettingsPage::slotPostProcessToggled(bool checked)
|
void Launcher::SettingsPage::slotPostProcessToggled(bool checked)
|
||||||
{
|
{
|
||||||
postprocessTransparentPostpassCheckBox->setEnabled(checked);
|
postprocessTransparentPostpassCheckBox->setEnabled(checked);
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Launcher
|
||||||
void slotSkyBlendingToggled(bool checked);
|
void slotSkyBlendingToggled(bool checked);
|
||||||
void slotShadowDistLimitToggled(bool checked);
|
void slotShadowDistLimitToggled(bool checked);
|
||||||
void slotDistantLandToggled(bool checked);
|
void slotDistantLandToggled(bool checked);
|
||||||
|
void slotControllerMenusToggled(bool checked);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config::GameSettings& mGameSettings;
|
Config::GameSettings& mGameSettings;
|
||||||
|
|
|
@ -25,7 +25,14 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QListWidget" name="dirListWidget"/>
|
<widget class="QListWidget" name="dirListWidget">
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QCheckBox" name="normaliseRaceSpeedCheckBox">
|
<widget class="QCheckBox" name="normaliseRaceSpeedCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html></string>
|
<string><html><head/><body><p>Don't use race weight in NPC movement speed calculations.</p></body></html></string>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QCheckBox" name="classicCalmSpellsCheckBox">
|
<widget class="QCheckBox" name="classicCalmSpellsCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Stops combat with NPCs affected by Calm spells every frame -- like in Morrowind without the MCP.</p></body></html></string>
|
<string><html><head/><body><p>Stops combat with NPCs affected by Calm spells every frame -- like in Morrowind without the MCP.</p></body></html></string>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QCheckBox" name="avoidCollisionsCheckBox">
|
<widget class="QCheckBox" name="avoidCollisionsCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>If enabled NPCs apply evasion maneuver to avoid collisions with others.</p></body></html></string>
|
<string><html><head/><body><p>If enabled NPCs apply evasion maneuver to avoid collisions with others.</p></body></html></string>
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox">
|
<widget class="QCheckBox" name="requireAppropriateAmmunitionCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>If enabled, a magical ammunition is required to bypass normal weapon resistance or weakness. If disabled, a magical ranged weapon or a magical ammunition is required.</p></body></html></string>
|
<string><html><head/><body><p>If enabled, a magical ammunition is required to bypass normal weapon resistance or weakness. If disabled, a magical ranged weapon or a magical ammunition is required.</p></body></html></string>
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="1">
|
<item row="12" column="1">
|
||||||
<widget class="QCheckBox" name="graphicHerbalismCheckBox">
|
<widget class="QCheckBox" name="graphicHerbalismCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>If this setting is true, containers supporting graphic herbalism will do so instead of opening the menu.</p></body></html></string>
|
<string><html><head/><body><p>If this setting is true, containers supporting graphic herbalism will do so instead of opening the menu.</p></body></html></string>
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="QCheckBox" name="swimUpwardCorrectionCheckBox">
|
<widget class="QCheckBox" name="swimUpwardCorrectionCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.</p></body></html></string>
|
<string><html><head/><body><p>Makes player swim a bit upward from the line of sight. Applies only in third person mode. Intended to make simpler swimming without diving.</p></body></html></string>
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="QCheckBox" name="enchantedWeaponsMagicalCheckBox">
|
<widget class="QCheckBox" name="enchantedWeaponsMagicalCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Make enchanted weapons without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html></string>
|
<string><html><head/><body><p>Make enchanted weapons without Magical flag bypass normal weapons resistance, like in Morrowind.</p></body></html></string>
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QCheckBox" name="canLootDuringDeathAnimationCheckBox">
|
<widget class="QCheckBox" name="canLootDuringDeathAnimationCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html></string>
|
<string><html><head/><body><p>If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. In this case we have to increment death counter and run disposed actor's script instantly.</p><p>If this setting is false, player has to wait until end of death animation in all cases. Makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder. Conflicts with mannequin mods, which use SkipAnim to prevent end of death animation.</p></body></html></string>
|
||||||
|
@ -203,7 +203,7 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QCheckBox" name="classicReflectedAbsorbSpellsCheckBox">
|
<widget class="QCheckBox" name="classicReflectedAbsorbSpellsCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Effects of reflected Absorb spells are not mirrored - like in Morrowind.</p></body></html></string>
|
<string><html><head/><body><p>Effects of reflected Absorb spells are not mirrored - like in Morrowind.</p></body></html></string>
|
||||||
|
@ -213,16 +213,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QCheckBox" name="unarmedCreatureAttacksDamageArmorCheckBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Makes unarmed creature attacks able to reduce armor condition, just as attacks from NPCs and armed creatures.</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Unarmed Creature Attacks Damage Armor</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -430,14 +420,14 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="smoothAnimTransitionsCheckBox">
|
<widget class="QCheckBox" name="smoothAnimTransitionsCheckBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></string>
|
<string><html><head/><body><p>If enabled - makes transitions between different animations/poses much smoother. Also allows to load animation blending config YAML files that can be bundled with animations in order to customise blending styles.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Smooth Animation Transitions</string>
|
<string>Smooth Animation Transitions</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
@ -1099,68 +1089,20 @@
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Audio</string>
|
<string>Audio</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QGridLayout" name="audioLayout">
|
||||||
<item>
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="audioDeviceSelectorLabel">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Select your preferred audio device.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Audio Device</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="audioDeviceSelectorComboBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>283</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="enableHRTFLabel">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>This setting controls HRTF, which simulates 3D sound on stereo systems.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>HRTF</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="enableHRTFComboBox">
|
<widget class="QComboBox" name="enableHRTFComboBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>283</width>
|
<width>0</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1184,11 +1126,74 @@
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item row="1" column="0">
|
||||||
</item>
|
<widget class="QLabel" name="enableHRTFLabel">
|
||||||
<item>
|
<property name="toolTip">
|
||||||
<layout class="QHBoxLayout">
|
<string>This setting controls HRTF, which simulates 3D sound on stereo systems.</string>
|
||||||
<item>
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>HRTF</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="cameraListenerCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use the Camera as the Sound Listener</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="dopplerLabel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Controls the strength of the Doppler effect. Zero means it is completely disabled.</p><p>The Doppler effect increases or decreases the pitch of sounds relative to the velocity of the sound source and the listener.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Doppler Factor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="dopplerSpinBox">
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.250000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="hrtfProfileSelectorComboBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Default</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="hrtfProfileSelectorLabel">
|
<widget class="QLabel" name="hrtfProfileSelectorLabel">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Select your preferred HRTF profile.</string>
|
<string>Select your preferred HRTF profile.</string>
|
||||||
|
@ -1198,17 +1203,27 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QComboBox" name="hrtfProfileSelectorComboBox">
|
<widget class="QLabel" name="audioDeviceSelectorLabel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select your preferred audio device.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Audio Device</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="audioDeviceSelectorComboBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>283</width>
|
<width>0</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1224,16 +1239,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="cameraListenerCheckBox">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use the Camera as the Sound Listener</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -1241,8 +1246,8 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>20</width>
|
||||||
<height>0</height>
|
<height>40</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
|
@ -1398,6 +1403,29 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QCheckBox" name="controllerMenusCheckBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Make it easier to use game menus with a controller.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Controller Menus</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QCheckBox" name="controllerMenuTooltipsCheckBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>When using controller menus, make tooltips visible by default.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Controller Tooltips By Default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="showOwnedLabel">
|
<widget class="QLabel" name="showOwnedLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
|
@ -43,10 +43,10 @@ std::vector<std::string> Launcher::enumerateOpenALDevicesHrtf()
|
||||||
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
|
LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr;
|
||||||
void* funcPtr = alcGetProcAddress(device, "alcGetStringiSOFT");
|
void* funcPtr = alcGetProcAddress(device, "alcGetStringiSOFT");
|
||||||
memcpy(&alcGetStringiSOFT, &funcPtr, sizeof(funcPtr));
|
memcpy(&alcGetStringiSOFT, &funcPtr, sizeof(funcPtr));
|
||||||
ALCint num_hrtf;
|
ALCint numHrtf;
|
||||||
alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf);
|
alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &numHrtf);
|
||||||
ret.reserve(num_hrtf);
|
ret.reserve(numHrtf);
|
||||||
for (ALCint i = 0; i < num_hrtf; ++i)
|
for (ALCint i = 0; i < numHrtf; ++i)
|
||||||
{
|
{
|
||||||
const ALCchar* entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
|
const ALCchar* entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i);
|
||||||
if (strcmp(entry, "") == 0)
|
if (strcmp(entry, "") == 0)
|
||||||
|
|
|
@ -9,7 +9,22 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace sfs = std::filesystem;
|
namespace
|
||||||
|
{
|
||||||
|
// from configfileparser.cpp
|
||||||
|
std::string trim_ws(const std::string& s)
|
||||||
|
{
|
||||||
|
std::string::size_type n, n2;
|
||||||
|
n = s.find_first_not_of(" \t\r\n");
|
||||||
|
if (n == std::string::npos)
|
||||||
|
return std::string();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n2 = s.find_last_not_of(" \t\r\n");
|
||||||
|
return s.substr(n, n2 - n + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MwIniImporter::MwIniImporter()
|
MwIniImporter::MwIniImporter()
|
||||||
: mVerbose(false)
|
: mVerbose(false)
|
||||||
|
@ -311,10 +326,10 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comment_pos = static_cast<int>(utf8.find(';'));
|
const std::string::size_type commentPos = utf8.find(';');
|
||||||
if (comment_pos > 0)
|
if (commentPos != std::string::npos)
|
||||||
{
|
{
|
||||||
utf8 = utf8.substr(0, comment_pos);
|
utf8 = utf8.substr(0, commentPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos = static_cast<int>(utf8.find('='));
|
int pos = static_cast<int>(utf8.find('='));
|
||||||
|
@ -336,7 +351,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat
|
||||||
if (it == map.end())
|
if (it == map.end())
|
||||||
it = map.emplace_hint(it, std::move(key), std::vector<std::string>());
|
it = map.emplace_hint(it, std::move(key), std::vector<std::string>());
|
||||||
|
|
||||||
it->second.push_back(std::string(value));
|
it->second.emplace_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
@ -352,12 +367,10 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(file, line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
|
// ignore comments - keep in sync with configfileparser.cpp
|
||||||
// we cant say comment by only looking at first char anymore
|
if (line.find('#') == line.find_first_not_of(" \t\r\n"))
|
||||||
int comment_pos = static_cast<int>(line.find('#'));
|
|
||||||
if (comment_pos > 0)
|
|
||||||
{
|
{
|
||||||
line = line.substr(0, comment_pos);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.empty())
|
if (line.empty())
|
||||||
|
@ -373,12 +386,14 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat
|
||||||
|
|
||||||
std::string key(line.substr(0, pos));
|
std::string key(line.substr(0, pos));
|
||||||
std::string value(line.substr(pos + 1));
|
std::string value(line.substr(pos + 1));
|
||||||
|
key = trim_ws(key);
|
||||||
|
value = trim_ws(value);
|
||||||
|
|
||||||
if (map.find(key) == map.end())
|
if (map.find(key) == map.end())
|
||||||
{
|
{
|
||||||
map.insert(std::make_pair(key, std::vector<std::string>()));
|
map.insert(std::make_pair(key, std::vector<std::string>()));
|
||||||
}
|
}
|
||||||
map[key].push_back(value);
|
map[key].push_back(std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
class MwIniImporter
|
class MwIniImporter
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <components/files/conversion.hpp>
|
#include <components/files/conversion.hpp>
|
||||||
|
|
||||||
namespace bpo = boost::program_options;
|
namespace bpo = boost::program_options;
|
||||||
namespace sfs = std::filesystem;
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
@ -63,7 +62,7 @@ int wmain(int argc, wchar_t* wargv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
|
bpo::options_description desc("Syntax: openmw-iniimporter <options> inifile configfile\nAllowed options");
|
||||||
bpo::positional_options_description p_desc;
|
bpo::positional_options_description positionalDesc;
|
||||||
auto addOption = desc.add_options();
|
auto addOption = desc.add_options();
|
||||||
addOption("help,h", "produce help message");
|
addOption("help,h", "produce help message");
|
||||||
addOption("verbose,v", "verbose output");
|
addOption("verbose,v", "verbose output");
|
||||||
|
@ -80,11 +79,12 @@ int wmain(int argc, wchar_t* wargv[])
|
||||||
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
"\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n"
|
||||||
"\n\twin1252 - Western European (Latin) alphabet, used by default");
|
"\n\twin1252 - Western European (Latin) alphabet, used by default");
|
||||||
;
|
;
|
||||||
p_desc.add("ini", 1).add("cfg", 1);
|
positionalDesc.add("ini", 1).add("cfg", 1);
|
||||||
|
|
||||||
bpo::variables_map vm;
|
bpo::variables_map vm;
|
||||||
|
|
||||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run();
|
bpo::parsed_options parsed
|
||||||
|
= bpo::command_line_parser(argc, argv).options(desc).positional(positionalDesc).run();
|
||||||
bpo::store(parsed, vm);
|
bpo::store(parsed, vm);
|
||||||
|
|
||||||
if (vm.count("help") || !vm.count("ini") || !vm.count("cfg"))
|
if (vm.count("help") || !vm.count("ini") || !vm.count("cfg"))
|
||||||
|
@ -126,12 +126,20 @@ int wmain(int argc, wchar_t* wargv[])
|
||||||
MwIniImporter importer;
|
MwIniImporter importer;
|
||||||
importer.setVerbose(vm.count("verbose") != 0);
|
importer.setVerbose(vm.count("verbose") != 0);
|
||||||
|
|
||||||
|
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
|
||||||
|
|
||||||
// Font encoding settings
|
// Font encoding settings
|
||||||
std::string encoding(vm["encoding"].as<std::string>());
|
std::string encoding;
|
||||||
|
if (vm["encoding"].defaulted() && cfg.contains("encoding") && !cfg["encoding"].empty())
|
||||||
|
encoding = cfg["encoding"].back();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encoding = vm["encoding"].as<std::string>();
|
||||||
|
cfg["encoding"] = { encoding };
|
||||||
|
}
|
||||||
importer.setInputEncoding(ToUTF8::calculateEncoding(encoding));
|
importer.setInputEncoding(ToUTF8::calculateEncoding(encoding));
|
||||||
|
|
||||||
MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile);
|
MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile);
|
||||||
MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile);
|
|
||||||
|
|
||||||
if (!vm.count("fonts"))
|
if (!vm.count("fonts"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
set(NAVMESHTOOL
|
set(NAVMESHTOOL_LIB
|
||||||
worldspacedata.cpp
|
worldspacedata.cpp
|
||||||
navmesh.cpp
|
navmesh.cpp
|
||||||
main.cpp
|
|
||||||
)
|
)
|
||||||
source_group(apps\\navmeshtool FILES ${NAVMESHTOOL})
|
|
||||||
|
|
||||||
add_library(openmw-navmeshtool-lib STATIC
|
source_group(apps\\navmeshtool FILES ${NAVMESHTOOL_LIB} main.cpp)
|
||||||
${NAVMESHTOOL}
|
|
||||||
)
|
add_library(openmw-navmeshtool-lib STATIC ${NAVMESHTOOL_LIB})
|
||||||
|
|
||||||
if (ANDROID)
|
if (ANDROID)
|
||||||
add_library(openmw-navmeshtool SHARED
|
add_library(openmw-navmeshtool SHARED main.cpp)
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
else()
|
else()
|
||||||
openmw_add_executable(openmw-navmeshtool ${NAVMESHTOOL})
|
openmw_add_executable(openmw-navmeshtool main.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(openmw-navmeshtool openmw-navmeshtool-lib)
|
target_link_libraries(openmw-navmeshtool openmw-navmeshtool-lib)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <components/resource/niffilemanager.hpp>
|
#include <components/resource/niffilemanager.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
#include <components/settings/values.hpp>
|
#include <components/settings/values.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
#include <components/version/version.hpp>
|
#include <components/version/version.hpp>
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
#include <components/vfs/registerarchives.hpp>
|
#include <components/vfs/registerarchives.hpp>
|
||||||
|
@ -62,8 +62,6 @@ namespace NavMeshTool
|
||||||
|
|
||||||
bpo::options_description makeOptionsDescription()
|
bpo::options_description makeOptionsDescription()
|
||||||
{
|
{
|
||||||
using Fallback::FallbackMap;
|
|
||||||
|
|
||||||
bpo::options_description result;
|
bpo::options_description result;
|
||||||
auto addOption = result.add_options();
|
auto addOption = result.add_options();
|
||||||
addOption("help", "print help message");
|
addOption("help", "print help message");
|
||||||
|
@ -145,6 +143,7 @@ namespace NavMeshTool
|
||||||
}
|
}
|
||||||
|
|
||||||
Files::ConfigurationManager config;
|
Files::ConfigurationManager config;
|
||||||
|
config.processPaths(variables, std::filesystem::current_path());
|
||||||
config.readConfiguration(variables, desc);
|
config.readConfiguration(variables, desc);
|
||||||
|
|
||||||
Debug::setupLogging(config.getLogPath(), applicationName);
|
Debug::setupLogging(config.getLogPath(), applicationName);
|
||||||
|
@ -190,7 +189,7 @@ namespace NavMeshTool
|
||||||
|
|
||||||
VFS::Manager vfs;
|
VFS::Manager vfs;
|
||||||
|
|
||||||
VFS::registerArchives(&vfs, fileCollections, archives, true);
|
VFS::registerArchives(&vfs, fileCollections, archives, true, &encoder.getStatelessEncoder());
|
||||||
|
|
||||||
Settings::Manager::load(config);
|
Settings::Manager::load(config);
|
||||||
|
|
||||||
|
@ -225,7 +224,8 @@ namespace NavMeshTool
|
||||||
Resource::SceneManager sceneManager(&vfs, &imageManager, &nifFileManager, &bgsmFileManager, expiryDelay);
|
Resource::SceneManager sceneManager(&vfs, &imageManager, &nifFileManager, &bgsmFileManager, expiryDelay);
|
||||||
Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager, expiryDelay);
|
Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager, expiryDelay);
|
||||||
DetourNavigator::RecastGlobalAllocator::init();
|
DetourNavigator::RecastGlobalAllocator::init();
|
||||||
DetourNavigator::Settings navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager();
|
DetourNavigator::Settings navigatorSettings
|
||||||
|
= DetourNavigator::makeSettingsFromSettingsManager(Debug::getRecastMaxLogLevel());
|
||||||
navigatorSettings.mRecast.mSwimHeightScale
|
navigatorSettings.mRecast.mSwimHeightScale
|
||||||
= EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat();
|
= EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat();
|
||||||
|
|
||||||
|
|
|
@ -201,8 +201,8 @@ namespace NavMeshTool
|
||||||
{
|
{
|
||||||
if (!land.has_value() || osg::Vec2i(land->mX, land->mY) != cellPosition
|
if (!land.has_value() || osg::Vec2i(land->mX, land->mY) != cellPosition
|
||||||
|| (land->mDataTypes & ESM::Land::DATA_VHGT) == 0)
|
|| (land->mDataTypes & ESM::Land::DATA_VHGT) == 0)
|
||||||
return { HeightfieldPlane{ ESM::Land::DEFAULT_HEIGHT }, ESM::Land::DEFAULT_HEIGHT,
|
return { HeightfieldPlane{ static_cast<float>(ESM::Land::DEFAULT_HEIGHT) },
|
||||||
ESM::Land::DEFAULT_HEIGHT };
|
static_cast<float>(ESM::Land::DEFAULT_HEIGHT), static_cast<float>(ESM::Land::DEFAULT_HEIGHT) };
|
||||||
|
|
||||||
ESM::Land::LandData& landData = *landDatas.emplace_back(std::make_unique<ESM::Land::LandData>());
|
ESM::Land::LandData& landData = *landDatas.emplace_back(std::make_unique<ESM::Land::LandData>());
|
||||||
land->loadData(ESM::Land::DATA_VHGT, landData);
|
land->loadData(ESM::Land::DATA_VHGT, landData);
|
||||||
|
|
|
@ -113,7 +113,7 @@ bool isBSA(const std::filesystem::path& path)
|
||||||
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
|
std::unique_ptr<VFS::Archive> makeArchive(const std::filesystem::path& path)
|
||||||
{
|
{
|
||||||
if (isBSA(path))
|
if (isBSA(path))
|
||||||
return VFS::makeBsaArchive(path);
|
return VFS::makeBsaArchive(path, nullptr);
|
||||||
if (std::filesystem::is_directory(path))
|
if (std::filesystem::is_directory(path))
|
||||||
return std::make_unique<VFS::FileSystemArchive>(path);
|
return std::make_unique<VFS::FileSystemArchive>(path);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -198,7 +198,7 @@ void readVFS(std::unique_ptr<VFS::Archive>&& archive, const std::filesystem::pat
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
readVFS(VFS::makeBsaArchive(file.second), file.second, quiet);
|
readVFS(VFS::makeBsaArchive(file.second, nullptr), file.second, quiet);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -235,8 +235,8 @@ Allowed options)");
|
||||||
bpo::variables_map variables;
|
bpo::variables_map variables;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).positional(p).run();
|
bpo::parsed_options validOpts = bpo::command_line_parser(argc, argv).options(desc).positional(p).run();
|
||||||
bpo::store(valid_opts, variables);
|
bpo::store(validOpts, variables);
|
||||||
bpo::notify(variables);
|
bpo::notify(variables);
|
||||||
if (variables.count("help"))
|
if (variables.count("help"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,7 +88,7 @@ opencs_units (view/render
|
||||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||||
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands
|
cellwater terraintexturemode actor terrainselection terrainshapemode brushdraw commands objectmarker
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
|
@ -240,11 +240,7 @@ target_link_libraries(openmw-cs-lib
|
||||||
components_qt
|
components_qt
|
||||||
)
|
)
|
||||||
|
|
||||||
if (QT_VERSION_MAJOR VERSION_EQUAL 6)
|
target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::OpenGLWidgets Qt::Svg)
|
||||||
target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::OpenGLWidgets Qt::Svg)
|
|
||||||
else()
|
|
||||||
target_link_libraries(openmw-cs-lib Qt::Widgets Qt::Core Qt::Network Qt::OpenGL Qt::Svg)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_sources(openmw-cs PRIVATE ${CMAKE_SOURCE_DIR}/files/windows/openmw-cs.exe.manifest)
|
target_sources(openmw-cs PRIVATE ${CMAKE_SOURCE_DIR}/files/windows/openmw-cs.exe.manifest)
|
||||||
|
|
|
@ -34,12 +34,10 @@
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
#include <components/nifosg/nifloader.hpp>
|
#include <components/nifosg/nifloader.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include "view/doc/viewmanager.hpp"
|
#include "view/doc/viewmanager.hpp"
|
||||||
|
|
||||||
using namespace Fallback;
|
|
||||||
|
|
||||||
CS::Editor::Editor(int argc, char** argv)
|
CS::Editor::Editor(int argc, char** argv)
|
||||||
: mConfigVariables(readConfiguration())
|
: mConfigVariables(readConfiguration())
|
||||||
, mSettingsState(mCfgMgr)
|
, mSettingsState(mCfgMgr)
|
||||||
|
@ -124,7 +122,10 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
|
||||||
->default_value(std::vector<std::string>(), "fallback-archive")
|
->default_value(std::vector<std::string>(), "fallback-archive")
|
||||||
->multitoken());
|
->multitoken());
|
||||||
addOption("fallback",
|
addOption("fallback",
|
||||||
boost::program_options::value<FallbackMap>()->default_value(FallbackMap(), "")->multitoken()->composing(),
|
boost::program_options::value<Fallback::FallbackMap>()
|
||||||
|
->default_value(Fallback::FallbackMap(), "")
|
||||||
|
->multitoken()
|
||||||
|
->composing(),
|
||||||
"fallback values");
|
"fallback values");
|
||||||
Files::ConfigurationManager::addCommonOptions(desc);
|
Files::ConfigurationManager::addCommonOptions(desc);
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ std::pair<Files::PathContainer, std::vector<std::string>> CS::Editor::readConfig
|
||||||
{
|
{
|
||||||
boost::program_options::variables_map& variables = mConfigVariables;
|
boost::program_options::variables_map& variables = mConfigVariables;
|
||||||
|
|
||||||
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);
|
Fallback::Map::init(variables["fallback"].as<Fallback::FallbackMap>().mMap);
|
||||||
|
|
||||||
mEncodingName = variables["encoding"].as<std::string>();
|
mEncodingName = variables["encoding"].as<std::string>();
|
||||||
mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName));
|
mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName));
|
||||||
|
@ -165,7 +166,7 @@ std::pair<Files::PathContainer, std::vector<std::string>> CS::Editor::readConfig
|
||||||
if (!local.empty())
|
if (!local.empty())
|
||||||
{
|
{
|
||||||
std::filesystem::create_directories(local);
|
std::filesystem::create_directories(local);
|
||||||
dataLocal.push_back(local);
|
dataLocal.push_back(std::move(local));
|
||||||
}
|
}
|
||||||
mCfgMgr.filterOutNonExistingPaths(dataDirs);
|
mCfgMgr.filterOutNonExistingPaths(dataDirs);
|
||||||
mCfgMgr.filterOutNonExistingPaths(dataLocal);
|
mCfgMgr.filterOutNonExistingPaths(dataLocal);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include <apps/opencs/model/world/universalid.hpp>
|
#include <apps/opencs/model/world/universalid.hpp>
|
||||||
|
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
#include "../world/idcompletionmanager.hpp"
|
#include "../world/idcompletionmanager.hpp"
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <components/files/multidircollection.hpp>
|
#include <components/files/multidircollection.hpp>
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,8 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
@ -55,16 +52,17 @@ void CSMDoc::Runner::start(bool delayed)
|
||||||
|
|
||||||
QString path = "openmw";
|
QString path = "openmw";
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
path.append(QString(".exe"));
|
path.append(QLatin1String(".exe"));
|
||||||
#elif defined(Q_OS_MAC)
|
|
||||||
QDir dir(QCoreApplication::applicationDirPath());
|
|
||||||
dir.cdUp();
|
|
||||||
dir.cdUp();
|
|
||||||
dir.cdUp();
|
|
||||||
path = dir.absoluteFilePath(path.prepend("OpenMW.app/Contents/MacOS/"));
|
|
||||||
#else
|
|
||||||
path.prepend(QString("./"));
|
|
||||||
#endif
|
#endif
|
||||||
|
QDir dir(QCoreApplication::applicationDirPath());
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
// the CS and engine are in separate .app directories
|
||||||
|
dir.cdUp();
|
||||||
|
dir.cdUp();
|
||||||
|
dir.cdUp();
|
||||||
|
path.prepend("OpenMW.app/Contents/MacOS/");
|
||||||
|
#endif
|
||||||
|
path = dir.absoluteFilePath(path);
|
||||||
|
|
||||||
mStartup = new QTemporaryFile(this);
|
mStartup = new QTemporaryFile(this);
|
||||||
mStartup->open();
|
mStartup->open();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include <components/to_utf8/to_utf8.hpp>
|
#include <components/toutf8/toutf8.hpp>
|
||||||
|
|
||||||
#include "operation.hpp"
|
#include "operation.hpp"
|
||||||
#include "savingstate.hpp"
|
#include "savingstate.hpp"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue