Compare commits
516 Commits
pre0.16.3
...
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 |
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: (delete this line before submitting)
|
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: (delete this line before submitting)
|
|
||||||
*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: (delete this line before submitting)
|
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: (delete this line before submitting)
|
|
||||||
*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
|
||||||
32
.github/actions/build-android/action.yml
vendored
@@ -59,11 +59,41 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
7z a -tzip love-android/app/src/main/assets/game.love libAndroid
|
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
|
- name: Build Techmino
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "${{ inputs.SIGNING_KEY }}" | base64 -d > love-android/app/android.keystore
|
echo "${{ inputs.SIGNING_KEY }}" | base64 -d > love-android/app/android.keystore
|
||||||
python3 .github/workflows/updateVersion.py -T Android${{ inputs.type }} -C ${{ inputs.apkCode }} -N ${{ inputs.name }} -S ${{ inputs.KEY_STORE_PASSWORD }} -A ${{ inputs.ALIAS }} -K ${{ inputs.KEY_PASSWORD }}
|
|
||||||
chmod 777 love-android/gradlew
|
chmod 777 love-android/gradlew
|
||||||
cd love-android/
|
cd love-android/
|
||||||
./gradlew assembleRelease
|
./gradlew assembleRelease
|
||||||
|
|||||||
4
.github/actions/build-ios/action.yml
vendored
@@ -40,6 +40,9 @@ inputs:
|
|||||||
FASTLANE_DISCORD_WEBHOOK:
|
FASTLANE_DISCORD_WEBHOOK:
|
||||||
required: true
|
required: true
|
||||||
description: "Fastlane Discord webhook"
|
description: "Fastlane Discord webhook"
|
||||||
|
FASTLANE_ACTION_ID:
|
||||||
|
required: true
|
||||||
|
description: "Fastlane Action ID"
|
||||||
FASTLANE_MATCH_PWD:
|
FASTLANE_MATCH_PWD:
|
||||||
required: true
|
required: true
|
||||||
description: "Fastlane Match description password"
|
description: "Fastlane Match description password"
|
||||||
@@ -71,6 +74,7 @@ runs:
|
|||||||
lane: '${{ inputs.type }}'
|
lane: '${{ inputs.type }}'
|
||||||
subdirectory: 'Techmino-iOS/platform/xcode'
|
subdirectory: 'Techmino-iOS/platform/xcode'
|
||||||
env:
|
env:
|
||||||
|
ACTION_ID: '${{ inputs.FASTLANE_ACTION_ID }}'
|
||||||
API_ID: '${{ inputs.APPLE_API_ID }}'
|
API_ID: '${{ inputs.APPLE_API_ID }}'
|
||||||
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
|
||||||
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
API_KEY: '${{ inputs.APPLE_API_KEY }}'
|
||||||
|
|||||||
2
.github/actions/build-linux/action.yml
vendored
@@ -33,7 +33,7 @@ runs:
|
|||||||
cp squashfs-root/icon.png squashfs-root/.DirIcon
|
cp squashfs-root/icon.png squashfs-root/.DirIcon
|
||||||
chmod 777 squashfs-root/love
|
chmod 777 squashfs-root/love
|
||||||
mkdir -p squashfs-root/usr/share/Techmino
|
mkdir -p squashfs-root/usr/share/Techmino
|
||||||
mv media parts Zframework conf.lua main.lua version.lua 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 CCloader.so squashfs-root/usr/share/Techmino
|
||||||
mv libcold_clear.so squashfs-root/usr/lib
|
mv libcold_clear.so squashfs-root/usr/lib
|
||||||
chmod 777 appimagetool-x86_64.AppImage
|
chmod 777 appimagetool-x86_64.AppImage
|
||||||
|
|||||||
2
.github/actions/build-love/action.yml
vendored
@@ -7,5 +7,5 @@ inputs:
|
|||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua
|
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua legals.md license.txt
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
18
.github/actions/build-macos/action.yml
vendored
@@ -59,12 +59,22 @@ runs:
|
|||||||
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
|
||||||
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
|
||||||
- name: Modify template
|
- 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
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
python3 .github/workflows/updateVersion.py -T macOS \
|
|
||||||
-N ${{ inputs.name }} \
|
|
||||||
-B ${{ inputs.APPLE_APP_IDENTIFIER }}
|
|
||||||
|
|
||||||
mv Techmino.love Techmino-macOS/Techmino.app/Contents/Resources
|
mv Techmino.love Techmino-macOS/Techmino.app/Contents/Resources
|
||||||
mv CCloader.dylib Techmino-macOS/Techmino.app/Contents/Frameworks
|
mv CCloader.dylib Techmino-macOS/Techmino.app/Contents/Frameworks
|
||||||
mv ${{ inputs.icon }} Techmino-macOS/Techmino.app/Contents/Resources/iconfile.icns
|
mv ${{ inputs.icon }} Techmino-macOS/Techmino.app/Contents/Resources/iconfile.icns
|
||||||
|
|||||||
13
.github/actions/build-windows/action.yml
vendored
@@ -30,6 +30,18 @@ runs:
|
|||||||
with:
|
with:
|
||||||
url: http://www.angusj.com/resourcehacker/resource_hacker.zip
|
url: http://www.angusj.com/resourcehacker/resource_hacker.zip
|
||||||
- uses: ./.github/actions/build-love
|
- 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
|
- name: Pack Techmino
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
@@ -42,7 +54,6 @@ runs:
|
|||||||
del .\love\readme.txt
|
del .\love\readme.txt
|
||||||
move .\cold_clear.dll .\love
|
move .\cold_clear.dll .\love
|
||||||
move .\CCloader.dll .\love
|
move .\CCloader.dll .\love
|
||||||
python .\.github\workflows\updateVersion.py -T Windows -N ${{ inputs.version }}
|
|
||||||
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action delete -mask ICONGROUP,,'
|
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 .\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 "${{ inputs.icon }}" -mask ICONGROUP,1,'
|
||||||
|
|||||||
12
.github/actions/snapshot-update/action.yml
vendored
@@ -1,12 +0,0 @@
|
|||||||
name: 'update for a snapshot'
|
|
||||||
description: 'common update logic for snapshot'
|
|
||||||
inputs:
|
|
||||||
commit:
|
|
||||||
required: true
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- shell: bash
|
|
||||||
run: |
|
|
||||||
python3 .github/workflows/updateVersion.py -T Conf
|
|
||||||
python3 .github/workflows/updateVersion.py -T Version -H ${{ inputs.commit }}
|
|
||||||
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)
|
||||||
BIN
.github/build/macOS/backgroundImage.tiff
vendored
68
.github/workflows/dev.yml
vendored
@@ -27,14 +27,21 @@ jobs:
|
|||||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
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:
|
build-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-windows
|
- uses: ./.github/actions/build-windows
|
||||||
with:
|
with:
|
||||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
@@ -53,9 +60,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-linux
|
- uses: ./.github/actions/build-linux
|
||||||
with:
|
with:
|
||||||
icon: .github/build/Linux/icon_snapshot.png
|
icon: .github/build/Linux/icon_snapshot.png
|
||||||
@@ -70,9 +78,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-android
|
- uses: ./.github/actions/build-android
|
||||||
with:
|
with:
|
||||||
type: Snapshot
|
type: Snapshot
|
||||||
@@ -88,15 +97,44 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
|
||||||
path: Techmino_Snapshot.apk
|
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:
|
build-macOS:
|
||||||
runs-on: macos-10.15
|
runs-on: macos-10.15
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-macos
|
- uses: ./.github/actions/build-macos
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
@@ -117,12 +155,14 @@ jobs:
|
|||||||
|
|
||||||
build-iOS:
|
build-iOS:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
if: (!startsWith( github.ref , 'refs/heads/ci-')) || startsWith( github.ref , 'refs/heads/ci-ios-')
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-ios
|
- uses: ./.github/actions/build-ios
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
@@ -137,6 +177,7 @@ jobs:
|
|||||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
@@ -144,4 +185,19 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_iOS
|
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||||
path: "Techmino.ipa"
|
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
|
||||||
|
|||||||
17
.github/workflows/getVersion.lua
vendored
@@ -1,22 +1,23 @@
|
|||||||
if arg[1]=="-apkCode"then
|
local arg=arg[1]
|
||||||
|
if arg=="-apkCode"then
|
||||||
local code=require"version".apkCode
|
local code=require"version".apkCode
|
||||||
print(code)
|
print(code)
|
||||||
elseif arg[1]=="-code"then
|
elseif arg=="-code"then
|
||||||
local str=require"version".code
|
local str=require"version".code
|
||||||
print(str)
|
print(str)
|
||||||
elseif arg[1]=="-name"then
|
elseif arg=="-name"then
|
||||||
local str=require"version".string:gsub("@DEV","")
|
local str=require"version".string
|
||||||
print(str)
|
print(str)
|
||||||
elseif arg[1]=="-release"then
|
elseif arg=="-release"then
|
||||||
local str=require"version".string:gsub("V","",1):gsub("@DEV","")
|
local str=require"version".string:gsub("V","",1)
|
||||||
print(str)
|
print(str)
|
||||||
elseif arg[1]=="-updateTitle"then
|
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)
|
||||||
|
|||||||
331
.github/workflows/release.yml
vendored
@@ -3,7 +3,7 @@ name: Techmino Release CI
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- "v*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-info:
|
get-info:
|
||||||
@@ -14,233 +14,176 @@ jobs:
|
|||||||
code: ${{ steps.actual-get-info.outputs.code }}
|
code: ${{ steps.actual-get-info.outputs.code }}
|
||||||
release: ${{ steps.actual-get-info.outputs.release }}
|
release: ${{ steps.actual-get-info.outputs.release }}
|
||||||
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
|
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
|
||||||
|
updateNote: ${{ steps.actual-get-info.outputs.updateNote }}
|
||||||
commit: ${{ steps.actual-get-info.outputs.commit }}
|
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- name: Install lua
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install lua5.3 -y
|
sudo apt-get install lua5.3 -y
|
||||||
- name: Get Version
|
- name: Get Version
|
||||||
id: actual-get-info
|
id: actual-get-info
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
UPDATE_NOTE=$(lua .github/workflows/getVersion.lua -updateNote)
|
||||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
UPDATE_NOTE="${UPDATE_NOTE//'%'/'%25'}"
|
||||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
UPDATE_NOTE="${UPDATE_NOTE//$'\n'/'%0A'}"
|
||||||
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
UPDATE_NOTE="${UPDATE_NOTE//$'\r'/'%0D'}"
|
||||||
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
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=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
||||||
|
echo "::set-output name=updateNote::$UPDATE_NOTE"
|
||||||
|
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||||
|
|
||||||
build-windows-x64:
|
build-windows-x64:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Update Version
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-windows
|
||||||
python .\.github\workflows\updateVersion.py -T Version
|
with:
|
||||||
- uses: ./.github/actions/build-windows
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
with:
|
love-dir: love-11.3-win64
|
||||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
arch: win64
|
||||||
love-dir: love-11.3-win64
|
version: ${{ needs.get-info.outputs.release }}
|
||||||
arch: win64
|
icon: .\.github\build\Windows\icon.ico
|
||||||
version: ${{ needs.get-info.outputs.release }}
|
- name: Pack Techmino
|
||||||
icon: .\.github\build\Windows\icon.ico
|
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip .\love
|
||||||
- name: Pack Techmino
|
- name: Release
|
||||||
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win64.zip .\love
|
uses: softprops/action-gh-release@v1
|
||||||
- name: Release
|
with:
|
||||||
uses: softprops/action-gh-release@v1
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
with:
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
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
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Update Version
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-windows
|
||||||
python .\.github\workflows\updateVersion.py -T Version
|
with:
|
||||||
- uses: ./.github/actions/build-windows
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
||||||
with:
|
love-dir: love-11.3-win32
|
||||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
arch: win32
|
||||||
love-dir: love-11.3-win32
|
version: ${{ needs.get-info.outputs.release }}
|
||||||
arch: win32
|
icon: .\.github\build\Windows\icon.ico
|
||||||
version: ${{ needs.get-info.outputs.release }}
|
- name: Pack Techmino
|
||||||
icon: .\.github\build\Windows\icon.ico
|
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip .\love
|
||||||
- name: Pack Techmino
|
- name: Release
|
||||||
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win32.zip .\love
|
uses: softprops/action-gh-release@v1
|
||||||
- name: Release
|
with:
|
||||||
uses: softprops/action-gh-release@v1
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
with:
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
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
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Update Version
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-linux
|
||||||
python3 .github/workflows/updateVersion.py -T Version
|
with:
|
||||||
- uses: ./.github/actions/build-linux
|
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||||
with:
|
icon: .github/build/Linux/icon.png
|
||||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
|
- name: Release
|
||||||
icon: .github/build/Linux/icon.png
|
uses: softprops/action-gh-release@v1
|
||||||
- name: Release
|
with:
|
||||||
uses: softprops/action-gh-release@v1
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
with:
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
|
|
||||||
|
|
||||||
build-android:
|
build-android:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Update Version
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-android
|
||||||
python3 .github/workflows/updateVersion.py -T Version
|
with:
|
||||||
- uses: ./.github/actions/build-android
|
type: Release
|
||||||
with:
|
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||||
type: Release
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.apk
|
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||||
ALIAS: ${{ secrets.ALIAS }}
|
- name: Release
|
||||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
uses: softprops/action-gh-release@v1
|
||||||
- name: Release
|
with:
|
||||||
uses: softprops/action-gh-release@v1
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
with:
|
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.apk
|
|
||||||
|
|
||||||
build-android-mini:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
needs: get-info
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 .github/workflows/updateVersion.py -T Version
|
|
||||||
- name: remove media
|
|
||||||
run: |
|
|
||||||
rm -rf media/music media/effect media/vocal
|
|
||||||
- uses: ./.github/actions/build-android
|
|
||||||
with:
|
|
||||||
type: Release
|
|
||||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
|
||||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
|
|
||||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
|
||||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
|
||||||
ALIAS: ${{ secrets.ALIAS }}
|
|
||||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
|
|
||||||
|
|
||||||
build-macOS:
|
build-macOS:
|
||||||
runs-on: macos-10.15
|
runs-on: macos-10.15
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Update Version
|
- uses: ./.github/actions/update-version
|
||||||
run: |
|
- uses: ./.github/actions/build-macos
|
||||||
python3 .github/workflows/updateVersion.py -T Version
|
with:
|
||||||
- uses: ./.github/actions/build-macos
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
with:
|
icon: .github/build/macOS/icon.icns
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||||
icon: .github/build/macOS/icon.icns
|
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
- name: Pack Techmino
|
||||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
run: |
|
||||||
- name: Pack Techmino
|
mv Techmino.dmg Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||||
run: |
|
- name: Release
|
||||||
mv Techmino.dmg Techmino.a${{ needs.get-info.outputs.release }}.macOS.dmg
|
uses: softprops/action-gh-release@v1
|
||||||
- name: Release
|
with:
|
||||||
uses: softprops/action-gh-release@v1
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
with:
|
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.macOS.zip
|
|
||||||
|
|
||||||
build-iOS:
|
build-iOS:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
- uses: ./.github/actions/build-ios
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
with:
|
||||||
- uses: ./.github/actions/build-ios
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
with:
|
type: "release"
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||||
type: 'release'
|
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
APPLE_APP_BUILD: "${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}"
|
||||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
APPLE_APP_CHANGELOG: "${{ needs.get-info.outputs.updateNote }}"
|
||||||
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}'
|
APPLE_APP_ID: "${{ secrets.APPLE_APP_ID }}"
|
||||||
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||||
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
APPLE_APP_PROFILE: "${{ secrets.APPLE_APP_PROFILE }}"
|
||||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
FASTLANE_ACTION_ID: "${{ github.run_id }}"
|
||||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
FASTLANE_DISCORD_WEBHOOK: "${{ secrets.FASTLANE_DISCORD_WEBHOOK }}"
|
||||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
- name: Rename ipa
|
||||||
- name: Rename ipa
|
shell: bash
|
||||||
shell: bash
|
run: |
|
||||||
run: |
|
mv Techmino.ipa Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||||
mv Techmino.ipa Techmino.a${{ needs.get-info.outputs.release }}.ipa
|
- name: Release
|
||||||
- name: Release
|
uses: softprops/action-gh-release@v1
|
||||||
uses: softprops/action-gh-release@v1
|
with:
|
||||||
with:
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.ipa
|
|
||||||
|
|
||||||
build-love:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
needs: get-info
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
python3 .github/workflows/updateVersion.py -T Version
|
|
||||||
- uses: ./.github/actions/build-love
|
|
||||||
with:
|
|
||||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.love
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
files: Techmino.a${{ needs.get-info.outputs.release }}.love
|
|
||||||
|
|
||||||
Add-Release-note:
|
Add-Release-note:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install lua
|
- name: Release
|
||||||
run: |
|
uses: softprops/action-gh-release@v1
|
||||||
sudo apt-get update -y
|
with:
|
||||||
sudo apt-get upgrade -y
|
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||||
sudo apt-get install lua5.3 -y
|
body: ${{ needs.get-info.outputs.updateNote }}
|
||||||
- name: Get ReleaseNote
|
|
||||||
run: |
|
|
||||||
lua .github/workflows/getVersion.lua -updateNote > updateNote.txt
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
|
||||||
body_path: updateNote.txt
|
|
||||||
|
|||||||
30
.github/workflows/test.yml
vendored
@@ -33,9 +33,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-windows
|
- uses: ./.github/actions/build-windows
|
||||||
with:
|
with:
|
||||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||||
@@ -46,24 +47,25 @@ jobs:
|
|||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Windows
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||||
path: love
|
path: love
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-linux
|
- uses: ./.github/actions/build-linux
|
||||||
with:
|
with:
|
||||||
icon: .github/build/Linux/icon_snapshot.png
|
icon: .github/build/Linux/icon_snapshot.png
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Linux
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||||
path: Techmino.AppImage
|
path: Techmino.AppImage
|
||||||
|
|
||||||
build-android:
|
build-android:
|
||||||
@@ -71,9 +73,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-android
|
- uses: ./.github/actions/build-android
|
||||||
with:
|
with:
|
||||||
type: Snapshot
|
type: Snapshot
|
||||||
@@ -87,7 +90,7 @@ jobs:
|
|||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Android
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
|
||||||
path: Techmino_Snapshot.apk
|
path: Techmino_Snapshot.apk
|
||||||
|
|
||||||
build-macOS:
|
build-macOS:
|
||||||
@@ -95,9 +98,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-macos
|
- uses: ./.github/actions/build-macos
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
@@ -113,7 +117,7 @@ jobs:
|
|||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.macOS
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
|
||||||
path: Techmino.dmg
|
path: Techmino.dmg
|
||||||
|
|
||||||
build-iOS:
|
build-iOS:
|
||||||
@@ -121,9 +125,10 @@ jobs:
|
|||||||
needs: get-info
|
needs: get-info
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: ./.github/actions/snapshot-update
|
- uses: ./.github/actions/update-version
|
||||||
with:
|
with:
|
||||||
commit: ${{ needs.get-info.outputs.commit }}
|
commit: ${{ needs.get-info.outputs.commit }}
|
||||||
|
type: snapshot
|
||||||
- uses: ./.github/actions/build-ios
|
- uses: ./.github/actions/build-ios
|
||||||
with:
|
with:
|
||||||
name: ${{ needs.get-info.outputs.name }}
|
name: ${{ needs.get-info.outputs.name }}
|
||||||
@@ -138,11 +143,12 @@ jobs:
|
|||||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||||
|
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.iOS
|
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||||
path: "Techmino.ipa"
|
path: Techmino.ipa
|
||||||
|
|||||||
100
.github/workflows/updateVersion.py
vendored
@@ -1,100 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import re
|
|
||||||
|
|
||||||
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]}')
|
|
||||||
else:
|
|
||||||
data = data.replace('@DEV', '')
|
|
||||||
file.seek(0)
|
|
||||||
file.truncate()
|
|
||||||
file.flush()
|
|
||||||
file.write(data)
|
|
||||||
|
|
||||||
def updateMacOS(args): #更新macOS打包信息
|
|
||||||
import datetime
|
|
||||||
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', args.Name[1:])\
|
|
||||||
.replace('@thisYear', thisYear)\
|
|
||||||
.replace('@bundleId', args.Bundle)
|
|
||||||
with open('./Techmino-macOS/Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
|
|
||||||
file.write(data)
|
|
||||||
|
|
||||||
def updateWindows(args): #更新Windows打包信息
|
|
||||||
Version = (args.Name).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)
|
|
||||||
|
|
||||||
def updateAndroid(args, edition): #更新Android打包信息
|
|
||||||
if edition == 'Release':
|
|
||||||
appName = 'Techmino'
|
|
||||||
packageName = 'org.love2d.MrZ.Techmino'
|
|
||||||
edition = 'release'
|
|
||||||
elif edition == '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', args.Code)\
|
|
||||||
.replace('@versionName', args.Name)\
|
|
||||||
.replace('@storePassword', args.Store)\
|
|
||||||
.replace('@keyAlias', args.Alias)\
|
|
||||||
.replace('@keyPassword', args.Key)
|
|
||||||
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('-B', '--Bundle', 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')
|
|
||||||
parser.add_argument('-S', '--Store', type=str, default = False, help = 'storePassword')
|
|
||||||
parser.add_argument('-A', '--Alias', type=str, default = False, help = 'keyAlias')
|
|
||||||
parser.add_argument('-K', '--Key', type=str, default = False, help = 'keyPassword')
|
|
||||||
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 == 'AndroidRelease':
|
|
||||||
updateAndroid(args, 'Release')
|
|
||||||
elif args.Type == 'AndroidSnapshot':
|
|
||||||
updateAndroid(args, 'Snapshot')
|
|
||||||
7
.gitignore
vendored
@@ -1,3 +1,8 @@
|
|||||||
.vscode
|
.vscode
|
||||||
libAndroid
|
libAndroid
|
||||||
*.ini
|
*.ini
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Icon?
|
||||||
|
.Trash
|
||||||
|
.file
|
||||||
|
|||||||
@@ -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)
|
||||||
background=background or BG.default
|
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,17 +1,74 @@
|
|||||||
local Sources={}
|
local lastLoaded={}
|
||||||
|
local maxLoadedCount=3
|
||||||
|
local nameList={}
|
||||||
|
local SourceObjList={}
|
||||||
local volume=1
|
local volume=1
|
||||||
|
|
||||||
local BGM={
|
local BGM={
|
||||||
default=false,
|
default=false,
|
||||||
getList=function()error("Cannot getList before initialize!")end,
|
|
||||||
getCount=function()return 0 end,
|
|
||||||
play=NULL,
|
|
||||||
stop=NULL,
|
|
||||||
onChange=NULL,
|
onChange=NULL,
|
||||||
--nowPlay=[str:playing ID]
|
--nowPlay=[str:playing ID]
|
||||||
--playing=[src:playing SRC]
|
--playing=[src:playing SRC]
|
||||||
--lastPlayed=[str:lastPlayed ID]
|
--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)
|
||||||
|
BGM.default=bgm
|
||||||
|
end
|
||||||
|
function BGM.setMaxSources(count)
|
||||||
|
maxLoadedCount=count
|
||||||
|
_tryReleaseSources()
|
||||||
|
end
|
||||||
|
function BGM.setChange(func)
|
||||||
|
BGM.onChange=func
|
||||||
|
end
|
||||||
|
function BGM.setVol(v)
|
||||||
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
|
volume=v
|
||||||
|
if BGM.playing then
|
||||||
|
if volume>0 then
|
||||||
|
BGM.playing:setVolume(volume)
|
||||||
|
BGM.playing:play()
|
||||||
|
elseif BGM.nowPlay then
|
||||||
|
BGM.playing:pause()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function task_fadeOut(src)
|
local function task_fadeOut(src)
|
||||||
while true do
|
while true do
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
@@ -37,110 +94,89 @@ end
|
|||||||
local function check_curFadeOut(task,code,src)
|
local function check_curFadeOut(task,code,src)
|
||||||
return task.code==code and task.args[1]==src
|
return task.code==code and task.args[1]==src
|
||||||
end
|
end
|
||||||
function BGM.setDefault(bgm)
|
local function _tryLoad(name)
|
||||||
BGM.default=bgm
|
if SourceObjList[name]then
|
||||||
end
|
if SourceObjList[name].source then
|
||||||
function BGM.setChange(func)
|
|
||||||
BGM.onChange=func
|
|
||||||
end
|
|
||||||
function BGM.setVol(v)
|
|
||||||
assert(type(v)=='number'and v>=0 and v<=1)
|
|
||||||
volume=v
|
|
||||||
end
|
|
||||||
function BGM.init(list)
|
|
||||||
BGM.init=nil
|
|
||||||
|
|
||||||
local simpList={}
|
|
||||||
for _,v in next,list do
|
|
||||||
table.insert(simpList,v.name)
|
|
||||||
Sources[v.name]=v.path
|
|
||||||
end
|
|
||||||
table.sort(simpList)
|
|
||||||
function BGM.getList()return simpList end
|
|
||||||
local count=#simpList
|
|
||||||
LOG(count.." BGM files added")
|
|
||||||
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
|
|
||||||
LOG("No BGM: "..Sources[name],5)
|
|
||||||
end
|
|
||||||
elseif Sources[name]then
|
|
||||||
return true
|
return true
|
||||||
elseif name then
|
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
||||||
LOG("No BGM: "..name,5)
|
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
|
end
|
||||||
|
elseif name then
|
||||||
|
LOG("No BGM: "..name,5)
|
||||||
end
|
end
|
||||||
function BGM.setVol(v)
|
end
|
||||||
assert(type(v)=='number'and v>=0 and v<=1)
|
function BGM.play(name,args)
|
||||||
volume=v
|
name=name or BGM.default
|
||||||
if BGM.playing then
|
args=args or""
|
||||||
if volume>0 then
|
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:setVolume(volume)
|
||||||
BGM.playing:play()
|
BGM.playing:play()
|
||||||
elseif BGM.nowPlay then
|
|
||||||
BGM.playing:pause()
|
|
||||||
end
|
end
|
||||||
end
|
SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
|
||||||
end
|
BGM.lastPlayed=BGM.nowPlay
|
||||||
function BGM.loadAll()--Not neccessary, unless you want avoid the lag when playing something for the first time
|
BGM.playing:seek(0)
|
||||||
for name in next,Sources do
|
|
||||||
_load(name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function BGM.play(name)
|
|
||||||
name=name or BGM.default
|
|
||||||
if not _load(name)then return end
|
|
||||||
if volume==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(task_fadeOut,BGM.playing)
|
|
||||||
end
|
|
||||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
|
|
||||||
TASK.removeTask_code(task_fadeIn)
|
|
||||||
|
|
||||||
TASK.new(task_fadeIn,Sources[name])
|
|
||||||
BGM.nowPlay=name
|
|
||||||
BGM.playing=Sources[name]
|
|
||||||
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.continue()
|
|
||||||
if BGM.lastPlayed then
|
|
||||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,Sources[BGM.lastPlayed]
|
|
||||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[BGM.nowPlay])
|
|
||||||
TASK.removeTask_code(task_fadeIn)
|
|
||||||
TASK.new(task_fadeIn,BGM.playing)
|
|
||||||
BGM.playing:play()
|
BGM.playing:play()
|
||||||
|
BGM.onChange(name)
|
||||||
end
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
function BGM.stop()
|
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.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
|
if BGM.nowPlay then
|
||||||
TASK.new(task_fadeOut,BGM.playing)
|
TASK.new(task_fadeOut,BGM.playing)
|
||||||
end
|
end
|
||||||
BGM.nowPlay,BGM.playing=nil
|
elseif BGM.playing then
|
||||||
|
BGM.playing:pause()
|
||||||
end
|
end
|
||||||
|
BGM.nowPlay,BGM.playing=nil
|
||||||
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,76 @@
|
|||||||
local fs=love.filesystem
|
local fs=love.filesystem
|
||||||
local FILE={}
|
local FILE={}
|
||||||
function FILE.load(name,mode)
|
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 mode=='luaon'or not mode and 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
|
||||||
end
|
(s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or
|
||||||
elseif mode=='json'or not mode and s:sub(1,1)=="["and s:sub(-1)=="]"or s:sub(1,1)=="{"and s:sub(-1)=="}"then
|
'string'
|
||||||
local res=JSON.decode(s)
|
if mode=='luaon'then
|
||||||
if res then
|
local func,err_mes=loadstring(s)
|
||||||
return res
|
if func then
|
||||||
end
|
setfenv(func,{})
|
||||||
elseif mode=='string'or not mode then
|
local res=func()
|
||||||
return s
|
return assert(res,'decode error')
|
||||||
else
|
else
|
||||||
MES.new("No file loading mode called "..tostring(mode))
|
error('decode error: '..err_mes)
|
||||||
end
|
end
|
||||||
|
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)
|
||||||
|
if res then
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
error('decode error')
|
||||||
|
elseif mode=='string'then
|
||||||
|
return s
|
||||||
else
|
else
|
||||||
MES.new('error',name.." "..text.loadError)
|
error('unknown mode')
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
error('no file')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function FILE.save(data,name,mode)
|
function FILE.save(data,name,args)
|
||||||
if not mode then mode=""end
|
if not args then args=''end
|
||||||
|
if STRING.sArg(args,'-d')and fs.getInfo(name)then
|
||||||
|
error('duplicate')
|
||||||
|
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 and fs.getInfo(path).type=='directory'then
|
if fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory'then
|
||||||
|
|||||||
@@ -1,67 +1,60 @@
|
|||||||
local gc=love.graphics
|
local gc=love.graphics
|
||||||
local set=gc.setFont
|
local set=gc.setFont
|
||||||
local fontCache={}
|
local fontFiles,fontCache={},{}
|
||||||
local currentFontSize
|
local defaultFont,defaultFallBack
|
||||||
|
local curFont=false--Current using font object
|
||||||
|
|
||||||
local FONT={}
|
local FONT={}
|
||||||
function FONT.set(s)
|
function FONT.setDefault(name)defaultFont=name end
|
||||||
if s~=currentFontSize then
|
function FONT.setFallback(name)defaultFallBack=name end
|
||||||
if not fontCache[s]then
|
function FONT.rawget(s)
|
||||||
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
|
||||||
end
|
|
||||||
set(fontCache[s])
|
|
||||||
currentFontSize=s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function FONT.get(s)
|
|
||||||
if not fontCache[s]then
|
if not fontCache[s]then
|
||||||
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
||||||
end
|
end
|
||||||
return fontCache[s]
|
return fontCache[s]
|
||||||
end
|
end
|
||||||
function FONT.reset()
|
function FONT.rawset(s)
|
||||||
for s in next,fontCache do
|
set(fontCache[s]or FONT.rawget(s))
|
||||||
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
function FONT.load(fonts)
|
||||||
function FONT.load(mainFont,secFont)
|
for name,path in next,fonts do
|
||||||
assert(love.filesystem.getInfo(mainFont),"Font file '"..mainFont.."' not exist!")
|
assert(love.filesystem.getInfo(path),STRING.repD("Font file $1($2) not exist!",name,path))
|
||||||
mainFont=love.filesystem.newFile(mainFont)
|
fontFiles[name]=love.filesystem.newFile(path)
|
||||||
if secFont and love.filesystem.getInfo(secFont)then
|
fontCache[name]={}
|
||||||
secFont=love.filesystem.newFile(secFont)
|
|
||||||
else
|
|
||||||
secFont=false
|
|
||||||
end
|
|
||||||
function FONT.set(s)
|
|
||||||
if s~=currentFontSize then
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
|
|
||||||
if secFont then
|
|
||||||
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
set(fontCache[s])
|
|
||||||
currentFontSize=s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function FONT.get(s)
|
|
||||||
if not fontCache[s]then
|
|
||||||
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
|
|
||||||
if secFont then
|
|
||||||
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return fontCache[s]
|
|
||||||
end
|
|
||||||
function FONT.reset()
|
|
||||||
for s in next,fontCache do
|
|
||||||
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
|
|
||||||
if secFont then
|
|
||||||
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
FONT.reset()
|
FONT.reset()
|
||||||
end
|
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
|
return FONT
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ do--function GC.DO(L)
|
|||||||
setLJ="setLineJoin",
|
setLJ="setLineJoin",
|
||||||
|
|
||||||
print="print",
|
print="print",
|
||||||
|
rawFT=function(...)FONT.rawset(...)end,
|
||||||
setFT=function(...)FONT.set(...)end,
|
setFT=function(...)FONT.set(...)end,
|
||||||
mText=GC.mStr,
|
mText=GC.mStr,
|
||||||
mDraw=GC.draw,
|
mDraw=GC.draw,
|
||||||
|
|||||||
@@ -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]={}
|
||||||
@@ -13,7 +12,7 @@ function IMG.init(list)
|
|||||||
self[name]=love.graphics.newImage(list[name])
|
self[name]=love.graphics.newImage(list[name])
|
||||||
else
|
else
|
||||||
LOG("No IMG: "..name)
|
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)
|
||||||
@@ -35,7 +37,6 @@ 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'
|
||||||
@@ -59,6 +60,7 @@ 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
|
||||||
@@ -70,10 +72,24 @@ 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
|
||||||
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},
|
||||||
@@ -91,17 +107,16 @@ 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)
|
||||||
else gc_setColor(1,0,0)
|
else gc_setColor(1,0,0)
|
||||||
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
|
||||||
@@ -124,36 +139,81 @@ local function updatePowerInfo()
|
|||||||
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,
|
|
||||||
math.floor(mx/10)*10,math.floor(my/10)*10,
|
|
||||||
math.floor((mx-lastX)/10)*10,math.floor((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
|
||||||
@@ -188,13 +248,13 @@ function love.touchpressed(id,x,y)
|
|||||||
x,y=ITP(xOy,x,y)
|
x,y=ITP(xOy,x,y)
|
||||||
lastX,lastY=x,y
|
lastX,lastY=x,y
|
||||||
WIDGET.cursorMove(x,y)
|
WIDGET.cursorMove(x,y)
|
||||||
if SCN.touchDown then SCN.touchDown(x,y)end
|
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)
|
||||||
end
|
end
|
||||||
function love.touchreleased(id,x,y)
|
function love.touchreleased(id,x,y)
|
||||||
@@ -207,40 +267,40 @@ function love.touchreleased(id,x,y)
|
|||||||
WIDGET.unFocus()
|
WIDGET.unFocus()
|
||||||
SCN.mainTouchID=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 fnKey={NULL,NULL,NULL,NULL,NULL,NULL,NULL}
|
||||||
local function noDevkeyPressed(key)
|
local function noDevkeyPressed(key)
|
||||||
if key=="f1"then fnKey[1]()
|
if key=='f1'then fnKey[1]()
|
||||||
elseif key=="f2"then fnKey[2]()
|
elseif key=='f2'then fnKey[2]()
|
||||||
elseif key=="f3"then fnKey[3]()
|
elseif key=='f3'then fnKey[3]()
|
||||||
elseif key=="f4"then fnKey[4]()
|
elseif key=='f4'then fnKey[4]()
|
||||||
elseif key=="f5"then fnKey[5]()
|
elseif key=='f5'then fnKey[5]()
|
||||||
elseif key=="f6"then fnKey[6]()
|
elseif key=='f6'then fnKey[6]()
|
||||||
elseif key=="f7"then fnKey[7]()
|
elseif key=='f7'then fnKey[7]()
|
||||||
elseif key=="f8"then devMode=nil MES.new('info',"DEBUG OFF",.2)
|
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=='f9'then devMode=1 MES.new('info',"DEBUG 1")
|
||||||
elseif key=="f10"then devMode=2 MES.new('info',"DEBUG 2")
|
elseif key=='f10'then devMode=2 MES.new('info',"DEBUG 2")
|
||||||
elseif key=="f11"then devMode=3 MES.new('info',"DEBUG 3")
|
elseif key=='f11'then devMode=3 MES.new('info',"DEBUG 3")
|
||||||
elseif key=="f12"then devMode=4 MES.new('info',"DEBUG 4")
|
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
|
||||||
@@ -254,22 +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
|
||||||
SETTING.fullscreen=not SETTING.fullscreen
|
SETTING.fullscreen=not SETTING.fullscreen
|
||||||
applyFullscreen()
|
applySettings()
|
||||||
saveSettings()
|
saveSettings()
|
||||||
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
|
||||||
|
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
|
||||||
|
if W and W.keypress then
|
||||||
|
W:keypress(key)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
elseif key=="escape"and not isRep then
|
|
||||||
SCN.back()
|
|
||||||
else
|
|
||||||
WIDGET.keyPressed(key,isRep)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -285,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
|
||||||
table.insert(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'},
|
||||||
table.remove(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',
|
||||||
@@ -304,65 +376,131 @@ 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 love.timer.getTime()-lastGCtime>6.26 then
|
collectgarbage()
|
||||||
collectgarbage()
|
if autoGCcount<3 then
|
||||||
lastGCtime=love.timer.getTime()
|
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()
|
FONT.reset()
|
||||||
|
onResize(w,h)
|
||||||
SHADER.warning:send('w',w*SCR.dpi)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local onFocus=NULL
|
local onFocus=NULL
|
||||||
@@ -376,7 +514,7 @@ end
|
|||||||
function love.errorhandler(msg)
|
function love.errorhandler(msg)
|
||||||
if type(msg)~='string'then
|
if type(msg)~='string'then
|
||||||
msg="Unknown error"
|
msg="Unknown error"
|
||||||
elseif msg:find("Invaild UTF-8")and text then
|
elseif msg:find("Invalid UTF-8")and text then
|
||||||
msg=text.tryAnotherBuild
|
msg=text.tryAnotherBuild
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -400,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"
|
||||||
table.insert(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) "..love.system.getOS().."-"..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
|
||||||
@@ -473,7 +611,7 @@ 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},
|
||||||
@@ -483,31 +621,23 @@ local wsBottomImage do
|
|||||||
table.insert(L,{'setCL',1,1,1,i*.005})
|
table.insert(L,{'setCL',1,1,1,i*.005})
|
||||||
table.insert(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)
|
||||||
|
wsImg.dead=GC.DO{20,20,
|
||||||
|
{'rawFT',20},
|
||||||
|
{'setCL',1,.3,.3},
|
||||||
|
{'mText',"X",11,-1},
|
||||||
|
}
|
||||||
|
wsImg.connecting=GC.DO{20,20,
|
||||||
|
{'rawFT',20},
|
||||||
|
{'setLW',3},
|
||||||
|
{'mText',"C",11,-1},
|
||||||
|
}
|
||||||
|
wsImg.running=GC.DO{20,20,
|
||||||
|
{'rawFT',20},
|
||||||
|
{'setCL',.5,1,0},
|
||||||
|
{'mText',"R",11,-1},
|
||||||
|
}
|
||||||
end
|
end
|
||||||
local ws_deadImg=GC.DO{20,20,
|
|
||||||
{'setFT',20},
|
|
||||||
{'setCL',1,.3,.3},
|
|
||||||
{'mText',"X",11,-1},
|
|
||||||
}
|
|
||||||
local ws_connectingImg=GC.DO{20,20,
|
|
||||||
{'setFT',20},
|
|
||||||
{'setLW',3},
|
|
||||||
{'mText',"C",11,-1},
|
|
||||||
}
|
|
||||||
local ws_runningImg=GC.DO{20,20,
|
|
||||||
{'setFT',20},
|
|
||||||
{'setCL',.5,1,0},
|
|
||||||
{'mText',"R",11,-1},
|
|
||||||
}
|
|
||||||
|
|
||||||
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 function showPowerInfo()return true end
|
|
||||||
local onQuit=NULL
|
|
||||||
|
|
||||||
function love.run()
|
function love.run()
|
||||||
local love=love
|
local love=love
|
||||||
@@ -519,12 +649,11 @@ 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 timer,SETTING,VERSION=love.timer.getTime,SETTING,VERSION
|
local timer,VERSION=love.timer.getTime,VERSION
|
||||||
|
|
||||||
local frameTimeList={}
|
local frameTimeList={}
|
||||||
local lastFrame=timer()
|
local lastFrame=timer()
|
||||||
@@ -536,7 +665,7 @@ 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 _
|
||||||
@@ -558,6 +687,8 @@ function love.run()
|
|||||||
|
|
||||||
--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(dt)
|
TEXT_update(dt)
|
||||||
@@ -571,11 +702,10 @@ function love.run()
|
|||||||
|
|
||||||
--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()
|
||||||
@@ -586,16 +716,14 @@ function love.run()
|
|||||||
TEXT_draw()
|
TEXT_draw()
|
||||||
|
|
||||||
--Draw cursor
|
--Draw cursor
|
||||||
if mouseShow then
|
if mouseShow then drawCursor(time,mx,my)end
|
||||||
drawCursor(time,mx,my)
|
|
||||||
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 showPowerInfo()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
|
||||||
@@ -606,10 +734,12 @@ 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)
|
||||||
FONT.set(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
|
||||||
FONT.set(15)
|
FONT.set(15)
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
@@ -620,9 +750,8 @@ 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)
|
|
||||||
|
|
||||||
--Update & draw frame time
|
--Update & draw frame time
|
||||||
table.insert(frameTimeList,1,dt)table.remove(frameTimeList,126)
|
table.insert(frameTimeList,1,dt)table.remove(frameTimeList,126)
|
||||||
@@ -650,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*math.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)
|
||||||
@@ -668,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 showPowerInfo()then
|
if showPowerInfo then
|
||||||
updatePowerInfo()
|
updatePowerInfo()
|
||||||
lastFreshPow=time
|
lastFreshPow=time
|
||||||
end
|
end
|
||||||
@@ -692,28 +821,44 @@ function love.run()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--Keep 60fps
|
|
||||||
_=timer()-lastFrame
|
_=timer()-lastFrame
|
||||||
if _<.0162 then WAIT(.0162-_)end
|
if _<sleepInterval*.9626 then WAIT(sleepInterval*.9626-_)end
|
||||||
while timer()-lastFrame<1/60 do end
|
while timer()-lastFrame<sleepInterval do end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local Z={}
|
local Z={}
|
||||||
|
|
||||||
function Z.setIfPowerInfo(func)showPowerInfo=func end
|
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.
|
--[Warning] Color and line width is uncertain value, set it in the function.
|
||||||
function Z.setCursor(func)drawCursor=func end
|
function Z.setCursor(func)drawCursor=func end
|
||||||
|
|
||||||
--Change F1~F7 events of devmode (F8 mode)
|
--Change F1~F7 events of devmode (F8 mode)
|
||||||
function Z.setOnFnKeys(list)
|
function Z.setOnFnKeys(list)
|
||||||
assert(type(list)=='table')
|
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
|
for i=1,7 do fnKey[i]=type(list[i])=='function'and list[i]or NULL end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Z.setOnFocus(func)onFocus=type(func)=='function'and func or NULL end
|
function Z.setOnFocus(func)onFocus=assert(type(func)=='function'and func,"Z.setOnFocus(func): func must be a function")end
|
||||||
|
|
||||||
function Z.setOnQuit(func)onQuit=type(func)=='function'and func or NULL 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
|
return Z
|
||||||
|
|||||||
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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -15,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,
|
||||||
|
|
||||||
@@ -52,14 +54,15 @@ function SCN.swapUpdate(dt)
|
|||||||
S.time=S.time-dt
|
S.time=S.time-dt
|
||||||
if S.time<S.changeTime and S.time+dt>=S.changeTime then
|
if S.time<S.changeTime and S.time+dt>=S.changeTime then
|
||||||
--Scene swapped this frame
|
--Scene swapped this frame
|
||||||
SCN.init(S.tar,SCN.cur)
|
SCN.prev=SCN.cur
|
||||||
|
SCN.init(S.tar)
|
||||||
SCN.mainTouchID=nil
|
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]
|
||||||
@@ -89,7 +92,7 @@ function SCN.init(s,org)
|
|||||||
SCN.update=S.update
|
SCN.update=S.update
|
||||||
SCN.draw=S.draw
|
SCN.draw=S.draw
|
||||||
if S.sceneInit then
|
if S.sceneInit then
|
||||||
S.sceneInit(org)
|
S.sceneInit()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function SCN.push(tar,style)
|
function SCN.push(tar,style)
|
||||||
@@ -165,11 +168,12 @@ local swap={
|
|||||||
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
|
||||||
style=style or'fade'
|
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
|
||||||
@@ -180,15 +184,15 @@ 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
|
||||||
@@ -199,7 +203,7 @@ function SCN.back()
|
|||||||
--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,4 +1,6 @@
|
|||||||
local type,rem=type,table.remove
|
local type,rem=type,table.remove
|
||||||
|
local int,rnd=math.floor,math.random
|
||||||
|
local interval=MATH.interval
|
||||||
|
|
||||||
local sfxList={}
|
local sfxList={}
|
||||||
local packSetting={}
|
local packSetting={}
|
||||||
@@ -6,7 +8,7 @@ local Sources={}
|
|||||||
local volume=1
|
local volume=1
|
||||||
local stereo=1
|
local stereo=1
|
||||||
|
|
||||||
local noteName={
|
local noteVal={
|
||||||
C=1,c=1,
|
C=1,c=1,
|
||||||
D=3,d=3,
|
D=3,d=3,
|
||||||
E=5,e=5,
|
E=5,e=5,
|
||||||
@@ -15,10 +17,11 @@ local noteName={
|
|||||||
A=10,a=10,
|
A=10,a=10,
|
||||||
B=12,b=12,
|
B=12,b=12,
|
||||||
}
|
}
|
||||||
|
local noteName={'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
|
||||||
local function _getTuneHeight(tune)
|
local function _getTuneHeight(tune)
|
||||||
local octave=tonumber(tune:sub(-1,-1))
|
local octave=tonumber(tune:sub(-1,-1))
|
||||||
if octave then
|
if octave then
|
||||||
local tuneHeight=noteName[tune:sub(1,1)]
|
local tuneHeight=noteVal[tune:sub(1,1)]
|
||||||
if tuneHeight then
|
if tuneHeight then
|
||||||
tuneHeight=tuneHeight+(octave-1)*12
|
tuneHeight=tuneHeight+(octave-1)*12
|
||||||
local s=tune:sub(2,2)
|
local s=tune:sub(2,2)
|
||||||
@@ -40,29 +43,41 @@ function SFX.init(list)
|
|||||||
end
|
end
|
||||||
function SFX.load(path)
|
function SFX.load(path)
|
||||||
local c=0
|
local c=0
|
||||||
|
local missing=0
|
||||||
for i=1,#sfxList do
|
for i=1,#sfxList do
|
||||||
local fullPath=path..sfxList[i]..'.ogg'
|
local fullPath=path..sfxList[i]..'.ogg'
|
||||||
if love.filesystem.getInfo(fullPath)then
|
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')}
|
Sources[sfxList[i]]={love.audio.newSource(fullPath,'static')}
|
||||||
c=c+1
|
c=c+1
|
||||||
else
|
else
|
||||||
LOG("No SFX: "..sfxList[i]..'.ogg',.1)
|
LOG("No SFX: "..sfxList[i]..'.ogg',.1)
|
||||||
|
missing=missing+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
LOG(c.."/"..#sfxList.." SFX files loaded")
|
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
|
end
|
||||||
function SFX.loadSample(pack)
|
function SFX.loadSample(pack)
|
||||||
assert(type(pack)=='table',"Usage: SFX.loadsample([table])")
|
assert(type(pack)=='table',"Usage: SFX.loadsample([table])")
|
||||||
assert(pack.name,"No field: name")
|
assert(pack.name,"No field: name")
|
||||||
assert(pack.path,"No field: path")
|
assert(pack.path,"No field: path")
|
||||||
packSetting[pack.name]={
|
|
||||||
base=(_getTuneHeight(pack.base)or 37)-1,
|
|
||||||
}
|
|
||||||
local num=1
|
local num=1
|
||||||
while love.filesystem.getInfo(pack.path..'/'..num..'.ogg')do
|
while love.filesystem.getInfo(pack.path..'/'..num..'.ogg')do
|
||||||
Sources[pack.name..num]={love.audio.newSource(pack.path..'/'..num..'.ogg','static')}
|
Sources[pack.name..num]={love.audio.newSource(pack.path..'/'..num..'.ogg','static')}
|
||||||
num=num+1
|
num=num+1
|
||||||
end
|
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")
|
LOG((num-1).." "..pack.name.." samples loaded")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -70,31 +85,47 @@ function SFX.getCount()
|
|||||||
return #sfxList
|
return #sfxList
|
||||||
end
|
end
|
||||||
function SFX.setVol(v)
|
function SFX.setVol(v)
|
||||||
assert(type(v)=='number'and v>=0 and v<=1)
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
volume=v
|
volume=v
|
||||||
end
|
end
|
||||||
function SFX.setStereo(v)
|
function SFX.setStereo(v)
|
||||||
assert(type(v)=='number'and v>=0 and v<=1)
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong stereo')
|
||||||
stereo=v
|
stereo=v
|
||||||
end
|
end
|
||||||
|
|
||||||
function SFX.playSample(pack,...)--vol-2, sampSet1, vol-3, sampSet2, vol-1
|
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
|
if ... then
|
||||||
local arg={...}
|
local arg={...}
|
||||||
local vol
|
local vol
|
||||||
if type(arg[#arg])=='number'then vol=rem(arg)end
|
|
||||||
for i=1,#arg do
|
for i=1,#arg do
|
||||||
if type(arg[i])=='number'then
|
local a=arg[i]
|
||||||
vol=arg[i]
|
if type(a)=='number'and a<=1 then
|
||||||
|
vol=a
|
||||||
else
|
else
|
||||||
local tune=arg[i]
|
local base=packSetting[pack].base
|
||||||
tune=_getTuneHeight(tune)-packSetting[pack].base
|
local top=packSetting[pack].top
|
||||||
SFX.play(pack..tune,vol)
|
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function SFX.play(name,vol,pos)
|
local function _play(name,vol,pos,pitch)
|
||||||
if volume==0 or vol==0 then return end
|
if volume==0 or vol==0 then return end
|
||||||
local S=Sources[name]--Source list
|
local S=Sources[name]--Source list
|
||||||
if not S then return end
|
if not S then return end
|
||||||
@@ -110,39 +141,20 @@ function SFX.play(name,vol,pos)
|
|||||||
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*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)*volume)^1.626)
|
|
||||||
S:play()
|
|
||||||
end
|
|
||||||
function SFX.fplay(name,vol,pos)
|
|
||||||
local S=Sources[name]--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*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
|
||||||
|
|||||||
@@ -2,9 +2,25 @@ local data=love.data
|
|||||||
local STRING={}
|
local STRING={}
|
||||||
local assert,tostring,tonumber=assert,tostring,tonumber
|
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']='%',
|
||||||
@@ -63,9 +79,9 @@ function STRING.time(t)
|
|||||||
if t<60 then
|
if t<60 then
|
||||||
return format("%.3f\"",t)
|
return format("%.3f\"",t)
|
||||||
elseif t<3600 then
|
elseif t<3600 then
|
||||||
return format("%d'%05.2f\"",int(t/60),t%60)
|
return format("%d'%05.2f\"",int(t/60),int(t%60*100)/100)
|
||||||
else
|
else
|
||||||
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),t%60)
|
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),int(t%60*100)/100)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -153,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")
|
||||||
@@ -162,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))
|
||||||
|
|||||||
@@ -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={}
|
||||||
|
|
||||||
@@ -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,7 +84,7 @@ 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=1,#G do
|
for i=1,#G do
|
||||||
G[i]=nil
|
G[i]=nil
|
||||||
@@ -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={
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function TASK.update(dt)
|
|||||||
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,5 +1,7 @@
|
|||||||
|
local rnd=math.random
|
||||||
|
local volume=1
|
||||||
|
local diversion=0
|
||||||
local VOC={
|
local VOC={
|
||||||
vol=1,
|
|
||||||
getCount=function()return 0 end,
|
getCount=function()return 0 end,
|
||||||
getQueueCount=function()return 0 end,
|
getQueueCount=function()return 0 end,
|
||||||
load=function()error("Cannot load before init!")end,
|
load=function()error("Cannot load before init!")end,
|
||||||
@@ -7,13 +9,16 @@ local VOC={
|
|||||||
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)
|
function VOC.setVol(v)
|
||||||
assert(type(v)=='number'and v>=0 and v<=1)
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||||
VOC.vol=v
|
volume=v
|
||||||
end
|
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},...}
|
||||||
@@ -72,7 +77,7 @@ function VOC.init(list)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function VOC.play(s,chn)
|
function VOC.play(s,chn)
|
||||||
if VOC.vol>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
|
||||||
@@ -95,13 +100,15 @@ function VOC.init(list)
|
|||||||
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(VOC.vol)
|
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(VOC.vol)
|
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
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ return function(y,key1,key2)
|
|||||||
trigDist=min(trigDist,0)-(-y)^1.2
|
trigDist=min(trigDist,0)-(-y)^1.2
|
||||||
end
|
end
|
||||||
while trigDist>=1 do
|
while trigDist>=1 do
|
||||||
love.keypressed(key1 or"up")
|
love.keypressed(key1 or'up')
|
||||||
trigDist=trigDist-1
|
trigDist=trigDist-1
|
||||||
end
|
end
|
||||||
while trigDist<=-1 do
|
while trigDist<=-1 do
|
||||||
love.keypressed(key2 or"down")
|
love.keypressed(key2 or'down')
|
||||||
trigDist=trigDist+1
|
trigDist=trigDist+1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,13 +13,13 @@ local kb=love.keyboard
|
|||||||
local timer=love.timer.getTime
|
local timer=love.timer.getTime
|
||||||
|
|
||||||
local next=next
|
local next=next
|
||||||
local int,ceil,abs=math.floor,math.ceil,math.abs
|
local int,ceil=math.floor,math.ceil
|
||||||
local max,min=math.max,math.min
|
local max,min=math.max,math.min
|
||||||
local sub,ins,rem=string.sub,table.insert,table.remove
|
local sub,ins,rem=string.sub,table.insert,table.remove
|
||||||
local mDraw,mDraw_X,mDraw_Y=GC.draw,GC.simpX,GC.simpY
|
|
||||||
local xOy=SCR.xOy
|
local xOy=SCR.xOy
|
||||||
local FONT=FONT
|
local FONT=FONT
|
||||||
local mStr=GC.mStr
|
local mStr=GC.mStr
|
||||||
|
local approach=MATH.expApproach
|
||||||
|
|
||||||
local downArrowIcon=GC.DO{40,25,{'fPoly',0,0,20,25,40,0}}
|
local downArrowIcon=GC.DO{40,25,{'fPoly',0,0,20,25,40,0}}
|
||||||
local upArrowIcon=GC.DO{40,25,{'fPoly',0,25,20,0,40,25}}
|
local upArrowIcon=GC.DO{40,25,{'fPoly',0,25,20,0,40,25}}
|
||||||
@@ -29,7 +29,7 @@ local clearIcon=GC.DO{40,40,
|
|||||||
{'fRect',11,14,18,21},
|
{'fRect',11,14,18,21},
|
||||||
}
|
}
|
||||||
local sureIcon=GC.DO{40,40,
|
local sureIcon=GC.DO{40,40,
|
||||||
{'setFT',35},
|
{'rawFT',35},
|
||||||
{'mText',"?",20,0},
|
{'mText',"?",20,0},
|
||||||
}
|
}
|
||||||
local smallerThen=GC.DO{20,20,
|
local smallerThen=GC.DO{20,20,
|
||||||
@@ -46,7 +46,12 @@ local function _rectangleStencil()
|
|||||||
gc.rectangle('fill',1,1,STW-2,STH-2)
|
gc.rectangle('fill',1,1,STW-2,STH-2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local onChange=NULL
|
||||||
|
|
||||||
local WIDGET={}
|
local WIDGET={}
|
||||||
|
|
||||||
|
function WIDGET.setOnChange(func)onChange=assert(type(func)=='function'and func,"WIDGET.setOnChange(func): func must be a function")end
|
||||||
|
|
||||||
local widgetMetatable={
|
local widgetMetatable={
|
||||||
__tostring=function(self)
|
__tostring=function(self)
|
||||||
return self:getInfo()
|
return self:getInfo()
|
||||||
@@ -73,24 +78,28 @@ function text:draw()
|
|||||||
if self.alpha>0 then
|
if self.alpha>0 then
|
||||||
local c=self.color
|
local c=self.color
|
||||||
gc_setColor(c[1],c[2],c[3],self.alpha)
|
gc_setColor(c[1],c[2],c[3],self.alpha)
|
||||||
|
local w=self.obj:getWidth()
|
||||||
|
local k=min(self.lim/self.obj:getWidth(),1)
|
||||||
if self.align=='M'then
|
if self.align=='M'then
|
||||||
mDraw_X(self.obj,self.x,self.y)
|
gc_draw(self.obj,self.x,self.y,nil,k,1,w*.5,0)
|
||||||
elseif self.align=='L'then
|
elseif self.align=='L'then
|
||||||
gc_draw(self.obj,self.x,self.y)
|
gc_draw(self.obj,self.x,self.y,nil,k,1)
|
||||||
elseif self.align=='R'then
|
elseif self.align=='R'then
|
||||||
gc_draw(self.obj,self.x-self.obj:getWidth(),self.y)
|
gc_draw(self.obj,self.x,self.y,nil,k,1,w,0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.newText(D)--name,x,y[,fText][,color][,font=30][,align='M'][,hideF][,hide]
|
function WIDGET.newText(D)--name,x,y[,lim][,fText][,color][,font=30][,fType][,align='M'][,hideF][,hide]
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
x= D.x,
|
x= D.x,
|
||||||
y= D.y,
|
y= D.y,
|
||||||
|
lim= D.lim or 1e99,
|
||||||
|
|
||||||
fText=D.fText,
|
fText=D.fText,
|
||||||
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
|
fType=D.fType,
|
||||||
align=D.align or'M',
|
align=D.align or'M',
|
||||||
hideF=D.hideF,
|
hideF=D.hideF,
|
||||||
}
|
}
|
||||||
@@ -139,7 +148,7 @@ function button:reset()
|
|||||||
end
|
end
|
||||||
function button:setObject(obj)
|
function button:setObject(obj)
|
||||||
if type(obj)=='string'or type(obj)=='number'then
|
if type(obj)=='string'or type(obj)=='number'then
|
||||||
self.obj=gc.newText(FONT.get(self.font),obj)
|
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
|
||||||
elseif obj then
|
elseif obj then
|
||||||
self.obj=obj
|
self.obj=obj
|
||||||
end
|
end
|
||||||
@@ -148,9 +157,9 @@ function button:isAbove(x,y)
|
|||||||
local ATV=self.ATV
|
local ATV=self.ATV
|
||||||
return
|
return
|
||||||
x>self.x-ATV and
|
x>self.x-ATV and
|
||||||
y>self.y-ATV and
|
y>self.y and
|
||||||
x<self.x+self.w+2*ATV and
|
x<self.x+self.w+2*ATV and
|
||||||
y<self.y+self.h+2*ATV
|
y<self.y+self.h
|
||||||
end
|
end
|
||||||
function button:getCenter()
|
function button:getCenter()
|
||||||
return self.x+self.w*.5,self.y+self.h*.5
|
return self.x+self.w*.5,self.y+self.h*.5
|
||||||
@@ -171,45 +180,49 @@ function button:draw()
|
|||||||
|
|
||||||
--Button
|
--Button
|
||||||
gc_setColor(.15+r*.7,.15+g*.7,.15+b*.7,.9)
|
gc_setColor(.15+r*.7,.15+g*.7,.15+b*.7,.9)
|
||||||
gc_rectangle('fill',x-ATV,y-ATV,w+2*ATV,h+2*ATV,3)
|
gc_rectangle('fill',x-ATV,y,w+2*ATV,h,4)
|
||||||
|
gc_setLineWidth(2)
|
||||||
|
gc_setColor(.3+r*.7,.3+g*.7,.3+b*.7)
|
||||||
|
gc_rectangle('line',x-ATV,y,w+2*ATV,h,5)
|
||||||
if ATV>0 then
|
if ATV>0 then
|
||||||
gc_setLineWidth(2)
|
|
||||||
gc_setColor(.97,.97,.97,ATV*.125)
|
gc_setColor(.97,.97,.97,ATV*.125)
|
||||||
gc_rectangle('line',x-ATV+2,y-ATV+2,w+2*ATV-4,h+2*ATV-4,3)
|
gc_rectangle('line',x-ATV,y,w+2*ATV,h,3)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Drawable
|
--Drawable
|
||||||
local obj=self.obj
|
local obj=self.obj
|
||||||
local y0=y+h*.5-ATV*.5
|
local ox,oy=obj:getWidth()*.5,obj:getHeight()*.5
|
||||||
|
local y0=y+h*.5
|
||||||
gc_setColor(1,1,1,.2+ATV*.05)
|
gc_setColor(1,1,1,.2+ATV*.05)
|
||||||
if self.align=='M'then
|
if self.align=='M'then
|
||||||
local x0=x+w*.5
|
local x0=x+w*.5
|
||||||
mDraw(obj,x0-1,y0-1)
|
local kx=obj:type()=='Text'and min(w/ox/2,1)or 1
|
||||||
mDraw(obj,x0-1,y0+1)
|
gc_draw(obj,x0-1,y0-1,nil,kx,1,ox,oy)
|
||||||
mDraw(obj,x0+1,y0-1)
|
gc_draw(obj,x0-1,y0+1,nil,kx,1,ox,oy)
|
||||||
mDraw(obj,x0+1,y0+1)
|
gc_draw(obj,x0+1,y0-1,nil,kx,1,ox,oy)
|
||||||
|
gc_draw(obj,x0+1,y0+1,nil,kx,1,ox,oy)
|
||||||
gc_setColor(r*.55,g*.55,b*.55)
|
gc_setColor(r*.55,g*.55,b*.55)
|
||||||
mDraw(obj,x0,y0)
|
gc_draw(obj,x0,y0,nil,kx,1,ox,oy)
|
||||||
elseif self.align=='L'then
|
elseif self.align=='L'then
|
||||||
local edge=self.edge
|
local edge=self.edge
|
||||||
mDraw_Y(obj,x+edge-1,y0-1)
|
gc_draw(obj,x+edge-1,y0-1-oy)
|
||||||
mDraw_Y(obj,x+edge-1,y0+1)
|
gc_draw(obj,x+edge-1,y0+1-oy)
|
||||||
mDraw_Y(obj,x+edge+1,y0-1)
|
gc_draw(obj,x+edge+1,y0-1-oy)
|
||||||
mDraw_Y(obj,x+edge+1,y0+1)
|
gc_draw(obj,x+edge+1,y0+1-oy)
|
||||||
gc_setColor(r*.55,g*.55,b*.55)
|
gc_setColor(r*.55,g*.55,b*.55)
|
||||||
mDraw_Y(obj,x+edge,y0)
|
gc_draw(obj,x+edge,y0-oy)
|
||||||
elseif self.align=='R'then
|
elseif self.align=='R'then
|
||||||
local x0=x+w-self.edge-obj:getWidth()
|
local x0=x+w-self.edge-ox*2
|
||||||
mDraw_Y(obj,x0-1,y0-1)
|
gc_draw(obj,x0-1,y0-1-oy)
|
||||||
mDraw_Y(obj,x0-1,y0+1)
|
gc_draw(obj,x0-1,y0+1-oy)
|
||||||
mDraw_Y(obj,x0+1,y0-1)
|
gc_draw(obj,x0+1,y0-1-oy)
|
||||||
mDraw_Y(obj,x0+1,y0+1)
|
gc_draw(obj,x0+1,y0+1-oy)
|
||||||
gc_setColor(r*.55,g*.55,b*.55)
|
gc_setColor(r*.55,g*.55,b*.55)
|
||||||
mDraw_Y(obj,x0,y0)
|
gc_draw(obj,x0,y0-oy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function button:getInfo()
|
function button:getInfo()
|
||||||
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
|
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
|
||||||
end
|
end
|
||||||
function button:press(_,_,k)
|
function button:press(_,_,k)
|
||||||
self.code(k)
|
self.code(k)
|
||||||
@@ -217,15 +230,15 @@ function button:press(_,_,k)
|
|||||||
SYSFX.newRectRipple(
|
SYSFX.newRectRipple(
|
||||||
6,
|
6,
|
||||||
self.x-ATV,
|
self.x-ATV,
|
||||||
self.y-ATV-WIDGET.scrollPos,
|
self.y-WIDGET.scrollPos,
|
||||||
self.w+2*ATV,
|
self.w+2*ATV,
|
||||||
self.h+2*ATV
|
self.h
|
||||||
)
|
)
|
||||||
if self.sound then
|
if self.sound then
|
||||||
SFX.play('button')
|
SFX.play(self.sound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
|
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,fType][,sound][,align='M'][,edge=0][,code][,hideF][,hide]
|
||||||
if not D.h then D.h=D.w end
|
if not D.h then D.h=D.w end
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
@@ -246,13 +259,21 @@ function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=tr
|
|||||||
fText=D.fText,
|
fText=D.fText,
|
||||||
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
|
fType=D.fType,
|
||||||
align=D.align or'M',
|
align=D.align or'M',
|
||||||
edge= D.edge or 0,
|
edge= D.edge or 0,
|
||||||
sound=D.sound~=false,
|
code= D.code or NULL,
|
||||||
code= D.code,
|
|
||||||
hideF=D.hideF,
|
hideF=D.hideF,
|
||||||
hide= D.hide,
|
hide= D.hide,
|
||||||
}
|
}
|
||||||
|
if D.sound==false then
|
||||||
|
_.sound=false
|
||||||
|
elseif type(D.sound)=='string'then
|
||||||
|
_.sound=D.sound
|
||||||
|
else
|
||||||
|
_.sound='button'
|
||||||
|
end
|
||||||
|
|
||||||
for k,v in next,button do _[k]=v end
|
for k,v in next,button do _[k]=v end
|
||||||
setmetatable(_,widgetMetatable)
|
setmetatable(_,widgetMetatable)
|
||||||
return _
|
return _
|
||||||
@@ -268,7 +289,7 @@ function key:reset()
|
|||||||
end
|
end
|
||||||
function key:setObject(obj)
|
function key:setObject(obj)
|
||||||
if type(obj)=='string'or type(obj)=='number'then
|
if type(obj)=='string'or type(obj)=='number'then
|
||||||
self.obj=gc.newText(FONT.get(self.font),obj)
|
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
|
||||||
elseif obj then
|
elseif obj then
|
||||||
self.obj=obj
|
self.obj=obj
|
||||||
end
|
end
|
||||||
@@ -298,48 +319,54 @@ function key:draw()
|
|||||||
local align=self.align
|
local align=self.align
|
||||||
local r,g,b=c[1],c[2],c[3]
|
local r,g,b=c[1],c[2],c[3]
|
||||||
|
|
||||||
--Frame
|
|
||||||
if not self.noFrame then
|
|
||||||
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
|
|
||||||
gc_setLineWidth(2)
|
|
||||||
gc_rectangle('line',x,y,w,h,3)
|
|
||||||
end
|
|
||||||
|
|
||||||
--Fill
|
--Fill
|
||||||
if self.fShade then
|
if self.fShade then
|
||||||
gc_setColor(r,g,b,ATV*.25)
|
gc_setColor(r,g,b,ATV*.25)
|
||||||
if align=='M'then
|
if align=='M'then
|
||||||
mDraw(self.fShade,x+w*.5,y+h*.5)
|
gc_draw(self.fShade,x+w*.5-self.fShade:getWidth()*.5,y+h*.5-self.fShade:getHeight()*.5)
|
||||||
elseif align=='L'then
|
elseif align=='L'then
|
||||||
mDraw_Y(self.fShade,x+self.edge,y+h*.5)
|
gc_draw(self.fShade,x+self.edge,y+h*.5-self.fShade:getHeight()*.5)
|
||||||
elseif align=='R'then
|
elseif align=='R'then
|
||||||
mDraw_Y(self.fShade,x+w-self.edge-self.fShade:getWidth(),y+h*.5)
|
gc_draw(self.fShade,x+w-self.edge-self.fShade:getWidth(),y+h*.5-self.fShade:getHeight()*.5)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
--Background
|
||||||
|
gc_setColor(0,0,0,.3)
|
||||||
|
gc_rectangle('fill',x,y,w,h,4)
|
||||||
|
|
||||||
|
--Frame
|
||||||
|
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
|
||||||
|
gc_setLineWidth(2)
|
||||||
|
gc_rectangle('line',x,y,w,h,3)
|
||||||
|
|
||||||
|
--Shade
|
||||||
gc_setColor(1,1,1,ATV*.05)
|
gc_setColor(1,1,1,ATV*.05)
|
||||||
gc_rectangle('fill',x,y,w,h,3)
|
gc_rectangle('fill',x,y,w,h,3)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Drawable
|
--Drawable
|
||||||
|
local obj=self.obj
|
||||||
|
local ox,oy=obj:getWidth()*.5,obj:getHeight()*.5
|
||||||
gc_setColor(r,g,b)
|
gc_setColor(r,g,b)
|
||||||
if align=='M'then
|
if align=='M'then
|
||||||
mDraw(self.obj,x+w*.5,y+h*.5)
|
local kx=obj:type()=='Text'and min(w/ox/2,1)or 1
|
||||||
|
gc_draw(obj,x+w*.5,y+h*.5,nil,kx,1,ox,oy)
|
||||||
elseif align=='L'then
|
elseif align=='L'then
|
||||||
mDraw_Y(self.obj,x+self.edge,y+h*.5)
|
gc_draw(obj,x+self.edge,y-oy+h*.5)
|
||||||
elseif align=='R'then
|
elseif align=='R'then
|
||||||
mDraw_Y(self.obj,x+w-self.edge-self.obj:getWidth(),y+h*.5)
|
gc_draw(obj,x+w-self.edge-ox*2,y-oy+h*.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function key:getInfo()
|
function key:getInfo()
|
||||||
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
|
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
|
||||||
end
|
end
|
||||||
function key:press(_,_,k)
|
function key:press(_,_,k)
|
||||||
self.code(k)
|
self.code(k)
|
||||||
if self.sound then
|
if self.sound then
|
||||||
SFX.play('key')
|
SFX.play(self.sound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
|
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,color][,font=30][,fType][,sound][,align='M'][,edge=0][,code][,hideF][,hide]
|
||||||
if not D.h then D.h=D.w end
|
if not D.h then D.h=D.w end
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
@@ -359,16 +386,22 @@ function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,fo
|
|||||||
|
|
||||||
fText= D.fText,
|
fText= D.fText,
|
||||||
fShade= D.fShade,
|
fShade= D.fShade,
|
||||||
noFrame=D.noFrame,
|
|
||||||
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
sound= D.sound~=false,
|
fType= D.fType,
|
||||||
align= D.align or'M',
|
align= D.align or'M',
|
||||||
edge= D.edge or 0,
|
edge= D.edge or 0,
|
||||||
code= D.code,
|
code= D.code or NULL,
|
||||||
hideF= D.hideF,
|
hideF= D.hideF,
|
||||||
hide= D.hide,
|
hide= D.hide,
|
||||||
}
|
}
|
||||||
|
if D.sound==false then
|
||||||
|
_.sound=false
|
||||||
|
elseif type(D.sound)=='string'then
|
||||||
|
_.sound=D.sound
|
||||||
|
else
|
||||||
|
_.sound='key'
|
||||||
|
end
|
||||||
for k,v in next,key do _[k]=v end
|
for k,v in next,key do _[k]=v end
|
||||||
setmetatable(_,widgetMetatable)
|
setmetatable(_,widgetMetatable)
|
||||||
return _
|
return _
|
||||||
@@ -408,6 +441,10 @@ function switch:draw()
|
|||||||
local x,y=self.x,self.y
|
local x,y=self.x,self.y
|
||||||
local ATV=self.ATV
|
local ATV=self.ATV
|
||||||
|
|
||||||
|
--Background
|
||||||
|
gc_setColor(0,0,0,.3)
|
||||||
|
gc_rectangle('fill',x,y-25,50,50,4)
|
||||||
|
|
||||||
--Frame
|
--Frame
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
gc_setColor(1,1,1,.6+ATV*.1)
|
gc_setColor(1,1,1,.6+ATV*.1)
|
||||||
@@ -430,15 +467,15 @@ function switch:draw()
|
|||||||
gc_draw(obj,x-12-ATV,y,nil,min(self.lim/obj:getWidth(),1),1,obj:getWidth(),obj:getHeight()*.5)
|
gc_draw(obj,x-12-ATV,y,nil,min(self.lim/obj:getWidth(),1),1,obj:getWidth(),obj:getHeight()*.5)
|
||||||
end
|
end
|
||||||
function switch:getInfo()
|
function switch:getInfo()
|
||||||
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font)
|
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font,self.fType)
|
||||||
end
|
end
|
||||||
function switch:press()
|
function switch:press()
|
||||||
self.code()
|
self.code()
|
||||||
if self.sound then
|
if self.sound then
|
||||||
SFX.play('move')
|
SFX.play(self.disp()and'check'or'uncheck')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=true][,disp],code[,hideF][,hide]
|
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,fType][,sound=true][,disp][,code][,hideF][,hide]
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -453,9 +490,10 @@ function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=tr
|
|||||||
fText=D.fText,
|
fText=D.fText,
|
||||||
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
|
fType=D.fType,
|
||||||
sound=D.sound~=false,
|
sound=D.sound~=false,
|
||||||
disp= D.disp,
|
disp= D.disp,
|
||||||
code= D.code,
|
code= D.code or NULL,
|
||||||
hideF=D.hideF,
|
hideF=D.hideF,
|
||||||
hide= D.hide,
|
hide= D.hide,
|
||||||
}
|
}
|
||||||
@@ -491,7 +529,7 @@ function slider:isAbove(x,y)
|
|||||||
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-25 and y<self.y+25
|
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-25 and y<self.y+25
|
||||||
end
|
end
|
||||||
function slider:getCenter()
|
function slider:getCenter()
|
||||||
return self.x+self.w*(self.pos/self.unit),self.y
|
return self.x+self.w*((self.pos-self.rangeL)/(self.rangeR-self.rangeL)),self.y
|
||||||
end
|
end
|
||||||
function slider:update(dt)
|
function slider:update(dt)
|
||||||
local ATV=self.ATV
|
local ATV=self.ATV
|
||||||
@@ -505,7 +543,7 @@ function slider:update(dt)
|
|||||||
if ATV>0 then self.ATV=max(ATV-dt*30,0)end
|
if ATV>0 then self.ATV=max(ATV-dt*30,0)end
|
||||||
end
|
end
|
||||||
if not self.hide then
|
if not self.hide then
|
||||||
self.pos=self.pos*.7+self.disp()*.3
|
self.pos=approach(self.pos,self.disp(),dt*26)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function slider:draw()
|
function slider:draw()
|
||||||
@@ -518,8 +556,8 @@ function slider:draw()
|
|||||||
--Units
|
--Units
|
||||||
if not self.smooth then
|
if not self.smooth then
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
for p=0,self.unit do
|
for p=self.rangeL,self.rangeR,self.unit do
|
||||||
local X=x+(x2-x)*p/self.unit
|
local X=x+(x2-x)*(p-self.rangeL)/(self.rangeR-self.rangeL)
|
||||||
gc_line(X,y+7,X,y-7)
|
gc_line(X,y+7,X,y-7)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -529,7 +567,7 @@ function slider:draw()
|
|||||||
gc_line(x,y,x2,y)
|
gc_line(x,y,x2,y)
|
||||||
|
|
||||||
--Block
|
--Block
|
||||||
local cx=x+(x2-x)*self.pos/self.unit
|
local cx=x+(x2-x)*(self.pos-self.rangeL)/(self.rangeR-self.rangeL)
|
||||||
local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV
|
local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV
|
||||||
gc_setColor(.8,.8,.8)
|
gc_setColor(.8,.8,.8)
|
||||||
gc_rectangle('fill',bx,by,bw,bh,3)
|
gc_rectangle('fill',bx,by,bw,bh,3)
|
||||||
@@ -564,13 +602,16 @@ end
|
|||||||
function slider:drag(x)
|
function slider:drag(x)
|
||||||
if not x then return end
|
if not x then return end
|
||||||
x=x-self.x
|
x=x-self.x
|
||||||
local p=self.disp()
|
local newPos=MATH.interval(x/self.w,0,1)
|
||||||
local P=x<0 and 0 or x>self.w and self.unit or x/self.w*self.unit
|
local newVal
|
||||||
if not self.smooth then
|
if not self.unit then
|
||||||
P=int(P+.5)
|
newVal=(1-newPos)*self.rangeL+newPos*self.rangeR
|
||||||
|
else
|
||||||
|
newVal=newPos*(self.rangeR-self.rangeL)
|
||||||
|
newVal=self.rangeL+newVal-newVal%self.unit
|
||||||
end
|
end
|
||||||
if p~=P then
|
if newVal~=self.disp()then
|
||||||
self.code(P)
|
self.code(newVal)
|
||||||
end
|
end
|
||||||
if self.change and timer()-self.lastTime>.5 then
|
if self.change and timer()-self.lastTime>.5 then
|
||||||
self.lastTime=timer()
|
self.lastTime=timer()
|
||||||
@@ -583,8 +624,8 @@ function slider:release(x)
|
|||||||
end
|
end
|
||||||
function slider:scroll(n)
|
function slider:scroll(n)
|
||||||
local p=self.disp()
|
local p=self.disp()
|
||||||
local u=self.smooth and .01 or 1
|
local u=self.unit or .01
|
||||||
local P=n==-1 and max(p-u,0)or min(p+u,self.unit)
|
local P=MATH.interval(p+u*n,self.rangeL,self.rangeR)
|
||||||
if p==P or not P then return end
|
if p==P or not P then return end
|
||||||
self.code(P)
|
self.code(P)
|
||||||
if self.change and timer()-self.lastTime>.18 then
|
if self.change and timer()-self.lastTime>.18 then
|
||||||
@@ -593,9 +634,15 @@ function slider:scroll(n)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
function slider:arrowKey(k)
|
function slider:arrowKey(k)
|
||||||
self:scroll((k=="left"or k=="up")and -1 or 1)
|
self:scroll((k=='left'or k=='up')and -1 or 1)
|
||||||
end
|
end
|
||||||
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,font=30][,change],disp[,show],code,hide
|
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,axis][,smooth][,font=30][,fType][,change],disp[,show][,code],hide
|
||||||
|
if not D.axis then
|
||||||
|
D.axis={0,1,false}
|
||||||
|
D.smooth=true
|
||||||
|
elseif not D.axis[3]then
|
||||||
|
D.smooth=true
|
||||||
|
end
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -614,32 +661,30 @@ function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,
|
|||||||
|
|
||||||
fText= D.fText,
|
fText= D.fText,
|
||||||
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||||
unit= D.unit or 1,
|
rangeL=D.axis[1],
|
||||||
smooth=false,
|
rangeR=D.axis[2],
|
||||||
|
unit= D.axis[3],
|
||||||
|
smooth=D.smooth,
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
|
fType= D.fType,
|
||||||
change=D.change,
|
change=D.change,
|
||||||
disp= D.disp,
|
disp= D.disp,
|
||||||
code= D.code,
|
code= D.code or NULL,
|
||||||
hideF= D.hideF,
|
hideF= D.hideF,
|
||||||
hide= D.hide,
|
hide= D.hide,
|
||||||
show= false,
|
show= false,
|
||||||
}
|
}
|
||||||
if D.smooth~=nil then
|
|
||||||
_.smooth=D.smooth
|
|
||||||
else
|
|
||||||
_.smooth=_.unit<=1
|
|
||||||
end
|
|
||||||
if D.show then
|
if D.show then
|
||||||
if type(D.show)=='function'then
|
if type(D.show)=='function'then
|
||||||
_.show=D.show
|
_.show=D.show
|
||||||
else
|
else
|
||||||
_.show=sliderShowFunc[D.show]
|
_.show=sliderShowFunc[D.show]
|
||||||
end
|
end
|
||||||
elseif D.show~=false then
|
elseif D.show~=false then--Use default if nil
|
||||||
if _.unit<=1 then
|
if _.unit and _.unit%1==0 then
|
||||||
_.show=sliderShowFunc.percent
|
|
||||||
else
|
|
||||||
_.show=sliderShowFunc.int
|
_.show=sliderShowFunc.int
|
||||||
|
else
|
||||||
|
_.show=sliderShowFunc.percent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for k,v in next,slider do _[k]=v end
|
for k,v in next,slider do _[k]=v end
|
||||||
@@ -691,6 +736,10 @@ function selector:draw()
|
|||||||
local w=self.w
|
local w=self.w
|
||||||
local ATV=self.ATV
|
local ATV=self.ATV
|
||||||
|
|
||||||
|
--Background
|
||||||
|
gc_setColor(0,0,0,.3)
|
||||||
|
gc_rectangle('fill',x,y,w,60,4)
|
||||||
|
|
||||||
--Frame
|
--Frame
|
||||||
gc_setColor(1,1,1,.6+ATV*.1)
|
gc_setColor(1,1,1,.6+ATV*.1)
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
@@ -744,7 +793,7 @@ function selector:press(x)
|
|||||||
self.select=s
|
self.select=s
|
||||||
self.selText=self.list[s]
|
self.selText=self.list[s]
|
||||||
if self.sound then
|
if self.sound then
|
||||||
SFX.play('prerotate')
|
SFX.play('selector')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -764,14 +813,14 @@ function selector:scroll(n)
|
|||||||
self.select=s
|
self.select=s
|
||||||
self.selText=self.list[s]
|
self.selText=self.list[s]
|
||||||
if self.sound then
|
if self.sound then
|
||||||
SFX.play('prerotate')
|
SFX.play('selector')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function selector:arrowKey(k)
|
function selector:arrowKey(k)
|
||||||
self:scroll((k=="left"or k=="up")and -1 or 1)
|
self:scroll((k=='left'or k=='up')and -1 or 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,disp,code,hide
|
function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,disp[,code],hide
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -793,7 +842,7 @@ function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,dis
|
|||||||
font= 30,
|
font= 30,
|
||||||
list= D.list,
|
list= D.list,
|
||||||
disp= D.disp,
|
disp= D.disp,
|
||||||
code= D.code,
|
code= D.code or NULL,
|
||||||
hideF=D.hideF,
|
hideF=D.hideF,
|
||||||
hide= D.hide,
|
hide= D.hide,
|
||||||
}
|
}
|
||||||
@@ -854,18 +903,24 @@ function inputBox:draw()
|
|||||||
local x,y,w,h=self.x,self.y,self.w,self.h
|
local x,y,w,h=self.x,self.y,self.w,self.h
|
||||||
local ATV=self.ATV
|
local ATV=self.ATV
|
||||||
|
|
||||||
gc_setColor(1,1,1,ATV*.08)
|
--Background
|
||||||
gc_rectangle('fill',x,y,w,h,3)
|
gc_setColor(0,0,0,.4)
|
||||||
|
gc_rectangle('fill',x,y,w,h,4)
|
||||||
|
|
||||||
|
--Highlight
|
||||||
|
gc_setColor(1,1,1,ATV*.08*(math.sin(TIME()*4.2)*.2+.8))
|
||||||
|
gc_rectangle('fill',x,y,w,h,4)
|
||||||
|
|
||||||
|
--Frame
|
||||||
gc_setColor(1,1,1)
|
gc_setColor(1,1,1)
|
||||||
gc_setLineWidth(3)
|
gc_setLineWidth(3)
|
||||||
gc_rectangle('line',x,y,w,h,3)
|
gc_rectangle('line',x,y,w,h,3)
|
||||||
|
|
||||||
--Drawable
|
--Drawable
|
||||||
local f=self.font
|
local f=self.font
|
||||||
FONT.set(f)
|
FONT.set(f,self.fType)
|
||||||
if self.obj then
|
if self.obj then
|
||||||
mDraw_Y(self.obj,x-12-self.obj:getWidth(),y+h*.5)
|
gc_draw(self.obj,x-12-self.obj:getWidth(),y+h*.5-self.obj:getHeight()*.5)
|
||||||
end
|
end
|
||||||
if self.secret then
|
if self.secret then
|
||||||
y=y+h*.5-f*.2
|
y=y+h*.5-f*.2
|
||||||
@@ -892,21 +947,21 @@ end
|
|||||||
function inputBox:keypress(k)
|
function inputBox:keypress(k)
|
||||||
local t=self.value
|
local t=self.value
|
||||||
if #t>0 and EDITING==""then
|
if #t>0 and EDITING==""then
|
||||||
if k=="backspace"then
|
if k=='backspace'then
|
||||||
local p=#t
|
local p=#t
|
||||||
while t:byte(p)>=128 and t:byte(p)<192 do
|
while t:byte(p)>=128 and t:byte(p)<192 do
|
||||||
p=p-1
|
p=p-1
|
||||||
end
|
end
|
||||||
t=sub(t,1,p-1)
|
t=sub(t,1,p-1)
|
||||||
SFX.play('lock')
|
SFX.play('lock')
|
||||||
elseif k=="delete"then
|
elseif k=='delete'then
|
||||||
t=""
|
t=""
|
||||||
SFX.play('hold')
|
SFX.play('hold')
|
||||||
end
|
end
|
||||||
self.value=t
|
self.value=t
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit],hide
|
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,fType][,secret][,regex][,limit],hide
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -922,6 +977,7 @@ function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit
|
|||||||
},
|
},
|
||||||
|
|
||||||
font= D.font or int(D.h/7-1)*5,
|
font= D.font or int(D.h/7-1)*5,
|
||||||
|
fType= D.fType,
|
||||||
secret=D.secret==true,
|
secret=D.secret==true,
|
||||||
regex= D.regex,
|
regex= D.regex,
|
||||||
limit= D.limit,
|
limit= D.limit,
|
||||||
@@ -999,9 +1055,9 @@ function textBox:scroll(dir)
|
|||||||
self:drag(nil,nil,nil,-dir*self.lineH)
|
self:drag(nil,nil,nil,-dir*self.lineH)
|
||||||
end
|
end
|
||||||
function textBox:arrowKey(k)
|
function textBox:arrowKey(k)
|
||||||
if k=="up"then
|
if k=='up'then
|
||||||
self:scroll(-1)
|
self:scroll(-1)
|
||||||
elseif k=="down"then
|
elseif k=='down'then
|
||||||
self:scroll(-1)
|
self:scroll(-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1013,8 +1069,8 @@ function textBox:draw()
|
|||||||
local lineH=self.lineH
|
local lineH=self.lineH
|
||||||
|
|
||||||
--Background
|
--Background
|
||||||
gc_setColor(0,0,0,.4)
|
gc_setColor(0,0,0,.3)
|
||||||
gc_rectangle('fill',x,y,w,h,3)
|
gc_rectangle('fill',x,y,w,h,4)
|
||||||
|
|
||||||
--Frame
|
--Frame
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
@@ -1022,7 +1078,7 @@ function textBox:draw()
|
|||||||
gc_rectangle('line',x,y,w,h,3)
|
gc_rectangle('line',x,y,w,h,3)
|
||||||
|
|
||||||
--Texts
|
--Texts
|
||||||
FONT.set(self.font)
|
FONT.set(self.font,self.fType)
|
||||||
gc_push('transform')
|
gc_push('transform')
|
||||||
gc_translate(x,y)
|
gc_translate(x,y)
|
||||||
|
|
||||||
@@ -1054,7 +1110,7 @@ end
|
|||||||
function textBox:getInfo()
|
function textBox:getInfo()
|
||||||
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
|
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
|
||||||
end
|
end
|
||||||
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
|
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,fType][,lineH][,fix],hide
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -1076,6 +1132,7 @@ function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
|
|||||||
h= D.h,
|
h= D.h,
|
||||||
|
|
||||||
font= D.font or 30,
|
font= D.font or 30,
|
||||||
|
fType=D.fType,
|
||||||
fix= D.fix,
|
fix= D.fix,
|
||||||
texts={},
|
texts={},
|
||||||
hideF=D.hideF,
|
hideF=D.hideF,
|
||||||
@@ -1153,7 +1210,7 @@ function listBox:press(x,y)
|
|||||||
if self.list[y]then
|
if self.list[y]then
|
||||||
if self.selected~=y then
|
if self.selected~=y then
|
||||||
self.selected=y
|
self.selected=y
|
||||||
SFX.play('click',.4)
|
SFX.play('selector',.8,0,12)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1176,6 +1233,14 @@ function listBox:arrowKey(dir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function listBox:select(i)
|
||||||
|
self.selected=i
|
||||||
|
if self.selected<int(self.scrollPos/self.lineH)+2 then
|
||||||
|
self:drag(nil,nil,nil,1e99)
|
||||||
|
elseif self.selected>int(self.scrollPos/self.lineH)+self.capacity-1 then
|
||||||
|
self:drag(nil,nil,nil,-1e99)
|
||||||
|
end
|
||||||
|
end
|
||||||
function listBox:draw()
|
function listBox:draw()
|
||||||
local x,y,w,h=self.x,self.y,self.w,self.h
|
local x,y,w,h=self.x,self.y,self.w,self.h
|
||||||
local list=self.list
|
local list=self.list
|
||||||
@@ -1186,6 +1251,10 @@ function listBox:draw()
|
|||||||
gc_push('transform')
|
gc_push('transform')
|
||||||
gc_translate(x,y)
|
gc_translate(x,y)
|
||||||
|
|
||||||
|
--Background
|
||||||
|
gc_setColor(0,0,0,.4)
|
||||||
|
gc_rectangle('fill',0,0,w,h,4)
|
||||||
|
|
||||||
--Frame
|
--Frame
|
||||||
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
|
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
@@ -1214,7 +1283,7 @@ end
|
|||||||
function listBox:getInfo()
|
function listBox:getInfo()
|
||||||
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
|
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
|
||||||
end
|
end
|
||||||
function WIDGET.newListBox(D)--name,x,y,w,h,lineH[,hideF][,hide][,drawF]
|
function WIDGET.newListBox(D)--name,x,y,w,h,lineH,drawF[,hideF][,hide]
|
||||||
local _={
|
local _={
|
||||||
name= D.name or"_",
|
name= D.name or"_",
|
||||||
|
|
||||||
@@ -1271,16 +1340,7 @@ function WIDGET.setWidgetList(list)
|
|||||||
for i=1,#list do
|
for i=1,#list do
|
||||||
list[i]:reset()
|
list[i]:reset()
|
||||||
end
|
end
|
||||||
if SCN.cur~='custom_field'then
|
onChange()
|
||||||
local colorList=THEME.getThemeColor()
|
|
||||||
if not colorList then return end
|
|
||||||
local rnd=math.random
|
|
||||||
for _,W in next,list do
|
|
||||||
if W.color and not W.fText then
|
|
||||||
W.color=colorList[rnd(#colorList)]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.setScrollHeight(height)
|
function WIDGET.setScrollHeight(height)
|
||||||
@@ -1373,101 +1433,17 @@ function WIDGET.release(x,y)
|
|||||||
W:release(x,y+WIDGET.scrollPos)
|
W:release(x,y+WIDGET.scrollPos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function WIDGET.keyPressed(k,isRep)
|
|
||||||
local W=WIDGET.sel
|
|
||||||
if k=="space"or k=="return"then
|
|
||||||
if not isRep then
|
|
||||||
WIDGET.press()
|
|
||||||
end
|
|
||||||
elseif k=="up"or k=="down"or k=="left"or k=="right"then
|
|
||||||
if kb.isDown("lshift","lalt","lctrl")then
|
|
||||||
--Control some widgets with arrowkeys when hold shift/ctrl/alt
|
|
||||||
if W and W.arrowKey then W:arrowKey(k)end
|
|
||||||
else
|
|
||||||
if not W then
|
|
||||||
for _,w in next,WIDGET.active do
|
|
||||||
if not w.hide and w.isAbove then
|
|
||||||
WIDGET.focus(w)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif W.getCenter then
|
|
||||||
local WX,WY=W:getCenter()
|
|
||||||
local dir=(k=="right"or k=="down")and 1 or -1
|
|
||||||
local tar
|
|
||||||
local minDist=1e99
|
|
||||||
local swap_xy=k=="up"or k=="down"
|
|
||||||
if swap_xy then WX,WY=WY,WX end--note that we do not swap them back later
|
|
||||||
for _,W1 in ipairs(WIDGET.active)do
|
|
||||||
if W~=W1 and W1.resCtr and not W1.hide then
|
|
||||||
local L=W1.resCtr
|
|
||||||
for j=1,#L,2 do
|
|
||||||
local x,y=L[j],L[j+1]
|
|
||||||
if swap_xy then x,y=y,x end--note that we do not swap them back later
|
|
||||||
local dist=(x-WX)*dir
|
|
||||||
if dist>10 then
|
|
||||||
dist=dist+abs(y-WY)*6.26
|
|
||||||
if dist<minDist then
|
|
||||||
minDist=dist
|
|
||||||
tar=W1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if tar then
|
|
||||||
WIDGET.focus(tar)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if W and W.keypress then
|
|
||||||
W:keypress(k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function WIDGET.textinput(texts)
|
function WIDGET.textinput(texts)
|
||||||
local W=WIDGET.sel
|
local W=WIDGET.sel
|
||||||
if W and W.type=='inputBox'then
|
if W and W.type=='inputBox'then
|
||||||
if(not W.regex or texts:match(W.regex))and(not W.limit or #(WIDGET.sel.value..texts)<=W.limit)then
|
if(not W.regex or texts:match(W.regex))and(not W.limit or #(WIDGET.sel.value..texts)<=W.limit)then
|
||||||
WIDGET.sel.value=WIDGET.sel.value..texts
|
WIDGET.sel.value=WIDGET.sel.value..texts
|
||||||
SFX.play('move')
|
SFX.play('touch')
|
||||||
else
|
else
|
||||||
SFX.play('finesseError',.3)
|
SFX.play('drop_cancel')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local keyMirror={
|
|
||||||
dpup="up",
|
|
||||||
dpdown="down",
|
|
||||||
dpleft="left",
|
|
||||||
dpright="right",
|
|
||||||
start="return",
|
|
||||||
back="escape",
|
|
||||||
}
|
|
||||||
function WIDGET.gamepadPressed(i)
|
|
||||||
if i=="start"then
|
|
||||||
WIDGET.press()
|
|
||||||
elseif i=="a"or i=="b"then
|
|
||||||
local W=WIDGET.sel
|
|
||||||
if W then
|
|
||||||
if W.type=='button'or W.type=='key'then
|
|
||||||
WIDGET.press()
|
|
||||||
elseif W.type=='slider'then
|
|
||||||
local p=W.disp()
|
|
||||||
local P=i=="left"and(p>0 and p-1)or p<W.unit and p+1
|
|
||||||
if p==P or not P then return end
|
|
||||||
W.code(P)
|
|
||||||
if W.change and timer()-W.lastTime>.18 then
|
|
||||||
W.lastTime=timer()
|
|
||||||
W.change()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
|
|
||||||
WIDGET.keyPressed(keyMirror[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function WIDGET.update(dt)
|
function WIDGET.update(dt)
|
||||||
for _,W in next,WIDGET.active do
|
for _,W in next,WIDGET.active do
|
||||||
|
|||||||
44
legals.md
@@ -1,27 +1,23 @@
|
|||||||
**TECHMINO © 2019-2021 26F Studio. Some rights reserved.**
|
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.
|
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.
|
||||||
|
|
||||||
|
|
||||||
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.
|
"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.
|
||||||
|
|
||||||
|
|
||||||
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc.
|
|
||||||
|
|
||||||
|
|
||||||
Powered by LÖVE, © 2006-2021 LÖVE Development Team.
|
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.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
||||||
"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.
|
|
||||||
|
|
||||||
|
|
||||||
Alibaba Sans is copyrighted by Alibaba Group Holding Limited. Alibaba is a trademark of Alibaba Group Holding Limited in the People’s Republic of China and other countries or regions.
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
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.
|
||||||
@@ -30,22 +26,26 @@ JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains M
|
|||||||
"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.
|
"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.
|
||||||
|
|
||||||
|
|
||||||
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
|
"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.
|
"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. © Facebook, Inc.
|
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.
|
GoldWave is a registered trademark of GoldWave, Inc.
|
||||||
|
|
||||||
|
Linux is a registered trademark of Linus Torvalds.
|
||||||
Linux is a registered trademark of Linus Torvalds.
|
|
||||||
|
|
||||||
|
|
||||||
Touhou Project © Team Shanghai Alice 2002-2021.
|
Touhou Project © Team Shanghai Alice 2002-2021.
|
||||||
|
|
||||||
|
All other trademarks, logos, and copyrights are the properties of their respective owners.
|
||||||
All other trademarks are the properties of their respective owners.
|
|
||||||
|
|||||||
244
main.lua
@@ -23,13 +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'}
|
SFXPACKS={'chiptune'}
|
||||||
VOCPACKS={'miya','mono','xiaoya','miku'}
|
VOCPACKS={'miya',--[['mono',]]'xiaoya','miku'}
|
||||||
FIRSTLAUNCH=false
|
FIRSTLAUNCH=false
|
||||||
DAILYLAUNCH=false
|
DAILYLAUNCH=false
|
||||||
|
|
||||||
@@ -49,9 +50,30 @@ local _LOADTIME_=TIME()
|
|||||||
|
|
||||||
--Load modules
|
--Load modules
|
||||||
Z=require'Zframework'
|
Z=require'Zframework'
|
||||||
FONT.load('parts/fonts/proportional.ttf')
|
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)
|
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_))
|
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
@@ -62,6 +84,9 @@ mStr=GC.mStr
|
|||||||
mText=GC.simpX
|
mText=GC.simpX
|
||||||
mDraw=GC.draw
|
mDraw=GC.draw
|
||||||
Snd=SFX.playSample
|
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('')
|
||||||
@@ -90,7 +115,8 @@ for _,v in next,fs.getDirectoryItems('parts/shaders')do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
FREEROW= require'parts.freeRow'
|
THEME= require'parts.theme'
|
||||||
|
LINE= require'parts.line'
|
||||||
DATA= require'parts.data'
|
DATA= require'parts.data'
|
||||||
|
|
||||||
TEXTURE= require'parts.texture'
|
TEXTURE= require'parts.texture'
|
||||||
@@ -102,14 +128,17 @@ BOT= require'parts.bot'
|
|||||||
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_))
|
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
--Init Zframework
|
--Init Zframework
|
||||||
Z.setIfPowerInfo(function()
|
|
||||||
return SETTING.powerInfo and LOADED
|
|
||||||
end)
|
|
||||||
do--Z.setCursor
|
do--Z.setCursor
|
||||||
local normImg=GC.DO{16,16,
|
local normImg=GC.DO{16,16,
|
||||||
{'fCirc',8,8,4},
|
{'fCirc',8,8,4},
|
||||||
@@ -143,8 +172,8 @@ Z.setOnFnKeys({
|
|||||||
function()
|
function()
|
||||||
if GAME.playing and not GAME.net then
|
if GAME.playing and not GAME.net then
|
||||||
for _=1,8 do
|
for _=1,8 do
|
||||||
local P=PLY_ALIVE[math.random(#PLY_ALIVE)]
|
if #PLY_ALIVE>1 then
|
||||||
if P and P~=PLAYERS[1]then
|
local P=PLY_ALIVE[math.random(2,#PLY_ALIVE)]
|
||||||
P.lastRecv=PLAYERS[1]
|
P.lastRecv=PLAYERS[1]
|
||||||
P:lose()
|
P:lose()
|
||||||
end
|
end
|
||||||
@@ -153,8 +182,11 @@ Z.setOnFnKeys({
|
|||||||
end,
|
end,
|
||||||
function()print(WIDGET.getSelected()or"no widget selected")end,
|
function()print(WIDGET.getSelected()or"no widget selected")end,
|
||||||
function()for k,v in next,_G do print(k,v)end end,
|
function()for k,v in next,_G do print(k,v)end end,
|
||||||
function()if love["_openConsole"]then love["_openConsole"]()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
|
do--Z.setOnFocus
|
||||||
local function task_autoSoundOff()
|
local function task_autoSoundOff()
|
||||||
while true do
|
while true do
|
||||||
@@ -196,15 +228,15 @@ end
|
|||||||
Z.setOnQuit(destroyPlayers)
|
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{},KEY_MAP)
|
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','string')
|
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
|
||||||
@@ -213,16 +245,16 @@ if fieldData then
|
|||||||
else
|
else
|
||||||
FIELD[1]=DATA.newBoard()
|
FIELD[1]=DATA.newBoard()
|
||||||
end
|
end
|
||||||
local sequenceData=FILE.load('conf/customSequence','string')
|
local sequenceData=loadFile('conf/customSequence','-string -canSkip')
|
||||||
if sequenceData then
|
if sequenceData then
|
||||||
DATA.pasteSequence(sequenceData)
|
DATA.pasteSequence(sequenceData)
|
||||||
end
|
end
|
||||||
local missionData=FILE.load('conf/customMissions','string')
|
local missionData=loadFile('conf/customMissions','-string -canSkip')
|
||||||
if missionData then
|
if missionData then
|
||||||
DATA.pasteMission(missionData)
|
DATA.pasteMission(missionData)
|
||||||
end
|
end
|
||||||
local customData=FILE.load('conf/customEnv')
|
local customData=loadFile('conf/customEnv','-canSkip')
|
||||||
if customData and customData.version==VERSION.code then
|
if customData and customData['version']==VERSION.code then
|
||||||
TABLE.complete(customData,CUSTOMENV)
|
TABLE.complete(customData,CUSTOMENV)
|
||||||
end
|
end
|
||||||
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
||||||
@@ -239,14 +271,17 @@ 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',
|
||||||
|
miyaGlow='media/image/characters/miya_glow.png',
|
||||||
monoCH='media/image/characters/mono.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',
|
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',
|
||||||
@@ -263,7 +298,7 @@ IMG.init{
|
|||||||
SKIN.load{
|
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_cho",path='media/image/skin/shiny_cho.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'},
|
||||||
@@ -286,6 +321,7 @@ SKIN.load{
|
|||||||
{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'},
|
||||||
@@ -301,11 +337,11 @@ SFX.init((function()--[Warning] Not loading files here, just get the list of sou
|
|||||||
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/music')do
|
for _,v in next,fs.getDirectoryItems('media/music')do
|
||||||
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
|
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
|
||||||
table.insert(L,{name=v:sub(1,-5),path='media/music/'..v})
|
L[v:sub(1,-5)]='media/music/'..v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return L
|
return L
|
||||||
@@ -324,17 +360,19 @@ VOC.init{
|
|||||||
LANG.init('zh',
|
LANG.init('zh',
|
||||||
{
|
{
|
||||||
zh=require'parts.language.lang_zh',
|
zh=require'parts.language.lang_zh',
|
||||||
|
zh_trad=require'parts.language.lang_zh_trad',
|
||||||
zh_full=require'parts.language.lang_zh_full',
|
zh_full=require'parts.language.lang_zh_full',
|
||||||
en=require'parts.language.lang_en',
|
en=require'parts.language.lang_en',
|
||||||
fr=require'parts.language.lang_fr',
|
fr=require'parts.language.lang_fr',
|
||||||
es=require'parts.language.lang_es',
|
es=require'parts.language.lang_es',
|
||||||
pt=require'parts.language.lang_pt',
|
pt=require'parts.language.lang_pt',
|
||||||
|
id=require'parts.language.lang_id',
|
||||||
zh_grass=require'parts.language.lang_zh_grass',
|
zh_grass=require'parts.language.lang_zh_grass',
|
||||||
zh_yygq=require'parts.language.lang_yygq',
|
zh_yygq=require'parts.language.lang_yygq',
|
||||||
symbol=require'parts.language.lang_symbol',
|
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_NAMES
|
block=BLOCK_NAMES
|
||||||
@@ -363,6 +401,7 @@ for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
|
|||||||
BG.add(name,require('parts.backgrounds.'..name))
|
BG.add(name,require('parts.backgrounds.'..name))
|
||||||
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 isSafeFile('parts/scenes/'..v)then
|
if isSafeFile('parts/scenes/'..v)then
|
||||||
@@ -371,21 +410,6 @@ for _,v in next,fs.getDirectoryItems('parts/scenes')do
|
|||||||
LANG.addScene(sceneName)
|
LANG.addScene(sceneName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--Load mode files
|
|
||||||
for i=1,#MODES do
|
|
||||||
local m=MODES[i]--Mode template
|
|
||||||
if isSafeFile('parts/modes/'..m.name)then
|
|
||||||
TABLE.complete(require('parts.modes.'..m.name),MODES[i])
|
|
||||||
MODES[m.name],MODES[i]=MODES[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _,v in next,fs.getDirectoryItems('parts/modes')do
|
|
||||||
if isSafeFile('parts/modes/'..v)and not MODES[v:sub(1,-5)]then
|
|
||||||
local M={name=v:sub(1,-5)}
|
|
||||||
TABLE.complete(require('parts.modes.'..M.name),M)
|
|
||||||
MODES[M.name]=M
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_))
|
table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
@@ -394,7 +418,6 @@ 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
|
||||||
@@ -426,7 +449,6 @@ do
|
|||||||
if RANKS.tsd_u then
|
if RANKS.tsd_u then
|
||||||
RANKS.tsd_u=0
|
RANKS.tsd_u=0
|
||||||
end
|
end
|
||||||
needSave=true
|
|
||||||
end
|
end
|
||||||
if STAT.version==1601 then
|
if STAT.version==1601 then
|
||||||
RANKS.round_e=nil
|
RANKS.round_e=nil
|
||||||
@@ -440,6 +462,21 @@ do
|
|||||||
fs.remove('record/round_l.rec')
|
fs.remove('record/round_l.rec')
|
||||||
fs.remove('record/round_u.rec')
|
fs.remove('record/round_u.rec')
|
||||||
end
|
end
|
||||||
|
if STAT.version<1700 and SETTING.dascut<5 then
|
||||||
|
SETTING.dascut=SETTING.dascut+1
|
||||||
|
needSave=true
|
||||||
|
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
|
||||||
@@ -448,21 +485,48 @@ 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
|
||||||
|
for k,v in next,MODE_UPDATE_MAP do
|
||||||
|
if RANKS[k]then
|
||||||
|
RANKS[v]=RANKS[k]
|
||||||
|
RANKS[k]=nil
|
||||||
|
end
|
||||||
|
k='record/'..k
|
||||||
|
if fs.getInfo(k..'.dat')then
|
||||||
|
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
|
||||||
|
fs.remove(k..'.dat')
|
||||||
|
end
|
||||||
|
if fs.getInfo(k..'.rec')then
|
||||||
|
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
|
||||||
|
fs.remove(k..'.rec')
|
||||||
|
end
|
||||||
|
end
|
||||||
STAT.version=VERSION.code
|
STAT.version=VERSION.code
|
||||||
needSave=true
|
needSave=true
|
||||||
love.event.quit('restart')
|
|
||||||
end
|
end
|
||||||
SETTING.appLock=nil
|
SETTING.appLock,SETTING.dataSaving,SETTING.swap=nil
|
||||||
SETTING.dataSaving=nil
|
|
||||||
SETTING.swap=nil
|
|
||||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
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
|
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 not RSlist[SETTING.RS]then SETTING.RS='TRS'end
|
||||||
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
||||||
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'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 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 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 then RANKS.infinite=0 end
|
||||||
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
||||||
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
||||||
@@ -473,40 +537,6 @@ do
|
|||||||
if type(name)=='number'or type(rank)~='number'then
|
if type(name)=='number'or type(rank)~='number'then
|
||||||
RANKS[name]=nil
|
RANKS[name]=nil
|
||||||
needSave=true
|
needSave=true
|
||||||
else
|
|
||||||
local M=MODES[name]
|
|
||||||
if M and M.unlock and rank>0 then
|
|
||||||
for _,unlockName in next,M.unlock do
|
|
||||||
if not RANKS[unlockName]then
|
|
||||||
RANKS[unlockName]=0
|
|
||||||
needSave=true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not(M and M.x)then
|
|
||||||
RANKS[name]=nil
|
|
||||||
needSave=true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not MODES[STAT.lastPlay]then
|
|
||||||
STAT.lastPlay='sprint_10l'
|
|
||||||
needSave=true
|
|
||||||
end
|
|
||||||
|
|
||||||
for k,v in next,MODE_UPDATE_MAP do
|
|
||||||
if RANKS[k]then
|
|
||||||
RANKS[v]=RANKS[k]
|
|
||||||
RANKS[k]=nil
|
|
||||||
end
|
|
||||||
k='record/'..k
|
|
||||||
if fs.getInfo(k..'.dat')then
|
|
||||||
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
|
|
||||||
fs.remove(k..'.dat')
|
|
||||||
end
|
|
||||||
if fs.getInfo(k..'.rec')then
|
|
||||||
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
|
|
||||||
fs.remove(k..'.rec')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -514,10 +544,12 @@ do
|
|||||||
saveStats()
|
saveStats()
|
||||||
saveProgress()
|
saveProgress()
|
||||||
saveSettings()
|
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.powerInfo=true
|
SETTING.powerInfo=true
|
||||||
@@ -525,7 +557,7 @@ if FIRSTLAUNCH and MOBILE then
|
|||||||
end
|
end
|
||||||
|
|
||||||
--Apply system setting
|
--Apply system setting
|
||||||
applyAllSettings()
|
applySettings()
|
||||||
|
|
||||||
--Load replays
|
--Load replays
|
||||||
for _,fileName in next,fs.getDirectoryItems('replay')do
|
for _,fileName in next,fs.getDirectoryItems('replay')do
|
||||||
@@ -576,3 +608,37 @@ table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)
|
|||||||
table.insert(_LOADTIMELIST_,("Initialize Data: %.3fs"):format(TIME()-_LOADTIME_))
|
table.insert(_LOADTIMELIST_,("Initialize Data: %.3fs"):format(TIME()-_LOADTIME_))
|
||||||
|
|
||||||
for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i])end
|
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
|
||||||
|
|||||||
BIN
media/effect/chiptune/back.ogg
Normal file
BIN
media/effect/chiptune/check.ogg
Normal file
BIN
media/effect/chiptune/selector.ogg
Normal file
BIN
media/effect/chiptune/uncheck.ogg
Normal file
|
Before Width: | Height: | Size: 74 KiB |
BIN
media/image/characters/miya1.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
media/image/characters/miya2.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
media/image/characters/miya3.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
media/image/characters/miya4.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
media/image/characters/miya_glow.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
media/image/characters/miya_heart.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
BIN
media/image/characters/xiaoya_Omino.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 552 B |
|
Before Width: | Height: | Size: 534 B |
|
Before Width: | Height: | Size: 603 B |
|
Before Width: | Height: | Size: 483 B |
|
Before Width: | Height: | Size: 324 B |
|
Before Width: | Height: | Size: 275 B |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 272 B |
|
Before Width: | Height: | Size: 338 B |
|
Before Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 434 B |
|
Before Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 457 B |
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
media/image/skin/pixel_chno.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 41 KiB |
BIN
media/music/1980s.ogg
Normal file
BIN
media/music/lounge.ogg
Normal file
BIN
media/music/malate.ogg
Normal file
BIN
media/music/peak.ogg
Normal file
102
parts/RSlist.lua
@@ -97,12 +97,12 @@ do
|
|||||||
{131,2,2, 0, 0,0},{131,2,2,-1,-1,0},{131,2,2,-1, 0,0},--S
|
{131,2,2, 0, 0,0},{131,2,2,-1,-1,0},{131,2,2,-1, 0,0},--S
|
||||||
{131,1,2,-1, 0,0},{131,1,2, 0,-1,0},{131,1,2, 0, 0,0},--Z(misOrder)
|
{131,1,2,-1, 0,0},{131,1,2, 0,-1,0},{131,1,2, 0, 0,0},--Z(misOrder)
|
||||||
{313,2,2, 0, 0,0},{313,2,2,-1,-1,0},{313,2,2,-1, 0,0},--S(misOrder)
|
{313,2,2, 0, 0,0},{313,2,2,-1,-1,0},{313,2,2,-1, 0,0},--S(misOrder)
|
||||||
{331,3,2, 0,-1,0},--J(farDown)
|
{331,3,2, 0,-1,1},--J(farDown)
|
||||||
{113,4,2,-1,-1,0},--L(farDown)
|
{113,4,2,-1,-1,1},--L(farDown)
|
||||||
{113,3,2,-1,-1,0},{113,3,0, 0, 0,0},--J
|
{113,3,2,-1,-1,0},{113,3,0, 0, 0,0},--J
|
||||||
{331,4,2, 0,-1,0},{331,4,0,-1, 0,0},--L
|
{331,4,2, 0,-1,0},{331,4,0,-1, 0,0},--L
|
||||||
{222,7,2,-1, 0,2},{222,7,2,-2, 0,2},{222,7,2, 0, 0,2},--I
|
|
||||||
{222,7,0,-1, 1,1},{222,7,0,-2, 1,1},{222,7,0, 0, 1,1},--I(high)
|
{222,7,0,-1, 1,1},{222,7,0,-2, 1,1},{222,7,0, 0, 1,1},--I(high)
|
||||||
|
{222,7,2,-1, 0,2},{222,7,2,-2, 0,2},{222,7,2, 0, 0,2},--I(low)
|
||||||
{121,6,0, 1,-1,2},{112,6,0, 2,-1,2},{122,6,0, 1,-2,2},--O
|
{121,6,0, 1,-1,2},{112,6,0, 2,-1,2},{122,6,0, 1,-2,2},--O
|
||||||
{323,6,0,-1,-1,2},{332,6,0,-2,-1,2},{322,6,0,-1,-2,2},--O
|
{323,6,0,-1,-1,2},{332,6,0,-2,-1,2},{322,6,0,-1,-2,2},--O
|
||||||
}--{keys, ID, dir, dx, dy, freeLevel (0=immovable, 1=U/D-immovable, 2=free)}
|
}--{keys, ID, dir, dx, dy, freeLevel (0=immovable, 1=U/D-immovable, 2=free)}
|
||||||
@@ -129,10 +129,10 @@ do
|
|||||||
[10]={'+0+0','+1+0','+1-1','+0+2','+1-2','+1-2'},
|
[10]={'+0+0','+1+0','+1-1','+0+2','+1-2','+1-2'},
|
||||||
[03]={'+0+0','+1+0','+1+1','+0-2','+1-1','+1-2'},
|
[03]={'+0+0','+1+0','+1+1','+0-2','+1-1','+1-2'},
|
||||||
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1'},
|
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1'},
|
||||||
[12]={'+0+0','+1+0','+1-1','+0+2','+1+2'},
|
[12]={'+0+0','+1+0','+1-1','+0+2','+1+2','+1+1'},
|
||||||
[21]={'+0+0','-1+0','-1+1','+0-2','-1-2'},
|
[21]={'+0+0','-1+0','-1+1','+0-2','-1-2','-1-1'},
|
||||||
[32]={'+0+0','-1+0','-1-1','+0+2','-1+2'},
|
[32]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1'},
|
||||||
[23]={'+0+0','+1+0','+1+1','+0-2','+1-2'},
|
[23]={'+0+0','+1+0','+1+1','+0-2','+1-2','+0+1'},
|
||||||
[02]={'+0+0','+1+0','-1+0','+0-1','+0+1'},
|
[02]={'+0+0','+1+0','-1+0','+0-1','+0+1'},
|
||||||
[20]={'+0+0','-1+0','+1+0','+0+1','+0-1'},
|
[20]={'+0+0','-1+0','+1+0','+0+1','+0-1'},
|
||||||
[13]={'+0+0','+0-1','+0+1','+0-2'},
|
[13]={'+0+0','+0-1','+0+1','+0-2'},
|
||||||
@@ -140,8 +140,8 @@ do
|
|||||||
},--Z
|
},--Z
|
||||||
false,--S
|
false,--S
|
||||||
{
|
{
|
||||||
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1'},
|
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1','+0-1'},
|
||||||
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1'},
|
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1','+0+1'},
|
||||||
[03]={'+0+0','+1+0','+1+1','+0-2','+1-2','+1-1','+0+1'},
|
[03]={'+0+0','+1+0','+1+1','+0-2','+1-2','+1-1','+0+1'},
|
||||||
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1','-1+1'},
|
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1','-1+1'},
|
||||||
[12]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-1','+0+2','+1+2'},
|
[12]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-1','+0+2','+1+2'},
|
||||||
@@ -204,6 +204,7 @@ do
|
|||||||
P.spinLast=2
|
P.spinLast=2
|
||||||
P.stat.rotate=P.stat.rotate+1
|
P.stat.rotate=P.stat.rotate+1
|
||||||
P:freshBlock('move')
|
P:freshBlock('move')
|
||||||
|
C.spinSeq=nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -304,8 +305,8 @@ do
|
|||||||
[10]={'+0+0','+0+1','+1+0','+0-2','+1-2'},
|
[10]={'+0+0','+0+1','+1+0','+0-2','+1-2'},
|
||||||
[03]={'+0+0','+0-1','+0+1','+0+2'},
|
[03]={'+0+0','+0-1','+0+1','+0+2'},
|
||||||
[30]={'+0+0','+0-1','+0+1','+0-2'},
|
[30]={'+0+0','+0-1','+0+1','+0-2'},
|
||||||
[12]={'+0+0','+0-1','+0+1'},
|
[12]={'+0+0','+0-1','+0+1','+0+2'},
|
||||||
[21]={'+0+0','+0-1','+0-2'},
|
[21]={'+0+0','+0-1','+0-2','+0-2'},
|
||||||
[32]={'+0+0','+1+0','-1+0'},
|
[32]={'+0+0','+1+0','-1+0'},
|
||||||
[23]={'+0+0','-1+0','+1+0'},
|
[23]={'+0+0','-1+0','+1+0'},
|
||||||
[02]={'+0+0','-1+1','+1-1'},
|
[02]={'+0+0','-1+1','+1-1'},
|
||||||
@@ -353,8 +354,8 @@ do
|
|||||||
[21]={'+0+0','-1+0','-1+1','+0+1','-1+2','+0+2','-1-1','+1+0','+0-2','-1-2'},
|
[21]={'+0+0','-1+0','-1+1','+0+1','-1+2','+0+2','-1-1','+1+0','+0-2','-1-2'},
|
||||||
[32]={'+0+0','-1+0','-1+1','-1-1','+1+0','+0+2','-1+2','+0-2'},
|
[32]={'+0+0','-1+0','-1+1','-1-1','+1+0','+0+2','-1+2','+0-2'},
|
||||||
[23]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-2','+1-2','+0+2'},
|
[23]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-2','+1-2','+0+2'},
|
||||||
[02]={'+0+0','+0-1','+1-1','-1+0','+2-1'},
|
[02]={'+0+0','+0-1','-1-1','+1-1','-1+0','+2-1'},
|
||||||
[20]={'+0+0','+0+1','-1+1','+1+0','-2+1'},
|
[20]={'+0+0','+0+1','+1+1','-1+1','+1+0','-2+1'},
|
||||||
[13]={'+0+0','-1+0','-1-1','+0+1','-1-2'},
|
[13]={'+0+0','-1+0','-1-1','+0+1','-1-2'},
|
||||||
[31]={'+0+0','+1+0','+1+1','+0-1','+1+2'},
|
[31]={'+0+0','+1+0','+1+1','+0-1','+1+2'},
|
||||||
},--J5
|
},--J5
|
||||||
@@ -375,8 +376,8 @@ do
|
|||||||
},--R
|
},--R
|
||||||
false,--Y
|
false,--Y
|
||||||
{
|
{
|
||||||
[01]={'+0+0','-1+0','-1+1','+0+1','+1+0','-1+2','-2+0','+0-2'},
|
[01]={'+0+0','-1+0','-1+1','+0+1','+1+0','+1+1','-1+2','-2+0','+0-2'},
|
||||||
[10]={'+0+0','+1+0','-1+0','+0-1','+1-1','+1-2','+2+0','+0+2'},
|
[10]={'+0+0','+1+0','-1+0','+0-1','-1-1','+1-1','+1-2','+2+0','+0+2'},
|
||||||
[03]={'+0+0','-1+0','+1-1','+0-2','+0-3','+1+0','+1-2','+1-3','+0+1','-1+1'},
|
[03]={'+0+0','-1+0','+1-1','+0-2','+0-3','+1+0','+1-2','+1-3','+0+1','-1+1'},
|
||||||
[30]={'+0+0','-1+0','+1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},
|
[30]={'+0+0','-1+0','+1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},
|
||||||
[12]={'+0+0','-1+0','+1-1','-1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},
|
[12]={'+0+0','-1+0','+1-1','-1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},
|
||||||
@@ -686,13 +687,7 @@ do
|
|||||||
sfx='prerotate'
|
sfx='prerotate'
|
||||||
elseif P:ifoverlap(icb,x,y+1)and P:ifoverlap(icb,x-1,y)and P:ifoverlap(icb,x+1,y)then
|
elseif P:ifoverlap(icb,x,y+1)and P:ifoverlap(icb,x-1,y)and P:ifoverlap(icb,x+1,y)then
|
||||||
sfx='rotatekick'
|
sfx='rotatekick'
|
||||||
if P.gameEnv.shakeFX then
|
P:_rotateField(d)
|
||||||
if d==1 or d==3 then
|
|
||||||
P.fieldOff.va=P.fieldOff.va+(2-d)*6e-3
|
|
||||||
else
|
|
||||||
P.fieldOff.va=P.fieldOff.va+P:getCenterX()*3e-3
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
sfx='rotate'
|
sfx='rotate'
|
||||||
end
|
end
|
||||||
@@ -767,6 +762,68 @@ do
|
|||||||
ARS_Z.kickTable[25]=upSet
|
ARS_Z.kickTable[25]=upSet
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local DRS_weak
|
||||||
|
do
|
||||||
|
local centerPos=TABLE.copy(defaultCenterPos)
|
||||||
|
centerPos[1]={[0]={1,1},{1,0},{1,1},{1,1}}--Z
|
||||||
|
centerPos[2]={[0]={1,1},{1,0},{1,1},{1,1}}--S
|
||||||
|
centerPos[3]={[0]={1,1},{1,0},{1,1},{1,1}}--L
|
||||||
|
centerPos[4]={[0]={1,1},{1,0},{1,1},{1,1}}--J
|
||||||
|
centerPos[5]={[0]={1,1},{1,0},{1,1},{1,1}}--T
|
||||||
|
centerPos[7]={[0]={.5,1.5},{1.5,-.5},{.5,1.5},{1.5,.5}}--I
|
||||||
|
centerPos[10]={[0]={1,1},{1,0},{1,1},{1,0}}--P
|
||||||
|
centerPos[11]={[0]={1,1},{1,1},{1,1},{1,1}}--Q
|
||||||
|
centerPos[15]={[0]={1,1},{1,0},{1,1},{1,1}}--U
|
||||||
|
centerPos[16]={[0]={1,1},{1,1},{1,1},{1,1}}--V
|
||||||
|
centerPos[19]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--J5
|
||||||
|
centerPos[20]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--L5
|
||||||
|
centerPos[21]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--R
|
||||||
|
centerPos[22]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--Y
|
||||||
|
centerPos[23]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--N
|
||||||
|
centerPos[24]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--H
|
||||||
|
centerPos[26]={[0]={0,1},{0,0},{0,1},{0,0}}--I3
|
||||||
|
centerPos[28]={[0]={0,1},{0,0},{0,1},{0,0}}--I2
|
||||||
|
|
||||||
|
local L={'+0+0','-1+0','+1+0','+0-1','-1-1','+1-1'}
|
||||||
|
local R={'+0+0','+1+0','-1+0','+0-1','+1-1','-1-1'}
|
||||||
|
|
||||||
|
local Z={
|
||||||
|
[01]=R,[10]=L,[03]=L,[30]=R,
|
||||||
|
[12]=R,[21]=L,[32]=L,[23]=R,
|
||||||
|
[02]=R,[20]=L,[13]=L,[31]=R,
|
||||||
|
}
|
||||||
|
local S=_reflect(Z)
|
||||||
|
|
||||||
|
DRS_weak={
|
||||||
|
centerTex=GC.DO{10,10,
|
||||||
|
{'setLW',2},
|
||||||
|
{'dRect',1,1,8,8},
|
||||||
|
{'fRect',3,3,4,4},
|
||||||
|
},
|
||||||
|
centerPos=centerPos,
|
||||||
|
kickTable={
|
||||||
|
Z,S,--Z,S
|
||||||
|
Z,S,--J,L
|
||||||
|
Z,--T
|
||||||
|
noKickSet,--O
|
||||||
|
Z,--I
|
||||||
|
|
||||||
|
Z,S,--Z5,S5
|
||||||
|
Z,S,--P,Q
|
||||||
|
Z,S,--F,E
|
||||||
|
Z,Z,Z,Z,--T5,U,V,W
|
||||||
|
noKickSet,--X
|
||||||
|
Z,S,--J5,L5
|
||||||
|
Z,S,--R,Y
|
||||||
|
Z,S,--N,H
|
||||||
|
Z,--I5
|
||||||
|
|
||||||
|
Z,Z,--I3,C
|
||||||
|
Z,Z,--I2,O1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local ASC
|
local ASC
|
||||||
do
|
do
|
||||||
local L={'+0+0','+1+0','+0-1','+1-1','+0-2','+1-2','+2+0','+2-1','+2-2','-1+0','-1-1','+0+1','+1+1','+2+1','-1-2','-2+0','+0+2','+1+2','+2+2','-2-1','-2-2'}
|
local L={'+0+0','+1+0','+0-1','+1-1','+0-2','+1-2','+2+0','+2-1','+2-2','-1+0','-1-1','+0+1','+1+1','+2+1','-1-2','-2+0','+0+2','+1+2','+2+2','-2-1','-2-2'}
|
||||||
@@ -940,6 +997,7 @@ local RSlist={
|
|||||||
SRS_X=SRS_X,
|
SRS_X=SRS_X,
|
||||||
BiRS=BiRS,
|
BiRS=BiRS,
|
||||||
ARS_Z=ARS_Z,
|
ARS_Z=ARS_Z,
|
||||||
|
DRS_weak=DRS_weak,
|
||||||
ASC=ASC,
|
ASC=ASC,
|
||||||
ASC_plus=ASC_plus,
|
ASC_plus=ASC_plus,
|
||||||
C2=C2,
|
C2=C2,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
--Blackhole
|
--blockhole
|
||||||
local gc=love.graphics
|
local gc=love.graphics
|
||||||
local gc_clear,gc_replaceTransform=gc.clear,gc.replaceTransform
|
local gc_clear,gc_replaceTransform=gc.clear,gc.replaceTransform
|
||||||
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
||||||
@@ -51,7 +51,7 @@ function back.draw()
|
|||||||
gc_draw(S.texture,S.d*cos(S.ang),S.d*sin(S.ang),S.rotate,S.size*.026,nil,15,15)
|
gc_draw(S.texture,S.d*cos(S.ang),S.d*sin(S.ang),S.rotate,S.size*.026,nil,15,15)
|
||||||
end
|
end
|
||||||
|
|
||||||
--Blackhole
|
--blockhole
|
||||||
gc_setColor(.07,.07,.07)
|
gc_setColor(.07,.07,.07)
|
||||||
gc_circle('fill',0,0,157)
|
gc_circle('fill',0,0,157)
|
||||||
gc_setLineWidth(6)
|
gc_setLineWidth(6)
|
||||||
31
parts/backgrounds/custom.lua
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
--Secret custom background
|
||||||
|
local gc_clear,gc_setColor=love.graphics.clear,love.graphics.setColor
|
||||||
|
local back={}
|
||||||
|
|
||||||
|
local image=false
|
||||||
|
local alpha=.26
|
||||||
|
|
||||||
|
local mx,my,k
|
||||||
|
|
||||||
|
function back.init()
|
||||||
|
back.resize()
|
||||||
|
end
|
||||||
|
function back.resize()
|
||||||
|
mx,my=SCR.w*.5,SCR.h*.5
|
||||||
|
if image then
|
||||||
|
k=math.max(SCR.w/image:getWidth(),SCR.h/image:getHeight())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function back.draw()
|
||||||
|
gc_clear(.1,.1,.1)
|
||||||
|
if image then
|
||||||
|
gc_setColor(1,1,1,alpha)
|
||||||
|
mDraw(image,mx,my,nil,k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function back.event(a,img)
|
||||||
|
if a then alpha=a end
|
||||||
|
if img then image=img end
|
||||||
|
back.resize()
|
||||||
|
end
|
||||||
|
return back
|
||||||
@@ -12,10 +12,9 @@ local ins,rem=table.insert,table.remove
|
|||||||
local back={}
|
local back={}
|
||||||
|
|
||||||
local t
|
local t
|
||||||
local fan,petal
|
local petal
|
||||||
function back.init()
|
function back.init()
|
||||||
t=0
|
t=0
|
||||||
fan=SVG_TITLE_FAN
|
|
||||||
petal={}
|
petal={}
|
||||||
end
|
end
|
||||||
function back.update()
|
function back.update()
|
||||||
@@ -62,7 +61,7 @@ function back.draw()
|
|||||||
|
|
||||||
gc_setLineWidth(6)
|
gc_setLineWidth(6)
|
||||||
gc_setColor(.8,.9,1,.3)
|
gc_setColor(.8,.9,1,.3)
|
||||||
for i=1,8 do gc_polygon('line',fan[i])end
|
for i=1,#SVG_TITLE_FAN do gc_polygon('line',SVG_TITLE_FAN[i])end
|
||||||
|
|
||||||
gc_setLineWidth(2)
|
gc_setLineWidth(2)
|
||||||
gc_setColor(1,.5,.7,.3)
|
gc_setColor(1,.5,.7,.3)
|
||||||
|
|||||||
11
parts/backgrounds/gray.lua
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
--Customizable grey background
|
||||||
|
local gc=love.graphics
|
||||||
|
local back={}
|
||||||
|
local brightness=.26
|
||||||
|
function back.draw()
|
||||||
|
gc.clear(brightness,brightness,brightness)
|
||||||
|
end
|
||||||
|
function back.event(b)
|
||||||
|
brightness=b
|
||||||
|
end
|
||||||
|
return back
|
||||||
@@ -22,12 +22,12 @@ function back.resize(w,h)
|
|||||||
S[i+4]=(rnd()-.5)*.01*s--Vy
|
S[i+4]=(rnd()-.5)*.01*s--Vy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function back.update()
|
function back.update(dt)
|
||||||
local S=stars
|
local S=stars
|
||||||
--Star moving
|
--Star moving
|
||||||
for i=1,1260,5 do
|
for i=1,1260,5 do
|
||||||
S[i+1]=(S[i+1]+S[i+3])%W
|
S[i+1]=(S[i+1]+S[i+3]*dt*60)%W
|
||||||
S[i+2]=(S[i+2]+S[i+4])%H
|
S[i+2]=(S[i+2]+S[i+4]*dt*60)%H
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function back.draw()
|
function back.draw()
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ function back.draw()
|
|||||||
gc.setColor(wingColor[i])
|
gc.setColor(wingColor[i])
|
||||||
local B=crystals[i]
|
local B=crystals[i]
|
||||||
gc.draw(crystal_img,B.x,B.y,B.a,k,k,21,0)
|
gc.draw(crystal_img,B.x,B.y,B.a,k,k,21,0)
|
||||||
B=crystals[17-i]
|
B=crystals[8+i]
|
||||||
gc.draw(crystal_img,B.x,B.y,B.a,-k,k,21,0)
|
gc.draw(crystal_img,B.x,B.y,B.a,-k,k,21,0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ local function _ifoverlapAI(f,bk,x,y)
|
|||||||
end
|
end
|
||||||
end end
|
end end
|
||||||
end
|
end
|
||||||
local discardRow=FREEROW.discard
|
local getRow,discardRow=LINE.new,LINE.discard
|
||||||
local getRow=FREEROW.get
|
|
||||||
local function _resetField(f0,f,start)
|
local function _resetField(f0,f,start)
|
||||||
for _=#f,start,-1 do
|
for _=#f,start,-1 do
|
||||||
discardRow(f[_])
|
discardRow(f[_])
|
||||||
|
|||||||