Compare commits
1082 Commits
v0.16.1
...
test-new-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
707bcca368 | ||
|
|
f8f115de10 | ||
|
|
b07c4dc53a | ||
|
|
6eeddba773 | ||
|
|
0cfe4df468 | ||
|
|
eb5c3c3be5 | ||
|
|
a5b9206694 | ||
|
|
375e67bdc4 | ||
|
|
724a576aa3 | ||
|
|
ed47dcb90c | ||
|
|
64b08a5a4d | ||
|
|
baed0153a2 | ||
|
|
46d95b33e4 | ||
|
|
200d270fee | ||
|
|
a8628275a0 | ||
|
|
20a1d2bcc1 | ||
|
|
b887a1f096 | ||
|
|
9bf0e9f28d | ||
|
|
dfc724767b | ||
|
|
f0e66e9dc5 | ||
|
|
0932335f0b | ||
|
|
a9b39e396a | ||
|
|
2e0ceaae72 | ||
|
|
04f38d2eb6 | ||
|
|
fc1ed4dff6 | ||
|
|
f8935d3dd7 | ||
|
|
a86228677f | ||
|
|
79df9f7876 | ||
|
|
12ea2d76be | ||
|
|
485bd72241 | ||
|
|
7240275075 | ||
|
|
29ef9b8d15 | ||
|
|
97f4795d4e | ||
|
|
226e45b24d | ||
|
|
d6ab7e72b2 | ||
|
|
168f44b8b3 | ||
|
|
b73f646a4c | ||
|
|
36cefcc000 | ||
|
|
f901c25c87 | ||
|
|
6d8478b029 | ||
|
|
9bcb040019 | ||
|
|
d977087fc0 | ||
|
|
1a330771d7 | ||
|
|
9c8c9f2106 | ||
|
|
0498beecdf | ||
|
|
8e075adf8f | ||
|
|
60f2a0e647 | ||
|
|
b642f2b5c4 | ||
|
|
2b80f72c6b | ||
|
|
462720881a | ||
|
|
3dda0254a8 | ||
|
|
054a52a445 | ||
|
|
85242d808b | ||
|
|
57241677a9 | ||
|
|
6ccdee2a53 | ||
|
|
a3d2b7b7f3 | ||
|
|
b7b28b4ae3 | ||
|
|
30748200dd | ||
|
|
c9f8240234 | ||
|
|
5c7082e886 | ||
|
|
9a3c889a9d | ||
|
|
f41f58e13f | ||
|
|
e81f25c216 | ||
|
|
36fc681fbf | ||
|
|
87e5e29129 | ||
|
|
b432fdf90a | ||
|
|
6e78a3fedd | ||
|
|
24760801af | ||
|
|
f5e8e0f7a5 | ||
|
|
df089a2f04 | ||
|
|
6600713f4b | ||
|
|
96dad762b2 | ||
|
|
5470387685 | ||
|
|
fa64c868b9 | ||
|
|
2f4a416353 | ||
|
|
3dbafb042c | ||
|
|
97e7b019dd | ||
|
|
28103ad952 | ||
|
|
1826ca6f2f | ||
|
|
db490a6c6c | ||
|
|
421fdef4f9 | ||
|
|
d717ce842d | ||
|
|
f13c9792af | ||
|
|
41e7b8e0f4 | ||
|
|
4bd723a7ee | ||
|
|
66d5bd5490 | ||
|
|
351d0258b2 | ||
|
|
26fb9a7052 | ||
|
|
307fd637fa | ||
|
|
93fb716f89 | ||
|
|
7b41551e2d | ||
|
|
4806af5f7d | ||
|
|
85cb55cdd0 | ||
|
|
27a9697e47 | ||
|
|
7d230cc3b0 | ||
|
|
0db2fffad1 | ||
|
|
2a3296a0e8 | ||
|
|
941b875afa | ||
|
|
99155bb9cf | ||
|
|
0701dd2ad3 | ||
|
|
5570c19e1f | ||
|
|
a728c91476 | ||
|
|
6a43481067 | ||
|
|
29a049fe4e | ||
|
|
b5a9c8e1bb | ||
|
|
bb9a35c161 | ||
|
|
b25a345b42 | ||
|
|
b22b0e0194 | ||
|
|
55cf95f218 | ||
|
|
225ddbcfac | ||
|
|
9377090c7c | ||
|
|
ed002ec2e1 | ||
|
|
e33036d9ec | ||
|
|
ef03e7c009 | ||
|
|
aef4220ac0 | ||
|
|
46223e38cd | ||
|
|
4bafa4bffe | ||
|
|
2b3dd877dd | ||
|
|
0553e5c45e | ||
|
|
4d93374cf6 | ||
|
|
4e421bf9ba | ||
|
|
8b2a9d7c01 | ||
|
|
5a3244d345 | ||
|
|
f1b9d0c5e4 | ||
|
|
6493e0e623 | ||
|
|
e71ba17f9f | ||
|
|
e656363e20 | ||
|
|
0826a748ae | ||
|
|
a595fe99ef | ||
|
|
9dbc7942e3 | ||
|
|
845d8ae32e | ||
|
|
5c524e138c | ||
|
|
86d9265ff9 | ||
|
|
6994a5d6d3 | ||
|
|
e6213b00c1 | ||
|
|
43e2caa30e | ||
|
|
97ca245dfc | ||
|
|
36de1c0751 | ||
|
|
704341fd15 | ||
|
|
22b61bc9c3 | ||
|
|
f4cbbc0a2a | ||
|
|
dc99187b9d | ||
|
|
915598dec4 | ||
|
|
e7b4518d73 | ||
|
|
9603a78e87 | ||
|
|
bd90e051d4 | ||
|
|
26e66b313f | ||
|
|
c534bbd12a | ||
|
|
83b5e217e5 | ||
|
|
c0adf5bf0b | ||
|
|
4ff737a4ac | ||
|
|
5af0706c09 | ||
|
|
4ccee0f1de | ||
|
|
9b752d540e | ||
|
|
e860c7b7ec | ||
|
|
8a1fd9531f | ||
|
|
5fd6e0ee99 | ||
|
|
53b2b81fe0 | ||
|
|
6ccc811b46 | ||
|
|
962a61567a | ||
|
|
58f05e1cec | ||
|
|
6b426790c7 | ||
|
|
d4fc578673 | ||
|
|
51b567b8db | ||
|
|
07b47dee3f | ||
|
|
4431a906b9 | ||
|
|
2bb6852e3e | ||
|
|
1948ed3e16 | ||
|
|
81b5ccae30 | ||
|
|
5543ff0d29 | ||
|
|
cd567e9e98 | ||
|
|
5d86925a8a | ||
|
|
e3db564a4b | ||
|
|
a4293624ab | ||
|
|
367e2dc81a | ||
|
|
9ec33c6eef | ||
|
|
9c9b8d36f2 | ||
|
|
4fc6f335c7 | ||
|
|
d2f4123d08 | ||
|
|
b29d352a1b | ||
|
|
cd5a71cd12 | ||
|
|
cdd68e985d | ||
|
|
8cf4d4280c | ||
|
|
cd29bf8702 | ||
|
|
13d98be051 | ||
|
|
a350ff3182 | ||
|
|
e0360cc7eb | ||
|
|
4249a29b63 | ||
|
|
43b2a0a8c8 | ||
|
|
6d6584f99e | ||
|
|
077c651226 | ||
|
|
3fc872aa76 | ||
|
|
cb0b347a38 | ||
|
|
d08967c688 | ||
|
|
3666c0caa9 | ||
|
|
4ef179fccb | ||
|
|
861f9b3caa | ||
|
|
05292df456 | ||
|
|
9fed692223 | ||
|
|
b1c04c1fea | ||
|
|
bc9adc2cd3 | ||
|
|
cdf149afca | ||
|
|
73145b4e5e | ||
|
|
f8b9f30fd6 | ||
|
|
e6bc567b12 | ||
|
|
fe004a72f0 | ||
|
|
0433fd3d9d | ||
|
|
1c18060570 | ||
|
|
be54c0e641 | ||
|
|
0be2eb9107 | ||
|
|
4859faf1e7 | ||
|
|
c25d40c67d | ||
|
|
b6c37a5c9f | ||
|
|
f6b4c1b109 | ||
|
|
841faeede4 | ||
|
|
e61b9b23a0 | ||
|
|
72a826ef0a | ||
|
|
f070b8f295 | ||
|
|
1646b75520 | ||
|
|
241617e31a | ||
|
|
5de2893e07 | ||
|
|
030e894040 | ||
|
|
e7b9a4ba87 | ||
|
|
617bae67c6 | ||
|
|
64d2d08820 | ||
|
|
037b33c99a | ||
|
|
afa69ce9a4 | ||
|
|
3226c0c831 | ||
|
|
4e759cad4c | ||
|
|
291795928d | ||
|
|
a1315e7f7f | ||
|
|
657bc2b4e0 | ||
|
|
d8b12fc55d | ||
|
|
6d11367ea4 | ||
|
|
eb9e741b4f | ||
|
|
c47546d501 | ||
|
|
11aa178fc1 | ||
|
|
f3a88ef269 | ||
|
|
720dc2131f | ||
|
|
701ef17ae1 | ||
|
|
1a689a5f07 | ||
|
|
ef12ab0cee | ||
|
|
3d26db7a01 | ||
|
|
dd3df9981b | ||
|
|
5d04e83529 | ||
|
|
7ed4626d71 | ||
|
|
ecf5a29a71 | ||
|
|
1a24b346a0 | ||
|
|
72d06c7a02 | ||
|
|
26fde8c694 | ||
|
|
8adeb99be7 | ||
|
|
c92f15156b | ||
|
|
63f69d712b | ||
|
|
55a1bd06f3 | ||
|
|
6a29abf7f0 | ||
|
|
83bdd9f2c4 | ||
|
|
95879827c8 | ||
|
|
2ade518207 | ||
|
|
36c8449e4d | ||
|
|
3c04df69f3 | ||
|
|
1224ee9a67 | ||
|
|
fdd1d4463a | ||
|
|
940ac3736c | ||
|
|
d38897b54d | ||
|
|
90848c6654 | ||
|
|
0220d5aefc | ||
|
|
f42032df07 | ||
|
|
05d7eb60bc | ||
|
|
942416317c | ||
|
|
576de945fb | ||
|
|
8b02084428 | ||
|
|
9f666d69db | ||
|
|
a4c52d9162 | ||
|
|
592b11366e | ||
|
|
07f50b9243 | ||
|
|
ec74d55686 | ||
|
|
4518513e87 | ||
|
|
7df4e2144f | ||
|
|
7f9c9248ce | ||
|
|
9c1db48804 | ||
|
|
0628830f0c | ||
|
|
9436f2f5fb | ||
|
|
c5e1b5617f | ||
|
|
298c417aa3 | ||
|
|
fc74831700 | ||
|
|
d9db55de44 | ||
|
|
3fd205e8c2 | ||
|
|
5cb828fb92 | ||
|
|
5f7a3fd53f | ||
|
|
8e3e598753 | ||
|
|
2a0a0f60f8 | ||
|
|
6b7d1fdf9f | ||
|
|
65199a40f7 | ||
|
|
f9082a8800 | ||
|
|
1670c6e7d6 | ||
|
|
ff2073ed4d | ||
|
|
f14aaac635 | ||
|
|
c709fa622f | ||
|
|
c752556bf3 | ||
|
|
e7d9703fcc | ||
|
|
1ed52a84b0 | ||
|
|
4fdb278751 | ||
|
|
8318803923 | ||
|
|
42de7e3676 | ||
|
|
3efa646ee3 | ||
|
|
b414c2ab42 | ||
|
|
205dea3db7 | ||
|
|
6cac688555 | ||
|
|
09b1b08c1e | ||
|
|
b61a1270e9 | ||
|
|
b85cee7e1f | ||
|
|
8e674e3e29 | ||
|
|
aa2812c874 | ||
|
|
6f282431c4 | ||
|
|
470e54cdd0 | ||
|
|
da3ef1c2a6 | ||
|
|
9efe0e62d5 | ||
|
|
7038f81b46 | ||
|
|
de972a60df | ||
|
|
6a87787d6f | ||
|
|
6dc9a4b507 | ||
|
|
5b7c888d57 | ||
|
|
a1f761b83e | ||
|
|
c40a6bfaa0 | ||
|
|
441c6f7667 | ||
|
|
a07d57cf71 | ||
|
|
a467f972f9 | ||
|
|
3f455ee360 | ||
|
|
7a0b913768 | ||
|
|
a7b240ade8 | ||
|
|
bb64404821 | ||
|
|
caf92eb3c8 | ||
|
|
6a117a0fab | ||
|
|
26682509f7 | ||
|
|
d85d92fb43 | ||
|
|
c412003cb3 | ||
|
|
e39b5dbd51 | ||
|
|
db162ea66f | ||
|
|
f9f9fde368 | ||
|
|
4b221c2eb5 | ||
|
|
ed45bebfa0 | ||
|
|
fa0bc3805f | ||
|
|
7710f0b70f | ||
|
|
0277ddadb5 | ||
|
|
88e23e32f5 | ||
|
|
8ab5b4a17a | ||
|
|
503dfd69ef | ||
|
|
ae61ec26c0 | ||
|
|
00bc24bd50 | ||
|
|
abd15d6307 | ||
|
|
c01ac546d1 | ||
|
|
af77221ba2 | ||
|
|
204f0938d3 | ||
|
|
ad39d1408c | ||
|
|
ed011173f6 | ||
|
|
491fcb5860 | ||
|
|
c2d5537d8d | ||
|
|
7d5037ae87 | ||
|
|
07d7714317 | ||
|
|
2cab97f37d | ||
|
|
d184778c9a | ||
|
|
9fd3b3008d | ||
|
|
71aa35b214 | ||
|
|
4443dc9d3e | ||
|
|
839e357301 | ||
|
|
ac56c5a415 | ||
|
|
36e3343341 | ||
|
|
510f7d7513 | ||
|
|
3128eb38c0 | ||
|
|
14ef654612 | ||
|
|
bc5193f95e | ||
|
|
8cbb4a38bc | ||
|
|
fce08c83ef | ||
|
|
018e99f9e6 | ||
|
|
7fe390b34b | ||
|
|
8c7202c569 | ||
|
|
ab386bb53c | ||
|
|
87c791b8c7 | ||
|
|
00e3e2d19d | ||
|
|
8d7d5c7b04 | ||
|
|
849a18e159 | ||
|
|
a4357d0843 | ||
|
|
e2b4a78b59 | ||
|
|
01387b5488 | ||
|
|
168e2f80b8 | ||
|
|
4f79ef8708 | ||
|
|
16497833df | ||
|
|
cd6a50d5a0 | ||
|
|
4c5a61f2d8 | ||
|
|
1fd8d39970 | ||
|
|
d133d64890 | ||
|
|
b27aa8b60d | ||
|
|
230d67492e | ||
|
|
4f9d5b282c | ||
|
|
a2955e8722 | ||
|
|
df892671d5 | ||
|
|
7fa96eee1a | ||
|
|
a1030906c7 | ||
|
|
e6a9a4f4be | ||
|
|
efa1247596 | ||
|
|
069fcee721 | ||
|
|
66621404f1 | ||
|
|
e09609ea21 | ||
|
|
d02ae67bc0 | ||
|
|
27327d57c4 | ||
|
|
cce93b6df9 | ||
|
|
546104ba5b | ||
|
|
ca5816ba14 | ||
|
|
e5bd16476e | ||
|
|
94431d4c2e | ||
|
|
f98d6892f1 | ||
|
|
1fe436cbe3 | ||
|
|
c5a37a9920 | ||
|
|
eed7e96096 | ||
|
|
a7f36a4162 | ||
|
|
8ba872d45d | ||
|
|
7a55451faa | ||
|
|
372571bd80 | ||
|
|
77120c0b90 | ||
|
|
01d1e44644 | ||
|
|
0ad8cddefe | ||
|
|
ce67253502 | ||
|
|
cb9f2c0617 | ||
|
|
635d9407ed | ||
|
|
0f9f6565f1 | ||
|
|
a45b6ad57e | ||
|
|
a5de06dedb | ||
|
|
fbfbd1ed98 | ||
|
|
8f06b3bd1a | ||
|
|
7e0dbceefc | ||
|
|
7e3db1de17 | ||
|
|
111790fdab | ||
|
|
bec03de7b8 | ||
|
|
f5dfae3a6c | ||
|
|
d3dec2b5f1 | ||
|
|
f083136998 | ||
|
|
cd3d0b370c | ||
|
|
f4c6632941 | ||
|
|
750cb9a669 | ||
|
|
62a198a017 | ||
|
|
5780ba0f3e | ||
|
|
86edeb1e0c | ||
|
|
53b1852f28 | ||
|
|
e3c385693b | ||
|
|
572c0fbfa1 | ||
|
|
bbdf71167a | ||
|
|
2136ccd9a2 | ||
|
|
2131aea575 | ||
|
|
32b21c7d29 | ||
|
|
8f6f6f316f | ||
|
|
66f9ac2791 | ||
|
|
ac0ba90438 | ||
|
|
990659ce91 | ||
|
|
00c602c844 | ||
|
|
9db62ffc39 | ||
|
|
e7c777e502 | ||
|
|
4991e8cea2 | ||
|
|
111d4e991f | ||
|
|
bedfa74a32 | ||
|
|
f6944dc223 | ||
|
|
a34a3051a3 | ||
|
|
0e13883faf | ||
|
|
e8860eda1b | ||
|
|
33ba4820b3 | ||
|
|
5ed0dda8ab | ||
|
|
bd260b2c6f | ||
|
|
aa01ab07f7 | ||
|
|
684cb90a7d | ||
|
|
172101ed55 | ||
|
|
98b5914726 | ||
|
|
d1518e7ba4 | ||
|
|
72d4faa52a | ||
|
|
862dcbf806 | ||
|
|
3db28f5136 | ||
|
|
f9e37f3c6a | ||
|
|
457681e6ec | ||
|
|
904bcf6852 | ||
|
|
e21e57ff84 | ||
|
|
562a69831a | ||
|
|
706a683540 | ||
|
|
8e2aee5e84 | ||
|
|
c009893377 | ||
|
|
3ae128d4c3 | ||
|
|
cb2164c21d | ||
|
|
951b7407fc | ||
|
|
f68facbe0e | ||
|
|
5535366bb1 | ||
|
|
d75b709f23 | ||
|
|
5a1fd0ca4d | ||
|
|
f4b85e0dbb | ||
|
|
c38bceb87e | ||
|
|
2569e8844e | ||
|
|
e42fa8351e | ||
|
|
9582a625ff | ||
|
|
81abb06f7b | ||
|
|
7cfea0eebe | ||
|
|
01c2bfe955 | ||
|
|
70242e6a07 | ||
|
|
c1edba974f | ||
|
|
546b3f230d | ||
|
|
14593eb487 | ||
|
|
838621a3ae | ||
|
|
283d4a5fce | ||
|
|
490cf44132 | ||
|
|
9dcbd86fc3 | ||
|
|
0a15011ec7 | ||
|
|
f7dfe1d869 | ||
|
|
5e9c9cb5fa | ||
|
|
c485c26c93 | ||
|
|
137d9296cd | ||
|
|
11b144da74 | ||
|
|
25ef9d9886 | ||
|
|
0e1e279209 | ||
|
|
a960897a83 | ||
|
|
69ab7849c5 | ||
|
|
bc55c3d892 | ||
|
|
cee1c41c35 | ||
|
|
6c5fe2463e | ||
|
|
880ce376b3 | ||
|
|
5a8b573bb7 | ||
|
|
ab1e750fa4 | ||
|
|
f6f4e1cd1a | ||
|
|
2a9549b106 | ||
|
|
1ed7ee3952 | ||
|
|
a69fc35f5a | ||
|
|
28e83dcf02 | ||
|
|
8c6df74237 | ||
|
|
d86cd6a8c6 | ||
|
|
c40d411d63 | ||
|
|
aca63abf49 | ||
|
|
4733615c4b | ||
|
|
80e5469653 | ||
|
|
4ea2cb18c7 | ||
|
|
840be65198 | ||
|
|
5a568df6cd | ||
|
|
cf57161174 | ||
|
|
7847e72f63 | ||
|
|
00999426b9 | ||
|
|
188da8b6ff | ||
|
|
59182b0ec8 | ||
|
|
6ced935c22 | ||
|
|
ad50475bb6 | ||
|
|
9c40f4918c | ||
|
|
62c802d2c3 | ||
|
|
3294760f6d | ||
|
|
85d72a1ee5 | ||
|
|
e02bb0f23c | ||
|
|
b0465775dc | ||
|
|
bd4b28e052 | ||
|
|
c6c5c849b4 | ||
|
|
cc5c3db1c1 | ||
|
|
f60236f06e | ||
|
|
bd63584207 | ||
|
|
e5fd3f6c9f | ||
|
|
423173413f | ||
|
|
a136d01da5 | ||
|
|
8ab675baf0 | ||
|
|
8d8e537cd4 | ||
|
|
d3b117a23f | ||
|
|
007982c481 | ||
|
|
ff9b0abfc7 | ||
|
|
275e983f55 | ||
|
|
bccb0b9976 | ||
|
|
d5f01537f8 | ||
|
|
6029363af8 | ||
|
|
cde61a57b8 | ||
|
|
2fc1768a7a | ||
|
|
50d73bcc1e | ||
|
|
0f570be7e5 | ||
|
|
658e6f7fdd | ||
|
|
d651932d9a | ||
|
|
6167c9f317 | ||
|
|
33acf06a71 | ||
|
|
9833e759cc | ||
|
|
918bb09d54 | ||
|
|
9a0a396872 | ||
|
|
6c6dc654e6 | ||
|
|
00c0cc3d9e | ||
|
|
0eb0fd3311 | ||
|
|
4e3823616d | ||
|
|
7450bae6d2 | ||
|
|
a2ddaf5341 | ||
|
|
b266a0ae57 | ||
|
|
ac9e649e02 | ||
|
|
506e1a4c1d | ||
|
|
c9d74a4cdf | ||
|
|
0ff2e6e273 | ||
|
|
c4c6ab3130 | ||
|
|
bc5b7638db | ||
|
|
2db147461c | ||
|
|
716c44746b | ||
|
|
0278a3ad47 | ||
|
|
3601047ffb | ||
|
|
8013319c14 | ||
|
|
b4f14bcb5b | ||
|
|
406beab9d6 | ||
|
|
58a8828503 | ||
|
|
fd563b732c | ||
|
|
30093f9db5 | ||
|
|
2f16c54cde | ||
|
|
bca7f2e19b | ||
|
|
2696106f96 | ||
|
|
9f7692f91c | ||
|
|
48b2ff5416 | ||
|
|
81104d7004 | ||
|
|
b56103f247 | ||
|
|
0923cf3acf | ||
|
|
fffb7d0188 | ||
|
|
f02124de0c | ||
|
|
a1a77f291b | ||
|
|
31bb7f62c6 | ||
|
|
bfb5fc3f5e | ||
|
|
ac2e53adc7 | ||
|
|
46e8e161d0 | ||
|
|
68e2255e1b | ||
|
|
222c1b5bba | ||
|
|
59c63da36f | ||
|
|
89fb7a7659 | ||
|
|
ea02bc470a | ||
|
|
361dc576f3 | ||
|
|
395ad907b8 | ||
|
|
bf5cdb1b99 | ||
|
|
45f9c80888 | ||
|
|
b80a72785b | ||
|
|
20ab916f9c | ||
|
|
76bfaa870e | ||
|
|
10ed702c2e | ||
|
|
e236be7a62 | ||
|
|
2fbd183322 | ||
|
|
14df29ce21 | ||
|
|
cb3d9e4862 | ||
|
|
d9a82878bf | ||
|
|
e484bef6df | ||
|
|
c8d358cc64 | ||
|
|
013765d5d2 | ||
|
|
ed2b07d5cf | ||
|
|
8d0780cef4 | ||
|
|
2ba25014c6 | ||
|
|
033a770759 | ||
|
|
b7832c133a | ||
|
|
93af618fa0 | ||
|
|
d4539c3a23 | ||
|
|
3d70a5ac79 | ||
|
|
f40b2f75bd | ||
|
|
46a49050b9 | ||
|
|
fb4fd15687 | ||
|
|
f3e18de45f | ||
|
|
fd3b187d32 | ||
|
|
820b555924 | ||
|
|
f8a0e67a2e | ||
|
|
99e77969ad | ||
|
|
fdb6276869 | ||
|
|
221e252acb | ||
|
|
dea01ffed6 | ||
|
|
166769e7e1 | ||
|
|
86d3314cb2 | ||
|
|
13a08298b7 | ||
|
|
66d2323626 | ||
|
|
cd432e3b3f | ||
|
|
cbf73f5194 | ||
|
|
5cd03f40f6 | ||
|
|
25b5f53f34 | ||
|
|
f9902a6ea5 | ||
|
|
0099bf53cb | ||
|
|
e6a8cf7a10 | ||
|
|
9b6855b424 | ||
|
|
6df8383580 | ||
|
|
b12663f404 | ||
|
|
66d3df0c10 | ||
|
|
a61e74c004 | ||
|
|
3d0a39dd34 | ||
|
|
6f643b8a1b | ||
|
|
d39cc71240 | ||
|
|
501fab147d | ||
|
|
6ee6cd7a1e | ||
|
|
7d5586d9a1 | ||
|
|
db78d713e7 | ||
|
|
ece5dfb799 | ||
|
|
1cb6b82f25 | ||
|
|
b0728650df | ||
|
|
48b4049d90 | ||
|
|
7f8efcdf41 | ||
|
|
dfa356e9d9 | ||
|
|
964537219a | ||
|
|
07eecc860f | ||
|
|
faf25008f9 | ||
|
|
116a3563bb | ||
|
|
6880c88301 | ||
|
|
8590f4c383 | ||
|
|
ff1e034a87 | ||
|
|
b36948cf30 | ||
|
|
c01df71fd4 | ||
|
|
7d90571d50 | ||
|
|
0cc7e121c8 | ||
|
|
060cdbbf51 | ||
|
|
769a654ed6 | ||
|
|
469899e8eb | ||
|
|
024e0df8e1 | ||
|
|
7603829942 | ||
|
|
ad91ac9c93 | ||
|
|
7a22dead81 | ||
|
|
73bc5dd30e | ||
|
|
154157b976 | ||
|
|
c5551a1b64 | ||
|
|
0d292446a2 | ||
|
|
7ba0d0d3a0 | ||
|
|
88bd9216d0 | ||
|
|
d8b728a6b3 | ||
|
|
26acecb8e4 | ||
|
|
b64234a7a3 | ||
|
|
1ca5fd7204 | ||
|
|
6868d53224 | ||
|
|
993866ab5b | ||
|
|
3eddb524d0 | ||
|
|
956316c327 | ||
|
|
88ff734ec7 | ||
|
|
3fb6b34a1e | ||
|
|
81a4429767 | ||
|
|
73bf974b1c | ||
|
|
693fb9f43f | ||
|
|
b3e65aea9f | ||
|
|
bb149f9890 | ||
|
|
26d2c8188d | ||
|
|
051d45edce | ||
|
|
6e35d7683c | ||
|
|
da405793da | ||
|
|
ef9aa8e195 | ||
|
|
7899c3a49f | ||
|
|
3394409183 | ||
|
|
300cf10413 | ||
|
|
8203f75cc9 | ||
|
|
10e0453a54 | ||
|
|
b131c34717 | ||
|
|
94a0f44fc5 | ||
|
|
8a47d7dc0f | ||
|
|
7a18c86927 | ||
|
|
958a296662 | ||
|
|
d932a0a990 | ||
|
|
3060d89ed4 | ||
|
|
54447e187a | ||
|
|
e4d62cc4af | ||
|
|
83a1770bac | ||
|
|
fd9793a42f | ||
|
|
47ba8fe0af | ||
|
|
639df50a31 | ||
|
|
bded1eab15 | ||
|
|
4a06c7b0bb | ||
|
|
08775dcca9 | ||
|
|
011fd8d175 | ||
|
|
f2ef3644aa | ||
|
|
b3a319b336 | ||
|
|
667a39dfd3 | ||
|
|
8f9b9952ea | ||
|
|
444e39ce33 | ||
|
|
74ad038f21 | ||
|
|
00401befca | ||
|
|
f5bffd6f74 | ||
|
|
63ac23a999 | ||
|
|
41e4cacdd8 | ||
|
|
a61e0086e0 | ||
|
|
6f7ebb4cbf | ||
|
|
43db02f97d | ||
|
|
3d4c51c532 | ||
|
|
45718eb41a | ||
|
|
90d51b979a | ||
|
|
6261256dea | ||
|
|
b1a508f209 | ||
|
|
17eedeaf38 | ||
|
|
733919e1df | ||
|
|
7f7eec18bc | ||
|
|
7c70f8c9bc | ||
|
|
9473364fde | ||
|
|
f8fc909fe6 | ||
|
|
d5a42f2316 | ||
|
|
9837330be0 | ||
|
|
c99bc2c38d | ||
|
|
9896918c35 | ||
|
|
0e605c66c4 | ||
|
|
4bf7ef0e25 | ||
|
|
438fef9f26 | ||
|
|
489a00e2d2 | ||
|
|
a1dd5b4188 | ||
|
|
3b5c66d192 | ||
|
|
10df10abfd | ||
|
|
4e0607b09c | ||
|
|
96f8f2cb28 | ||
|
|
4d91b92a33 | ||
|
|
9ad96608cf | ||
|
|
73f4dcd828 | ||
|
|
95cff8b986 | ||
|
|
f2ffdc9e58 | ||
|
|
702abbf7b1 | ||
|
|
cc0076a204 | ||
|
|
3f64d1044b | ||
|
|
28a0dd8b97 | ||
|
|
1787dbde4d | ||
|
|
6c10bff565 | ||
|
|
479fec4c59 | ||
|
|
1533e0fe74 | ||
|
|
242416a25d | ||
|
|
03689c6a0b | ||
|
|
2e9f1c18e5 | ||
|
|
c405cd93be | ||
|
|
99bbff0d34 | ||
|
|
653debbbc2 | ||
|
|
2279eb8e31 | ||
|
|
f475fafbf1 | ||
|
|
52bb86ad78 | ||
|
|
535a590ffd | ||
|
|
b2143557bd | ||
|
|
a6c47f5122 | ||
|
|
fddb2db8c7 | ||
|
|
da58578d33 | ||
|
|
391821bf16 | ||
|
|
7ae314fb2c | ||
|
|
7b141a5eaa | ||
|
|
0b1357c2ee | ||
|
|
417072bf00 | ||
|
|
ff0fa1802d | ||
|
|
07e07e61ee | ||
|
|
4f939d7ea4 | ||
|
|
9fa4b97e5e | ||
|
|
b890813732 | ||
|
|
f9650c565c | ||
|
|
6eca35759f | ||
|
|
c927e58ce4 | ||
|
|
4c7ba04274 | ||
|
|
bb60813323 | ||
|
|
4fc7dd447e | ||
|
|
dc0b39d6b5 | ||
|
|
84058f9833 | ||
|
|
d78fc5bf9c | ||
|
|
d839037c09 | ||
|
|
cfe0ef8864 | ||
|
|
e2d12d766f | ||
|
|
e73647780c | ||
|
|
1de11365c1 | ||
|
|
7ebf8aca5b | ||
|
|
58b8f354e0 | ||
|
|
2bfcc7e0f2 | ||
|
|
a7ddc69679 | ||
|
|
86d1f9470e | ||
|
|
57a233d51b | ||
|
|
a021fcd951 | ||
|
|
3bfa49236e | ||
|
|
0e52416a9b | ||
|
|
a0f8258cad | ||
|
|
a2da057581 | ||
|
|
56cbe4c5b6 | ||
|
|
48c9bd6dfd | ||
|
|
a30b69db4c | ||
|
|
e57ddbb6eb | ||
|
|
f1068eacd8 | ||
|
|
b762741a6e | ||
|
|
1f59aaca43 | ||
|
|
53d4fd8547 | ||
|
|
0eea1ae0c6 | ||
|
|
43a2ca9407 | ||
|
|
30ed4179d6 | ||
|
|
6f715a663a | ||
|
|
1d30623222 | ||
|
|
4db71b4b0d | ||
|
|
fe6d698b74 | ||
|
|
7393b3c716 | ||
|
|
493fcb2f05 | ||
|
|
47c509c0a7 | ||
|
|
c98783d33f | ||
|
|
b71c9d7bf3 | ||
|
|
25ed49f1a6 | ||
|
|
cb0a3314b6 | ||
|
|
3880197d02 | ||
|
|
ec04da06d7 | ||
|
|
4654e9f7c7 | ||
|
|
fc3517584d | ||
|
|
8677e98a24 | ||
|
|
152dc13ded | ||
|
|
76ab6282a9 | ||
|
|
61b264cd70 | ||
|
|
3714fea994 | ||
|
|
e1a820d1f9 | ||
|
|
3f94dadcef | ||
|
|
e67d6ce53c | ||
|
|
13cf53e885 | ||
|
|
f95be0996d | ||
|
|
dbc5a1e45c | ||
|
|
dd30e4b3ec | ||
|
|
9468c0435a | ||
|
|
4be5933dc8 | ||
|
|
fe5ba06328 | ||
|
|
a2f5db8d3c | ||
|
|
b48e65a9d8 | ||
|
|
18471a201f | ||
|
|
1d61a3af8b | ||
|
|
e4f5b8f95c | ||
|
|
d31ab133f4 | ||
|
|
dcc15dd42b | ||
|
|
280f2c0af5 | ||
|
|
890264ef7d | ||
|
|
e9d58a4f74 | ||
|
|
9020798f90 | ||
|
|
7167df10e6 | ||
|
|
8bedd7aa2a | ||
|
|
357e747391 | ||
|
|
8c11721c75 | ||
|
|
da13235c88 | ||
|
|
aababce74c | ||
|
|
a395004027 | ||
|
|
0489394d67 | ||
|
|
4cde774cc2 | ||
|
|
baa2b105d3 | ||
|
|
9667d9ffa8 | ||
|
|
b8b85b569c | ||
|
|
27f2d05c56 | ||
|
|
49e1c0758d | ||
|
|
2299eb0e33 | ||
|
|
b6e17594c6 | ||
|
|
19c2724e8b | ||
|
|
7f4591bcec | ||
|
|
4de7ee4ce0 | ||
|
|
eb6f1718a8 | ||
|
|
36ce09c4f1 | ||
|
|
1994a615c2 | ||
|
|
82b75a5aa9 | ||
|
|
2ec91f58ae | ||
|
|
e9cd7ef5ca | ||
|
|
29aff06b1d | ||
|
|
18f3414f34 | ||
|
|
a7b236d528 | ||
|
|
46fdf03925 | ||
|
|
f67f31baa2 | ||
|
|
1fcbb8ea7d | ||
|
|
60ef682c80 | ||
|
|
c668a22345 | ||
|
|
cb69f011e5 | ||
|
|
176e96fd1f | ||
|
|
43e550b9b2 | ||
|
|
ee139d5ff0 | ||
|
|
5c5ec3e16c | ||
|
|
da82d679ce | ||
|
|
834a08d58d | ||
|
|
395485527e | ||
|
|
8c9fd45fcc | ||
|
|
59356b9f28 | ||
|
|
bb3cc84ca4 | ||
|
|
ac2c708d01 | ||
|
|
57497dbd74 | ||
|
|
827d0cdf5a | ||
|
|
e3539f17bd | ||
|
|
b88580ad9a | ||
|
|
8d8cceaeea | ||
|
|
290c7988b2 | ||
|
|
f97767aff4 | ||
|
|
fae14d4f9b | ||
|
|
699247266e | ||
|
|
5c8b80741f | ||
|
|
e5287d876b | ||
|
|
b3e6e42790 | ||
|
|
fce5b9696f | ||
|
|
f252ed63d5 | ||
|
|
3114d3a27d | ||
|
|
e186bfe80d | ||
|
|
3db2a4b30d | ||
|
|
1c25138eaf | ||
|
|
1807c95c53 | ||
|
|
7ea78ee48a | ||
|
|
5d57feaea5 | ||
|
|
f4583e46bf | ||
|
|
5ed00a67c4 | ||
|
|
0148c539be | ||
|
|
51cdf864be | ||
|
|
bd9ee49255 | ||
|
|
16c377427a | ||
|
|
66dcfa40b0 | ||
|
|
e726ef505f | ||
|
|
a686a2e9d1 | ||
|
|
720ee71f8b | ||
|
|
557cdf6cfb | ||
|
|
6b93675ec1 | ||
|
|
9419c4c639 | ||
|
|
7eb243a18f | ||
|
|
3a2b531d4c | ||
|
|
05068f8df5 | ||
|
|
a6d80667c1 | ||
|
|
a0dccadfd7 | ||
|
|
7992eab16c | ||
|
|
a1c6f720a2 | ||
|
|
a1162f1b0f | ||
|
|
80f21ae2f0 | ||
|
|
fce8623595 | ||
|
|
e82a5c8026 | ||
|
|
517d4cfc82 | ||
|
|
7f7f7e752e | ||
|
|
5963db479e | ||
|
|
96266ab310 | ||
|
|
c7f6b396e0 | ||
|
|
b7ca91f9e2 | ||
|
|
9ec7cdb070 | ||
|
|
3e1220fa0e | ||
|
|
660946215e | ||
|
|
a7b38335c9 | ||
|
|
e4803cc89d | ||
|
|
b104298c7d | ||
|
|
e049375bbc | ||
|
|
f48bd550b7 | ||
|
|
00ec064dc3 | ||
|
|
4c5409aa01 | ||
|
|
6166c87e16 | ||
|
|
159cd74c28 | ||
|
|
60ef83dd34 | ||
|
|
3c02c5957e | ||
|
|
bbef071931 | ||
|
|
726928aadc | ||
|
|
7ad386d28f | ||
|
|
a4c9bdef4a | ||
|
|
a64edc70ed | ||
|
|
f6826432d0 | ||
|
|
f29efa8f60 | ||
|
|
e7bcf489eb | ||
|
|
15d43f6313 | ||
|
|
a7f7374f96 | ||
|
|
de1a1cbe9a | ||
|
|
27a0e8ee3a | ||
|
|
db4f193046 | ||
|
|
118182a6cc | ||
|
|
442b3bd233 | ||
|
|
12c96f321b | ||
|
|
f77d8d5219 | ||
|
|
b7d5a3f9c6 | ||
|
|
b887ca01d0 | ||
|
|
179ff9b10a | ||
|
|
4c18629cd7 | ||
|
|
295e79984f | ||
|
|
8f910f95f4 | ||
|
|
ee55055385 | ||
|
|
674edfc330 | ||
|
|
c33e5029df | ||
|
|
a2f205362a | ||
|
|
3d6771b3d2 | ||
|
|
fe9ff0c337 | ||
|
|
754545cc40 | ||
|
|
aab45b1b14 | ||
|
|
9eaa00e878 | ||
|
|
8520ca44ee | ||
|
|
6b8ac5e939 | ||
|
|
5767acb5bf | ||
|
|
9e3fc97727 | ||
|
|
7817499da7 | ||
|
|
1c43e92577 | ||
|
|
3e4f945d56 | ||
|
|
491c4d25d7 | ||
|
|
2432d57d70 | ||
|
|
9408b592fd | ||
|
|
743f192d85 | ||
|
|
4e47b0acb7 | ||
|
|
43ab4e1e42 | ||
|
|
9b28cdbcd2 | ||
|
|
acb29c33d3 | ||
|
|
e3eee3dc02 | ||
|
|
e3eae25caa | ||
|
|
cc23869128 | ||
|
|
36c11961b6 | ||
|
|
f21dc94979 | ||
|
|
d4ab850e7b | ||
|
|
edf6e075f2 | ||
|
|
92c3b8314d | ||
|
|
33260fc820 | ||
|
|
5b5afec84d | ||
|
|
d818e697e9 | ||
|
|
03edb20265 | ||
|
|
4157062442 | ||
|
|
2f46645149 | ||
|
|
31f4576acd | ||
|
|
e1d85b0a04 | ||
|
|
961cf347da | ||
|
|
02c4655f0d | ||
|
|
b7b94ca900 | ||
|
|
8671b52cbb | ||
|
|
9fe045b916 | ||
|
|
4d2a914719 | ||
|
|
1cfcf03ede | ||
|
|
a81d2e9ccc | ||
|
|
d7cf2c19ab |
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
@@ -2,8 +2,7 @@
|
|||||||
name: Bug report (bluescreen crash) Bug报告 (蓝屏报错)
|
name: Bug report (bluescreen crash) Bug报告 (蓝屏报错)
|
||||||
about: Create a report of problems which made the crash with a bluescreen
|
about: Create a report of problems which made the crash with a bluescreen
|
||||||
---
|
---
|
||||||
Screenshot with crash information:
|
Screenshot with crash information (*Image(s) Here*):
|
||||||
*Image Here*
|
|
||||||
|
|
||||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button:
|
|
||||||
*Details Here*
|
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*)
|
||||||
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
@@ -2,8 +2,7 @@
|
|||||||
name: Bug report (unintended behaviors) Bug报告 (奇怪的现象)
|
name: Bug report (unintended behaviors) Bug报告 (奇怪的现象)
|
||||||
about: Create a report of unintended behaviors
|
about: Create a report of unintended behaviors
|
||||||
---
|
---
|
||||||
Screenshot with unintended behaviors:
|
Screenshot with unintended behaviors (*Image(s) Here*):
|
||||||
*Image(s) Here*
|
|
||||||
|
|
||||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button:
|
|
||||||
*Details Here*
|
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*):
|
||||||
|
|||||||
24
.github/actions/automatic-test/action.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: 'Automatic Test'
|
||||||
|
description: 'Check for obvious errors.'
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
with:
|
||||||
|
file-path: Techmino.love
|
||||||
|
- name: Download love
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -L https://github.com/love2d/love/releases/download/11.3/love-11.3-linux-x86_64.tar.gz | tar xz
|
||||||
|
- name: Prepare PulseAudio
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install pulseaudio pulseaudio-utils pavucontrol alsa-oss alsa-utils -y
|
||||||
|
- name: Run automated test
|
||||||
|
uses: GabrielBB/xvfb-action@v1
|
||||||
|
with:
|
||||||
|
run: |
|
||||||
|
./dest/love Techmino.love --test
|
||||||
102
.github/actions/build-android/action.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
name: 'build Android'
|
||||||
|
description: 'build Android package'
|
||||||
|
inputs:
|
||||||
|
type:
|
||||||
|
required: true
|
||||||
|
apkCode:
|
||||||
|
required: true
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
file-path:
|
||||||
|
required: true
|
||||||
|
SIGNING_KEY:
|
||||||
|
required: true
|
||||||
|
KEY_STORE_PASSWORD:
|
||||||
|
required: true
|
||||||
|
ALIAS:
|
||||||
|
required: true
|
||||||
|
KEY_PASSWORD:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: '8'
|
||||||
|
- name: Clone love-android
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --recurse-submodules https://github.com/26F-Studio/love-android -b CI --depth 1 --shallow-submodules
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
with:
|
||||||
|
file-path: love-android/app/src/main/assets/game.love
|
||||||
|
- name: Download ColdClear arm64-v8a
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: android_aarch64
|
||||||
|
dir: ColdClear/arm64-v8a
|
||||||
|
- name: Process ColdClear arm64-v8a
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p love-android/app/libs/arm64-v8a
|
||||||
|
mv ColdClear/arm64-v8a/love-11.3-android/lib/arm64-v8a/libcold_clear.so love-android/app/libs/arm64-v8a
|
||||||
|
mkdir -p libAndroid/arm64-v8a
|
||||||
|
mv ColdClear/arm64-v8a/libs/arm64-v8a/libCCloader.so libAndroid/arm64-v8a
|
||||||
|
- name: Download ColdClear armeabi-v7a
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: android_armv7
|
||||||
|
dir: ColdClear/armeabi-v7a
|
||||||
|
- name: Process ColdClear armeabi-v7a
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p love-android/app/libs/armeabi-v7a
|
||||||
|
mv ColdClear/armeabi-v7a/love-11.3-android/lib/armeabi-v7a/libcold_clear.so love-android/app/libs/armeabi-v7a
|
||||||
|
mkdir -p libAndroid/armeabi-v7a
|
||||||
|
mv ColdClear/armeabi-v7a/libs/armeabi-v7a/libCCloader.so libAndroid/armeabi-v7a
|
||||||
|
- name: Pack ColdClear
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
7z a -tzip love-android/app/src/main/assets/game.love libAndroid
|
||||||
|
- name: update Android information
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
if '${{ inputs.type }}' == 'Release':
|
||||||
|
appName = 'Techmino'
|
||||||
|
packageName = 'org.love2d.MrZ.Techmino'
|
||||||
|
edition = 'release'
|
||||||
|
elif '${{ inputs.type }}' == 'Snapshot':
|
||||||
|
appName = 'Techmino_Snapshot'
|
||||||
|
packageName = 'org.love2d.MrZ.Techmino.Snapshot'
|
||||||
|
edition = 'snapshot'
|
||||||
|
with open('./love-android/app/src/main/AndroidManifest.xml', "r+", encoding='utf-8') as file:
|
||||||
|
data = file.read()
|
||||||
|
data = data\
|
||||||
|
.replace('@appName', appName)\
|
||||||
|
.replace('@edition', edition)
|
||||||
|
file.seek(0)
|
||||||
|
file.truncate()
|
||||||
|
file.write(data)
|
||||||
|
with open("./love-android/app/build.gradle", "r+", encoding='utf-8') as file:
|
||||||
|
data = file.read()
|
||||||
|
data = data\
|
||||||
|
.replace('@packageName', packageName)\
|
||||||
|
.replace('@versionCode', '${{ inputs.apkCode }}')\
|
||||||
|
.replace('@versionName', '${{ inputs.name }}')\
|
||||||
|
.replace('@storePassword', '${{ inputs.KEY_STORE_PASSWORD }}')\
|
||||||
|
.replace('@keyAlias', '${{ inputs.ALIAS }}')\
|
||||||
|
.replace('@keyPassword', '${{ inputs.KEY_PASSWORD }}')
|
||||||
|
file.seek(0)
|
||||||
|
file.truncate()
|
||||||
|
file.write(data)
|
||||||
|
- name: Build Techmino
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "${{ inputs.SIGNING_KEY }}" | base64 -d > love-android/app/android.keystore
|
||||||
|
chmod 777 love-android/gradlew
|
||||||
|
cd love-android/
|
||||||
|
./gradlew assembleRelease
|
||||||
|
- name: rename apk
|
||||||
|
shell: bash
|
||||||
|
run: mv love-android/app/build/outputs/apk/release/app-release.apk ${{ inputs.file-path }}
|
||||||
96
.github/actions/build-ios/action.yml
vendored
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
name: 'build iOS'
|
||||||
|
description: 'build iOS package'
|
||||||
|
inputs:
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
description: "Version name"
|
||||||
|
type:
|
||||||
|
required: true
|
||||||
|
description: "Build type"
|
||||||
|
APPLE_API_ID:
|
||||||
|
required: true
|
||||||
|
description: "API key ID"
|
||||||
|
APPLE_API_ISSUER:
|
||||||
|
required: true
|
||||||
|
description: "API issuer ID"
|
||||||
|
APPLE_API_KEY:
|
||||||
|
required: true
|
||||||
|
description: "API key content"
|
||||||
|
APPLE_APP_BUILD:
|
||||||
|
required: true
|
||||||
|
description: "Build number"
|
||||||
|
APPLE_APP_CHANGELOG:
|
||||||
|
required: true
|
||||||
|
description: "Changelog"
|
||||||
|
APPLE_APP_ID:
|
||||||
|
required: true
|
||||||
|
description: "AppStore Apple ID"
|
||||||
|
APPLE_APP_IDENTIFIER:
|
||||||
|
required: true
|
||||||
|
description: "Bundle ID"
|
||||||
|
APPLE_APP_PROFILE:
|
||||||
|
required: true
|
||||||
|
description: "Provisioning Profile specifer"
|
||||||
|
APPLE_KEYCHAIN_NAME:
|
||||||
|
required: true
|
||||||
|
description: "Temporary keychain name"
|
||||||
|
APPLE_KEYCHAIN_PWD:
|
||||||
|
required: true
|
||||||
|
description: "Temporary keychain password"
|
||||||
|
FASTLANE_DISCORD_WEBHOOK:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Discord webhook"
|
||||||
|
FASTLANE_ACTION_ID:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Action ID"
|
||||||
|
FASTLANE_MATCH_PWD:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Match description password"
|
||||||
|
FASTLANE_MATCH_TOKEN:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Match Github token"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
- name: Checkout source codes
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: '26F-Studio/Techmino-iOS'
|
||||||
|
path: 'Techmino-iOS'
|
||||||
|
- name: Download CCloader
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: iOS
|
||||||
|
- name: Update source codes
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv Techmino.love Techmino-iOS/platform/xcode
|
||||||
|
mv libcold_clear.a Techmino-iOS/platform/xcode
|
||||||
|
mv libCCloader.a Techmino-iOS/platform/xcode
|
||||||
|
- name: Run fastlane
|
||||||
|
uses: maierj/fastlane-action@v2.0.1
|
||||||
|
with:
|
||||||
|
lane: '${{ inputs.type }}'
|
||||||
|
subdirectory: 'Techmino-iOS/platform/xcode'
|
||||||
|
env:
|
||||||
|
ACTION_ID: '${{ inputs.FASTLANE_ACTION_ID }}'
|
||||||
|
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||||
|
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||||
|
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||||
|
APP_BUILD: '${{ inputs.APPLE_APP_BUILD }}'
|
||||||
|
APP_CHANGELOG: '${{ inputs.APPLE_APP_CHANGELOG }}'
|
||||||
|
APP_ID: '${{ inputs.APPLE_APP_ID }}'
|
||||||
|
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||||
|
APP_PROFILE: '${{ inputs.APPLE_APP_PROFILE }}'
|
||||||
|
APP_VERSION: '${{ inputs.name }}'
|
||||||
|
DISCORD_WEBHOOK: '${{ inputs.FASTLANE_DISCORD_WEBHOOK }}'
|
||||||
|
KEYCHAIN_NAME: '${{ inputs.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
KEYCHAIN_PWD: '${{ inputs.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
||||||
|
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Move ipa
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv Techmino-iOS/platform/xcode/Techmino.ipa Techmino.ipa
|
||||||
|
|
||||||
40
.github/actions/build-linux/action.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: 'build Linux'
|
||||||
|
description: 'build Linux package'
|
||||||
|
inputs:
|
||||||
|
file-path:
|
||||||
|
required: false
|
||||||
|
default: Techmino.AppImage
|
||||||
|
icon:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Download AppImageKit
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -OL https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
|
||||||
|
- name: Download love
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-x86_64.AppImage
|
||||||
|
chmod 777 love-11.3-x86_64.AppImage
|
||||||
|
./love-11.3-x86_64.AppImage --appimage-extract
|
||||||
|
- name: Download ColdClear
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: linux
|
||||||
|
- name: Pack Techmino
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
rm -rf squashfs-root/love squashfs-root/love.desktop squashfs-root/love.svg squashfs-root/.DirIcon
|
||||||
|
mv .github/build/Linux/love.template squashfs-root/love
|
||||||
|
mv .github/build/Linux/Techmino.desktop.template squashfs-root/Techmino.desktop
|
||||||
|
mv ${{ inputs.icon }} squashfs-root/icon.png
|
||||||
|
cp squashfs-root/icon.png squashfs-root/.DirIcon
|
||||||
|
chmod 777 squashfs-root/love
|
||||||
|
mkdir -p squashfs-root/usr/share/Techmino
|
||||||
|
mv media parts Zframework conf.lua main.lua version.lua legals.md license.txt squashfs-root/usr/share/Techmino
|
||||||
|
mv CCloader.so squashfs-root/usr/share/Techmino
|
||||||
|
mv libcold_clear.so squashfs-root/usr/lib
|
||||||
|
chmod 777 appimagetool-x86_64.AppImage
|
||||||
|
./appimagetool-x86_64.AppImage squashfs-root ${{ inputs.file-path }}
|
||||||
11
.github/actions/build-love/action.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
name: 'build love'
|
||||||
|
description: 'build love file'
|
||||||
|
inputs:
|
||||||
|
file-path:
|
||||||
|
required: true
|
||||||
|
default: Techmino.love
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua legals.md license.txt
|
||||||
|
shell: bash
|
||||||
152
.github/actions/build-macos/action.yml
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
name: 'build Mac OS'
|
||||||
|
description: 'build Mac OS package'
|
||||||
|
inputs:
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
description: "Version name"
|
||||||
|
icon:
|
||||||
|
required: true
|
||||||
|
description: "App icons (.icns)"
|
||||||
|
APPLE_API_ID:
|
||||||
|
required: true
|
||||||
|
description: "API key ID"
|
||||||
|
APPLE_API_ISSUER:
|
||||||
|
required: true
|
||||||
|
description: "API issuer ID"
|
||||||
|
APPLE_API_KEY:
|
||||||
|
required: true
|
||||||
|
description: "API key content"
|
||||||
|
APPLE_APP_IDENTIFIER:
|
||||||
|
required: true
|
||||||
|
description: "Bundle ID"
|
||||||
|
APPLE_KEYCHAIN_NAME:
|
||||||
|
required: true
|
||||||
|
description: "Temporary keychain name"
|
||||||
|
APPLE_KEYCHAIN_PWD:
|
||||||
|
required: true
|
||||||
|
description: "Temporary keychain password"
|
||||||
|
FASTLANE_MATCH_PWD:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Match description password"
|
||||||
|
FASTLANE_MATCH_TOKEN:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Match Github token"
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
- name: Checkout template
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: '26F-Studio/Techmino-macOS'
|
||||||
|
path: 'Techmino-macOS'
|
||||||
|
- name: Download ColdClear
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: macOS
|
||||||
|
- name: Fastlane match
|
||||||
|
uses: maierj/fastlane-action@v2.0.1
|
||||||
|
with:
|
||||||
|
lane: 'get_cert'
|
||||||
|
subdirectory: 'Techmino-macOS'
|
||||||
|
env:
|
||||||
|
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||||
|
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||||
|
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||||
|
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||||
|
KEYCHAIN_NAME: '${{ inputs.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
KEYCHAIN_PWD: '${{ inputs.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
||||||
|
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Modify template
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
import datetime
|
||||||
|
from io import open
|
||||||
|
thisYear = str(datetime.datetime.today().year)
|
||||||
|
with open('./.github/build/macOS/info.plist.template', 'r', encoding='utf-8') as file:
|
||||||
|
data = file.read()
|
||||||
|
data = data\
|
||||||
|
.replace('@versionName', '${{ inputs.name }}'[1:])\
|
||||||
|
.replace('@thisYear', thisYear)\
|
||||||
|
.replace('@bundleId', '${{ inputs.APPLE_APP_IDENTIFIER }}')
|
||||||
|
with open('./Techmino-macOS/Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
|
||||||
|
file.write(data)
|
||||||
|
- name: Pack
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv Techmino.love Techmino-macOS/Techmino.app/Contents/Resources
|
||||||
|
mv CCloader.dylib Techmino-macOS/Techmino.app/Contents/Frameworks
|
||||||
|
mv ${{ inputs.icon }} Techmino-macOS/Techmino.app/Contents/Resources/iconfile.icns
|
||||||
|
|
||||||
|
chmod +x Techmino-macOS/Techmino.app/Contents/Frameworks/CCloader.dylib
|
||||||
|
chmod +x Techmino-macOS/Techmino.app/Contents/MacOS/love
|
||||||
|
- name: Codesign executable
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
security unlock-keychain -p ${{ inputs.TEMP_KEYCHAIN_PASSWORD }} \
|
||||||
|
~/Library/Keychains/${{ inputs.TEMP_KEYCHAIN_USER }}-db
|
||||||
|
|
||||||
|
[[ $(security find-identity) =~ ([0-9A-F]{40}) ]]
|
||||||
|
|
||||||
|
codesign --timestamp --force --strict --deep -v \
|
||||||
|
--options runtime \
|
||||||
|
-s ${BASH_REMATCH[1]} \
|
||||||
|
--entitlements Techmino-macOS/love.entitlements \
|
||||||
|
Techmino-macOS/Techmino.app
|
||||||
|
- name: Fastlane notarize
|
||||||
|
uses: maierj/fastlane-action@v2.0.1
|
||||||
|
with:
|
||||||
|
lane: 'make_safe'
|
||||||
|
subdirectory: 'Techmino-macOS'
|
||||||
|
env:
|
||||||
|
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||||
|
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||||
|
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||||
|
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||||
|
NOTARIZE_OBJECT: 'Techmino.app'
|
||||||
|
- name: Create DMG file
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew install create-dmg
|
||||||
|
create-dmg \
|
||||||
|
--volname "Techmino for MacOS" \
|
||||||
|
--volicon "./.github/build/macOS/Techminodisk.icns" \
|
||||||
|
--window-pos 200 120 \
|
||||||
|
--window-size 800 500 \
|
||||||
|
--icon-size 100 \
|
||||||
|
--icon "Techmino.app" 239 203 \
|
||||||
|
--background ".github/build/macOS/backgroundImage.tiff" \
|
||||||
|
--hide-extension "Techmino.app" \
|
||||||
|
--app-drop-link 565 203 \
|
||||||
|
"Techmino-macOS/Techmino-macOS.dmg" \
|
||||||
|
"Techmino-macOS/Techmino.app/"
|
||||||
|
- name: Codesign DMG
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
security unlock-keychain -p ${{ inputs.TEMP_KEYCHAIN_PASSWORD }} \
|
||||||
|
~/Library/Keychains/${{ inputs.TEMP_KEYCHAIN_USER }}-db
|
||||||
|
|
||||||
|
[[ $(security find-identity) =~ ([0-9A-F]{40}) ]]
|
||||||
|
|
||||||
|
codesign --timestamp --force --strict --deep -v \
|
||||||
|
--options runtime \
|
||||||
|
-s ${BASH_REMATCH[1]} \
|
||||||
|
--entitlements Techmino-macOS/love.entitlements \
|
||||||
|
Techmino-macOS/Techmino-macOS.dmg
|
||||||
|
- name: Fastlane notarize
|
||||||
|
uses: maierj/fastlane-action@v2.0.1
|
||||||
|
with:
|
||||||
|
lane: 'make_safe'
|
||||||
|
subdirectory: 'Techmino-macOS'
|
||||||
|
env:
|
||||||
|
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||||
|
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||||
|
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||||
|
APP_IDENTIFIER: '${{ inputs.APPLE_APP_IDENTIFIER }}'
|
||||||
|
NOTARIZE_OBJECT: 'Techmino-macOS.dmg'
|
||||||
|
- name: Finalize
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mv Techmino-macOS/Techmino-macOS.dmg Techmino.dmg
|
||||||
|
spctl -a -t open --context context:primary-signature -vv Techmino.dmg
|
||||||
60
.github/actions/build-windows/action.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: 'build Windows'
|
||||||
|
description: 'build Windows package'
|
||||||
|
inputs:
|
||||||
|
love-url:
|
||||||
|
required: true
|
||||||
|
love-dir:
|
||||||
|
required: true
|
||||||
|
arch:
|
||||||
|
required: true
|
||||||
|
version:
|
||||||
|
required: true
|
||||||
|
icon:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Download love
|
||||||
|
uses: ./.github/actions/get-unzip
|
||||||
|
with:
|
||||||
|
url: ${{ inputs.love-url }}
|
||||||
|
- name: move love
|
||||||
|
shell: bash
|
||||||
|
run: mv ${{ inputs.love-dir }} love
|
||||||
|
- name: Download ColdClear
|
||||||
|
uses: ./.github/actions/get-cc
|
||||||
|
with:
|
||||||
|
arch: ${{ inputs.arch }}
|
||||||
|
- name: Download ResourceHacker
|
||||||
|
uses: ./.github/actions/get-unzip
|
||||||
|
with:
|
||||||
|
url: http://www.angusj.com/resourcehacker/resource_hacker.zip
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
- name: update Windows template
|
||||||
|
shell: python
|
||||||
|
run: |
|
||||||
|
Version = '${{ inputs.version }}'.replace('V', '')
|
||||||
|
FileVersion = (f"{Version.replace('.', ',')},0")
|
||||||
|
with open('./.github/build/Windows/Techmino.rc.template', 'r', encoding='utf8') as file:
|
||||||
|
data = file.read()
|
||||||
|
data = data\
|
||||||
|
.replace('@FileVersion', FileVersion)\
|
||||||
|
.replace('@Version', Version)
|
||||||
|
with open('Techmino.rc', 'w+', encoding='utf8') as file:
|
||||||
|
file.write(data)
|
||||||
|
- name: Pack Techmino
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
cmd /c copy /b .\love\love.exe + .\Techmino.love .\love\Techmino.exe
|
||||||
|
del .\love\love.exe
|
||||||
|
del .\love\lovec.exe
|
||||||
|
del .\love\game.ico
|
||||||
|
del .\love\love.ico
|
||||||
|
del .\love\changes.txt
|
||||||
|
del .\love\readme.txt
|
||||||
|
move .\cold_clear.dll .\love
|
||||||
|
move .\CCloader.dll .\love
|
||||||
|
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action delete -mask ICONGROUP,,'
|
||||||
|
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
|
||||||
|
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action addoverwrite -res "${{ inputs.icon }}" -mask ICONGROUP,1,'
|
||||||
|
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action addoverwrite -res ".\Techmino.res" -mask VERSIONINFO,1,'
|
||||||
32
.github/actions/get-cc/action.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: 'get cc'
|
||||||
|
description: 'download cc into specific dir'
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
required: false
|
||||||
|
default:
|
||||||
|
arch:
|
||||||
|
required: true
|
||||||
|
dir:
|
||||||
|
required: false
|
||||||
|
default: '.'
|
||||||
|
repo:
|
||||||
|
required: false
|
||||||
|
default: 26F-Studio/cold_clear_ai_love2d_wrapper
|
||||||
|
temp-file:
|
||||||
|
required: false
|
||||||
|
default: temp.zip
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
echo "::set-output name=tag::"$(if [ -z "${{ inputs.tag }}" ]
|
||||||
|
then curl -w '%{url_effective}' -I -L -s -S https://github.com/${{ inputs.repo }}/releases/latest -o /dev/null | grep -o '\<[^/]*$'
|
||||||
|
else echo ${{ inputs.tag }}
|
||||||
|
fi)
|
||||||
|
id: get-tag
|
||||||
|
shell: bash
|
||||||
|
- uses: ./.github/actions/get-unzip
|
||||||
|
with:
|
||||||
|
url: https://github.com/${{ inputs.repo }}/releases/download/${{ steps.get-tag.outputs.tag }}/${{ inputs.arch }}.zip
|
||||||
|
dir: ${{ inputs.dir }}
|
||||||
|
temp-file: ${{ inputs.temp-file }}
|
||||||
18
.github/actions/get-unzip/action.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: 'get and unzip'
|
||||||
|
description: 'cURL and then 7-zip x'
|
||||||
|
inputs:
|
||||||
|
url:
|
||||||
|
required: true
|
||||||
|
dir:
|
||||||
|
required: false
|
||||||
|
default: '.'
|
||||||
|
temp-file:
|
||||||
|
required: false
|
||||||
|
default: temp.zip
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- run: curl -L ${{ inputs.url }} -o ${{ inputs.temp-file }}
|
||||||
|
shell: bash
|
||||||
|
- run: 7z x ${{ inputs.temp-file }} -o${{ inputs.dir }}
|
||||||
|
shell: bash
|
||||||
37
.github/actions/update-version/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: 'update version'
|
||||||
|
description: 'common update logic for snapshot and release'
|
||||||
|
inputs:
|
||||||
|
commit:
|
||||||
|
required: false
|
||||||
|
type:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- shell: python
|
||||||
|
name: update snapshot saving folder
|
||||||
|
run: |
|
||||||
|
from io import open
|
||||||
|
if '${{ inputs.type }}'.lower() != 'snapshot':
|
||||||
|
exit(0)
|
||||||
|
with open('conf.lua', 'r+', encoding='utf-8') as file:
|
||||||
|
data = file.read()
|
||||||
|
data = data.replace("t.identity='Techmino'--Saving folder", "t.identity='Techmino_Snapshot'--Saving folder")
|
||||||
|
file.seek(0)
|
||||||
|
file.truncate()
|
||||||
|
file.flush()
|
||||||
|
file.write(data)
|
||||||
|
- shell: python
|
||||||
|
run: |
|
||||||
|
from io import open
|
||||||
|
import re
|
||||||
|
with open('version.lua', 'r+', encoding='utf-8') as file:
|
||||||
|
commitHash = '${{ inputs.commit }}'
|
||||||
|
if commitHash != '':
|
||||||
|
commitHash = '@' + commitHash[0:4]
|
||||||
|
data = file.read()
|
||||||
|
data = re.sub('(\d)"', r'\1' + commitHash + '"', data, 1)
|
||||||
|
file.seek(0)
|
||||||
|
file.truncate()
|
||||||
|
file.flush()
|
||||||
|
file.write(data)
|
||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
23
.github/build/Windows/Techmino.rc.template
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION @FileVersion
|
||||||
|
PRODUCTVERSION @FileVersion
|
||||||
|
FILEOS 0x40004
|
||||||
|
FILETYPE 0x1
|
||||||
|
{
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
{
|
||||||
|
BLOCK "040904B0"
|
||||||
|
{
|
||||||
|
VALUE "FileDescription", "Techmino Alpha"
|
||||||
|
VALUE "CompanyName", "26F Studio"
|
||||||
|
VALUE "LegalCopyright", "Copyright @ 26F Studio"
|
||||||
|
VALUE "ProductName", "Techmino"
|
||||||
|
VALUE "ProductVersion", "@Version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
{
|
||||||
|
VALUE "Translation", 0x0409 0x04E4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
.github/build/macOS/Techminodisk.icns
vendored
Normal file
BIN
.github/build/macOS/backgroundImage.tiff
vendored
Normal file
BIN
.github/build/macOS/icon.icns
vendored
Normal file
BIN
.github/build/macOS/icon_snapshot.icns
vendored
Normal file
56
.github/build/macOS/info.plist.template
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildMachineOSBuild</key>
|
||||||
|
<string>19B88</string>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>love</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>iconfile</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>@bundleId</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>Techmino</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>@versionName</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>LoVe</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>MacOSX</string>
|
||||||
|
</array>
|
||||||
|
<key>DTCompiler</key>
|
||||||
|
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||||
|
<key>DTPlatformBuild</key>
|
||||||
|
<string>11C504</string>
|
||||||
|
<key>DTPlatformVersion</key>
|
||||||
|
<string>GM</string>
|
||||||
|
<key>DTSDKBuild</key>
|
||||||
|
<string>19B90</string>
|
||||||
|
<key>DTSDKName</key>
|
||||||
|
<string>macosx10.15</string>
|
||||||
|
<key>DTXcode</key>
|
||||||
|
<string>1130</string>
|
||||||
|
<key>DTXcodeBuild</key>
|
||||||
|
<string>11C504</string>
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.games</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>10.7</string>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
246
.github/workflows/build.yml
vendored
@@ -1,246 +0,0 @@
|
|||||||
name: Techmino CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main, ci ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-windows:
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Download lua
|
|
||||||
run: |
|
|
||||||
curl -OL https://nchc.dl.sourceforge.net/project/luabinaries/5.4.2/Tools%20Executables/lua-5.4.2_Win64_bin.zip
|
|
||||||
- name: Unpack lua
|
|
||||||
run: |
|
|
||||||
7z x .\lua-5.4.2_Win64_bin.zip -olua
|
|
||||||
rename-Item '.\lua\lua54.exe' -NewName 'lua.exe'
|
|
||||||
- name: Get CommitID
|
|
||||||
run: |
|
|
||||||
$CommitID=git rev-parse --short "${{ GITHUB.SHA }}"
|
|
||||||
echo "CommitID=${CommitID}" >> $env:GITHUB_ENV
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
$Version=.\lua\lua.exe .\.github\workflows\getVersion.lua -name
|
|
||||||
echo "Version=${Version}" >> $env:GITHUB_ENV
|
|
||||||
- name: Update Conf
|
|
||||||
run: |
|
|
||||||
python .\.github\workflows\updateVersion.py -T Conf
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python .\.github\workflows\updateVersion.py -T Version -H ${{ env.CommitID }}
|
|
||||||
- name: Download love
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
|
||||||
- name: Unpack love
|
|
||||||
run: |
|
|
||||||
7z x .\love-11.3-win64.zip
|
|
||||||
- name: Download ColdClear
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/cold_clear_ai_love2d_wrapper/releases/download/latest/win64.zip
|
|
||||||
- name: Unpack ColdClear
|
|
||||||
run: |
|
|
||||||
7z x .\win64.zip -oColdClear
|
|
||||||
- name: Download ResourceHacker
|
|
||||||
run: |
|
|
||||||
curl -OL http://www.angusj.com/resourcehacker/resource_hacker.zip
|
|
||||||
- name: Unpack ResourceHacker
|
|
||||||
run: |
|
|
||||||
7z x .\resource_hacker.zip
|
|
||||||
- name: Pack Techmino
|
|
||||||
run: |
|
|
||||||
7z a -tzip .\Techmino.love .\document .\media .\parts .\Zframework .\conf.lua .\font.ttf .\main.lua .\version.lua
|
|
||||||
cmd /c copy /b .\love-11.3-win64\love.exe + .\Techmino.love .\love-11.3-win64\Techmino.exe
|
|
||||||
del .\love-11.3-win64\love.exe
|
|
||||||
del .\love-11.3-win64\lovec.exe
|
|
||||||
del .\love-11.3-win64\game.ico
|
|
||||||
del .\love-11.3-win64\love.ico
|
|
||||||
del .\love-11.3-win64\changes.txt
|
|
||||||
del .\love-11.3-win64\readme.txt
|
|
||||||
move .\ColdClear\cold_clear.dll .\love-11.3-win64
|
|
||||||
move .\ColdClear\CCloader.dll .\love-11.3-win64
|
|
||||||
python .\.github\workflows\updateVersion.py -T Windows -N ${{ env.Version }}
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action delete -mask ICONGROUP,,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action addoverwrite -res ".\build\Windows\icon.ico" -mask ICONGROUP,1,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action addoverwrite -res ".\Techmino.res" -mask VERSIONINFO,1,'
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: Techmino_${{ env.Version }}_${{ GITHUB.RUN_NUMBER }}_${{ env.CommitID }}_Windows
|
|
||||||
path: love-11.3-win64
|
|
||||||
|
|
||||||
build-linux:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install lua
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Get CommitID
|
|
||||||
run: |
|
|
||||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
|
||||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Update Conf
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Conf
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version -H ${{ env.CommitID }}
|
|
||||||
#我不是很懂这里为什么不能用https://github.com/AppImage/AppImageKit/releases/download/latest/appimagetool-x86_64.AppImage 但是事实就是它404了
|
|
||||||
- name: Download AppImageKit
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
|
|
||||||
- name: Download love
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-x86_64.AppImage
|
|
||||||
- name: Unpack love
|
|
||||||
run: |
|
|
||||||
chmod 777 ./love-11.3-x86_64.AppImage
|
|
||||||
./love-11.3-x86_64.AppImage --appimage-extract
|
|
||||||
- name: Download ColdClear
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/cold_clear_ai_love2d_wrapper/releases/download/latest/linux.zip
|
|
||||||
- name: Unpack ColdClear
|
|
||||||
run: |
|
|
||||||
7z x ./linux.zip -oColdClear
|
|
||||||
- name: Pack Techmino
|
|
||||||
run: |
|
|
||||||
rm -rf ./squashfs-root/love ./squashfs-root/love.desktop ./squashfs-root/love.svg ./squashfs-root/.DirIcon
|
|
||||||
mv ./build/Linux/love.template ./squashfs-root/love
|
|
||||||
mv ./build/Linux/Techmino.desktop.template ./squashfs-root/Techmino.desktop
|
|
||||||
mv ./build/Linux/icon_snapshot.png ./squashfs-root/icon.png
|
|
||||||
cp ./squashfs-root/icon.png ./squashfs-root/.DirIcon
|
|
||||||
chmod 777 ./squashfs-root/love
|
|
||||||
mkdir -p ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./document ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./ColdClear/CCloader.so ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./ColdClear/libcold_clear.so ./squashfs-root/usr/lib
|
|
||||||
chmod 777 ./appimagetool-x86_64.AppImage
|
|
||||||
./appimagetool-x86_64.AppImage ./squashfs-root ./Techmino.AppImage
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: Techmino_${{ env.Version }}_${{ GITHUB.RUN_NUMBER }}_${{ env.CommitID }}_Linux
|
|
||||||
path: Techmino.AppImage
|
|
||||||
|
|
||||||
#Android待更新
|
|
||||||
build-android:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install lua
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Get CommitID
|
|
||||||
run: |
|
|
||||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
|
||||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Update Conf
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Conf
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version -H ${{ env.CommitID }}
|
|
||||||
- name: Download Apktool
|
|
||||||
run: curl -OL https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.5.0.jar
|
|
||||||
- name: Unpack and Repack
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.apk
|
|
||||||
java -jar ./apktool_2.5.0.jar d -s -o apk ./Techmino.apk
|
|
||||||
7z x ./apk/assets/game.love libAndroid -o.
|
|
||||||
rm -rf ./apk/assets/game.love ./Techmino.apk
|
|
||||||
7z a -tzip ./apk/assets/game.love ./document ./libAndroid ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Android -C $(lua ./.github/workflows/getVersion.lua -code) -N ${{ env.Version }}
|
|
||||||
java -jar ./apktool_2.5.0.jar b -o apk ./Techmino.apk
|
|
||||||
- uses: 26F-Studio/sign-android-release@master
|
|
||||||
name: Sign APK
|
|
||||||
id: sign_app
|
|
||||||
with:
|
|
||||||
releaseDirectory: ./Techmino.apk
|
|
||||||
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
|
|
||||||
alias: ${{ secrets.ALIAS }}
|
|
||||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
|
||||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
|
||||||
env:
|
|
||||||
BUILD_TOOLS_VERSION: "30.0.2"
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: Techmino_${{ env.Version }}_${{ GITHUB.RUN_NUMBER }}_${{ env.CommitID }}_Android
|
|
||||||
path: ${{steps.sign_app.outputs.signedReleaseFile}}
|
|
||||||
|
|
||||||
build-macOS:
|
|
||||||
runs-on: macos-10.15
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install lua
|
|
||||||
run: |
|
|
||||||
curl -OL http://www.lua.org/ftp/lua-5.4.3.tar.gz
|
|
||||||
tar zxf lua-5.4.3.tar.gz
|
|
||||||
cd lua-5.4.3
|
|
||||||
make macosx
|
|
||||||
sudo make install
|
|
||||||
- name: Get CommitID
|
|
||||||
run: |
|
|
||||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
|
||||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Update Conf
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Conf
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version -H ${{ env.CommitID }}
|
|
||||||
- name: Pack love
|
|
||||||
run: |
|
|
||||||
7z a -tzip ./Techmino.love ./document ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
- name: Download template
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.app.zip
|
|
||||||
- name: Unpack template
|
|
||||||
run: |
|
|
||||||
7z x ./Techmino.app.zip
|
|
||||||
- name: Modify template
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T macOS -N ${{ env.Version }}
|
|
||||||
mv ./Techmino.love ./Techmino.app/Contents/Resources
|
|
||||||
- name: Codesign executable
|
|
||||||
# In secrets:
|
|
||||||
# - MACOS_CERTIFICATE: the *.p12 Developer ID Certificate, encoded in base64
|
|
||||||
# - MACOS_CERTIFICATE_PWD: The password
|
|
||||||
env:
|
|
||||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
|
||||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
|
||||||
run: |
|
|
||||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
|
||||||
security create-keychain -p Techminohaowan build.keychain
|
|
||||||
security default-keychain -s build.keychain
|
|
||||||
security unlock-keychain -p Techminohaowan build.keychain
|
|
||||||
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
|
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k Techminohaowan build.keychain
|
|
||||||
/usr/bin/codesign --force --deep -s 79B81FC5EA155243C973B5417B0996501F00EF55 ./Techmino.app -v
|
|
||||||
- name: Pack Techmino
|
|
||||||
run: |
|
|
||||||
zip -r -y Techmino.zip Techmino.app
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: Techmino_${{ env.Version }}_${{ GITHUB.RUN_NUMBER }}_${{ env.CommitID }}_macOS
|
|
||||||
path: Techmino.zip
|
|
||||||
203
.github/workflows/dev.yml
vendored
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
name: Techmino Develop CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, ci* ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
get-info:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
outputs:
|
||||||
|
name: ${{ steps.actual-get-info.outputs.name }}
|
||||||
|
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||||
|
code: ${{ steps.actual-get-info.outputs.code }}
|
||||||
|
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install lua
|
||||||
|
run: |
|
||||||
|
sudo apt-get install lua5.3 -y
|
||||||
|
- name: Get Version
|
||||||
|
id: actual-get-info
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||||
|
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||||
|
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||||
|
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||||
|
|
||||||
|
automatic-test:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/automatic-test
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-windows
|
||||||
|
with:
|
||||||
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
|
love-dir: love-11.3-win64
|
||||||
|
arch: win64
|
||||||
|
version: ${{ needs.get-info.outputs.name }}
|
||||||
|
icon: .\.github\build\Windows\icon_snapshot.ico
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||||
|
path: love
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-linux
|
||||||
|
with:
|
||||||
|
icon: .github/build/Linux/icon_snapshot.png
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||||
|
path: Techmino.AppImage
|
||||||
|
|
||||||
|
build-android:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-android
|
||||||
|
with:
|
||||||
|
type: Snapshot
|
||||||
|
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
file-path: Techmino_Snapshot.apk
|
||||||
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||||
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
|
||||||
|
path: Techmino_Snapshot.apk
|
||||||
|
|
||||||
|
build-android-mini:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- name: remove media
|
||||||
|
run: |
|
||||||
|
rm -rf media/music media/effect media/vocal
|
||||||
|
- uses: ./.github/actions/build-android
|
||||||
|
with:
|
||||||
|
type: Snapshot
|
||||||
|
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
file-path: Techmino_Snapshot_Mini.apk
|
||||||
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||||
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android_Mini
|
||||||
|
path: Techmino_Snapshot_Mini.apk
|
||||||
|
|
||||||
|
build-macOS:
|
||||||
|
runs-on: macos-10.15
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-macos
|
||||||
|
with:
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
icon: .github/build/macOS/icon_snapshot.icns
|
||||||
|
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||||
|
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||||
|
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||||
|
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||||
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_macOS
|
||||||
|
path: Techmino.dmg
|
||||||
|
|
||||||
|
build-iOS:
|
||||||
|
runs-on: macos-latest
|
||||||
|
if: (!startsWith( github.ref , 'refs/heads/ci-')) || startsWith( github.ref , 'refs/heads/ci-ios-')
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-ios
|
||||||
|
with:
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
type: 'dev'
|
||||||
|
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||||
|
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||||
|
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||||
|
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.2.${{ github.run_number }}.${{ github.run_attempt }}'
|
||||||
|
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
||||||
|
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
||||||
|
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||||
|
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||||
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||||
|
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||||
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||||
|
path: Techmino.ipa
|
||||||
|
|
||||||
|
build-love:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
- uses: ./.github/actions/build-love
|
||||||
|
with:
|
||||||
|
file-path: Techmino.love
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Love
|
||||||
|
path: Techmino.love
|
||||||
31
.github/workflows/getVersion.lua
vendored
@@ -1,25 +1,28 @@
|
|||||||
if arg[1]=="-code"then
|
local arg=arg[1]
|
||||||
print(require"version".apkCode)
|
if arg=="-apkCode"then
|
||||||
elseif arg[1]=="-name"then
|
local code=require"version".apkCode
|
||||||
print((require"version".string:gsub("@DEV","")))
|
print(code)
|
||||||
elseif arg[1]=="-release"then
|
elseif arg=="-code"then
|
||||||
print((require"version".string:gsub("V","")))
|
local str=require"version".code
|
||||||
elseif arg[1]=="-updateTitle"then
|
print(str)
|
||||||
|
elseif arg=="-name"then
|
||||||
|
local str=require"version".string
|
||||||
|
print(str)
|
||||||
|
elseif arg=="-release"then
|
||||||
|
local str=require"version".string:gsub("V","",1)
|
||||||
|
print(str)
|
||||||
|
elseif arg=="-updateTitle"then
|
||||||
local note=require"parts.updateLog"
|
local note=require"parts.updateLog"
|
||||||
local p1=note:find("\n%d")+1
|
local p1=note:find("\n%d")+1
|
||||||
local p2=note:find("\n",p1)-1
|
local p2=note:find("\n",p1)-1
|
||||||
note=note:sub(p1,p2)
|
note=note:sub(p1,p2)
|
||||||
print(note)
|
print(note)
|
||||||
elseif arg[1]=="-updateNote"then
|
elseif arg=="-updateNote"then
|
||||||
local note=require"parts.updateLog"
|
local note=require"parts.updateLog"
|
||||||
local p1=note:find("\n",note:find("\n%d")+1)+1
|
local p1=note:find("\n",note:find("\n%d")+1)+1
|
||||||
local p2=note:find("\n%d",p1+1)
|
local p2=note:find("\n%d",p1+1)
|
||||||
note=note:sub(p1,p2-2)
|
note=note:sub(p1,p2-2)
|
||||||
note=note
|
:gsub(" ","- ")
|
||||||
:gsub("\t\t\t\t","_")
|
:gsub(" ","# ")
|
||||||
:gsub("\t\t","")
|
|
||||||
:gsub("\n([^_])","\n\n%1")
|
|
||||||
:gsub("\n_","\n")
|
|
||||||
:gsub("\n\n","\n",1)
|
|
||||||
print(note)
|
print(note)
|
||||||
end
|
end
|
||||||
456
.github/workflows/release.yml
vendored
@@ -3,399 +3,187 @@ name: Techmino Release CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- "v*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-windows-x64:
|
get-info:
|
||||||
runs-on: windows-latest
|
runs-on: ubuntu-20.04
|
||||||
|
outputs:
|
||||||
|
name: ${{ steps.actual-get-info.outputs.name }}
|
||||||
|
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||||
|
code: ${{ steps.actual-get-info.outputs.code }}
|
||||||
|
release: ${{ steps.actual-get-info.outputs.release }}
|
||||||
|
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
|
||||||
|
updateNote: ${{ steps.actual-get-info.outputs.updateNote }}
|
||||||
|
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Download lua
|
- name: Install lua
|
||||||
run: |
|
run: |
|
||||||
curl -OL https://nchc.dl.sourceforge.net/project/luabinaries/5.4.2/Tools%20Executables/lua-5.4.2_Win64_bin.zip
|
sudo apt-get install lua5.3 -y
|
||||||
- name: Unpack lua
|
|
||||||
run: |
|
|
||||||
7z x .\lua-5.4.2_Win64_bin.zip -olua
|
|
||||||
rename-Item '.\lua\lua54.exe' -NewName 'lua.exe'
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python .\.github\workflows\updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
- name: Get Version
|
||||||
|
id: actual-get-info
|
||||||
run: |
|
run: |
|
||||||
$Version=.\lua\lua.exe .\.github\workflows\getVersion.lua -release
|
UPDATE_NOTE=$(lua .github/workflows/getVersion.lua -updateNote)
|
||||||
echo "Version=${Version}" >> $env:GITHUB_ENV
|
UPDATE_NOTE="${UPDATE_NOTE//'%'/'%25'}"
|
||||||
- name: Get ReleaseTitle
|
UPDATE_NOTE="${UPDATE_NOTE//$'\n'/'%0A'}"
|
||||||
run: |
|
UPDATE_NOTE="${UPDATE_NOTE//$'\r'/'%0D'}"
|
||||||
$Title=.\lua\lua.exe .\.github\workflows\getVersion.lua -updateTitle
|
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||||
echo "Title=${Title}" >> $env:GITHUB_ENV
|
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||||
- name: Download love
|
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||||
run: |
|
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
||||||
- name: Unpack love
|
echo "::set-output name=updateNote::$UPDATE_NOTE"
|
||||||
run: |
|
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||||
7z x .\love-11.3-win64.zip
|
|
||||||
- name: Download ColdClear
|
build-windows-x64:
|
||||||
run: |
|
runs-on: windows-latest
|
||||||
curl -OL https://github.com/26F-Studio/cold_clear_ai_love2d_wrapper/releases/download/latest/win64.zip
|
needs: get-info
|
||||||
- name: Unpack ColdClear
|
steps:
|
||||||
run: |
|
- uses: actions/checkout@v2
|
||||||
7z x .\win64.zip -oColdClear
|
- uses: ./.github/actions/update-version
|
||||||
- name: Download ResourceHacker
|
- uses: ./.github/actions/build-windows
|
||||||
run: |
|
with:
|
||||||
curl -OL http://www.angusj.com/resourcehacker/resource_hacker.zip
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
- name: Unpack ResourceHacker
|
love-dir: love-11.3-win64
|
||||||
run: |
|
arch: win64
|
||||||
7z x .\resource_hacker.zip
|
version: ${{ needs.get-info.outputs.release }}
|
||||||
|
icon: .\.github\build\Windows\icon.ico
|
||||||
- name: Pack Techmino
|
- name: Pack Techmino
|
||||||
run: |
|
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip .\love
|
||||||
7z a -tzip .\Techmino.love .\document .\media .\parts .\Zframework .\conf.lua .\font.ttf .\main.lua .\version.lua
|
|
||||||
cmd /c copy /b .\love-11.3-win64\love.exe + .\Techmino.love .\love-11.3-win64\Techmino.exe
|
|
||||||
del .\love-11.3-win64\love.exe
|
|
||||||
del .\love-11.3-win64\lovec.exe
|
|
||||||
del .\love-11.3-win64\game.ico
|
|
||||||
del .\love-11.3-win64\love.ico
|
|
||||||
del .\love-11.3-win64\changes.txt
|
|
||||||
del .\love-11.3-win64\readme.txt
|
|
||||||
move .\ColdClear\cold_clear.dll .\love-11.3-win64
|
|
||||||
move .\ColdClear\CCloader.dll .\love-11.3-win64
|
|
||||||
python .\.github\workflows\updateVersion.py -T Windows -N ${{ env.Version }}
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action delete -mask ICONGROUP,,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action addoverwrite -res ".\build\Windows\icon.ico" -mask ICONGROUP,1,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win64\Techmino.exe -save .\love-11.3-win64\Techmino.exe -action addoverwrite -res ".\Techmino.res" -mask VERSIONINFO,1,'
|
|
||||||
7z a -tzip .\Techmino.a${{ env.Version }}.Win64.zip .\love-11.3-win64\
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: Techmino.a${{ env.Version }}.Win64.zip
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
|
||||||
|
|
||||||
build-windows-x86:
|
build-windows-x86:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Download lua
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-windows
|
||||||
curl -OL https://nchc.dl.sourceforge.net/project/luabinaries/5.4.2/Tools%20Executables/lua-5.4.2_Win64_bin.zip
|
with:
|
||||||
- name: Unpack lua
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
||||||
run: |
|
love-dir: love-11.3-win32
|
||||||
7z x .\lua-5.4.2_Win64_bin.zip -olua
|
arch: win32
|
||||||
rename-Item '.\lua\lua54.exe' -NewName 'lua.exe'
|
version: ${{ needs.get-info.outputs.release }}
|
||||||
- name: Update Version
|
icon: .\.github\build\Windows\icon.ico
|
||||||
run: |
|
|
||||||
python .\.github\workflows\updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
$Version=.\lua\lua.exe .\.github\workflows\getVersion.lua -release
|
|
||||||
echo "Version=${Version}" >> $env:GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
$Title=.\lua\lua.exe .\.github\workflows\getVersion.lua -updateTitle
|
|
||||||
echo "Title=${Title}" >> $env:GITHUB_ENV
|
|
||||||
- name: Download love
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
|
||||||
- name: Unpack love
|
|
||||||
run: |
|
|
||||||
7z x .\love-11.3-win32.zip
|
|
||||||
- name: Download ColdClear
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/cold_clear_ai_love2d_wrapper/releases/download/latest/win32.zip
|
|
||||||
- name: Unpack ColdClear
|
|
||||||
run: |
|
|
||||||
7z x .\win32.zip -oColdClear
|
|
||||||
- name: Download ResourceHacker
|
|
||||||
run: |
|
|
||||||
curl -OL http://www.angusj.com/resourcehacker/resource_hacker.zip
|
|
||||||
- name: Unpack ResourceHacker
|
|
||||||
run: |
|
|
||||||
7z x .\resource_hacker.zip
|
|
||||||
- name: Pack Techmino
|
- name: Pack Techmino
|
||||||
run: |
|
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip .\love
|
||||||
7z a -tzip .\Techmino.love .\document .\media .\parts .\Zframework .\conf.lua .\font.ttf .\main.lua .\version.lua
|
|
||||||
cmd /c copy /b .\love-11.3-win32\love.exe + .\Techmino.love .\love-11.3-win32\Techmino.exe
|
|
||||||
del .\love-11.3-win32\love.exe
|
|
||||||
del .\love-11.3-win32\lovec.exe
|
|
||||||
del .\love-11.3-win32\game.ico
|
|
||||||
del .\love-11.3-win32\love.ico
|
|
||||||
del .\love-11.3-win32\changes.txt
|
|
||||||
del .\love-11.3-win32\readme.txt
|
|
||||||
move .\ColdClear\cold_clear.dll .\love-11.3-win32
|
|
||||||
move .\ColdClear\CCloader.dll .\love-11.3-win32
|
|
||||||
python .\.github\workflows\updateVersion.py -T Windows -N ${{ env.Version }}
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win32\Techmino.exe -save .\love-11.3-win32\Techmino.exe -action delete -mask ICONGROUP,,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win32\Techmino.exe -save .\love-11.3-win32\Techmino.exe -action addoverwrite -res ".\build\Windows\icon.ico" -mask ICONGROUP,1,'
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love-11.3-win32\Techmino.exe -save .\love-11.3-win32\Techmino.exe -action addoverwrite -res ".\Techmino.res" -mask VERSIONINFO,1,'
|
|
||||||
7z a -tzip .\Techmino.a${{ env.Version }}.Win32.zip .\love-11.3-win32\
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: Techmino.a${{ env.Version }}.Win32.zip
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-linux
|
||||||
sudo apt-get update -y
|
with:
|
||||||
sudo apt-get upgrade -y
|
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||||
sudo apt-get install lua5.3 -y
|
icon: .github/build/Linux/icon.png
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -release)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=$(lua ./.github/workflows/getVersion.lua -updateTitle)
|
|
||||||
echo "Title=${Title}" >> $GITHUB_ENV
|
|
||||||
#我不是很懂这里为什么不能用https://github.com/AppImage/AppImageKit/releases/download/latest/appimagetool-x86_64.AppImage 但是事实就是它404了
|
|
||||||
- name: Download AppImageKit
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
|
|
||||||
- name: Download love
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-x86_64.AppImage
|
|
||||||
- name: Unpack love
|
|
||||||
run: |
|
|
||||||
chmod 777 ./love-11.3-x86_64.AppImage
|
|
||||||
./love-11.3-x86_64.AppImage --appimage-extract
|
|
||||||
- name: Download ColdClear
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/cold_clear_ai_love2d_wrapper/releases/download/latest/linux.zip
|
|
||||||
- name: Unpack ColdClear
|
|
||||||
run: |
|
|
||||||
7z x ./linux.zip -oColdClear
|
|
||||||
- name: Pack Techmino
|
|
||||||
run: |
|
|
||||||
rm -rf ./squashfs-root/love ./squashfs-root/love.desktop ./squashfs-root/love.svg ./squashfs-root/.DirIcon
|
|
||||||
mv ./build/Linux/love.template ./squashfs-root/love
|
|
||||||
mv ./build/Linux/Techmino.desktop.template ./squashfs-root/Techmino.desktop
|
|
||||||
mv ./build/Linux/icon.png ./squashfs-root/icon.png
|
|
||||||
cp ./squashfs-root/icon.png ./squashfs-root/.DirIcon
|
|
||||||
chmod 777 ./squashfs-root/love
|
|
||||||
mkdir -p ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./document ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./ColdClear/CCloader.so ./squashfs-root/usr/share/Techmino
|
|
||||||
mv ./ColdClear/libcold_clear.so ./squashfs-root/usr/lib
|
|
||||||
chmod 777 ./appimagetool-x86_64.AppImage
|
|
||||||
./appimagetool-x86_64.AppImage ./squashfs-root ./Techmino.a${{ env.Version }}.AppImage
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: Techmino.a${{ env.Version }}.AppImage
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||||
|
|
||||||
#Android待更新
|
|
||||||
build-android:
|
build-android:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-android
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -release)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=$(lua ./.github/workflows/getVersion.lua -updateTitle)
|
|
||||||
echo "Title=${Title}" >> $GITHUB_ENV
|
|
||||||
- name: Download Apktool
|
|
||||||
run: curl -OL https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.5.0.jar
|
|
||||||
- name: Unpack and Repack
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.apk
|
|
||||||
java -jar ./apktool_2.5.0.jar d -s -o apk ./Techmino.apk
|
|
||||||
7z x ./apk/assets/game.love libAndroid -o.
|
|
||||||
rm -rf ./apk/assets/game.love ./Techmino.apk
|
|
||||||
7z a -tzip ./apk/assets/game.love ./document ./libAndroid ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Android -C $(lua ./.github/workflows/getVersion.lua -code) -N $(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
java -jar ./apktool_2.5.0.jar b -o apk ./Techmino.a${{ env.Version }}.apk
|
|
||||||
- uses: 26F-Studio/sign-android-release@master
|
|
||||||
name: Sign APK
|
|
||||||
id: sign_app
|
|
||||||
with:
|
with:
|
||||||
releaseDirectory: ./Techmino.a${{ env.Version }}.apk
|
type: Release
|
||||||
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
|
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||||
alias: ${{ secrets.ALIAS }}
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
env:
|
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||||
BUILD_TOOLS_VERSION: "30.0.2"
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: ${{steps.sign_app.outputs.signedReleaseFile}}
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||||
|
|
||||||
#Android-mini待更新
|
|
||||||
build-android-mini:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install lua
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -release)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=$(lua ./.github/workflows/getVersion.lua -updateTitle)
|
|
||||||
echo "Title=${Title}" >> $GITHUB_ENV
|
|
||||||
- name: Download Apktool
|
|
||||||
run: curl -OL https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.5.0.jar
|
|
||||||
- name: Unpack and Repack
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.apk
|
|
||||||
java -jar ./apktool_2.5.0.jar d -s -o apk ./Techmino.apk
|
|
||||||
7z x ./apk/assets/game.love libAndroid -o.
|
|
||||||
rm -rf ./apk/assets/game.love ./Techmino.apk
|
|
||||||
rm -rf ./media/BGM ./media/SFX ./media/VOICE
|
|
||||||
7z a -tzip ./apk/assets/game.love ./document ./libAndroid ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Android -C $(lua ./.github/workflows/getVersion.lua -code) -N $(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
java -jar ./apktool_2.5.0.jar b -o apk ./Techmino.a${{ env.Version }}.mini.apk
|
|
||||||
- uses: 26F-Studio/sign-android-release@master
|
|
||||||
name: Sign APK
|
|
||||||
id: sign_app
|
|
||||||
with:
|
|
||||||
releaseDirectory: ./Techmino.a${{ env.Version }}.mini.apk
|
|
||||||
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
|
|
||||||
alias: ${{ secrets.ALIAS }}
|
|
||||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
|
||||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
|
||||||
env:
|
|
||||||
BUILD_TOOLS_VERSION: "30.0.2"
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
name: ${{ env.Title }}
|
|
||||||
files: ${{steps.sign_app.outputs.signedReleaseFile}}
|
|
||||||
|
|
||||||
build-macOS:
|
build-macOS:
|
||||||
runs-on: macos-10.15
|
runs-on: macos-10.15
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-macos
|
||||||
curl -OL http://www.lua.org/ftp/lua-5.4.3.tar.gz
|
with:
|
||||||
tar zxf lua-5.4.3.tar.gz
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
cd lua-5.4.3
|
icon: .github/build/macOS/icon.icns
|
||||||
make macosx
|
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||||
sudo make install
|
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||||
- name: Update Version
|
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||||
run: |
|
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version
|
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||||
- name: Get Version
|
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||||
run: |
|
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -release)
|
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=$(lua ./.github/workflows/getVersion.lua -updateTitle)
|
|
||||||
echo "Title=${Title}" >> $GITHUB_ENV
|
|
||||||
- name: Pack love
|
|
||||||
run: |
|
|
||||||
7z a -tzip ./Techmino.love ./document ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
- name: Download template
|
|
||||||
run: |
|
|
||||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.app.zip
|
|
||||||
- name: Unpack template
|
|
||||||
run: |
|
|
||||||
7z x ./Techmino.app.zip
|
|
||||||
- name: Modify template
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T macOS -N $(lua ./.github/workflows/getVersion.lua -name)
|
|
||||||
mv ./Techmino.love ./Techmino.app/Contents/Resources
|
|
||||||
- name: Codesign executable
|
|
||||||
# In secrets:
|
|
||||||
# - MACOS_CERTIFICATE: the *.p12 Developer ID Certificate, encoded in base64
|
|
||||||
# - MACOS_CERTIFICATE_PWD: The password
|
|
||||||
env:
|
|
||||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
|
||||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
|
||||||
run: |
|
|
||||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
|
||||||
security create-keychain -p Techminohaowan build.keychain
|
|
||||||
security default-keychain -s build.keychain
|
|
||||||
security unlock-keychain -p Techminohaowan build.keychain
|
|
||||||
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
|
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k Techminohaowan build.keychain
|
|
||||||
/usr/bin/codesign --force --deep -s 79B81FC5EA155243C973B5417B0996501F00EF55 ./Techmino.app -v
|
|
||||||
- name: Pack Techmino
|
- name: Pack Techmino
|
||||||
run: |
|
run: |
|
||||||
zip -r -y Techmino.a${{ env.Version }}.macOS.zip Techmino.app
|
mv Techmino.dmg Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: Techmino.a${{ env.Version }}.macOS.zip
|
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||||
|
|
||||||
build-love:
|
build-iOS:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: macos-latest
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- uses: ./.github/actions/update-version
|
||||||
|
- uses: ./.github/actions/build-ios
|
||||||
|
with:
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
type: "release"
|
||||||
|
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||||
|
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||||
|
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||||
|
APPLE_APP_BUILD: "${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}"
|
||||||
|
APPLE_APP_CHANGELOG: "${{ needs.get-info.outputs.updateNote }}"
|
||||||
|
APPLE_APP_ID: "${{ secrets.APPLE_APP_ID }}"
|
||||||
|
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||||
|
APPLE_APP_PROFILE: "${{ secrets.APPLE_APP_PROFILE }}"
|
||||||
|
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||||
|
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||||
|
FASTLANE_ACTION_ID: "${{ github.run_id }}"
|
||||||
|
FASTLANE_DISCORD_WEBHOOK: "${{ secrets.FASTLANE_DISCORD_WEBHOOK }}"
|
||||||
|
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||||
|
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||||
|
- name: Rename ipa
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -y
|
mv Techmino.ipa Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 ./.github/workflows/updateVersion.py -T Version
|
|
||||||
- name: Get Version
|
|
||||||
run: |
|
|
||||||
Version=$(lua ./.github/workflows/getVersion.lua -release)
|
|
||||||
echo "Version=${Version}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=$(lua ./.github/workflows/getVersion.lua -updateTitle)
|
|
||||||
- name: Pack Techmino
|
|
||||||
run: |
|
|
||||||
7z a -tzip ./Techmino.a${{ env.Version }}.love ./document ./media ./parts ./Zframework ./conf.lua ./font.ttf ./main.lua ./version.lua
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
files: Techmino.a${{ env.Version }}.love
|
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||||
|
|
||||||
Add-Release-note:
|
Add-Release-note:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get upgrade -y
|
|
||||||
sudo apt-get install lua5.3 -y
|
|
||||||
- name: Get ReleaseTitle
|
|
||||||
run: |
|
|
||||||
Title=lua ./.github/workflows/getVersion.lua -updateTitle
|
|
||||||
echo "Title=${Title}" >> $GITHUB_ENV
|
|
||||||
- name: Get ReleaseNote
|
|
||||||
run: |
|
|
||||||
Note=lua ./.github/workflows/getVersion.lua -updateNote
|
|
||||||
echo "Note=${Note}" >> $GITHUB_ENV
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.Title }}
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
body: ${{ env.Note }}
|
body: ${{ needs.get-info.outputs.updateNote }}
|
||||||
|
|||||||
154
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
name: Techmino Test CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'pre*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
get-info:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
outputs:
|
||||||
|
name: ${{ steps.actual-get-info.outputs.name }}
|
||||||
|
apkCode: ${{ steps.actual-get-info.outputs.apkCode }}
|
||||||
|
code: ${{ steps.actual-get-info.outputs.code }}
|
||||||
|
release: ${{ steps.actual-get-info.outputs.release }}
|
||||||
|
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install lua
|
||||||
|
run: |
|
||||||
|
sudo apt-get install lua5.3 -y
|
||||||
|
- name: Get Version
|
||||||
|
id: actual-get-info
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||||
|
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||||
|
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||||
|
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||||
|
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-windows
|
||||||
|
with:
|
||||||
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
|
love-dir: love-11.3-win64
|
||||||
|
arch: win64
|
||||||
|
version: ${{ needs.get-info.outputs.name }}
|
||||||
|
icon: .\.github\build\Windows\icon_snapshot.ico
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||||
|
path: love
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-linux
|
||||||
|
with:
|
||||||
|
icon: .github/build/Linux/icon_snapshot.png
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||||
|
path: Techmino.AppImage
|
||||||
|
|
||||||
|
build-android:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-android
|
||||||
|
with:
|
||||||
|
type: Snapshot
|
||||||
|
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
file-path: Techmino_Snapshot.apk
|
||||||
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||||
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
|
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
|
||||||
|
path: Techmino_Snapshot.apk
|
||||||
|
|
||||||
|
build-macOS:
|
||||||
|
runs-on: macos-10.15
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-macos
|
||||||
|
with:
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
icon: .github/build/macOS/icon_snapshot.icns
|
||||||
|
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||||
|
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||||
|
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||||
|
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||||
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
|
||||||
|
path: Techmino.dmg
|
||||||
|
|
||||||
|
build-iOS:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: get-info
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/actions/update-version
|
||||||
|
with:
|
||||||
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
|
- uses: ./.github/actions/build-ios
|
||||||
|
with:
|
||||||
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
|
type: 'test'
|
||||||
|
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||||
|
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||||
|
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||||
|
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.1.${{ github.run_number }}.${{ github.run_attempt }}'
|
||||||
|
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
||||||
|
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
||||||
|
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||||
|
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||||
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||||
|
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||||
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||||
|
path: Techmino.ipa
|
||||||
66
.github/workflows/updateVersion.py
vendored
@@ -1,66 +0,0 @@
|
|||||||
import argparse
|
|
||||||
|
|
||||||
def updateConf(): #更新存档位置
|
|
||||||
with open('conf.lua', 'r+', encoding='utf-8') as file:
|
|
||||||
data = file.read()
|
|
||||||
data = data.replace("t.identity='Techmino'--Saving folder", "t.identity='Techmino_Snapshot'--Saving folder")
|
|
||||||
file.seek(0)
|
|
||||||
file.truncate()
|
|
||||||
file.flush()
|
|
||||||
file.write(data)
|
|
||||||
|
|
||||||
def updateVersion(args): #更新版本号
|
|
||||||
with open('version.lua', 'r+', encoding='utf-8') as file:
|
|
||||||
data = file.read()
|
|
||||||
if args.Hash != False:
|
|
||||||
data = data.replace('@DEV', f'@{args.Hash[0:4]}')
|
|
||||||
updateConf()
|
|
||||||
else:
|
|
||||||
data = data.replace('@DEV', '')
|
|
||||||
file.seek(0)
|
|
||||||
file.truncate()
|
|
||||||
file.flush()
|
|
||||||
file.write(data)
|
|
||||||
|
|
||||||
def updateMacOS(args): #更新macOS打包信息
|
|
||||||
import datetime
|
|
||||||
with open('./build/macOS/info.plist.template', 'r', encoding='utf-8') as template:
|
|
||||||
template = ((template.read()).replace('@versionName', args.Name)).replace('@ThisYear', str(datetime.datetime.today().year))
|
|
||||||
with open('./Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
|
|
||||||
file.write(template)
|
|
||||||
|
|
||||||
def updateWindows(args): #更新Windows打包信息
|
|
||||||
Version = (args.Name).replace('V', '')
|
|
||||||
FileVersion = (f"{Version.replace('.', ',')},0")
|
|
||||||
with open('./build/Windows/Techmino.rc.template', 'r', encoding='utf8') as templace:
|
|
||||||
template = ((templace.read()).replace('@FileVersion', FileVersion)).replace('@Version', Version)
|
|
||||||
with open('Techmino.rc', 'w+', encoding='utf8') as file:
|
|
||||||
file.write(template)
|
|
||||||
|
|
||||||
def updateAndroid(args): #更新Android打包信息
|
|
||||||
import re
|
|
||||||
with open('./apk/apktool.yml', 'r+', encoding='utf-8') as file:
|
|
||||||
data = file.read()
|
|
||||||
data = re.sub("versionCode:.+", f"versionCode: '{args.Code}'", data)
|
|
||||||
data = re.sub("versionName:.+", f"versionName: '{args.Name}'", data)
|
|
||||||
file.seek(0)
|
|
||||||
file.truncate()
|
|
||||||
file.write(data)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser(description='用于CI更新程序各类信息')
|
|
||||||
parser.add_argument('-T', '--Type', type=str, help = '更新的种类')
|
|
||||||
parser.add_argument('-H', '--Hash', type=str, default = False, help = 'Github提交Hash')
|
|
||||||
parser.add_argument('-C', '--Code', type=str, default = False, help = 'versionCode')
|
|
||||||
parser.add_argument('-N', '--Name', type=str, default = False, help = 'versionName')
|
|
||||||
args = parser.parse_args()
|
|
||||||
if args.Type == 'Conf':
|
|
||||||
updateConf()
|
|
||||||
elif args.Type == 'Version':
|
|
||||||
updateVersion(args)
|
|
||||||
elif args.Type == 'Windows':
|
|
||||||
updateWindows(args)
|
|
||||||
elif args.Type == 'macOS':
|
|
||||||
updateMacOS(args)
|
|
||||||
elif args.Type == 'Android':
|
|
||||||
updateAndroid(args)
|
|
||||||
8
.gitignore
vendored
@@ -1,4 +1,8 @@
|
|||||||
.vscode
|
.vscode
|
||||||
libAndroid
|
libAndroid
|
||||||
font.ttf
|
*.ini
|
||||||
note.lua
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Icon?
|
||||||
|
.Trash
|
||||||
|
.file
|
||||||
|
|||||||
165
LICENSE
@@ -1,165 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
|
|
||||||
This version of the GNU Lesser General Public License incorporates
|
|
||||||
the terms and conditions of version 3 of the GNU General Public
|
|
||||||
License, supplemented by the additional permissions listed below.
|
|
||||||
|
|
||||||
0. Additional Definitions.
|
|
||||||
|
|
||||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
|
||||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
|
||||||
General Public License.
|
|
||||||
|
|
||||||
"The Library" refers to a covered work governed by this License,
|
|
||||||
other than an Application or a Combined Work as defined below.
|
|
||||||
|
|
||||||
An "Application" is any work that makes use of an interface provided
|
|
||||||
by the Library, but which is not otherwise based on the Library.
|
|
||||||
Defining a subclass of a class defined by the Library is deemed a mode
|
|
||||||
of using an interface provided by the Library.
|
|
||||||
|
|
||||||
A "Combined Work" is a work produced by combining or linking an
|
|
||||||
Application with the Library. The particular version of the Library
|
|
||||||
with which the Combined Work was made is also called the "Linked
|
|
||||||
Version".
|
|
||||||
|
|
||||||
The "Minimal Corresponding Source" for a Combined Work means the
|
|
||||||
Corresponding Source for the Combined Work, excluding any source code
|
|
||||||
for portions of the Combined Work that, considered in isolation, are
|
|
||||||
based on the Application, and not on the Linked Version.
|
|
||||||
|
|
||||||
The "Corresponding Application Code" for a Combined Work means the
|
|
||||||
object code and/or source code for the Application, including any data
|
|
||||||
and utility programs needed for reproducing the Combined Work from the
|
|
||||||
Application, but excluding the System Libraries of the Combined Work.
|
|
||||||
|
|
||||||
1. Exception to Section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
You may convey a covered work under sections 3 and 4 of this License
|
|
||||||
without being bound by section 3 of the GNU GPL.
|
|
||||||
|
|
||||||
2. Conveying Modified Versions.
|
|
||||||
|
|
||||||
If you modify a copy of the Library, and, in your modifications, a
|
|
||||||
facility refers to a function or data to be supplied by an Application
|
|
||||||
that uses the facility (other than as an argument passed when the
|
|
||||||
facility is invoked), then you may convey a copy of the modified
|
|
||||||
version:
|
|
||||||
|
|
||||||
a) under this License, provided that you make a good faith effort to
|
|
||||||
ensure that, in the event an Application does not supply the
|
|
||||||
function or data, the facility still operates, and performs
|
|
||||||
whatever part of its purpose remains meaningful, or
|
|
||||||
|
|
||||||
b) under the GNU GPL, with none of the additional permissions of
|
|
||||||
this License applicable to that copy.
|
|
||||||
|
|
||||||
3. Object Code Incorporating Material from Library Header Files.
|
|
||||||
|
|
||||||
The object code form of an Application may incorporate material from
|
|
||||||
a header file that is part of the Library. You may convey such object
|
|
||||||
code under terms of your choice, provided that, if the incorporated
|
|
||||||
material is not limited to numerical parameters, data structure
|
|
||||||
layouts and accessors, or small macros, inline functions and templates
|
|
||||||
(ten or fewer lines in length), you do both of the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the object code that the
|
|
||||||
Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
4. Combined Works.
|
|
||||||
|
|
||||||
You may convey a Combined Work under terms of your choice that,
|
|
||||||
taken together, effectively do not restrict modification of the
|
|
||||||
portions of the Library contained in the Combined Work and reverse
|
|
||||||
engineering for debugging such modifications, if you also do each of
|
|
||||||
the following:
|
|
||||||
|
|
||||||
a) Give prominent notice with each copy of the Combined Work that
|
|
||||||
the Library is used in it and that the Library and its use are
|
|
||||||
covered by this License.
|
|
||||||
|
|
||||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
|
||||||
document.
|
|
||||||
|
|
||||||
c) For a Combined Work that displays copyright notices during
|
|
||||||
execution, include the copyright notice for the Library among
|
|
||||||
these notices, as well as a reference directing the user to the
|
|
||||||
copies of the GNU GPL and this license document.
|
|
||||||
|
|
||||||
d) Do one of the following:
|
|
||||||
|
|
||||||
0) Convey the Minimal Corresponding Source under the terms of this
|
|
||||||
License, and the Corresponding Application Code in a form
|
|
||||||
suitable for, and under terms that permit, the user to
|
|
||||||
recombine or relink the Application with a modified version of
|
|
||||||
the Linked Version to produce a modified Combined Work, in the
|
|
||||||
manner specified by section 6 of the GNU GPL for conveying
|
|
||||||
Corresponding Source.
|
|
||||||
|
|
||||||
1) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (a) uses at run time
|
|
||||||
a copy of the Library already present on the user's computer
|
|
||||||
system, and (b) will operate properly with a modified version
|
|
||||||
of the Library that is interface-compatible with the Linked
|
|
||||||
Version.
|
|
||||||
|
|
||||||
e) Provide Installation Information, but only if you would otherwise
|
|
||||||
be required to provide such information under section 6 of the
|
|
||||||
GNU GPL, and only to the extent that such information is
|
|
||||||
necessary to install and execute a modified version of the
|
|
||||||
Combined Work produced by recombining or relinking the
|
|
||||||
Application with a modified version of the Linked Version. (If
|
|
||||||
you use option 4d0, the Installation Information must accompany
|
|
||||||
the Minimal Corresponding Source and Corresponding Application
|
|
||||||
Code. If you use option 4d1, you must provide the Installation
|
|
||||||
Information in the manner specified by section 6 of the GNU GPL
|
|
||||||
for conveying Corresponding Source.)
|
|
||||||
|
|
||||||
5. Combined Libraries.
|
|
||||||
|
|
||||||
You may place library facilities that are a work based on the
|
|
||||||
Library side by side in a single library together with other library
|
|
||||||
facilities that are not Applications and are not covered by this
|
|
||||||
License, and convey such a combined library under terms of your
|
|
||||||
choice, if you do both of the following:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work based
|
|
||||||
on the Library, uncombined with any other library facilities,
|
|
||||||
conveyed under the terms of this License.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library that part of it
|
|
||||||
is a work based on the Library, and explaining where to find the
|
|
||||||
accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
6. Revised Versions of the GNU Lesser General Public License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the GNU Lesser General Public License from time to time. Such new
|
|
||||||
versions will be similar in spirit to the present version, but may
|
|
||||||
differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Library as you received it specifies that a certain numbered version
|
|
||||||
of the GNU Lesser General Public License "or any later version"
|
|
||||||
applies to it, you have the option of following the terms and
|
|
||||||
conditions either of that published version or of any later version
|
|
||||||
published by the Free Software Foundation. If the Library as you
|
|
||||||
received it does not specify a version number of the GNU Lesser
|
|
||||||
General Public License, you may choose any version of the GNU Lesser
|
|
||||||
General Public License ever published by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Library as you received it specifies that a proxy can decide
|
|
||||||
whether future versions of the GNU Lesser General Public License shall
|
|
||||||
apply, that proxy's public statement of acceptance of any version is
|
|
||||||
permanent authorization for you to choose that version for the
|
|
||||||
Library.
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Techmino
|
|
||||||
|
|
||||||
《Techmino:方块研究所》
|
|
||||||
——Github & Gitee 官方仓库 Official Repository
|
|
||||||
|
|
||||||
集合各种现代方块规则,更多玩法,全新体验。
|
|
||||||
|
|
||||||
官网(建设中) http://home.techmino.org
|
|
||||||
@@ -4,8 +4,9 @@ local BGs={
|
|||||||
}
|
}
|
||||||
local BGlist={'none'}
|
local BGlist={'none'}
|
||||||
local BG={
|
local BG={
|
||||||
cur='none',
|
|
||||||
default='none',
|
default='none',
|
||||||
|
locked=false,
|
||||||
|
cur='none',
|
||||||
init=false,
|
init=false,
|
||||||
resize=false,
|
resize=false,
|
||||||
update=NULL,
|
update=NULL,
|
||||||
@@ -14,6 +15,8 @@ local BG={
|
|||||||
discard=NULL,
|
discard=NULL,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BG.lock()BG.locked=true end
|
||||||
|
function BG.unlock()BG.locked=false end
|
||||||
function BG.add(name,bg)
|
function BG.add(name,bg)
|
||||||
BGs[name]=bg
|
BGs[name]=bg
|
||||||
BGlist[#BGlist+1]=name
|
BGlist[#BGlist+1]=name
|
||||||
@@ -21,6 +24,9 @@ end
|
|||||||
function BG.getList()
|
function BG.getList()
|
||||||
return BGlist
|
return BGlist
|
||||||
end
|
end
|
||||||
|
function BG.remList(name)
|
||||||
|
table.remove(BGlist,TABLE.find(BGlist,name))
|
||||||
|
end
|
||||||
function BG.send(...)
|
function BG.send(...)
|
||||||
if BG.event then
|
if BG.event then
|
||||||
BG.event(...)
|
BG.event(...)
|
||||||
@@ -29,20 +35,20 @@ end
|
|||||||
function BG.setDefault(bg)
|
function BG.setDefault(bg)
|
||||||
BG.default=bg
|
BG.default=bg
|
||||||
end
|
end
|
||||||
function BG.set(background)
|
function BG.set(name)
|
||||||
if not background then background=BG.default end
|
name=name or BG.default
|
||||||
if not BGs[background]or not SETTING.bg then return end
|
if not BGs[name]or BG.locked then return end
|
||||||
if background~=BG.cur then
|
if name~=BG.cur then
|
||||||
BG.discard()
|
BG.discard()
|
||||||
BG.cur=background
|
BG.cur=name
|
||||||
background=BGs[background]
|
local bg=BGs[name]
|
||||||
|
|
||||||
BG.init= background.init or NULL
|
BG.init= bg.init or NULL
|
||||||
BG.resize= background.resize or NULL
|
BG.resize= bg.resize or NULL
|
||||||
BG.update= background.update or NULL
|
BG.update= bg.update or NULL
|
||||||
BG.draw= background.draw or NULL
|
BG.draw= bg.draw or NULL
|
||||||
BG.event= background.event or NULL
|
BG.event= bg.event or NULL
|
||||||
BG.discard= background.discard or NULL
|
BG.discard=bg.discard or NULL
|
||||||
BG.init()
|
BG.init()
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,109 +1,182 @@
|
|||||||
|
local lastLoaded={}
|
||||||
|
local maxLoadedCount=3
|
||||||
|
local nameList={}
|
||||||
|
local SourceObjList={}
|
||||||
|
local volume=1
|
||||||
|
|
||||||
local BGM={
|
local BGM={
|
||||||
default=false,
|
default=false,
|
||||||
getList=function()error("Cannot getList before initialize!")end,
|
onChange=NULL,
|
||||||
getCount=function()return 0 end,
|
|
||||||
play=NULL,
|
|
||||||
freshVolume=NULL,
|
|
||||||
stop=NULL,
|
|
||||||
--nowPlay=[str:playing ID]
|
--nowPlay=[str:playing ID]
|
||||||
--playing=[src:playing SRC]
|
--playing=[src:playing SRC]
|
||||||
|
--lastPlayed=[str:lastPlayed ID]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BGM.getList()return nameList end
|
||||||
|
function BGM.getCount()return #nameList end
|
||||||
|
local function _addFile(name,path)
|
||||||
|
if not SourceObjList[name]then
|
||||||
|
table.insert(nameList,name)
|
||||||
|
SourceObjList[name]={path=path,source=false}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function BGM.load(name,path)
|
||||||
|
if type(name)=='table'then
|
||||||
|
for k,v in next,name do
|
||||||
|
_addFile(k,v)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
_addFile(name,path)
|
||||||
|
end
|
||||||
|
table.sort(nameList)
|
||||||
|
LOG(BGM.getCount().." BGM files added")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _tryReleaseSources()
|
||||||
|
local n=#lastLoaded
|
||||||
|
while #lastLoaded>maxLoadedCount do
|
||||||
|
local name=lastLoaded[n]
|
||||||
|
if SourceObjList[name].source:isPlaying()then
|
||||||
|
n=n-1
|
||||||
|
if n<=0 then return end
|
||||||
|
else
|
||||||
|
SourceObjList[name].source=SourceObjList[name].source:release()and nil
|
||||||
|
table.remove(lastLoaded,n)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
function BGM.setDefault(bgm)
|
function BGM.setDefault(bgm)
|
||||||
BGM.default=bgm
|
BGM.default=bgm
|
||||||
end
|
end
|
||||||
function BGM.init(list)
|
function BGM.setMaxSources(count)
|
||||||
BGM.init=nil
|
maxLoadedCount=count
|
||||||
local Sources={}
|
_tryReleaseSources()
|
||||||
|
|
||||||
local simpList={}
|
|
||||||
for _,v in next,list do
|
|
||||||
table.insert(simpList,v.name)
|
|
||||||
Sources[v.name]=v.path
|
|
||||||
end
|
end
|
||||||
table.sort(simpList)
|
function BGM.setChange(func)
|
||||||
function BGM.getList()return simpList end
|
BGM.onChange=func
|
||||||
local count=#simpList
|
|
||||||
function BGM.getCount()return count end
|
|
||||||
|
|
||||||
local function load(name)
|
|
||||||
if type(Sources[name])=='string'then
|
|
||||||
if love.filesystem.getInfo(Sources[name])then
|
|
||||||
Sources[name]=love.audio.newSource(Sources[name],'stream')
|
|
||||||
Sources[name]:setLooping(true)
|
|
||||||
Sources[name]:setVolume(0)
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
MES.new('warn',"No BGM file: "..Sources[name],5)
|
|
||||||
end
|
end
|
||||||
elseif Sources[name]then
|
function BGM.setVol(v)
|
||||||
return true
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
elseif name then
|
volume=v
|
||||||
MES.new('warn',"No BGM: "..name,5)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function BGM.loadAll()for name in next,Sources do load(name)end end
|
|
||||||
local function fadeOut(src)
|
|
||||||
while true do
|
|
||||||
coroutine.yield()
|
|
||||||
local v=src:getVolume()-.025*SETTING.bgm
|
|
||||||
src:setVolume(v>0 and v or 0)
|
|
||||||
if v<=0 then
|
|
||||||
src:stop()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function fadeIn(src)
|
|
||||||
while true do
|
|
||||||
coroutine.yield()
|
|
||||||
local v=SETTING.bgm
|
|
||||||
v=math.min(v,src:getVolume()+.025*v)
|
|
||||||
src:setVolume(v)
|
|
||||||
if v>=SETTING.bgm then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local function removeCurFadeOut(task,code,src)
|
|
||||||
return task.code==code and task.args[1]==src
|
|
||||||
end
|
|
||||||
function BGM.play(name)
|
|
||||||
if not name then name=BGM.default end
|
|
||||||
if not load(name)then return end
|
|
||||||
if SETTING.bgm==0 then
|
|
||||||
BGM.nowPlay=name
|
|
||||||
BGM.playing=Sources[name]
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
if name and Sources[name]then
|
|
||||||
if BGM.nowPlay~=name then
|
|
||||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
|
||||||
TASK.removeTask_iterate(removeCurFadeOut,fadeOut,Sources[name])
|
|
||||||
TASK.removeTask_code(fadeIn)
|
|
||||||
|
|
||||||
TASK.new(fadeIn,Sources[name])
|
|
||||||
BGM.nowPlay=name
|
|
||||||
BGM.playing=Sources[name]
|
|
||||||
BGM.playing:play()
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function BGM.freshVolume()
|
|
||||||
if BGM.playing then
|
if BGM.playing then
|
||||||
local v=SETTING.bgm
|
if volume>0 then
|
||||||
if v>0 then
|
BGM.playing:setVolume(volume)
|
||||||
BGM.playing:setVolume(v)
|
|
||||||
BGM.playing:play()
|
BGM.playing:play()
|
||||||
elseif BGM.nowPlay then
|
elseif BGM.nowPlay then
|
||||||
BGM.playing:pause()
|
BGM.playing:pause()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function BGM.stop()
|
|
||||||
TASK.removeTask_code(fadeIn)
|
local function task_fadeOut(src)
|
||||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
local v=src:getVolume()-.025*volume
|
||||||
|
src:setVolume(v>0 and v or 0)
|
||||||
|
if v<=0 then
|
||||||
|
src:pause()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function task_fadeIn(src)
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
local v=volume
|
||||||
|
v=math.min(v,src:getVolume()+.025*v)
|
||||||
|
src:setVolume(v)
|
||||||
|
if v>=volume then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function check_curFadeOut(task,code,src)
|
||||||
|
return task.code==code and task.args[1]==src
|
||||||
|
end
|
||||||
|
local function _tryLoad(name)
|
||||||
|
if SourceObjList[name]then
|
||||||
|
if SourceObjList[name].source then
|
||||||
|
return true
|
||||||
|
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
||||||
|
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
|
||||||
|
SourceObjList[name].source:setVolume(0)
|
||||||
|
table.insert(lastLoaded,1,name)
|
||||||
|
_tryReleaseSources()
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
LOG("No BGM: "..SourceObjList[name],5)
|
||||||
|
end
|
||||||
|
elseif name then
|
||||||
|
LOG("No BGM: "..name,5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function BGM.play(name,args)
|
||||||
|
name=name or BGM.default
|
||||||
|
args=args or""
|
||||||
|
if not _tryLoad(name)or args:sArg('-preLoad')then return end
|
||||||
|
if volume==0 then
|
||||||
|
BGM.nowPlay=name
|
||||||
|
BGM.playing=SourceObjList[name].source
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if name and SourceObjList[name].source then
|
||||||
|
if BGM.nowPlay~=name then
|
||||||
|
if BGM.nowPlay then
|
||||||
|
if not args:sArg('-sdout')then
|
||||||
|
TASK.new(task_fadeOut,BGM.playing)
|
||||||
|
else
|
||||||
|
BGM.playing:pause()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
|
||||||
|
TASK.removeTask_code(task_fadeIn)
|
||||||
|
|
||||||
|
BGM.nowPlay=name
|
||||||
|
BGM.playing=SourceObjList[name].source
|
||||||
|
if not args:sArg('-sdin')then
|
||||||
|
BGM.playing:setVolume(0)
|
||||||
|
TASK.new(task_fadeIn,BGM.playing)
|
||||||
|
else
|
||||||
|
BGM.playing:setVolume(volume)
|
||||||
|
BGM.playing:play()
|
||||||
|
end
|
||||||
|
SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
|
||||||
|
BGM.lastPlayed=BGM.nowPlay
|
||||||
|
BGM.playing:seek(0)
|
||||||
|
BGM.playing:play()
|
||||||
|
BGM.onChange(name)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function BGM.seek(t)
|
||||||
|
if BGM.playing then
|
||||||
|
BGM.playing:seek(t)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function BGM.isPlaying()
|
||||||
|
return BGM.playing and BGM.playing:isPlaying()
|
||||||
|
end
|
||||||
|
function BGM.continue()
|
||||||
|
if BGM.lastPlayed then
|
||||||
|
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
|
||||||
|
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
|
||||||
|
TASK.removeTask_code(task_fadeIn)
|
||||||
|
TASK.new(task_fadeIn,BGM.playing)
|
||||||
|
BGM.playing:play()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function BGM.stop(args)
|
||||||
|
args=args or""
|
||||||
|
TASK.removeTask_code(task_fadeIn)
|
||||||
|
if not args:sArg('-s')then
|
||||||
|
if BGM.nowPlay then
|
||||||
|
TASK.new(task_fadeOut,BGM.playing)
|
||||||
|
end
|
||||||
|
elseif BGM.playing then
|
||||||
|
BGM.playing:pause()
|
||||||
|
end
|
||||||
BGM.nowPlay,BGM.playing=nil
|
BGM.nowPlay,BGM.playing=nil
|
||||||
end
|
end
|
||||||
end
|
|
||||||
return BGM
|
return BGM
|
||||||
@@ -1,66 +1,88 @@
|
|||||||
|
local abs=math.abs
|
||||||
|
local function hsv(h,s,v,a)--Color type, Color amount, Light
|
||||||
|
if s<=0 then return v,v,v,a end
|
||||||
|
h=h*6
|
||||||
|
local c=v*s
|
||||||
|
local x=abs((h-1)%2-1)*c
|
||||||
|
if h<1 then return v,x+v-c,v-c,a
|
||||||
|
elseif h<2 then return x+v-c,v,v-c,a
|
||||||
|
elseif h<3 then return v-c,v,x+v-c,a
|
||||||
|
elseif h<4 then return v-c,x+v-c,v,a
|
||||||
|
elseif h<5 then return x+v-c,v-c,v,a
|
||||||
|
else return v,v-c,x+v-c,a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local COLOR={
|
local COLOR={
|
||||||
red= {.92, .12, .12},
|
hsv=hsv,
|
||||||
fire= {.92, 0.4, .12},
|
|
||||||
orange= {.92, 0.6, .12},
|
|
||||||
yellow= {.92, .92, .12},
|
|
||||||
lime= {0.7, .92, .12},
|
|
||||||
jade= {0.5, .92, .12},
|
|
||||||
green= {.12, .92, .12},
|
|
||||||
aqua= {.12, .92, 0.6},
|
|
||||||
cyan= {.12, .92, .92},
|
|
||||||
navy= {.12, 0.7, .92},
|
|
||||||
sea= {.12, 0.4, .92},
|
|
||||||
blue= {0.2, 0.2, .92},
|
|
||||||
violet= {0.4, .12, .92},
|
|
||||||
purple= {0.7, .12, .92},
|
|
||||||
magenta= {.92, .12, .92},
|
|
||||||
wine= {.92, .12, 0.5},
|
|
||||||
|
|
||||||
lRed= {.95, 0.5, 0.5},
|
red= {hsv(0.00, 0.89, 0.91)},
|
||||||
lFire= {.95, 0.7, 0.5},
|
fire= {hsv(0.04, 0.93, 0.94)},
|
||||||
lOrange= {.95, 0.8, 0.3},
|
orange= {hsv(0.09, 0.99, 0.96)},
|
||||||
lYellow= {.95, .95, 0.5},
|
yellow= {hsv(0.15, 0.82, 0.90)},
|
||||||
lLime= {0.8, .95, 0.4},
|
lime= {hsv(0.20, 0.89, 0.88)},
|
||||||
lJade= {0.6, .95, 0.4},
|
jade= {hsv(0.25, 1.00, 0.82)},
|
||||||
lGreen= {0.5, .95, 0.5},
|
green= {hsv(0.33, 1.00, 0.81)},
|
||||||
lAqua= {0.4, .95, 0.7},
|
aqua= {hsv(0.47, 1.00, 0.76)},
|
||||||
lCyan= {0.5, .95, .95},
|
cyan= {hsv(0.53, 1.00, 0.88)},
|
||||||
lNavy= {0.4, .85, .95},
|
navy= {hsv(0.56, 1.00, 1.00)},
|
||||||
lSea= {0.5, 0.7, .95},
|
sea= {hsv(0.61, 1.00, 1.00)},
|
||||||
lBlue= {0.7, 0.7, .95},
|
blue= {hsv(0.64, 1.00, 0.95)},
|
||||||
lViolet= {0.7, 0.4, .95},
|
violet= {hsv(0.74, 1.00, 0.91)},
|
||||||
lPurple= {0.8, 0.4, .95},
|
purple= {hsv(0.80, 1.00, 0.81)},
|
||||||
lMagenta= {.95, 0.5, .95},
|
magenta= {hsv(0.86, 1.00, 0.78)},
|
||||||
lWine= {.95, 0.4, 0.7},
|
wine= {hsv(0.92, 0.98, 0.91)},
|
||||||
|
|
||||||
dRed= {0.6, .08, .08},
|
lRed= {hsv(0.00, 0.38, 0.93)},
|
||||||
dFire= {0.6, 0.3, .08},
|
lFire= {hsv(0.04, 0.45, 0.91)},
|
||||||
dOrange= {0.6, 0.4, .08},
|
lOrange= {hsv(0.10, 0.53, 0.92)},
|
||||||
dYellow= {0.6, 0.6, .08},
|
lYellow= {hsv(0.14, 0.61, 0.95)},
|
||||||
dLime= {0.5, 0.6, .08},
|
lLime= {hsv(0.20, 0.66, 0.92)},
|
||||||
dJade= {0.3, 0.6, .08},
|
lJade= {hsv(0.26, 0.56, 0.90)},
|
||||||
dGreen= {.08, 0.6, .08},
|
lGreen= {hsv(0.34, 0.49, 0.89)},
|
||||||
dAqua= {.08, 0.6, 0.4},
|
lAqua= {hsv(0.47, 0.59, 0.86)},
|
||||||
dCyan= {.08, 0.6, 0.6},
|
lCyan= {hsv(0.51, 0.77, 0.88)},
|
||||||
dNavy= {.08, 0.4, 0.6},
|
lNavy= {hsv(0.54, 0.80, 0.95)},
|
||||||
dSea= {.08, 0.2, 0.6},
|
lSea= {hsv(0.57, 0.72, 0.97)},
|
||||||
dBlue= {0.1, 0.1, 0.6},
|
lBlue= {hsv(0.64, 0.44, 0.96)},
|
||||||
dViolet= {0.2, .08, 0.6},
|
lViolet= {hsv(0.72, 0.47, 0.95)},
|
||||||
dPurple= {0.4, .08, 0.6},
|
lPurple= {hsv(0.80, 0.62, 0.89)},
|
||||||
dMagenta= {0.6, .08, 0.6},
|
lMagenta= {hsv(0.86, 0.61, 0.89)},
|
||||||
dWine= {0.6, .08, 0.3},
|
lWine= {hsv(0.93, 0.57, 0.92)},
|
||||||
|
|
||||||
black= {.05, .05, .05},
|
dRed= {hsv(0.00, 0.80, 0.48)},
|
||||||
dGray= {0.3, 0.3, 0.3},
|
dFire= {hsv(0.04, 0.80, 0.34)},
|
||||||
gray= {0.6, 0.6, 0.6},
|
dOrange= {hsv(0.07, 0.80, 0.39)},
|
||||||
lGray= {0.8, 0.8, 0.8},
|
dYellow= {hsv(0.12, 0.80, 0.37)},
|
||||||
white= {.97, .97, .97},
|
dLime= {hsv(0.20, 0.80, 0.26)},
|
||||||
|
dJade= {hsv(0.29, 0.80, 0.27)},
|
||||||
|
dGreen= {hsv(0.33, 0.80, 0.26)},
|
||||||
|
dAqua= {hsv(0.46, 0.80, 0.24)},
|
||||||
|
dCyan= {hsv(0.50, 0.80, 0.30)},
|
||||||
|
dNavy= {hsv(0.58, 0.80, 0.42)},
|
||||||
|
dSea= {hsv(0.64, 0.80, 0.40)},
|
||||||
|
dBlue= {hsv(0.67, 0.80, 0.34)},
|
||||||
|
dViolet= {hsv(0.71, 0.80, 0.35)},
|
||||||
|
dPurple= {hsv(0.76, 0.80, 0.32)},
|
||||||
|
dMagenta= {hsv(0.87, 0.80, 0.28)},
|
||||||
|
dWine= {hsv(0.92, 0.80, 0.28)},
|
||||||
|
|
||||||
|
black= {hsv(0.04, 0.04, 0.14)},
|
||||||
|
dGray= {hsv(0.02, 0.05, 0.44)},
|
||||||
|
gray= {hsv(0.02, 0.05, 0.65)},
|
||||||
|
lGray= {hsv(0.02, 0.06, 0.86)},
|
||||||
|
white= {hsv(0.01, 0.02, 0.99)},
|
||||||
|
|
||||||
|
xGray= {hsv(0.00, 0.00, 0.35,.8)},
|
||||||
|
lxGray= {hsv(0.00, 0.00, 0.62,.8)},
|
||||||
|
dxGray= {hsv(0.00, 0.00, 0.16,.8)},
|
||||||
}
|
}
|
||||||
for k,v in next,{
|
for k,v in next,{
|
||||||
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
|
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
|
||||||
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
|
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
|
||||||
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
|
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
|
||||||
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
|
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
|
||||||
|
X='xGray',lX='lxGray',dX='dxGray',
|
||||||
--Remain letter: EIKQTUX
|
--Remain letter: EIKQTUX
|
||||||
}do
|
}do
|
||||||
COLOR[k]=COLOR[v]
|
COLOR[k]=COLOR[v]
|
||||||
|
|||||||
@@ -1,66 +1,79 @@
|
|||||||
local fs=love.filesystem
|
local fs=love.filesystem
|
||||||
local FILE={}
|
local FILE={}
|
||||||
function FILE.load(name)
|
function FILE.load(name,args)
|
||||||
|
if not args then args=''end
|
||||||
if fs.getInfo(name)then
|
if fs.getInfo(name)then
|
||||||
local F=fs.newFile(name)
|
local F=fs.newFile(name)
|
||||||
if F:open'r'then
|
assert(F:open'r','open error')
|
||||||
local s=F:read()
|
local s=F:read()F:close()
|
||||||
F:close()
|
local mode=
|
||||||
if s:sub(1,6)=="return"then
|
STRING.sArg(args,'-luaon')and'luaon'or
|
||||||
s=loadstring(s)
|
STRING.sArg(args,'-lua')and'lua'or
|
||||||
if s then
|
STRING.sArg(args,'-json')and'json'or
|
||||||
setfenv(s,{})
|
STRING.sArg(args,'-string')and'string'or
|
||||||
return s()
|
s:sub(1,6)=='return{'and'luaon'or
|
||||||
|
(s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or
|
||||||
|
'string'
|
||||||
|
if mode=='luaon'then
|
||||||
|
local func,err_mes=loadstring(s)
|
||||||
|
if func then
|
||||||
|
setfenv(func,{})
|
||||||
|
local res=func()
|
||||||
|
return assert(res,'decode error')
|
||||||
|
else
|
||||||
|
error('decode error: '..err_mes)
|
||||||
end
|
end
|
||||||
elseif s:sub(1,1)=="["or s:sub(1,1)=="{"then
|
elseif mode=='lua'then
|
||||||
|
local func,err_mes=loadstring(s)
|
||||||
|
if func then
|
||||||
|
local res=func()
|
||||||
|
return assert(res,'run error')
|
||||||
|
else
|
||||||
|
error('compile error: '..err_mes)
|
||||||
|
end
|
||||||
|
elseif mode=='json'then
|
||||||
local res=JSON.decode(s)
|
local res=JSON.decode(s)
|
||||||
if res then
|
if res then
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
else
|
error('decode error')
|
||||||
|
elseif mode=='string'then
|
||||||
return s
|
return s
|
||||||
|
else
|
||||||
|
error('unknown mode')
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error('no file')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
MES.new('error',name.." "..text.loadError)
|
function FILE.save(data,name,args)
|
||||||
|
if not args then args=''end
|
||||||
|
if STRING.sArg(args,'-d')and fs.getInfo(name)then
|
||||||
|
error('duplicate')
|
||||||
end
|
end
|
||||||
end
|
|
||||||
function FILE.save(data,name,mode)
|
|
||||||
if not mode then mode=""end
|
|
||||||
if type(data)=='table'then
|
if type(data)=='table'then
|
||||||
if mode:find'l'then
|
if STRING.sArg(args,'-luaon')then
|
||||||
data=TABLE.dump(data)
|
data=TABLE.dump(data)
|
||||||
if not data then
|
if not data then
|
||||||
MES.new('error',name.." "..text.saveError.."dump error")
|
error('encode error')
|
||||||
return
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
data=JSON.encode(data)
|
data=JSON.encode(data)
|
||||||
if not data then
|
if not data then
|
||||||
MES.new('error',name.." "..text.saveError.."json error")
|
error('encode error')
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
data=tostring(data)
|
data=tostring(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
if mode:find'd'and fs.getInfo(name)then
|
|
||||||
MES.new('error',text.saveError_duplicate)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local F=fs.newFile(name)
|
local F=fs.newFile(name)
|
||||||
F:open'w'
|
assert(F:open('w'),'open error')
|
||||||
local success,mes=F:write(data)
|
F:write(data)F:flush()F:close()
|
||||||
F:flush()F:close()
|
|
||||||
if success then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
MES.new('error',text.saveError..(mes or"unknown error"))
|
|
||||||
MES.traceback()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
function FILE.clear(path)
|
function FILE.clear(path)
|
||||||
if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end
|
if fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory'then
|
||||||
for _,name in next,fs.getDirectoryItems(path)do
|
for _,name in next,fs.getDirectoryItems(path)do
|
||||||
name=path..'/'..name
|
name=path..'/'..name
|
||||||
if fs.getRealDirectory(name)==SAVEDIR then
|
if fs.getRealDirectory(name)==SAVEDIR then
|
||||||
@@ -71,8 +84,9 @@ function FILE.clear(path)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
function FILE.clear_s(path)
|
function FILE.clear_s(path)
|
||||||
if path~=''and(fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory')then return end
|
if path==''or(fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory')then
|
||||||
for _,name in next,fs.getDirectoryItems(path)do
|
for _,name in next,fs.getDirectoryItems(path)do
|
||||||
name=path..'/'..name
|
name=path..'/'..name
|
||||||
if fs.getRealDirectory(name)==SAVEDIR then
|
if fs.getRealDirectory(name)==SAVEDIR then
|
||||||
@@ -87,4 +101,5 @@ function FILE.clear_s(path)
|
|||||||
end
|
end
|
||||||
fs.remove(path)
|
fs.remove(path)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return FILE
|
return FILE
|
||||||
60
Zframework/font.lua
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
local gc=love.graphics
|
||||||
|
local set=gc.setFont
|
||||||
|
local fontFiles,fontCache={},{}
|
||||||
|
local defaultFont,defaultFallBack
|
||||||
|
local curFont=false--Current using font object
|
||||||
|
|
||||||
|
local FONT={}
|
||||||
|
function FONT.setDefault(name)defaultFont=name end
|
||||||
|
function FONT.setFallback(name)defaultFallBack=name end
|
||||||
|
function FONT.rawget(s)
|
||||||
|
if not fontCache[s]then
|
||||||
|
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
||||||
|
end
|
||||||
|
return fontCache[s]
|
||||||
|
end
|
||||||
|
function FONT.rawset(s)
|
||||||
|
set(fontCache[s]or FONT.rawget(s))
|
||||||
|
end
|
||||||
|
function FONT.load(fonts)
|
||||||
|
for name,path in next,fonts do
|
||||||
|
assert(love.filesystem.getInfo(path),STRING.repD("Font file $1($2) not exist!",name,path))
|
||||||
|
fontFiles[name]=love.filesystem.newFile(path)
|
||||||
|
fontCache[name]={}
|
||||||
|
end
|
||||||
|
FONT.reset()
|
||||||
|
end
|
||||||
|
function FONT.get(size,name)
|
||||||
|
if not name then name=defaultFont end
|
||||||
|
local f=fontCache[name][size]
|
||||||
|
if not f then
|
||||||
|
f=gc.setNewFont(fontFiles[name],size,'light',gc.getDPIScale()*SCR.k*2)
|
||||||
|
if defaultFallBack and name~=defaultFallBack then
|
||||||
|
f:setFallbacks(FONT.get(size,defaultFallBack))
|
||||||
|
end
|
||||||
|
fontCache[name][size]=f
|
||||||
|
end
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
function FONT.set(size,name)
|
||||||
|
if not name then name=defaultFont end
|
||||||
|
|
||||||
|
local f=fontCache[name][size]
|
||||||
|
if f~=curFont then
|
||||||
|
curFont=f or FONT.get(size,name)
|
||||||
|
set(curFont)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function FONT.reset()
|
||||||
|
for name,cache in next,fontCache do
|
||||||
|
if type(cache)=='table'then
|
||||||
|
for size in next,cache do
|
||||||
|
cache[size]=FONT.get(size,name)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
fontCache[name]=FONT.rawget(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return FONT
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
local gc=love.graphics
|
local gc=love.graphics
|
||||||
local setColor,printf,draw=gc.setColor,gc.printf,gc.draw
|
local setColor,printf,draw=gc.setColor,gc.printf,gc.draw
|
||||||
local GC={}
|
local GC={}
|
||||||
function GC.str(obj,x,y)printf(obj,x-626,y,1252,'center')end
|
function GC.mStr(obj,x,y)printf(obj,x-626,y,1252,'center')end--Printf a string with 'center'
|
||||||
function GC.simpX(obj,x,y)draw(obj,x-obj:getWidth()*.5,y)end
|
function GC.simpX(obj,x,y)draw(obj,x-obj:getWidth()*.5,y)end--Simply draw an obj with x=obj:getWidth()/2
|
||||||
function GC.simpY(obj,x,y)draw(obj,x,y-obj:getHeight()*.5)end
|
function GC.simpY(obj,x,y)draw(obj,x,y-obj:getHeight()*.5)end--Simply draw an obj with y=obj:getWidth()/2
|
||||||
function GC.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end
|
function GC.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end--Draw an obj with x=obj:getWidth()/2
|
||||||
function GC.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end
|
function GC.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end--Draw an obj with y=obj:getWidth()/2
|
||||||
function GC.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end
|
function GC.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end--Draw an obj with both middle X & Y
|
||||||
function GC.outDraw(obj,div,x,y,a,k)
|
function GC.outDraw(obj,div,x,y,a,k)
|
||||||
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
|
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
|
||||||
draw(obj,x-div,y-div,a,k,nil,w,h)
|
draw(obj,x-div,y-div,a,k,nil,w,h)
|
||||||
@@ -95,9 +95,12 @@ do--function GC.DO(L)
|
|||||||
setLJ="setLineJoin",
|
setLJ="setLineJoin",
|
||||||
|
|
||||||
print="print",
|
print="print",
|
||||||
setFT=function(...)setFont(...)end,
|
rawFT=function(...)FONT.rawset(...)end,
|
||||||
mText=GC.str,
|
setFT=function(...)FONT.set(...)end,
|
||||||
|
mText=GC.mStr,
|
||||||
mDraw=GC.draw,
|
mDraw=GC.draw,
|
||||||
|
mDrawX=GC.X,
|
||||||
|
mDrawY=GC.Y,
|
||||||
mOutDraw=GC.outDraw,
|
mOutDraw=GC.outDraw,
|
||||||
|
|
||||||
draw="draw",
|
draw="draw",
|
||||||
@@ -143,7 +146,9 @@ do--function GC.DO(L)
|
|||||||
end
|
end
|
||||||
if type(cmd)=='string'then
|
if type(cmd)=='string'then
|
||||||
local func=cmds[cmd]
|
local func=cmds[cmd]
|
||||||
if type(func)=='string'then func=gc[func]end
|
if type(func)=='string'then
|
||||||
|
func=gc[func]
|
||||||
|
end
|
||||||
if func then
|
if func then
|
||||||
func(unpack(L[i],2))
|
func(unpack(L[i],2))
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ local IMG={}
|
|||||||
function IMG.init(list)
|
function IMG.init(list)
|
||||||
IMG.init=nil
|
IMG.init=nil
|
||||||
|
|
||||||
local null=love.graphics.newCanvas(1,1)
|
|
||||||
setmetatable(IMG,{__index=function(self,name)
|
setmetatable(IMG,{__index=function(self,name)
|
||||||
if type(list[name])=='table'then
|
if type(list[name])=='table'then
|
||||||
self[name]={}
|
self[name]={}
|
||||||
@@ -12,8 +11,8 @@ function IMG.init(list)
|
|||||||
elseif type(list[name])=='string'then
|
elseif type(list[name])=='string'then
|
||||||
self[name]=love.graphics.newImage(list[name])
|
self[name]=love.graphics.newImage(list[name])
|
||||||
else
|
else
|
||||||
MES.new('warn',"No IMG: "..name,5)
|
LOG("No IMG: "..name)
|
||||||
self[name]=null
|
self[name]=PAPER
|
||||||
end
|
end
|
||||||
return self[name]
|
return self[name]
|
||||||
end})
|
end})
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
NONE={}function NULL()end
|
NONE={}function NULL()end PAPER=love.graphics.newCanvas(1,1)
|
||||||
EDITING=""
|
EDITING=""
|
||||||
LOADED=false
|
LOADED=false
|
||||||
ERRDATA={}
|
|
||||||
|
|
||||||
--Pure lua modules (basic)
|
--Pure lua modules (basic)
|
||||||
|
MATH= require'Zframework.mathExtend'
|
||||||
COLOR= require'Zframework.color'
|
COLOR= require'Zframework.color'
|
||||||
TABLE= require'Zframework.tableExtend'
|
TABLE= require'Zframework.tableExtend'
|
||||||
STRING= require'Zframework.stringExtend'
|
STRING= require'Zframework.stringExtend'
|
||||||
PROFILE= require'Zframework.profile'
|
PROFILE= require'Zframework.profile'
|
||||||
JSON= require'Zframework.json'
|
JSON= require'Zframework.json'
|
||||||
|
TEST= require'Zframework.test'
|
||||||
|
|
||||||
do--Add pcall & MES for JSON lib
|
do--Add pcall & MES for JSON lib
|
||||||
local encode,decode=JSON.encode,JSON.decode
|
local encode,decode=JSON.encode,JSON.decode
|
||||||
JSON.encode=function(val)
|
JSON.encode=function(val)
|
||||||
@@ -30,11 +32,11 @@ do--Add pcall & MES for JSON lib
|
|||||||
end
|
end
|
||||||
|
|
||||||
--Pure lua modules (complex)
|
--Pure lua modules (complex)
|
||||||
LOADLIB=require'Zframework.loadLib'
|
LOG= require'Zframework.log'
|
||||||
|
REQUIRE= require'Zframework.require'
|
||||||
TASK= require'Zframework.task'
|
TASK= require'Zframework.task'
|
||||||
WS= require'Zframework.websocket'
|
WS= require'Zframework.websocket'
|
||||||
LANG= require'Zframework.languages'
|
LANG= require'Zframework.languages'
|
||||||
THEME= require'Zframework.theme'
|
|
||||||
|
|
||||||
--Love-based modules (basic)
|
--Love-based modules (basic)
|
||||||
FILE= require'Zframework.file'
|
FILE= require'Zframework.file'
|
||||||
@@ -45,10 +47,7 @@ LIGHT= require'Zframework.light'
|
|||||||
|
|
||||||
--Love-based modules (complex)
|
--Love-based modules (complex)
|
||||||
GC= require'Zframework.gcExtend'
|
GC= require'Zframework.gcExtend'
|
||||||
mStr=GC.str
|
FONT= require'Zframework.font'
|
||||||
mText=GC.simpX
|
|
||||||
mDraw=GC.draw
|
|
||||||
require'Zframework.setFont'
|
|
||||||
TEXT= require'Zframework.text'
|
TEXT= require'Zframework.text'
|
||||||
SYSFX= require'Zframework.sysFX'
|
SYSFX= require'Zframework.sysFX'
|
||||||
MES= require'Zframework.message'
|
MES= require'Zframework.message'
|
||||||
@@ -61,28 +60,36 @@ BGM= require'Zframework.bgm'
|
|||||||
VOC= require'Zframework.voice'
|
VOC= require'Zframework.voice'
|
||||||
|
|
||||||
local ms,kb=love.mouse,love.keyboard
|
local ms,kb=love.mouse,love.keyboard
|
||||||
|
local KBisDown=kb.isDown
|
||||||
|
|
||||||
local gc=love.graphics
|
local gc=love.graphics
|
||||||
local gc_push,gc_pop,gc_clear,gc_discard=gc.push,gc.pop,gc.clear,gc.discard
|
local gc_push,gc_pop,gc_clear,gc_discard=gc.push,gc.pop,gc.clear,gc.discard
|
||||||
local gc_replaceTransform,gc_present=gc.replaceTransform,gc.present
|
local gc_replaceTransform,gc_present=gc.replaceTransform,gc.present
|
||||||
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
||||||
local gc_draw,gc_line,gc_print=gc.draw,gc.line,gc.print
|
local gc_draw,gc_line,gc_circle,gc_print=gc.draw,gc.line,gc.circle,gc.print
|
||||||
|
|
||||||
local setFont,mStr=setFont,mStr
|
|
||||||
|
|
||||||
local int,rnd,abs=math.floor,math.random,math.abs
|
|
||||||
local min,sin=math.min,math.sin
|
|
||||||
local ins,rem=table.insert,table.remove
|
|
||||||
|
|
||||||
local WIDGET,SCR,SCN=WIDGET,SCR,SCN
|
local WIDGET,SCR,SCN=WIDGET,SCR,SCN
|
||||||
local xOy=SCR.xOy
|
local xOy=SCR.xOy
|
||||||
local ITP=xOy.inverseTransformPoint
|
local ITP=xOy.inverseTransformPoint
|
||||||
|
|
||||||
local mx,my,mouseShow=-20,-20,false
|
local max,min=math.max,math.min
|
||||||
local touching--First touching ID(userdata)
|
|
||||||
joysticks={}
|
|
||||||
|
|
||||||
local devMode
|
local devMode
|
||||||
|
local mx,my,mouseShow,cursorSpd=640,360,false,0
|
||||||
|
local jsState={}--map, joystickID->axisStates: {axisName->axisVal}
|
||||||
|
local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr}
|
||||||
|
|
||||||
|
local function drawCursor(_,x,y)
|
||||||
|
gc_setColor(1,1,1)
|
||||||
|
gc_setLineWidth(2)
|
||||||
|
gc_circle(ms.isDown(1)and'fill'or'line',x,y,6)
|
||||||
|
end
|
||||||
|
local showPowerInfo=true
|
||||||
|
local showClickFX=true
|
||||||
|
local discardCanvas=false
|
||||||
|
local frameMul=100
|
||||||
|
local sleepInterval=1/60
|
||||||
|
local onQuit=NULL
|
||||||
|
|
||||||
local batteryImg=GC.DO{31,20,
|
local batteryImg=GC.DO{31,20,
|
||||||
{'fRect',1,0,26,2},
|
{'fRect',1,0,26,2},
|
||||||
@@ -100,13 +107,12 @@ local function updatePowerInfo()
|
|||||||
gc_clear(0,0,0,.25)
|
gc_clear(0,0,0,.25)
|
||||||
if state~='unknown'then
|
if state~='unknown'then
|
||||||
gc_setLineWidth(4)
|
gc_setLineWidth(4)
|
||||||
local charging=state=='charging'
|
|
||||||
if state=='nobattery'then
|
if state=='nobattery'then
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
gc_line(74,SCR.safeX+5,100,22)
|
gc_line(74,5,100,22)
|
||||||
elseif pow then
|
elseif pow then
|
||||||
if charging then gc_setColor(0,1,0)
|
if state=='charging'then gc_setColor(0,1,0)
|
||||||
elseif pow>50 then gc_setColor(1,1,1)
|
elseif pow>50 then gc_setColor(1,1,1)
|
||||||
elseif pow>26 then gc_setColor(1,1,0)
|
elseif pow>26 then gc_setColor(1,1,0)
|
||||||
elseif pow==26 then gc_setColor(.5,0,1)
|
elseif pow==26 then gc_setColor(.5,0,1)
|
||||||
@@ -114,7 +120,7 @@ local function updatePowerInfo()
|
|||||||
end
|
end
|
||||||
gc.rectangle('fill',76,6,pow*.22,14)
|
gc.rectangle('fill',76,6,pow*.22,14)
|
||||||
if pow<100 then
|
if pow<100 then
|
||||||
setFont(15)
|
FONT.set(15)
|
||||||
gc.setColor(COLOR.D)
|
gc.setColor(COLOR.D)
|
||||||
gc_print(pow,77,1)
|
gc_print(pow,77,1)
|
||||||
gc_print(pow,77,3)
|
gc_print(pow,77,3)
|
||||||
@@ -126,43 +132,88 @@ local function updatePowerInfo()
|
|||||||
end
|
end
|
||||||
gc_draw(batteryImg,73,3)
|
gc_draw(batteryImg,73,3)
|
||||||
end
|
end
|
||||||
setFont(25)
|
FONT.set(25)
|
||||||
gc_print(os.date("%H:%M"),3,-5)
|
gc_print(os.date("%H:%M"),3,-5)
|
||||||
gc_pop()
|
gc_pop()
|
||||||
gc.setCanvas()
|
gc.setCanvas()
|
||||||
end
|
end
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
local lastX,lastY=0,0--Last click pos
|
local lastX,lastY=0,0--Last click pos
|
||||||
|
local function _updateMousePos(x,y,dx,dy)
|
||||||
|
if SCN.swapping then return end
|
||||||
|
dx,dy=dx/SCR.k,dy/SCR.k
|
||||||
|
if SCN.mouseMove then SCN.mouseMove(x,y,dx,dy)end
|
||||||
|
if ms.isDown(1)then
|
||||||
|
WIDGET.drag(x,y,dx,dy)
|
||||||
|
else
|
||||||
|
WIDGET.cursorMove(x,y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function _triggerMouseDown(x,y,k)
|
||||||
|
if devMode==1 then
|
||||||
|
print(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
|
||||||
|
x,y,
|
||||||
|
x-lastX,y-lastY,
|
||||||
|
math.floor(x/10)*10,math.floor(y/10)*10,
|
||||||
|
math.floor((x-lastX)/10)*10,math.floor((y-lastY)/10)*10
|
||||||
|
))
|
||||||
|
end
|
||||||
|
if SCN.swapping then return end
|
||||||
|
if SCN.mouseDown then SCN.mouseDown(x,y,k)end
|
||||||
|
WIDGET.press(x,y,k)
|
||||||
|
lastX,lastY=x,y
|
||||||
|
if showClickFX then SYSFX.newTap(3,x,y)end
|
||||||
|
end
|
||||||
|
local function mouse_update(dt)
|
||||||
|
if not KBisDown('lctrl','rctrl')and KBisDown('up','down','left','right')then
|
||||||
|
local dx,dy=0,0
|
||||||
|
if KBisDown('up')then dy=dy-cursorSpd end
|
||||||
|
if KBisDown('down')then dy=dy+cursorSpd end
|
||||||
|
if KBisDown('left')then dx=dx-cursorSpd end
|
||||||
|
if KBisDown('right')then dx=dx+cursorSpd end
|
||||||
|
mx=max(min(mx+dx,1280),0)
|
||||||
|
my=max(min(my+dy,720),0)
|
||||||
|
if my==0 or my==720 then
|
||||||
|
WIDGET.sel=false
|
||||||
|
WIDGET.drag(0,0,0,-dy)
|
||||||
|
end
|
||||||
|
_updateMousePos(mx,my,dx,dy)
|
||||||
|
cursorSpd=min(cursorSpd+dt*26,12.6)
|
||||||
|
else
|
||||||
|
cursorSpd=6
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function gp_update(js,dt)
|
||||||
|
local sx,sy=js._jsObj:getGamepadAxis('leftx'),js._jsObj:getGamepadAxis('lefty')
|
||||||
|
if math.abs(sx)>.1 or math.abs(sy)>.1 then
|
||||||
|
local dx,dy=0,0
|
||||||
|
if sy<-.1 then dy=dy+2*sy*cursorSpd end
|
||||||
|
if sy>.1 then dy=dy+2*sy*cursorSpd end
|
||||||
|
if sx<-.1 then dx=dx+2*sx*cursorSpd end
|
||||||
|
if sx>.1 then dx=dx+2*sx*cursorSpd end
|
||||||
|
mx=max(min(mx+dx,1280),0)
|
||||||
|
my=max(min(my+dy,720),0)
|
||||||
|
if my==0 or my==720 then
|
||||||
|
WIDGET.sel=false
|
||||||
|
WIDGET.drag(0,0,0,-dy)
|
||||||
|
end
|
||||||
|
_updateMousePos(mx,my,dx,dy)
|
||||||
|
cursorSpd=min(cursorSpd+dt*26,12.6)
|
||||||
|
else
|
||||||
|
cursorSpd=6
|
||||||
|
end
|
||||||
|
end
|
||||||
function love.mousepressed(x,y,k,touch)
|
function love.mousepressed(x,y,k,touch)
|
||||||
if touch then return end
|
if touch then return end
|
||||||
mouseShow=true
|
mouseShow=true
|
||||||
mx,my=ITP(xOy,x,y)
|
mx,my=ITP(xOy,x,y)
|
||||||
if devMode==1 then
|
_triggerMouseDown(mx,my,k)
|
||||||
print(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
|
|
||||||
mx,my,
|
|
||||||
mx-lastX,my-lastY,
|
|
||||||
int(mx/10)*10,int(my/10)*10,
|
|
||||||
int((mx-lastX)/10)*10,int((my-lastY)/10)*10
|
|
||||||
))
|
|
||||||
end
|
|
||||||
if SCN.swapping then return end
|
|
||||||
if SCN.mouseDown then SCN.mouseDown(mx,my,k)end
|
|
||||||
WIDGET.press(mx,my,k)
|
|
||||||
lastX,lastY=mx,my
|
|
||||||
if SETTING.clickFX then SYSFX.newTap(3,mx,my)end
|
|
||||||
end
|
end
|
||||||
function love.mousemoved(x,y,dx,dy,touch)
|
function love.mousemoved(x,y,dx,dy,touch)
|
||||||
if touch then return end
|
if touch then return end
|
||||||
mouseShow=true
|
mouseShow=true
|
||||||
mx,my=ITP(xOy,x,y)
|
mx,my=ITP(xOy,x,y)
|
||||||
if SCN.swapping then return end
|
_updateMousePos(mx,my,dx,dy)
|
||||||
dx,dy=dx/SCR.k,dy/SCR.k
|
|
||||||
if SCN.mouseMove then SCN.mouseMove(mx,my,dx,dy)end
|
|
||||||
if ms.isDown(1)then
|
|
||||||
WIDGET.drag(mx,my,dx/SCR.k,dy/SCR.k)
|
|
||||||
else
|
|
||||||
WIDGET.cursorMove(mx,my)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
function love.mousereleased(x,y,k,touch)
|
function love.mousereleased(x,y,k,touch)
|
||||||
if touch or SCN.swapping then return end
|
if touch or SCN.swapping then return end
|
||||||
@@ -189,87 +240,67 @@ end
|
|||||||
function love.touchpressed(id,x,y)
|
function love.touchpressed(id,x,y)
|
||||||
mouseShow=false
|
mouseShow=false
|
||||||
if SCN.swapping then return end
|
if SCN.swapping then return end
|
||||||
if not touching then
|
if not SCN.mainTouchID then
|
||||||
touching=id
|
SCN.mainTouchID=id
|
||||||
WIDGET.unFocus(true)
|
WIDGET.unFocus(true)
|
||||||
love.touchmoved(id,x,y,0,0)
|
love.touchmoved(id,x,y,0,0)
|
||||||
end
|
end
|
||||||
x,y=ITP(xOy,x,y)
|
x,y=ITP(xOy,x,y)
|
||||||
lastX,lastY=x,y
|
lastX,lastY=x,y
|
||||||
if SCN.touchDown then SCN.touchDown(x,y)end
|
WIDGET.cursorMove(x,y)
|
||||||
|
if SCN.touchDown then SCN.touchDown(x,y,id)end
|
||||||
if kb.hasTextInput()then kb.setTextInput(false)end
|
if kb.hasTextInput()then kb.setTextInput(false)end
|
||||||
end
|
end
|
||||||
function love.touchmoved(_,x,y,dx,dy)
|
function love.touchmoved(id,x,y,dx,dy)
|
||||||
if SCN.swapping then return end
|
if SCN.swapping then return end
|
||||||
x,y=ITP(xOy,x,y)
|
x,y=ITP(xOy,x,y)
|
||||||
if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k)end
|
if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k,id)end
|
||||||
WIDGET.drag(x,y,dx/SCR.k,dy/SCR.k)
|
WIDGET.drag(x,y,dx/SCR.k,dy/SCR.k)
|
||||||
if touching then
|
|
||||||
WIDGET.cursorMove(x,y)
|
|
||||||
if not WIDGET.sel then touching=false end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
function love.touchreleased(id,x,y)
|
function love.touchreleased(id,x,y)
|
||||||
if SCN.swapping then return end
|
if SCN.swapping then return end
|
||||||
x,y=ITP(xOy,x,y)
|
x,y=ITP(xOy,x,y)
|
||||||
if id==touching then
|
if id==SCN.mainTouchID then
|
||||||
WIDGET.press(x,y,1)
|
WIDGET.press(x,y,1)
|
||||||
WIDGET.release(x,y)
|
WIDGET.release(x,y)
|
||||||
WIDGET.cursorMove(x,y)
|
WIDGET.cursorMove(x,y)
|
||||||
WIDGET.unFocus()
|
WIDGET.unFocus()
|
||||||
touching=false
|
SCN.mainTouchID=false
|
||||||
end
|
end
|
||||||
if SCN.touchUp then SCN.touchUp(x,y)end
|
if SCN.touchUp then SCN.touchUp(x,y,id)end
|
||||||
if(x-lastX)^2+(y-lastY)^2<62 then
|
if(x-lastX)^2+(y-lastY)^2<62 then
|
||||||
if SCN.touchClick then SCN.touchClick(x,y)end
|
if SCN.touchClick then SCN.touchClick(x,y)end
|
||||||
if SETTING.clickFX then SYSFX.newTap(3,x,y)end
|
if showClickFX then SYSFX.newTap(3,x,y)end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local fnKey={NULL,NULL,NULL,NULL,NULL,NULL,NULL}
|
||||||
local function noDevkeyPressed(key)
|
local function noDevkeyPressed(key)
|
||||||
if key=="f1"then
|
if key=='f1'then fnKey[1]()
|
||||||
MES.new('check',PROFILE.switch()and"profile start!"or"profile report copied!")
|
elseif key=='f2'then fnKey[2]()
|
||||||
elseif key=="f2"then
|
elseif key=='f3'then fnKey[3]()
|
||||||
MES.new('info',("System:%s[%s]\nluaVer:%s\njitVer:%s\njitVerNum:%s"):format(SYSTEM,jit.arch,_VERSION,jit.version,jit.version_num))
|
elseif key=='f4'then fnKey[4]()
|
||||||
elseif key=="f3"then
|
elseif key=='f5'then fnKey[5]()
|
||||||
MES.new('error',"挂了")
|
elseif key=='f6'then fnKey[6]()
|
||||||
elseif key=="f4"then
|
elseif key=='f7'then fnKey[7]()
|
||||||
for _=1,8 do
|
elseif key=='f8'then devMode=nil MES.new('info',"DEBUG OFF",.2)
|
||||||
local P=PLY_ALIVE[rnd(#PLY_ALIVE)]
|
elseif key=='f9'then devMode=1 MES.new('info',"DEBUG 1")
|
||||||
if P and P~=PLAYERS[1]then
|
elseif key=='f10'then devMode=2 MES.new('info',"DEBUG 2")
|
||||||
P.lastRecv=PLAYERS[1]
|
elseif key=='f11'then devMode=3 MES.new('info',"DEBUG 3")
|
||||||
P:lose()
|
elseif key=='f12'then devMode=4 MES.new('info',"DEBUG 4")
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif key=="f5"then
|
|
||||||
print(WIDGET.getSelected()or"no widget selected")
|
|
||||||
elseif key=="f6"then
|
|
||||||
for k,v in next,_G do print(k,v)end
|
|
||||||
elseif key=="f7"and love._openConsole then
|
|
||||||
love._openConsole()
|
|
||||||
elseif key=="f8"then
|
|
||||||
devMode=nil MES.new('info',"DEBUG OFF",.2)
|
|
||||||
elseif key=="f9"then
|
|
||||||
devMode=1 MES.new('info',"DEBUG 1")
|
|
||||||
elseif key=="f10"then
|
|
||||||
devMode=2 MES.new('info',"DEBUG 2")
|
|
||||||
elseif key=="f11"then
|
|
||||||
devMode=3 MES.new('info',"DEBUG 3")
|
|
||||||
elseif key=="f12"then
|
|
||||||
devMode=4 MES.new('info',"DEBUG 4")
|
|
||||||
elseif devMode==2 then
|
elseif devMode==2 then
|
||||||
local W=WIDGET.sel
|
local W=WIDGET.sel
|
||||||
if W then
|
if W then
|
||||||
if key=="left"then W.x=W.x-10
|
if key=='left'then W.x=W.x-10
|
||||||
elseif key=="right"then W.x=W.x+10
|
elseif key=='right'then W.x=W.x+10
|
||||||
elseif key=="up"then W.y=W.y-10
|
elseif key=='up'then W.y=W.y-10
|
||||||
elseif key=="down"then W.y=W.y+10
|
elseif key=='down'then W.y=W.y+10
|
||||||
elseif key==","then W.w=W.w-10
|
elseif key==','then W.w=W.w-10
|
||||||
elseif key=="."then W.w=W.w+10
|
elseif key=='.'then W.w=W.w+10
|
||||||
elseif key=="/"then W.h=W.h-10
|
elseif key=='/'then W.h=W.h-10
|
||||||
elseif key=="'"then W.h=W.h+10
|
elseif key=='\''then W.h=W.h+10
|
||||||
elseif key=="["then W.font=W.font-5
|
elseif key=='['then W.font=W.font-5
|
||||||
elseif key=="]"then W.font=W.font+5
|
elseif key==']'then W.font=W.font+5
|
||||||
else return true
|
else return true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -283,24 +314,34 @@ function love.keypressed(key,_,isRep)
|
|||||||
mouseShow=false
|
mouseShow=false
|
||||||
if devMode and not noDevkeyPressed(key)then
|
if devMode and not noDevkeyPressed(key)then
|
||||||
return
|
return
|
||||||
elseif key=="f8"then
|
elseif key=='f8'then
|
||||||
devMode=1
|
devMode=1
|
||||||
MES.new('info',"DEBUG ON",.2)
|
MES.new('info',"DEBUG ON",.2)
|
||||||
elseif key=="f11"then
|
elseif key=='f11'then
|
||||||
if kb.isDown("lctrl","rctrl")then
|
SETTING.fullscreen=not SETTING.fullscreen
|
||||||
_G['\100\114\97\119\70\87\77']=NULL
|
applySettings()
|
||||||
else
|
saveSettings()
|
||||||
switchFullscreen()
|
|
||||||
end
|
|
||||||
elseif not SCN.swapping then
|
elseif not SCN.swapping then
|
||||||
if SCN.keyDown then
|
if EDITING==""and(not SCN.keyDown or SCN.keyDown(key,isRep))then
|
||||||
if EDITING==""then
|
local W=WIDGET.sel
|
||||||
SCN.keyDown(key,isRep)
|
if key=='escape'and not isRep then
|
||||||
end
|
|
||||||
elseif key=="escape"and not isRep then
|
|
||||||
SCN.back()
|
SCN.back()
|
||||||
|
elseif key=='up'or key=='down'or key=='left'or key=='right'then
|
||||||
|
mouseShow=true
|
||||||
|
if KBisDown('lctrl','rctrl')then
|
||||||
|
if W and W.arrowKey then W:arrowKey(key)end
|
||||||
|
end
|
||||||
|
elseif key=='space'or key=='return'then
|
||||||
|
mouseShow=true
|
||||||
|
if not isRep then
|
||||||
|
if showClickFX then SYSFX.newTap(3,mx,my)end
|
||||||
|
_triggerMouseDown(mx,my,1)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
WIDGET.keyPressed(key,isRep)
|
if W and W.keypress then
|
||||||
|
W:keypress(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -316,18 +357,18 @@ function love.textinput(texts)
|
|||||||
WIDGET.textinput(texts)
|
WIDGET.textinput(texts)
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.joystickadded(JS)
|
--analog sticks: -1, 0, 1 for neg, neutral, pos
|
||||||
ins(joysticks,JS)
|
--triggers: 0 for released, 1 for pressed
|
||||||
MES.new('info',"Joystick added")
|
local jsAxisEventName={
|
||||||
end
|
leftx={'leftstick_left','leftstick_right'},
|
||||||
function love.joystickremoved(JS)
|
lefty={'leftstick_up','leftstick_down'},
|
||||||
local i=TABLE.find(joysticks,JS)
|
rightx={'rightstick_left','rightstick_right'},
|
||||||
if i then
|
righty={'rightstick_up','rightstick_down'},
|
||||||
rem(joysticks,i)
|
triggerleft='triggerleft',
|
||||||
MES.new('info',"Joystick removed")
|
triggerright='triggerright'
|
||||||
end
|
}
|
||||||
end
|
local gamePadKeys={'a','b','x','y','back','guide','start','leftstick','rightstick','leftshoulder','rightshoulder','dpup','dpdown','dpleft','dpright'}
|
||||||
local keyMirror={
|
local dPadToKey={
|
||||||
dpup='up',
|
dpup='up',
|
||||||
dpdown='down',
|
dpdown='down',
|
||||||
dpleft='left',
|
dpleft='left',
|
||||||
@@ -335,72 +376,135 @@ local keyMirror={
|
|||||||
start='return',
|
start='return',
|
||||||
back='escape',
|
back='escape',
|
||||||
}
|
}
|
||||||
function love.gamepadpressed(_,i)
|
function love.joystickadded(JS)
|
||||||
|
table.insert(jsState,{
|
||||||
|
_id=JS:getID(),
|
||||||
|
_jsObj=JS,
|
||||||
|
leftx=0,lefty=0,
|
||||||
|
rightx=0,righty=0,
|
||||||
|
triggerleft=0,triggerright=0
|
||||||
|
})
|
||||||
|
MES.new('info',"Joystick added")
|
||||||
|
end
|
||||||
|
function love.joystickremoved(JS)
|
||||||
|
for i=1,#jsState do
|
||||||
|
if jsState[i]._jsObj==JS then
|
||||||
|
for j=1,#gamePadKeys do
|
||||||
|
if JS:isGamepadDown(gamePadKeys[j])then
|
||||||
|
love.gamepadreleased(JS,gamePadKeys[j])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
love.gamepadaxis(JS,'leftx',0)
|
||||||
|
love.gamepadaxis(JS,'lefty',0)
|
||||||
|
love.gamepadaxis(JS,'rightx',0)
|
||||||
|
love.gamepadaxis(JS,'righty',0)
|
||||||
|
love.gamepadaxis(JS,'triggerleft',-1)
|
||||||
|
love.gamepadaxis(JS,'triggerright',-1)
|
||||||
|
MES.new('info',"Joystick removed")
|
||||||
|
table.remove(jsState,i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function love.gamepadaxis(JS,axis,val)
|
||||||
|
if jsState[1]and JS==jsState[1]._jsObj then
|
||||||
|
local js=jsState[1]
|
||||||
|
if axis=='leftx'or axis=='lefty'or axis=='rightx'or axis=='righty'then
|
||||||
|
local newVal=--range: [0,1]
|
||||||
|
val>.4 and 1 or
|
||||||
|
val<-.4 and -1 or
|
||||||
|
0
|
||||||
|
if newVal~=js[axis]then
|
||||||
|
if js[axis]==-1 then
|
||||||
|
love.gamepadreleased(JS,jsAxisEventName[axis][1])
|
||||||
|
elseif js[axis]~=0 then
|
||||||
|
love.gamepadreleased(JS,jsAxisEventName[axis][2])
|
||||||
|
end
|
||||||
|
if newVal==-1 then
|
||||||
|
love.gamepadpressed(JS,jsAxisEventName[axis][1])
|
||||||
|
elseif newVal==1 then
|
||||||
|
love.gamepadpressed(JS,jsAxisEventName[axis][2])
|
||||||
|
end
|
||||||
|
js[axis]=newVal
|
||||||
|
end
|
||||||
|
elseif axis=='triggerleft'or axis=='triggerright'then
|
||||||
|
local newVal=val>.3 and 1 or 0--range: [0,1]
|
||||||
|
if newVal~=js[axis]then
|
||||||
|
if newVal==1 then
|
||||||
|
love.gamepadpressed(JS,jsAxisEventName[axis])
|
||||||
|
else
|
||||||
|
love.gamepadreleased(JS,jsAxisEventName[axis])
|
||||||
|
end
|
||||||
|
js[axis]=newVal
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function love.gamepadpressed(_,key)
|
||||||
mouseShow=false
|
mouseShow=false
|
||||||
if SCN.swapping then return end
|
if not SCN.swapping then
|
||||||
if SCN.gamepadDown then SCN.gamepadDown(i)
|
local cursorCtrl
|
||||||
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
|
if SCN.gamepadDown then
|
||||||
elseif i=="back"then SCN.back()
|
cursorCtrl=SCN.gamepadDown(key)
|
||||||
else WIDGET.gamepadPressed(keyMirror[i]or i)
|
elseif SCN.keyDown then
|
||||||
|
cursorCtrl=SCN.keyDown(dPadToKey[key]or key)
|
||||||
|
else
|
||||||
|
cursorCtrl=true
|
||||||
|
end
|
||||||
|
if cursorCtrl then
|
||||||
|
key=dPadToKey[key]or key
|
||||||
|
mouseShow=true
|
||||||
|
local W=WIDGET.sel
|
||||||
|
if key=='back'then
|
||||||
|
SCN.back()
|
||||||
|
elseif key=='up'or key=='down'or key=='left'or key=='right'then
|
||||||
|
mouseShow=true
|
||||||
|
if W and W.arrowKey then W:arrowKey(key)end
|
||||||
|
elseif key=='return'then
|
||||||
|
mouseShow=true
|
||||||
|
if showClickFX then SYSFX.newTap(3,mx,my)end
|
||||||
|
_triggerMouseDown(mx,my,1)
|
||||||
|
else
|
||||||
|
if W and W.keypress then
|
||||||
|
W:keypress(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function love.gamepadreleased(_,i)
|
function love.gamepadreleased(_,i)
|
||||||
if SCN.swapping then return end
|
if SCN.swapping then return end
|
||||||
if SCN.gamepadUp then SCN.gamepadUp(i)end
|
if SCN.gamepadUp then SCN.gamepadUp(i)end
|
||||||
end
|
end
|
||||||
--[[
|
|
||||||
function love.joystickpressed(JS,k)
|
|
||||||
mouseShow=false
|
|
||||||
if SCN.swapping then return end
|
|
||||||
if SCN.gamepadDown then SCN.gamepadDown(i)
|
|
||||||
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
|
|
||||||
elseif i=="back"then SCN.back()
|
|
||||||
else WIDGET.gamepadPressed(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function love.joystickreleased(JS,k)
|
|
||||||
if SCN.swapping then return end
|
|
||||||
if SCN.gamepadUp then SCN.gamepadUp(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function love.joystickaxis(JS,axis,val)
|
|
||||||
|
|
||||||
end
|
|
||||||
function love.joystickhat(JS,hat,dir)
|
|
||||||
|
|
||||||
end
|
|
||||||
function love.sendData(data)end
|
|
||||||
function love.receiveData(id,data)end
|
|
||||||
]]
|
|
||||||
function love.filedropped(file)
|
function love.filedropped(file)
|
||||||
if SCN.fileDropped then SCN.fileDropped(file)end
|
if SCN.fileDropped then SCN.fileDropped(file)end
|
||||||
end
|
end
|
||||||
function love.directorydropped(dir)
|
function love.directorydropped(dir)
|
||||||
if SCN.directoryDropped then SCN.directoryDropped(dir)end
|
if SCN.directoryDropped then SCN.directoryDropped(dir)end
|
||||||
end
|
end
|
||||||
local lastGCtime=0
|
local autoGCcount=0
|
||||||
function love.lowmemory()
|
function love.lowmemory()
|
||||||
if TIME()-lastGCtime>6.26 then
|
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
lastGCtime=TIME()
|
if autoGCcount<3 then
|
||||||
|
autoGCcount=autoGCcount+1
|
||||||
MES.new('check',"[auto GC] low MEM 设备内存过低")
|
MES.new('check',"[auto GC] low MEM 设备内存过低")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local onResize=NULL
|
||||||
function love.resize(w,h)
|
function love.resize(w,h)
|
||||||
|
if SCR.w==w and SCR.h==h then return end
|
||||||
SCR.resize(w,h)
|
SCR.resize(w,h)
|
||||||
if BG.resize then BG.resize(w,h)end
|
if BG.resize then BG.resize(w,h)end
|
||||||
if SCN.resize then SCN.resize(w,h)end
|
if SCN.resize then SCN.resize(w,h)end
|
||||||
WIDGET.resize(w,h)
|
WIDGET.resize(w,h)
|
||||||
|
FONT.reset()
|
||||||
|
onResize(w,h)
|
||||||
|
end
|
||||||
|
|
||||||
SHADER.warning:send('w',w*SCR.dpi)
|
local onFocus=NULL
|
||||||
end
|
function love.focus(f)onFocus(f)end
|
||||||
function love.focus(f)
|
|
||||||
if f then
|
|
||||||
love.timer.step()
|
|
||||||
elseif SCN.cur=='game'and SETTING.autoPause then
|
|
||||||
pauseGame()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local yield=coroutine.yield
|
local yield=coroutine.yield
|
||||||
local function secondLoopThread()
|
local function secondLoopThread()
|
||||||
@@ -408,7 +512,11 @@ local function secondLoopThread()
|
|||||||
repeat yield()until mainLoop()
|
repeat yield()until mainLoop()
|
||||||
end
|
end
|
||||||
function love.errorhandler(msg)
|
function love.errorhandler(msg)
|
||||||
if not msg then msg="Unknown error" end
|
if type(msg)~='string'then
|
||||||
|
msg="Unknown error"
|
||||||
|
elseif msg:find("Invalid UTF-8")and text then
|
||||||
|
msg=text.tryAnotherBuild
|
||||||
|
end
|
||||||
|
|
||||||
--Generate error message
|
--Generate error message
|
||||||
local err={"Error:"..msg}
|
local err={"Error:"..msg}
|
||||||
@@ -430,20 +538,20 @@ function love.errorhandler(msg)
|
|||||||
love.audio.stop()
|
love.audio.stop()
|
||||||
gc.reset()
|
gc.reset()
|
||||||
|
|
||||||
if LOADED and #ERRDATA<3 then
|
if LOADED and #errData<3 then
|
||||||
BG.set('none')
|
BG.set('none')
|
||||||
local scn=SCN and SCN.cur or"NULL"
|
local scn=SCN and SCN.cur or"NULL"
|
||||||
ins(ERRDATA,{mes=err,scene=scn})
|
table.insert(errData,{mes=err,scene=scn})
|
||||||
|
|
||||||
--Write messages to log file
|
--Write messages to log file
|
||||||
love.filesystem.append('conf/error.log',
|
love.filesystem.append('conf/error.log',
|
||||||
os.date("%Y/%m/%d %A %H:%M:%S\n")..
|
os.date("%Y/%m/%d %A %H:%M:%S\n")..
|
||||||
#ERRDATA.." crash(es) "..SYSTEM.."-"..VERSION.string.." scene: "..scn.."\n"..
|
#errData.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
|
||||||
table.concat(err,"\n",1,c-2).."\n\n"
|
table.concat(err,"\n",1,c-2).."\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
--Get screencapture
|
--Get screencapture
|
||||||
gc.captureScreenshot(function(_)ERRDATA[#ERRDATA].shot=gc.newImage(_)end)
|
gc.captureScreenshot(function(_)errData[#errData].shot=gc.newImage(_)end)
|
||||||
gc.present()
|
gc.present()
|
||||||
|
|
||||||
--Create a new mainLoop thread to keep game alive
|
--Create a new mainLoop thread to keep game alive
|
||||||
@@ -468,7 +576,6 @@ function love.errorhandler(msg)
|
|||||||
love.event.pump()
|
love.event.pump()
|
||||||
for E,a,b in love.event.poll()do
|
for E,a,b in love.event.poll()do
|
||||||
if E=='quit'or a=='escape'then
|
if E=='quit'or a=='escape'then
|
||||||
destroyPlayers()
|
|
||||||
return true
|
return true
|
||||||
elseif E=='resize'then
|
elseif E=='resize'then
|
||||||
SCR.resize(a,b)
|
SCR.resize(a,b)
|
||||||
@@ -477,10 +584,10 @@ function love.errorhandler(msg)
|
|||||||
gc_clear(.3,.5,.9)
|
gc_clear(.3,.5,.9)
|
||||||
gc_push('transform')
|
gc_push('transform')
|
||||||
gc_replaceTransform(SCR.xOy)
|
gc_replaceTransform(SCR.xOy)
|
||||||
setFont(100)gc_print(":(",100,0,0,1.2)
|
FONT.set(100)gc_print(":(",100,0,0,1.2)
|
||||||
setFont(40)gc.printf(errorMsg,100,160,SCR.w0-100)
|
FONT.set(40)gc.printf(errorMsg,100,160,SCR.w0-100)
|
||||||
setFont(20)
|
FONT.set(20)
|
||||||
gc_print(SYSTEM.."-"..VERSION.string.." scene:"..(SCN and SCN.cur or"NULL"),100,660)
|
gc_print(love.system.getOS().."-"..VERSION.string.." scene:"..(SCN and SCN.cur or"NULL"),100,660)
|
||||||
gc.printf(err[1],100,360,1260-100)
|
gc.printf(err[1],100,360,1260-100)
|
||||||
gc_print("TRACEBACK",100,450)
|
gc_print("TRACEBACK",100,450)
|
||||||
for i=4,#err-2 do
|
for i=4,#err-2 do
|
||||||
@@ -504,42 +611,34 @@ local devColor={
|
|||||||
}
|
}
|
||||||
local WS=WS
|
local WS=WS
|
||||||
local WSnames={'app','user','play','stream','chat','manage'}
|
local WSnames={'app','user','play','stream','chat','manage'}
|
||||||
local wsBottomImage do
|
local wsImg={}do
|
||||||
local L={78,18,
|
local L={78,18,
|
||||||
{'clear',1,1,1,0},
|
{'clear',1,1,1,0},
|
||||||
{'setCL',1,1,1,.3},
|
{'setCL',1,1,1,.3},
|
||||||
{'fRect',60,0,18,18},
|
{'fRect',60,0,18,18},
|
||||||
}
|
}
|
||||||
for i=0,59 do
|
for i=0,59 do
|
||||||
ins(L,{'setCL',1,1,1,i*.005})
|
table.insert(L,{'setCL',1,1,1,i*.005})
|
||||||
ins(L,{'fRect',i,0,1,18})
|
table.insert(L,{'fRect',i,0,1,18})
|
||||||
end
|
end
|
||||||
wsBottomImage=GC.DO(L)
|
wsImg.bottom=GC.DO(L)
|
||||||
end
|
wsImg.dead=GC.DO{20,20,
|
||||||
local ws_deadImg=GC.DO{20,20,
|
{'rawFT',20},
|
||||||
{'setFT',20},
|
|
||||||
{'setCL',1,.3,.3},
|
{'setCL',1,.3,.3},
|
||||||
{'print',"X",3,-4},
|
{'mText',"X",11,-1},
|
||||||
}
|
}
|
||||||
local ws_connectingImg=GC.DO{20,20,
|
wsImg.connecting=GC.DO{20,20,
|
||||||
|
{'rawFT',20},
|
||||||
{'setLW',3},
|
{'setLW',3},
|
||||||
{'dArc',11.5,10,6.26,1,5.28},
|
{'mText',"C",11,-1},
|
||||||
}
|
}
|
||||||
local ws_runningImg=GC.DO{20,20,
|
wsImg.running=GC.DO{20,20,
|
||||||
{'setFT',20},
|
{'rawFT',20},
|
||||||
{'setCL',.5,1,0},
|
{'setCL',.5,1,0},
|
||||||
{'print',"R",3,-4},
|
{'mText',"R",11,-1},
|
||||||
}
|
|
||||||
local cursorImg=GC.DO{16,16,
|
|
||||||
{'fCirc',8,8,4},
|
|
||||||
{'setCL',1,1,1,.7},
|
|
||||||
{'fCirc',8,8,6},
|
|
||||||
}
|
|
||||||
local cursor_holdImg=GC.DO{16,16,
|
|
||||||
{'setLW',2},
|
|
||||||
{'dCirc',8,8,7},
|
|
||||||
{'fCirc',8,8,3},
|
|
||||||
}
|
}
|
||||||
|
end
|
||||||
|
|
||||||
function love.run()
|
function love.run()
|
||||||
local love=love
|
local love=love
|
||||||
|
|
||||||
@@ -550,15 +649,14 @@ function love.run()
|
|||||||
local TASK_update=TASK.update
|
local TASK_update=TASK.update
|
||||||
local SYSFX_update,SYSFX_draw=SYSFX.update,SYSFX.draw
|
local SYSFX_update,SYSFX_draw=SYSFX.update,SYSFX.draw
|
||||||
local WIDGET_update,WIDGET_draw=WIDGET.update,WIDGET.draw
|
local WIDGET_update,WIDGET_draw=WIDGET.update,WIDGET.draw
|
||||||
|
|
||||||
local STEP,WAIT=love.timer.step,love.timer.sleep
|
local STEP,WAIT=love.timer.step,love.timer.sleep
|
||||||
local FPS,MINI=love.timer.getFPS,love.window.isMinimized
|
local FPS,MINI=love.timer.getFPS,love.window.isMinimized
|
||||||
local PUMP,POLL=love.event.pump,love.event.poll
|
local PUMP,POLL=love.event.pump,love.event.poll
|
||||||
|
|
||||||
local TIME,SETTING,VERSION=TIME,SETTING,VERSION
|
local timer,VERSION=love.timer.getTime,VERSION
|
||||||
|
|
||||||
local frameTimeList={}
|
local frameTimeList={}
|
||||||
local lastFrame=TIME()
|
local lastFrame=timer()
|
||||||
local lastFreshPow=lastFrame
|
local lastFreshPow=lastFrame
|
||||||
local FCT=0--Framedraw counter, from 0~99
|
local FCT=0--Framedraw counter, from 0~99
|
||||||
|
|
||||||
@@ -567,12 +665,12 @@ function love.run()
|
|||||||
--Scene Launch
|
--Scene Launch
|
||||||
while #SCN.stack>0 do SCN.pop()end
|
while #SCN.stack>0 do SCN.pop()end
|
||||||
SCN.push('quit','slowFade')
|
SCN.push('quit','slowFade')
|
||||||
SCN.init(#ERRDATA==0 and'load'or'error')
|
SCN.init(#errData==0 and'load'or'error')
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
local _
|
local _
|
||||||
|
|
||||||
local time=TIME()
|
local time=timer()
|
||||||
local dt=time-lastFrame
|
local dt=time-lastFrame
|
||||||
lastFrame=time
|
lastFrame=time
|
||||||
|
|
||||||
@@ -582,31 +680,32 @@ function love.run()
|
|||||||
if love[N]then
|
if love[N]then
|
||||||
love[N](a,b,c,d,e)
|
love[N](a,b,c,d,e)
|
||||||
elseif N=='quit'then
|
elseif N=='quit'then
|
||||||
destroyPlayers()
|
onQuit()
|
||||||
return a or true
|
return a or true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--UPDATE
|
--UPDATE
|
||||||
STEP()
|
STEP()
|
||||||
|
if mouseShow then mouse_update(dt)end
|
||||||
|
if next(jsState)then gp_update(jsState[1],dt)end
|
||||||
VOC.update()
|
VOC.update()
|
||||||
BG.update(dt)
|
BG.update(dt)
|
||||||
TEXT_update()
|
TEXT_update(dt)
|
||||||
MES_update(dt)
|
MES_update(dt)
|
||||||
WS_update(dt)
|
WS_update(dt)
|
||||||
TASK_update()
|
TASK_update(dt)
|
||||||
SYSFX_update(dt)
|
SYSFX_update(dt)
|
||||||
if SCN.update then SCN.update(dt)end
|
if SCN.update then SCN.update(dt)end
|
||||||
if SCN.swapping then SCN.swapUpdate()end
|
if SCN.swapping then SCN.swapUpdate(dt)end
|
||||||
WIDGET_update()
|
WIDGET_update(dt)
|
||||||
|
|
||||||
--DRAW
|
--DRAW
|
||||||
if not MINI()then
|
if not MINI()then
|
||||||
FCT=FCT+SETTING.frameMul
|
FCT=FCT+frameMul
|
||||||
if FCT>=100 then
|
if FCT>=100 then
|
||||||
FCT=FCT-100
|
FCT=FCT-100
|
||||||
|
|
||||||
local safeX=SCR.safeX
|
|
||||||
gc_replaceTransform(SCR.origin)
|
gc_replaceTransform(SCR.origin)
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
BG.draw()
|
BG.draw()
|
||||||
@@ -617,22 +716,14 @@ function love.run()
|
|||||||
TEXT_draw()
|
TEXT_draw()
|
||||||
|
|
||||||
--Draw cursor
|
--Draw cursor
|
||||||
if mouseShow then
|
if mouseShow then drawCursor(time,mx,my)end
|
||||||
local R=int((time+1)/2)%7+1
|
|
||||||
_=minoColor[SETTING.skin[R]]
|
|
||||||
gc_setColor(_[1],_[2],_[3],min(abs(1-time%2),.3))
|
|
||||||
_=DSCP[R][0]
|
|
||||||
gc_draw(TEXTURE.miniBlock[R],mx,my,time%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
|
|
||||||
gc_setColor(1,1,1)
|
|
||||||
gc_draw(ms.isDown(1)and cursor_holdImg or cursorImg,mx,my,nil,nil,nil,8,8)
|
|
||||||
end
|
|
||||||
gc_replaceTransform(SCR.xOy_ul)
|
|
||||||
MES_draw()
|
|
||||||
gc_replaceTransform(SCR.origin)
|
gc_replaceTransform(SCR.origin)
|
||||||
|
MES_draw()
|
||||||
|
|
||||||
--Draw power info.
|
--Draw power info.
|
||||||
if SETTING.powerInfo then
|
if showPowerInfo then
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
gc_draw(infoCanvas,safeX,0,0,SCR.k)
|
gc_draw(infoCanvas,SCR.safeX,0,0,SCR.k)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Draw scene swapping animation
|
--Draw scene swapping animation
|
||||||
@@ -643,12 +734,14 @@ function love.run()
|
|||||||
end
|
end
|
||||||
gc_replaceTransform(SCR.xOy_d)
|
gc_replaceTransform(SCR.xOy_d)
|
||||||
--Draw Version string
|
--Draw Version string
|
||||||
gc_setColor(.8,.8,.8,.4)
|
gc_setColor(.9,.9,.9,.42)
|
||||||
setFont(20)
|
FONT.set(20)
|
||||||
mStr(VERSION.string,0,-30)
|
mStr(VERSION.string,0,-30)
|
||||||
gc_replaceTransform(SCR.xOy_dl)
|
gc_replaceTransform(SCR.xOy_dl)
|
||||||
|
local safeX=SCR.safeX/SCR.k
|
||||||
|
|
||||||
--Draw FPS
|
--Draw FPS
|
||||||
setFont(15)
|
FONT.set(15)
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
gc_print(FPS(),safeX+5,-20)
|
gc_print(FPS(),safeX+5,-20)
|
||||||
|
|
||||||
@@ -657,13 +750,11 @@ function love.run()
|
|||||||
--Left-down infos
|
--Left-down infos
|
||||||
gc_setColor(devColor[devMode])
|
gc_setColor(devColor[devMode])
|
||||||
gc_print("MEM "..gcinfo(),safeX+5,-40)
|
gc_print("MEM "..gcinfo(),safeX+5,-40)
|
||||||
gc_print("Lines "..FREEROW.getCount(),safeX+5,-60)
|
gc_print("Tasks "..TASK.getCount(),safeX+5,-60)
|
||||||
gc_print("Tasks "..TASK.getCount(),safeX+5,-80)
|
gc_print("Voices "..VOC.getQueueCount(),safeX+5,-80)
|
||||||
gc_print("Voices "..VOC.getQueueCount(),safeX+5,-100)
|
|
||||||
gc_print(tostring(GAME.playing),safeX+5,-120)
|
|
||||||
|
|
||||||
--Update & draw frame time
|
--Update & draw frame time
|
||||||
ins(frameTimeList,1,dt)rem(frameTimeList,126)
|
table.insert(frameTimeList,1,dt)table.remove(frameTimeList,126)
|
||||||
gc_setColor(1,1,1,.3)
|
gc_setColor(1,1,1,.3)
|
||||||
for i=1,#frameTimeList do
|
for i=1,#frameTimeList do
|
||||||
gc.rectangle('fill',150+2*i,-20,2,-frameTimeList[i]*4000)
|
gc.rectangle('fill',150+2*i,-20,2,-frameTimeList[i]*4000)
|
||||||
@@ -675,7 +766,7 @@ function love.run()
|
|||||||
gc_setLineWidth(1)
|
gc_setLineWidth(1)
|
||||||
gc_line(x,0,x,SCR.h)
|
gc_line(x,0,x,SCR.h)
|
||||||
gc_line(0,y,SCR.w,y)
|
gc_line(0,y,SCR.w,y)
|
||||||
local t=int(mx+.5)..","..int(my+.5)
|
local t=math.floor(mx+.5)..","..math.floor(my+.5)
|
||||||
gc.setColor(COLOR.D)
|
gc.setColor(COLOR.D)
|
||||||
gc_print(t,x+1,y)
|
gc_print(t,x+1,y)
|
||||||
gc_print(t,x+1,y-1)
|
gc_print(t,x+1,y-1)
|
||||||
@@ -688,14 +779,14 @@ function love.run()
|
|||||||
for i=1,6 do
|
for i=1,6 do
|
||||||
local status=WS.status(WSnames[i])
|
local status=WS.status(WSnames[i])
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
gc.draw(wsBottomImage,-79,20*i-139)
|
gc.draw(wsImg.bottom,-79,20*i-139)
|
||||||
if status=='dead'then
|
if status=='dead'then
|
||||||
gc_draw(ws_deadImg,-20,20*i-140)
|
gc_draw(wsImg.dead,-20,20*i-140)
|
||||||
elseif status=='connecting'then
|
elseif status=='connecting'then
|
||||||
gc_setColor(1,1,1,.5+.3*sin(time*6.26))
|
gc_setColor(1,1,1,.5+.3*math.sin(time*6.26))
|
||||||
gc_draw(ws_connectingImg,-20,20*i-140)
|
gc_draw(wsImg.connecting,-20,20*i-140)
|
||||||
elseif status=='running'then
|
elseif status=='running'then
|
||||||
gc_draw(ws_runningImg,-20,20*i-140)
|
gc_draw(wsImg.running,-20,20*i-140)
|
||||||
end
|
end
|
||||||
local t1,t2,t3=WS.getTimers(WSnames[i])
|
local t1,t2,t3=WS.getTimers(WSnames[i])
|
||||||
gc_setColor(.9,.9,.9,t1)gc.rectangle('fill',-60,20*i-122,-16,-16)
|
gc_setColor(.9,.9,.9,t1)gc.rectangle('fill',-60,20*i-122,-16,-16)
|
||||||
@@ -706,13 +797,13 @@ function love.run()
|
|||||||
gc_present()
|
gc_present()
|
||||||
|
|
||||||
--SPEED UPUPUP!
|
--SPEED UPUPUP!
|
||||||
if SETTING.cleanCanvas then gc_discard()end
|
if discardCanvas then gc_discard()end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Fresh power info.
|
--Fresh power info.
|
||||||
if time-lastFreshPow>2.6 then
|
if time-lastFreshPow>2.6 then
|
||||||
if SETTING.powerInfo and LOADED then
|
if showPowerInfo then
|
||||||
updatePowerInfo()
|
updatePowerInfo()
|
||||||
lastFreshPow=time
|
lastFreshPow=time
|
||||||
end
|
end
|
||||||
@@ -730,9 +821,44 @@ function love.run()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Keep 60fps
|
_=timer()-lastFrame
|
||||||
_=TIME()-lastFrame
|
if _<sleepInterval*.9626 then WAIT(sleepInterval*.9626-_)end
|
||||||
if _<.016 then WAIT(.016-_)end
|
while timer()-lastFrame<sleepInterval do end
|
||||||
while TIME()-lastFrame<1/60-5e-6 do WAIT(0)end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local Z={}
|
||||||
|
|
||||||
|
function Z.getJsState()return jsState end
|
||||||
|
function Z.getErr(i)
|
||||||
|
if i=='#'then
|
||||||
|
return errData[#errData]
|
||||||
|
elseif i then
|
||||||
|
return errData[i]
|
||||||
|
else
|
||||||
|
return errData
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Z.setPowerInfo(bool)showPowerInfo=bool end
|
||||||
|
function Z.setCleanCanvas(bool)discardCanvas=bool end
|
||||||
|
function Z.setFrameMul(n)frameMul=n end
|
||||||
|
function Z.setMaxFPS(fps)sleepInterval=1/fps end
|
||||||
|
function Z.setClickFX(bool)showClickFX=bool end
|
||||||
|
|
||||||
|
--[Warning] Color and line width is uncertain value, set it in the function.
|
||||||
|
function Z.setCursor(func)drawCursor=func end
|
||||||
|
|
||||||
|
--Change F1~F7 events of devmode (F8 mode)
|
||||||
|
function Z.setOnFnKeys(list)
|
||||||
|
assert(type(list)=='table',"Z.setOnFnKeys(list): list must be a table.")
|
||||||
|
for i=1,7 do fnKey[i]=type(list[i])=='function'and list[i]or NULL end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Z.setOnFocus(func)onFocus=assert(type(func)=='function'and func,"Z.setOnFocus(func): func must be a function")end
|
||||||
|
|
||||||
|
function Z.setOnResize(func)onResize=assert(type(func)=='function'and func,"Z.setOnResize(func): func must be a function")end
|
||||||
|
|
||||||
|
function Z.setOnQuit(func)onQuit=assert(type(func)=='function'and func,"Z.setOnQuit(func): func must be a function")end
|
||||||
|
|
||||||
|
return Z
|
||||||
|
|||||||
@@ -1,56 +1,57 @@
|
|||||||
local LANG={}
|
local LANG={}
|
||||||
function LANG.init(langList,publicText)--Attention, calling this will destory all initializing methods, create a LANG.set()!
|
--ONLY FIRST CALL MAKE SENSE
|
||||||
local function langFallback(T0,T)
|
--Create LANG.get() and LANG.addScene()
|
||||||
|
function LANG.init(defaultLang,langList,publicText,pretreatFunc)
|
||||||
|
local function _langFallback(T0,T)
|
||||||
for k,v in next,T0 do
|
for k,v in next,T0 do
|
||||||
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
|
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
|
||||||
if not T[k]then T[k]={}end
|
if not T[k]then T[k]={}end
|
||||||
if type(T[k])=='table'then langFallback(v,T[k])end
|
if type(T[k])=='table'then
|
||||||
|
_langFallback(v,T[k])
|
||||||
|
end
|
||||||
elseif not T[k]then
|
elseif not T[k]then
|
||||||
T[k]=v
|
T[k]=v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local tipMeta={__call=function(L)return L[math.random(#L)]end}
|
|
||||||
|
|
||||||
for i=1,#langList do
|
|
||||||
local L=langList[i]
|
|
||||||
|
|
||||||
--Set public text
|
--Set public text
|
||||||
for key,list in next,publicText do
|
if publicText then
|
||||||
L[key]=list
|
for _,L in next,langList do
|
||||||
end
|
for key,list in next,publicText do L[key]=list end
|
||||||
|
|
||||||
--Fallback to other language, default zh
|
|
||||||
if i>1 then
|
|
||||||
langFallback(langList[L.fallback or 1],L)
|
|
||||||
end
|
|
||||||
|
|
||||||
--Metatable:__call for table:getTip
|
|
||||||
if type(rawget(L,'getTip'))=='table'then
|
|
||||||
setmetatable(L.getTip,tipMeta)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
LANG.init,LANG.setLangList,LANG.setPublicText=nil
|
--Fallback to default language
|
||||||
|
for name,L in next,langList do
|
||||||
|
if name~=defaultLang then
|
||||||
|
_langFallback(langList[L.fallback or defaultLang],L)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function LANG.set(l)
|
--Custom pretreatment for each language
|
||||||
if text~=langList[l]then
|
if pretreatFunc then
|
||||||
text=langList[l]
|
for _,L in next,langList do
|
||||||
WIDGET.setLang(text.WidgetText)
|
pretreatFunc(L)
|
||||||
for k,v in next,drawableText do
|
|
||||||
if text[k]then
|
|
||||||
v:set(text[k])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function LANG.get(l)
|
||||||
|
if not langList[l]then
|
||||||
|
LOG("Wrong language: "..tostring(l))
|
||||||
|
l=defaultLang
|
||||||
end
|
end
|
||||||
|
return langList[l]
|
||||||
end
|
end
|
||||||
|
|
||||||
function LANG.addScene(name)
|
function LANG.addScene(name)
|
||||||
for i=1,#langList do
|
for _,L in next,langList do
|
||||||
if langList[i].WidgetText and not langList[i].WidgetText[name]then
|
if L.WidgetText and not L.WidgetText[name]then
|
||||||
langList[i].WidgetText[name]={back=langList[i].back}
|
L.WidgetText[name]={}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function LANG.init()end
|
||||||
end
|
end
|
||||||
return LANG
|
return LANG
|
||||||
@@ -62,7 +62,7 @@ function LIGHT.draw()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function LIGHT.clear()
|
function LIGHT.clear()
|
||||||
for i=#Lights,1,-1 do
|
for i=1,#Lights do
|
||||||
Lights[i].blackCanvas:release()
|
Lights[i].blackCanvas:release()
|
||||||
Lights[i].shadowCanvas:release()
|
Lights[i].shadowCanvas:release()
|
||||||
Lights[i].renderCanvas:release()
|
Lights[i].renderCanvas:release()
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
return function(name,libName)
|
|
||||||
if SYSTEM=='Windows'or SYSTEM=='Linux'then
|
|
||||||
local r1,r2,r3=pcall(require,libName[SYSTEM])
|
|
||||||
if r1 and r2 then
|
|
||||||
return r2
|
|
||||||
else
|
|
||||||
MES.new('error',"Cannot load "..name..": "..(r2 or r3))
|
|
||||||
end
|
|
||||||
elseif SYSTEM=='Android'then
|
|
||||||
local fs=love.filesystem
|
|
||||||
local platform={'arm64-v8a','armeabi-v7a'}
|
|
||||||
|
|
||||||
for i=1,#platform do
|
|
||||||
local soFile,_,_,mes1=fs.read('data','libAndroid/'..platform[i]..'/'..libName.Android)
|
|
||||||
if soFile then
|
|
||||||
local success,mes2=fs.write('lib/'..libName.Android,soFile)
|
|
||||||
if success then
|
|
||||||
libFunc,mes2=package.loadlib(SAVEDIR..'/lib/'..libName.Android,libName.libFunc)
|
|
||||||
if libFunc then
|
|
||||||
MES.new('check',name.." lib loaded")
|
|
||||||
break
|
|
||||||
else
|
|
||||||
MES.new('error',"Cannot load "..name..": "..mes2)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
MES.new('error',("Write %s-%s to saving failed: %s"):format(name,platform[i],mes2))
|
|
||||||
end
|
|
||||||
else
|
|
||||||
MES.new('error',("Read %s-%s to saving failed: %s"):format(name,platform[i],mes1))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not libFunc then
|
|
||||||
MES.new('error',"Cannot load "..name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return libFunc()
|
|
||||||
elseif SYSTEM=="OS X" then
|
|
||||||
local rtn = package.loadlib(libName["OS X"], libName.libFunc)
|
|
||||||
if rtn then
|
|
||||||
local a = rtn()
|
|
||||||
MES.new('check',name.." lib loaded")
|
|
||||||
return a
|
|
||||||
else
|
|
||||||
MES.new('error',"Cannot load "..name)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
MES.new('error',"No "..name.." for "..SYSTEM)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
20
Zframework/log.lua
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
local ins=table.insert
|
||||||
|
|
||||||
|
local logs={os.date("Techmino logs %Y/%m/%d %A")}
|
||||||
|
|
||||||
|
local function log(message)
|
||||||
|
ins(logs,os.date("[%H:%M:%S] ")..message)
|
||||||
|
end
|
||||||
|
|
||||||
|
local LOG=setmetatable({logs=logs},{
|
||||||
|
__call=function(_,message)
|
||||||
|
print(message)
|
||||||
|
log(message)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
function LOG.read()
|
||||||
|
return table.concat(logs,"\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
return LOG
|
||||||
37
Zframework/mathExtend.lua
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
local MATH={}for k,v in next,math do MATH[k]=v end
|
||||||
|
|
||||||
|
local rnd=math.random
|
||||||
|
|
||||||
|
MATH.tau=2*math.pi
|
||||||
|
|
||||||
|
function MATH.sign(a)
|
||||||
|
return a>0 and 1 or a<0 and -1 or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function MATH.roll(chance)
|
||||||
|
return rnd()<(chance or .5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function MATH.coin(a,b)
|
||||||
|
if rnd()<.5 then
|
||||||
|
return a
|
||||||
|
else
|
||||||
|
return b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MATH.interval(v,low,high)
|
||||||
|
if v<=low then
|
||||||
|
return low
|
||||||
|
elseif v>=high then
|
||||||
|
return high
|
||||||
|
else
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MATH.expApproach(a,b,k)
|
||||||
|
return b+(a-b)*2.718281828459045^-k
|
||||||
|
end
|
||||||
|
|
||||||
|
return MATH
|
||||||
@@ -29,19 +29,19 @@ local mesIcon={
|
|||||||
{'fRect',2,4,36,26,3},
|
{'fRect',2,4,36,26,3},
|
||||||
{'fPoly',2,27,2,37,14,25},
|
{'fPoly',2,27,2,37,14,25},
|
||||||
{'setCL',.5,.5,.5},
|
{'setCL',.5,.5,.5},
|
||||||
{'fRect',6,11,4,4},{'fRect',14,11,19,4},
|
{'fRect',6,11,4,4,1},{'fRect',14,11,19,4,1},
|
||||||
{'fRect',6,19,4,4},{'fRect',14,19,19,4},
|
{'fRect',6,19,4,4,1},{'fRect',14,19,19,4,1},
|
||||||
},
|
},
|
||||||
warn=GC.DO{40,40,
|
warn=GC.DO{40,40,
|
||||||
{'setCL',.95,.83,.4},
|
{'setCL',.95,.83,.4},
|
||||||
{'fPoly',20.5,1,0,38,40,38},
|
{'fPoly',20.5,1,0,38,40,38},
|
||||||
{'setCL',0,0,0},
|
{'setCL',0,0,0},
|
||||||
{'dPoly',20.5,1,0,38,40,38},
|
{'dPoly',20.5,1,0,38,40,38},
|
||||||
{'fRect',17,10,7,18},
|
{'fRect',17,10,7,18,2},
|
||||||
{'fRect',17,29,7,7},
|
{'fRect',17,29,7,7,2},
|
||||||
{'setCL',1,1,1},
|
{'setCL',1,1,1},
|
||||||
{'fRect',18,11,5,16},
|
{'fRect',18,11,5,16,2},
|
||||||
{'fRect',18,30,5,5},
|
{'fRect',18,30,5,5,2},
|
||||||
},
|
},
|
||||||
error=GC.DO{40,40,
|
error=GC.DO{40,40,
|
||||||
{'setCL',.95,.3,.3},
|
{'setCL',.95,.3,.3},
|
||||||
@@ -56,27 +56,32 @@ local mesIcon={
|
|||||||
{'line',11,11,29,29},
|
{'line',11,11,29,29},
|
||||||
{'line',11,29,29,11},
|
{'line',11,29,29,11},
|
||||||
},
|
},
|
||||||
|
music=GC.DO{40,40,
|
||||||
|
{'setLW',2},
|
||||||
|
{'dRect',1,3,38,34,3},
|
||||||
|
{'setLW',4},
|
||||||
|
{'line',21,26,21,10,28,10},
|
||||||
|
{'fElps',17,26,6,5},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
local MES={}
|
local MES={}
|
||||||
|
local backColors={
|
||||||
|
check={.3,.6,.3,.7},
|
||||||
|
broadcast={.3,.3,.6,.8},
|
||||||
|
warn={.4,.4,.2,.9},
|
||||||
|
error={.4,.2,.2,.9},
|
||||||
|
music={.2,.4,.4,.9},
|
||||||
|
}
|
||||||
function MES.new(icon,str,time)
|
function MES.new(icon,str,time)
|
||||||
local backColor={.5,.5,.5,.7}
|
local backColor={.5,.5,.5,.7}
|
||||||
if type(icon)=='string'then
|
if type(icon)=='string'then
|
||||||
if icon=='check'then
|
backColor=backColors[icon]or backColor
|
||||||
backColor={.3,.6,.3,.7}
|
|
||||||
elseif icon=='broadcast'then
|
|
||||||
backColor={.3,.3,.6,.8}
|
|
||||||
elseif icon=='warn'then
|
|
||||||
backColor={.4,.4,.2,.9}
|
|
||||||
elseif icon=='error'then
|
|
||||||
backColor={.4,.2,.2,.9}
|
|
||||||
end
|
|
||||||
icon=mesIcon[icon]
|
icon=mesIcon[icon]
|
||||||
end
|
end
|
||||||
local t=gc.newText(getFont(30),str)
|
local t=gc.newText(FONT.get(30),str)
|
||||||
local w=math.max(t:getWidth()+(icon and 45 or 5),200)+20
|
local w=math.max(t:getWidth()+(icon and 45 or 5),200)+15
|
||||||
local h=math.max(t:getHeight(),46)+3
|
local h=math.max(t:getHeight(),46)+2
|
||||||
local L={w,h,
|
local L={w,h,
|
||||||
{'clear',backColor},
|
{'clear',backColor},
|
||||||
{'setCL',.7,.7,.7},
|
{'setCL',.7,.7,.7},
|
||||||
@@ -87,7 +92,7 @@ function MES.new(icon,str,time)
|
|||||||
if icon then
|
if icon then
|
||||||
ins(L,{'draw',icon,4,4,nil,40/icon:getWidth(),40/icon:getHeight()})
|
ins(L,{'draw',icon,4,4,nil,40/icon:getWidth(),40/icon:getHeight()})
|
||||||
end
|
end
|
||||||
ins(L,{'draw',t,icon and 50 or 10,2})
|
ins(L,{'mDrawY',t,icon and 50 or 10,h/2})
|
||||||
|
|
||||||
ins(mesList,{
|
ins(mesList,{
|
||||||
startTime=.5,
|
startTime=.5,
|
||||||
@@ -122,7 +127,7 @@ function MES.draw()
|
|||||||
local m=mesList[i]
|
local m=mesList[i]
|
||||||
gc_setColor(1,1,1,2*(m.endTime-m.startTime))
|
gc_setColor(1,1,1,2*(m.endTime-m.startTime))
|
||||||
gc_draw(m.canvas,40-80*(m.endTime+m.startTime),0,nil,m.scale)
|
gc_draw(m.canvas,40-80*(m.endTime+m.startTime),0,nil,m.scale)
|
||||||
gc_translate(0,m.height*m.scale+4)
|
gc_translate(0,m.height*m.scale+2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
gc_pop()
|
gc_pop()
|
||||||
|
|||||||
@@ -140,11 +140,11 @@ function profile.switch()
|
|||||||
switch=not switch
|
switch=not switch
|
||||||
if not switch then
|
if not switch then
|
||||||
profile.stop()
|
profile.stop()
|
||||||
love.system.setClipboardText(PROFILE.report())
|
love.system.setClipboardText(profile.report())
|
||||||
PROFILE.reset()
|
profile.reset()
|
||||||
return false
|
return false
|
||||||
else
|
else
|
||||||
PROFILE.start()
|
profile.start()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
33
Zframework/require.lua
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package.cpath=package.cpath..';'..SAVEDIR..'/lib/lib?.so;'..'?.dylib'
|
||||||
|
local loaded={}
|
||||||
|
return function(libName)
|
||||||
|
local require=require
|
||||||
|
if love.system.getOS()=='OS X'then
|
||||||
|
require=package.loadlib(libName..'.dylib','luaopen_'..libName)
|
||||||
|
libname=nil
|
||||||
|
elseif love.system.getOS()=='Android'then
|
||||||
|
if not loaded[libName]then
|
||||||
|
local platform=(function()
|
||||||
|
local p=io.popen('uname -m')
|
||||||
|
local arch=p:read('*a'):lower()
|
||||||
|
p:close()
|
||||||
|
if arch:find('v8')or arch:find('64')then
|
||||||
|
return'arm64-v8a'
|
||||||
|
else
|
||||||
|
return'armeabi-v7a'
|
||||||
|
end
|
||||||
|
end)()
|
||||||
|
love.filesystem.write(
|
||||||
|
'lib/libCCloader.so',
|
||||||
|
love.filesystem.read('data','libAndroid/'..platform..'/libCCloader.so')
|
||||||
|
)
|
||||||
|
loaded[libName]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local success,res=pcall(require,libName)
|
||||||
|
if success and res then
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
MES.new('error',"Cannot load "..libName..": "..res)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,6 +4,7 @@ local abs=math.abs
|
|||||||
local scenes={}
|
local scenes={}
|
||||||
|
|
||||||
local SCN={
|
local SCN={
|
||||||
|
mainTouchID=nil, --First touching ID(userdata)
|
||||||
cur='NULL', --Current scene name
|
cur='NULL', --Current scene name
|
||||||
swapping=false, --If Swapping
|
swapping=false, --If Swapping
|
||||||
stat={
|
stat={
|
||||||
@@ -14,6 +15,8 @@ local SCN={
|
|||||||
draw=false, --Swap draw func
|
draw=false, --Swap draw func
|
||||||
},
|
},
|
||||||
stack={},--Scene stack
|
stack={},--Scene stack
|
||||||
|
prev=false,
|
||||||
|
args={},--Arguments from previous scene
|
||||||
|
|
||||||
scenes=scenes,
|
scenes=scenes,
|
||||||
|
|
||||||
@@ -46,18 +49,20 @@ function SCN.add(name,scene)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SCN.swapUpdate()
|
function SCN.swapUpdate(dt)
|
||||||
local S=SCN.stat
|
local S=SCN.stat
|
||||||
S.time=S.time-1
|
S.time=S.time-dt
|
||||||
if S.time==S.changeTime then
|
if S.time<S.changeTime and S.time+dt>=S.changeTime then
|
||||||
--Scene swapped this moment
|
--Scene swapped this frame
|
||||||
SCN.init(S.tar,SCN.cur)
|
SCN.prev=SCN.cur
|
||||||
|
SCN.init(S.tar)
|
||||||
|
SCN.mainTouchID=nil
|
||||||
end
|
end
|
||||||
if S.time==0 then
|
if S.time<0 then
|
||||||
SCN.swapping=false
|
SCN.swapping=false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function SCN.init(s,org)
|
function SCN.init(s)
|
||||||
love.keyboard.setTextInput(false)
|
love.keyboard.setTextInput(false)
|
||||||
|
|
||||||
local S=scenes[s]
|
local S=scenes[s]
|
||||||
@@ -86,7 +91,9 @@ function SCN.init(s,org)
|
|||||||
SCN.socketRead=S.socketRead
|
SCN.socketRead=S.socketRead
|
||||||
SCN.update=S.update
|
SCN.update=S.update
|
||||||
SCN.draw=S.draw
|
SCN.draw=S.draw
|
||||||
if S.sceneInit then S.sceneInit(org)end
|
if S.sceneInit then
|
||||||
|
S.sceneInit()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
function SCN.push(tar,style)
|
function SCN.push(tar,style)
|
||||||
if not SCN.swapping then
|
if not SCN.swapping then
|
||||||
@@ -101,47 +108,72 @@ function SCN.pop()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local swap={
|
local swap={
|
||||||
none={duration=1,changeTime=0,draw=function()end},
|
none={
|
||||||
flash={duration=8,changeTime=1,draw=function()gc.clear(1,1,1)end},
|
duration=0,changeTime=0,
|
||||||
fade={duration=30,changeTime=15,draw=function(t)
|
draw=function()end
|
||||||
t=t>15 and 2-t/15 or t/15
|
},
|
||||||
|
flash={
|
||||||
|
duration=.16,changeTime=.08,
|
||||||
|
draw=function()gc.clear(1,1,1)end
|
||||||
|
},
|
||||||
|
fade={
|
||||||
|
duration=.5,changeTime=.25,
|
||||||
|
draw=function(t)
|
||||||
|
t=t>.25 and 2-t*4 or t*4
|
||||||
gc.setColor(0,0,0,t)
|
gc.setColor(0,0,0,t)
|
||||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
fade_togame={duration=120,changeTime=20,draw=function(t)
|
},
|
||||||
t=t>20 and(120-t)/100 or t/20
|
fade_togame={
|
||||||
|
duration=2,changeTime=.5,
|
||||||
|
draw=function(t)
|
||||||
|
t=t>.5 and(2-t)/1.5 or t*.5
|
||||||
gc.setColor(0,0,0,t)
|
gc.setColor(0,0,0,t)
|
||||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
slowFade={duration=180,changeTime=90,draw=function(t)
|
},
|
||||||
t=t>90 and 2-t/90 or t/90
|
slowFade={
|
||||||
|
duration=3,changeTime=1.5,
|
||||||
|
draw=function(t)
|
||||||
|
t=t>1.5 and (3-t)/1.5 or t/1.5
|
||||||
gc.setColor(0,0,0,t)
|
gc.setColor(0,0,0,t)
|
||||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
swipeL={duration=30,changeTime=15,draw=function(t)
|
},
|
||||||
t=t/30
|
swipeL={
|
||||||
|
duration=.5,changeTime=.25,
|
||||||
|
draw=function(t)
|
||||||
|
t=t*2
|
||||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||||
t=t*t*(3-2*t)*2-1
|
t=t*t*(3-2*t)*2-1
|
||||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
swipeR={duration=30,changeTime=15,draw=function(t)
|
},
|
||||||
t=t/30
|
swipeR={
|
||||||
|
duration=.5,changeTime=.25,
|
||||||
|
draw=function(t)
|
||||||
|
t=t*2
|
||||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||||
t=t*t*(2*t-3)*2+1
|
t=t*t*(2*t-3)*2+1
|
||||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
swipeD={duration=30,changeTime=15,draw=function(t)
|
},
|
||||||
t=t/30
|
swipeD={
|
||||||
|
duration=.5,changeTime=.25,
|
||||||
|
draw=function(t)
|
||||||
|
t=t*2
|
||||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||||
t=t*t*(2*t-3)*2+1
|
t=t*t*(2*t-3)*2+1
|
||||||
gc.rectangle('fill',0,t*SCR.h,SCR.w,SCR.h)
|
gc.rectangle('fill',0,t*SCR.h,SCR.w,SCR.h)
|
||||||
end},
|
end
|
||||||
|
},
|
||||||
}--Scene swapping animations
|
}--Scene swapping animations
|
||||||
function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
|
function SCN.swapTo(tar,style,...)--Parallel scene swapping, cannot back
|
||||||
if scenes[tar]then
|
if scenes[tar]then
|
||||||
if not SCN.swapping and tar~=SCN.cur then
|
if not SCN.swapping and tar~=SCN.cur then
|
||||||
if not style then style='fade'end
|
style=style or'fade'
|
||||||
SCN.swapping=true
|
SCN.swapping=true
|
||||||
|
SCN.args={...}
|
||||||
local S=SCN.stat
|
local S=SCN.stat
|
||||||
S.tar,S.style=tar,style
|
S.tar,S.style=tar,style
|
||||||
S.time=swap[style].duration
|
S.time=swap[style].duration
|
||||||
@@ -152,24 +184,26 @@ function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
|
|||||||
MES.new('warn',"No Scene: "..tar)
|
MES.new('warn',"No Scene: "..tar)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function SCN.go(tar,style)--Normal scene swapping, can back
|
function SCN.go(tar,style,...)--Normal scene swapping, can back
|
||||||
if scenes[tar]then
|
if scenes[tar]then
|
||||||
SCN.push()
|
SCN.push()
|
||||||
SCN.swapTo(tar,style)
|
SCN.swapTo(tar,style,...)
|
||||||
else
|
else
|
||||||
MES.new('warn',"No Scene: "..tar)
|
MES.new('warn',"No Scene: "..tar)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function SCN.back()
|
function SCN.back(...)
|
||||||
if SCN.swapping then return end
|
if SCN.swapping then return end
|
||||||
|
|
||||||
--Leave scene
|
--Leave scene
|
||||||
if SCN.sceneBack then SCN.sceneBack()end
|
if SCN.sceneBack then
|
||||||
|
SCN.sceneBack()
|
||||||
|
end
|
||||||
|
|
||||||
--Poll&Back to previous Scene
|
--Poll&Back to previous Scene
|
||||||
local m=#SCN.stack
|
local m=#SCN.stack
|
||||||
if m>0 then
|
if m>0 then
|
||||||
SCN.swapTo(SCN.stack[m-1],SCN.stack[m])
|
SCN.swapTo(SCN.stack[m-1],SCN.stack[m],...)
|
||||||
SCN.stack[m],SCN.stack[m-1]=nil
|
SCN.stack[m],SCN.stack[m-1]=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
local gc=love.graphics
|
|
||||||
local newFont=gc.setNewFont
|
|
||||||
local setNewFont=gc.setFont
|
|
||||||
local fontCache,currentFontSize={}
|
|
||||||
if love.filesystem.getInfo('font.ttf')then
|
|
||||||
local fontData=love.filesystem.newFile('font.ttf')
|
|
||||||
function setFont(s)
|
|
||||||
if s~=currentFontSize then
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=newFont(fontData,s)
|
|
||||||
end
|
|
||||||
setNewFont(fontCache[s])
|
|
||||||
currentFontSize=s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function getFont(s)
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=newFont(fontData,s)
|
|
||||||
end
|
|
||||||
return fontCache[s]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
function setFont(s)
|
|
||||||
if s~=currentFontSize then
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=newFont(s)
|
|
||||||
end
|
|
||||||
setNewFont(fontCache[s])
|
|
||||||
currentFontSize=s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function getFont(s)
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=newFont(s)
|
|
||||||
end
|
|
||||||
return fontCache[s]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,30 +1,133 @@
|
|||||||
local SFX={
|
local type,rem=type,table.remove
|
||||||
getCount=function()return 0 end,
|
local int,rnd=math.floor,math.random
|
||||||
loadAll=function()error("Cannot load before init!")end,
|
local interval=MATH.interval
|
||||||
fieldPlay=NULL,
|
|
||||||
play=NULL,
|
local sfxList={}
|
||||||
fplay=NULL,
|
local packSetting={}
|
||||||
reset=NULL,
|
|
||||||
}
|
|
||||||
function SFX.init(list)
|
|
||||||
SFX.init=nil
|
|
||||||
local rem=table.remove
|
|
||||||
local Sources={}
|
local Sources={}
|
||||||
|
local volume=1
|
||||||
|
local stereo=1
|
||||||
|
|
||||||
local count=#list function SFX.getCount()return count end
|
local noteVal={
|
||||||
function SFX.loadAll()
|
C=1,c=1,
|
||||||
for i=1,count do
|
D=3,d=3,
|
||||||
local N='media/SFX/'..list[i]..'.ogg'
|
E=5,e=5,
|
||||||
if love.filesystem.getInfo(N)then
|
F=6,f=6,
|
||||||
Sources[list[i]]={love.audio.newSource(N,'static')}
|
G=8,g=8,
|
||||||
|
A=10,a=10,
|
||||||
|
B=12,b=12,
|
||||||
|
}
|
||||||
|
local noteName={'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
|
||||||
|
local function _getTuneHeight(tune)
|
||||||
|
local octave=tonumber(tune:sub(-1,-1))
|
||||||
|
if octave then
|
||||||
|
local tuneHeight=noteVal[tune:sub(1,1)]
|
||||||
|
if tuneHeight then
|
||||||
|
tuneHeight=tuneHeight+(octave-1)*12
|
||||||
|
local s=tune:sub(2,2)
|
||||||
|
if s=='s'or s=='#'then
|
||||||
|
tuneHeight=tuneHeight+1
|
||||||
|
elseif s=='f'or s=='b'then
|
||||||
|
tuneHeight=tuneHeight-1
|
||||||
|
end
|
||||||
|
return tuneHeight
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local SFX={}
|
||||||
|
|
||||||
|
function SFX.init(list)
|
||||||
|
assert(type(list)=='table',"Initialize SFX lib with a list of filenames!")
|
||||||
|
for i=1,#list do table.insert(sfxList,list[i])end
|
||||||
|
end
|
||||||
|
function SFX.load(path)
|
||||||
|
local c=0
|
||||||
|
local missing=0
|
||||||
|
for i=1,#sfxList do
|
||||||
|
local fullPath=path..sfxList[i]..'.ogg'
|
||||||
|
if love.filesystem.getInfo(fullPath)then
|
||||||
|
if Sources[sfxList[i]]then
|
||||||
|
for j=1,#Sources[sfxList[i]]do
|
||||||
|
Sources[sfxList[i]][j]:release()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Sources[sfxList[i]]={love.audio.newSource(fullPath,'static')}
|
||||||
|
c=c+1
|
||||||
else
|
else
|
||||||
MES.new('warn',"No SFX file: "..N,.1)
|
LOG("No SFX: "..sfxList[i]..'.ogg',.1)
|
||||||
|
missing=missing+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
LOG(c.."/"..#sfxList.." SFX files loaded")
|
||||||
|
LOG(missing.." SFX files missing")
|
||||||
|
if missing>0 then
|
||||||
|
MES.new('info',missing.." SFX files missing")
|
||||||
|
end
|
||||||
|
collectgarbage()
|
||||||
|
end
|
||||||
|
function SFX.loadSample(pack)
|
||||||
|
assert(type(pack)=='table',"Usage: SFX.loadsample([table])")
|
||||||
|
assert(pack.name,"No field: name")
|
||||||
|
assert(pack.path,"No field: path")
|
||||||
|
local num=1
|
||||||
|
while love.filesystem.getInfo(pack.path..'/'..num..'.ogg')do
|
||||||
|
Sources[pack.name..num]={love.audio.newSource(pack.path..'/'..num..'.ogg','static')}
|
||||||
|
num=num+1
|
||||||
|
end
|
||||||
|
local base=(_getTuneHeight(pack.base)or 37)-1
|
||||||
|
local top=base+num-1
|
||||||
|
packSetting[pack.name]={base=base,top=top}
|
||||||
|
LOG((num-1).." "..pack.name.." samples loaded")
|
||||||
|
end
|
||||||
|
|
||||||
function SFX.play(s,vol,pos)
|
function SFX.getCount()
|
||||||
if SETTING.sfx==0 or vol==0 then return end
|
return #sfxList
|
||||||
local S=Sources[s]--Source list
|
end
|
||||||
|
function SFX.setVol(v)
|
||||||
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
|
volume=v
|
||||||
|
end
|
||||||
|
function SFX.setStereo(v)
|
||||||
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong stereo')
|
||||||
|
stereo=v
|
||||||
|
end
|
||||||
|
|
||||||
|
function SFX.getNoteName(note)
|
||||||
|
if note<1 then
|
||||||
|
return'---'
|
||||||
|
else
|
||||||
|
note=note-1
|
||||||
|
local octave=int(note/12)+1
|
||||||
|
return noteName[note%12+1]..octave
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function SFX.playSample(pack,...)--vol-1, sampSet1, vol-2, sampSet2
|
||||||
|
if ... then
|
||||||
|
local arg={...}
|
||||||
|
local vol
|
||||||
|
for i=1,#arg do
|
||||||
|
local a=arg[i]
|
||||||
|
if type(a)=='number'and a<=1 then
|
||||||
|
vol=a
|
||||||
|
else
|
||||||
|
local base=packSetting[pack].base
|
||||||
|
local top=packSetting[pack].top
|
||||||
|
local tune=type(a)=='string'and _getTuneHeight(a)or a--Absolute tune in number
|
||||||
|
local playTune=tune+rnd(-2,2)
|
||||||
|
if playTune<=base then--Too low notes
|
||||||
|
playTune=base+1
|
||||||
|
elseif playTune>top then--Too high notes
|
||||||
|
playTune=top
|
||||||
|
end
|
||||||
|
SFX.play(pack..playTune-base,vol,nil,tune-playTune)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function _play(name,vol,pos,pitch)
|
||||||
|
if volume==0 or vol==0 then return end
|
||||||
|
local S=Sources[name]--Source list
|
||||||
if not S then return end
|
if not S then return end
|
||||||
local n=1
|
local n=1
|
||||||
while S[n]:isPlaying()do
|
while S[n]:isPlaying()do
|
||||||
@@ -38,39 +141,20 @@ function SFX.init(list)
|
|||||||
S=S[n]--AU_SRC
|
S=S[n]--AU_SRC
|
||||||
if S:getChannelCount()==1 then
|
if S:getChannelCount()==1 then
|
||||||
if pos then
|
if pos then
|
||||||
pos=pos*SETTING.stereo
|
pos=interval(pos,-1,1)*stereo
|
||||||
S:setPosition(pos,1-pos^2,0)
|
|
||||||
else
|
|
||||||
S:setPosition(0,0,0)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
S:setVolume(((vol or 1)*SETTING.sfx)^1.626)
|
|
||||||
S:play()
|
|
||||||
end
|
|
||||||
function SFX.fplay(s,vol,pos)
|
|
||||||
local S=Sources[s]--Source list
|
|
||||||
if not S then return end
|
|
||||||
local n=1
|
|
||||||
while S[n]:isPlaying()do
|
|
||||||
n=n+1
|
|
||||||
if not S[n]then
|
|
||||||
S[n]=S[1]:clone()
|
|
||||||
S[n]:seek(0)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
S=S[n]--AU_SRC
|
|
||||||
if S:getChannelCount()==1 then
|
|
||||||
if pos then
|
|
||||||
pos=pos*SETTING.stereo
|
|
||||||
S:setPosition(pos,1-pos^2,0)
|
S:setPosition(pos,1-pos^2,0)
|
||||||
else
|
else
|
||||||
S:setPosition(0,0,0)
|
S:setPosition(0,0,0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
S:setVolume(vol^1.626)
|
S:setVolume(vol^1.626)
|
||||||
|
S:setPitch(pitch and 1.0594630943592953^pitch or 1)
|
||||||
S:play()
|
S:play()
|
||||||
end
|
end
|
||||||
|
SFX.fplay=_play--Play sounds without apply module's volume setting
|
||||||
|
function SFX.play(name,vol,pos,pitch)
|
||||||
|
_play(name,(vol or 1)*volume,pos,pitch)
|
||||||
|
end
|
||||||
function SFX.reset()
|
function SFX.reset()
|
||||||
for _,L in next,Sources do
|
for _,L in next,Sources do
|
||||||
if type(L)=='table'then
|
if type(L)=='table'then
|
||||||
@@ -82,6 +166,5 @@ function SFX.init(list)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
return SFX
|
return SFX
|
||||||
@@ -1,9 +1,26 @@
|
|||||||
local data=love.data
|
local data=love.data
|
||||||
local STRING={}
|
local STRING={}
|
||||||
|
local assert,tostring,tonumber=assert,tostring,tonumber
|
||||||
local int,format=math.floor,string.format
|
local int,format=math.floor,string.format
|
||||||
local find,sub,upper=string.find,string.sub,string.upper
|
local find,sub,gsub,upper=string.find,string.sub,string.gsub,string.upper
|
||||||
local char,byte=string.char,string.byte
|
local char,byte=string.char,string.byte
|
||||||
|
|
||||||
|
--"Replace dollars", replace all $n with ...
|
||||||
|
function STRING.repD(str,...)
|
||||||
|
local l={...}
|
||||||
|
for i=#l,1,-1 do
|
||||||
|
str=gsub(str,'$'..i,l[i])
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
--"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q")
|
||||||
|
function STRING.sArg(str,switch)
|
||||||
|
if find(str.." ",switch.." ")then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
do--function STRING.shiftChar(c)
|
do--function STRING.shiftChar(c)
|
||||||
local shiftMap={
|
local shiftMap={
|
||||||
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
|
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
|
||||||
@@ -54,15 +71,59 @@ function STRING.simpEmailCheck(e)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function STRING.time(s)
|
function STRING.time_simp(t)
|
||||||
if s<60 then
|
return format("%02d:%02d",int(t/60),int(t%60))
|
||||||
return format("%.3f\"",s)
|
|
||||||
elseif s<3600 then
|
|
||||||
return format("%d'%05.2f\"",int(s/60),s%60)
|
|
||||||
else
|
|
||||||
local h=int(s/3600)
|
|
||||||
return format("%d:%.2d'%05.2f\"",h,int(s/60%60),s%60)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function STRING.time(t)
|
||||||
|
if t<60 then
|
||||||
|
return format("%.3f\"",t)
|
||||||
|
elseif t<3600 then
|
||||||
|
return format("%d'%05.2f\"",int(t/60),int(t%60*100)/100)
|
||||||
|
else
|
||||||
|
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),int(t%60*100)/100)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function STRING.UTF8(n)--Simple utf8 coding
|
||||||
|
assert(type(n)=='number',"Wrong type ("..type(n)..")")
|
||||||
|
assert(n>=0 and n<2^31,"Out of range ("..n..")")
|
||||||
|
if n<2^7 then return char(n)
|
||||||
|
elseif n<2^11 then return char(192+int(n/2^06),128+n%2^6)
|
||||||
|
elseif n<2^16 then return char(224+int(n/2^12),128+int(n/2^06)%2^6,128+n%2^6)
|
||||||
|
elseif n<2^21 then return char(240+int(n/2^18),128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||||
|
elseif n<2^26 then return char(248+int(n/2^24),128+int(n/2^18)%2^6,128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||||
|
elseif n<2^31 then return char(252+int(n/2^30),128+int(n/2^24)%2^6,128+int(n/2^18)%2^6,128+int(n/2^12)%2^6,128+int(n/2^06)%2^6,128+n%2^6)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
do--function STRING.bigInt(t)
|
||||||
|
local lg=math.log10
|
||||||
|
local units={"","K","M","B","T","Qa","Qt","Sx","Sp","Oc","No"}
|
||||||
|
local preUnits={"","U","D","T","Qa","Qt","Sx","Sp","O","N"}
|
||||||
|
local secUnits={"Dc","Vg","Tg","Qd","Qi","Se","St","Og","Nn","Ce"}--Ce is next-level unit, but DcCe is not used so used here
|
||||||
|
for _,preU in next,preUnits do for _,secU in next,secUnits do table.insert(units,preU..secU)end end
|
||||||
|
function STRING.bigInt(t)
|
||||||
|
if t<1000 then
|
||||||
|
return tostring(t)
|
||||||
|
elseif t~=1e999 then
|
||||||
|
local e=int(lg(t)/3)
|
||||||
|
return(t/10^(e*3))..units[e+1]
|
||||||
|
else
|
||||||
|
return"INF"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function STRING.hexColor(str)--[LOW PERFORMENCE]
|
||||||
|
assert(type(str)=='string')
|
||||||
|
if str:sub(1,1)=="#"then str=str:sub(2)end
|
||||||
|
assert(#str<=8)
|
||||||
|
local r=(tonumber(str:sub(1,2),16)or 0)/255
|
||||||
|
local g=(tonumber(str:sub(3,4),16)or 0)/255
|
||||||
|
local b=(tonumber(str:sub(5,6),16)or 0)/255
|
||||||
|
local a=(tonumber(str:sub(7,8),16)or 255)/255
|
||||||
|
return r,g,b,a
|
||||||
end
|
end
|
||||||
|
|
||||||
do--function STRING.urlEncode(s)
|
do--function STRING.urlEncode(s)
|
||||||
@@ -108,6 +169,25 @@ function STRING.vcsDecrypt(text,key)
|
|||||||
end
|
end
|
||||||
return result..buffer
|
return result..buffer
|
||||||
end
|
end
|
||||||
|
function STRING.digezt(text)--Not powerful hash, just protect the original text
|
||||||
|
local out={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
local seed=26
|
||||||
|
for i=1,#text do
|
||||||
|
local c=byte(text,i)
|
||||||
|
seed=(seed+c)%26
|
||||||
|
c=c+seed
|
||||||
|
local pos=c*i%16
|
||||||
|
local step=(c+i)%4+1
|
||||||
|
local times=2+(c%6)
|
||||||
|
for _=1,times do
|
||||||
|
out[pos+1]=(out[pos+1]+c)%256
|
||||||
|
pos=(pos+step)%16
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local result=""
|
||||||
|
for i=1,16 do result=result..char(out[i])end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
function STRING.readLine(str)
|
function STRING.readLine(str)
|
||||||
local p=str:find("\n")
|
local p=str:find("\n")
|
||||||
@@ -117,6 +197,9 @@ function STRING.readLine(str)
|
|||||||
return str,""
|
return str,""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function STRING.readChars(str,n)
|
||||||
|
return sub(str,1,n),sub(str,n+1)
|
||||||
|
end
|
||||||
|
|
||||||
function STRING.packBin(s)
|
function STRING.packBin(s)
|
||||||
return data.encode('string','base64',data.compress('string','zlib',s))
|
return data.encode('string','base64',data.compress('string','zlib',s))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ local ins,rem=table.insert,table.remove
|
|||||||
|
|
||||||
local fx={}
|
local fx={}
|
||||||
|
|
||||||
local function normUpdate(S,dt)
|
local function _normUpdate(S,dt)
|
||||||
S.t=S.t+dt*S.rate
|
S.t=S.t+dt*S.rate
|
||||||
return S.t>1
|
return S.t>1
|
||||||
end
|
end
|
||||||
@@ -28,11 +28,11 @@ function FXupdate.badge(S,dt)
|
|||||||
end
|
end
|
||||||
return S.t>=1
|
return S.t>=1
|
||||||
end
|
end
|
||||||
FXupdate.attack=normUpdate
|
FXupdate.attack=_normUpdate
|
||||||
FXupdate.tap=normUpdate
|
FXupdate.tap=_normUpdate
|
||||||
FXupdate.ripple=normUpdate
|
FXupdate.ripple=_normUpdate
|
||||||
FXupdate.rectRipple=normUpdate
|
FXupdate.rectRipple=_normUpdate
|
||||||
FXupdate.shade=normUpdate
|
FXupdate.shade=_normUpdate
|
||||||
function FXupdate.cell(S,dt)
|
function FXupdate.cell(S,dt)
|
||||||
if S.vx then
|
if S.vx then
|
||||||
S.x=S.x+S.vx*S.rate
|
S.x=S.x+S.vx*S.rate
|
||||||
@@ -45,7 +45,7 @@ function FXupdate.cell(S,dt)
|
|||||||
S.t=S.t+dt*S.rate
|
S.t=S.t+dt*S.rate
|
||||||
return S.t>1
|
return S.t>1
|
||||||
end
|
end
|
||||||
FXupdate.line=normUpdate
|
FXupdate.line=_normUpdate
|
||||||
|
|
||||||
local FXdraw={}
|
local FXdraw={}
|
||||||
function FXdraw.badge(S)
|
function FXdraw.badge(S)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
local find=string.find
|
local find=string.find
|
||||||
|
local rem=table.remove
|
||||||
local next,type=next,type
|
local next,type=next,type
|
||||||
local TABLE={}
|
local TABLE={}
|
||||||
|
|
||||||
@@ -16,10 +17,10 @@ function TABLE.shift(org,depth)
|
|||||||
if not depth then depth=1e99 end
|
if not depth then depth=1e99 end
|
||||||
local L={}
|
local L={}
|
||||||
for i=1,#org do
|
for i=1,#org do
|
||||||
if type(org[i])~='table'or depth==0 then
|
if type(org[i])=='table'and depth>0 then
|
||||||
L[i]=org[i]
|
|
||||||
else
|
|
||||||
L[i]=TABLE.shift(org[i],depth-1)
|
L[i]=TABLE.shift(org[i],depth-1)
|
||||||
|
else
|
||||||
|
L[i]=org[i]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L
|
return L
|
||||||
@@ -30,10 +31,10 @@ function TABLE.copy(org,depth)
|
|||||||
if not depth then depth=1e99 end
|
if not depth then depth=1e99 end
|
||||||
local L={}
|
local L={}
|
||||||
for k,v in next,org do
|
for k,v in next,org do
|
||||||
if type(v)~='table'or depth==0 then
|
if type(v)=='table'and depth>0 then
|
||||||
L[k]=v
|
|
||||||
else
|
|
||||||
L[k]=TABLE.copy(v,depth-1)
|
L[k]=TABLE.copy(v,depth-1)
|
||||||
|
else
|
||||||
|
L[k]=v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L
|
return L
|
||||||
@@ -46,6 +47,18 @@ function TABLE.cover(new,old)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--For all things in new, push to old
|
||||||
|
function TABLE.coverR(new,old)
|
||||||
|
for k,v in next,new do
|
||||||
|
if type(v)=='table'and type(old[k])=='table'then
|
||||||
|
TABLE.coverR(v,old[k])
|
||||||
|
else
|
||||||
|
old[k]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--For all things in new if same type in old, push to old
|
--For all things in new if same type in old, push to old
|
||||||
function TABLE.update(new,old)
|
function TABLE.update(new,old)
|
||||||
for k,v in next,new do
|
for k,v in next,new do
|
||||||
@@ -71,9 +84,9 @@ function TABLE.complete(new,old)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Remove positive integer index of table
|
--Remove [1~#] of table
|
||||||
function TABLE.cut(G)
|
function TABLE.cut(G)
|
||||||
for i=#G,1,-1 do
|
for i=1,#G do
|
||||||
G[i]=nil
|
G[i]=nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -85,11 +98,53 @@ function TABLE.clear(G)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Remove duplicated value of [1~#]
|
||||||
|
function TABLE.trimDuplicate(org)
|
||||||
|
local cache={}
|
||||||
|
for i=1,#org,-1 do
|
||||||
|
if cache[org[i]]then
|
||||||
|
rem(org,i)
|
||||||
|
else
|
||||||
|
cache[org[i]]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--Discard duplicated value
|
||||||
|
function TABLE.remDuplicate(org)
|
||||||
|
local cache={}
|
||||||
|
for k,v in next,org do
|
||||||
|
if cache[v]then
|
||||||
|
org[k]=nil
|
||||||
|
else
|
||||||
|
cache[v]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--Reverse [1~#]
|
||||||
|
function TABLE.reverse(org)
|
||||||
|
local l=#org
|
||||||
|
for i=1,math.floor(l/2)do
|
||||||
|
org[i],org[l+1-i]=org[l+1-i],org[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
|
||||||
--Find value in [1~#]
|
--Find value in [1~#]
|
||||||
function TABLE.find(t,val)
|
function TABLE.find(t,val)
|
||||||
for i=1,#t do if t[i]==val then return i end end
|
for i=1,#t do if t[i]==val then return i end end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--Return next value of [1~#] (by value)
|
||||||
|
function TABLE.next(t,val)
|
||||||
|
for i=1,#t do if t[i]==val then return t[i%#t+1]end end
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
|
||||||
--Find value in whole table
|
--Find value in whole table
|
||||||
function TABLE.search(t,val)
|
function TABLE.search(t,val)
|
||||||
for k,v in next,t do if v==val then return k end end
|
for k,v in next,t do if v==val then return k end end
|
||||||
@@ -104,6 +159,8 @@ function TABLE.reIndex(org)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
|
||||||
--Dump a simple lua table
|
--Dump a simple lua table
|
||||||
do--function TABLE.dump(L,t)
|
do--function TABLE.dump(L,t)
|
||||||
local tabs={
|
local tabs={
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ local TASK={}
|
|||||||
function TASK.getCount()
|
function TASK.getCount()
|
||||||
return #tasks
|
return #tasks
|
||||||
end
|
end
|
||||||
function TASK.update()
|
local trigFrame=0
|
||||||
|
function TASK.update(dt)
|
||||||
|
trigFrame=trigFrame+dt*60
|
||||||
|
while trigFrame>=1 do
|
||||||
for i=#tasks,1,-1 do
|
for i=#tasks,1,-1 do
|
||||||
local T=tasks[i]
|
local T=tasks[i]
|
||||||
if status(T.thread)=='dead'then
|
if status(T.thread)=='dead'then
|
||||||
@@ -15,10 +18,12 @@ function TASK.update()
|
|||||||
assert(resume(T.thread))
|
assert(resume(T.thread))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
trigFrame=trigFrame-1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
function TASK.new(code,...)
|
function TASK.new(code,...)
|
||||||
local thread=coroutine.create(code)
|
local thread=coroutine.create(code)
|
||||||
resume(thread,...)
|
assert(resume(thread,...))
|
||||||
if status(thread)~='dead'then
|
if status(thread)~='dead'then
|
||||||
tasks[#tasks+1]={
|
tasks[#tasks+1]={
|
||||||
thread=thread,
|
thread=thread,
|
||||||
|
|||||||
12
Zframework/test.lua
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
local TEST={}
|
||||||
|
|
||||||
|
--Wait for the scene swapping animation to finish
|
||||||
|
function TEST.yieldUntilNextScene()
|
||||||
|
while SCN.swapping do YIELD()end
|
||||||
|
end
|
||||||
|
|
||||||
|
function TEST.yieldN(frames)
|
||||||
|
for _=1,frames do YIELD()end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TEST
|
||||||
@@ -1,76 +1,99 @@
|
|||||||
local gc=love.graphics
|
local gc=love.graphics
|
||||||
local gc_getColor,gc_setColor,gc_push,gc_pop=gc.getColor,gc.setColor,gc.push,gc.pop
|
local getColor,setColor=gc.getColor,gc.setColor
|
||||||
local gc_translate,gc_scale,gc_rotate,gc_shear=gc.translate,gc.scale,gc.rotate,gc.shear
|
|
||||||
|
|
||||||
local int,rnd=math.floor,math.random
|
local int,rnd=math.floor,math.random
|
||||||
local ins,rem=table.insert,table.remove
|
local ins,rem=table.insert,table.remove
|
||||||
local setFont,mStr=setFont,mStr
|
local draw=gc.draw
|
||||||
|
|
||||||
local texts={}
|
local texts={}
|
||||||
|
|
||||||
local textFX={}
|
local textFX={}
|
||||||
function textFX.appear(t)
|
function textFX.appear(t)
|
||||||
mStr(t.text,t.x,t.y-t.font*.7)
|
draw(
|
||||||
|
t.text,t.x,t.y,
|
||||||
|
nil,
|
||||||
|
nil,nil,
|
||||||
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.sudden(t)
|
function textFX.sudden(t)
|
||||||
gc_setColor(1,1,1,1-t.c)
|
setColor(1,1,1,1-t.c)
|
||||||
mStr(t.text,t.x,t.y-t.font*.7)
|
draw(
|
||||||
|
t.text,t.x,t.y,
|
||||||
|
nil,
|
||||||
|
nil,nil,
|
||||||
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.fly(t)
|
function textFX.fly(t)
|
||||||
mStr(t.text,t.x+(t.c-.5)^3*300,t.y-t.font*.7)
|
draw(
|
||||||
|
t.text,t.x+(t.c-.5)^3*300,t.y,
|
||||||
|
nil,
|
||||||
|
nil,nil,
|
||||||
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.stretch(t)
|
function textFX.stretch(t)
|
||||||
gc_push('transform')
|
draw(
|
||||||
gc_translate(t.x,t.y)
|
t.text,t.x,t.y,
|
||||||
if t.c<.3 then gc_scale((.3-t.c)*1.6+1,1)end
|
nil,
|
||||||
mStr(t.text,0,-t.font*.7)
|
t.c<.3 and(.3-t.c)*1.6+1 or 1,1,
|
||||||
gc_pop()
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.drive(t)
|
function textFX.drive(t)
|
||||||
gc_push('transform')
|
draw(
|
||||||
gc_translate(t.x,t.y)
|
t.text,t.x,t.y,
|
||||||
if t.c<.3 then gc_shear((.3-t.c)*2,0)end
|
nil,
|
||||||
mStr(t.text,0,-t.font*.7)
|
nil,nil,
|
||||||
gc_pop()
|
t.text:getWidth()*.5,t.text:getHeight()*.5,
|
||||||
|
t.c<.3 and(.3-t.c)*2 or 0,0
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.spin(t)
|
function textFX.spin(t)
|
||||||
gc_push('transform')
|
draw(
|
||||||
gc_translate(t.x,t.y)
|
t.text,t.x,t.y,
|
||||||
if t.c<.3 then
|
t.c<.3 and(.3-t.c)^2*4 or t.c<.8 and 0 or(t.c-.8)^2*-4,
|
||||||
gc_rotate((.3-t.c)^2*4)
|
nil,nil,
|
||||||
elseif t.c>.8 then
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
gc_rotate((t.c-.8)^2*-4)
|
)
|
||||||
end
|
|
||||||
mStr(t.text,0,-t.font*.7)
|
|
||||||
gc_pop()
|
|
||||||
end
|
end
|
||||||
function textFX.flicker(t)
|
function textFX.flicker(t)
|
||||||
local _,_,_,T=gc_getColor()
|
local _,_,_,T=getColor()
|
||||||
gc_setColor(1,1,1,T*(rnd()+.5))
|
setColor(1,1,1,T*(rnd()+.5))
|
||||||
mStr(t.text,t.x,t.y-t.font*.7)
|
draw(
|
||||||
|
t.text,t.x,t.y,
|
||||||
|
nil,
|
||||||
|
nil,nil,
|
||||||
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
function textFX.zoomout(t)
|
function textFX.zoomout(t)
|
||||||
gc_push('transform')
|
draw(
|
||||||
local k=t.c^.5*.1+1
|
t.text,t.x,t.y,
|
||||||
gc_translate(t.x,t.y)
|
nil,
|
||||||
gc_scale(k,k)
|
t.c^.5*.1+1,nil,
|
||||||
mStr(t.text,0,-t.font*.7)
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
gc_pop()
|
)
|
||||||
end
|
end
|
||||||
function textFX.beat(t)
|
function textFX.beat(t)
|
||||||
gc_push('transform')
|
local k=t.c<.3 and 1.3-t.c^2/.3 or 1
|
||||||
gc_translate(t.x,t.y)
|
draw(
|
||||||
if t.c<.3 then
|
t.text,t.x,t.y,
|
||||||
local k=1.3-t.c^2/.3
|
nil,
|
||||||
gc_scale(k,k)
|
k,k,
|
||||||
end
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
mStr(t.text,0,-t.font*.7)
|
)
|
||||||
gc_pop()
|
|
||||||
end
|
end
|
||||||
function textFX.score(t)
|
function textFX.score(t)
|
||||||
local _,_,_,T=gc_getColor()
|
local _,_,_,T=getColor()
|
||||||
gc_setColor(1,1,1,T*.5)
|
setColor(1,1,1,T*.5)
|
||||||
mStr(t.text,t.x,t.y-t.font*.7-t.c^.2*50)
|
draw(
|
||||||
|
t.text,t.x,t.y-0-t.c^.2*50,
|
||||||
|
nil,
|
||||||
|
nil,nil,
|
||||||
|
t.text:getWidth()*.5,t.text:getHeight()*.5
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
local TEXT={}
|
local TEXT={}
|
||||||
@@ -80,32 +103,32 @@ end
|
|||||||
function TEXT.show(text,x,y,font,style,spd,stop)
|
function TEXT.show(text,x,y,font,style,spd,stop)
|
||||||
ins(texts,{
|
ins(texts,{
|
||||||
c=0, --Timer
|
c=0, --Timer
|
||||||
text=text, --String
|
text=gc.newText(FONT.get(int(font/5)*5 or 40),text), --String
|
||||||
x=x or 0, --X
|
x=x or 0, --X
|
||||||
y=y or 0, --Y
|
y=y or 0, --Y
|
||||||
font=int(font/5)*5 or 40, --Font
|
spd=(spd or 1), --Timing speed(1=last 1 sec)
|
||||||
spd=(spd or 1)/60, --Timing speed(1=last 1 sec)
|
|
||||||
stop=stop, --Stop time(sustained text)
|
stop=stop, --Stop time(sustained text)
|
||||||
draw=textFX[style or'appear']or error("unavailable type:"..style), --Draw method
|
draw=assert(textFX[style or'appear'],"no text type:"..style),--Draw method
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT.show(), but only return text object, need manual management
|
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT.show(), but only return text object, need manual management
|
||||||
return{
|
return{
|
||||||
c=0,
|
c=0,
|
||||||
text=text,
|
text=gc.newText(FONT.get(int(font/5)*5 or 40),text),
|
||||||
x=x or 0,
|
x=x or 0,
|
||||||
y=y or 0,
|
y=y or 0,
|
||||||
font=int(font/5)*5 or 40,
|
spd=(spd or 1),
|
||||||
spd=(spd or 1)/60,
|
|
||||||
stop=stop,
|
stop=stop,
|
||||||
draw=textFX[style or'appear']or error("unavailable type:"..style),
|
draw=textFX[style or'appear']or error("unavailable type:"..style),
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
function TEXT.update(list)
|
function TEXT.update(dt,list)
|
||||||
if not list then list=texts end
|
if not list then
|
||||||
|
list=texts
|
||||||
|
end
|
||||||
for i=#list,1,-1 do
|
for i=#list,1,-1 do
|
||||||
local t=list[i]
|
local t=list[i]
|
||||||
t.c=t.c+t.spd
|
t.c=t.c+t.spd*dt
|
||||||
if t.stop then
|
if t.stop then
|
||||||
if t.c>t.stop then
|
if t.c>t.stop then
|
||||||
t.c=t.stop
|
t.c=t.stop
|
||||||
@@ -117,12 +140,13 @@ function TEXT.update(list)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function TEXT.draw(list)
|
function TEXT.draw(list)
|
||||||
if not list then list=texts end
|
if not list then
|
||||||
|
list=texts
|
||||||
|
end
|
||||||
for i=1,#list do
|
for i=1,#list do
|
||||||
local t=list[i]
|
local t=list[i]
|
||||||
local p=t.c
|
local p=t.c
|
||||||
gc_setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
|
setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
|
||||||
setFont(t.font)
|
|
||||||
t:draw()
|
t:draw()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
local THEME={
|
|
||||||
cur=false,--Current theme
|
|
||||||
}
|
|
||||||
local themeColor={
|
|
||||||
xmas={COLOR.R,COLOR.Z,COLOR.G},
|
|
||||||
sprfes={COLOR.R,COLOR.O,COLOR.Y},
|
|
||||||
}
|
|
||||||
|
|
||||||
function THEME.calculate(Y,M,D)
|
|
||||||
if not Y then Y,M,D=os.date('%Y'),os.date('%m'),os.date('%d')end
|
|
||||||
--Festival calculate within one statement
|
|
||||||
return
|
|
||||||
--Christmas
|
|
||||||
M=='12'and math.abs(D-25)<4 and
|
|
||||||
'xmas'or
|
|
||||||
|
|
||||||
--Birthday
|
|
||||||
M=='06'and D=='06'and
|
|
||||||
'birth'or
|
|
||||||
|
|
||||||
--Spring festival
|
|
||||||
M<'03'and math.abs((({
|
|
||||||
--Festival days. Jan 26=26, Feb 1=32, etc.
|
|
||||||
24,43,32,22,40,29,49,38,26,45,
|
|
||||||
34,23,41,31,50,39,28,47,36,25,
|
|
||||||
43,32,22,41,29,48,37,26,44,34,
|
|
||||||
23,42,31,50,39,28,46,35,24,43,
|
|
||||||
32,22,41,30,48,37,26,45,33,23,
|
|
||||||
42,32,50,39,28,46,35,24,43,33,
|
|
||||||
21,40,
|
|
||||||
})[Y-2000]or -26)-((M-1)*31+D))<6 and
|
|
||||||
'sprfes'or
|
|
||||||
|
|
||||||
--April fool's day
|
|
||||||
M=='04'and D=='01'and
|
|
||||||
'fool'or
|
|
||||||
|
|
||||||
--Z day
|
|
||||||
D=='26'and(
|
|
||||||
(M=='01'or M=='02'or M=='03')and'zday1'or
|
|
||||||
(M=='04'or M=='05'or M=='06')and'zday2'or
|
|
||||||
(M=='07'or M=='08'or M=='09')and'zday3'or
|
|
||||||
(M=='10'or M=='11'or M=='12')and'zday4'
|
|
||||||
)or
|
|
||||||
|
|
||||||
'classic'
|
|
||||||
end
|
|
||||||
|
|
||||||
function THEME.set(theme)
|
|
||||||
if theme=='classic'then
|
|
||||||
BG.setDefault('space')
|
|
||||||
BGM.setDefault('nil')
|
|
||||||
elseif theme=='xmas'then
|
|
||||||
BG.setDefault('snow')
|
|
||||||
BGM.setDefault('xmas')
|
|
||||||
MES.new('info',"==Merry Christmas==")
|
|
||||||
elseif theme=='birth'then
|
|
||||||
BG.setDefault('firework')
|
|
||||||
BGM.setDefault('magicblock')
|
|
||||||
elseif theme=='sprfes'then
|
|
||||||
BG.setDefault('firework')
|
|
||||||
BGM.setDefault('spring festival')
|
|
||||||
MES.new('info',"★☆新年快乐☆★")
|
|
||||||
elseif theme=='zday1'then
|
|
||||||
BG.setDefault('lanterns')
|
|
||||||
BGM.setDefault('overzero')
|
|
||||||
elseif theme=='zday2'then
|
|
||||||
BG.setDefault('lanterns')
|
|
||||||
BGM.setDefault('vacuum')
|
|
||||||
elseif theme=='zday3'then
|
|
||||||
BG.setDefault('lanterns')
|
|
||||||
BGM.setDefault('empty')
|
|
||||||
elseif theme=='zday4'then
|
|
||||||
BG.setDefault('lanterns')
|
|
||||||
BGM.setDefault('space')
|
|
||||||
elseif theme=='fool'then
|
|
||||||
BG.setDefault('blockrain')
|
|
||||||
BGM.setDefault('how feeling')
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
THEME.cur=theme
|
|
||||||
BG.set()
|
|
||||||
BGM.play()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function THEME.getThemeColor(theme)
|
|
||||||
if not theme then theme=THEME.cur end
|
|
||||||
return themeColor[theme]
|
|
||||||
end
|
|
||||||
|
|
||||||
function THEME.fresh()
|
|
||||||
THEME.set(THEME.calculate(os.date('%Y'),os.date('%m'),os.date('%d')))
|
|
||||||
end
|
|
||||||
|
|
||||||
return THEME
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
local level={0,0,.01,.016,.023,.03,.04,.05,.06,.07,.08,.09,.12,.15}
|
local level={0,0,.01,.016,.023,.03,.04,.05,.06,.07,.08,.09,.12,.15}
|
||||||
local vib=love.system.vibrate
|
local vib=love.system.vibrate
|
||||||
return function(t)
|
return love.system.getOS()=='iOS'and
|
||||||
local L=SETTING.vib
|
function(t)
|
||||||
if L>0 then
|
t=level[t]
|
||||||
vib(level[L+t])
|
if t then vib(t<=.03 and 1 or t<=.09 and 2 or 3)end
|
||||||
end
|
end
|
||||||
|
or
|
||||||
|
function(t)
|
||||||
|
t=level[t]
|
||||||
|
if t then vib(t)end
|
||||||
end
|
end
|
||||||
@@ -1,29 +1,40 @@
|
|||||||
|
local rnd=math.random
|
||||||
|
local volume=1
|
||||||
|
local diversion=0
|
||||||
local VOC={
|
local VOC={
|
||||||
getCount=function()return 0 end,
|
getCount=function()return 0 end,
|
||||||
getQueueCount=function()return 0 end,
|
getQueueCount=function()return 0 end,
|
||||||
loadAll=function()error("Cannot load before init!")end,
|
load=function()error("Cannot load before init!")end,
|
||||||
getFreeChannel=NULL,
|
getFreeChannel=NULL,
|
||||||
play=NULL,
|
play=NULL,
|
||||||
update=NULL,
|
update=NULL,
|
||||||
}
|
}
|
||||||
|
function VOC.setDiversion(n)
|
||||||
|
assert(type(n)=='number'and n>0 and n<12,'Wrong div')
|
||||||
|
diversion=n
|
||||||
|
end
|
||||||
|
function VOC.setVol(v)
|
||||||
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
|
volume=v
|
||||||
|
end
|
||||||
function VOC.init(list)
|
function VOC.init(list)
|
||||||
VOC.init=nil
|
VOC.init=nil
|
||||||
local rnd=math.random
|
|
||||||
local rem=table.remove
|
local rem=table.remove
|
||||||
local voiceQueue={free=0}
|
local voiceQueue={free=0}
|
||||||
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
|
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
|
||||||
local Source={}
|
local Source={}
|
||||||
|
|
||||||
local count=#list function VOC.getCount()return count end
|
local count=#list function VOC.getCount()return count end
|
||||||
local function loadVoiceFile(N,vocName)
|
local function _loadVoiceFile(path,N,vocName)
|
||||||
local fileName='media/VOICE/'..SETTING.cv..'/'..vocName..'.ogg'
|
local fullPath=path..vocName..'.ogg'
|
||||||
if love.filesystem.getInfo(fileName)then
|
if love.filesystem.getInfo(fullPath)then
|
||||||
bank[vocName]={love.audio.newSource(fileName,'stream')}
|
bank[vocName]={love.audio.newSource(fullPath,'stream')}
|
||||||
table.insert(Source[N],vocName)
|
table.insert(Source[N],vocName)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function getVoice(str)
|
--Load voice with string
|
||||||
|
local function _getVoice(str)
|
||||||
local L=bank[str]
|
local L=bank[str]
|
||||||
local n=1
|
local n=1
|
||||||
while L[n]:isPlaying()do
|
while L[n]:isPlaying()do
|
||||||
@@ -35,21 +46,22 @@ function VOC.init(list)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L[n]
|
return L[n]
|
||||||
--Load voice with string
|
|
||||||
end
|
end
|
||||||
function VOC.loadAll()
|
function VOC.load(path)
|
||||||
for i=1,count do
|
for i=1,count do
|
||||||
Source[list[i]]={}
|
Source[list[i]]={}
|
||||||
|
|
||||||
local n=0
|
local n=0
|
||||||
repeat n=n+1 until not loadVoiceFile(list[i],list[i]..'_'..n)
|
repeat n=n+1 until not _loadVoiceFile(path,list[i],list[i]..'_'..n)
|
||||||
|
|
||||||
if n==1 then
|
if n==1 then
|
||||||
if not loadVoiceFile(list[i],list[i])then
|
if not _loadVoiceFile(path,list[i],list[i])then
|
||||||
MES.new('warn',"No VOICE file: "..list[i],.1)
|
LOG("No VOC: "..list[i],.1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not Source[list[i]][1]then Source[list[i]]=nil end
|
if not Source[list[i]][1]then
|
||||||
|
Source[list[i]]=nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function VOC.getQueueCount()
|
function VOC.getQueueCount()
|
||||||
@@ -65,7 +77,7 @@ function VOC.init(list)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function VOC.play(s,chn)
|
function VOC.play(s,chn)
|
||||||
if SETTING.voc>0 then
|
if volume>0 then
|
||||||
local _=Source[s]
|
local _=Source[s]
|
||||||
if not _ then return end
|
if not _ then return end
|
||||||
if chn then
|
if chn then
|
||||||
@@ -87,14 +99,16 @@ function VOC.init(list)
|
|||||||
rem(voiceQueue,i)
|
rem(voiceQueue,i)
|
||||||
end
|
end
|
||||||
elseif Q.s==1 then--Waiting load source
|
elseif Q.s==1 then--Waiting load source
|
||||||
Q[1]=getVoice(Q[1])
|
Q[1]=_getVoice(Q[1])
|
||||||
Q[1]:setVolume(SETTING.voc)
|
Q[1]:setVolume(volume)
|
||||||
|
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||||
Q[1]:play()
|
Q[1]:play()
|
||||||
Q.s=Q[2]and 2 or 4
|
Q.s=Q[2]and 2 or 4
|
||||||
elseif Q.s==2 then--Playing 1,ready 2
|
elseif Q.s==2 then--Playing 1,ready 2
|
||||||
if Q[1]:getDuration()-Q[1]:tell()<.08 then
|
if Q[1]:getDuration()-Q[1]:tell()<.08 then
|
||||||
Q[2]=getVoice(Q[2])
|
Q[2]=_getVoice(Q[2])
|
||||||
Q[2]:setVolume(SETTING.voc)
|
Q[2]:setVolume(volume)
|
||||||
|
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||||
Q[2]:play()
|
Q[2]:play()
|
||||||
Q.s=3
|
Q.s=3
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
local host=
|
local host=
|
||||||
-- '127.0.0.1'
|
-- '127.0.0.1'
|
||||||
-- '192.168.114.102'
|
-- '192.168.114.102'
|
||||||
'krakens.tpddns.cn'
|
'game.techmino.org'
|
||||||
-- 'game.techmino.org'
|
|
||||||
local port='10026'
|
local port='10026'
|
||||||
local path='/tech/socket/v1'
|
local path='/tech/socket/v1'
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ local readThread=coroutine.wrap(function()
|
|||||||
if op==8 then--8=close
|
if op==8 then--8=close
|
||||||
CHN_push(readCHN,8)--close
|
CHN_push(readCHN,8)--close
|
||||||
if type(res)=='string'then
|
if type(res)=='string'then
|
||||||
CHN_push(readCHN,res:sub(3))--Warning: 2 bytes close code at start so :sub(3)
|
CHN_push(readCHN,res:sub(3))--[Warning] 2 bytes close code at start so :sub(3)
|
||||||
else
|
else
|
||||||
CHN_push(readCHN,"WS closed")
|
CHN_push(readCHN,"WS closed")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
local love=love
|
local love=love
|
||||||
local max,min=math.max,math.min
|
local max,min=math.max,math.min
|
||||||
local float=0
|
local trigDist=0
|
||||||
return function(y,key1,key2)
|
return function(y,key1,key2)
|
||||||
if y>0 then
|
if y>0 then
|
||||||
float=max(float,0)+y^1.2
|
trigDist=max(trigDist,0)+y^1.2
|
||||||
elseif y<0 then
|
elseif y<0 then
|
||||||
if float>0 then float=0 end
|
if trigDist>0 then trigDist=0 end
|
||||||
float=min(float,0)-(-y)^1.2
|
trigDist=min(trigDist,0)-(-y)^1.2
|
||||||
end
|
end
|
||||||
while float>=1 do
|
while trigDist>=1 do
|
||||||
love.keypressed(key1 or"up")
|
love.keypressed(key1 or'up')
|
||||||
float=float-1
|
trigDist=trigDist-1
|
||||||
end
|
end
|
||||||
while float<=-1 do
|
while trigDist<=-1 do
|
||||||
love.keypressed(key2 or"down")
|
love.keypressed(key2 or'down')
|
||||||
float=float+1
|
trigDist=trigDist+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
1 VERSIONINFO
|
|
||||||
FILEVERSION @FileVersion
|
|
||||||
PRODUCTVERSION @FileVersion
|
|
||||||
FILEOS 0x40004
|
|
||||||
FILETYPE 0x1
|
|
||||||
{
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
{
|
|
||||||
BLOCK "040904B0"
|
|
||||||
{
|
|
||||||
VALUE "FileDescription", "Techmino Alpha"
|
|
||||||
VALUE "CompanyName", "26F Studio"
|
|
||||||
VALUE "LegalCopyright", "Copyright @ 26F Studio"
|
|
||||||
VALUE "ProductName", "Techmino"
|
|
||||||
VALUE "ProductVersion", "@Version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
{
|
|
||||||
VALUE "Translation", 0x0409 0x04E4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>BuildMachineOSBuild</key>
|
|
||||||
<string>19B88</string>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>English</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>love</string>
|
|
||||||
<key>CFBundleIconFile</key>
|
|
||||||
<string>iconfile</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>org.love2d.MrZ.Techmino</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>Techmino</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>APPL</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>@versionName</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>LoVe</string>
|
|
||||||
<key>CFBundleSupportedPlatforms</key>
|
|
||||||
<array>
|
|
||||||
<string>MacOSX</string>
|
|
||||||
</array>
|
|
||||||
<key>DTCompiler</key>
|
|
||||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
|
||||||
<key>DTPlatformBuild</key>
|
|
||||||
<string>11C504</string>
|
|
||||||
<key>DTPlatformVersion</key>
|
|
||||||
<string>GM</string>
|
|
||||||
<key>DTSDKBuild</key>
|
|
||||||
<string>19B90</string>
|
|
||||||
<key>DTSDKName</key>
|
|
||||||
<string>macosx10.15</string>
|
|
||||||
<key>DTXcode</key>
|
|
||||||
<string>1130</string>
|
|
||||||
<key>DTXcodeBuild</key>
|
|
||||||
<string>11C504</string>
|
|
||||||
<key>LSApplicationCategoryType</key>
|
|
||||||
<string>public.app-category.games</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>10.7</string>
|
|
||||||
<key>NSHighResolutionCapable</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSHumanReadableCopyright</key>
|
|
||||||
<string>©2020-@ThisYear 26F Studio, GNU LGPLv3.0</string>
|
|
||||||
<key>NSPrincipalClass</key>
|
|
||||||
<string>NSApplication</string>
|
|
||||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
1
conf.lua
@@ -11,7 +11,6 @@ function love.conf(t)
|
|||||||
|
|
||||||
local W=t.window
|
local W=t.window
|
||||||
W.title="Techmino "..require"version".string
|
W.title="Techmino "..require"version".string
|
||||||
W.icon="media/image/icon.png"
|
|
||||||
W.width,W.height=1280,720
|
W.width,W.height=1280,720
|
||||||
W.minwidth,W.minheight=640,360
|
W.minwidth,W.minheight=640,360
|
||||||
W.borderless=false
|
W.borderless=false
|
||||||
|
|||||||
@@ -1,158 +0,0 @@
|
|||||||
模式文件应当是一个合(语)法的lua程序文件,其必须返回一个table,里面的内容包括:
|
|
||||||
color:
|
|
||||||
必选
|
|
||||||
模式的颜色,用于点击地图图标后显示的提示文本
|
|
||||||
env:
|
|
||||||
必选
|
|
||||||
模式环境变量,决定了关卡的各项属性
|
|
||||||
*属性名* *默认值* *说明*
|
|
||||||
drop 60 下落延迟(帧,支持自然数和2的整数次幂)
|
|
||||||
lock 60 锁定延迟(帧)
|
|
||||||
wait 0 出块延迟(帧)
|
|
||||||
fall 0 消行延迟(帧)
|
|
||||||
bone false 是否开启骨块模式
|
|
||||||
fieldH 20 场地高度
|
|
||||||
heightLimit 1e99 允许的最大场地高度
|
|
||||||
nextCount 6 显示next个数
|
|
||||||
nextStartPos 1 next从第几个开始显示
|
|
||||||
holdCount 1 hold个数
|
|
||||||
infHold false 是否能无限hold
|
|
||||||
phyHold false 是否开启物理hold
|
|
||||||
ospin true 是否能O-spin
|
|
||||||
deepDrop false 是否开启深降
|
|
||||||
RS 'TRS' 旋转系统名
|
|
||||||
|
|
||||||
das 10 DAS
|
|
||||||
arr 2 ARR
|
|
||||||
sddas 2 软降DAS
|
|
||||||
sdarr 2 软降ARR
|
|
||||||
mindas 0 允许的最小DAS
|
|
||||||
minarr 0 允许的最小ARR
|
|
||||||
minsdarr 0 允许的最小软降ARR
|
|
||||||
ihs true 提前Hold
|
|
||||||
irs true 提前旋转
|
|
||||||
ims true 提前移动
|
|
||||||
|
|
||||||
skinSet [设置] 方块贴图,只能填写内置皮肤的名字
|
|
||||||
skin [设置] 方块颜色,包含25个整数(1~16)的table
|
|
||||||
face [设置] 方块朝向,包含25个整数(0~3)的table
|
|
||||||
|
|
||||||
block true 是否显示方块
|
|
||||||
ghost 0.3 影子透明度(0~1)
|
|
||||||
center 1 旋转中心透明度(0~1)
|
|
||||||
smooth false 是否平滑下落
|
|
||||||
grid 0.16 网格透明度(0~1)
|
|
||||||
bagLine true 是否显示包分界线(如果存在)
|
|
||||||
lockFX 2 锁定特效等级(0~5整数)
|
|
||||||
dropFX 2 瞬间下落特效等级(0~5整数)
|
|
||||||
moveFX 2 移动特效等级(0~5整数)
|
|
||||||
clearFX 2 消除特效等级(0~5整数)
|
|
||||||
splashFX 2 溅射特效等级(0~5整数)
|
|
||||||
shakeFX 2 晃动特效等级(0~5整数)
|
|
||||||
atkFX 2 攻击特效等级(0~5整数)
|
|
||||||
|
|
||||||
text true 是否显示消行文本
|
|
||||||
score true 是否显示落块分数
|
|
||||||
highCam false 是否开启超屏视野
|
|
||||||
nextPos false 是否开启生成预览
|
|
||||||
showSpike false 是否开启spike计数器
|
|
||||||
|
|
||||||
hideBoard false 场地隐藏模式("down"|"up"|"all")
|
|
||||||
flipBoard false 场地翻转模式("U-D"|"L-R"|"180")
|
|
||||||
|
|
||||||
sequence 'bag' 序列模式,是放一块后对next序列的刷新函数,可以使用默认的几个函数用字符串表示。也可以自己写一个,注意:使用协程技术
|
|
||||||
seqData {1,2,3,4,5,6,7}序列模式使用的"包"数据(本质是生成序列用的数据,会作为参数传进上面那个叫sequence的序列生成函数,不一定是包)
|
|
||||||
mission false 包含任务的table,说明暂时略
|
|
||||||
|
|
||||||
life 0 生命数(复活次数)
|
|
||||||
garbageSpeed 1 垃圾行释放速度
|
|
||||||
pushSpeed 3 垃圾行上涨速度
|
|
||||||
noTele false 是否禁止10个高级按键
|
|
||||||
visible 'show' 方块可见性,填写固定的几个字符串
|
|
||||||
freshLimit 1e99 锁延刷新次数限制
|
|
||||||
easyFresh true 是否使用简单锁延刷新规则
|
|
||||||
bufferLimit 1e99 攻击缓冲行数上限
|
|
||||||
|
|
||||||
fkey1 false 按下功能键1后执行的函数
|
|
||||||
fkey2 false 按下功能键2后执行的函数
|
|
||||||
keyCancel {} 包含禁止使用的按键的id,例如{1,2}就是禁止左移和右移
|
|
||||||
fine [设置] 是否开启非极简提示音
|
|
||||||
fineKill false 是否开启非极简即死
|
|
||||||
b2bKill false 是否开启断b2b即死
|
|
||||||
missionKill false 是否开启强制任务
|
|
||||||
dropPiece NULL 放一块后要执行的函数,输入玩家对象
|
|
||||||
task NULL 每帧会*继续执行*的函数,输入玩家对象,注意:使用协程技术
|
|
||||||
noInitSZO false 是否禁止SZO块开局,如果禁止,开局序列会自动跳过最多连续五个SZO
|
|
||||||
|
|
||||||
bg 'none' 背景,只能填写内置背景的名字
|
|
||||||
bgm 'race' 背景音乐名(或者列表随机,例如{'race','push'}),只能用内置音乐库的音乐名
|
|
||||||
allowMod true 是否允许mod
|
|
||||||
load:
|
|
||||||
必选
|
|
||||||
模式初始化函数,一般创建一个玩家即可
|
|
||||||
无输入
|
|
||||||
无输出
|
|
||||||
mesDisp:
|
|
||||||
必选
|
|
||||||
模式显示信息,是一个绘图函数,坐标系原点是玩家对象最左上角
|
|
||||||
输入玩家对象
|
|
||||||
无输出
|
|
||||||
|
|
||||||
score:
|
|
||||||
可选(不填就没有分数保存和计算)
|
|
||||||
一局打完后要存储的数据
|
|
||||||
输入玩家对象
|
|
||||||
输出游戏结束瞬间返回一个包含直接决定该模式成绩的数据table(会被强制加上date标签)
|
|
||||||
|
|
||||||
scoreDisp:
|
|
||||||
可选(模式不出现在地图上的时候不用写)
|
|
||||||
是把score()存起来的table转换为字符串显示出来的函数
|
|
||||||
输入一个成绩table
|
|
||||||
输出一个字符串
|
|
||||||
|
|
||||||
comp:
|
|
||||||
可选(没有score函数的时候不用写)
|
|
||||||
是成绩table之间对比并排序的规则
|
|
||||||
输入两个成绩table
|
|
||||||
输出[第一个是不是排在第二个前面]的布尔值(可以类比"小于"运算)
|
|
||||||
|
|
||||||
getRank:
|
|
||||||
可选,模式评级函数
|
|
||||||
是用于评价玩家表现的函数
|
|
||||||
输入玩家对象
|
|
||||||
输出0~5,0表示除了记录到排行榜外什么都不做;1/2/3/4/5表示D/C/B/A/S级,能解锁连接的模式,还会让模式图标在地图上显示不同的颜色
|
|
||||||
|
|
||||||
以下是40行的模式文件内容:
|
|
||||||
//sprint_40l.lua
|
|
||||||
return{--返回一个table,你也可以在之前定义一些常量或者函数什么的
|
|
||||||
color=COLOR.green,--颜色
|
|
||||||
env={--模式环境变量
|
|
||||||
drop=60,lock=60,
|
|
||||||
dropPiece=function(P)if P.stat.row>=40 then P win('finish')end end,
|
|
||||||
bg='bg2',bgm='race',
|
|
||||||
},
|
|
||||||
load=function()--模式加载函数,这里只生成了一个玩家,常用的单人模式可以不写,默认使用这个函数
|
|
||||||
PLY.newPlayer(1)--1是玩家编号,默认用户控制1号玩家
|
|
||||||
end,
|
|
||||||
mesDisp=function(P)--40行模式需要显示的信息
|
|
||||||
setFont(55)
|
|
||||||
local r=40-P.stat.row
|
|
||||||
if r<0 then r=0 end
|
|
||||||
mStr(r,63,265)--把计算出来的剩余行数r显示出来
|
|
||||||
PLY.draw.drawTargetLine(P,r)--使用自带的境界高度线绘制函数
|
|
||||||
end,
|
|
||||||
score=function(P)return{P.stat.time,P.stat.piece}end,--游戏结束时需要保存的本局关键信息
|
|
||||||
scoreDisp=function(D)return STRING.time(D[1]).." "..D[2].." Pieces"end,--把score返回的数据显示出来的方法
|
|
||||||
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,--按照时间排序,时间一样就看块数
|
|
||||||
getRank=function(P)--计算评级
|
|
||||||
if P.stat.row<40 then return end--你总得打完40行对吧,否则直接return空掉,成绩都不记录
|
|
||||||
local T=P.stat.time
|
|
||||||
return
|
|
||||||
T<=26 and 5 or--时间小于等于26秒就是S级要求
|
|
||||||
T<=32.6 and 4 or--A级要求
|
|
||||||
T<=52.6 and 3 or--B级要求
|
|
||||||
T<=92.9 and 2 or--C级要求
|
|
||||||
T<=183 and 1 or--D级要求,解锁别的模式的最低标准
|
|
||||||
0--记录成绩的最低标准
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
以下是Techmino使用/将要使用/未来也许会使用的语音文件, 每一个都可以录任意多条
|
|
||||||
有多个文件的语音在播放时会随机挑选一个播放, 所以组合性的语音大概率不能随意发挥, 不然和其他组合起来可能就会出现奇怪的现象
|
|
||||||
|
|
||||||
例如多个mini语音文件名: mini_1.ogg, mini_2.ogg, ......
|
|
||||||
如果只有一个, "_1"可以省略, 但是多个文件的数字不能跳跃
|
|
||||||
|
|
||||||
要投稿语音包的话如果没有经过后期处理, 建议使用wav格式;
|
|
||||||
如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小)
|
|
||||||
|
|
||||||
目前游戏内正在使用, 必须录制的音频文件名们:
|
|
||||||
single, double, triple, techrash (读作\'tekrʌʃ\)
|
|
||||||
以上直接念就可以,用于普通直接消行
|
|
||||||
|
|
||||||
mini, b2b, b2b2b
|
|
||||||
以上直接念就可以,用于组合进spin消除
|
|
||||||
注: b2b读作back to back
|
|
||||||
|
|
||||||
[各种spin消除]
|
|
||||||
以上的每一个都要衍生出数条语音,例如zpin的是这五条:
|
|
||||||
z-spin (用于不消行)
|
|
||||||
z-spin single
|
|
||||||
z-spin double
|
|
||||||
z-spin triple
|
|
||||||
(z-spin techrash)
|
|
||||||
(z-spin pentacrash)
|
|
||||||
(z-spin hexacrash)
|
|
||||||
对于 S L J T O I 每一个都是这样至少四条语音
|
|
||||||
加括号一般不用所以可以不录(消5和消6),
|
|
||||||
另:对于P, Q, F, E, U, V, W, X, R, Y, N, H
|
|
||||||
这些方块也可以有上面那些语音,但由于仅在五连块使用还会显著增加语音包体积, 所以不录也可以
|
|
||||||
|
|
||||||
perfect_clear, half_clear
|
|
||||||
这俩可以直接念也可以略做修改
|
|
||||||
|
|
||||||
win, lose, bye
|
|
||||||
这几个可以自由发挥, 能用在三个场合就行,尽量不要太长
|
|
||||||
|
|
||||||
test, happy, doubt, sad, egg
|
|
||||||
这几个是特殊音效,具体使用情况不定
|
|
||||||
第一个是测试音量用的音效,尽量短一点,长度在半秒内
|
|
||||||
其他是彩蛋音效(不录也行, 反正一般不会触发)
|
|
||||||
|
|
||||||
welcome_voc
|
|
||||||
进入游戏播放的欢迎语音(类似osu)
|
|
||||||
|
|
||||||
目前没有用到但是将要加入的:
|
|
||||||
split
|
|
||||||
|
|
||||||
未来可能加入的:
|
|
||||||
暂无
|
|
||||||
51
legals.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
TECHMINO © 2019-2021 26F Studio. Some rights reserved.
|
||||||
|
|
||||||
|
TECHMINO and "26F Studio" are trademarks of 26F Studio. The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
|
||||||
|
|
||||||
|
|
||||||
|
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc. TECHMINO is not a fan game of Tetris. TECHMINO and 26F Studio are not affiliated with Tetris Holding, LLC or The Tetris Company, Inc. in any way.
|
||||||
|
|
||||||
|
|
||||||
|
Powered by LÖVE, © 2006-2021 LÖVE Development Team.
|
||||||
|
|
||||||
|
Lua is free software distributed under the terms of the MIT license. Copyright © 1994-2021 by Lua.org, PUC-Rio.
|
||||||
|
|
||||||
|
SIMPLE LOVE LIGHTS is under a MIT License. Created by Dylan Hunn.
|
||||||
|
|
||||||
|
json.lua is copyrighted by rxi. © 2021 rxi.
|
||||||
|
|
||||||
|
IBM Plex is copyrighted by the International Business Machines Corporation. IBM and IBM Plex are trademarks of IBM Corp, registered in many jurisdictions worldwide. IBM Plex is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
|
||||||
|
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Adobe are registered trademarks of Adobe Inc. in United States and other countries or regions. Source Han Sans is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
|
||||||
|
JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains Mono is a trademark of JetBrains s.r.o. JetBrains Mono is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
|
||||||
|
"PlayStation", "PS", "PlayStation Family Mark", "PS logo", "DualSense" and "Play Has No Limits" are registered trademarks or trademarks of Sony Interactive Entertainment Inc. "SONY" is a registered trademark of Sony Corporation. © 2021 Sony Interactive Entertainment LLC.
|
||||||
|
|
||||||
|
|
||||||
|
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
|
||||||
|
|
||||||
|
|
||||||
|
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
|
||||||
|
|
||||||
|
|
||||||
|
"EA" and "Electronic Arts" are registered trademarks of Electronic Arts Inc. © 2021 Electronic Arts Inc.
|
||||||
|
|
||||||
|
SEGA and the SEGA logo are registered trademarks of Sega Corporation. © 2021 Sega Corporation.
|
||||||
|
|
||||||
|
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Meta Platforms, Inc.
|
||||||
|
|
||||||
|
"Nintendo" is a registered trademarks of Nintendo Co., Ltd. © 2021 Nintendo Co., Ltd.
|
||||||
|
|
||||||
|
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
|
||||||
|
|
||||||
|
GoldWave is a registered trademark of GoldWave, Inc.
|
||||||
|
|
||||||
|
Linux is a registered trademark of Linus Torvalds.
|
||||||
|
|
||||||
|
Touhou Project © Team Shanghai Alice 2002-2021.
|
||||||
|
|
||||||
|
All other trademarks, logos, and copyrights are the properties of their respective owners.
|
||||||
165
license.txt
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
473
main.lua
@@ -23,11 +23,14 @@ local fs=love.filesystem
|
|||||||
VERSION=require"version"
|
VERSION=require"version"
|
||||||
TIME=love.timer.getTime
|
TIME=love.timer.getTime
|
||||||
YIELD=coroutine.yield
|
YIELD=coroutine.yield
|
||||||
SYSTEM=love.system.getOS()
|
SYSTEM=love.system.getOS()if SYSTEM=='OS X'then SYSTEM='macOS'end
|
||||||
|
FNNS=SYSTEM:find'\79\83'--What does FNSF stand for? IDK so don't ask me lol
|
||||||
MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
|
MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
|
||||||
SAVEDIR=fs.getSaveDirectory()
|
SAVEDIR=fs.getSaveDirectory()
|
||||||
|
|
||||||
--Global Vars & Settings
|
--Global Vars & Settings
|
||||||
|
SFXPACKS={'chiptune'}
|
||||||
|
VOCPACKS={'miya',--[['mono',]]'xiaoya','miku'}
|
||||||
FIRSTLAUNCH=false
|
FIRSTLAUNCH=false
|
||||||
DAILYLAUNCH=false
|
DAILYLAUNCH=false
|
||||||
|
|
||||||
@@ -36,16 +39,54 @@ math.randomseed(os.time()*626)
|
|||||||
love.setDeprecationOutput(false)
|
love.setDeprecationOutput(false)
|
||||||
love.keyboard.setKeyRepeat(true)
|
love.keyboard.setKeyRepeat(true)
|
||||||
love.keyboard.setTextInput(false)
|
love.keyboard.setTextInput(false)
|
||||||
love.mouse.setVisible(false)
|
if MOBILE then
|
||||||
if SYSTEM=='Android'or SYSTEM=='iOS'then
|
|
||||||
local w,h,f=love.window.getMode()
|
local w,h,f=love.window.getMode()
|
||||||
f.resizable=false
|
f.resizable=false
|
||||||
love.window.setMode(w,h,f)
|
love.window.setMode(w,h,f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local _LOADTIMELIST_={}
|
||||||
|
local _LOADTIME_=TIME()
|
||||||
|
|
||||||
--Load modules
|
--Load modules
|
||||||
require'Zframework'
|
Z=require'Zframework'
|
||||||
|
FONT.load{
|
||||||
|
norm='parts/fonts/proportional.ttf',
|
||||||
|
mono='parts/fonts/monospaced.ttf',
|
||||||
|
}
|
||||||
|
FONT.setDefault('norm')
|
||||||
|
FONT.setFallback('norm')
|
||||||
|
|
||||||
SCR.setSize(1280,720)--Initialize Screen size
|
SCR.setSize(1280,720)--Initialize Screen size
|
||||||
|
BGM.setMaxSources(5)
|
||||||
|
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
|
||||||
|
VOC.setDiversion(.62)
|
||||||
|
|
||||||
|
WIDGET.setOnChange(function()
|
||||||
|
if SCN.cur~='custom_field'then
|
||||||
|
local colorList=THEME.getThemeColor()
|
||||||
|
if not colorList then return end
|
||||||
|
local rnd=math.random
|
||||||
|
for _,W in next,SCN.scenes[SCN.cur].widgetList do
|
||||||
|
if W.color then
|
||||||
|
W.color=colorList[rnd(#colorList)]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
|
--Create shortcuts
|
||||||
|
setFont=FONT.set
|
||||||
|
getFont=FONT.get
|
||||||
|
mStr=GC.mStr
|
||||||
|
mText=GC.simpX
|
||||||
|
mDraw=GC.draw
|
||||||
|
Snd=SFX.playSample
|
||||||
|
string.repD=STRING.repD
|
||||||
|
string.sArg=STRING.sArg
|
||||||
|
string.split=STRING.split
|
||||||
|
|
||||||
--Delete all naked files (from too old version)
|
--Delete all naked files (from too old version)
|
||||||
FILE.clear('')
|
FILE.clear('')
|
||||||
@@ -61,20 +102,21 @@ for _,v in next,{'conf','record','replay','cache','lib'}do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CHAR=require'parts.char'
|
||||||
|
require'parts.gameTables'
|
||||||
|
require'parts.gameFuncs'
|
||||||
|
|
||||||
--Load shader files from SOURCE ONLY
|
--Load shader files from SOURCE ONLY
|
||||||
SHADER={}
|
SHADER={}
|
||||||
for _,v in next,fs.getDirectoryItems('parts/shaders')do
|
for _,v in next,fs.getDirectoryItems('parts/shaders')do
|
||||||
if fs.getRealDirectory('parts/shaders/'..v)~=SAVEDIR then
|
if isSafeFile('parts/shaders/'..v)then
|
||||||
local name=v:sub(1,-6)
|
local name=v:sub(1,-6)
|
||||||
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
|
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require'parts.list'
|
THEME= require'parts.theme'
|
||||||
require'parts.globalTables'
|
LINE= require'parts.line'
|
||||||
require'parts.gametoolfunc'
|
|
||||||
|
|
||||||
FREEROW= require'parts.freeRow'
|
|
||||||
DATA= require'parts.data'
|
DATA= require'parts.data'
|
||||||
|
|
||||||
TEXTURE= require'parts.texture'
|
TEXTURE= require'parts.texture'
|
||||||
@@ -82,23 +124,119 @@ SKIN= require'parts.skin'
|
|||||||
USERS= require'parts.users'
|
USERS= require'parts.users'
|
||||||
NET= require'parts.net'
|
NET= require'parts.net'
|
||||||
VK= require'parts.virtualKey'
|
VK= require'parts.virtualKey'
|
||||||
AIFUNC= require'parts.ai'
|
BOT= require'parts.bot'
|
||||||
AIBUILDER= require'parts.AITemplate'
|
|
||||||
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
|
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
|
||||||
PLY= require'parts.player'
|
PLY= require'parts.player'
|
||||||
netPLY= require'parts.netPlayer'
|
NETPLY= require'parts.netPlayer'
|
||||||
MODES= require'parts.modes'
|
MODETREE= require'parts.modeTree'
|
||||||
|
|
||||||
|
setmetatable(TEXTURE,{__index=function(self,k)
|
||||||
|
MES.new('warn',"No texture called: "..k)
|
||||||
|
self[k]=PAPER
|
||||||
|
return self[k]
|
||||||
|
end})
|
||||||
|
|
||||||
|
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
|
--Init Zframework
|
||||||
|
do--Z.setCursor
|
||||||
|
local normImg=GC.DO{16,16,
|
||||||
|
{'fCirc',8,8,4},
|
||||||
|
{'setCL',1,1,1,.7},
|
||||||
|
{'fCirc',8,8,6},
|
||||||
|
}
|
||||||
|
local holdImg=GC.DO{16,16,
|
||||||
|
{'setLW',2},
|
||||||
|
{'dCirc',8,8,7},
|
||||||
|
{'fCirc',8,8,3},
|
||||||
|
}
|
||||||
|
local min,int,abs=math.min,math.floor,math.abs
|
||||||
|
local gc_setColor,gc_draw=love.graphics.setColor,love.graphics.draw
|
||||||
|
local ms=love.mouse
|
||||||
|
Z.setCursor(function(time,x,y)
|
||||||
|
if not SETTING.sysCursor then
|
||||||
|
local R=int((time+1)/2)%7+1
|
||||||
|
_=BLOCK_COLORS[SETTING.skin[R]]
|
||||||
|
gc_setColor(_[1],_[2],_[3],min(abs(1-time%2),.3))
|
||||||
|
_=DSCP[R][0]
|
||||||
|
gc_draw(TEXTURE.miniBlock[R],x,y,time%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
|
||||||
|
gc_setColor(1,1,1)
|
||||||
|
gc_draw(ms.isDown(1)and holdImg or normImg,x,y,nil,nil,nil,8,8)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
Z.setOnFnKeys({
|
||||||
|
function()MES.new('check',PROFILE.switch()and"profile start!"or"profile report copied!")end,
|
||||||
|
function()MES.new('info',("System:%s[%s]\nluaVer:%s\njitVer:%s\njitVerNum:%s"):format(SYSTEM,jit.arch,_VERSION,jit.version,jit.version_num))end,
|
||||||
|
function()MES.new('error',"挂了")end,
|
||||||
|
function()
|
||||||
|
if GAME.playing and not GAME.net then
|
||||||
|
for _=1,8 do
|
||||||
|
if #PLY_ALIVE>1 then
|
||||||
|
local P=PLY_ALIVE[math.random(2,#PLY_ALIVE)]
|
||||||
|
P.lastRecv=PLAYERS[1]
|
||||||
|
P:lose()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
function()print(WIDGET.getSelected()or"no widget selected")end,
|
||||||
|
function()for k,v in next,_G do print(k,v)end end,
|
||||||
|
function()if love['_openConsole']then love['_openConsole']()end end,
|
||||||
|
})
|
||||||
|
Z.setOnResize(function(w,_)
|
||||||
|
SHADER.warning:send('w',w*SCR.dpi)
|
||||||
|
end)
|
||||||
|
do--Z.setOnFocus
|
||||||
|
local function task_autoSoundOff()
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
local v=love.audio.getVolume()
|
||||||
|
love.audio.setVolume(math.max(v-.05,0))
|
||||||
|
if v==0 then return end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function task_autoSoundOn()
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
local v=love.audio.getVolume()
|
||||||
|
if v<SETTING.mainVol then
|
||||||
|
love.audio.setVolume(math.min(v+.05,SETTING.mainVol,1))
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Z.setOnFocus(function(f)
|
||||||
|
if f then
|
||||||
|
love.timer.step()
|
||||||
|
if SETTING.autoMute then
|
||||||
|
TASK.removeTask_code(task_autoSoundOff)
|
||||||
|
TASK.new(task_autoSoundOn)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if SCN.cur=='game'and SETTING.autoPause then
|
||||||
|
pauseGame()
|
||||||
|
end
|
||||||
|
if SETTING.autoMute then
|
||||||
|
TASK.removeTask_code(task_autoSoundOn)
|
||||||
|
TASK.new(task_autoSoundOff)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
Z.setOnQuit(destroyPlayers)
|
||||||
|
|
||||||
--Load settings and statistics
|
--Load settings and statistics
|
||||||
TABLE.cover(FILE.load('conf/user')or{},USER)
|
TABLE.cover (loadFile('conf/user','-canSkip')or{},USER)
|
||||||
TABLE.cover(FILE.load('conf/unlock')or{},RANKS)
|
TABLE.cover (loadFile('conf/unlock','-canSkip')or{},RANKS)
|
||||||
TABLE.update(FILE.load('conf/settings')or{},SETTING)
|
TABLE.update(loadFile('conf/settings','-canSkip')or{},SETTING)
|
||||||
TABLE.update(FILE.load('conf/data')or{},STAT)
|
TABLE.coverR(loadFile('conf/data','-canSkip')or{},STAT)
|
||||||
TABLE.cover(FILE.load('conf/key')or{},keyMap)
|
TABLE.cover (loadFile('conf/key','-canSkip')or{},KEY_MAP)
|
||||||
TABLE.cover(FILE.load('conf/virtualkey')or{},VK_org)
|
TABLE.cover (loadFile('conf/virtualkey','-json -canSkip')or{},VK_ORG)
|
||||||
|
|
||||||
--Initialize fields, sequence, missions, gameEnv for cutsom game
|
--Initialize fields, sequence, missions, gameEnv for cutsom game
|
||||||
local fieldData=FILE.load('conf/customBoards')
|
local fieldData=loadFile('conf/customBoards','-string -canSkip')
|
||||||
if fieldData then
|
if fieldData then
|
||||||
fieldData=STRING.split(fieldData,"!")
|
fieldData=STRING.split(fieldData,"!")
|
||||||
for i=1,#fieldData do
|
for i=1,#fieldData do
|
||||||
@@ -107,12 +245,18 @@ if fieldData then
|
|||||||
else
|
else
|
||||||
FIELD[1]=DATA.newBoard()
|
FIELD[1]=DATA.newBoard()
|
||||||
end
|
end
|
||||||
local sequenceData=FILE.load('conf/customSequence')
|
local sequenceData=loadFile('conf/customSequence','-string -canSkip')
|
||||||
if sequenceData then DATA.pasteSequence(sequenceData)end
|
if sequenceData then
|
||||||
local missionData=FILE.load('conf/customMissions')
|
DATA.pasteSequence(sequenceData)
|
||||||
if missionData then DATA.pasteMission(missionData)end
|
end
|
||||||
local customData=FILE.load('conf/customEnv')
|
local missionData=loadFile('conf/customMissions','-string -canSkip')
|
||||||
if customData and customData.version==VERSION.code then TABLE.complete(customData,CUSTOMENV)end
|
if missionData then
|
||||||
|
DATA.pasteMission(missionData)
|
||||||
|
end
|
||||||
|
local customData=loadFile('conf/customEnv','-canSkip')
|
||||||
|
if customData and customData['version']==VERSION.code then
|
||||||
|
TABLE.complete(customData,CUSTOMENV)
|
||||||
|
end
|
||||||
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
||||||
|
|
||||||
|
|
||||||
@@ -127,14 +271,18 @@ IMG.init{
|
|||||||
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
|
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
|
||||||
pay1='media/image/mess/pay1.png',
|
pay1='media/image/mess/pay1.png',
|
||||||
pay2='media/image/mess/pay2.png',
|
pay2='media/image/mess/pay2.png',
|
||||||
|
drought='media/image/mess/drought.png',
|
||||||
|
|
||||||
miyaCH='media/image/characters/miya.png',
|
miyaCH1='media/image/characters/miya1.png',
|
||||||
miyaF1='media/image/characters/miya_f1.png',
|
miyaCH2='media/image/characters/miya2.png',
|
||||||
miyaF2='media/image/characters/miya_f2.png',
|
miyaCH3='media/image/characters/miya3.png',
|
||||||
miyaF3='media/image/characters/miya_f3.png',
|
miyaCH4='media/image/characters/miya4.png',
|
||||||
miyaF4='media/image/characters/miya_f4.png',
|
miyaHeart='media/image/characters/miya_heart.png',
|
||||||
nakiCH='media/image/characters/nakiharu.png',
|
miyaGlow='media/image/characters/miya_glow.png',
|
||||||
|
monoCH='media/image/characters/mono.png',
|
||||||
xiaoyaCH='media/image/characters/xiaoya.png',
|
xiaoyaCH='media/image/characters/xiaoya.png',
|
||||||
|
xiaoyaOmino='media/image/characters/xiaoya_Omino.png',
|
||||||
|
mikuCH='media/image/characters/miku.png',
|
||||||
electric='media/image/characters/electric.png',
|
electric='media/image/characters/electric.png',
|
||||||
hbm='media/image/characters/hbm.png',
|
hbm='media/image/characters/hbm.png',
|
||||||
|
|
||||||
@@ -147,9 +295,10 @@ IMG.init{
|
|||||||
'media/image/lanterns/6.png',
|
'media/image/lanterns/6.png',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
SKIN.init{
|
SKIN.load{
|
||||||
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
|
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
|
||||||
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
|
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
|
||||||
|
{name="shiny_chno",path='media/image/skin/shiny_chno.png'},
|
||||||
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
|
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
|
||||||
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
|
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
|
||||||
{name="toy_scf",path='media/image/skin/toy_scf.png'},
|
{name="toy_scf",path='media/image/skin/toy_scf.png'},
|
||||||
@@ -172,100 +321,103 @@ SKIN.init{
|
|||||||
{name="classic",path='media/image/skin/classic_unknown.png'},
|
{name="classic",path='media/image/skin/classic_unknown.png'},
|
||||||
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
|
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
|
||||||
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
|
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
|
||||||
|
{name="pixel_chno",path='media/image/skin/pixel_chno.png'},
|
||||||
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
|
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
|
||||||
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
|
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
|
||||||
{name="wtf",path='media/image/skin/wtf_mrz.png'},
|
{name="wtf",path='media/image/skin/wtf_mrz.png'},
|
||||||
}
|
}
|
||||||
|
|
||||||
--Initialize sound libs
|
--Initialize sound libs
|
||||||
SFX.init((function()
|
SFX.init((function()--[Warning] Not loading files here, just get the list of sound needed
|
||||||
local L={}
|
local L={}
|
||||||
for _,v in next,fs.getDirectoryItems('media/SFX')do
|
for _,v in next,fs.getDirectoryItems('media/effect/chiptune/')do
|
||||||
if fs.getRealDirectory('media/SFX/'..v)~=SAVEDIR then
|
if isSafeFile('media/effect/chiptune/'..v,"Dangerous file : %SAVE%/media/effect/chiptune/"..v)then
|
||||||
table.insert(L,v:sub(1,-5))
|
table.insert(L,v:sub(1,-5))
|
||||||
else
|
|
||||||
MES.new('warn',"Dangerous file : %SAVE%/media/SFX/"..v)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L
|
return L
|
||||||
end)())
|
end)())
|
||||||
BGM.init((function()
|
BGM.load((function()
|
||||||
local L={}
|
local L={}
|
||||||
for _,v in next,fs.getDirectoryItems('media/BGM')do
|
for _,v in next,fs.getDirectoryItems('media/music')do
|
||||||
if fs.getRealDirectory('media/BGM/'..v)~=SAVEDIR then
|
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
|
||||||
table.insert(L,{name=v:sub(1,-5),path='media/BGM/'..v})
|
L[v:sub(1,-5)]='media/music/'..v
|
||||||
else
|
|
||||||
MES.new('warn',"Dangerous file : %SAVE%/media/BGM/"..v)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L
|
return L
|
||||||
end)())
|
end)())
|
||||||
VOC.init{
|
VOC.init{
|
||||||
'zspin','sspin','lspin','jspin','tspin','ospin','ispin',
|
'zspin','sspin','jspin','lspin','tspin','ospin','ispin','pspin','qspin','fspin','espin','uspin','vspin','wspin','xspin','rspin','yspin','nspin','hspin','cspin',
|
||||||
'single','double','triple','techrash',
|
'single','double','triple','techrash','pentacrash','hexacrash',
|
||||||
'mini','b2b','b3b',
|
'mini','b2b','b3b',
|
||||||
'perfect_clear','half_clear',
|
'perfect_clear','half_clear',
|
||||||
'win','lose','bye',
|
'win','lose','bye',
|
||||||
'test','happy','doubt','sad','egg',
|
'test','happy','doubt',
|
||||||
'welcome_voc',
|
'welcome',
|
||||||
}
|
}
|
||||||
|
|
||||||
--Initialize language lib
|
--Initialize language lib
|
||||||
LANG.init(
|
LANG.init('zh',
|
||||||
{
|
{
|
||||||
require'parts.language.lang_zh',
|
zh=require'parts.language.lang_zh',
|
||||||
require'parts.language.lang_zh2',
|
zh_trad=require'parts.language.lang_zh_trad',
|
||||||
require'parts.language.lang_yygq',
|
zh_full=require'parts.language.lang_zh_full',
|
||||||
require'parts.language.lang_en',
|
en=require'parts.language.lang_en',
|
||||||
require'parts.language.lang_fr',
|
fr=require'parts.language.lang_fr',
|
||||||
require'parts.language.lang_es',
|
es=require'parts.language.lang_es',
|
||||||
require'parts.language.lang_pt',
|
pt=require'parts.language.lang_pt',
|
||||||
require'parts.language.lang_symbol',
|
id=require'parts.language.lang_id',
|
||||||
|
zh_grass=require'parts.language.lang_zh_grass',
|
||||||
|
zh_yygq=require'parts.language.lang_yygq',
|
||||||
|
symbol=require'parts.language.lang_symbol',
|
||||||
--1. Add language file to LANG folder;
|
--1. Add language file to LANG folder;
|
||||||
--2. Require it;
|
--2. Require it;
|
||||||
--3. Add a button in parts/scenes/setting_lang.lua;
|
--3. Add a button in parts/scenes/lang.lua;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
block={
|
block=BLOCK_NAMES
|
||||||
"Z","S","J","L","T","O","I",
|
|
||||||
"Z5","S5","Q","P","F","E",
|
|
||||||
"T5","U","V","W","X",
|
|
||||||
"J5","L5","R","Y","N","H","I5",
|
|
||||||
"I3","C","I2","O1"
|
|
||||||
},
|
},
|
||||||
}
|
(function()
|
||||||
|
local tipMeta={__call=function(L)return L[math.random(#L)]end}
|
||||||
|
return function(L)
|
||||||
|
if type(rawget(L,'getTip'))=='table'then setmetatable(L.getTip,tipMeta)end
|
||||||
|
setmetatable(L,{__index=function(self,k)
|
||||||
|
local mes="No Text ("..SETTING.locale.."): "..k
|
||||||
|
LOG(mes)
|
||||||
|
MES.new('warn',mes)
|
||||||
|
self[k]=CHAR.zChan.thinking
|
||||||
|
return self[k]
|
||||||
|
end})
|
||||||
|
end
|
||||||
|
end)()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
table.insert(_LOADTIMELIST_,("Initialize Parts: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
--Load background files from SOURCE ONLY
|
--Load background files from SOURCE ONLY
|
||||||
for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
|
for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
|
||||||
if fs.getRealDirectory('parts/backgrounds/'..v)~=SAVEDIR then
|
if isSafeFile('parts/backgrounds/'..v)and v:sub(-3)=='lua'then
|
||||||
if v:sub(-3)=='lua'then
|
|
||||||
local name=v:sub(1,-5)
|
local name=v:sub(1,-5)
|
||||||
BG.add(name,require('parts.backgrounds.'..name))
|
BG.add(name,require('parts.backgrounds.'..name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
BG.remList('none')BG.remList('gray')BG.remList('custom')
|
||||||
--Load scene files from SOURCE ONLY
|
--Load scene files from SOURCE ONLY
|
||||||
for _,v in next,fs.getDirectoryItems('parts/scenes')do
|
for _,v in next,fs.getDirectoryItems('parts/scenes')do
|
||||||
if fs.getRealDirectory('parts/scenes/'..v)~=SAVEDIR then
|
if isSafeFile('parts/scenes/'..v)then
|
||||||
local sceneName=v:sub(1,-5)
|
local sceneName=v:sub(1,-5)
|
||||||
SCN.add(sceneName,require('parts.scenes.'..sceneName))
|
SCN.add(sceneName,require('parts.scenes.'..sceneName))
|
||||||
LANG.addScene(sceneName)
|
LANG.addScene(sceneName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--Load mode files
|
|
||||||
for i=1,#MODES do
|
table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
local m=MODES[i]--Mode template
|
|
||||||
local M=require('parts.modes.'..m.name)--Mode file
|
|
||||||
for k,v in next,m do M[k]=v end
|
|
||||||
MODES[m.name],MODES[i]=M
|
|
||||||
end
|
|
||||||
|
|
||||||
--Update data
|
--Update data
|
||||||
do
|
do
|
||||||
local needSave
|
local needSave
|
||||||
|
|
||||||
if not fs.getInfo('conf/data')then
|
if not fs.getInfo('conf/data')then
|
||||||
FIRSTLAUNCH=true
|
|
||||||
needSave=true
|
needSave=true
|
||||||
end
|
end
|
||||||
if type(STAT.version)~='number'then
|
if type(STAT.version)~='number'then
|
||||||
@@ -281,14 +433,50 @@ do
|
|||||||
end
|
end
|
||||||
if STAT.version==1506 then
|
if STAT.version==1506 then
|
||||||
local temp1,temp2
|
local temp1,temp2
|
||||||
if fs.getInfo('record/master_l.rec')then temp1=fs.read('record/master_l.rec')end
|
if fs.getInfo('record/master_l.rec')then
|
||||||
if fs.getInfo('record/master_u.rec')then temp2=fs.read('record/master_u.rec')end
|
temp1=fs.read('record/master_l.rec')
|
||||||
if temp1 then fs.write('record/master_u.rec',temp1)end
|
end
|
||||||
if temp2 then fs.write('record/master_l.rec',temp2)end
|
if fs.getInfo('record/master_u.rec')then
|
||||||
|
temp2=fs.read('record/master_u.rec')
|
||||||
|
end
|
||||||
|
if temp1 then
|
||||||
|
fs.write('record/master_u.rec',temp1)
|
||||||
|
end
|
||||||
|
if temp2 then
|
||||||
|
fs.write('record/master_l.rec',temp2)
|
||||||
|
end
|
||||||
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
|
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
|
||||||
if RANKS.tsd_u then RANKS.tsd_u=0 end
|
if RANKS.tsd_u then
|
||||||
|
RANKS.tsd_u=0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if STAT.version==1601 then
|
||||||
|
RANKS.round_e=nil
|
||||||
|
RANKS.round_n=nil
|
||||||
|
RANKS.round_h=nil
|
||||||
|
RANKS.round_l=nil
|
||||||
|
RANKS.round_u=nil
|
||||||
|
fs.remove('record/round_e.rec')
|
||||||
|
fs.remove('record/round_n.rec')
|
||||||
|
fs.remove('record/round_h.rec')
|
||||||
|
fs.remove('record/round_l.rec')
|
||||||
|
fs.remove('record/round_u.rec')
|
||||||
|
end
|
||||||
|
if STAT.version<1700 and SETTING.dascut<5 then
|
||||||
|
SETTING.dascut=SETTING.dascut+1
|
||||||
needSave=true
|
needSave=true
|
||||||
end
|
end
|
||||||
|
if SETTING.vocPack=='mono'then
|
||||||
|
SETTING.vocPack='miya'
|
||||||
|
end
|
||||||
|
if RANKS.stack_e then
|
||||||
|
RANKS.stack_e=nil
|
||||||
|
RANKS.stack_h=nil
|
||||||
|
RANKS.stack_u=nil
|
||||||
|
fs.remove('record/stack_e.rec')
|
||||||
|
fs.remove('record/stack_h.rec')
|
||||||
|
fs.remove('record/stack_u.rec')
|
||||||
|
end
|
||||||
if RANKS.stack_20l then
|
if RANKS.stack_20l then
|
||||||
RANKS.stack_20l=nil
|
RANKS.stack_20l=nil
|
||||||
RANKS.stack_40l=nil
|
RANKS.stack_40l=nil
|
||||||
@@ -297,36 +485,20 @@ do
|
|||||||
fs.remove('record/stack_40l.rec')
|
fs.remove('record/stack_40l.rec')
|
||||||
fs.remove('record/stack_100l.rec')
|
fs.remove('record/stack_100l.rec')
|
||||||
end
|
end
|
||||||
|
if RANKS.rhythm_e then
|
||||||
|
RANKS.rhythm_e=nil
|
||||||
|
RANKS.rhythm_h=nil
|
||||||
|
RANKS.rhythm_u=nil
|
||||||
|
fs.remove('record/rhythm_e.rec')
|
||||||
|
fs.remove('record/rhythm_h.rec')
|
||||||
|
fs.remove('record/rhythm_u.rec')
|
||||||
|
end
|
||||||
|
if RANKS.bigbang then
|
||||||
|
RANKS.clearRush,RANKS.bigbang=RANKS.bigbang
|
||||||
|
fs.remove('record/bigbang.rec')
|
||||||
|
end
|
||||||
if STAT.version~=VERSION.code then
|
if STAT.version~=VERSION.code then
|
||||||
STAT.version=VERSION.code
|
for k,v in next,MODE_UPDATE_MAP do
|
||||||
needSave=true
|
|
||||||
love.event.quit('restart')
|
|
||||||
end
|
|
||||||
SETTING.appLock=nil
|
|
||||||
SETTING.dataSaving=nil
|
|
||||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
|
||||||
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
|
|
||||||
if
|
|
||||||
SETTING.RS=='ZRS'or SETTING.RS=='BRS'or
|
|
||||||
SETTING.RS=='ASCplus'or SETTING.RS=='C2sym'
|
|
||||||
then SETTING.RS='TRS'end
|
|
||||||
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
|
||||||
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
|
|
||||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
|
|
||||||
|
|
||||||
for _,v in next,VK_org do v.color=nil end
|
|
||||||
if RANKS.infinite then RANKS.infinite=0 end
|
|
||||||
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
|
||||||
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
|
||||||
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
|
|
||||||
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
|
|
||||||
for k in next,RANKS do
|
|
||||||
if type(k)=='number'then
|
|
||||||
RANKS[k]=nil
|
|
||||||
needSave=true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for k,v in next,oldModeNameTable do
|
|
||||||
if RANKS[k]then
|
if RANKS[k]then
|
||||||
RANKS[v]=RANKS[k]
|
RANKS[v]=RANKS[k]
|
||||||
RANKS[k]=nil
|
RANKS[k]=nil
|
||||||
@@ -341,18 +513,45 @@ do
|
|||||||
fs.remove(k..'.rec')
|
fs.remove(k..'.rec')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
STAT.version=VERSION.code
|
||||||
|
needSave=true
|
||||||
|
end
|
||||||
|
SETTING.appLock,SETTING.dataSaving,SETTING.swap=nil
|
||||||
|
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
||||||
|
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
|
||||||
|
if not RSlist[SETTING.RS]then SETTING.RS='TRS'end
|
||||||
|
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
||||||
|
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
|
||||||
|
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
|
||||||
|
if SETTING.cv then SETTING.vocPack,SETTING.cv=SETTING.cv end
|
||||||
|
if type(SETTING.bg)~='string'then SETTING.bg='on'end
|
||||||
|
if SETTING.skin[18]==10 then SETTING.skin[18]=4 end
|
||||||
|
if SETTING.reTime>3 or SETTING.reTime<.5 then SETTING.reTime=2 end
|
||||||
|
if RANKS.infinite then RANKS.infinite=0 end
|
||||||
|
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
||||||
|
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
||||||
|
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
|
||||||
|
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
|
||||||
|
for _,v in next,VK_ORG do v.color=nil end
|
||||||
|
for name,rank in next,RANKS do
|
||||||
|
if type(name)=='number'or type(rank)~='number'then
|
||||||
|
RANKS[name]=nil
|
||||||
|
needSave=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if needSave then
|
if needSave then
|
||||||
FILE.save(SETTING,'conf/settings')
|
saveStats()
|
||||||
FILE.save(RANKS,'conf/unlock')
|
saveProgress()
|
||||||
FILE.save(STAT,'conf/data')
|
saveSettings()
|
||||||
|
love.event.quit('restart')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--First start for phones
|
--First start
|
||||||
|
FIRSTLAUNCH=STAT.run==0
|
||||||
if FIRSTLAUNCH and MOBILE then
|
if FIRSTLAUNCH and MOBILE then
|
||||||
SETTING.VKSwitch=true
|
SETTING.VKSwitch=true
|
||||||
SETTING.swap=false
|
|
||||||
SETTING.powerInfo=true
|
SETTING.powerInfo=true
|
||||||
SETTING.cleanCanvas=true
|
SETTING.cleanCanvas=true
|
||||||
end
|
end
|
||||||
@@ -366,7 +565,7 @@ for _,fileName in next,fs.getDirectoryItems('replay')do
|
|||||||
local date,mode,version,player,seed,setting,mod
|
local date,mode,version,player,seed,setting,mod
|
||||||
local fileData=fs.read('replay/'..fileName)
|
local fileData=fs.read('replay/'..fileName)
|
||||||
date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","")
|
date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","")
|
||||||
mode, fileData=STRING.readLine(fileData)mode=oldModeNameTable[mode]or mode
|
mode, fileData=STRING.readLine(fileData)mode=MODE_UPDATE_MAP[mode]or mode
|
||||||
version,fileData=STRING.readLine(fileData)
|
version,fileData=STRING.readLine(fileData)
|
||||||
player, fileData=STRING.readLine(fileData)if player=="Local Player"then player="Stacker"end
|
player, fileData=STRING.readLine(fileData)if player=="Local Player"then player="Stacker"end
|
||||||
local success
|
local success
|
||||||
@@ -405,3 +604,41 @@ for _,fileName in next,fs.getDirectoryItems('replay')do
|
|||||||
table.insert(REPLAY,rep)
|
table.insert(REPLAY,rep)
|
||||||
end
|
end
|
||||||
table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)
|
table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)
|
||||||
|
|
||||||
|
table.insert(_LOADTIMELIST_,("Initialize Data: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
|
for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i])end
|
||||||
|
|
||||||
|
--Launch testing task if launch param received
|
||||||
|
if TABLE.find(arg,'--test')then
|
||||||
|
TASK.new(function()
|
||||||
|
while not LOADED do YIELD()end
|
||||||
|
|
||||||
|
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
|
||||||
|
BGM.setVol(0)SFX.setVol(0)
|
||||||
|
love.keypressed('space')
|
||||||
|
TEST.yieldUntilNextScene()
|
||||||
|
|
||||||
|
for k,mode in next,MODES do
|
||||||
|
if k~='netBattle'then
|
||||||
|
LOG("Scanning mode: "..mode.name)
|
||||||
|
loadGame(mode.name,true)
|
||||||
|
TEST.yieldUntilNextScene()
|
||||||
|
SCN.back()
|
||||||
|
TEST.yieldUntilNextScene()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
LOG("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
|
||||||
|
TEST.yieldN(60)
|
||||||
|
love.event.quit(0)
|
||||||
|
end)
|
||||||
|
TASK.new(function()
|
||||||
|
while true do
|
||||||
|
YIELD()
|
||||||
|
if Z.getErr(1)then break end
|
||||||
|
end
|
||||||
|
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.getErr(1).mes,"\n").."\27[91m\nAborting\27[0m")
|
||||||
|
TEST.yieldN(60)
|
||||||
|
love.event.quit(1)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|||||||