Compare commits
631 Commits
Author | SHA1 | Date | |
---|---|---|---|
b98408dd32 | |||
36054434a5 | |||
d9e41c27ef | |||
8e8f8e4706 | |||
edb1a6f9e1 | |||
![]() |
33723db314 | ||
4bc440e906 | |||
![]() |
27b248d851 | ||
e3c2e024bb | |||
![]() |
b69610d7f3 | ||
92a768d6f1 | |||
![]() |
5ecd7d754d | ||
![]() |
e3161f64f6 | ||
![]() |
5b0b091ab6 | ||
![]() |
4fdf28fb79 | ||
49213a1cf0 | |||
e30db231f6 | |||
6609c4867f | |||
![]() |
84c5e8bca6 | ||
1a25749315 | |||
![]() |
3852f5995d | ||
9093b7a16e | |||
afead1c2c0 | |||
1b2572f381 | |||
![]() |
27ca6b3f73 | ||
![]() |
f157648d1e | ||
![]() |
d4baaeccfc | ||
![]() |
d412b66c6e | ||
![]() |
74ae511f92 | ||
![]() |
a3fbafe4ae | ||
![]() |
8a45fbe9ed | ||
![]() |
01c7929ee3 | ||
![]() |
2261af17d7 | ||
![]() |
41f34c3992 | ||
![]() |
36b1cd2dde | ||
![]() |
80374b3ec6 | ||
![]() |
bc00d1e45f | ||
![]() |
6ddb507247 | ||
![]() |
b0f3b8f3d0 | ||
![]() |
06e7191056 | ||
![]() |
997131ba64 | ||
![]() |
ef9f412e5f | ||
![]() |
7b69d41c60 | ||
![]() |
552947f507 | ||
![]() |
f69f2df63c | ||
![]() |
aa270067f6 | ||
![]() |
28977313da | ||
![]() |
cfe35d7795 | ||
![]() |
4abbe332db | ||
![]() |
3104abd4ad | ||
![]() |
7714f7b503 | ||
![]() |
9d06f10a9b | ||
![]() |
8c27f7683b | ||
![]() |
bf1a491789 | ||
![]() |
701cb540e5 | ||
![]() |
0f18a0349a | ||
![]() |
205a152350 | ||
![]() |
dae1a56691 | ||
![]() |
39181f42cf | ||
![]() |
3d706ad1a7 | ||
![]() |
a31b77e5bc | ||
![]() |
b417643415 | ||
![]() |
dac2b4ff16 | ||
![]() |
2d12b0c747 | ||
![]() |
5fe26edaa6 | ||
![]() |
a736cfd548 | ||
![]() |
5af4214daa | ||
![]() |
98ef7b329a | ||
![]() |
b0e1962fa7 | ||
![]() |
83684e8882 | ||
![]() |
1ed7d077a9 | ||
![]() |
ba4b36618f | ||
![]() |
af647a4bad | ||
![]() |
b719530ef0 | ||
![]() |
530d61d67e | ||
![]() |
3d76bcb48c | ||
![]() |
70ce2f1f3c | ||
![]() |
21a190a1aa | ||
![]() |
a88d222709 | ||
![]() |
b2defceae5 | ||
![]() |
8d7565ffc4 | ||
![]() |
9960b25dff | ||
![]() |
411c116deb | ||
![]() |
64e007f1fd | ||
![]() |
c62fc365db | ||
![]() |
e7e630bd5d | ||
![]() |
7d77175fbb | ||
![]() |
f033553972 | ||
![]() |
ae1ed044ba | ||
![]() |
35d601c7a7 | ||
![]() |
f89aeec374 | ||
![]() |
42c3b4b42e | ||
![]() |
322fc31396 | ||
![]() |
6e4d5cfddd | ||
![]() |
d81485a8bf | ||
![]() |
a9260d956c | ||
![]() |
025bb560bc | ||
![]() |
cdd1488e13 | ||
![]() |
b8b2644969 | ||
![]() |
09b5c0a5d0 | ||
![]() |
1ed66f3aa2 | ||
![]() |
3b4d5d1c3f | ||
![]() |
f98fd5a7ad | ||
![]() |
b961109623 | ||
![]() |
8f0d1023a4 | ||
![]() |
79773ba95c | ||
![]() |
ff3f02fb8c | ||
![]() |
0af2b20b3a | ||
![]() |
b026fe357e | ||
![]() |
ade36c013b | ||
![]() |
54a6a7f590 | ||
![]() |
20728e4a0f | ||
![]() |
afa456f6b3 | ||
![]() |
3fbfb77430 | ||
![]() |
051bcb62c6 | ||
![]() |
d2c57eed6d | ||
![]() |
f2f38c0e0d | ||
![]() |
4046bdbc6a | ||
![]() |
c83cc206fd | ||
![]() |
41ac14fbd3 | ||
![]() |
e4c1cad1a7 | ||
![]() |
863c1ac27a | ||
![]() |
c85eba617c | ||
![]() |
dcb7b7c309 | ||
![]() |
3cee186663 | ||
![]() |
06afe507f6 | ||
![]() |
4268d4d770 | ||
![]() |
d61dae5ab4 | ||
![]() |
b5f39c1d53 | ||
![]() |
767a61b86e | ||
![]() |
0d3c0a2233 | ||
![]() |
0431103a1d | ||
![]() |
633e4e642c | ||
![]() |
77dc82a381 | ||
![]() |
44a63d4aaa | ||
![]() |
5b3297f916 | ||
![]() |
41413d4712 | ||
![]() |
fd2e5ce71e | ||
![]() |
e9ddd7d3b8 | ||
![]() |
da6795f002 | ||
![]() |
f497bb4b44 | ||
![]() |
4aea85649f | ||
![]() |
c56672dd04 | ||
![]() |
c2dc1cd65f | ||
![]() |
555783af4c | ||
![]() |
b9ffae25e3 | ||
![]() |
0f89936e01 | ||
![]() |
6ecccb3fe1 | ||
![]() |
2e003b56ea | ||
![]() |
a705418b6f | ||
![]() |
9767eb9d7f | ||
![]() |
450b15944f | ||
![]() |
1fa7cb2afa | ||
![]() |
d2415ff5f9 | ||
![]() |
cdbe8d73f6 | ||
![]() |
38ae86f315 | ||
![]() |
100201d23c | ||
![]() |
db7a7f38f7 | ||
![]() |
677ad5c54b | ||
![]() |
b8e3cd5d64 | ||
![]() |
dead1197bd | ||
![]() |
a2455daa6c | ||
![]() |
ddff1fc455 | ||
![]() |
82f2bd6231 | ||
![]() |
cc7c13e17f | ||
![]() |
04a64e1312 | ||
![]() |
bfecd9ebc6 | ||
![]() |
6fb8ceb501 | ||
![]() |
8124d101ad | ||
![]() |
de8602847e | ||
![]() |
9d1ca1986d | ||
![]() |
a0312ff604 | ||
![]() |
6f04513faa | ||
![]() |
a747f55423 | ||
![]() |
d27e6569a0 | ||
![]() |
135ed0bf8b | ||
![]() |
67ac27c054 | ||
![]() |
4e123d747a | ||
![]() |
9df470acfc | ||
![]() |
af8edc72f4 | ||
![]() |
2b2ae66b8d | ||
![]() |
0a95c5dff3 | ||
![]() |
56e1d80cf4 | ||
![]() |
65432fd317 | ||
![]() |
2ec21f5eba | ||
![]() |
92e82c203f | ||
![]() |
272bc5fe89 | ||
![]() |
e8d5efd3b3 | ||
![]() |
8b1a0a5b8e | ||
![]() |
293b05fec6 | ||
![]() |
37ba495354 | ||
![]() |
a2e689a0dc | ||
![]() |
2ea119fb31 | ||
![]() |
162f59d220 | ||
![]() |
880c5e722e | ||
![]() |
82efa28703 | ||
![]() |
c091a90cea | ||
![]() |
e4c014c1a8 | ||
![]() |
fe4704d0f6 | ||
![]() |
9ea797b00b | ||
![]() |
683f202191 | ||
![]() |
1cf6e2743b | ||
![]() |
2375aefebb | ||
![]() |
1e04f66a11 | ||
![]() |
f8bd483139 | ||
![]() |
3548ce84c1 | ||
![]() |
90b68f9987 | ||
![]() |
44e895ee08 | ||
![]() |
8032547fd0 | ||
![]() |
a34dc35f0f | ||
![]() |
68a5f0dd4b | ||
![]() |
654f8d0761 | ||
![]() |
942ff8bf4a | ||
![]() |
e2c4392c6d | ||
![]() |
7e771b1cfc | ||
![]() |
dd799cf5c0 | ||
![]() |
b8be28619a | ||
![]() |
ca012a1c80 | ||
![]() |
50de42ec9f | ||
![]() |
38c9dd50ff | ||
![]() |
27e4e3444a | ||
![]() |
a8935da416 | ||
![]() |
beb56c527b | ||
![]() |
5e3caedaf6 | ||
![]() |
0be17716f5 | ||
![]() |
dda5fbc330 | ||
![]() |
ffc16c6814 | ||
![]() |
705371d7ee | ||
![]() |
7c7810836e | ||
![]() |
af9c039dcb | ||
![]() |
7325835c3f | ||
![]() |
e7aa72a7ab | ||
![]() |
35c48de638 | ||
![]() |
ae50ed980f | ||
![]() |
1d6f0445f7 | ||
![]() |
799ef63b81 | ||
![]() |
6b22a0c03a | ||
![]() |
2d54638f49 | ||
![]() |
8adec835f6 | ||
![]() |
a34654a9a9 | ||
![]() |
b7c8108ad5 | ||
![]() |
c34c3c3654 | ||
![]() |
88988dd3e1 | ||
![]() |
351b98189f | ||
![]() |
e6a049c214 | ||
![]() |
b9d027291e | ||
![]() |
eb00915c39 | ||
![]() |
828a22a939 | ||
![]() |
875d02458e | ||
![]() |
51d59cc90b | ||
![]() |
a6d6ced1ad | ||
![]() |
7e9855881b | ||
![]() |
cf4e7ca279 | ||
![]() |
0a9b2b0bac | ||
![]() |
f6b0a63410 | ||
![]() |
7563cd4a08 | ||
![]() |
851f6d6624 | ||
![]() |
cd97acfcc1 | ||
![]() |
613a2c5583 | ||
![]() |
4bff6efe97 | ||
![]() |
c514dc7a24 | ||
![]() |
32e95185ad | ||
![]() |
24754edb6a | ||
![]() |
79fbb76524 | ||
![]() |
bbe61e4443 | ||
![]() |
b85aede966 | ||
![]() |
c66ca6e44f | ||
![]() |
a192024fef | ||
![]() |
918df9098a | ||
![]() |
c9271bfa36 | ||
![]() |
fa162c818b | ||
![]() |
ff976e3ec2 | ||
![]() |
17c5651305 | ||
![]() |
7c7b049ba1 | ||
![]() |
0823fe8b3d | ||
![]() |
e787fd0fb5 | ||
![]() |
650497bff4 | ||
![]() |
2f25bd30b0 | ||
![]() |
d58157a450 | ||
![]() |
9d049bd041 | ||
![]() |
988222b711 | ||
![]() |
f42bd3036f | ||
![]() |
297239fb5c | ||
![]() |
dbd46d44aa | ||
![]() |
254f4d6e92 | ||
![]() |
e48719fa44 | ||
![]() |
348e5a4e19 | ||
![]() |
8d28972323 | ||
![]() |
d74bd0a39b | ||
![]() |
07307a6d8f | ||
![]() |
151fb6e58d | ||
![]() |
888ab49e44 | ||
![]() |
24dad37da7 | ||
![]() |
eb6a41556d | ||
![]() |
5534cc4457 | ||
![]() |
dde90fb5b7 | ||
![]() |
efb2f749aa | ||
![]() |
fbee977166 | ||
![]() |
9f012b8ac8 | ||
![]() |
9c3a157a84 | ||
![]() |
b7f632077c | ||
![]() |
bfab242344 | ||
![]() |
6e54a96730 | ||
![]() |
69d35a749f | ||
![]() |
4745702909 | ||
![]() |
e94801ee02 | ||
![]() |
cc57fbdcd5 | ||
![]() |
674097f672 | ||
![]() |
472561c1b8 | ||
![]() |
d345be2114 | ||
![]() |
c505dfaa11 | ||
![]() |
1574d5ab4c | ||
![]() |
0a24f497cc | ||
![]() |
9e629780ad | ||
![]() |
98a842655a | ||
![]() |
53943878c1 | ||
![]() |
34360c1603 | ||
![]() |
356448bb70 | ||
![]() |
103cd641a7 | ||
![]() |
d7fb0b3021 | ||
![]() |
7bf79ec645 | ||
![]() |
dd0e904432 | ||
![]() |
561739ba8b | ||
![]() |
b2596c0580 | ||
![]() |
b1456b4fda | ||
![]() |
923cf9b2bb | ||
![]() |
273917060b | ||
![]() |
7ba2046d14 | ||
![]() |
be145c12a3 | ||
![]() |
759e796fdd | ||
![]() |
9121beaf8d | ||
![]() |
89472dfc54 | ||
![]() |
eb739195ea | ||
![]() |
2da0bc9535 | ||
![]() |
7255a162e9 | ||
![]() |
a479506dcf | ||
![]() |
cf62e85172 | ||
![]() |
c0ea7acd28 | ||
![]() |
7923db38c8 | ||
![]() |
bf9937619e | ||
![]() |
e5fe99eda9 | ||
![]() |
eded375cf6 | ||
![]() |
1b619a7a36 | ||
![]() |
5d79e475d1 | ||
![]() |
cb2b9dd3a2 | ||
![]() |
04f819b331 | ||
![]() |
5807ea001a | ||
![]() |
28d92dc68b | ||
![]() |
91a221529f | ||
![]() |
844af0d93f | ||
![]() |
6912d74d71 | ||
![]() |
f1a6c0fcee | ||
![]() |
edad3ab28c | ||
![]() |
fb7e086770 | ||
![]() |
6446f1d1bc | ||
![]() |
01f391dea3 | ||
![]() |
5b635abb38 | ||
![]() |
54c52b230a | ||
![]() |
40eb51e5eb | ||
![]() |
546c4f36f0 | ||
![]() |
2911960482 | ||
![]() |
265e19def8 | ||
![]() |
2bc88768b6 | ||
![]() |
32f7923652 | ||
![]() |
e379f05aca | ||
![]() |
a7bab660e9 | ||
![]() |
1bcb85968b | ||
![]() |
4adf13539a | ||
![]() |
8b47c5633a | ||
![]() |
cb1e3f1b76 | ||
![]() |
92ef89d5d2 | ||
![]() |
b8fd9d6c45 | ||
![]() |
0c17ca115e | ||
![]() |
505a840574 | ||
![]() |
56d742c1d2 | ||
![]() |
28c66fa689 | ||
![]() |
ceea1339d0 | ||
![]() |
8aea50fd2b | ||
![]() |
166e1f40fe | ||
![]() |
415dcafee3 | ||
![]() |
0399a6eb3c | ||
![]() |
ac70da5b38 | ||
![]() |
5ad20f6b4e | ||
![]() |
283aa92579 | ||
![]() |
a24cbbcc93 | ||
![]() |
17b70b47ce | ||
![]() |
295912fbb3 | ||
![]() |
859adf966a | ||
![]() |
cf404f980d | ||
![]() |
6979abe96a | ||
![]() |
c685cbd640 | ||
![]() |
4934d78cea | ||
![]() |
c6716e1b1a | ||
![]() |
cc1d77ea32 | ||
![]() |
3e7ac0d87d | ||
![]() |
a6952251de | ||
![]() |
d10bf29493 | ||
![]() |
9364aa3536 | ||
![]() |
a63135045e | ||
![]() |
bc441116e2 | ||
![]() |
025ef61de1 | ||
![]() |
e4c7ffe201 | ||
![]() |
0264fbebcd | ||
![]() |
7dd61c89fc | ||
![]() |
a62645f0b7 | ||
![]() |
88079a3ee4 | ||
![]() |
c7fbe591ba | ||
![]() |
b1139a3911 | ||
![]() |
f03fa29836 | ||
![]() |
04a6365349 | ||
![]() |
4d3c16fabc | ||
![]() |
9d5896b62c | ||
![]() |
23a1033787 | ||
![]() |
c35cb6cf45 | ||
![]() |
e0708e519c | ||
![]() |
0935dda00b | ||
![]() |
1119f774f9 | ||
![]() |
7dcf98c395 | ||
![]() |
e5174fdb08 | ||
![]() |
0594668387 | ||
![]() |
ebbb1f82fe | ||
![]() |
dc8061a0a4 | ||
![]() |
6c1c17445a | ||
![]() |
56d366116a | ||
![]() |
1ed4d271c7 | ||
![]() |
bd1098f373 | ||
![]() |
8ed9a33bcd | ||
![]() |
17f37b48e7 | ||
![]() |
5ea8bec0cf | ||
![]() |
2f94fa4e2f | ||
![]() |
6832b32741 | ||
![]() |
c06b3db71e | ||
![]() |
ebbaec762d | ||
![]() |
ebc2246901 | ||
![]() |
df76d83d4b | ||
![]() |
7b15677426 | ||
![]() |
297201a75f | ||
![]() |
0c0cdfdee1 | ||
![]() |
579194dd35 | ||
![]() |
fa59bb06b1 | ||
![]() |
38d4c5dd52 | ||
![]() |
ce5658a205 | ||
![]() |
f9e68a6854 | ||
![]() |
f4bd4fe69b | ||
![]() |
26d5c56cd0 | ||
![]() |
9fc73468a2 | ||
![]() |
37317136ed | ||
![]() |
4ce7b0cadf | ||
![]() |
29e8592582 | ||
![]() |
a088c2455e | ||
![]() |
dab16fb80a | ||
![]() |
c9f918784c | ||
![]() |
2876076cea | ||
![]() |
08c53160a4 | ||
![]() |
6cabacbcc0 | ||
![]() |
d3d153b9c0 | ||
![]() |
b9afcec3cf | ||
![]() |
fd73afb66b | ||
![]() |
64fb980ae4 | ||
![]() |
c58f85c6ac | ||
![]() |
94131a24ad | ||
![]() |
30cc2a5e9c | ||
![]() |
6eb3e814fe | ||
![]() |
e029978937 | ||
![]() |
85d637e62e | ||
![]() |
dbdd7f3705 | ||
![]() |
7b7eba1c7c | ||
![]() |
0daf33c36f | ||
![]() |
68a8d7d212 | ||
![]() |
9f943aa2d0 | ||
![]() |
6b9a2ed5d2 | ||
![]() |
dcb332b06f | ||
![]() |
b9f2cc4300 | ||
![]() |
48716f1c0e | ||
![]() |
33c8c28899 | ||
![]() |
eb5968bdd2 | ||
![]() |
16768cf10c | ||
![]() |
789828e8b8 | ||
![]() |
4b57ee4e64 | ||
![]() |
b61c03630d | ||
![]() |
b3a4b7158e | ||
![]() |
28bb2e2adf | ||
![]() |
c575385ba3 | ||
![]() |
45ef5ee000 | ||
![]() |
5552bea525 | ||
![]() |
4f22704922 | ||
![]() |
e0660a699b | ||
![]() |
4b5827cb3e | ||
![]() |
08ade0eb6f | ||
![]() |
e4f89f0486 | ||
![]() |
b2709aef6f | ||
![]() |
3bf385b317 | ||
![]() |
bebfdfa267 | ||
![]() |
e3e7d12ff8 | ||
![]() |
058bafe033 | ||
![]() |
2dd4e0d841 | ||
![]() |
d603d9d54a | ||
![]() |
568d278871 | ||
![]() |
438c50d775 | ||
![]() |
8c08f63881 | ||
![]() |
71020e40a5 | ||
![]() |
413a32f33f | ||
![]() |
d4ca781e90 | ||
![]() |
539a5ed74f | ||
![]() |
093cead312 | ||
![]() |
c57ef45ce6 | ||
![]() |
8232543abc | ||
![]() |
29ec02b65e | ||
![]() |
0e765e427b | ||
![]() |
1cbedb41d9 | ||
![]() |
a78231eac5 | ||
![]() |
9bd0ca74b6 | ||
![]() |
800bbd359b | ||
![]() |
10cc27e7cf | ||
![]() |
9deeb5e405 | ||
![]() |
614793ecd0 | ||
![]() |
a9ed10573b | ||
![]() |
15a951288d | ||
![]() |
f15440c3c3 | ||
![]() |
dab4b13bfd | ||
![]() |
f8db912f5f | ||
![]() |
5cfee38329 | ||
![]() |
466fea495d | ||
![]() |
ba77e21817 | ||
![]() |
cc72a28ee3 | ||
![]() |
e815fe2787 | ||
![]() |
2ff6c71c23 | ||
![]() |
1dd633be0b | ||
![]() |
d885f27e0b | ||
![]() |
a08c738a65 | ||
![]() |
14ab8942af | ||
![]() |
9caae00db9 | ||
![]() |
4b87b6e5d6 | ||
![]() |
1febce3775 | ||
![]() |
d2b677a0e2 | ||
![]() |
82df40591b | ||
![]() |
774e4f5306 | ||
![]() |
19f6d85243 | ||
![]() |
1be7987abe | ||
![]() |
2dbe129857 | ||
![]() |
d1280f28c2 | ||
![]() |
53897f8186 | ||
![]() |
b4bf29dc9e | ||
![]() |
bc87df170b | ||
![]() |
67ea080c2e | ||
![]() |
7159b9e513 | ||
![]() |
7931069302 | ||
![]() |
eb413f79e4 | ||
![]() |
7bd8b56657 | ||
![]() |
c94e31f82a | ||
![]() |
639fd53a19 | ||
![]() |
62b04ff491 | ||
![]() |
1e5c36a351 | ||
![]() |
c8fd4df6f3 | ||
![]() |
1928d57f46 | ||
![]() |
39bb5f5ee9 | ||
![]() |
1cef3117cb | ||
![]() |
61c34da01e | ||
![]() |
7687ccf3e8 | ||
![]() |
b047dc9313 | ||
![]() |
c4d016a0fd | ||
![]() |
ae0154935d | ||
![]() |
dd238755c9 | ||
![]() |
5e07c98919 | ||
![]() |
98b2511660 | ||
![]() |
2ecff6276c | ||
![]() |
e8aee5412f | ||
![]() |
7fa48f6c5d | ||
![]() |
d81c120024 | ||
![]() |
6a8cdbab4c | ||
![]() |
bde7ed901c | ||
![]() |
f0aa9c423b | ||
![]() |
8313b2a2fd | ||
![]() |
95dce399b5 | ||
![]() |
3eb836fd81 | ||
![]() |
a0bfe0f77f | ||
![]() |
765c41307f | ||
![]() |
46edda6d18 | ||
![]() |
09df72c3d2 | ||
![]() |
c305e32a47 | ||
![]() |
ad8818f811 | ||
![]() |
d3e1d9d158 | ||
![]() |
f3e25d9c64 | ||
![]() |
d51e0cc32e | ||
![]() |
1c5bf4d3a8 | ||
![]() |
edfa71d3ac | ||
![]() |
9e47a366de | ||
![]() |
0bc4e061d0 | ||
![]() |
14ef4e2613 | ||
![]() |
93c8c0f21f | ||
![]() |
f6e3d518e4 | ||
![]() |
cad496b1fb | ||
![]() |
f7354e54dc | ||
![]() |
d6288518c4 | ||
![]() |
abb485f828 | ||
![]() |
6b1d09955f | ||
![]() |
1c97a08b8d | ||
![]() |
589ebdc73f | ||
![]() |
8b5da7535b | ||
![]() |
3bad3122f0 | ||
![]() |
3f672e6ef3 | ||
![]() |
70e4e285d7 | ||
![]() |
5a7e660812 | ||
![]() |
428887cb8a | ||
![]() |
064e967810 | ||
![]() |
be0ccfa1ba | ||
![]() |
cf1fed9bec | ||
![]() |
307f640327 | ||
![]() |
40d34c2cca | ||
![]() |
7f5a47f8a4 | ||
![]() |
2494bc0522 | ||
![]() |
b70ea57122 | ||
![]() |
3d705f7178 | ||
![]() |
1cd41ce0b9 | ||
![]() |
eab0eec746 | ||
![]() |
17f605275e | ||
![]() |
f4771d4f37 | ||
![]() |
445bb5bad5 | ||
![]() |
1902e34d04 | ||
![]() |
a7210c69ed | ||
![]() |
4b4fabaee3 | ||
![]() |
876e6079d4 | ||
![]() |
b81818f74d | ||
![]() |
0de719b67f | ||
![]() |
296c64eb73 | ||
![]() |
4cb3275498 | ||
![]() |
c909779514 | ||
![]() |
e1ac0a35b4 | ||
![]() |
e3d8992a35 | ||
![]() |
f167b4d447 | ||
![]() |
0f3c78a8c7 |
.github
.gitignore.gitmodules.travis.ymlREADME.mdapp
AboutDialog.qmlApplicationSettings.qmlCheckableSlider.qmlFontPixels.qmlFontScanlines.qmlFonts.qmlGlossy.qmlInsertNameDialog.qmlPreprocessedTerminal.qmlSettingsEffectsTab.qmlSettingsGeneralTab.qmlSettingsTerminalTab.qmlSettingsWindow.qmlShaderTerminal.qmlapp.profileio.cppfileio.h
fonts
1977-commodore-pet
COMMODORE_PET_128.ttfCOMMODORE_PET_128_2y.ttfCOMMODORE_PET_2x.ttfCOMMODORE_PET_2y.ttfCOMMODORE_PET_64.ttfCOMMODORE_PET_64_2y.ttf
1979-atari-400-800
1982-commodore64
C64_Elite_Mono_v1.0-STYLE.ttfC64_Pro_Mono_v1.0-STYLE.ttfC64_Pro_v1.0-STYLE.ttfC64_User_Mono_v1.0-STYLE.ttfC64_User_v1.0-STYLE.ttflicense.txt
1985-atari-st
1985-ibm-pc-vga
modern-terminus
frames
BlackRoughFrame.qmlNoFrame.qmlWhiteSimpleFrame.qml
images
black-frame-normals.pngblack-frame-original.pngblack-frame.pngrandfunction.pngscreen-frame-normals.pngscreen-frame-original.pngscreen-frame.png
utils
icons
main.cppmain.qmlmonospacefontmanager.cppmonospacefontmanager.hqml
AboutDialog.qmlApplicationSettings.qmlBurnInEffect.qmlCheckableSlider.qmlColorButton.qml
Components
FontPixels.qmlFontScanlines.qmlFonts.qmlInsertNameDialog.qmlPreprocessedTerminal.qmlSettingsAdvancedTab.qmlSettingsEffectsTab.qmlSettingsGeneralTab.qmlSettingsTerminalTab.qmlSettingsWindow.qmlShaderLibrary.qmlShaderTerminal.qmlSimpleSlider.qmlSizeOverlay.qmlStorage.qmlTerminalContainer.qmlTerminalFrame.qmlTimeManager.qmlfonts
1971-ibm-3278
1977-apple2
1977-commodore-pet
1979-atari-400-800
4
.github/FUNDING.yml
vendored
Normal file
4
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: swordfish90
|
||||
custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=flscogna%40gmail.com&item_name=Support+CRT¤cy_code=EUR&source=url']
|
98
.github/workflows/appimage.yml
vendored
Normal file
98
.github/workflows/appimage.yml
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
name: "ci"
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: "**"
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
appimage:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo add-apt-repository -y ppa:beineri/opt-qt-5.15.2-bionic
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
build-essential make wget libgl1-mesa-dev \
|
||||
qt515declarative qt515graphicaleffects \
|
||||
qt515quickcontrols qt515quickcontrols2
|
||||
|
||||
- name: Download QT appimage builder
|
||||
run: |
|
||||
wget -c -O linuxdeployqt.AppImage \
|
||||
https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
|
||||
chmod a+x linuxdeployqt.AppImage
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
source /opt/qt*/bin/qt*-env.sh && \
|
||||
qmake -v && \
|
||||
qmake CONFIG+=release PREFIX=/usr && \
|
||||
make -j$(nproc)
|
||||
|
||||
- name: Install to appdir
|
||||
run: |
|
||||
source /opt/qt*/bin/qt*-env.sh && \
|
||||
make INSTALL_ROOT=appdir -j$(nproc) install
|
||||
|
||||
- name: Extract version number
|
||||
run: |
|
||||
# Extract version for linuxdeployqt to name the file. Use the tag as
|
||||
# release name but remove prefix.
|
||||
echo "VERSION=$(echo '${{ github.ref }}' | sed 's;.*/;;')" >> $GITHUB_ENV
|
||||
|
||||
- name: Build appimage directory
|
||||
run: |
|
||||
mkdir -p \
|
||||
appdir/usr/bin \
|
||||
appdir/usr/lib \
|
||||
appdir/usr/share/applications \
|
||||
appdir/usr/share/metainfo \
|
||||
appdir/usr/share/icons/hicolor/128x128/apps
|
||||
|
||||
cp cool-retro-term appdir/usr/bin/
|
||||
cp cool-retro-term.desktop appdir/usr/share/applications/
|
||||
cp packaging/appdata/cool-retro-term.appdata.xml appdir/usr/share/metainfo/
|
||||
cp app/icons/128x128/cool-retro-term.png appdir/usr/share/icons/hicolor/128x128/apps/
|
||||
cp -r ./app/qml appdir/usr/
|
||||
# Workaround for https://github.com/probonopd/linuxdeployqt/issues/78
|
||||
cp -r ./qmltermwidget/QMLTermWidget appdir/usr/qml/
|
||||
|
||||
find appdir | sort
|
||||
|
||||
- name: Build appimage
|
||||
run: |
|
||||
source /opt/qt*/bin/qt*-env.sh && \
|
||||
./linuxdeployqt.AppImage appdir/usr/share/applications/cool-retro-term.desktop \
|
||||
-verbose=1 -appimage \
|
||||
-qmldir=./app/qml/ \
|
||||
-qmldir=./qmltermwidget/
|
||||
env:
|
||||
# Unset environment variables
|
||||
QTDIR:
|
||||
QT_PLUGIN_PATH:
|
||||
LD_LIBRARY_PATH:
|
||||
|
||||
- name: Upload release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
body: appimage release
|
||||
files: ./**/Cool_Retro_Term-*-x86_64.AppImage
|
||||
|
||||
- name: Clean up
|
||||
if: always()
|
||||
run: |
|
||||
find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
|
||||
make clean
|
||||
rm -rf appdir
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -18,6 +18,7 @@
|
||||
*.pro.user.*
|
||||
*.moc
|
||||
moc_*.cpp
|
||||
moc_*.h
|
||||
qrc_*.cpp
|
||||
ui_*.h
|
||||
Makefile*
|
||||
@ -35,4 +36,18 @@ Makefile*
|
||||
|
||||
*.xcf
|
||||
|
||||
/imports/
|
||||
# Ubuntu SDk
|
||||
*.excludes
|
||||
*.json
|
||||
|
||||
# Excludes compiled files
|
||||
imports
|
||||
cool-retro-term
|
||||
|
||||
# Mac OSX
|
||||
|
||||
.DS_Store
|
||||
*.app
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
|
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "qmltermwidget"]
|
||||
path = qmltermwidget
|
||||
url = https://github.com/Swordfish90/qmltermwidget
|
||||
branch = unstable
|
37
.travis.yml
Normal file
37
.travis.yml
Normal file
@ -0,0 +1,37 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: c++
|
||||
|
||||
install:
|
||||
- sudo add-apt-repository -y ppa:beineri/opt-qt58-trusty
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get -y install build-essential qt58declarative qt58graphicaleffects qt58quickcontrols libgl1-mesa-dev
|
||||
- source /opt/qt*/bin/qt*-env.sh
|
||||
|
||||
script:
|
||||
- qmake CONFIG+=release PREFIX=/usr
|
||||
- make -j$(nproc)
|
||||
- mkdir -p appdir/usr/share/metainfo appdir/usr/bin
|
||||
- cp packaging/appdata/cool-retro-term.appdata.xml appdir/usr/share/metainfo/
|
||||
- cp cool-retro-term appdir/usr/bin/
|
||||
- cp ./cool-retro-term.desktop appdir/
|
||||
- cp ./app/icons/128x128/cool-retro-term.png appdir/
|
||||
- cp -r ./app/qml appdir/usr/
|
||||
- cp -r ./qmltermwidget/QMLTermWidget appdir/usr/qml/ # Workaround for https://github.com/probonopd/linuxdeployqt/issues/78
|
||||
- wget -c https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
|
||||
- chmod a+x linuxdeployqt-*.AppImage
|
||||
- unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH
|
||||
- export VERSION=$(git rev-parse --short HEAD) # linuxdeployqt uses this for naming the file
|
||||
- ./linuxdeployqt-*.AppImage appdir/usr/bin/cool-retro-term -qmldir=./app/qml/ -qmldir=./qmltermwidget/ # -verbose=3 2>&1 | grep "path:" -C 3
|
||||
- ./linuxdeployqt-*.AppImage appdir/usr/bin/cool-retro-term -qmldir=./app/qml/ -qmldir=./qmltermwidget/ -verbose=2 -appimage
|
||||
|
||||
after_success:
|
||||
- find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
|
||||
- # curl --upload-file Cool*.AppImage https://transfer.sh/Cool_Retro_Term-git.$(git rev-parse --short HEAD)-x86_64.AppImage
|
||||
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
|
||||
- bash upload.sh Cool*.AppImage*
|
||||
|
||||
branches:
|
||||
except:
|
||||
- # Do not build tags that we create when we upload to GitHub Releases
|
||||
- /^(?i:continuous)/
|
107
README.md
107
README.md
@ -1,101 +1,30 @@
|
||||
#cool-old-term
|
||||
# cool-retro-term
|
||||
|
||||
|> Default Amber|C:\ IBM DOS|$ Default Green|
|
||||
|---|---|---|
|
||||
||||
|
||||
|
||||
## Description
|
||||
cool-old-term is a terminal emulator which tries to mimic the look and feel of the old cathode tube screens.
|
||||
cool-retro-term is a terminal emulator which mimics the look and feel of the old cathode tube screens.
|
||||
It has been designed to be eye-candy, customizable, and reasonably lightweight.
|
||||
|
||||
It now uses the konsole engine which is powerful and mature.
|
||||
It uses the QML port of qtermwidget (Konsole): https://github.com/Swordfish90/qmltermwidget.
|
||||
|
||||
This terminal emulator requires Qt 5.2 or higher to run.
|
||||
This terminal emulator works under Linux and macOS and requires Qt5. It's suggested that you stick to the latest LTS version.
|
||||
|
||||
Settings such as colors, fonts, and effects can be accessed via context menu.
|
||||
|
||||
## Screenshots
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
##Build instructions
|
||||
## Install
|
||||
|
||||
##Dependencies
|
||||
Make sure to install these first.
|
||||
If you want to get a hold of the latest version, just go to the Releases page and grab the latest AppImage (Linux) or dmg (macOS).
|
||||
|
||||
---
|
||||
Alternatively, most distributions such as Ubuntu, Fedora or Arch already package cool-retro-term in their official repositories.
|
||||
|
||||
**Ubuntu 14.04**
|
||||
## Building
|
||||
|
||||
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qtdeclarative5-controls-plugin qtdeclarative5-qtquick2-plugin libqt5qml-graphicaleffects qtdeclarative5-dialogs-plugin qtdeclarative5-localstorage-plugin qtdeclarative5-window-plugin
|
||||
|
||||
---
|
||||
|
||||
**Debian Jessie**
|
||||
|
||||
sudo apt-get install build-essential qmlscene qt5-qmake qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtgraphicaleffects qml-module-qtquick-dialogs qml-module-qtquick-localstorage qml-module-qtquick-window2
|
||||
|
||||
---
|
||||
|
||||
**Fedora**
|
||||
This command should install the known fedora dependencies:
|
||||
```
|
||||
sudo yum -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
|
||||
```
|
||||
or:
|
||||
```
|
||||
sudo dnf -y install qt5-qtbase qt5-qtbase-devel qt5-qtdeclarative qt5-qtdeclarative-devel qt5-qtgraphicaleffects qt5-qtquickcontrols
|
||||
```
|
||||
|
||||
Compile using the following:
|
||||
```
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
cd cool-old-term/konsole-qml-plugin
|
||||
qmake-qt5 && make && make install
|
||||
cd ..
|
||||
./cool-old-term
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Arch Linux**
|
||||
|
||||
sudo pacman -S qt5-base qt5-declarative qt5-quickcontrols qt5-graphicaleffects
|
||||
|
||||
You can also install this [package](https://aur.archlinux.org/packages/cool-old-term-git/) directly via the [AUR](https://aur.archlinux.org):
|
||||
|
||||
yaourt -S aur/cool-old-term-git
|
||||
|
||||
---
|
||||
|
||||
**OS X**
|
||||
|
||||
brew install qt5
|
||||
export CPPFLAGS="-I/usr/local/opt/qt5/include"
|
||||
export LDFLAGS="-L/usr/local/opt/qt5/lib"
|
||||
export PATH=/usr/local/opt/qt5/bin:$PATH
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
git checkout osx
|
||||
qmake && make && make install
|
||||
# Have fun!
|
||||
./cool-old-term
|
||||
|
||||
---
|
||||
|
||||
**Anyone else**
|
||||
|
||||
Install Qt directly from here http://qt-project.org/downloads . Once done export them in you path (replace "_/opt/Qt5.3.1/5.3/gcc_64/bin_" with your correct folder):
|
||||
|
||||
export PATH=/opt/Qt5.3.1/5.3/gcc_64/bin/:$PATH
|
||||
|
||||
###Compile
|
||||
Once you installed all dependencies (Qt is installed and in your path) you need to compile and run the application:
|
||||
|
||||
```bash
|
||||
# Get it from GitHub
|
||||
git clone https://github.com/Swordifish90/cool-old-term.git
|
||||
|
||||
# Build it
|
||||
cd cool-old-term
|
||||
cd konsole-qml-plugin
|
||||
qmake && make && make install
|
||||
cd ..
|
||||
|
||||
# Have fun!
|
||||
./cool-old-term
|
||||
```
|
||||
Check out the wiki and follow the instructions on how to build it on [Linux](https://github.com/Swordfish90/cool-retro-term/wiki/Build-Instructions-(Linux)) and [macOS](https://github.com/Swordfish90/cool-retro-term/wiki/Build-Instructions-(macOS)).
|
||||
|
@ -1,103 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.0
|
||||
|
||||
Window{
|
||||
id: dialogwindow
|
||||
title: qsTr("About")
|
||||
width: 450
|
||||
height: 300
|
||||
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 15
|
||||
spacing: 15
|
||||
Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: "cool-old-term"
|
||||
font {bold: true; pointSize: 18}
|
||||
}
|
||||
Loader{
|
||||
id: mainContent
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Default"
|
||||
PropertyChanges {
|
||||
target: mainContent
|
||||
sourceComponent: defaultComponent
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "License"
|
||||
PropertyChanges {
|
||||
target: mainContent
|
||||
sourceComponent: licenseComponent
|
||||
}
|
||||
}
|
||||
]
|
||||
Component.onCompleted: mainContent.state = "Default";
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
height: childrenRect.height
|
||||
Button{
|
||||
anchors.left: parent.left
|
||||
text: qsTr("License")
|
||||
onClicked: {
|
||||
mainContent.state == "Default" ? mainContent.state = "License" : mainContent.state = "Default"
|
||||
}
|
||||
}
|
||||
Button{
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Close")
|
||||
onClicked: dialogwindow.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
// MAIN COMPONENTS ////////////////////////////////////////////////////////
|
||||
Component{
|
||||
id: defaultComponent
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Text{
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: shadersettings.version + "\n" +
|
||||
qsTr("Author: ") + "Filippo Scognamiglio\n" +
|
||||
qsTr("Email: ") + "flscogna@gmail.com\n" +
|
||||
qsTr("Source: ") + "https://github.com/Swordifish90/cool-old-term\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: licenseComponent
|
||||
TextArea{
|
||||
anchors.fill: parent
|
||||
readOnly: true
|
||||
text: "Copyright (c) 2013 Filippo Scognamiglio <flscogna@gmail.com>\n\n" +
|
||||
"https://github.com/Swordifish90/cool-old-term\n\n" +
|
||||
|
||||
"cool-old-term is free software: you can redistribute it and/or modify " +
|
||||
"it under the terms of the GNU General Public License as published by " +
|
||||
"the Free Software Foundation, either version 3 of the License, or " +
|
||||
"(at your option) any later version.\n\n" +
|
||||
|
||||
"This program is distributed in the hope that it will be useful, " +
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of " +
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " +
|
||||
"GNU General Public License for more details.\n\n" +
|
||||
|
||||
"You should have received a copy of the GNU General Public License " +
|
||||
"along with this program. If not, see <http://www.gnu.org/licenses/>."
|
||||
}
|
||||
}
|
||||
}
|
@ -1,359 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
|
||||
|
||||
Item{
|
||||
property string version: "0.9"
|
||||
|
||||
// GENERAL SETTINGS ///////////////////////////////////////////////////
|
||||
|
||||
property bool fullscreen: false
|
||||
property bool showMenubar: true
|
||||
|
||||
property real windowOpacity: 1.0
|
||||
property real ambient_light: 0.2
|
||||
property real contrast: 0.85
|
||||
property real brightness: 0.5
|
||||
|
||||
property bool show_terminal_size: true
|
||||
|
||||
property real window_scaling: 1.0
|
||||
onWindow_scalingChanged: handleFontChanged();
|
||||
|
||||
property real fps: 0
|
||||
|
||||
function mix(c1, c2, alpha){
|
||||
return Qt.rgba(c1.r * alpha + c2.r * (1-alpha),
|
||||
c1.g * alpha + c2.g * (1-alpha),
|
||||
c1.b * alpha + c2.b * (1-alpha),
|
||||
c1.a * alpha + c2.a * (1-alpha))
|
||||
}
|
||||
function strToColor(s){
|
||||
var r = parseInt(s.substring(1,3), 16) / 256;
|
||||
var g = parseInt(s.substring(3,5), 16) / 256;
|
||||
var b = parseInt(s.substring(5,7), 16) / 256;
|
||||
return Qt.rgba(r, g, b, 1.0);
|
||||
}
|
||||
|
||||
// PROFILE SETTINGS ///////////////////////////////////////////////////////
|
||||
|
||||
property string _background_color: "#000000"
|
||||
property string _font_color: "#ff8100"
|
||||
property color font_color: mix(strToColor(_font_color), strToColor(_background_color), 0.7 + (contrast * 0.3))
|
||||
property color background_color: mix(strToColor(_background_color), strToColor(_font_color), 0.7 + (contrast * 0.3))
|
||||
|
||||
property real noise_strength: 0.1
|
||||
property real screen_distortion: 0.1
|
||||
property real glowing_line_strength: 0.2
|
||||
property real motion_blur: 0.40
|
||||
property real bloom_strength: 0.65
|
||||
|
||||
property real jitter: 0.18
|
||||
|
||||
property real horizontal_sincronization: 0.08
|
||||
property real brightness_flickering: 0.1
|
||||
|
||||
readonly property int no_rasterization: 0
|
||||
readonly property int scanline_rasterization: 1
|
||||
readonly property int pixel_rasterization: 2
|
||||
|
||||
property int rasterization: no_rasterization
|
||||
|
||||
ListModel{
|
||||
id: framelist
|
||||
ListElement{text: "No frame"; source: "./frames/NoFrame.qml"; reflections: false}
|
||||
ListElement{text: "Simple white frame"; source: "./frames/WhiteSimpleFrame.qml"; reflections: true}
|
||||
ListElement{text: "Rough black frame"; source: "./frames/BlackRoughFrame.qml"; reflections: true}
|
||||
}
|
||||
|
||||
property string frame_source: frames_list.get(frames_index).source
|
||||
property int frames_index: 1
|
||||
property var frames_list: framelist
|
||||
|
||||
|
||||
// FONTS //////////////////////////////////////////////////////////////////
|
||||
|
||||
signal terminalFontChanged(string fontSource, int pixelSize, int lineSpacing, size virtualCharSize)
|
||||
|
||||
Loader{
|
||||
id: fontManager
|
||||
|
||||
states: [
|
||||
State { when: rasterization == no_rasterization
|
||||
PropertyChanges {target: fontManager; source: "Fonts.qml" } },
|
||||
State { when: rasterization == scanline_rasterization
|
||||
PropertyChanges {target: fontManager; source: "FontScanlines.qml" } },
|
||||
State { when: rasterization == pixel_rasterization;
|
||||
PropertyChanges {target: fontManager; source: "FontPixels.qml" } }
|
||||
]
|
||||
|
||||
onLoaded: handleFontChanged()
|
||||
}
|
||||
|
||||
signal fontScalingChanged
|
||||
property var fontScalingList: fontManager.item.fontScalingList
|
||||
property var fontScalingIndexes: [5,1,1]
|
||||
|
||||
function setScalingIndex(newScaling){
|
||||
fontScalingIndexes[rasterization] = newScaling;
|
||||
fontScalingChanged();
|
||||
handleFontChanged();
|
||||
}
|
||||
|
||||
function getScalingIndex(){
|
||||
return fontScalingIndexes[rasterization];
|
||||
}
|
||||
|
||||
property var fontIndexes: [0,0,0]
|
||||
property var fontlist: fontManager.item.fontlist
|
||||
|
||||
function handleFontChanged(){
|
||||
if(!fontManager.item) return;
|
||||
fontManager.item.selectedFontIndex = fontIndexes[rasterization];
|
||||
fontManager.item.selectedScalingIndex = fontScalingIndexes[rasterization];
|
||||
|
||||
var fontSource = fontManager.item.source;
|
||||
var pixelSize = fontManager.item.pixelSize;
|
||||
var lineSpacing = fontManager.item.lineSpacing;
|
||||
var virtualCharSize = fontManager.item.virtualCharSize;
|
||||
|
||||
terminalFontChanged(fontSource, pixelSize, lineSpacing, virtualCharSize);
|
||||
}
|
||||
|
||||
// FRAMES /////////////////////////////////////////////////////////////////
|
||||
|
||||
property bool _frameReflections: true
|
||||
property bool reflectionsAllowed: framelist.get(frames_index).reflections
|
||||
property bool frameReflections: _frameReflections && reflectionsAllowed
|
||||
|
||||
property alias profiles_list: profileslist
|
||||
property int profiles_index: 0
|
||||
|
||||
// DB STORAGE /////////////////////////////////////////////////////////////
|
||||
|
||||
Storage{id: storage}
|
||||
|
||||
function composeSettingsString(){
|
||||
var settings = {
|
||||
fps: fps,
|
||||
window_scaling: window_scaling,
|
||||
show_terminal_size: show_terminal_size,
|
||||
fontScalingIndexes: fontScalingIndexes,
|
||||
fontIndexes: fontIndexes,
|
||||
frameReflections: _frameReflections,
|
||||
showMenubar: showMenubar
|
||||
}
|
||||
return JSON.stringify(settings);
|
||||
}
|
||||
|
||||
function composeProfileString(){
|
||||
var settings = {
|
||||
background_color: _background_color,
|
||||
font_color: _font_color,
|
||||
brightness_flickering: brightness_flickering,
|
||||
horizontal_sincronization: horizontal_sincronization,
|
||||
noise_strength: noise_strength,
|
||||
screen_distortion: screen_distortion,
|
||||
glowing_line_strength: glowing_line_strength,
|
||||
frames_index: frames_index,
|
||||
motion_blur: motion_blur,
|
||||
bloom_strength: bloom_strength,
|
||||
rasterization: rasterization,
|
||||
jitter: jitter,
|
||||
brightness: brightness,
|
||||
contrast: contrast,
|
||||
ambient_light: ambient_light,
|
||||
windowOpacity: windowOpacity,
|
||||
fontIndex: fontIndexes[rasterization]
|
||||
}
|
||||
return JSON.stringify(settings);
|
||||
}
|
||||
|
||||
function loadSettings(){
|
||||
var settingsString = storage.getSetting("_CURRENT_SETTINGS");
|
||||
var profileString = storage.getSetting("_CURRENT_PROFILE");
|
||||
|
||||
if(!settingsString) return;
|
||||
if(!profileString) return;
|
||||
|
||||
loadSettingsString(settingsString);
|
||||
loadProfileString(profileString);
|
||||
|
||||
console.log("Loading settings: " + settingsString + profileString);
|
||||
}
|
||||
|
||||
function storeSettings(){
|
||||
var settingsString = composeSettingsString();
|
||||
var profileString = composeProfileString();
|
||||
|
||||
storage.setSetting("_CURRENT_SETTINGS", settingsString);
|
||||
storage.setSetting("_CURRENT_PROFILE", profileString);
|
||||
|
||||
console.log("Storing settings: " + settingsString);
|
||||
console.log("Storing profile: " + profileString);
|
||||
}
|
||||
|
||||
function loadSettingsString(settingsString){
|
||||
var settings = JSON.parse(settingsString);
|
||||
|
||||
show_terminal_size = settings.show_terminal_size !== undefined ? settings.show_terminal_size : show_terminal_size
|
||||
|
||||
fps = settings.fps !== undefined ? settings.fps: fps
|
||||
window_scaling = settings.window_scaling !== undefined ? settings.window_scaling : window_scaling
|
||||
|
||||
fontIndexes = settings.fontIndexes !== undefined ? settings.fontIndexes : fontIndexes
|
||||
fontScalingIndexes = settings.fontScalingIndexes !== undefined ? settings.fontScalingIndexes : fontScalingIndexes
|
||||
|
||||
_frameReflections = settings.frameReflections !== undefined ? settings.frameReflections : _frameReflections;
|
||||
|
||||
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar;
|
||||
}
|
||||
|
||||
function loadProfileString(profileString){
|
||||
var settings = JSON.parse(profileString);
|
||||
|
||||
_background_color = settings.background_color !== undefined ? settings.background_color : _background_color;
|
||||
_font_color = settings.font_color !== undefined ? settings.font_color : _font_color;
|
||||
|
||||
horizontal_sincronization = settings.horizontal_sincronization !== undefined ? settings.horizontal_sincronization : horizontal_sincronization
|
||||
brightness_flickering = settings.brightness_flickering !== undefined ? settings.brightness_flickering : brightness_flickering;
|
||||
noise_strength = settings.noise_strength !== undefined ? settings.noise_strength : noise_strength;
|
||||
screen_distortion = settings.screen_distortion !== undefined ? settings.screen_distortion : screen_distortion;
|
||||
glowing_line_strength = settings.glowing_line_strength !== undefined ? settings.glowing_line_strength : glowing_line_strength;
|
||||
|
||||
motion_blur = settings.motion_blur !== undefined ? settings.motion_blur : motion_blur
|
||||
bloom_strength = settings.bloom_strength !== undefined ? settings.bloom_strength : bloom_strength
|
||||
|
||||
frames_index = settings.frames_index !== undefined ? settings.frames_index : frames_index;
|
||||
|
||||
rasterization = settings.rasterization !== undefined ? settings.rasterization : rasterization;
|
||||
|
||||
jitter = settings.jitter !== undefined ? settings.jitter : jitter;
|
||||
|
||||
ambient_light = settings.ambient_light !== undefined ? settings.ambient_light : ambient_light;
|
||||
contrast = settings.contrast !== undefined ? settings.contrast : contrast;
|
||||
brightness = settings.brightness !== undefined ? settings.brightness : brightness;
|
||||
windowOpacity = settings.windowOpacity !== undefined ? settings.windowOpacity : windowOpacity;
|
||||
|
||||
fontIndexes[rasterization] = settings.fontIndex !== undefined ? settings.fontIndex : fontIndexes[rasterization];
|
||||
}
|
||||
|
||||
function storeCustomProfiles(){
|
||||
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString());
|
||||
}
|
||||
|
||||
function loadCustomProfiles(){
|
||||
var customProfileString = storage.getSetting("_CUSTOM_PROFILES");
|
||||
if(customProfileString === undefined) customProfileString = "[]";
|
||||
loadCustomProfilesString(customProfileString);
|
||||
}
|
||||
|
||||
function loadCustomProfilesString(customProfilesString){
|
||||
var customProfiles = JSON.parse(customProfilesString);
|
||||
for (var i=0; i<customProfiles.length; i++) {
|
||||
var profile = customProfiles[i];
|
||||
console.log("Loading custom profile: " + JSON.stringify(profile));
|
||||
profiles_list.append(profile);
|
||||
}
|
||||
}
|
||||
|
||||
function composeCustomProfilesString(){
|
||||
var customProfiles = []
|
||||
for(var i=0; i<profileslist.count; i++){
|
||||
var profile = profileslist.get(i);
|
||||
if(profile.builtin) continue;
|
||||
customProfiles.push({text: profile.text, obj_string: profile.obj_string, builtin: false})
|
||||
}
|
||||
return JSON.stringify(customProfiles);
|
||||
}
|
||||
|
||||
function loadCurrentProfile(){
|
||||
loadProfile(profiles_index);
|
||||
}
|
||||
|
||||
function loadProfile(index){
|
||||
var profile = profileslist.get(index);
|
||||
loadProfileString(profile.obj_string);
|
||||
}
|
||||
|
||||
function addNewCustomProfile(name){
|
||||
var profileString = composeProfileString();
|
||||
profileslist.append({text: name, obj_string: profileString, builtin: false});
|
||||
}
|
||||
|
||||
// PROFILES ///////////////////////////////////////////////////////////////
|
||||
|
||||
ListModel{
|
||||
id: profileslist
|
||||
ListElement{
|
||||
text: "Default Amber"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.65,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.4,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Green"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.08,"jitter":0.18,"motion_blur":0.45,"noise_strength":0.1,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Scanlines"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#00ff5b","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.07,"jitter":0.11,"motion_blur":0.4,"noise_strength":0.05,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Default Pixelated"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.1,"contrast":0.85,"fontIndex":0,"font_color":"#ff8100","frames_index":1,"glowing_line_strength":0.2,"horizontal_sincronization":0.1,"jitter":0,"motion_blur":0.45,"noise_strength":0.14,"rasterization":2,"screen_distortion":0.05,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ]["
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.5,"brightness":0.5,"brightness_flickering":0.2,"contrast":0.85,"fontIndex":2,"font_color":"#2fff91","frames_index":1,"glowing_line_strength":0.22,"horizontal_sincronization":0.08,"jitter":0.1,"motion_blur":0.65,"noise_strength":0.08,"rasterization":1,"screen_distortion":0.18,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Vintage"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.54,"contrast":0.85,"fontIndex":0,"font_color":"#00ff3e","frames_index":2,"glowing_line_strength":0.3,"horizontal_sincronization":0.2,"jitter":0.4,"motion_blur":0.75,"noise_strength":0.2,"rasterization":1,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM Dos"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4,"brightness":0.5,"brightness_flickering":0.07,"contrast":0.85,"fontIndex":7,"font_color":"#ffffff","frames_index":1,"glowing_line_strength":0.13,"horizontal_sincronization":0,"jitter":0.08,"motion_blur":0.3,"noise_strength":0.03,"rasterization":0,"screen_distortion":0.1,"windowOpacity":1}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement{
|
||||
text: "Transparent Green"
|
||||
obj_string: '{"ambient_light":0.2,"background_color":"#000000","bloom_strength":0.4549689440993788,"brightness":0.5,"brightness_flickering":0.20341614906832298,"contrast":0.85,"fontIndex":0,"font_color":"#0ccc68","frames_index":0,"glowing_line_strength":0.15993788819875776,"horizontal_sincronization":0.05045871559633028,"jitter":0.20341614906832298,"motion_blur":0.24999999999999997,"noise_strength":0.20031055900621117,"rasterization":0,"screen_distortion":0.05045871559633028,"windowOpacity":0.5956221198156681}'
|
||||
builtin: true
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
loadSettings();
|
||||
loadCustomProfiles();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
storeSettings();
|
||||
storeCustomProfiles();
|
||||
//storage.dropSettings(); //DROPS THE SETTINGS!.. REMEMBER TO DISABLE ONCE ENABLED!!
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
RowLayout {
|
||||
property bool enabled: true
|
||||
property alias name: check.text
|
||||
property double value: (check.checked) ? _value : 0.0
|
||||
property alias _value: slider.value
|
||||
property alias min_value: slider.minimumValue
|
||||
property alias max_value: slider.maximumValue
|
||||
property alias stepSize: slider.stepSize
|
||||
|
||||
id: setting_component
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 25
|
||||
|
||||
CheckBox{
|
||||
id: check
|
||||
implicitWidth: 150
|
||||
Component.onCompleted: checked = (_value !== 0);
|
||||
enabled: parent.enabled
|
||||
}
|
||||
Slider{
|
||||
id: slider
|
||||
stepSize: parent.stepSize
|
||||
Layout.fillWidth: true
|
||||
enabled: check.checked && parent.enabled
|
||||
}
|
||||
Text{
|
||||
id: textfield
|
||||
property string unformattedText: Math.round(((value - min_value) / (max_value - min_value)) * 100)
|
||||
text: formatNumber(unformattedText)
|
||||
}
|
||||
function formatNumber(num) {
|
||||
var n = "" + num;
|
||||
while (n.length < 3) {
|
||||
n = " " + n;
|
||||
}
|
||||
return n + "%";
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var source: _font.source
|
||||
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.5]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
|
||||
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
|
||||
_font.virtualCharHeight)
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 7
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var source: _font.source
|
||||
property var fontScalingList: [0.75, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.50]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: (_font.pixelSize / _font.virtualCharHeight) * _font.lineSpacing
|
||||
property size virtualCharSize: Qt.size(_font.virtualCharWidth,
|
||||
_font.virtualCharHeight)
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Commodore PET 2Y (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 4
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
virtualCharWidth: 8
|
||||
virtualCharHeight: 8
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Item{
|
||||
property int selectedFontIndex
|
||||
property int selectedScalingIndex
|
||||
property alias fontlist: fontlist
|
||||
property var source: fontlist.get(selectedFontIndex).source
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var _scaling: fontScalingList[selectedScalingIndex]
|
||||
property var fontScalingList: [0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5]
|
||||
property int pixelSize: _font.pixelSize * _scaling
|
||||
property int lineSpacing: pixelSize * _font.lineSpacing
|
||||
|
||||
//In this configuration lineSpacing is proportional to pixelSize.
|
||||
|
||||
ListModel{
|
||||
id: fontlist
|
||||
ListElement{
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-Bold-4.38.2.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 35
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore PET 2Y (1977)"
|
||||
source: "fonts/1977-commodore-pet/COMMODORE_PET_2y.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/ATARI400800_original.TTF"
|
||||
lineSpacing: 0.3
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_User_Mono_v1.0-STYLE.ttf"
|
||||
lineSpacing: 0.3
|
||||
pixelSize: 24
|
||||
}
|
||||
ListElement{
|
||||
text: "Atari ST (1985)"
|
||||
source: "fonts/1985-atari-st/AtariST8x16SystemFont.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
ListElement{
|
||||
text: "IBM DOS (1985)"
|
||||
source: "fonts/1985-ibm-pc-vga/Perfect DOS VGA 437.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - parent.border.width
|
||||
height: parent.height - parent.border.width
|
||||
radius:parent.radius - parent.border.width/2
|
||||
smooth: true
|
||||
|
||||
border.width: parent.border.width/2
|
||||
border.color: "#22FFFFFF"
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0; color: "#88FFFFFF" }
|
||||
GradientStop { position: .1; color: "#55FFFFFF" }
|
||||
GradientStop { position: .5; color: "#33FFFFFF" }
|
||||
GradientStop { position: .501; color: "#11000000" }
|
||||
GradientStop { position: .8; color: "#11FFFFFF" }
|
||||
GradientStop { position: 1; color: "#55FFFFFF" }
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Window{
|
||||
id: insertnamedialog
|
||||
width: 400
|
||||
height: 100
|
||||
modality: Qt.ApplicationModal
|
||||
title: qsTr("Save current profile")
|
||||
|
||||
signal nameSelected(string name)
|
||||
|
||||
ColumnLayout{
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
RowLayout{
|
||||
Label{text: qsTr("Name")}
|
||||
TextField{
|
||||
id: namefield
|
||||
Layout.fillWidth: true
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
Button{
|
||||
text: qsTr("OK")
|
||||
onClicked: {
|
||||
nameSelected(namefield.text);
|
||||
close();
|
||||
}
|
||||
}
|
||||
Button{
|
||||
text: qsTr("Cancel")
|
||||
onClicked: close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,426 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
import org.kde.konsole 0.1
|
||||
|
||||
Item{
|
||||
id: terminalContainer
|
||||
property variant theSource: finalSource
|
||||
property variant bloomSource: bloomSourceLoader.item
|
||||
property variant rasterizationSource: rasterizationEffectSource
|
||||
property variant staticNoiseSource: staticNoiseSource
|
||||
|
||||
property alias kterminal: kterminal
|
||||
|
||||
signal sizeChanged
|
||||
onWidthChanged: sizeChanged()
|
||||
onHeightChanged: sizeChanged()
|
||||
|
||||
//The blur effect has to take into account the framerate
|
||||
property int fps: shadersettings.fps !== 0 ? shadersettings.fps : 60
|
||||
property real fpsAttenuation: Math.sqrt(60 / fps)
|
||||
property real mBlur: shadersettings.motion_blur
|
||||
property real motionBlurCoefficient: (_maxBlurCoefficient * mBlur + _minBlurCoefficient * (1 - mBlur))
|
||||
property real _minBlurCoefficient: 0.70
|
||||
property real _maxBlurCoefficient: 0.90
|
||||
|
||||
property size virtualPxSize: Qt.size(1,1)
|
||||
property size virtual_resolution: Qt.size(width / virtualPxSize.width, height / virtualPxSize.height)
|
||||
property real deltay: 0.5 / virtual_resolution.height
|
||||
property real deltax: 0.5 / virtual_resolution.width
|
||||
|
||||
property real mBloom: shadersettings.bloom_strength
|
||||
property int mScanlines: shadersettings.rasterization
|
||||
onMScanlinesChanged: restartBlurredSource()
|
||||
|
||||
property size terminalSize: kterminal.terminalSize
|
||||
property size paintedTextSize
|
||||
|
||||
onMBlurChanged: restartBlurredSource()
|
||||
|
||||
function restartBlurredSource(){
|
||||
if(!blurredSource) return;
|
||||
blurredSource.live = true;
|
||||
livetimer.restart()
|
||||
}
|
||||
function pasteClipboard(){
|
||||
kterminal.pasteClipboard();
|
||||
}
|
||||
function copyClipboard(){
|
||||
kterminal.copyClipboard();
|
||||
}
|
||||
|
||||
KTerminal {
|
||||
id: kterminal
|
||||
anchors.fill: parent
|
||||
|
||||
colorScheme: "cool-old-term"
|
||||
|
||||
session: KSession {
|
||||
id: ksession
|
||||
kbScheme: "linux"
|
||||
|
||||
onFinished: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
|
||||
FontLoader{ id: fontLoader }
|
||||
Text{id: fontMetrics; text: "B"; visible: false}
|
||||
|
||||
function getPaintedSize(pixelSize){
|
||||
fontMetrics.font.family = fontLoader.name;
|
||||
fontMetrics.font.pixelSize = pixelSize;
|
||||
return Qt.size(fontMetrics.paintedWidth, fontMetrics.paintedHeight);
|
||||
}
|
||||
function isValid(size){
|
||||
return size.width >= 0 && size.height >= 0;
|
||||
}
|
||||
function handleFontChange(fontSource, pixelSize, lineSpacing, virtualCharSize){
|
||||
fontLoader.source = fontSource;
|
||||
font.pixelSize = pixelSize * shadersettings.window_scaling;
|
||||
font.family = fontLoader.name;
|
||||
|
||||
var paintedSize = getPaintedSize(pixelSize);
|
||||
var charSize = isValid(virtualCharSize)
|
||||
? virtualCharSize
|
||||
: Qt.size(paintedSize.width / 2, paintedSize.height / 2);
|
||||
|
||||
var virtualPxSize = Qt.size((paintedSize.width / charSize.width) * shadersettings.window_scaling,
|
||||
(paintedSize.height / charSize.height) * shadersettings.window_scaling)
|
||||
|
||||
terminalContainer.virtualPxSize = virtualPxSize;
|
||||
|
||||
setLineSpacing(lineSpacing * shadersettings.window_scaling);
|
||||
restartBlurredSource();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
shadersettings.terminalFontChanged.connect(handleFontChange);
|
||||
forceActiveFocus();
|
||||
}
|
||||
}
|
||||
Menu{
|
||||
id: contextmenu
|
||||
|
||||
MenuItem{action: copyAction}
|
||||
MenuItem{action: pasteAction}
|
||||
MenuSeparator{}
|
||||
MenuItem{action: fullscreenAction}
|
||||
MenuItem{action: showMenubarAction}
|
||||
}
|
||||
MouseArea{
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
onWheel:{
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
var lines = wheel.angleDelta.y > 0 ? -2 : 2;
|
||||
kterminal.scrollWheel(coord.width, coord.height, lines);
|
||||
}
|
||||
onClicked: {
|
||||
if (mouse.button == Qt.RightButton){
|
||||
contextmenu.popup();
|
||||
} else if (mouse.button == Qt.MiddleButton){
|
||||
kterminal.pasteSelection();
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseDoubleClick(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressedButtons & Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseMove(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mousePress(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
if (mouse.button == Qt.LeftButton){
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.mouseRelease(coord.width, coord.height);
|
||||
}
|
||||
}
|
||||
|
||||
//Frame displacement properties
|
||||
property real dtop: frame.item.displacementTop
|
||||
property real dleft:frame.item.displacementLeft
|
||||
property real dright: frame.item.displacementRight
|
||||
property real dbottom: frame.item.displacementBottom
|
||||
|
||||
function correctDistortion(x, y){
|
||||
x = x / width;
|
||||
y = y / height;
|
||||
|
||||
x = (-dleft + x * (width + dleft + dright)) / width
|
||||
y = (-dtop + y * (height + dtop + dbottom)) / height
|
||||
|
||||
var cc = Qt.size(0.5 - x, 0.5 - y);
|
||||
var distortion = (cc.height * cc.height + cc.width * cc.width) * shadersettings.screen_distortion;
|
||||
|
||||
return Qt.size((x - cc.width * (1+distortion) * distortion) * width,
|
||||
(y - cc.height * (1+distortion) * distortion) * height)
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: source
|
||||
sourceItem: kterminal
|
||||
hideSource: true
|
||||
smooth: false
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: blurredSource
|
||||
sourceItem: blurredterminal
|
||||
recursive: true
|
||||
live: false
|
||||
|
||||
hideSource: true
|
||||
|
||||
smooth: false
|
||||
antialiasing: false
|
||||
|
||||
Timer{
|
||||
id: livetimer
|
||||
running: true
|
||||
onRunningChanged: running ?
|
||||
timeManager.onTimeChanged.connect(blurredSource.scheduleUpdate) :
|
||||
timeManager.onTimeChanged.disconnect(blurredSource.scheduleUpdate)
|
||||
|
||||
Component.onCompleted: kterminal.updatedImage.connect(restart);
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: finalSource
|
||||
sourceItem: blurredterminal
|
||||
sourceRect: frame.sourceRect
|
||||
//format: ShaderEffectSource.Alpha
|
||||
hideSource: true
|
||||
}
|
||||
ShaderEffect {
|
||||
id: blurredterminal
|
||||
anchors.fill: parent
|
||||
property variant source: source
|
||||
property variant blurredSource: (mBlur !== 0) ? blurredSource : undefined
|
||||
property size virtual_resolution: parent.virtual_resolution
|
||||
property size delta: Qt.size((mScanlines == shadersettings.pixel_rasterization ? deltax : 0),
|
||||
mScanlines != shadersettings.no_rasterization ? deltay : 0)
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
"uniform lowp sampler2D source;" +
|
||||
"uniform highp vec2 delta;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec2 virtual_resolution;" +
|
||||
|
||||
(mBlur !== 0 ?
|
||||
"uniform lowp sampler2D blurredSource;"
|
||||
: "") +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 coords = qt_TexCoord0;" +
|
||||
(mScanlines != shadersettings.no_rasterization ? "
|
||||
coords.y = floor(virtual_resolution.y * coords.y) / virtual_resolution.y;" +
|
||||
(mScanlines == shadersettings.pixel_rasterization ? "
|
||||
coords.x = floor(virtual_resolution.x * coords.x) / virtual_resolution.x;" : "")
|
||||
: "") +
|
||||
"coords = coords + delta;" +
|
||||
"vec4 vcolor = texture2D(source, coords) * 256.0;
|
||||
float color = vcolor.r * 0.21 + vcolor.g * 0.72 + vcolor.b + 0.04;" +
|
||||
(mBlur !== 0 ?
|
||||
"float blurredSourceColor = texture2D(blurredSource, coords).a * 256.0;" +
|
||||
"blurredSourceColor = blurredSourceColor - blurredSourceColor * " + (1.0 - motionBlurCoefficient) * fpsAttenuation+ ";" +
|
||||
"color = step(1.0, color) * color + step(color, 1.0) * blurredSourceColor;"
|
||||
: "") +
|
||||
|
||||
|
||||
"gl_FragColor.a = floor(color) / 256.0;" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EFFECTS //////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// BLOOM ////////////////////////////////////////////////////////////////
|
||||
|
||||
Loader{
|
||||
id: bloomEffectLoader
|
||||
active: mBloom != 0
|
||||
anchors.fill: parent
|
||||
sourceComponent: FastBlur{
|
||||
radius: 48
|
||||
source: kterminal
|
||||
transparentBorder: true
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
Loader{
|
||||
id: bloomSourceLoader
|
||||
active: mBloom != 0
|
||||
sourceComponent: ShaderEffectSource{
|
||||
sourceItem: bloomEffectLoader.item
|
||||
hideSource: true
|
||||
sourceRect: frame.sourceRect
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
// NOISE ////////////////////////////////////////////////////////////////
|
||||
|
||||
ShaderEffect {
|
||||
id: staticNoiseEffect
|
||||
anchors.fill: parent
|
||||
property size virtual_resolution: terminalContainer.virtual_resolution
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
uniform highp vec2 virtual_resolution;" +
|
||||
|
||||
"highp float noise(vec2 co)
|
||||
{
|
||||
highp float a = 12.9898;
|
||||
highp float b = 78.233;
|
||||
highp float c = 43758.5453;
|
||||
highp float dt= dot(co.xy ,vec2(a,b));
|
||||
highp float sn= mod(dt,3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
|
||||
vec2 sw(vec2 p) {return vec2( floor(p.x) , floor(p.y) );}
|
||||
vec2 se(vec2 p) {return vec2( ceil(p.x) , floor(p.y) );}
|
||||
vec2 nw(vec2 p) {return vec2( floor(p.x) , ceil(p.y) );}
|
||||
vec2 ne(vec2 p) {return vec2( ceil(p.x) , ceil(p.y) );}
|
||||
|
||||
float smoothNoise(vec2 p) {
|
||||
vec2 inter = smoothstep(0., 1., fract(p));
|
||||
float s = mix(noise(sw(p)), noise(se(p)), inter.x);
|
||||
float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
|
||||
return mix(s, n, inter.y);
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"gl_FragColor.a = smoothNoise(qt_TexCoord0 * virtual_resolution);" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: staticNoiseSource
|
||||
sourceItem: staticNoiseEffect
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
smooth: true
|
||||
hideSource: true
|
||||
//format: ShaderEffectSource.Alpha
|
||||
}
|
||||
|
||||
// RASTERIZATION //////////////////////////////////////////////////////////
|
||||
|
||||
ShaderEffect{
|
||||
id: rasterizationContainer
|
||||
width: frame.sourceRect.width
|
||||
height: frame.sourceRect.height
|
||||
property size offset: Qt.size(width - rasterizationEffect.width, height - rasterizationEffect.height)
|
||||
property size txtRes: Qt.size(width, height)
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;
|
||||
uniform highp vec2 offset;
|
||||
uniform highp vec2 txtRes;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
"void main() {" +
|
||||
"float color = 1.0;
|
||||
color *= smoothstep(0.0, offset.x / txtRes.x, qt_TexCoord0.x);
|
||||
color *= smoothstep(0.0, offset.y / txtRes.y, qt_TexCoord0.y);
|
||||
color *= smoothstep(0.0, offset.x / txtRes.x, 1.0 - qt_TexCoord0.x);
|
||||
color *= smoothstep(0.0, offset.y / txtRes.y, 1.0 - qt_TexCoord0.y);" +
|
||||
|
||||
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
|
||||
"color = mix(color, 0.0, 1.2 * distance * distance);" +
|
||||
|
||||
"gl_FragColor.a = color;" +
|
||||
"}"
|
||||
|
||||
ShaderEffect {
|
||||
id: rasterizationEffect
|
||||
width: terminalContainer.width
|
||||
height: terminalContainer.height
|
||||
anchors.centerIn: parent
|
||||
property size virtual_resolution: terminalContainer.virtual_resolution
|
||||
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
uniform highp vec2 virtual_resolution;
|
||||
|
||||
float getScanlineIntensity(vec2 coords) {
|
||||
float result = 1.0;" +
|
||||
(mScanlines != shadersettings.no_rasterization ?
|
||||
"result *= abs(sin(coords.y * virtual_resolution.y * "+Math.PI+"));" : "") +
|
||||
(mScanlines == shadersettings.pixel_rasterization ?
|
||||
"result *= abs(sin(coords.x * virtual_resolution.x * "+Math.PI+"));" : "") + "
|
||||
return result;
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"float color = getScanlineIntensity(qt_TexCoord0);" +
|
||||
|
||||
"float distance = length(vec2(0.5) - qt_TexCoord0);" +
|
||||
"color = mix(color, 0.0, 1.2 * distance * distance);" +
|
||||
|
||||
"gl_FragColor.a = color;" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: rasterizationEffectSource
|
||||
sourceItem: rasterizationContainer
|
||||
hideSource: true
|
||||
smooth: true
|
||||
//format: ShaderEffectSource.Alpha
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
GroupBox{
|
||||
title: qsTr("Effects")
|
||||
anchors.fill: parent
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
CheckableSlider{
|
||||
name: qsTr("Bloom")
|
||||
onValueChanged: shadersettings.bloom_strength = value
|
||||
_value: shadersettings.bloom_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Motion Blur")
|
||||
onValueChanged: shadersettings.motion_blur = value
|
||||
_value: shadersettings.motion_blur
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Noise")
|
||||
onValueChanged: shadersettings.noise_strength = value
|
||||
_value: shadersettings.noise_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Jitter")
|
||||
onValueChanged: shadersettings.jitter = value
|
||||
_value: shadersettings.jitter
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Glow")
|
||||
onValueChanged: shadersettings.glowing_line_strength = value;
|
||||
_value: shadersettings.glowing_line_strength
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Screen distortion")
|
||||
onValueChanged: shadersettings.screen_distortion = value;
|
||||
_value: shadersettings.screen_distortion;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Ambient light")
|
||||
onValueChanged: shadersettings.ambient_light = value;
|
||||
_value: shadersettings.ambient_light
|
||||
enabled: shadersettings.frames_index !== 0
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Brightness flickering")
|
||||
onValueChanged: shadersettings.brightness_flickering= value;
|
||||
_value: shadersettings.brightness_flickering;
|
||||
}
|
||||
CheckableSlider{
|
||||
name: qsTr("Horizontal flickering")
|
||||
onValueChanged: shadersettings.horizontal_sincronization = value;
|
||||
_value: shadersettings.horizontal_sincronization;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Profile")
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
ComboBox{
|
||||
id: profilesbox
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.profiles_list
|
||||
currentIndex: shadersettings.profiles_index
|
||||
}
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Load")
|
||||
onClicked: {
|
||||
shadersettings.profiles_index = profilesbox.currentIndex
|
||||
shadersettings.loadCurrentProfile();
|
||||
shadersettings.handleFontChanged();
|
||||
}
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Store current")
|
||||
onClicked: insertname.show()
|
||||
}
|
||||
Button{
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Remove Selected")
|
||||
enabled: !shadersettings.profiles_list.get(profilesbox.currentIndex).builtin
|
||||
onClicked: {
|
||||
shadersettings.profiles_list.remove(profilesbox.currentIndex)
|
||||
profilesbox.currentIndex = profilesbox.currentIndex - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
InsertNameDialog{
|
||||
id: insertname
|
||||
onNameSelected: shadersettings.addNewCustomProfile(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Lights")
|
||||
Layout.fillWidth: true
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Text{ text: qsTr("Brightness") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.brightness = value
|
||||
value: shadersettings.brightness
|
||||
}
|
||||
Text{ text: qsTr("Contrast") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.contrast = value
|
||||
value: shadersettings.contrast
|
||||
}
|
||||
Text{ text: qsTr("Opacity") }
|
||||
SimpleSlider{
|
||||
onValueChanged: shadersettings.windowOpacity = value
|
||||
value: shadersettings.windowOpacity
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Performace")
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
rows: 3
|
||||
columns: 3
|
||||
CheckBox{
|
||||
Layout.columnSpan: 3
|
||||
checked: !shadersettings._frameReflections
|
||||
text: qsTr("Disable reflections")
|
||||
onCheckedChanged: shadersettings._frameReflections = !checked
|
||||
enabled: shadersettings.reflectionsAllowed
|
||||
}
|
||||
CheckBox{
|
||||
property int fps: checked ? slider.value : 0
|
||||
onFpsChanged: shadersettings.fps = fps
|
||||
checked: shadersettings.fps !== 0
|
||||
text: qsTr("Limit FPS")
|
||||
}
|
||||
Slider{
|
||||
id: slider
|
||||
Layout.fillWidth: true
|
||||
stepSize: 1
|
||||
maximumValue: 60
|
||||
minimumValue: 1
|
||||
enabled: shadersettings.fps !== 0
|
||||
value: shadersettings.fps !== 0 ? shadersettings.fps : 60
|
||||
}
|
||||
Text{text: slider.value}
|
||||
Text{text: qsTr("Texture quality")}
|
||||
Slider{
|
||||
Layout.fillWidth: true
|
||||
id: txtslider
|
||||
onValueChanged: shadersettings.window_scaling = value;
|
||||
value: shadersettings.window_scaling
|
||||
tickmarksEnabled: true
|
||||
stepSize: 0.25
|
||||
Component.onCompleted: minimumValue = 0.5 //Without this value gets set to 0.5
|
||||
}
|
||||
Text{text: Math.round(txtslider.value * 100) + "%"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Tab{
|
||||
ColumnLayout{
|
||||
anchors.fill: parent
|
||||
GroupBox{
|
||||
title: qsTr("Rasterization Mode")
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
id: rasterizationBox
|
||||
property string selectedElement: model[currentIndex]
|
||||
anchors.fill: parent
|
||||
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")]
|
||||
currentIndex: shadersettings.rasterization
|
||||
onCurrentIndexChanged: {
|
||||
scalingChanger.enabled = false;
|
||||
shadersettings.rasterization = currentIndex
|
||||
fontChanger.updateIndex();
|
||||
scalingChanger.updateIndex();
|
||||
scalingChanger.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Font") + " (" + rasterizationBox.selectedElement + ")"
|
||||
Layout.fillWidth: true
|
||||
GridLayout{
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Text{ text: qsTr("Name") }
|
||||
ComboBox{
|
||||
id: fontChanger
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.fontlist
|
||||
currentIndex: updateIndex()
|
||||
onActivated: {
|
||||
shadersettings.fontIndexes[shadersettings.rasterization] = index;
|
||||
shadersettings.handleFontChanged();
|
||||
}
|
||||
function updateIndex(){
|
||||
currentIndex = shadersettings.fontIndexes[shadersettings.rasterization];
|
||||
}
|
||||
}
|
||||
Text{ text: qsTr("Scaling") }
|
||||
RowLayout{
|
||||
Layout.fillWidth: true
|
||||
Slider{
|
||||
id: scalingChanger
|
||||
Layout.fillWidth: true
|
||||
minimumValue: 0
|
||||
maximumValue: shadersettings.fontScalingList.length - 1
|
||||
stepSize: 1
|
||||
tickmarksEnabled: true
|
||||
value: updateIndex()
|
||||
onValueChanged: {
|
||||
if(!enabled) return; //Ugly and hacky solution. Look for a better solution.
|
||||
shadersettings.setScalingIndex(value);
|
||||
}
|
||||
function updateIndex(){
|
||||
value = shadersettings.getScalingIndex();
|
||||
}
|
||||
Component.onCompleted: shadersettings.fontScalingChanged.connect(updateIndex);
|
||||
}
|
||||
Text{
|
||||
text: shadersettings.fontScalingList[scalingChanger.value].toFixed(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Colors")
|
||||
Layout.fillWidth: true
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
ColorButton{
|
||||
name: qsTr("Font")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: shadersettings._font_color = color;
|
||||
button_color: shadersettings._font_color
|
||||
}
|
||||
ColorButton{
|
||||
name: qsTr("Background")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: shadersettings._background_color = color;
|
||||
button_color: shadersettings._background_color
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox{
|
||||
title: qsTr("Frame")
|
||||
Layout.fillWidth: true
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
ComboBox{
|
||||
id: framescombobox
|
||||
Layout.fillWidth: true
|
||||
model: shadersettings.frames_list
|
||||
currentIndex: shadersettings.frames_index
|
||||
onCurrentIndexChanged: shadersettings.frames_index = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Window {
|
||||
id: settings_window
|
||||
title: qsTr("Settings")
|
||||
width: 640
|
||||
height: 450
|
||||
|
||||
property int tabmargins: 15
|
||||
|
||||
TabView{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
SettingsGeneralTab{
|
||||
title: qsTr("General")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsTerminalTab{
|
||||
title: qsTr("Terminal")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
SettingsEffectsTab{
|
||||
title: qsTr("Effects")
|
||||
anchors.fill: parent
|
||||
anchors.margins: tabmargins
|
||||
}
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
ShaderEffect {
|
||||
property color font_color: shadersettings.font_color
|
||||
property color background_color: shadersettings.background_color
|
||||
property variant source: terminal.theSource
|
||||
property variant bloomSource: terminal.bloomSource
|
||||
property variant rasterizationSource: terminal.rasterizationSource
|
||||
property variant noiseSource: terminal.staticNoiseSource
|
||||
property size txt_Size: Qt.size(frame.sourceRect.width, frame.sourceRect.height)
|
||||
property real bloom: shadersettings.bloom_strength * 2.5
|
||||
|
||||
property int rasterization: shadersettings.rasterization
|
||||
|
||||
property real jitter: shadersettings.jitter * 0.007
|
||||
|
||||
property real noise_strength: shadersettings.noise_strength
|
||||
property real screen_distorsion: shadersettings.screen_distortion
|
||||
property real glowing_line_strength: shadersettings.glowing_line_strength
|
||||
|
||||
property real brightness_flickering: shadersettings.brightness_flickering
|
||||
property real horizontal_sincronization: shadersettings.horizontal_sincronization
|
||||
|
||||
property bool frameReflections: shadersettings.frameReflections
|
||||
|
||||
property real disp_top: frame.item.displacementTop * shadersettings.window_scaling
|
||||
property real disp_bottom: frame.item.displacementBottom * shadersettings.window_scaling
|
||||
property real disp_left: frame.item.displacementLeft * shadersettings.window_scaling
|
||||
property real disp_right: frame.item.displacementRight * shadersettings.window_scaling
|
||||
|
||||
property real brightness: shadersettings.brightness * 1.5 + 0.5
|
||||
|
||||
property real time: timeManager.time
|
||||
property variant randomFunctionSource: randfuncsource
|
||||
|
||||
blending: false
|
||||
|
||||
//Smooth random texture used for flickering effect.
|
||||
Image{
|
||||
id: randtexture
|
||||
source: "frames/images/randfunction.png"
|
||||
width: 512
|
||||
height: 512
|
||||
sourceSize.width: 512
|
||||
sourceSize.height: 256
|
||||
fillMode: Image.TileVertically
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: randfuncsource
|
||||
sourceItem: randtexture
|
||||
live: false
|
||||
hideSource: true
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
}
|
||||
|
||||
//Print the number with a reasonable precision for the shader.
|
||||
function str(num){
|
||||
return num.toFixed(8);
|
||||
}
|
||||
|
||||
vertexShader: "
|
||||
uniform highp mat4 qt_Matrix;
|
||||
uniform highp float time;
|
||||
uniform sampler2D randomFunctionSource;
|
||||
uniform highp vec2 txt_Size;
|
||||
|
||||
attribute highp vec4 qt_Vertex;
|
||||
attribute highp vec2 qt_MultiTexCoord0;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
(brightness_flickering !== 0.0 ?"
|
||||
varying lowp float brightness;" : "") +
|
||||
(horizontal_sincronization !== 0.0 ?"
|
||||
varying lowp float horizontal_distortion;" : "") +
|
||||
"
|
||||
void main() {
|
||||
qt_TexCoord0.x = -"+str(disp_left)+"/txt_Size.x + qt_MultiTexCoord0.x / ((txt_Size.x -("+str(disp_left+disp_right)+")) / txt_Size.x);" + "
|
||||
qt_TexCoord0.y = -"+str(disp_top)+"/txt_Size.y + qt_MultiTexCoord0.y / ((txt_Size.y -("+str(disp_top+disp_bottom)+")) / txt_Size.y);" + "
|
||||
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
|
||||
(brightness_flickering !== 0.0 ? "
|
||||
brightness = 1.0 + (texture2D(randomFunctionSource, coords).g - 0.5) * "+str(brightness_flickering)+";"
|
||||
: "") +
|
||||
|
||||
(horizontal_sincronization !== 0.0 ? "
|
||||
float randval = 1.5 * texture2D(randomFunctionSource,(vec2(1.0) -coords) * 0.5).g;
|
||||
float negsinc = 1.0 - "+str(0.6*horizontal_sincronization)+";
|
||||
horizontal_distortion = step(negsinc, randval) * (randval - negsinc) * "+str(0.3*horizontal_sincronization)+";"
|
||||
: "") +
|
||||
|
||||
"gl_Position = qt_Matrix * qt_Vertex;
|
||||
}"
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform highp float qt_Opacity;
|
||||
uniform highp float time;
|
||||
uniform highp vec2 txt_Size;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec4 font_color;
|
||||
uniform highp vec4 background_color;
|
||||
uniform highp sampler2D rasterizationSource;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
uniform highp sampler2D bloomSource;" : "") +
|
||||
(noise_strength !== 0 ? "
|
||||
uniform highp float noise_strength;" : "") +
|
||||
(noise_strength !== 0 || jitter !== 0 ? "
|
||||
uniform lowp sampler2D noiseSource;" : "") +
|
||||
(screen_distorsion !== 0 ? "
|
||||
uniform highp float screen_distorsion;" : "")+
|
||||
(glowing_line_strength !== 0 ? "
|
||||
uniform highp float glowing_line_strength;" : "")+
|
||||
(brightness_flickering !== 0 ? "
|
||||
varying lowp float brightness;" : "") +
|
||||
(horizontal_sincronization !== 0 ? "
|
||||
varying lowp float horizontal_distortion;" : "") +
|
||||
|
||||
(glowing_line_strength !== 0 ? "
|
||||
float randomPass(vec2 coords){
|
||||
return fract(smoothstep(-0.2, 0.0, coords.y - 3.0 * fract(time * 0.0001))) * glowing_line_strength;
|
||||
}" : "") +
|
||||
|
||||
|
||||
"void main() {" +
|
||||
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
|
||||
"float distance = length(cc);" +
|
||||
|
||||
(noise_strength ? "
|
||||
float noise = noise_strength;" : "") +
|
||||
|
||||
(screen_distorsion !== 0 ? "
|
||||
float distortion = dot(cc, cc) * screen_distorsion;
|
||||
vec2 coords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);"
|
||||
:"
|
||||
vec2 coords = qt_TexCoord0;") +
|
||||
|
||||
(frameReflections ? "
|
||||
vec2 inside = step(0.0, coords) - step(1.0, coords);
|
||||
coords = abs(mod(floor(coords), 2.0) - fract(coords)) * clamp(inside.x + inside.y, 0.0, 1.0);" : "") +
|
||||
|
||||
(horizontal_sincronization !== 0 ? "
|
||||
float h_distortion = 0.5 * sin(time*0.001 + coords.y*10.0*fract(time/10.0));
|
||||
h_distortion += 0.5 * cos(time*0.04 + 0.03 + coords.y*50.0*fract(time/10.0 + 0.4));
|
||||
coords.x = coords.x + h_distortion * horizontal_distortion;" +
|
||||
(noise_strength ? "
|
||||
noise += horizontal_distortion;" : "")
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 ? "
|
||||
vec2 offset = vec2(texture2D(noiseSource, coords + fract(time / 57.0)).a,
|
||||
texture2D(noiseSource, coords + fract(time / 251.0)).a) - 0.5;
|
||||
vec2 txt_coords = coords + offset * "+str(jitter)+";"
|
||||
: "vec2 txt_coords = coords;") +
|
||||
|
||||
"float color = texture2D(source, txt_coords).a;" +
|
||||
|
||||
(noise_strength !== 0 ? "
|
||||
float noiseVal = texture2D(noiseSource, qt_TexCoord0 + vec2(fract(time / 51.0), fract(time / 237.0))).a;
|
||||
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
|
||||
|
||||
(glowing_line_strength !== 0 ? "
|
||||
color += randomPass(coords) * glowing_line_strength;" : "") +
|
||||
|
||||
"vec3 finalColor = mix(background_color, font_color, color).rgb;" +
|
||||
"finalColor *= texture2D(rasterizationSource, coords).a;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
finalColor += font_color.rgb * texture2D(bloomSource, coords).r *" + str(bloom) + ";" : "") +
|
||||
|
||||
(brightness_flickering !== 0 ? "
|
||||
finalColor *= brightness;" : "") +
|
||||
|
||||
"gl_FragColor = vec4(finalColor *"+str(brightness)+", qt_Opacity);
|
||||
}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
38
app/app.pro
Normal file
38
app/app.pro
Normal file
@ -0,0 +1,38 @@
|
||||
QT += qml quick widgets sql quickcontrols2
|
||||
TARGET = cool-retro-term
|
||||
|
||||
DESTDIR = $$OUT_PWD/../
|
||||
|
||||
HEADERS += \
|
||||
fileio.h \
|
||||
monospacefontmanager.h
|
||||
|
||||
SOURCES = main.cpp \
|
||||
fileio.cpp \
|
||||
monospacefontmanager.cpp
|
||||
|
||||
macx:ICON = icons/crt.icns
|
||||
|
||||
RESOURCES += qml/resources.qrc
|
||||
|
||||
#########################################
|
||||
## INSTALLS
|
||||
#########################################
|
||||
|
||||
target.path += /usr/bin/
|
||||
|
||||
INSTALLS += target
|
||||
|
||||
# Install icons
|
||||
unix {
|
||||
icon32.files = icons/32x32/cool-retro-term.png
|
||||
icon32.path = /usr/share/icons/hicolor/32x32/apps
|
||||
icon64.files = icons/64x64/cool-retro-term.png
|
||||
icon64.path = /usr/share/icons/hicolor/64x64/apps
|
||||
icon128.files = icons/128x128/cool-retro-term.png
|
||||
icon128.path = /usr/share/icons/hicolor/128x128/apps
|
||||
icon256.files = icons/256x256/cool-retro-term.png
|
||||
icon256.path = /usr/share/icons/hicolor/256x256/apps
|
||||
|
||||
INSTALLS += icon32 icon64 icon128 icon256
|
||||
}
|
37
app/fileio.cpp
Normal file
37
app/fileio.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "fileio.h"
|
||||
|
||||
FileIO::FileIO()
|
||||
{
|
||||
}
|
||||
|
||||
bool FileIO::write(const QString& sourceUrl, const QString& data) {
|
||||
if (sourceUrl.isEmpty())
|
||||
return false;
|
||||
|
||||
QUrl url(sourceUrl);
|
||||
QFile file(url.toLocalFile());
|
||||
if (!file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
return false;
|
||||
|
||||
QTextStream out(&file);
|
||||
out << data;
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
QString FileIO::read(const QString& sourceUrl) {
|
||||
if (sourceUrl.isEmpty())
|
||||
return "";
|
||||
|
||||
QUrl url(sourceUrl);
|
||||
QFile file(url.toLocalFile());
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
return "";
|
||||
|
||||
QTextStream in(&file);
|
||||
QString result = in.readAll();
|
||||
|
||||
file.close();
|
||||
|
||||
return result;
|
||||
}
|
21
app/fileio.h
Normal file
21
app/fileio.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FILEIO_H
|
||||
#define FILEIO_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QUrl>
|
||||
|
||||
class FileIO : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileIO();
|
||||
|
||||
public slots:
|
||||
bool write(const QString& sourceUrl, const QString& data);
|
||||
QString read(const QString& sourceUrl);
|
||||
};
|
||||
|
||||
#endif // FILEIO_H
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,317 +0,0 @@
|
||||
{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern\fprq1 Atari Classic Chunky;}{\f3\froman Times New Roman;}{\f4\fswiss\fprq2 Arial;}}
|
||||
{\colortbl\red0\green0\blue0;\red0\green0\blue255;}
|
||||
\deflang1033\pard\plain\f2\fs24\cf1 Atari Classic TrueType Fonts \plain\f2\fs24\cf0
|
||||
\par \plain\f4\fs16\cf0 (Windows Version 1.1)
|
||||
\par Created by Mark Simonson (v.1.0-1998, v.1.1-2001)
|
||||
\par marksim@bitstream.net
|
||||
\par Website: Mac/Atari Fusion--Atari Home Computer Resources for Mac Users
|
||||
\par http://www2.bitstream.net/~marksim/atarimac/
|
||||
\par Macintosh version also available.
|
||||
\par
|
||||
\par With these fonts installed, you can view and print Atari text files in any text editor that allows you to change fonts (WordPad, for example). Tip: In order to get the correct line breaks, you will need to change the ATASCII return character (155) to the DOS LF character. (In the Character Map accessory, the ATASCII return is the blank character that comes just before the inverse up-arrow.)
|
||||
\par
|
||||
\par There are three different fonts. \plain\f4\fs16\cf0\b Atari Classic Chunky \plain\f4\fs16\cf0 is a pixel-for-pixel copy of the original ATASCII character set. \plain\f4\fs16\cf0\b Atari Classic Smooth \plain\f4\fs16\cf0 interprets the pixel aliasing (stair steps) as diagonal lines. \plain\f4\fs16\cf0\b Atari Classic Extrasmooth \plain\f4\fs16\cf0 refines this idea further with the addition of curves. \plain\f4\fs16\cf0\b Smooth\plain\f4\fs16\cf0 and \plain\f4\fs16\cf0\b Extrasmooth\plain\f4\fs16\cf0 were designed for better appearance and legibility at larger sizes and on print-outs. Use the one that looks best to you.
|
||||
\par
|
||||
\par These fonts will tend to look uneven at font sizes that do not correspond to the 8-by-8 pixel grid that the characters are based on. Because Windows assumes 96ppi screen resolution, they will look best in a font size that is a multiple of 6 (i.e., 6pt, 12pt, 18pt, etc.). (In Windows, 6 points = 8 pixels.)
|
||||
\par
|
||||
\par The Atari Classic TrueType fonts duplicate the ATASCII character set on a low-level basis. Unlike a normal Windows font, ATASCII utilizes all character codes from $00 to $FF (0 to 255). The lower half are normal characters; the upper half are inverse versions of the lower half. The basic ASCII characters ($00 to $7F) correspond fairly closely except for the first 32, which don't normally contain characters in a Windows font.
|
||||
\par
|
||||
\par Due to differences between the way Windows and the Atari use character codes, not all characters will display properly in Windows. In fact, some characters will not display at all (though they do exist in the font). Unfortunately, this is due to certain character codes being reserved in Windows and there doesn't appear to be any way to work around it. The character codes affected are: $00-$1F (0-31), $7F-$81 (127-129), $8D-$90 (141-144), $9D (157), and $9F (158).
|
||||
\par
|
||||
\par Not all characters can be typed from the keyboard. You can however copy characters as needed from this document (see tables below). The Character Map desk accessory can help also.
|
||||
\par
|
||||
\par \plain\f4\fs16\cf0\b ATASCII CHARACTER SET TABLES
|
||||
\par \plain\f4\fs16\cf0
|
||||
\par In order to see the ATASCII character set with these tables, the Atari Classic TrueType fonts must be installed. Characters that are not displayed properly are due to character code usage differences between ATASCII and Windows (see above).
|
||||
\par
|
||||
\par
|
||||
\par \plain\f4\fs16\cf0\b TABLE 1: ATASCII Character Dump Block
|
||||
\par \plain\f4\fs16\cf0
|
||||
\par All characters (ATASCII $00 thru $FF) 16 characters per
|
||||
\par line.
|
||||
\par
|
||||
\par
|
||||
\par \plain\f2\fs12\cf0 \'01\'02\'03\'04\'05\'06\'07\'08\tab
|
||||
\par \'0b\'0c
|
||||
\par \'0e\'0f
|
||||
\par \'10\'11\'12\'13\'14\'15\'16\'17\'18\'19\'1a\'1b\'1c\'1d\'1e\'1f
|
||||
\par !"#$%&'()*+,-./
|
||||
\par 0123456789:;<=>?
|
||||
\par @ABCDEFGHIJKLMNO
|
||||
\par PQRSTUVWXYZ[\\]^_
|
||||
\par `abcdefghijklmno
|
||||
\par pqrstuvwxyz\{|\}~
|
||||
\par \'80\'81\'82\'83\'84\'85\'86\'87\'88\'89\'8a\'8b\'8c\'8d\'8e\'8f
|
||||
\par \'90''""\bullet \endash \emdash \'98\'99\'9a \'9c\'9d\'9e\'9f
|
||||
\par \~\'a1\'a2\'a3\'a4\'a5\'a6\'a7\'a8\'a9\'aa\'ab\'ac\'ad\'ae\'af
|
||||
\par \'b0\'b1\'b2\'b3\'b4\'b5\'b6\'b7\'b8\'b9\'ba\'bb\'bc\'bd\'be\'bf
|
||||
\par \'c0\'c1\'c2\'c3\'c4\'c5\'c6\'c7\'c8\'c9\'ca\'cb\'cc\'cd\'ce\'cf
|
||||
\par \'d0\'d1\'d2\'d3\'d4\'d5\'d6\'d7\'d8\'d9\'da\'db\'dc\'dd\'de\'df
|
||||
\par \'e0\'e1\'e2\'e3\'e4\'e5\'e6\'e7\'e8\'e9\'ea\'eb\'ec\'ed\'ee\'ef
|
||||
\par \'f0\'f1\'f2\'f3\'f4\'f5\'f6\'f7\'f8\'f9\'fa\'fb\'fc\'fd\'fe\'ff
|
||||
\par \plain\f4\fs16\cf0
|
||||
\par
|
||||
\par \plain\f4\fs16\cf0\b TABLE 2: ATASCII Character Dump List
|
||||
\par \plain\f4\fs16\cf0
|
||||
\par All characters (ATASCII $00 thru $FF) one character per
|
||||
\par line with hexadecimal value indicated on the left.
|
||||
\par
|
||||
\par \plain\f2\fs12\cf0 00=
|
||||
\par 01=\'01
|
||||
\par 02=\'02
|
||||
\par 03=\'03
|
||||
\par 04=\'04
|
||||
\par 05=\'05
|
||||
\par 06=\'06
|
||||
\par 07=\'07
|
||||
\par 08=\'08
|
||||
\par 09=\tab
|
||||
\par 0A=
|
||||
\par
|
||||
\par 0B=\'0b
|
||||
\par 0C=\'0c
|
||||
\par 0D=
|
||||
\par 0E=\'0e
|
||||
\par 0F=\'0f
|
||||
\par 10=\'10
|
||||
\par 11=\'11
|
||||
\par 12=\'12
|
||||
\par 13=\'13
|
||||
\par 14=\'14
|
||||
\par 15=\'15
|
||||
\par 16=\'16
|
||||
\par 17=\'17
|
||||
\par 18=\'18
|
||||
\par 19=\'19
|
||||
\par 1A=\'1a
|
||||
\par 1B=\'1b
|
||||
\par 1C=\'1c
|
||||
\par 1D=\'1d
|
||||
\par 1E=\'1e
|
||||
\par 1F=\'1f
|
||||
\par 20=
|
||||
\par 21=!
|
||||
\par 22="
|
||||
\par 23=#
|
||||
\par 24=$
|
||||
\par 25=%
|
||||
\par 26=&
|
||||
\par 27='
|
||||
\par 28=(
|
||||
\par 29=)
|
||||
\par 2A=*
|
||||
\par 2B=+
|
||||
\par 2C=,
|
||||
\par 2D=-
|
||||
\par 2E=.
|
||||
\par 2F=/
|
||||
\par 30=0
|
||||
\par 31=1
|
||||
\par 32=2
|
||||
\par 33=3
|
||||
\par 34=4
|
||||
\par 35=5
|
||||
\par 36=6
|
||||
\par 37=7
|
||||
\par 38=8
|
||||
\par 39=9
|
||||
\par 3A=:
|
||||
\par 3B=;
|
||||
\par 3C=<
|
||||
\par 3D==
|
||||
\par 3E=>
|
||||
\par 3F=?
|
||||
\par 40=@
|
||||
\par 41=A
|
||||
\par 42=B
|
||||
\par 43=C
|
||||
\par 44=D
|
||||
\par 45=E
|
||||
\par 46=F
|
||||
\par 47=G
|
||||
\par 48=H
|
||||
\par 49=I
|
||||
\par 4A=J
|
||||
\par 4B=K
|
||||
\par 4C=L
|
||||
\par 4D=M
|
||||
\par 4E=N
|
||||
\par 4F=O
|
||||
\par 50=P
|
||||
\par 51=Q
|
||||
\par 52=R
|
||||
\par 53=S
|
||||
\par 54=T
|
||||
\par 55=U
|
||||
\par 56=V
|
||||
\par 57=W
|
||||
\par 58=X
|
||||
\par 59=Y
|
||||
\par 5A=Z
|
||||
\par 5B=[
|
||||
\par 5C=\\
|
||||
\par 5D=]
|
||||
\par 5E=^
|
||||
\par 5F=_
|
||||
\par 60=`
|
||||
\par 61=a
|
||||
\par 62=b
|
||||
\par 63=c
|
||||
\par 64=d
|
||||
\par 65=e
|
||||
\par 66=f
|
||||
\par 67=g
|
||||
\par 68=h
|
||||
\par 69=i
|
||||
\par 6A=j
|
||||
\par 6B=k
|
||||
\par 6C=l
|
||||
\par 6D=m
|
||||
\par 6E=n
|
||||
\par 6F=o
|
||||
\par 70=p
|
||||
\par 71=q
|
||||
\par 72=r
|
||||
\par 73=s
|
||||
\par 74=t
|
||||
\par 75=u
|
||||
\par 76=v
|
||||
\par 77=w
|
||||
\par 78=x
|
||||
\par 79=y
|
||||
\par 7A=z
|
||||
\par 7B=\{
|
||||
\par 7C=|
|
||||
\par 7D=\}
|
||||
\par 7E=~
|
||||
\par 7F=
|
||||
\par 80=\'80
|
||||
\par 81=\'81
|
||||
\par 82=\'82
|
||||
\par 83=\'83
|
||||
\par 84=\'84
|
||||
\par 85=\'85
|
||||
\par 86=\'86
|
||||
\par 87=\'87
|
||||
\par 88=\'88
|
||||
\par 89=\'89
|
||||
\par 8A=\'8a
|
||||
\par 8B=\'8b
|
||||
\par 8C=\'8c
|
||||
\par 8D=\'8d
|
||||
\par 8E=\'8e
|
||||
\par 8F=\'8f
|
||||
\par 90=\'90
|
||||
\par 91='
|
||||
\par 92='
|
||||
\par 93="
|
||||
\par 94="
|
||||
\par 95=\bullet
|
||||
\par 96=\endash
|
||||
\par 97=\emdash
|
||||
\par 98=\'98
|
||||
\par 99=\'99
|
||||
\par 9A=\'9a
|
||||
\par 9B=
|
||||
\par 9C=\'9c
|
||||
\par 9D=\'9d
|
||||
\par 9E=\'9e
|
||||
\par 9F=\'9f
|
||||
\par A0=\~
|
||||
\par A1=\'a1
|
||||
\par A2=\'a2
|
||||
\par A3=\'a3
|
||||
\par A4=\'a4
|
||||
\par A5=\'a5
|
||||
\par A6=\'a6
|
||||
\par A7=\'a7
|
||||
\par A8=\'a8
|
||||
\par A9=\'a9
|
||||
\par AA=\'aa
|
||||
\par AB=\'ab
|
||||
\par AC=\'ac
|
||||
\par AD=\'ad
|
||||
\par AE=\'ae
|
||||
\par AF=\'af
|
||||
\par B0=\'b0
|
||||
\par B1=\'b1
|
||||
\par B2=\'b2
|
||||
\par B3=\'b3
|
||||
\par B4=\'b4
|
||||
\par B5=\'b5
|
||||
\par B6=\'b6
|
||||
\par B7=\'b7
|
||||
\par B8=\'b8
|
||||
\par B9=\'b9
|
||||
\par BA=\'ba
|
||||
\par BB=\'bb
|
||||
\par BC=\'bc
|
||||
\par BD=\'bd
|
||||
\par BE=\'be
|
||||
\par BF=\'bf
|
||||
\par C0=\'c0
|
||||
\par C1=\'c1
|
||||
\par C2=\'c2
|
||||
\par C3=\'c3
|
||||
\par C4=\'c4
|
||||
\par C5=\'c5
|
||||
\par C6=\'c6
|
||||
\par C7=\'c7
|
||||
\par C8=\'c8
|
||||
\par C9=\'c9
|
||||
\par CA=\'ca
|
||||
\par CB=\'cb
|
||||
\par CC=\'cc
|
||||
\par CD=\'cd
|
||||
\par CE=\'ce
|
||||
\par CF=\'cf
|
||||
\par D0=\'d0
|
||||
\par D1=\'d1
|
||||
\par D2=\'d2
|
||||
\par D3=\'d3
|
||||
\par D4=\'d4
|
||||
\par D5=\'d5
|
||||
\par D6=\'d6
|
||||
\par D7=\'d7
|
||||
\par D8=\'d8
|
||||
\par D9=\'d9
|
||||
\par DA=\'da
|
||||
\par DB=\'db
|
||||
\par DC=\'dc
|
||||
\par DD=\'dd
|
||||
\par DE=\'de
|
||||
\par DF=\'df
|
||||
\par E0=\'e0
|
||||
\par E1=\'e1
|
||||
\par E2=\'e2
|
||||
\par E3=\'e3
|
||||
\par E4=\'e4
|
||||
\par E5=\'e5
|
||||
\par E6=\'e6
|
||||
\par E7=\'e7
|
||||
\par E8=\'e8
|
||||
\par E9=\'e9
|
||||
\par EA=\'ea
|
||||
\par EB=\'eb
|
||||
\par EC=\'ec
|
||||
\par ED=\'ed
|
||||
\par EE=\'ee
|
||||
\par EF=\'ef
|
||||
\par F0=\'f0
|
||||
\par F1=\'f1
|
||||
\par F2=\'f2
|
||||
\par F3=\'f3
|
||||
\par F4=\'f4
|
||||
\par F5=\'f5
|
||||
\par F6=\'f6
|
||||
\par F7=\'f7
|
||||
\par F8=\'f8
|
||||
\par F9=\'f9
|
||||
\par FA=\'fa
|
||||
\par FB=\'fb
|
||||
\par FC=\'fc
|
||||
\par FD=\'fd
|
||||
\par FE=\'fe
|
||||
\par FF=\'ff
|
||||
\par }
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +0,0 @@
|
||||
|
||||
Fonts in this package are (c) 2010 Style.
|
||||
|
||||
You MAY NOT: sell this font; include/redistribute this font in any font collection regardless of pricing; provide the font for direct download from any web site. You MAY: link to "http://style64.org/c64-truetype" in order for others to download and install the font; embed this font or its .eot and .woff variants without any modification and using the same filename it was provided with for display on any web site using @font-face rules; use this font in static images and vector art; include this font without any modification and using the same filename it was provided with as part of a software package but ONLY if said software package is freely provided to end users. You may also contact us to negotiate a (possibly commercial) license for your use outside of these guidelines at "http://style64.org/contact-style".
|
||||
|
||||
At all times the most recent version of this license can be found at "http://style64.org/c64-truetype/license".
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,72 +0,0 @@
|
||||
/
|
||||
/(_____________ ____
|
||||
\ /______)\ | |
|
||||
:\ | / \:| |:::::::::: : .. . : .. . . :. .
|
||||
\_____| / | \| |______
|
||||
___ / ________ \... . . .
|
||||
\______________ \ | | /.. . . . . .
|
||||
\ |__| /
|
||||
--x--x-----x----\______ |-/_____/-x--x-xx--x-- - -x -- - - -- - - -
|
||||
. . . . . . . . . . . .\____|. . . . . .
|
||||
-------------------------------------------------------------------------------
|
||||
>> perfect dos vga 437 - general information >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
"Perfect DOS VGA 437" and "Perfect DOS VGA 437 Win" are truetype fonts
|
||||
designed to emulate the MS-DOS/Text mode standard font, used on VGA monitors,
|
||||
with the 437 Codepage (standard US/International). This is a "bitmap" font,
|
||||
meaning it emulates a bitmap font and can only be used at a given size (8 or
|
||||
multiples of it like 16, 24, 32, etc). It's optimized for Flash too, so it
|
||||
won't produce antialias if used at round positions.
|
||||
|
||||
There are two fonts available. "Perfect DOS VGA 437" uses the original DOS
|
||||
codepage 437. It should be used, for example, if you're opening DOS ASCII
|
||||
files on notepad or another windows-based editor. Since it's faithful to the
|
||||
original DOS codes, it won't accent correctly in windows ("é" would produce
|
||||
something different, not an "e" with an acute).
|
||||
|
||||
There's also "Perfect DOS VGA 437 Win" which is the exactly same font adapted
|
||||
to a windows codepage. This should use accented characters correctly but won't
|
||||
work if you're opening a DOS-based text file.
|
||||
|
||||
UPDATE: this is a new version, updated in august/2008. It has fixed leading
|
||||
metrics for Mac systems.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
>> perfect dos vga 437 - creation process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This font was created to be used on a Flash-based ANSi viewer I'm working. To
|
||||
create it, I created a small Quick Basic program to write all characters on
|
||||
screen,
|
||||
|
||||
CLS
|
||||
FOR l = 0 TO 255
|
||||
charWrite 1 + (l MOD 20), 1 + (l \ 20) * 6 + (l MOD 2), LTRIM$(RTRIM$(STR$(l))) + CHR$(l)
|
||||
NEXT
|
||||
SUB charWrite (lin, col, char$)
|
||||
DEF SEG = &HB800
|
||||
FOR i = 1 TO LEN(char$)
|
||||
POKE ((lin - 1) * 160) + ((col - 2 + i) * 2), ASC(MID$(char$, i, 1))
|
||||
IF (i = LEN(char$)) THEN POKE ((lin - 1) * 160) + ((col - 2 + i) * 2) + 1, 113
|
||||
NEXT
|
||||
END SUB
|
||||
|
||||
Then captured the text screen using SCREEN THIEF (a very, very old screen
|
||||
capture TSR program which converts text screens to images accurately). I then
|
||||
recreated the font polygon by polygon on Fontlab, while looking at the image
|
||||
on Photoshop. No conversion took place.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
>> author >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
zeh fernando remembers the old days. SMASH DAH FUCKING ENTAH.
|
||||
|
||||
http://www.fatorcaos.com.br
|
||||
|
||||
rorshack ^ maiden brazil
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
^zehPULLSdahTRICK^kudosOUTtoWHOkeepsITreal^smashDAHfuckingENTAH!!!^lowres4ever^
|
||||
-------------------------------------------------------------------------------
|
Binary file not shown.
Binary file not shown.
@ -1,28 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import "utils"
|
||||
|
||||
TerminalFrame{
|
||||
id: frame
|
||||
z: 2.1
|
||||
anchors.fill: parent
|
||||
addedWidth: 200
|
||||
addedHeight: 370
|
||||
borderLeft: 148
|
||||
borderRight: 148
|
||||
borderTop: 232
|
||||
borderBottom: 232
|
||||
imageSource: "../images/black-frame.png"
|
||||
normalsSource: "../images/black-frame-normals.png"
|
||||
|
||||
rectX: 20
|
||||
rectY: 20
|
||||
|
||||
distortionCoefficient: 1.9
|
||||
|
||||
displacementLeft: 70.0
|
||||
displacementTop: 55.0
|
||||
displacementRight: 50.0
|
||||
displacementBottom: 38.0
|
||||
|
||||
shaderString: "FrameShader.qml"
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import "utils"
|
||||
|
||||
TerminalFrame{
|
||||
id: frame
|
||||
z: 2.1
|
||||
anchors.fill: parent
|
||||
addedWidth: 0
|
||||
addedHeight: 0
|
||||
borderLeft: 0
|
||||
borderRight: 0
|
||||
borderTop: 0
|
||||
borderBottom: 0
|
||||
|
||||
rectX: 15
|
||||
rectY: 15
|
||||
|
||||
displacementLeft: 0
|
||||
displacementTop: 0
|
||||
displacementRight: 0
|
||||
displacementBottom: 0
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import "utils"
|
||||
|
||||
TerminalFrame{
|
||||
id: frame
|
||||
z: 2.1
|
||||
anchors.fill: parent
|
||||
addedWidth: 140
|
||||
addedHeight: 140
|
||||
borderLeft: 116
|
||||
borderRight: 116
|
||||
borderTop: 116
|
||||
borderBottom: 116
|
||||
imageSource: "../images/screen-frame.png"
|
||||
normalsSource: "../images/screen-frame-normals.png"
|
||||
|
||||
rectX: 15
|
||||
rectY: 15
|
||||
|
||||
distortionCoefficient: 1.5
|
||||
|
||||
displacementLeft: 45
|
||||
displacementTop: 40
|
||||
displacementRight: 38.0
|
||||
displacementBottom: 28.0
|
||||
|
||||
shaderString: "FrameShader.qml"
|
||||
}
|
Binary file not shown.
Before ![]() (image error) Size: 1.1 MiB |
Binary file not shown.
Before ![]() (image error) Size: 1.1 MiB |
Binary file not shown.
Before ![]() (image error) Size: 1.2 MiB |
Binary file not shown.
Before ![]() (image error) Size: 132 KiB |
Binary file not shown.
Before ![]() (image error) Size: 507 KiB |
Binary file not shown.
Before ![]() (image error) Size: 571 KiB |
Binary file not shown.
Before ![]() (image error) Size: 811 KiB |
@ -1,91 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
ShaderEffect{
|
||||
property variant source: framesource
|
||||
property variant normals: framesourcenormals
|
||||
property real screen_distorsion: shadersettings.screen_distortion * framecontainer.distortionCoefficient
|
||||
property real ambient_light: shadersettings.ambient_light
|
||||
property color font_color: shadersettings.font_color
|
||||
property color background_color: shadersettings.background_color
|
||||
property real brightness: shadersettings.brightness * 1.5 + 0.5
|
||||
|
||||
property bool frameReflections: shadersettings.frameReflections
|
||||
property variant lightSource: reflectionEffectSourceLoader.item
|
||||
|
||||
Loader{
|
||||
id: reflectionEffectLoader
|
||||
width: parent.width * 0.33
|
||||
height: parent.height * 0.33
|
||||
active: frameReflections
|
||||
|
||||
sourceComponent: FastBlur{
|
||||
id: frameReflectionEffect
|
||||
radius: 128
|
||||
source: terminal.kterminal
|
||||
smooth: false
|
||||
}
|
||||
}
|
||||
|
||||
Loader{
|
||||
id: reflectionEffectSourceLoader
|
||||
active: frameReflections
|
||||
sourceComponent: ShaderEffectSource{
|
||||
id: frameReflectionSource
|
||||
sourceItem: reflectionEffectLoader.item
|
||||
hideSource: true
|
||||
smooth: true
|
||||
}
|
||||
}
|
||||
|
||||
blending: true
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform sampler2D normals;
|
||||
uniform highp float screen_distorsion;
|
||||
uniform highp float ambient_light;
|
||||
uniform highp float qt_Opacity;" +
|
||||
|
||||
(frameReflections ?
|
||||
"uniform sampler2D lightSource;" : "") + "
|
||||
|
||||
uniform vec4 font_color;
|
||||
uniform vec4 background_color;
|
||||
varying lowp float brightness;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
vec2 distortCoordinates(vec2 coords){
|
||||
vec2 cc = coords - vec2(0.5);
|
||||
float dist = dot(cc, cc) * screen_distorsion;
|
||||
return (coords + cc * (1.0 + dist) * dist);
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec2 coords = distortCoordinates(qt_TexCoord0);
|
||||
vec4 txt_color = texture2D(source, coords);
|
||||
vec4 txt_normal = texture2D(normals, coords);
|
||||
vec3 normal = normalize(txt_normal.rgb * 2.0 - 1.0);
|
||||
vec3 light_direction = normalize(vec3(0.5, 0.5, 0.0) - vec3(qt_TexCoord0, 0.0));
|
||||
|
||||
float dotProd = dot(normal, light_direction);" +
|
||||
|
||||
(frameReflections ? "
|
||||
float screenLight = texture2D(lightSource, coords).r;
|
||||
float clampedDotProd = clamp(dotProd, 0.05, 1.0);
|
||||
float diffuseReflection = clamp(screenLight * 1.5 * clampedDotProd, 0.0, 0.35);
|
||||
float reflectionAlpha = mix(1.0, 0.90, dotProd);"
|
||||
: "
|
||||
float diffuseReflection = 0.0;
|
||||
float reflectionAlpha = 1.0;") + "
|
||||
|
||||
vec3 back_color = background_color.rgb * (0.2 + 0.5 * dotProd);
|
||||
vec3 front_color = font_color.rgb * (0.05 + diffuseReflection);
|
||||
|
||||
vec4 dark_color = vec4((back_color + front_color) * txt_normal.a, txt_normal.a * reflectionAlpha);
|
||||
gl_FragColor = mix(dark_color, txt_color, ambient_light);
|
||||
}"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
|
||||
ShaderEffect{
|
||||
property variant source: framesource
|
||||
property real screen_distorsion: shadersettings.screen_distortion
|
||||
|
||||
fragmentShader: "
|
||||
uniform sampler2D source;
|
||||
uniform highp float screen_distorsion;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
vec2 distortCoordinates(vec2 coords){
|
||||
vec2 cc = coords - vec2(0.5);
|
||||
float dist = dot(cc, cc) * screen_distorsion;
|
||||
return (coords + cc * (1.0 + dist) * dist);
|
||||
}
|
||||
|
||||
void main(){
|
||||
vec2 coords = distortCoordinates(qt_TexCoord0);
|
||||
float inside = texture2D(source, coords).a;
|
||||
gl_FragColor = vec4(vec3(0.0), inside);
|
||||
}"
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
import QtQuick 2.2
|
||||
|
||||
Item{
|
||||
id: framecontainer
|
||||
property int textureWidth: terminalWindow.width
|
||||
property int textureHeight: terminalWindow.height
|
||||
|
||||
property int addedWidth
|
||||
property int addedHeight
|
||||
property int borderLeft
|
||||
property int borderRight
|
||||
property int borderTop
|
||||
property int borderBottom
|
||||
property string imageSource
|
||||
property string normalsSource
|
||||
property string shaderString
|
||||
|
||||
//Value used to create the rect used to add the border to the texture
|
||||
property real rectX
|
||||
property real rectY
|
||||
|
||||
//Values used to displace the texture in the screen. Used to make reflections correct.
|
||||
property real displacementLeft
|
||||
property real displacementTop
|
||||
property real displacementRight
|
||||
property real displacementBottom
|
||||
|
||||
property real distortionCoefficient
|
||||
|
||||
property rect sourceRect: Qt.rect(-rectX * shadersettings.window_scaling,
|
||||
-rectY * shadersettings.window_scaling,
|
||||
terminal.width + 2*rectX * shadersettings.window_scaling,
|
||||
terminal.height + 2*rectY * shadersettings.window_scaling)
|
||||
|
||||
BorderImage{
|
||||
id: frameimage
|
||||
anchors.centerIn: parent
|
||||
width: textureWidth + addedWidth
|
||||
height: textureHeight + addedHeight
|
||||
|
||||
border.bottom: borderBottom
|
||||
border.top: borderTop
|
||||
border.left: borderLeft
|
||||
border.right: borderRight
|
||||
|
||||
source: imageSource
|
||||
horizontalTileMode: BorderImage.Stretch
|
||||
verticalTileMode: BorderImage.Stretch
|
||||
}
|
||||
BorderImage{
|
||||
id: framenormals
|
||||
anchors.fill: frameimage
|
||||
|
||||
border.bottom: borderBottom
|
||||
border.top: borderTop
|
||||
border.left: borderLeft
|
||||
border.right: borderRight
|
||||
|
||||
source: normalsSource
|
||||
horizontalTileMode: BorderImage.Stretch
|
||||
verticalTileMode: BorderImage.Stretch
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: framesource
|
||||
sourceItem: frameimage
|
||||
hideSource: true
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: framesourcenormals
|
||||
sourceItem: framenormals
|
||||
hideSource: true
|
||||
textureSize: Qt.size(parent.width, parent.height)
|
||||
}
|
||||
Loader{
|
||||
anchors.centerIn: parent
|
||||
width: parent.width + (addedWidth / textureWidth) * parent.width
|
||||
height: parent.height + (addedHeight / textureHeight) * parent.height
|
||||
source: shaderString
|
||||
}
|
||||
}
|
BIN
app/icons/128x128/cool-retro-term.png
Normal file
BIN
app/icons/128x128/cool-retro-term.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 32 KiB |
BIN
app/icons/256x256/cool-retro-term.png
Normal file
BIN
app/icons/256x256/cool-retro-term.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 62 KiB |
BIN
app/icons/32x32/cool-retro-term.png
Normal file
BIN
app/icons/32x32/cool-retro-term.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 8.4 KiB |
BIN
app/icons/64x64/cool-retro-term.png
Normal file
BIN
app/icons/64x64/cool-retro-term.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 19 KiB |
BIN
app/icons/crt.icns
Normal file
BIN
app/icons/crt.icns
Normal file
Binary file not shown.
127
app/main.cpp
Normal file
127
app/main.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#include <QtQml/QQmlApplicationEngine>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
#include <QQmlContext>
|
||||
#include <QStringList>
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QIcon>
|
||||
#include <QQuickStyle>
|
||||
|
||||
#include <QDebug>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#include <fileio.h>
|
||||
#include <monospacefontmanager.h>
|
||||
|
||||
QString getNamedArgument(QStringList args, QString name, QString defaultName)
|
||||
{
|
||||
int index = args.indexOf(name);
|
||||
return (index != -1) ? args[index + 1] : QString(defaultName);
|
||||
}
|
||||
|
||||
QString getNamedArgument(QStringList args, QString name)
|
||||
{
|
||||
return getNamedArgument(args, name, "");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Some environmental variable are necessary on certain platforms.
|
||||
|
||||
// This disables QT appmenu under Ubuntu, which is not working with QML apps.
|
||||
setenv("QT_QPA_PLATFORMTHEME", "", 1);
|
||||
|
||||
// Disable Connections slot warnings
|
||||
QLoggingCategory::setFilterRules("qt.qml.connections.warning=false");
|
||||
|
||||
#if defined (Q_OS_LINUX)
|
||||
setenv("QSG_RENDER_LOOP", "threaded", 0);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
// This allows UTF-8 characters usage in OSX.
|
||||
setenv("LC_CTYPE", "UTF-8", 1);
|
||||
#endif
|
||||
|
||||
if (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help"))) {
|
||||
QTextStream cout(stdout, QIODevice::WriteOnly);
|
||||
cout << "Usage: " << argv[0] << " [--default-settings] [--workdir <dir>] [--program <prog>] [-p|--profile <prof>] [--fullscreen] [-h|--help]" << '\n';
|
||||
cout << " --default-settings Run cool-retro-term with the default settings" << '\n';
|
||||
cout << " --workdir <dir> Change working directory to 'dir'" << '\n';
|
||||
cout << " -e <cmd> Command to execute. This option will catch all following arguments, so use it as the last option." << '\n';
|
||||
cout << " -T <title> Set window title to 'title'." << '\n';
|
||||
cout << " --fullscreen Run cool-retro-term in fullscreen." << '\n';
|
||||
cout << " -p|--profile <prof> Run cool-retro-term with the given profile." << '\n';
|
||||
cout << " -h|--help Print this help." << '\n';
|
||||
cout << " --verbose Print additional information such as profiles and settings." << '\n';
|
||||
cout << " -v|--version Print the program name and version." << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString appVersion("1.2.0");
|
||||
|
||||
if (argc>1 && (!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version"))) {
|
||||
QTextStream cout(stdout, QIODevice::WriteOnly);
|
||||
cout << "cool-retro-term " << appVersion << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
QApplication app(argc, argv);
|
||||
app.setAttribute(Qt::AA_MacDontSwapCtrlAndMeta, true);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
FileIO fileIO;
|
||||
MonospaceFontManager monospaceFontManager;
|
||||
|
||||
#if !defined(Q_OS_MAC)
|
||||
app.setWindowIcon(QIcon::fromTheme("cool-retro-term", QIcon(":../icons/32x32/cool-retro-term.png")));
|
||||
#else
|
||||
app.setWindowIcon(QIcon(":../icons/32x32/cool-retro-term.png"));
|
||||
#endif
|
||||
|
||||
app.setOrganizationName("cool-retro-term");
|
||||
app.setOrganizationDomain("cool-retro-term");
|
||||
|
||||
// Manage command line arguments from the cpp side
|
||||
QStringList args = app.arguments();
|
||||
|
||||
// Manage default command
|
||||
QStringList cmdList;
|
||||
if (args.contains("-e")) {
|
||||
cmdList << args.mid(args.indexOf("-e") + 1);
|
||||
}
|
||||
QVariant command(cmdList.empty() ? QVariant() : cmdList[0]);
|
||||
QVariant commandArgs(cmdList.size() <= 1 ? QVariant() : QVariant(cmdList.mid(1)));
|
||||
engine.rootContext()->setContextProperty("appVersion", appVersion);
|
||||
engine.rootContext()->setContextProperty("defaultCmd", command);
|
||||
engine.rootContext()->setContextProperty("defaultCmdArgs", commandArgs);
|
||||
|
||||
engine.rootContext()->setContextProperty("workdir", getNamedArgument(args, "--workdir", "$HOME"));
|
||||
engine.rootContext()->setContextProperty("fileIO", &fileIO);
|
||||
engine.rootContext()->setContextProperty("monospaceSystemFonts", monospaceFontManager.retrieveMonospaceFonts());
|
||||
|
||||
engine.rootContext()->setContextProperty("devicePixelRatio", app.devicePixelRatio());
|
||||
|
||||
// Manage import paths for Linux and OSX.
|
||||
QStringList importPathList = engine.importPathList();
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/qmltermwidget");
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../PlugIns");
|
||||
importPathList.prepend(QCoreApplication::applicationDirPath() + "/../../../qmltermwidget");
|
||||
engine.setImportPathList(importPathList);
|
||||
|
||||
engine.load(QUrl(QStringLiteral ("qrc:/main.qml")));
|
||||
|
||||
if (engine.rootObjects().isEmpty()) {
|
||||
qDebug() << "Cannot load QML interface";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Quit the application when the engine closes.
|
||||
QObject::connect((QObject*) &engine, SIGNAL(quit()), (QObject*) &app, SLOT(quit()));
|
||||
|
||||
return app.exec();
|
||||
}
|
193
app/main.qml
193
app/main.qml
@ -1,193 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import org.kde.konsole 0.1
|
||||
|
||||
ApplicationWindow{
|
||||
id: terminalWindow
|
||||
|
||||
width: 1024
|
||||
height: 768
|
||||
minimumWidth: 320
|
||||
minimumHeight: 240
|
||||
|
||||
property bool fullscreen: shadersettings.fullscreen
|
||||
onFullscreenChanged: visibility = (fullscreen ? Window.FullScreen : Window.Windowed)
|
||||
|
||||
flags: Qt.WA_TranslucentBackground
|
||||
color: "#00000000"
|
||||
title: qsTr("cool-old-term")
|
||||
|
||||
Action {
|
||||
id: showMenubarAction
|
||||
text: qsTr("Show Menubar")
|
||||
checkable: true
|
||||
checked: shadersettings.showMenubar
|
||||
onTriggered: shadersettings.showMenubar = !shadersettings.showMenubar
|
||||
}
|
||||
Action {
|
||||
id: fullscreenAction
|
||||
text: qsTr("&Fullscreen")
|
||||
shortcut: "Alt+F11"
|
||||
onTriggered: shadersettings.fullscreen = !shadersettings.fullscreen;
|
||||
checkable: true
|
||||
checked: shadersettings.fullscreen
|
||||
}
|
||||
Action {
|
||||
id: quitAction
|
||||
text: qsTr("&Quit")
|
||||
shortcut: "Ctrl+Q"
|
||||
onTriggered: terminalWindow.close();
|
||||
}
|
||||
Action{
|
||||
id: showsettingsAction
|
||||
text: qsTr("&Settings")
|
||||
onTriggered: settingswindow.show();
|
||||
}
|
||||
Action{
|
||||
id: copyAction
|
||||
text: qsTr("&Copy")
|
||||
shortcut: "Ctrl+Shift+C"
|
||||
onTriggered: terminal.copyClipboard()
|
||||
}
|
||||
Action{
|
||||
id: pasteAction
|
||||
text: qsTr("&Paste")
|
||||
shortcut: "Ctrl+Shift+V"
|
||||
onTriggered: terminal.pasteClipboard()
|
||||
}
|
||||
Action{
|
||||
id: zoomIn
|
||||
text: qsTr("&Zoom In")
|
||||
shortcut: "Ctrl++"
|
||||
onTriggered: {
|
||||
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
|
||||
var maxScalingIndex = shadersettings.fontScalingList.length - 1;
|
||||
shadersettings.setScalingIndex(Math.min(oldScaling + 1, maxScalingIndex));
|
||||
}
|
||||
}
|
||||
Action{
|
||||
id: zoomOut
|
||||
text: qsTr("&Zoom Out")
|
||||
shortcut: "Ctrl+-"
|
||||
onTriggered: {
|
||||
var oldScaling = shadersettings.fontScalingIndexes[shadersettings.rasterization];
|
||||
shadersettings.setScalingIndex(Math.max(oldScaling - 1, 0));
|
||||
}
|
||||
}
|
||||
Action{
|
||||
id: showAboutAction
|
||||
text: qsTr("About")
|
||||
onTriggered: {
|
||||
aboutDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
menuBar: MenuBar {
|
||||
id: menubar
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: quitAction}
|
||||
}
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: copyAction}
|
||||
MenuItem {action: pasteAction}
|
||||
MenuSeparator{}
|
||||
MenuItem {action: showsettingsAction}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("View")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: fullscreenAction}
|
||||
MenuItem {action: showMenubarAction}
|
||||
MenuSeparator{}
|
||||
MenuItem {action: zoomIn}
|
||||
MenuItem {action: zoomOut}
|
||||
}
|
||||
Menu{
|
||||
title: qsTr("Help")
|
||||
visible: shadersettings.showMenubar
|
||||
MenuItem {action: showAboutAction}
|
||||
}
|
||||
}
|
||||
ApplicationSettings{
|
||||
id: shadersettings
|
||||
}
|
||||
TimeManager{
|
||||
id: timeManager
|
||||
enableTimer: terminalWindow.visible
|
||||
}
|
||||
Item{
|
||||
id: maincontainer
|
||||
anchors.centerIn: parent
|
||||
width: parent.width * shadersettings.window_scaling
|
||||
height: parent.height * shadersettings.window_scaling
|
||||
scale: 1.0 / shadersettings.window_scaling
|
||||
smooth: false
|
||||
antialiasing: false
|
||||
opacity: shadersettings.windowOpacity * 0.3 + 0.7
|
||||
|
||||
Loader{
|
||||
id: frame
|
||||
anchors.fill: parent
|
||||
|
||||
property rect sourceRect: item.sourceRect
|
||||
|
||||
z: 2.1
|
||||
source: shadersettings.frame_source
|
||||
}
|
||||
PreprocessedTerminal{
|
||||
id: terminal
|
||||
anchors.fill: parent
|
||||
anchors.margins: 30
|
||||
}
|
||||
ShaderTerminal{
|
||||
id: shadercontainer
|
||||
anchors.fill: parent
|
||||
z: 1.9
|
||||
}
|
||||
}
|
||||
SettingsWindow{
|
||||
id: settingswindow
|
||||
visible: false
|
||||
}
|
||||
AboutDialog{
|
||||
id: aboutDialog
|
||||
visible: false
|
||||
}
|
||||
Loader{
|
||||
id: sizeoverlayloader
|
||||
z: 3
|
||||
anchors.centerIn: parent
|
||||
active: shadersettings.show_terminal_size
|
||||
sourceComponent: SizeOverlay{
|
||||
terminalSize: terminal.terminalSize
|
||||
}
|
||||
}
|
||||
Component.onCompleted: shadersettings.handleFontChanged();
|
||||
}
|
25
app/monospacefontmanager.cpp
Normal file
25
app/monospacefontmanager.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "monospacefontmanager.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
MonospaceFontManager::MonospaceFontManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QStringList MonospaceFontManager::retrieveMonospaceFonts() {
|
||||
QStringList result;
|
||||
|
||||
QFontDatabase fontDatabase;
|
||||
QStringList fontFamilies = fontDatabase.families();
|
||||
|
||||
for (int i = 0; i < fontFamilies.size(); i++) {
|
||||
QString fontFamily = fontFamilies[i];
|
||||
QFont font(fontFamily);
|
||||
if (fontDatabase.isFixedPitch(font.family())) {
|
||||
result.append(fontFamily);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
15
app/monospacefontmanager.h
Normal file
15
app/monospacefontmanager.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MONOSPACEFONTMANAGER_H
|
||||
#define MONOSPACEFONTMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFontDatabase>
|
||||
|
||||
class MonospaceFontManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MonospaceFontManager(QObject *parent = nullptr);
|
||||
Q_INVOKABLE QStringList retrieveMonospaceFonts();
|
||||
};
|
||||
|
||||
#endif // MONOSPACEFONTMANAGER_H
|
133
app/qml/AboutDialog.qml
Normal file
133
app/qml/AboutDialog.qml
Normal file
@ -0,0 +1,133 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.0
|
||||
|
||||
Window {
|
||||
id: dialogwindow
|
||||
title: qsTr("About")
|
||||
width: 600
|
||||
height: 400
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 15
|
||||
spacing: 15
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "cool-retro-term"
|
||||
font {
|
||||
bold: true
|
||||
pointSize: 18
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: mainContent
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Default"
|
||||
PropertyChanges {
|
||||
target: mainContent
|
||||
sourceComponent: defaultComponent
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "License"
|
||||
PropertyChanges {
|
||||
target: mainContent
|
||||
sourceComponent: licenseComponent
|
||||
}
|
||||
}
|
||||
]
|
||||
Component.onCompleted: mainContent.state = "Default"
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
height: childrenRect.height
|
||||
Button {
|
||||
anchors.left: parent.left
|
||||
text: qsTr("License")
|
||||
onClicked: {
|
||||
mainContent.state == "Default" ? mainContent.state
|
||||
= "License" : mainContent.state = "Default"
|
||||
}
|
||||
}
|
||||
Button {
|
||||
anchors.right: parent.right
|
||||
text: qsTr("Close")
|
||||
onClicked: dialogwindow.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
// MAIN COMPONENTS ////////////////////////////////////////////////////////
|
||||
Component {
|
||||
id: defaultComponent
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
Image {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/crt256.png"
|
||||
smooth: true
|
||||
}
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: appSettings.version + "\n" + qsTr(
|
||||
"Author: ") + "Filippo Scognamiglio\n" + qsTr(
|
||||
"Email: ") + "flscogna@gmail.com\n" + qsTr(
|
||||
"Source: ") + "https://github.com/Swordfish90/cool-retro-term\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: licenseComponent
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
TextArea {
|
||||
readOnly: true
|
||||
wrapMode: TextEdit.Wrap
|
||||
text: "Copyright (c) 2013-2021 Filippo Scognamiglio <flscogna@gmail.com>\n\n"
|
||||
+ "https://github.com/Swordfish90/cool-retro-term\n\n" +
|
||||
"cool-retro-term is free software: you can redistribute it and/or modify "
|
||||
+ "it under the terms of the GNU General Public License as published by "
|
||||
+ "the Free Software Foundation, either version 3 of the License, or "
|
||||
+ "(at your option) any later version.\n\n" +
|
||||
"This program is distributed in the hope that it will be useful, "
|
||||
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of "
|
||||
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
|
||||
+ "GNU General Public License for more details.\n\n" +
|
||||
"You should have received a copy of the GNU General Public License "
|
||||
+ "along with this program. If not, see <http://www.gnu.org/licenses/>."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
781
app/qml/ApplicationSettings.qml
Normal file
781
app/qml/ApplicationSettings.qml
Normal file
@ -0,0 +1,781 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
QtObject {
|
||||
readonly property string version: appVersion
|
||||
readonly property int profileVersion: 2
|
||||
|
||||
// STATIC CONSTANTS ////////////////////////////////////////////////////////
|
||||
readonly property real screenCurvatureSize: 0.4
|
||||
readonly property real minimumFontScaling: 0.25
|
||||
readonly property real maximumFontScaling: 2.50
|
||||
|
||||
readonly property real minBurnInFadeTime: 160
|
||||
readonly property real maxBurnInFadeTime: 1600
|
||||
|
||||
property bool isMacOS: Qt.platform.os === "osx"
|
||||
|
||||
// GENERAL SETTINGS ///////////////////////////////////////////////////////
|
||||
property int x: 100
|
||||
property int y: 100
|
||||
property int width: 1024
|
||||
property int height: 768
|
||||
|
||||
property bool fullscreen: false
|
||||
property bool showMenubar: false
|
||||
|
||||
property string wintitle: "cool-retro-term"
|
||||
|
||||
property bool showTerminalSize: true
|
||||
property real windowScaling: 1.0
|
||||
|
||||
property real fps: 20
|
||||
property bool verbose: false
|
||||
|
||||
property real bloomQuality: 0.5
|
||||
property real burnInQuality: 0.5
|
||||
|
||||
property bool blinkingCursor: false
|
||||
|
||||
onWindowScalingChanged: handleFontChanged()
|
||||
|
||||
// PROFILE SETTINGS ///////////////////////////////////////////////////////
|
||||
property real windowOpacity: 1.0
|
||||
property real ambientLight: 0.2
|
||||
property real contrast: 0.80
|
||||
property real brightness: 0.5
|
||||
|
||||
property bool useCustomCommand: false
|
||||
property string customCommand: ""
|
||||
|
||||
property string _backgroundColor: "#000000"
|
||||
property string _fontColor: "#ff8100"
|
||||
property string _frameColor: "#ffffff"
|
||||
property string saturatedColor: Utils.mix(Utils.strToColor("#FFFFFF"),
|
||||
Utils.strToColor(_fontColor),
|
||||
saturationColor * 0.5)
|
||||
property color fontColor: Utils.mix(Utils.strToColor(saturatedColor),
|
||||
Utils.strToColor(_backgroundColor),
|
||||
0.7 + (contrast * 0.3))
|
||||
property color backgroundColor: Utils.mix(Utils.strToColor(
|
||||
_backgroundColor),
|
||||
Utils.strToColor(saturatedColor),
|
||||
0.7 + (contrast * 0.3))
|
||||
property color frameColor: Utils.strToColor(_frameColor)
|
||||
|
||||
property real staticNoise: 0.12
|
||||
property real screenCurvature: 0.3
|
||||
property real glowingLine: 0.2
|
||||
property real burnIn: 0.25
|
||||
property real bloom: 0.55
|
||||
|
||||
property real chromaColor: 0.25
|
||||
property real saturationColor: 0.25
|
||||
property real frameGloss: 0
|
||||
|
||||
property real jitter: 0.2
|
||||
|
||||
property real horizontalSync: 0.08
|
||||
property real flickering: 0.1
|
||||
|
||||
property real rbgShift: 0.0
|
||||
|
||||
property real _margin: 0.5
|
||||
property real _frameMargin: 0.5
|
||||
|
||||
property real margin: Utils.lint(1.0, 20.0, _margin)
|
||||
property real frameMargin: Utils.lint(1.0, 50.0, _frameMargin)
|
||||
|
||||
property real totalMargin: frameMargin + margin
|
||||
|
||||
readonly property int no_rasterization: 0
|
||||
readonly property int scanline_rasterization: 1
|
||||
readonly property int pixel_rasterization: 2
|
||||
readonly property int subpixel_rasterization: 3
|
||||
|
||||
property int rasterization: no_rasterization
|
||||
|
||||
// FONTS //////////////////////////////////////////////////////////////////
|
||||
readonly property real baseFontScaling: 0.75
|
||||
property real fontScaling: 1.0
|
||||
property real totalFontScaling: baseFontScaling * fontScaling
|
||||
|
||||
property real fontWidth: 1.0
|
||||
|
||||
property bool lowResolutionFont: false
|
||||
|
||||
property var fontNames: ["TERMINUS_SCALED", "COMMODORE_PET", "COMMODORE_PET"]
|
||||
property var fontlist: fontManager.item.fontlist
|
||||
|
||||
signal terminalFontChanged(string fontFamily, int pixelSize, int lineSpacing, real screenScaling, real fontWidth)
|
||||
|
||||
signal initializedSettings
|
||||
|
||||
property Loader fontManager: Loader {
|
||||
states: [
|
||||
State {
|
||||
when: rasterization == no_rasterization
|
||||
PropertyChanges {
|
||||
target: fontManager
|
||||
source: "Fonts.qml"
|
||||
}
|
||||
},
|
||||
State {
|
||||
when: rasterization == scanline_rasterization
|
||||
PropertyChanges {
|
||||
target: fontManager
|
||||
source: "FontScanlines.qml"
|
||||
}
|
||||
},
|
||||
State {
|
||||
when: rasterization == pixel_rasterization
|
||||
PropertyChanges {
|
||||
target: fontManager
|
||||
source: "FontPixels.qml"
|
||||
}
|
||||
},
|
||||
State {
|
||||
when: rasterization == subpixel_rasterization
|
||||
PropertyChanges {
|
||||
target: fontManager
|
||||
source: "FontPixels.qml"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
onLoaded: handleFontChanged()
|
||||
}
|
||||
|
||||
property FontLoader fontLoader: FontLoader {}
|
||||
|
||||
onTotalFontScalingChanged: handleFontChanged()
|
||||
onFontWidthChanged: handleFontChanged()
|
||||
|
||||
function getIndexByName(name) {
|
||||
for (var i = 0; i < fontlist.count; i++) {
|
||||
var requestedName = fontlist.get(i).name
|
||||
if (name === requestedName)
|
||||
return i
|
||||
}
|
||||
return 0 // If the font is not available default to 0.
|
||||
}
|
||||
|
||||
function incrementScaling() {
|
||||
fontScaling = Math.min(fontScaling + 0.05, maximumFontScaling)
|
||||
handleFontChanged()
|
||||
}
|
||||
|
||||
function decrementScaling() {
|
||||
fontScaling = Math.max(fontScaling - 0.05, minimumFontScaling)
|
||||
handleFontChanged()
|
||||
}
|
||||
|
||||
function handleFontChanged() {
|
||||
if (!fontManager.item)
|
||||
return
|
||||
|
||||
var index = getIndexByName(fontNames[rasterization])
|
||||
if (index === undefined)
|
||||
return
|
||||
|
||||
fontManager.item.selectedFontIndex = index
|
||||
fontManager.item.scaling = totalFontScaling
|
||||
|
||||
var fontSource = fontManager.item.source
|
||||
var pixelSize = fontManager.item.pixelSize
|
||||
var lineSpacing = fontManager.item.lineSpacing
|
||||
var screenScaling = fontManager.item.screenScaling
|
||||
var fontWidth = fontManager.item.defaultFontWidth * appSettings.fontWidth
|
||||
var fontFamily = fontManager.item.family
|
||||
var isSystemFont = fontManager.item.isSystemFont
|
||||
|
||||
lowResolutionFont = fontManager.item.lowResolutionFont
|
||||
|
||||
if (!isSystemFont) {
|
||||
fontLoader.source = fontSource
|
||||
fontFamily = fontLoader.name
|
||||
}
|
||||
|
||||
terminalFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling,
|
||||
fontWidth)
|
||||
}
|
||||
|
||||
property Storage storage: Storage {}
|
||||
|
||||
function stringify(obj) {
|
||||
var replacer = function (key, val) {
|
||||
return val.toFixed ? Number(val.toFixed(4)) : val
|
||||
}
|
||||
return JSON.stringify(obj, replacer, 2)
|
||||
}
|
||||
|
||||
function composeSettingsString() {
|
||||
var settings = {
|
||||
"fps": fps,
|
||||
"x": x,
|
||||
"y": y,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"windowScaling": windowScaling,
|
||||
"showTerminalSize": showTerminalSize,
|
||||
"fontScaling": fontScaling,
|
||||
"fontNames": fontNames,
|
||||
"showMenubar": showMenubar,
|
||||
"bloomQuality": bloomQuality,
|
||||
"burnInQuality": burnInQuality,
|
||||
"useCustomCommand": useCustomCommand,
|
||||
"customCommand": customCommand
|
||||
}
|
||||
return stringify(settings)
|
||||
}
|
||||
|
||||
function composeProfileObject() {
|
||||
var settings = {
|
||||
"backgroundColor": _backgroundColor,
|
||||
"fontColor": _fontColor,
|
||||
"frameColor": _frameColor,
|
||||
"flickering": flickering,
|
||||
"horizontalSync": horizontalSync,
|
||||
"staticNoise": staticNoise,
|
||||
"chromaColor": chromaColor,
|
||||
"saturationColor": saturationColor,
|
||||
"frameGloss": frameGloss,
|
||||
"screenCurvature": screenCurvature,
|
||||
"glowingLine": glowingLine,
|
||||
"burnIn": burnIn,
|
||||
"bloom": bloom,
|
||||
"rasterization": rasterization,
|
||||
"jitter": jitter,
|
||||
"rbgShift": rbgShift,
|
||||
"brightness": brightness,
|
||||
"contrast": contrast,
|
||||
"ambientLight": ambientLight,
|
||||
"windowOpacity": windowOpacity,
|
||||
"fontName": fontNames[rasterization],
|
||||
"fontWidth": fontWidth,
|
||||
"margin": _margin,
|
||||
"blinkingCursor": blinkingCursor,
|
||||
"frameMargin": _frameMargin,
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
||||
function composeProfileString() {
|
||||
return stringify(composeProfileObject())
|
||||
}
|
||||
|
||||
function loadSettings() {
|
||||
var settingsString = storage.getSetting("_CURRENT_SETTINGS")
|
||||
var profileString = storage.getSetting("_CURRENT_PROFILE")
|
||||
|
||||
if (!settingsString)
|
||||
return
|
||||
if (!profileString)
|
||||
return
|
||||
|
||||
loadSettingsString(settingsString)
|
||||
loadProfileString(profileString)
|
||||
|
||||
if (verbose)
|
||||
console.log("Loading settings: " + settingsString + profileString)
|
||||
}
|
||||
|
||||
function storeSettings() {
|
||||
var settingsString = composeSettingsString()
|
||||
var profileString = composeProfileString()
|
||||
|
||||
storage.setSetting("_CURRENT_SETTINGS", settingsString)
|
||||
storage.setSetting("_CURRENT_PROFILE", profileString)
|
||||
|
||||
if (verbose) {
|
||||
console.log("Storing settings: " + settingsString)
|
||||
console.log("Storing profile: " + profileString)
|
||||
}
|
||||
}
|
||||
|
||||
function loadSettingsString(settingsString) {
|
||||
var settings = JSON.parse(settingsString)
|
||||
|
||||
showTerminalSize = settings.showTerminalSize
|
||||
!== undefined ? settings.showTerminalSize : showTerminalSize
|
||||
|
||||
fps = settings.fps !== undefined ? settings.fps : fps
|
||||
windowScaling = settings.windowScaling
|
||||
!== undefined ? settings.windowScaling : windowScaling
|
||||
|
||||
x = settings.x !== undefined ? settings.x : x
|
||||
y = settings.y !== undefined ? settings.y : y
|
||||
width = settings.width !== undefined ? settings.width : width
|
||||
height = settings.height !== undefined ? settings.height : height
|
||||
|
||||
fontNames = settings.fontNames !== undefined ? settings.fontNames : fontNames
|
||||
fontScaling = settings.fontScaling !== undefined ? settings.fontScaling : fontScaling
|
||||
|
||||
showMenubar = settings.showMenubar !== undefined ? settings.showMenubar : showMenubar
|
||||
|
||||
bloomQuality = settings.bloomQuality !== undefined ? settings.bloomQuality : bloomQuality
|
||||
burnInQuality = settings.burnInQuality
|
||||
!== undefined ? settings.burnInQuality : burnInQuality
|
||||
|
||||
useCustomCommand = settings.useCustomCommand
|
||||
!== undefined ? settings.useCustomCommand : useCustomCommand
|
||||
customCommand = settings.customCommand
|
||||
!== undefined ? settings.customCommand : customCommand
|
||||
}
|
||||
|
||||
function loadProfileString(profileString) {
|
||||
var settings = JSON.parse(profileString)
|
||||
|
||||
_backgroundColor = settings.backgroundColor
|
||||
!== undefined ? settings.backgroundColor : _backgroundColor
|
||||
_fontColor = settings.fontColor !== undefined ? settings.fontColor : _fontColor
|
||||
_frameColor = settings.frameColor !== undefined ? settings.frameColor : _frameColor
|
||||
|
||||
horizontalSync = settings.horizontalSync
|
||||
!== undefined ? settings.horizontalSync : horizontalSync
|
||||
flickering = settings.flickering !== undefined ? settings.flickering : flickering
|
||||
staticNoise = settings.staticNoise !== undefined ? settings.staticNoise : staticNoise
|
||||
chromaColor = settings.chromaColor !== undefined ? settings.chromaColor : chromaColor
|
||||
saturationColor = settings.saturationColor
|
||||
!== undefined ? settings.saturationColor : saturationColor
|
||||
frameGloss = settings.frameGloss !== undefined ? settings.frameGloss : frameGloss
|
||||
screenCurvature = settings.screenCurvature
|
||||
!== undefined ? settings.screenCurvature : screenCurvature
|
||||
glowingLine = settings.glowingLine !== undefined ? settings.glowingLine : glowingLine
|
||||
|
||||
burnIn = settings.burnIn !== undefined ? settings.burnIn : burnIn
|
||||
bloom = settings.bloom !== undefined ? settings.bloom : bloom
|
||||
|
||||
rasterization = settings.rasterization
|
||||
!== undefined ? settings.rasterization : rasterization
|
||||
|
||||
jitter = settings.jitter !== undefined ? settings.jitter : jitter
|
||||
|
||||
rbgShift = settings.rbgShift !== undefined ? settings.rbgShift : rbgShift
|
||||
|
||||
ambientLight = settings.ambientLight !== undefined ? settings.ambientLight : ambientLight
|
||||
contrast = settings.contrast !== undefined ? settings.contrast : contrast
|
||||
brightness = settings.brightness !== undefined ? settings.brightness : brightness
|
||||
windowOpacity = settings.windowOpacity
|
||||
!== undefined ? settings.windowOpacity : windowOpacity
|
||||
|
||||
fontNames[rasterization] = settings.fontName
|
||||
!== undefined ? settings.fontName : fontNames[rasterization]
|
||||
fontWidth = settings.fontWidth !== undefined ? settings.fontWidth : fontWidth
|
||||
|
||||
_margin = settings.margin !== undefined ? settings.margin : _margin
|
||||
_frameMargin = settings.frameMargin !== undefined ? settings.frameMargin : _frameMargin
|
||||
|
||||
blinkingCursor = settings.blinkingCursor !== undefined ? settings.blinkingCursor : blinkingCursor
|
||||
|
||||
handleFontChanged()
|
||||
}
|
||||
|
||||
function storeCustomProfiles() {
|
||||
storage.setSetting("_CUSTOM_PROFILES", composeCustomProfilesString())
|
||||
}
|
||||
|
||||
function loadCustomProfiles() {
|
||||
var customProfileString = storage.getSetting("_CUSTOM_PROFILES")
|
||||
if (customProfileString === undefined)
|
||||
customProfileString = "[]"
|
||||
loadCustomProfilesString(customProfileString)
|
||||
}
|
||||
|
||||
function loadCustomProfilesString(customProfilesString) {
|
||||
var customProfiles = JSON.parse(customProfilesString)
|
||||
for (var i = 0; i < customProfiles.length; i++) {
|
||||
var profile = customProfiles[i]
|
||||
|
||||
if (verbose)
|
||||
console.log("Loading custom profile: " + stringify(profile))
|
||||
|
||||
profilesList.append(profile)
|
||||
}
|
||||
}
|
||||
|
||||
function composeCustomProfilesString() {
|
||||
var customProfiles = []
|
||||
for (var i = 0; i < profilesList.count; i++) {
|
||||
var profile = profilesList.get(i)
|
||||
if (profile.builtin)
|
||||
continue
|
||||
customProfiles.push({
|
||||
"text": profile.text,
|
||||
"obj_string": profile.obj_string,
|
||||
"builtin": false
|
||||
})
|
||||
}
|
||||
return stringify(customProfiles)
|
||||
}
|
||||
|
||||
function loadProfile(index) {
|
||||
var profile = profilesList.get(index)
|
||||
loadProfileString(profile.obj_string)
|
||||
}
|
||||
|
||||
function appendCustomProfile(name, profileString) {
|
||||
profilesList.append({
|
||||
"text": name,
|
||||
"obj_string": profileString,
|
||||
"builtin": false
|
||||
})
|
||||
}
|
||||
|
||||
// PROFILES ///////////////////////////////////////////////////////////////
|
||||
property ListModel profilesList: ListModel {
|
||||
ListElement {
|
||||
text: "Default Amber"
|
||||
obj_string: '{
|
||||
"ambientLight": 0.2,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.5538,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.2517,
|
||||
"chromaColor": 0.2483,
|
||||
"contrast": 0.7959,
|
||||
"flickering": 0.1,
|
||||
"fontColor": "#ff8100",
|
||||
"fontName": "TERMINUS_SCALED",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.2,
|
||||
"horizontalSync": 0.08,
|
||||
"jitter": 0.1997,
|
||||
"rasterization": 0,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0.2483,
|
||||
"screenCurvature": 0.3,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.1198,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.1
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Monochrome Green"
|
||||
obj_string: '{
|
||||
"ambientLight": 0.2,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.5538,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.2517,
|
||||
"chromaColor": 0.0,
|
||||
"contrast": 0.7959,
|
||||
"flickering": 0.1,
|
||||
"fontColor": "#0ccc68",
|
||||
"fontName": "TERMINUS_SCALED",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.2,
|
||||
"horizontalSync": 0.08,
|
||||
"jitter": 0.1997,
|
||||
"rasterization": 0,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0.0,
|
||||
"screenCurvature": 0.3,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.1198,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.1
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Green Scanlines"
|
||||
obj_string: '{
|
||||
"ambientLight": 0,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.6,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.3,
|
||||
"chromaColor": 0.5,
|
||||
"contrast": 0.6,
|
||||
"flickering": 0.1,
|
||||
"fontColor": "#7cff4f",
|
||||
"fontName": "PRO_FONT_SCALED",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.2,
|
||||
"horizontalSync": 0.151,
|
||||
"jitter": 0.11,
|
||||
"rasterization": 1,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0.5,
|
||||
"screenCurvature": 0.3,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.15,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.1
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Default Pixelated"
|
||||
obj_string: '{
|
||||
"ambientLight": 0,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.4045,
|
||||
"brightness": 0.6041,
|
||||
"burnIn": 0.1024,
|
||||
"chromaColor": 0.7517,
|
||||
"contrast": 0.7473,
|
||||
"flickering": 0.1962,
|
||||
"fontColor": "#ffffff",
|
||||
"fontName": "COMMODORE_PET",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.2,
|
||||
"horizontalSync": 0.151,
|
||||
"jitter": 0,
|
||||
"rasterization": 2,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0,
|
||||
"screenCurvature": 0,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.15,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.1
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Apple ]["
|
||||
obj_string: '{
|
||||
"ambientLight": 0.3038,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.5,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.5017,
|
||||
"chromaColor": 0,
|
||||
"contrast": 0.85,
|
||||
"flickering": 0.2,
|
||||
"fontColor": "#00d56d",
|
||||
"fontName": "APPLE_II",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.22,
|
||||
"horizontalSync": 0.16,
|
||||
"jitter": 0.1,
|
||||
"rasterization": 1,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0,
|
||||
"screenCurvature": 0.5,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.099,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.2
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Vintage"
|
||||
obj_string: '{
|
||||
"ambientLight": 0.5,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.4983,
|
||||
"brightness": 0.5014,
|
||||
"burnIn": 0.4983,
|
||||
"chromaColor": 0,
|
||||
"contrast": 0.7473,
|
||||
"flickering": 0.9,
|
||||
"fontColor": "#00ff3e",
|
||||
"fontName": "COMMODORE_PET",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.3,
|
||||
"horizontalSync": 0.42,
|
||||
"jitter": 0.4,
|
||||
"rasterization": 1,
|
||||
"rbgShift": 0.2969,
|
||||
"saturationColor": 0,
|
||||
"screenCurvature": 0.5,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.2969,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.5
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "IBM DOS"
|
||||
obj_string: '{
|
||||
"ambientLight": 0.151,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.2969,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.0469,
|
||||
"chromaColor": 1,
|
||||
"contrast": 0.85,
|
||||
"flickering": 0.0955,
|
||||
"fontColor": "#ffffff",
|
||||
"fontName": "IBM_DOS",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.1545,
|
||||
"horizontalSync": 0,
|
||||
"jitter": 0.1545,
|
||||
"rasterization": 0,
|
||||
"rbgShift": 0.3524,
|
||||
"saturationColor": 0,
|
||||
"screenCurvature": 0.4,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.0503,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.2
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "IBM 3278"
|
||||
obj_string: '{
|
||||
"ambientLight": 0.1,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.2969,
|
||||
"brightness": 0.5,
|
||||
"burnIn": 0.6,
|
||||
"chromaColor": 0,
|
||||
"contrast": 0.85,
|
||||
"flickering": 0,
|
||||
"fontColor": "#0ccc68",
|
||||
"fontName": "IBM_3278",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0,
|
||||
"horizontalSync": 0,
|
||||
"jitter": 0,
|
||||
"rasterization": 0,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0,
|
||||
"screenCurvature": 0.2,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0,
|
||||
"windowOpacity": 1,
|
||||
"margin": 0.5,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0.1
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
ListElement {
|
||||
text: "Futuristic"
|
||||
obj_string: '{
|
||||
"ambientLight": 0,
|
||||
"backgroundColor": "#000000",
|
||||
"bloom": 0.5017,
|
||||
"brightness": 0.5014,
|
||||
"burnIn": 0.0955,
|
||||
"chromaColor": 1,
|
||||
"contrast": 0.85,
|
||||
"flickering": 0.2,
|
||||
"fontColor": "#729fcf",
|
||||
"fontName": "TERMINUS",
|
||||
"fontWidth": 1,
|
||||
"glowingLine": 0.1476,
|
||||
"horizontalSync": 0,
|
||||
"jitter": 0.099,
|
||||
"rasterization": 0,
|
||||
"rbgShift": 0,
|
||||
"saturationColor": 0.4983,
|
||||
"screenCurvature": 0,
|
||||
"frameColor": "#ffffff",
|
||||
"frameGloss": 0,
|
||||
"staticNoise": 0.0955,
|
||||
"windowOpacity": 0.7,
|
||||
"margin": 0.1,
|
||||
"blinkingCursor": false,
|
||||
"frameMargin": 0
|
||||
}'
|
||||
builtin: true
|
||||
}
|
||||
}
|
||||
|
||||
function getProfileIndexByName(name) {
|
||||
for (var i = 0; i < profilesList.count; i++) {
|
||||
if (profilesList.get(i).text === name)
|
||||
return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Manage the arguments from the QML side.
|
||||
var args = Qt.application.arguments
|
||||
if (args.indexOf("--verbose") !== -1) {
|
||||
verbose = true
|
||||
}
|
||||
if (args.indexOf("--default-settings") === -1) {
|
||||
loadSettings()
|
||||
}
|
||||
|
||||
loadCustomProfiles()
|
||||
|
||||
var profileArgPosition = args.indexOf("--profile")
|
||||
if (profileArgPosition !== -1) {
|
||||
var profileIndex = getProfileIndexByName(
|
||||
args[profileArgPosition + 1])
|
||||
if (profileIndex !== -1)
|
||||
loadProfile(profileIndex)
|
||||
else
|
||||
console.log("Warning: selected profile is not valid; ignoring it")
|
||||
}
|
||||
|
||||
if (args.indexOf("--fullscreen") !== -1) {
|
||||
fullscreen = true
|
||||
showMenubar = false
|
||||
}
|
||||
|
||||
if (args.indexOf("-T") !== -1) {
|
||||
wintitle = args[args.indexOf("-T") + 1]
|
||||
}
|
||||
|
||||
initializedSettings()
|
||||
}
|
||||
Component.onDestruction: {
|
||||
storeSettings()
|
||||
storeCustomProfiles()
|
||||
// storage.dropSettings(); //DROPS THE SETTINGS!.. REMEMBER TO DISABLE ONCE ENABLED!!
|
||||
}
|
||||
|
||||
// VARS ///////////////////////////////////////////////////////////////////
|
||||
property Label _sampleLabel: Label {
|
||||
text: "100%"
|
||||
}
|
||||
property real labelWidth: _sampleLabel.width
|
||||
}
|
161
app/qml/BurnInEffect.qml
Normal file
161
app/qml/BurnInEffect.qml
Normal file
@ -0,0 +1,161 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
Loader {
|
||||
id: burnInEffect
|
||||
|
||||
property ShaderEffectSource source: item ? item.source : null
|
||||
|
||||
property real lastUpdate: 0
|
||||
property real prevLastUpdate: 0
|
||||
|
||||
property real burnIn: appSettings.burnIn
|
||||
property real burnInFadeTime: 1 / Utils.lint(_minBurnInFadeTime, _maxBurnInFadeTime, burnIn)
|
||||
property real _minBurnInFadeTime: appSettings.minBurnInFadeTime
|
||||
property real _maxBurnInFadeTime: appSettings.maxBurnInFadeTime
|
||||
|
||||
active: appSettings.burnIn !== 0
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
function completelyUpdate() {
|
||||
let newTime = timeManager.time
|
||||
if (newTime > lastUpdate) {
|
||||
prevLastUpdate = lastUpdate
|
||||
lastUpdate = newTime
|
||||
}
|
||||
|
||||
item.source.scheduleUpdate()
|
||||
}
|
||||
|
||||
function restartBlurSource() {
|
||||
prevLastUpdate = timeManager.time
|
||||
lastUpdate = prevLastUpdate
|
||||
completelyUpdate()
|
||||
}
|
||||
|
||||
sourceComponent: Item {
|
||||
property alias source: burnInEffectSource
|
||||
|
||||
ShaderEffectSource {
|
||||
id: burnInEffectSource
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
sourceItem: burnInShaderEffect
|
||||
live: false
|
||||
recursive: true
|
||||
hideSource: true
|
||||
wrapMode: ShaderEffectSource.ClampToEdge
|
||||
|
||||
format: ShaderEffectSource.RGBA
|
||||
smooth: true
|
||||
|
||||
visible: false
|
||||
|
||||
Connections {
|
||||
target: kterminal
|
||||
|
||||
onImagePainted: {
|
||||
completelyUpdate()
|
||||
}
|
||||
}
|
||||
// Restart blurred source settings change.
|
||||
Connections {
|
||||
target: appSettings
|
||||
|
||||
onBurnInChanged: {
|
||||
burnInEffect.restartBlurSource()
|
||||
}
|
||||
|
||||
onTerminalFontChanged: {
|
||||
burnInEffect.restartBlurSource()
|
||||
}
|
||||
|
||||
onRasterizationChanged: {
|
||||
burnInEffect.restartBlurSource()
|
||||
}
|
||||
|
||||
onBurnInQualityChanged: {
|
||||
burnInEffect.restartBlurSource()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShaderLibrary {
|
||||
id: shaderLibrary
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: burnInShaderEffect
|
||||
|
||||
property variant txt_source: kterminalSource
|
||||
property variant burnInSource: burnInEffectSource
|
||||
property real burnInTime: burnInFadeTime
|
||||
property real lastUpdate: burnInEffect.lastUpdate
|
||||
property real prevLastUpdate: burnInEffect.prevLastUpdate
|
||||
|
||||
anchors.fill: parent
|
||||
blending: false
|
||||
|
||||
fragmentShader:
|
||||
"#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif\n" +
|
||||
|
||||
"uniform lowp float qt_Opacity;" +
|
||||
"uniform lowp sampler2D txt_source;" +
|
||||
|
||||
"varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform lowp sampler2D burnInSource;
|
||||
uniform highp float burnInTime;
|
||||
|
||||
uniform highp float lastUpdate;
|
||||
|
||||
uniform highp float prevLastUpdate;" +
|
||||
|
||||
shaderLibrary.rgb2grey +
|
||||
|
||||
"void main() {
|
||||
vec2 coords = qt_TexCoord0;
|
||||
|
||||
vec3 txtColor = texture2D(txt_source, coords).rgb;
|
||||
vec4 accColor = texture2D(burnInSource, coords);
|
||||
|
||||
float prevMask = accColor.a;
|
||||
float currMask = rgb2grey(txtColor);
|
||||
|
||||
highp float blurDecay = clamp((lastUpdate - prevLastUpdate) * burnInTime, 0.0, 1.0);
|
||||
blurDecay = max(0.0, blurDecay - prevMask);
|
||||
vec3 blurColor = accColor.rgb - vec3(blurDecay);
|
||||
vec3 color = max(blurColor, txtColor);
|
||||
|
||||
gl_FragColor = vec4(color, currMask);
|
||||
}
|
||||
"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
||||
}
|
||||
}
|
72
app/qml/CheckableSlider.qml
Normal file
72
app/qml/CheckableSlider.qml
Normal file
@ -0,0 +1,72 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
RowLayout {
|
||||
property alias name: check.text
|
||||
|
||||
property double value
|
||||
property alias min_value: slider.from
|
||||
property alias max_value: slider.to
|
||||
property alias stepSize: slider.stepSize
|
||||
|
||||
signal newValue(real newValue)
|
||||
|
||||
id: setting_component
|
||||
Layout.fillWidth: true
|
||||
|
||||
onValueChanged: {
|
||||
check.checked = !(value == 0)
|
||||
if (check.checked)
|
||||
slider.value = value
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: check
|
||||
implicitWidth: 160
|
||||
onClicked: {
|
||||
if (!checked) {
|
||||
checked = false
|
||||
slider.enabled = false
|
||||
newValue(0)
|
||||
} else {
|
||||
checked = true
|
||||
newValue(slider.value)
|
||||
slider.enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
Slider {
|
||||
id: slider
|
||||
stepSize: parent.stepSize
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: {
|
||||
newValue(value)
|
||||
}
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(
|
||||
((value - min_value) / (max_value - min_value)) * 100) + "%"
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
@ -17,13 +17,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
|
||||
signal colorSelected(color color)
|
||||
property color button_color
|
||||
property color color
|
||||
property string name
|
||||
|
||||
ColorDialog {
|
||||
@ -33,15 +34,14 @@ Item {
|
||||
visible: false
|
||||
|
||||
//This is a workaround to a Qt 5.2 bug.
|
||||
onCurrentColorChanged: colorDialog.color = colorDialog.currentColor;
|
||||
onAccepted: colorSelected(color)
|
||||
onColorChanged: if (!appSettings.isMacOS) colorSelected(color)
|
||||
onAccepted: if (appSettings.isMacOS) colorSelected(color)
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 10
|
||||
color: button_color
|
||||
border.color: "black"
|
||||
Glossy {}
|
||||
color: rootItem.color
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: parent.height * 0.25
|
||||
@ -52,11 +52,11 @@ Item {
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
z: parent.z + 1
|
||||
text: name + ": " + button_color
|
||||
text: name + ": " + rootItem.color
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: colorDialog.visible = true;
|
||||
onClicked: colorDialog.visible = true
|
||||
}
|
||||
}
|
32
app/qml/Components/SizedLabel.qml
Normal file
32
app/qml/Components/SizedLabel.qml
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
// This component is simply a label with a predefined size.
|
||||
// Used to improve alignment.
|
||||
Label {
|
||||
id: textfield
|
||||
Layout.minimumWidth: appSettings.labelWidth
|
||||
width: appSettings.labelWidth
|
||||
}
|
107
app/qml/FontPixels.qml
Normal file
107
app/qml/FontPixels.qml
Normal file
@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var source: _font.source
|
||||
property int pixelSize: _font.pixelSize
|
||||
property int lineSpacing: _font.lineSpacing
|
||||
property real screenScaling: scaling * _font.baseScaling
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
property bool lowResolutionFont: true
|
||||
|
||||
property ListModel fontlist: ListModel {
|
||||
ListElement {
|
||||
name: "COMMODORE_PET"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/PetMe.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement {
|
||||
name: "IBM_PC"
|
||||
text: "IBM PC (1981)"
|
||||
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement {
|
||||
name: "PROGGY_TINY"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 3.3
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement {
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement {
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement {
|
||||
name: "APPLE_II"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 2
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement {
|
||||
name: "ATARI_400"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement {
|
||||
name: "COMMODORE_64"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
}
|
||||
}
|
107
app/qml/FontScanlines.qml
Normal file
107
app/qml/FontScanlines.qml
Normal file
@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property var source: _font.source
|
||||
property int pixelSize: _font.pixelSize
|
||||
property int lineSpacing: _font.lineSpacing
|
||||
property real screenScaling: scaling * _font.baseScaling
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
property bool lowResolutionFont: true
|
||||
|
||||
property ListModel fontlist: ListModel {
|
||||
ListElement {
|
||||
name: "COMMODORE_PET"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/PetMe.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
}
|
||||
ListElement {
|
||||
name: "IBM_PC"
|
||||
text: "IBM PC (1981)"
|
||||
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement {
|
||||
name: "PROGGY_TINY"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 3.3
|
||||
fontWidth: 0.9
|
||||
}
|
||||
ListElement {
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement {
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
}
|
||||
ListElement {
|
||||
name: "APPLE_II"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
}
|
||||
ListElement {
|
||||
name: "ATARI_400"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
}
|
||||
ListElement {
|
||||
name: "COMMODORE_64"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
}
|
||||
}
|
||||
}
|
252
app/qml/Fonts.qml
Normal file
252
app/qml/Fonts.qml
Normal file
@ -0,0 +1,252 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property int selectedFontIndex
|
||||
property real scaling
|
||||
property var source: fontlist.get(selectedFontIndex).source
|
||||
property var _font: fontlist.get(selectedFontIndex)
|
||||
property bool lowResolutionFont: _font.lowResolutionFont
|
||||
|
||||
property int pixelSize: lowResolutionFont ? _font.pixelSize : _font.pixelSize * scaling
|
||||
|
||||
property int lineSpacing: lowResolutionFont ? _font.lineSpacing : pixelSize * _font.lineSpacing
|
||||
|
||||
property real screenScaling: lowResolutionFont ? _font.baseScaling * scaling : 1.0
|
||||
|
||||
property real defaultFontWidth: fontlist.get(selectedFontIndex).fontWidth
|
||||
|
||||
property string family: fontlist.get(selectedFontIndex).family
|
||||
|
||||
property bool isSystemFont: fontlist.get(selectedFontIndex).isSystemFont
|
||||
|
||||
// There are two kind of fonts: low resolution and high resolution.
|
||||
// Low resolution font sets the lowResolutionFont property to true.
|
||||
// They are rendered at a fixed pixel size and the texture is upscaled
|
||||
// to fill the screen (they are much faster to render).
|
||||
// High resolution fonts are instead drawn on a texture which has the
|
||||
// size of the screen, and the scaling directly controls their pixels size.
|
||||
// Those are slower to render but are not pixelated.
|
||||
property ListModel fontlist: ListModel {
|
||||
ListElement {
|
||||
name: "TERMINUS_SCALED"
|
||||
text: "Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "PRO_FONT_SCALED"
|
||||
text: "Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 12
|
||||
baseScaling: 3.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "EXCELSIOR_SCALED"
|
||||
text: "Fixedsys Excelsior (Modern)"
|
||||
source: "fonts/modern-fixedsys-excelsior/FSEX301-L2.ttf"
|
||||
lineSpacing: 0
|
||||
pixelSize: 16
|
||||
baseScaling: 2.4
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "COMMODORE_PET_SCALED"
|
||||
text: "Commodore PET (1977)"
|
||||
source: "fonts/1977-commodore-pet/PetMe.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "PROGGY_TINY_SCALED"
|
||||
text: "Proggy Tiny (Modern)"
|
||||
source: "fonts/modern-proggy-tiny/ProggyTiny.ttf"
|
||||
lineSpacing: 1
|
||||
pixelSize: 16
|
||||
baseScaling: 3.3
|
||||
fontWidth: 0.9
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "APPLE_II_SCALED"
|
||||
text: "Apple ][ (1977)"
|
||||
source: "fonts/1977-apple2/PrintChar21.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "ATARI_400_SCALED"
|
||||
text: "Atari 400-800 (1979)"
|
||||
source: "fonts/1979-atari-400-800/AtariClassic-Regular.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "IBM_PC_SCALED"
|
||||
text: "IBM PC (1981)"
|
||||
source: "fonts/1981-ibm-pc/PxPlus_IBM_BIOS.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.8
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "COMMODORE_64_SCALED"
|
||||
text: "Commodore 64 (1982)"
|
||||
source: "fonts/1982-commodore64/C64_Pro_Mono-STYLE.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 8
|
||||
baseScaling: 3.5
|
||||
fontWidth: 0.7
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "IBM_DOS"
|
||||
text: "IBM DOS (1985)"
|
||||
source: "fonts/1985-ibm-pc-vga/PxPlus_IBM_VGA8.ttf"
|
||||
lineSpacing: 3
|
||||
pixelSize: 16
|
||||
baseScaling: 2.0
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: true
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "HERMIT"
|
||||
text: "HD: Hermit (Modern)"
|
||||
source: "fonts/modern-hermit/Hermit-medium.otf"
|
||||
lineSpacing: 0.05
|
||||
pixelSize: 27
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "TERMINUS"
|
||||
text: "HD: Terminus (Modern)"
|
||||
source: "fonts/modern-terminus/TerminusTTF-4.46.0.ttf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "PRO_FONT"
|
||||
text: "HD: Pro Font (Modern)"
|
||||
source: "fonts/modern-pro-font-win-tweaked/ProFontWindows.ttf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "INCONSOLATA"
|
||||
text: "HD: Inconsolata (Modern)"
|
||||
source: "fonts/modern-inconsolata/Inconsolata.otf"
|
||||
lineSpacing: 0.1
|
||||
pixelSize: 35
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
ListElement {
|
||||
name: "IBM_3278"
|
||||
text: "HD: IBM 3278 (1971)"
|
||||
source: "fonts/1971-ibm-3278/3270-Regular.ttf"
|
||||
lineSpacing: 0.2
|
||||
pixelSize: 32
|
||||
fontWidth: 1.0
|
||||
lowResolutionFont: false
|
||||
isSystemFont: false
|
||||
family: ""
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: addSystemFonts()
|
||||
|
||||
function addSystemFonts() {
|
||||
var families = monospaceSystemFonts
|
||||
for (var i = 0; i < families.length; i++) {
|
||||
if (verbose) {
|
||||
console.log("Adding system font: ", families[i])
|
||||
}
|
||||
fontlist.append(convertToListElement(families[i]))
|
||||
}
|
||||
}
|
||||
|
||||
function convertToListElement(family) {
|
||||
return {
|
||||
"name": "System: " + family,
|
||||
"text": qsTr("System: ") + family,
|
||||
"source": "",
|
||||
"lineSpacing": 0.1,
|
||||
"pixelSize": 30,
|
||||
"fontWidth": 1.0,
|
||||
"baseScaling": 1.0,
|
||||
"lowResolutionFont": false,
|
||||
"isSystemFont": true,
|
||||
"family": family
|
||||
}
|
||||
}
|
||||
}
|
93
app/qml/InsertNameDialog.qml
Normal file
93
app/qml/InsertNameDialog.qml
Normal file
@ -0,0 +1,93 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Window {
|
||||
id: insertnamedialog
|
||||
width: 400
|
||||
height: 100
|
||||
modality: Qt.ApplicationModal
|
||||
title: qsTr("Save new profile")
|
||||
|
||||
property alias profileName: namefield.text
|
||||
signal nameSelected(string name)
|
||||
|
||||
MessageDialog {
|
||||
id: errorDialog
|
||||
title: qsTr("Error")
|
||||
visible: false
|
||||
|
||||
function showError(message) {
|
||||
text = message
|
||||
open()
|
||||
}
|
||||
}
|
||||
|
||||
function validateName(name) {
|
||||
var profile_list = appSettings.profilesList
|
||||
if (name === "")
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.margins: 10
|
||||
anchors.fill: parent
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Name")
|
||||
}
|
||||
TextField {
|
||||
id: namefield
|
||||
Layout.fillWidth: true
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
onAccepted: okbutton.clickAction()
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
||||
Button {
|
||||
id: okbutton
|
||||
text: qsTr("OK")
|
||||
onClicked: clickAction()
|
||||
function clickAction() {
|
||||
var name = namefield.text
|
||||
switch (validateName(name)) {
|
||||
case 1:
|
||||
errorDialog.showError(
|
||||
qsTr("The name you inserted is empty. Please choose a different one."))
|
||||
break
|
||||
default:
|
||||
nameSelected(name)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
onClicked: close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
286
app/qml/PreprocessedTerminal.qml
Normal file
286
app/qml/PreprocessedTerminal.qml
Normal file
@ -0,0 +1,286 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
import QMLTermWidget 1.0
|
||||
|
||||
import "menus"
|
||||
import "utils.js" as Utils
|
||||
|
||||
Item{
|
||||
id: terminalContainer
|
||||
|
||||
property size virtualResolution: Qt.size(kterminal.totalWidth, kterminal.totalHeight)
|
||||
property alias mainTerminal: kterminal
|
||||
|
||||
property ShaderEffectSource mainSource: kterminalSource
|
||||
property BurnInEffect burnInEffect: burnInEffect
|
||||
property real fontWidth: 1.0
|
||||
property real screenScaling: 1.0
|
||||
property real scaleTexture: 1.0
|
||||
property alias title: ksession.title
|
||||
property alias kterminal: kterminal
|
||||
|
||||
property size terminalSize: kterminal.terminalSize
|
||||
property size fontMetrics: kterminal.fontMetrics
|
||||
|
||||
// Manage copy and paste
|
||||
Connections {
|
||||
target: copyAction
|
||||
|
||||
onTriggered: {
|
||||
kterminal.copyClipboard()
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: pasteAction
|
||||
|
||||
onTriggered: {
|
||||
kterminal.pasteClipboard()
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: pasteActionAlt
|
||||
|
||||
onTriggered: {
|
||||
kterminal.pasteSelection()
|
||||
}
|
||||
}
|
||||
|
||||
//When settings are updated sources need to be redrawn.
|
||||
Connections {
|
||||
target: appSettings
|
||||
|
||||
onFontScalingChanged: {
|
||||
terminalContainer.updateSources()
|
||||
}
|
||||
|
||||
onFontWidthChanged: {
|
||||
terminalContainer.updateSources()
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: terminalContainer
|
||||
|
||||
onWidthChanged: {
|
||||
terminalContainer.updateSources()
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
terminalContainer.updateSources()
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: terminalWindow
|
||||
|
||||
onActiveChanged: {
|
||||
kterminal.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
function updateSources() {
|
||||
kterminal.update()
|
||||
}
|
||||
|
||||
QMLTermWidget {
|
||||
id: kterminal
|
||||
|
||||
property int textureResolutionScale: appSettings.lowResolutionFont ? devicePixelRatio : 1
|
||||
property int margin: appSettings.totalMargin / screenScaling
|
||||
property int totalWidth: Math.floor(parent.width / (screenScaling * fontWidth))
|
||||
property int totalHeight: Math.floor(parent.height / screenScaling)
|
||||
|
||||
property int rawWidth: totalWidth - 2 * margin
|
||||
property int rawHeight: totalHeight - 2 * margin
|
||||
|
||||
textureSize: Qt.size(width / textureResolutionScale, height / textureResolutionScale)
|
||||
|
||||
width: ensureMultiple(rawWidth, devicePixelRatio)
|
||||
height: ensureMultiple(rawHeight, devicePixelRatio)
|
||||
|
||||
/** Ensure size is a multiple of factor. This is needed for pixel perfect scaling on highdpi screens. */
|
||||
function ensureMultiple(size, factor) {
|
||||
return Math.round(size / factor) * factor;
|
||||
}
|
||||
|
||||
colorScheme: "cool-retro-term"
|
||||
|
||||
smooth: !appSettings.lowResolutionFont
|
||||
enableBold: false
|
||||
fullCursorHeight: true
|
||||
blinkingCursor: appSettings.blinkingCursor
|
||||
|
||||
session: QMLTermSession {
|
||||
id: ksession
|
||||
|
||||
onFinished: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
|
||||
QMLTermScrollbar {
|
||||
id: kterminalScrollbar
|
||||
terminal: kterminal
|
||||
anchors.margins: width * 0.5
|
||||
width: terminal.fontMetrics.width * 0.75
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 1
|
||||
anchors.bottomMargin: 1
|
||||
color: "white"
|
||||
radius: width * 0.25
|
||||
opacity: 0.7
|
||||
}
|
||||
}
|
||||
|
||||
function handleFontChanged(fontFamily, pixelSize, lineSpacing, screenScaling, fontWidth) {
|
||||
kterminal.antialiasText = !appSettings.lowResolutionFont;
|
||||
font.pixelSize = pixelSize;
|
||||
font.family = fontFamily;
|
||||
|
||||
terminalContainer.fontWidth = fontWidth;
|
||||
terminalContainer.screenScaling = screenScaling;
|
||||
scaleTexture = Math.max(1.0, Math.floor(screenScaling * appSettings.windowScaling));
|
||||
|
||||
kterminal.lineSpacing = lineSpacing;
|
||||
}
|
||||
|
||||
function startSession() {
|
||||
appSettings.initializedSettings.disconnect(startSession);
|
||||
|
||||
// Retrieve the variable set in main.cpp if arguments are passed.
|
||||
if (defaultCmd) {
|
||||
ksession.setShellProgram(defaultCmd);
|
||||
ksession.setArgs(defaultCmdArgs);
|
||||
} else if (appSettings.useCustomCommand) {
|
||||
var args = Utils.tokenizeCommandLine(appSettings.customCommand);
|
||||
ksession.setShellProgram(args[0]);
|
||||
ksession.setArgs(args.slice(1));
|
||||
} else if (!defaultCmd && appSettings.isMacOS) {
|
||||
// OSX Requires the following default parameters for auto login.
|
||||
ksession.setArgs(["-i", "-l"]);
|
||||
}
|
||||
|
||||
if (workdir)
|
||||
ksession.initialWorkingDirectory = workdir;
|
||||
|
||||
ksession.startShellProgram();
|
||||
forceActiveFocus();
|
||||
}
|
||||
Component.onCompleted: {
|
||||
appSettings.terminalFontChanged.connect(handleFontChanged);
|
||||
appSettings.initializedSettings.connect(startSession);
|
||||
appSettings.handleFontChanged()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: shortContextMenu
|
||||
ShortContextMenu { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: fullContextMenu
|
||||
FullContextMenu { }
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: menuLoader
|
||||
sourceComponent: (appSettings.isMacOS || appSettings.showMenubar ? shortContextMenu : fullContextMenu)
|
||||
}
|
||||
property alias contextmenu: menuLoader.item
|
||||
|
||||
MouseArea {
|
||||
property real margin: appSettings.totalMargin
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
|
||||
anchors.fill: parent
|
||||
cursorShape: kterminal.terminalUsesMouse ? Qt.ArrowCursor : Qt.IBeamCursor
|
||||
onWheel:{
|
||||
if(wheel.modifiers & Qt.ControlModifier){
|
||||
wheel.angleDelta.y > 0 ? zoomIn.trigger() : zoomOut.trigger();
|
||||
} else {
|
||||
var coord = correctDistortion(wheel.x, wheel.y);
|
||||
kterminal.simulateWheel(coord.x, coord.y, wheel.buttons, wheel.modifiers, wheel.angleDelta);
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseDoubleClick(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
onPressed: {
|
||||
if((!kterminal.terminalUsesMouse || mouse.modifiers & Qt.ShiftModifier) && mouse.button == Qt.RightButton) {
|
||||
contextmenu.popup();
|
||||
} else {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMousePress(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers)
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseRelease(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
onPositionChanged: {
|
||||
var coord = correctDistortion(mouse.x, mouse.y);
|
||||
kterminal.simulateMouseMove(coord.x, coord.y, mouse.button, mouse.buttons, mouse.modifiers);
|
||||
}
|
||||
|
||||
function correctDistortion(x, y){
|
||||
x = (x - margin) / width;
|
||||
y = (y - margin) / height;
|
||||
|
||||
var cc = Qt.size(0.5 - x, 0.5 - y);
|
||||
var distortion = (cc.height * cc.height + cc.width * cc.width) * appSettings.screenCurvature * appSettings.screenCurvatureSize;
|
||||
|
||||
return Qt.point((x - cc.width * (1+distortion) * distortion) * (kterminal.totalWidth),
|
||||
(y - cc.height * (1+distortion) * distortion) * (kterminal.totalHeight))
|
||||
}
|
||||
}
|
||||
ShaderEffectSource{
|
||||
id: kterminalSource
|
||||
sourceItem: kterminal
|
||||
hideSource: true
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
visible: false
|
||||
textureSize: Qt.size(kterminal.totalWidth * scaleTexture, kterminal.totalHeight * scaleTexture)
|
||||
sourceRect: Qt.rect(-kterminal.margin, -kterminal.margin, kterminal.totalWidth, kterminal.totalHeight)
|
||||
}
|
||||
|
||||
Item {
|
||||
id: burnInContainer
|
||||
|
||||
property int burnInScaling: scaleTexture * appSettings.burnInQuality
|
||||
|
||||
width: Math.round(appSettings.lowResolutionFont
|
||||
? kterminal.totalWidth * Math.max(1, burnInScaling)
|
||||
: kterminal.totalWidth * scaleTexture * appSettings.burnInQuality)
|
||||
|
||||
height: Math.round(appSettings.lowResolutionFont
|
||||
? kterminal.totalHeight * Math.max(1, burnInScaling)
|
||||
: kterminal.totalHeight * scaleTexture * appSettings.burnInQuality)
|
||||
|
||||
|
||||
BurnInEffect {
|
||||
id: burnInEffect
|
||||
}
|
||||
}
|
||||
}
|
159
app/qml/SettingsAdvancedTab.qml
Normal file
159
app/qml/SettingsAdvancedTab.qml
Normal file
@ -0,0 +1,159 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQml 2.0
|
||||
|
||||
import "Components"
|
||||
|
||||
ColumnLayout {
|
||||
GroupBox {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Command")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
CheckBox {
|
||||
id: useCustomCommand
|
||||
text: qsTr("Use custom command instead of shell at startup")
|
||||
checked: appSettings.useCustomCommand
|
||||
onCheckedChanged: appSettings.useCustomCommand = checked
|
||||
}
|
||||
// Workaround for QTBUG-31627 for pre 5.3.0
|
||||
Binding {
|
||||
target: useCustomCommand
|
||||
property: "checked"
|
||||
value: appSettings.useCustomCommand
|
||||
}
|
||||
TextField {
|
||||
id: customCommand
|
||||
Layout.fillWidth: true
|
||||
text: appSettings.customCommand
|
||||
enabled: useCustomCommand.checked
|
||||
onEditingFinished: appSettings.customCommand = text
|
||||
|
||||
// Save text even if user forgets to press enter or unfocus
|
||||
function saveSetting() {
|
||||
appSettings.customCommand = text
|
||||
}
|
||||
Component.onCompleted: settings_window.closing.connect(
|
||||
saveSetting)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Performance")
|
||||
Layout.fillWidth: true
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columns: 4
|
||||
|
||||
Label {
|
||||
text: qsTr("Effects FPS")
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
id: fpsSlider
|
||||
onValueChanged: {
|
||||
if (enabled) {
|
||||
appSettings.fps = value !== 60 ? value + 1 : 0
|
||||
}
|
||||
}
|
||||
stepSize: 1
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
from = 0
|
||||
to = 60
|
||||
value = appSettings.fps !== 0 ? appSettings.fps - 1 : 60
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
SizedLabel {
|
||||
text: appSettings.fps !== 0 ? appSettings.fps : qsTr("Max")
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Texture Quality")
|
||||
}
|
||||
Slider {
|
||||
id: txtslider
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
onValueChanged: if (enabled)
|
||||
appSettings.windowScaling = value
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
from = 0.25 //Without this value gets set to 0.5
|
||||
value = appSettings.windowScaling
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(txtslider.value * 100) + "%"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Bloom Quality")
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
id: bloomSlider
|
||||
onValueChanged: if (enabled)
|
||||
appSettings.bloomQuality = value
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
from = 0.25
|
||||
value = appSettings.bloomQuality
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(bloomSlider.value * 100) + "%"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("BurnIn Quality")
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
id: burnInSlider
|
||||
Layout.columnSpan: 2
|
||||
onValueChanged: if (enabled)
|
||||
appSettings.burnInQuality = value
|
||||
stepSize: 0.05
|
||||
enabled: false
|
||||
Component.onCompleted: {
|
||||
from = 0.25
|
||||
value = appSettings.burnInQuality
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(burnInSlider.value * 100) + "%"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
87
app/qml/SettingsEffectsTab.qml
Normal file
87
app/qml/SettingsEffectsTab.qml
Normal file
@ -0,0 +1,87 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 2
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Effects")
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
CheckableSlider {
|
||||
name: qsTr("Bloom")
|
||||
onNewValue: appSettings.bloom = newValue
|
||||
value: appSettings.bloom
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("BurnIn")
|
||||
onNewValue: appSettings.burnIn = newValue
|
||||
value: appSettings.burnIn
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Static Noise")
|
||||
onNewValue: appSettings.staticNoise = newValue
|
||||
value: appSettings.staticNoise
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Jitter")
|
||||
onNewValue: appSettings.jitter = newValue
|
||||
value: appSettings.jitter
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Glow Line")
|
||||
onNewValue: appSettings.glowingLine = newValue
|
||||
value: appSettings.glowingLine
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Screen Curvature")
|
||||
onNewValue: appSettings.screenCurvature = newValue
|
||||
value: appSettings.screenCurvature
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Ambient Light")
|
||||
onNewValue: appSettings.ambientLight = newValue
|
||||
value: appSettings.ambientLight
|
||||
enabled: appSettings.framesIndex !== 0
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Flickering")
|
||||
onNewValue: appSettings.flickering = newValue
|
||||
value: appSettings.flickering
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Horizontal Sync")
|
||||
onNewValue: appSettings.horizontalSync = newValue
|
||||
value: appSettings.horizontalSync
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("RGB Shift")
|
||||
onNewValue: appSettings.rbgShift = newValue
|
||||
value: appSettings.rbgShift
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
268
app/qml/SettingsGeneralTab.qml
Normal file
268
app/qml/SettingsGeneralTab.qml
Normal file
@ -0,0 +1,268 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.4
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
ColumnLayout {
|
||||
GroupBox {
|
||||
Layout.fillWidth: true
|
||||
title: qsTr("Profile")
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
ListView {
|
||||
id: profilesView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: appSettings.profilesList
|
||||
clip: true
|
||||
delegate: Rectangle {
|
||||
width: label.width
|
||||
height: label.height
|
||||
color: (index == profilesView.currentIndex) ? palette.highlight : palette.base
|
||||
Label {
|
||||
id: label
|
||||
text: appSettings.profilesList.get(index).text
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: profilesView.currentIndex = index
|
||||
onDoubleClicked: appSettings.loadProfile(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Save")
|
||||
onClicked: {
|
||||
insertname.profileName = ""
|
||||
insertname.show()
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
property alias currentIndex: profilesView.currentIndex
|
||||
enabled: currentIndex >= 0
|
||||
text: qsTr("Load")
|
||||
onClicked: {
|
||||
var index = currentIndex
|
||||
if (index >= 0)
|
||||
appSettings.loadProfile(index)
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Remove")
|
||||
property alias currentIndex: profilesView.currentIndex
|
||||
|
||||
enabled: currentIndex >= 0 && !appSettings.profilesList.get(
|
||||
currentIndex).builtin
|
||||
onClicked: {
|
||||
appSettings.profilesList.remove(currentIndex)
|
||||
profilesView.selection.clear()
|
||||
|
||||
// TODO This is a very ugly workaround. The view didn't update on Qt 5.3.2.
|
||||
profilesView.model = 0
|
||||
profilesView.model = appSettings.profilesList
|
||||
}
|
||||
}
|
||||
Item {
|
||||
// Spacing
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Import")
|
||||
onClicked: {
|
||||
fileDialog.selectExisting = true
|
||||
fileDialog.callBack = function (url) {
|
||||
loadFile(url)
|
||||
}
|
||||
fileDialog.open()
|
||||
}
|
||||
function loadFile(url) {
|
||||
try {
|
||||
if (appSettings.verbose)
|
||||
console.log("Loading file: " + url)
|
||||
|
||||
var profileObject = JSON.parse(fileIO.read(url))
|
||||
var name = profileObject.name
|
||||
|
||||
if (!name)
|
||||
throw "Profile doesn't have a name"
|
||||
|
||||
var version = profileObject.version
|
||||
!== undefined ? profileObject.version : 1
|
||||
if (version !== appSettings.profileVersion)
|
||||
throw "This profile is not supported on this version of CRT."
|
||||
|
||||
delete profileObject.name
|
||||
|
||||
appSettings.appendCustomProfile(name,
|
||||
JSON.stringify(
|
||||
profileObject))
|
||||
} catch (err) {
|
||||
messageDialog.text = qsTr(err)
|
||||
messageDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
property alias currentIndex: profilesView.currentIndex
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Export")
|
||||
enabled: currentIndex >= 0 && !appSettings.profilesList.get(
|
||||
currentIndex).builtin
|
||||
onClicked: {
|
||||
fileDialog.selectExisting = false
|
||||
fileDialog.callBack = function (url) {
|
||||
storeFile(url)
|
||||
}
|
||||
fileDialog.open()
|
||||
}
|
||||
function storeFile(url) {
|
||||
try {
|
||||
var urlString = url.toString()
|
||||
|
||||
// Fix the extension if it's missing.
|
||||
var extension = urlString.substring(
|
||||
urlString.length - 5, urlString.length)
|
||||
var urlTail = (extension === ".json" ? "" : ".json")
|
||||
url += urlTail
|
||||
|
||||
if (true)
|
||||
console.log("Storing file: " + url)
|
||||
|
||||
var profileObject = appSettings.profilesList.get(
|
||||
currentIndex)
|
||||
var profileSettings = JSON.parse(
|
||||
profileObject.obj_string)
|
||||
profileSettings["name"] = profileObject.text
|
||||
profileSettings["version"] = appSettings.profileVersion
|
||||
|
||||
var result = fileIO.write(url, JSON.stringify(
|
||||
profileSettings,
|
||||
undefined, 2))
|
||||
if (!result)
|
||||
throw "The file could not be written."
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
messageDialog.text = qsTr(
|
||||
"There has been an error storing the file.")
|
||||
messageDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Screen")
|
||||
Layout.fillWidth: true
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Label {
|
||||
text: qsTr("Brightness")
|
||||
}
|
||||
SimpleSlider {
|
||||
onValueChanged: appSettings.brightness = value
|
||||
value: appSettings.brightness
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Contrast")
|
||||
}
|
||||
SimpleSlider {
|
||||
onValueChanged: appSettings.contrast = value
|
||||
value: appSettings.contrast
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Margin")
|
||||
}
|
||||
SimpleSlider {
|
||||
onValueChanged: appSettings._margin = value
|
||||
value: appSettings._margin
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Frame size")
|
||||
}
|
||||
SimpleSlider {
|
||||
onValueChanged: appSettings._frameMargin = value
|
||||
value: appSettings._frameMargin
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Opacity")
|
||||
visible: !appSettings.isMacOS
|
||||
}
|
||||
SimpleSlider {
|
||||
onValueChanged: appSettings.windowOpacity = value
|
||||
value: appSettings.windowOpacity
|
||||
visible: !appSettings.isMacOS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DIALOGS ////////////////////////////////////////////////////////////////
|
||||
InsertNameDialog {
|
||||
id: insertname
|
||||
onNameSelected: {
|
||||
appSettings.appendCustomProfile(name,
|
||||
appSettings.composeProfileString())
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: messageDialog
|
||||
title: qsTr("File Error")
|
||||
onAccepted: {
|
||||
messageDialog.close()
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
property var callBack
|
||||
property bool selectExisting: false
|
||||
id: fileDialog
|
||||
|
||||
sourceComponent: FileDialog {
|
||||
nameFilters: ["Json files (*.json)"]
|
||||
selectMultiple: false
|
||||
selectFolder: false
|
||||
selectExisting: fileDialog.selectExisting
|
||||
onAccepted: callBack(fileUrl)
|
||||
}
|
||||
|
||||
onSelectExistingChanged: reload()
|
||||
|
||||
function open() {
|
||||
item.open()
|
||||
}
|
||||
|
||||
function reload() {
|
||||
active = false
|
||||
active = true
|
||||
}
|
||||
}
|
||||
}
|
184
app/qml/SettingsTerminalTab.qml
Normal file
184
app/qml/SettingsTerminalTab.qml
Normal file
@ -0,0 +1,184 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQml 2.0
|
||||
|
||||
import "Components"
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Font")
|
||||
Layout.fillWidth: true
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columns: 2
|
||||
Label {
|
||||
text: qsTr("Rasterization")
|
||||
}
|
||||
ComboBox {
|
||||
id: rasterizationBox
|
||||
|
||||
property string selectedElement: model[currentIndex]
|
||||
|
||||
Layout.fillWidth: true
|
||||
model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels"), qsTr("Sub-Pixels")]
|
||||
currentIndex: appSettings.rasterization
|
||||
onCurrentIndexChanged: {
|
||||
appSettings.rasterization = currentIndex
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Name")
|
||||
}
|
||||
ComboBox {
|
||||
id: fontChanger
|
||||
Layout.fillWidth: true
|
||||
model: appSettings.fontlist
|
||||
textRole: "text"
|
||||
onActivated: {
|
||||
var name = appSettings.fontlist.get(index).name
|
||||
appSettings.fontNames[appSettings.rasterization] = name
|
||||
appSettings.handleFontChanged()
|
||||
}
|
||||
function updateIndex() {
|
||||
var name = appSettings.fontNames[appSettings.rasterization]
|
||||
var index = appSettings.getIndexByName(name)
|
||||
if (index !== undefined)
|
||||
currentIndex = index
|
||||
}
|
||||
Connections {
|
||||
target: appSettings
|
||||
|
||||
onTerminalFontChanged: {
|
||||
fontChanger.updateIndex()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: updateIndex()
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Scaling")
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
id: fontScalingChanger
|
||||
onValueChanged: appSettings.fontScaling = value
|
||||
value: appSettings.fontScaling
|
||||
stepSize: 0.05
|
||||
from: appSettings.minimumFontScaling
|
||||
to: appSettings.maximumFontScaling
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(fontScalingChanger.value * 100) + "%"
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Font Width")
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
id: widthChanger
|
||||
onValueChanged: appSettings.fontWidth = value
|
||||
value: appSettings.fontWidth
|
||||
stepSize: 0.05
|
||||
from: 0.5
|
||||
to: 1.5
|
||||
}
|
||||
SizedLabel {
|
||||
text: Math.round(widthChanger.value * 100) + "%"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox {
|
||||
title: qsTr("Cursor")
|
||||
Layout.fillWidth: true
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
CheckBox {
|
||||
id: blinkingCursor
|
||||
text: qsTr("Blinking Cursor")
|
||||
checked: appSettings.blinkingCursor
|
||||
onCheckedChanged: appSettings.blinkingCursor = checked
|
||||
}
|
||||
Binding {
|
||||
target: blinkingCursor
|
||||
property: "checked"
|
||||
value: appSettings.blinkingCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
GroupBox {
|
||||
title: qsTr("Colors")
|
||||
Layout.fillWidth: true
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
CheckableSlider {
|
||||
name: qsTr("Chroma Color")
|
||||
onNewValue: appSettings.chromaColor = newValue
|
||||
value: appSettings.chromaColor
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Saturation Color")
|
||||
onNewValue: appSettings.saturationColor = newValue
|
||||
value: appSettings.saturationColor
|
||||
enabled: appSettings.chromaColor !== 0
|
||||
}
|
||||
CheckableSlider {
|
||||
name: qsTr("Frame Gloss")
|
||||
onNewValue: appSettings.frameGloss = newValue
|
||||
value: appSettings.frameGloss
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
ColorButton {
|
||||
name: qsTr("Font")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: appSettings._fontColor = color
|
||||
color: appSettings._fontColor
|
||||
}
|
||||
ColorButton {
|
||||
name: qsTr("Background")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: appSettings._backgroundColor = color
|
||||
color: appSettings._backgroundColor
|
||||
}
|
||||
ColorButton {
|
||||
name: qsTr("Frame")
|
||||
height: 50
|
||||
Layout.fillWidth: true
|
||||
onColorSelected: appSettings._frameColor = color
|
||||
color: appSettings._frameColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
app/qml/SettingsWindow.qml
Normal file
75
app/qml/SettingsWindow.qml
Normal file
@ -0,0 +1,75 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Dialogs 1.1
|
||||
|
||||
Window {
|
||||
id: settings_window
|
||||
title: qsTr("Settings")
|
||||
width: 640
|
||||
height: 640
|
||||
|
||||
property int tabmargins: 15
|
||||
|
||||
Item {
|
||||
anchors { fill: parent; margins: tabmargins }
|
||||
|
||||
TabBar {
|
||||
id: bar
|
||||
anchors { left: parent.left; right: parent.right; top: parent.top; }
|
||||
TabButton {
|
||||
text: qsTr("General")
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Terminal")
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Effects")
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Advanced")
|
||||
}
|
||||
}
|
||||
|
||||
Frame {
|
||||
anchors {
|
||||
top: bar.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
currentIndex: bar.currentIndex
|
||||
|
||||
SettingsGeneralTab { }
|
||||
SettingsTerminalTab { }
|
||||
SettingsEffectsTab { }
|
||||
SettingsAdvancedTab { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
app/qml/ShaderLibrary.qml
Normal file
91
app/qml/ShaderLibrary.qml
Normal file
@ -0,0 +1,91 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
QtObject {
|
||||
property string rasterizationShader:
|
||||
(appSettings.rasterization === appSettings.no_rasterization ? "
|
||||
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
|
||||
return texel;
|
||||
}" : "") +
|
||||
|
||||
(appSettings.rasterization === appSettings.scanline_rasterization ? "
|
||||
#define INTENSITY 0.30
|
||||
#define BRIGHTBOOST 0.30
|
||||
|
||||
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
|
||||
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
|
||||
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
|
||||
|
||||
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
|
||||
lowp float mask = 1.0 - abs(coords.y);
|
||||
|
||||
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
|
||||
return mix(texel, rasterizationColor, intensity);
|
||||
}" : "") +
|
||||
|
||||
(appSettings.rasterization === appSettings.pixel_rasterization ? "
|
||||
#define INTENSITY 0.30
|
||||
#define BRIGHTBOOST 0.30
|
||||
|
||||
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
|
||||
lowp vec3 result = texel;
|
||||
|
||||
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * texel)) * texel;
|
||||
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * texel)) * texel;
|
||||
|
||||
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
|
||||
coords = coords * coords;
|
||||
lowp float mask = 1.0 - coords.x - coords.y;
|
||||
|
||||
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
|
||||
return mix(texel, rasterizationColor, intensity);
|
||||
}" : "") +
|
||||
|
||||
(appSettings.rasterization === appSettings.subpixel_rasterization ? "
|
||||
#define INTENSITY 0.30
|
||||
#define BRIGHTBOOST 0.30
|
||||
#define SUBPIXELS 3.0
|
||||
const vec3 offsets = vec3(3.141592654) * vec3(1.0/2.0,1.0/2.0 - 2.0/3.0,1.0/2.0-4.0/3.0);
|
||||
|
||||
lowp vec3 applyRasterization(vec2 screenCoords, lowp vec3 texel, vec2 virtualResolution, float intensity) {
|
||||
vec2 omega = vec2(3.141592654) * vec2(2.0) * virtualResolution;
|
||||
vec2 angle = screenCoords * omega;
|
||||
vec3 xfactors = (SUBPIXELS + sin(angle.x + offsets)) / (SUBPIXELS + 1.0);
|
||||
|
||||
lowp vec3 result = texel * xfactors;
|
||||
lowp vec3 pixelHigh = ((1.0 + BRIGHTBOOST) - (0.2 * result)) * result;
|
||||
lowp vec3 pixelLow = ((1.0 - INTENSITY) + (0.1 * result)) * result;
|
||||
|
||||
vec2 coords = fract(screenCoords * virtualResolution) * 2.0 - vec2(1.0);
|
||||
lowp float mask = 1.0 - abs(coords.y);
|
||||
|
||||
lowp vec3 rasterizationColor = mix(pixelLow, pixelHigh, mask);
|
||||
return mix(texel, rasterizationColor, intensity);
|
||||
}" : "") +
|
||||
|
||||
"\n\n"
|
||||
|
||||
property string min2: "
|
||||
float min2(vec2 v) {
|
||||
return min(v.x, v.y);
|
||||
}\n\n"
|
||||
|
||||
property string rgb2grey: "
|
||||
float rgb2grey(vec3 v) {
|
||||
return dot(v, vec3(0.21, 0.72, 0.04));
|
||||
}\n\n"
|
||||
|
||||
property string max2: "
|
||||
float max2(vec2 v) {
|
||||
return max(v.x, v.y);
|
||||
}\n\n"
|
||||
|
||||
property string prod2: "
|
||||
float prod2(vec2 v) {
|
||||
return v.x * v.y;
|
||||
}\n\n"
|
||||
|
||||
property string sum2: "
|
||||
float sum2(vec2 v) {
|
||||
return v.x + v.y;
|
||||
}\n\n"
|
||||
}
|
532
app/qml/ShaderTerminal.qml
Normal file
532
app/qml/ShaderTerminal.qml
Normal file
@ -0,0 +1,532 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
Item {
|
||||
property ShaderEffectSource source
|
||||
property BurnInEffect burnInEffect
|
||||
property ShaderEffectSource bloomSource
|
||||
|
||||
property color fontColor: appSettings.fontColor
|
||||
property color backgroundColor: appSettings.backgroundColor
|
||||
|
||||
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize
|
||||
|
||||
property real chromaColor: appSettings.chromaColor
|
||||
|
||||
property real ambientLight: appSettings.ambientLight * 0.2
|
||||
|
||||
property real frameGloss: appSettings.frameGloss
|
||||
|
||||
property size virtualResolution
|
||||
property size screenResolution
|
||||
|
||||
property real _screenDensity: Math.min(
|
||||
screenResolution.width / virtualResolution.width,
|
||||
screenResolution.height / virtualResolution.height
|
||||
)
|
||||
|
||||
ShaderEffect {
|
||||
id: dynamicShader
|
||||
|
||||
property ShaderLibrary shaderLibrary: ShaderLibrary { }
|
||||
|
||||
property ShaderEffectSource screenBuffer: frameBuffer
|
||||
property ShaderEffectSource burnInSource: burnInEffect.source
|
||||
property ShaderEffectSource frameSource: terminalFrameLoader.item
|
||||
|
||||
property color fontColor: parent.fontColor
|
||||
property color backgroundColor: parent.backgroundColor
|
||||
property real screenCurvature: parent.screenCurvature
|
||||
property real chromaColor: parent.chromaColor
|
||||
property real ambientLight: parent.ambientLight
|
||||
property real frameGloss: parent.frameGloss
|
||||
|
||||
property real flickering: appSettings.flickering
|
||||
property real horizontalSync: appSettings.horizontalSync
|
||||
property real horizontalSyncStrength: Utils.lint(0.05, 0.35, horizontalSync)
|
||||
property real glowingLine: appSettings.glowingLine * 0.2
|
||||
|
||||
// Fast burnin properties
|
||||
property real burnIn: appSettings.burnIn
|
||||
property real burnInLastUpdate: burnInEffect.lastUpdate
|
||||
property real burnInTime: burnInEffect.burnInFadeTime
|
||||
|
||||
property real jitter: appSettings.jitter
|
||||
property size jitterDisplacement: Qt.size(0.007 * jitter, 0.002 * jitter)
|
||||
property real shadowLength: 0.25 * screenCurvature * Utils.lint(0.50, 1.5, ambientLight)
|
||||
property real staticNoise: appSettings.staticNoise
|
||||
property size scaleNoiseSize: Qt.size((width * 0.75) / (noiseTexture.width * appSettings.windowScaling * appSettings.totalFontScaling),
|
||||
(height * 0.75) / (noiseTexture.height * appSettings.windowScaling * appSettings.totalFontScaling))
|
||||
|
||||
property size virtualResolution: parent.virtualResolution
|
||||
|
||||
// Rasterization might display oversamping issues if virtual resolution is close to physical display resolution.
|
||||
// We progressively disable rasterization from 4x up to 2x resolution.
|
||||
property real rasterizationIntensity: Utils.smoothstep(2.0, 4.0, _screenDensity)
|
||||
|
||||
property real displayTerminalFrame: appSettings._frameMargin > 0 || appSettings.screenCurvature > 0
|
||||
|
||||
property real time: timeManager.time
|
||||
property ShaderEffectSource noiseSource: noiseShaderSource
|
||||
|
||||
// If something goes wrong activate the fallback version of the shader.
|
||||
property bool fallBack: false
|
||||
|
||||
anchors.fill: parent
|
||||
blending: false
|
||||
|
||||
//Smooth random texture used for flickering effect.
|
||||
Image {
|
||||
id: noiseTexture
|
||||
source: "images/allNoise512.png"
|
||||
width: 512
|
||||
height: 512
|
||||
fillMode: Image.Tile
|
||||
visible: false
|
||||
}
|
||||
ShaderEffectSource {
|
||||
id: noiseShaderSource
|
||||
sourceItem: noiseTexture
|
||||
wrapMode: ShaderEffectSource.Repeat
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
//Print the number with a reasonable precision for the shader.
|
||||
function str(num){
|
||||
return num.toFixed(8);
|
||||
}
|
||||
|
||||
vertexShader: "
|
||||
uniform highp mat4 qt_Matrix;
|
||||
uniform highp float time;
|
||||
|
||||
attribute highp vec4 qt_Vertex;
|
||||
attribute highp vec2 qt_MultiTexCoord0;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;" +
|
||||
|
||||
(!fallBack ? "
|
||||
uniform sampler2D noiseSource;" : "") +
|
||||
|
||||
(!fallBack && flickering !== 0.0 ?"
|
||||
varying lowp float brightness;
|
||||
uniform lowp float flickering;" : "") +
|
||||
|
||||
(!fallBack && horizontalSync !== 0.0 ?"
|
||||
uniform lowp float horizontalSyncStrength;
|
||||
varying lowp float distortionScale;
|
||||
varying lowp float distortionFreq;" : "") +
|
||||
|
||||
"
|
||||
void main() {
|
||||
qt_TexCoord0 = qt_MultiTexCoord0;
|
||||
vec2 coords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));" +
|
||||
|
||||
(!fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
|
||||
"vec4 initialNoiseTexel = texture2D(noiseSource, coords);"
|
||||
: "") +
|
||||
|
||||
(!fallBack && flickering !== 0.0 ? "
|
||||
brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
|
||||
: "") +
|
||||
|
||||
(!fallBack && horizontalSync !== 0.0 ? "
|
||||
float randval = horizontalSyncStrength - initialNoiseTexel.r;
|
||||
distortionScale = step(0.0, randval) * randval * horizontalSyncStrength;
|
||||
distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
|
||||
: "") +
|
||||
|
||||
"gl_Position = qt_Matrix * qt_Vertex;
|
||||
}"
|
||||
|
||||
fragmentShader: "
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D screenBuffer;
|
||||
uniform highp float qt_Opacity;
|
||||
uniform highp float time;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec4 fontColor;
|
||||
uniform highp vec4 backgroundColor;
|
||||
uniform lowp float shadowLength;
|
||||
uniform lowp float frameGloss;
|
||||
|
||||
uniform highp vec2 virtualResolution;
|
||||
uniform lowp float rasterizationIntensity;\n" +
|
||||
|
||||
(burnIn !== 0 ? "
|
||||
uniform sampler2D burnInSource;
|
||||
uniform highp float burnInLastUpdate;
|
||||
uniform highp float burnInTime;" : "") +
|
||||
(staticNoise !== 0 ? "
|
||||
uniform highp float staticNoise;" : "") +
|
||||
(((staticNoise !== 0 || jitter !== 0) ||(fallBack && (flickering || horizontalSync))) ? "
|
||||
uniform lowp sampler2D noiseSource;
|
||||
uniform highp vec2 scaleNoiseSize;" : "") +
|
||||
(displayTerminalFrame ? "
|
||||
uniform lowp sampler2D frameSource;" : "") +
|
||||
(screenCurvature !== 0 ? "
|
||||
uniform highp float screenCurvature;" : "") +
|
||||
(glowingLine !== 0 ? "
|
||||
uniform highp float glowingLine;" : "") +
|
||||
(chromaColor !== 0 ? "
|
||||
uniform lowp float chromaColor;" : "") +
|
||||
(jitter !== 0 ? "
|
||||
uniform lowp vec2 jitterDisplacement;" : "") +
|
||||
(ambientLight !== 0 ? "
|
||||
uniform lowp float ambientLight;" : "") +
|
||||
|
||||
(fallBack && horizontalSync !== 0 ? "
|
||||
uniform lowp float horizontalSyncStrength;" : "") +
|
||||
(fallBack && flickering !== 0.0 ?"
|
||||
uniform lowp float flickering;" : "") +
|
||||
(!fallBack && flickering !== 0 ? "
|
||||
varying lowp float brightness;"
|
||||
: "") +
|
||||
(!fallBack && horizontalSync !== 0 ? "
|
||||
varying lowp float distortionScale;
|
||||
varying lowp float distortionFreq;" : "") +
|
||||
|
||||
(glowingLine !== 0 ? "
|
||||
float randomPass(vec2 coords){
|
||||
return fract(smoothstep(-120.0, 0.0, coords.y - (virtualResolution.y + 120.0) * fract(time * 0.00015)));
|
||||
}" : "") +
|
||||
|
||||
shaderLibrary.min2 +
|
||||
shaderLibrary.rgb2grey +
|
||||
shaderLibrary.rasterizationShader +
|
||||
|
||||
"
|
||||
float isInScreen(vec2 v) {
|
||||
return min2(step(0.0, v) - step(1.0, v));
|
||||
}
|
||||
|
||||
vec2 barrel(vec2 v, vec2 cc) {" +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
float distortion = dot(cc, cc) * screenCurvature;
|
||||
return (v - cc * (1.0 + distortion) * distortion);"
|
||||
:
|
||||
"return v;") +
|
||||
"}" +
|
||||
|
||||
"vec3 convertWithChroma(vec3 inColor) {
|
||||
vec3 outColor = inColor;" +
|
||||
|
||||
(chromaColor !== 0 ?
|
||||
"outColor = fontColor.rgb * mix(vec3(rgb2grey(inColor)), inColor, chromaColor);"
|
||||
:
|
||||
"outColor = fontColor.rgb * rgb2grey(inColor);") +
|
||||
|
||||
" return outColor;
|
||||
}" +
|
||||
|
||||
//pseudo-random vector
|
||||
//https://stackoverflow.com/a/10625698
|
||||
"float random( vec2 p )
|
||||
{
|
||||
vec2 K1 = vec2(
|
||||
23.14069263277926, // e^pi (Gelfond's constant)
|
||||
2.665144142690225 // 2^sqrt(2) (Gelfond-Schneider constant)
|
||||
);
|
||||
return fract( cos( dot(p,K1) ) * 12345.6789 );
|
||||
}" +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
|
||||
"float distance = length(cc);" +
|
||||
|
||||
//FallBack if there are problems
|
||||
(fallBack && (flickering !== 0.0 || horizontalSync !== 0.0) ?
|
||||
"vec2 initialCoords = vec2(fract(time/(1024.0*2.0)), fract(time/(1024.0*1024.0)));
|
||||
vec4 initialNoiseTexel = texture2D(noiseSource, initialCoords);"
|
||||
: "") +
|
||||
(fallBack && flickering !== 0.0 ? "
|
||||
float brightness = 1.0 + (initialNoiseTexel.g - 0.5) * flickering;"
|
||||
: "") +
|
||||
(fallBack && horizontalSync !== 0.0 ? "
|
||||
float randval = horizontalSyncStrength - initialNoiseTexel.r;
|
||||
float distortionScale = step(0.0, randval) * randval * horizontalSyncStrength;
|
||||
float distortionFreq = mix(4.0, 40.0, initialNoiseTexel.g);"
|
||||
: "") +
|
||||
|
||||
(staticNoise ? "
|
||||
float noise = staticNoise;" : "") +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
vec2 staticCoords = barrel(qt_TexCoord0, cc);"
|
||||
:"
|
||||
vec2 staticCoords = qt_TexCoord0;") +
|
||||
|
||||
"vec2 coords = qt_TexCoord0;" +
|
||||
|
||||
(horizontalSync !== 0 ? "
|
||||
float dst = sin((coords.y + time * 0.001) * distortionFreq);
|
||||
coords.x += dst * distortionScale;" +
|
||||
|
||||
(staticNoise ? "
|
||||
noise += distortionScale * 7.0;" : "")
|
||||
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 || staticNoise !== 0 ?
|
||||
"vec4 noiseTexel = texture2D(
|
||||
noiseSource, scaleNoiseSize * coords
|
||||
+ vec2(0.0, random(vec2(fract(time / 237.0), 822.9582)))
|
||||
+ vec2(fract(time / 31.0), fract(time / 177.0))
|
||||
);"
|
||||
: "") +
|
||||
|
||||
(jitter !== 0 ? "
|
||||
vec2 offset = vec2(noiseTexel.b, noiseTexel.a) - vec2(0.5);
|
||||
vec2 txt_coords = coords + offset * jitterDisplacement;"
|
||||
: "vec2 txt_coords = coords;") +
|
||||
|
||||
"float color = 0.0001;" +
|
||||
|
||||
(staticNoise !== 0 ? "
|
||||
float noiseVal = noiseTexel.a;
|
||||
color += noiseVal * noise * (1.0 - distance * 1.3);" : "") +
|
||||
|
||||
(glowingLine !== 0 ? "
|
||||
color += randomPass(coords * virtualResolution) * glowingLine;" : "") +
|
||||
|
||||
"vec3 txt_color = texture2D(screenBuffer, txt_coords).rgb;" +
|
||||
|
||||
(burnIn !== 0 ? "
|
||||
vec4 txt_blur = texture2D(burnInSource, staticCoords);
|
||||
float blurDecay = clamp((time - burnInLastUpdate) * burnInTime, 0.0, 1.0);
|
||||
vec3 burnInColor = 0.65 * (txt_blur.rgb - vec3(blurDecay));
|
||||
txt_color = max(txt_color, convertWithChroma(burnInColor));"
|
||||
: "") +
|
||||
|
||||
"txt_color += fontColor.rgb * vec3(color);" +
|
||||
|
||||
"txt_color = applyRasterization(staticCoords, txt_color, virtualResolution, rasterizationIntensity);\n" +
|
||||
|
||||
"vec3 finalColor = txt_color;" +
|
||||
|
||||
(flickering !== 0 ? "
|
||||
finalColor *= brightness;" : "") +
|
||||
|
||||
(ambientLight !== 0 ? "
|
||||
finalColor += vec3(ambientLight) * (1.0 - distance) * (1.0 - distance);" : "") +
|
||||
|
||||
(displayTerminalFrame ?
|
||||
"vec4 frameColor = texture2D(frameSource, qt_TexCoord0);
|
||||
finalColor = mix(finalColor, frameColor.rgb + (finalColor*frameGloss), frameColor.a);"
|
||||
: "") +
|
||||
|
||||
"gl_FragColor = vec4(finalColor, qt_Opacity);" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: {
|
||||
// Print warning messages
|
||||
if (log)
|
||||
console.log(log);
|
||||
|
||||
// Activate fallback mode
|
||||
if (status == ShaderEffect.Error) {
|
||||
fallBack = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: terminalFrameLoader
|
||||
|
||||
active: dynamicShader.displayTerminalFrame
|
||||
|
||||
width: staticShader.width
|
||||
height: staticShader.height
|
||||
|
||||
sourceComponent: ShaderEffectSource {
|
||||
|
||||
sourceItem: terminalFrame
|
||||
hideSource: true
|
||||
visible: false
|
||||
format: ShaderEffectSource.RGBA
|
||||
|
||||
TerminalFrame {
|
||||
id: terminalFrame
|
||||
blending: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShaderLibrary {
|
||||
id: shaderLibrary
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: staticShader
|
||||
|
||||
width: parent.width * appSettings.windowScaling
|
||||
height: parent.height * appSettings.windowScaling
|
||||
|
||||
property ShaderEffectSource source: parent.source
|
||||
property ShaderEffectSource bloomSource: parent.bloomSource
|
||||
|
||||
property color fontColor: parent.fontColor
|
||||
property color backgroundColor: parent.backgroundColor
|
||||
property real bloom: appSettings.bloom * 2.5
|
||||
|
||||
property real screenCurvature: parent.screenCurvature
|
||||
|
||||
property real chromaColor: appSettings.chromaColor;
|
||||
|
||||
property real rbgShift: (appSettings.rbgShift / width) * appSettings.totalFontScaling // TODO FILIPPO width here is wrong.
|
||||
|
||||
property int rasterization: appSettings.rasterization
|
||||
|
||||
property real screen_brightness: Utils.lint(0.5, 1.5, appSettings.brightness)
|
||||
|
||||
property real ambientLight: parent.ambientLight
|
||||
|
||||
property size virtualResolution: parent.virtualResolution
|
||||
|
||||
blending: false
|
||||
visible: false
|
||||
|
||||
//Print the number with a reasonable precision for the shader.
|
||||
function str(num){
|
||||
return num.toFixed(8);
|
||||
}
|
||||
|
||||
fragmentShader: "
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform sampler2D source;
|
||||
uniform highp float qt_Opacity;
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform highp vec4 fontColor;
|
||||
uniform highp vec4 backgroundColor;
|
||||
uniform lowp float screen_brightness;
|
||||
|
||||
uniform highp vec2 virtualResolution;" +
|
||||
|
||||
(bloom !== 0 ? "
|
||||
uniform highp sampler2D bloomSource;
|
||||
uniform lowp float bloom;" : "") +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
uniform highp float screenCurvature;" : "") +
|
||||
|
||||
(chromaColor !== 0 ? "
|
||||
uniform lowp float chromaColor;" : "") +
|
||||
|
||||
(rbgShift !== 0 ? "
|
||||
uniform lowp float rbgShift;" : "") +
|
||||
|
||||
(ambientLight !== 0 ? "
|
||||
uniform lowp float ambientLight;" : "") +
|
||||
|
||||
shaderLibrary.min2 +
|
||||
shaderLibrary.sum2 +
|
||||
shaderLibrary.rgb2grey +
|
||||
|
||||
"vec3 convertWithChroma(vec3 inColor) {
|
||||
vec3 outColor = inColor;" +
|
||||
|
||||
(chromaColor !== 0 ?
|
||||
"outColor = fontColor.rgb * mix(vec3(rgb2grey(inColor)), inColor, chromaColor);"
|
||||
:
|
||||
"outColor = fontColor.rgb * rgb2grey(inColor);") +
|
||||
|
||||
" return outColor;
|
||||
}" +
|
||||
|
||||
shaderLibrary.rasterizationShader +
|
||||
|
||||
"void main() {" +
|
||||
"vec2 cc = vec2(0.5) - qt_TexCoord0;" +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
float distortion = dot(cc, cc) * screenCurvature;
|
||||
vec2 curvatureCoords = (qt_TexCoord0 - cc * (1.0 + distortion) * distortion);
|
||||
vec2 txt_coords = - 2.0 * curvatureCoords + 3.0 * step(vec2(0.0), curvatureCoords) * curvatureCoords - 3.0 * step(vec2(1.0), curvatureCoords) * curvatureCoords;"
|
||||
:"
|
||||
vec2 txt_coords = qt_TexCoord0;") +
|
||||
|
||||
"vec3 txt_color = texture2D(source, txt_coords).rgb;" +
|
||||
|
||||
(rbgShift !== 0 ? "
|
||||
vec2 displacement = vec2(12.0, 0.0) * rbgShift;
|
||||
vec3 rightColor = texture2D(source, txt_coords + displacement).rgb;
|
||||
vec3 leftColor = texture2D(source, txt_coords - displacement).rgb;
|
||||
txt_color.r = leftColor.r * 0.10 + rightColor.r * 0.30 + txt_color.r * 0.60;
|
||||
txt_color.g = leftColor.g * 0.20 + rightColor.g * 0.20 + txt_color.g * 0.60;
|
||||
txt_color.b = leftColor.b * 0.30 + rightColor.b * 0.10 + txt_color.b * 0.60;
|
||||
" : "") +
|
||||
|
||||
"txt_color += vec3(0.0001);" +
|
||||
"float greyscale_color = rgb2grey(txt_color);" +
|
||||
|
||||
(screenCurvature !== 0 ? "
|
||||
float reflectionMask = sum2(step(vec2(0.0), curvatureCoords) - step(vec2(1.0), curvatureCoords));
|
||||
reflectionMask = clamp(reflectionMask, 0.0, 1.0);"
|
||||
:
|
||||
"float reflectionMask = 1.0;") +
|
||||
|
||||
(chromaColor !== 0 ?
|
||||
"vec3 foregroundColor = mix(fontColor.rgb, txt_color * fontColor.rgb / greyscale_color, chromaColor);
|
||||
vec3 finalColor = mix(backgroundColor.rgb, foregroundColor, greyscale_color * reflectionMask);"
|
||||
:
|
||||
"vec3 finalColor = mix(backgroundColor.rgb, fontColor.rgb, greyscale_color * reflectionMask);") +
|
||||
|
||||
(bloom !== 0 ?
|
||||
"vec4 bloomFullColor = texture2D(bloomSource, txt_coords);
|
||||
vec3 bloomColor = bloomFullColor.rgb;
|
||||
float bloomAlpha = bloomFullColor.a;
|
||||
bloomColor = convertWithChroma(bloomColor);
|
||||
finalColor += clamp(bloomColor * bloom * bloomAlpha, 0.0, 0.5);"
|
||||
: "") +
|
||||
|
||||
"finalColor *= screen_brightness;" +
|
||||
|
||||
"gl_FragColor = vec4(finalColor, qt_Opacity);" +
|
||||
"}"
|
||||
|
||||
onStatusChanged: {
|
||||
// Print warning messages
|
||||
if (log) console.log(log);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: frameBuffer
|
||||
visible: false
|
||||
sourceItem: staticShader
|
||||
hideSource: true
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
@ -17,16 +17,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
import "Components"
|
||||
|
||||
RowLayout {
|
||||
property alias value: slider.value
|
||||
property alias stepSize: slider.stepSize
|
||||
property alias minimumValue: slider.minimumValue
|
||||
property alias maximumValue: slider.maximumValue
|
||||
property alias minimumValue: slider.from
|
||||
property alias maximumValue: slider.to
|
||||
property real maxMultiplier: 100
|
||||
|
||||
id: setting_component
|
||||
@ -36,15 +37,7 @@ RowLayout {
|
||||
stepSize: parent.stepSize
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text{
|
||||
id: textfield
|
||||
text: formatNumber(Math.round(value * maxMultiplier))
|
||||
}
|
||||
function formatNumber(num) {
|
||||
var n = "" + num;
|
||||
while (n.length < 3) {
|
||||
n = " " + n;
|
||||
}
|
||||
return n + "%";
|
||||
SizedLabel {
|
||||
text: Math.round(value * maxMultiplier) + "%"
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
@ -17,12 +17,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Rectangle {
|
||||
property size terminalSize
|
||||
property real topOpacity: 0.6
|
||||
|
||||
width: textSize.width * 2
|
||||
height: textSize.height * 2
|
||||
radius: 5
|
||||
@ -31,7 +31,11 @@ Rectangle{
|
||||
color: "black"
|
||||
opacity: sizetimer.running ? 0.6 : 0.0
|
||||
|
||||
Behavior on opacity{NumberAnimation{duration: 200}}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
onTerminalSizeChanged: sizetimer.restart()
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
@ -21,11 +21,13 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.LocalStorage 2.0
|
||||
|
||||
Item {
|
||||
QtObject {
|
||||
readonly property string dbMajorVersion: "1"
|
||||
readonly property string dbMinorVersion: "1.0"
|
||||
property bool initialized: false
|
||||
|
||||
function getDatabase() {
|
||||
return LocalStorage.openDatabaseSync("coololdterm", "1.0", "StorageDatabase", 100000);
|
||||
return LocalStorage.openDatabaseSync("coolretroterm" + dbMajorVersion, dbMinorVersion, "StorageDatabase", 100000)
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
@ -33,9 +35,10 @@ Item {
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(setting TEXT UNIQUE, value TEXT)');
|
||||
});
|
||||
}
|
||||
)
|
||||
|
||||
initialized = true;
|
||||
initialized = true
|
||||
}
|
||||
|
||||
function setSetting(setting, value) {
|
||||
@ -43,7 +46,8 @@ Item {
|
||||
|
||||
var db = getDatabase();
|
||||
var res = "";
|
||||
db.transaction(function(tx) {
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
var rs = tx.executeSql('INSERT OR REPLACE INTO settings VALUES (?,?);', [setting,value]);
|
||||
//console.log(rs.rowsAffected)
|
||||
if (rs.rowsAffected > 0) {
|
||||
@ -52,23 +56,25 @@ Item {
|
||||
res = "Error";
|
||||
}
|
||||
}
|
||||
);
|
||||
)
|
||||
// The function returns “OK” if it was successful, or “Error” if it wasn't
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
function getSetting(setting) {
|
||||
if(!initialized) initialize();
|
||||
var db = getDatabase();
|
||||
var res = "";
|
||||
db.transaction(function(tx) {
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
var rs = tx.executeSql('SELECT value FROM settings WHERE setting=?;', [setting]);
|
||||
if (rs.rows.length > 0) {
|
||||
res = rs.rows.item(0).value;
|
||||
} else {
|
||||
res = undefined;
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
return res
|
||||
}
|
||||
|
||||
@ -77,6 +83,7 @@ Item {
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
tx.executeSql('DROP TABLE settings');
|
||||
});
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
80
app/qml/TerminalContainer.qml
Normal file
80
app/qml/TerminalContainer.qml
Normal file
@ -0,0 +1,80 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
ShaderTerminal {
|
||||
property alias title: terminal.title
|
||||
property alias terminalSize: terminal.terminalSize
|
||||
|
||||
property real devicePixelRatio: terminalWindow.screen.devicePixelRatio
|
||||
|
||||
id: mainShader
|
||||
opacity: appSettings.windowOpacity * 0.3 + 0.7
|
||||
|
||||
source: terminal.mainSource
|
||||
burnInEffect: terminal.burnInEffect
|
||||
virtualResolution: terminal.virtualResolution
|
||||
screenResolution: Qt.size(
|
||||
terminalWindow.width * devicePixelRatio * appSettings.windowScaling,
|
||||
terminalWindow.height * devicePixelRatio * appSettings.windowScaling
|
||||
)
|
||||
|
||||
TimeManager {
|
||||
id: timeManager
|
||||
enableTimer: terminalWindow.visible
|
||||
}
|
||||
|
||||
PreprocessedTerminal {
|
||||
id: terminal
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
// EFFECTS ////////////////////////////////////////////////////////////////
|
||||
Loader {
|
||||
id: bloomEffectLoader
|
||||
active: appSettings.bloom
|
||||
asynchronous: true
|
||||
width: parent.width * appSettings.bloomQuality
|
||||
height: parent.height * appSettings.bloomQuality
|
||||
|
||||
sourceComponent: FastBlur {
|
||||
radius: Utils.lint(16, 64, appSettings.bloomQuality)
|
||||
source: terminal.mainSource
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: bloomSourceLoader
|
||||
active: appSettings.bloom !== 0
|
||||
asynchronous: true
|
||||
sourceComponent: ShaderEffectSource {
|
||||
id: _bloomEffectSource
|
||||
sourceItem: bloomEffectLoader.item
|
||||
hideSource: true
|
||||
smooth: true
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
bloomSource: bloomSourceLoader.item
|
||||
}
|
104
app/qml/TerminalFrame.qml
Normal file
104
app/qml/TerminalFrame.qml
Normal file
@ -0,0 +1,104 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
import QtQuick 2.0
|
||||
|
||||
import "utils.js" as Utils
|
||||
|
||||
ShaderEffect {
|
||||
property color _frameColor: appSettings.frameColor
|
||||
property color _backgroundColor: appSettings.backgroundColor
|
||||
property color _fontColor: appSettings.fontColor
|
||||
property color _lightColor: Utils.mix(_fontColor, _backgroundColor, 0.2)
|
||||
property real _ambientLight: Utils.lint(0.2, 0.8, appSettings.ambientLight)
|
||||
|
||||
property color frameColor: Utils.mix(_frameColor, _lightColor, _ambientLight)
|
||||
property real screenCurvature: appSettings.screenCurvature * appSettings.screenCurvatureSize
|
||||
|
||||
// Coefficient of the log curve used to approximate shadowing
|
||||
property real screenShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
|
||||
property real frameShadowCoeff: Utils.lint(20.0, 10.0, _ambientLight)
|
||||
|
||||
property size margin: Qt.size(
|
||||
appSettings.frameMargin / width * appSettings.windowScaling,
|
||||
appSettings.frameMargin / height * appSettings.windowScaling
|
||||
)
|
||||
|
||||
ShaderLibrary {
|
||||
id: shaderLibrary
|
||||
}
|
||||
|
||||
fragmentShader: "
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
uniform lowp float screenCurvature;
|
||||
uniform lowp float screenShadowCoeff;
|
||||
uniform lowp float frameShadowCoeff;
|
||||
uniform highp float qt_Opacity;
|
||||
uniform lowp vec4 frameColor;
|
||||
uniform mediump vec2 margin;
|
||||
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
vec2 distortCoordinates(vec2 coords){
|
||||
vec2 cc = (coords - vec2(0.5));
|
||||
float dist = dot(cc, cc) * screenCurvature;
|
||||
return (coords + cc * (1.0 + dist) * dist);
|
||||
}
|
||||
" +
|
||||
|
||||
shaderLibrary.max2 +
|
||||
shaderLibrary.min2 +
|
||||
shaderLibrary.prod2 +
|
||||
shaderLibrary.sum2 +
|
||||
|
||||
"
|
||||
|
||||
vec2 positiveLog(vec2 x) {
|
||||
return clamp(log(x), vec2(0.0), vec2(100.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 staticCoords = qt_TexCoord0;
|
||||
vec2 coords = distortCoordinates(staticCoords) * (vec2(1.0) + margin * 2.0) - margin;
|
||||
|
||||
vec2 vignetteCoords = staticCoords * (1.0 - staticCoords.yx);
|
||||
float vignette = pow(prod2(vignetteCoords) * 15.0, 0.25);
|
||||
|
||||
vec3 color = frameColor.rgb * vec3(1.0 - vignette);
|
||||
float alpha = 0.0;
|
||||
|
||||
float frameShadow = max2(positiveLog(-coords * frameShadowCoeff + vec2(1.0)) + positiveLog(coords * frameShadowCoeff - (vec2(frameShadowCoeff) - vec2(1.0))));
|
||||
frameShadow = clamp(sqrt(frameShadow), 0.0, 1.0);
|
||||
color *= frameShadow;
|
||||
alpha = sum2(1.0 - step(vec2(0.0), coords) + step(vec2(1.0), coords));
|
||||
alpha = clamp(alpha, 0.0, 1.0);
|
||||
alpha *= mix(1.0, 0.9, frameShadow);
|
||||
|
||||
float screenShadow = 1.0 - prod2(positiveLog(coords * screenShadowCoeff + vec2(1.0)) * positiveLog(-coords * screenShadowCoeff + vec2(screenShadowCoeff + 1.0)));
|
||||
alpha = max(0.8 * screenShadow, alpha);
|
||||
|
||||
gl_FragColor = vec4(color * alpha, alpha);
|
||||
}
|
||||
"
|
||||
|
||||
onStatusChanged: if (log) console.log(log) //Print warning messages
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordifish90/cool-old-term
|
||||
* Copyright (c) 2013-2021 "Filippo Scognamiglio"
|
||||
* https://github.com/Swordfish90/cool-retro-term
|
||||
*
|
||||
* This file is part of cool-old-term.
|
||||
* This file is part of cool-retro-term.
|
||||
*
|
||||
* cool-old-term is free software: you can redistribute it and/or modify
|
||||
* cool-retro-term is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
@ -17,7 +17,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*******************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Timer {
|
||||
@ -27,13 +26,13 @@ Timer{
|
||||
NumberAnimation on time {
|
||||
from: 0
|
||||
to: 100000
|
||||
running: shadersettings.fps === 0 && enableTimer
|
||||
running: appSettings.fps === 0 && enableTimer
|
||||
duration: 100000
|
||||
loops: Animation.Infinite
|
||||
}
|
||||
|
||||
onTriggered: time += interval
|
||||
running: shadersettings.fps !== 0 && enableTimer
|
||||
interval: Math.round(1000 / shadersettings.fps)
|
||||
running: appSettings.fps !== 0 && enableTimer
|
||||
interval: Math.round(1000 / appSettings.fps)
|
||||
repeat: true
|
||||
}
|
BIN
app/qml/fonts/1971-ibm-3278/3270-Regular.ttf
Normal file
BIN
app/qml/fonts/1971-ibm-3278/3270-Regular.ttf
Normal file
Binary file not shown.
49
app/qml/fonts/1971-ibm-3278/LICENSE.txt
Normal file
49
app/qml/fonts/1971-ibm-3278/LICENSE.txt
Normal file
@ -0,0 +1,49 @@
|
||||
Copyright (c) 2011-2017, Ricardo Banffy.
|
||||
Copyright (c) 1993-2011, Paul Mattes.
|
||||
Copyright (c) 2004-2005, Don Russell.
|
||||
Copyright (c) 2004, Dick Altenbern.
|
||||
Copyright (c) 1990, Jeff Sparkes.
|
||||
Copyright (c) 1989, Georgia Tech Research Corporation (GTRC), Atlanta, GA 30332.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Ricardo Banffy, Paul Mattes, Don Russell,
|
||||
Dick Altenbern, Jeff Sparkes, GTRC nor the names of their contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL RICARDO BANFFY, PAUL MATTES, DON RUSSELL, DICK ALTENBERN, JEFF
|
||||
SPARKES OR GTRC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The Debian Logo glyph is based on the Debian Open Use Logo and is
|
||||
Copyright (c) 1999 Software in the Public Interest, Inc., and it is
|
||||
incorporated here under the terms of the Creative Commons
|
||||
Attribution-ShareAlike 3.0 Unported License. The logo is released
|
||||
under the terms of the GNU Lesser General Public License, version 3 or
|
||||
any later version, or, at your option, of the Creative Commons
|
||||
Attribution-ShareAlike 3.0 Unported License.
|
||||
|
||||
Ubuntu, the Ubuntu logo and the Circle of Friends symbol are
|
||||
registered trademarks of Canonical Ltd.
|
||||
|
||||
The Fontforge SFD font description file is optionally licensed under
|
||||
the SIL Open Font License v1.1 with no Reserved Font Name. This
|
||||
license is available with a FAQ at http://scripts.sil.org/OFL.
|
121
app/qml/fonts/1971-ibm-3278/README.md
Normal file
121
app/qml/fonts/1971-ibm-3278/README.md
Normal file
@ -0,0 +1,121 @@
|
||||
3270font: A font for the nostalgic
|
||||
==================================
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
A little bit of history
|
||||
-----------------------
|
||||
|
||||
This font is derived from the x3270 font, which, in turn, was
|
||||
translated from the one in Georgia Tech's 3270tool, which was itself
|
||||
hand-copied from a 3270 series terminal. I built it because I felt
|
||||
terminals deserve to be pretty. The .sfd font file contains a x3270
|
||||
bitmap font that was used for guidance.
|
||||
|
||||

|
||||
|
||||
Getting it
|
||||
----------
|
||||
|
||||
If you are running Debian or Ubuntu and you don't want to mess with
|
||||
building your font files, you can simply `apt-get install fonts-3270`
|
||||
(It's available from the Debian
|
||||
(https://packages.debian.org/sid/fonts/fonts-3270) and Ubuntu
|
||||
(http://packages.ubuntu.com/zesty/fonts-3270) package repos at
|
||||
https://packages.debian.org/sid/fonts/fonts-3270 and
|
||||
http://packages.ubuntu.com/xenial/fonts/fonts-3270, although the
|
||||
packaged version may not be the latest version, but it's good enough for
|
||||
most purposes. For those who don't have the luxury of a proper
|
||||
system-managed package, Adobe Type 1, TTF, OTF and WOFF versions are
|
||||
available for download on
|
||||
http://s3.amazonaws.com/3270font/3270_fonts_4cfe95c.zip (although this
|
||||
URL may not always reflect the latest version).
|
||||
|
||||

|
||||
|
||||
The format
|
||||
----------
|
||||
|
||||
The "source" file is edited using FontForge. You'll need it if you want
|
||||
to generate fonts for your platform. On most civilized operating
|
||||
systems, you can simply `apt-get install fontforge`, `yum install
|
||||
fontforge` or even `port install fontforge`. On others, you may need to
|
||||
grab your copy from http://fontforge.org/. I encourage you to drop by
|
||||
and read the tutorials.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
If you are running Windows, you'll probably need something like
|
||||
Cygwin, but, in the end, the font works correctly (with some very
|
||||
minor hinting issues).
|
||||
|
||||

|
||||
|
||||
Generating usable font files
|
||||
----------------------------
|
||||
|
||||
The easiest way to generate the font files your computer can use is to
|
||||
run `make all` (if you are running Ubuntu or Debian, `make install` will
|
||||
install them too). Using `make help` will offer a handy list of options.
|
||||
|
||||
The script `generate_derived.pe` calls FontForge and generates
|
||||
PostScript, OTF, TTF and WOFF versions of the base font, as well as a
|
||||
slightly more condensed .sfd file with the base font narrowed to 488
|
||||
units, with no glyph rescaling (or cropping - we need to fix that) and
|
||||
its corresponding PostScript, TTF, OTF and WOFF versions.
|
||||
|
||||

|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
I fear GitHub's pull-request mechanism may not be very
|
||||
FontForge-friendly. If you want to contribute (there are a lot of
|
||||
missing glyphs, such as most non-latin alphabets which most likely were
|
||||
never built into 3270 terminals), the best workflow would probably be to
|
||||
add the encoding slots (if needed), add/make the changes, remove the
|
||||
unchanged glyphs and save it as a different file. If, in doubt, get in
|
||||
touch and we will figure out how to do it right.
|
||||
|
||||
In order to generate the sample image and the grids for FontForge,
|
||||
you'll need a Python 3 environment with PIL or pillow installed. The
|
||||
requirements.txt file lists everything you need to do it.
|
||||
|
||||
Known problems
|
||||
--------------
|
||||
|
||||
Not all symbols in the 3270 charset have Unicode counterparts. When
|
||||
possible, they are duplicated in the Unicode space. The 3270-only
|
||||
symbols are at the end of the font, along with some glyphs useful for
|
||||
building others.
|
||||
|
||||
Please refer to http://x3270.bgp.nu/Charset.html for a complete map.
|
||||
|
||||
Future improvements
|
||||
-------------------
|
||||
|
||||
A grid generator is provided for producing various grid sizes for the
|
||||
font. Those grids are not used yet, but they are intended to be used to
|
||||
align font features to provide better rendering at common font size
|
||||
choices. The captures below exemplify these choices:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
BIN
app/qml/fonts/1979-atari-400-800/AtariClassic-Regular.ttf
Normal file
BIN
app/qml/fonts/1979-atari-400-800/AtariClassic-Regular.ttf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user