Compare commits
292 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b44d144b26 | ||
|
|
376a528fac | ||
|
|
6dec156d4d | ||
|
|
372f27b6ac | ||
|
|
d6d2d394bc | ||
|
|
7c326ce0d7 | ||
|
|
1ae26d39c2 | ||
|
|
702d427183 | ||
|
|
432ba338b7 | ||
|
|
c1ce09ac52 | ||
|
|
57982d3c43 | ||
|
|
c168a6c685 | ||
|
|
17479ac08b | ||
|
|
a73819214b | ||
|
|
c5730b31f7 | ||
|
|
4bfebdea13 | ||
|
|
d040754d8c | ||
|
|
7943ebc8f8 | ||
|
|
5ce0b90d9f | ||
|
|
e97d892926 | ||
|
|
3b026ce204 | ||
|
|
d269828924 | ||
|
|
1e1560651a | ||
|
|
782e1ef506 | ||
|
|
3a3c805792 | ||
|
|
51235a61ad | ||
|
|
f493de998c | ||
|
|
72b5acfece | ||
|
|
176ddf6abb | ||
|
|
44c52300e4 | ||
|
|
2eae6cdfda | ||
|
|
0f896d0a4f | ||
|
|
02189c4262 | ||
| d649a0caa1 | |||
| e28894549c | |||
| b3ef90237f | |||
| ebc4e08986 | |||
| 8d74a35f29 | |||
| a37e164c0b | |||
| a71b504589 | |||
|
|
20cd27d7f6 | ||
|
|
ac889dcba9 | ||
|
|
70bbb12285 | ||
|
|
e7e568f67a | ||
|
|
3452ae1d66 | ||
|
|
2ad336b13a | ||
|
|
78b15b78fa | ||
|
|
eb7b637703 | ||
|
|
b083a0801f | ||
|
|
471f1076c4 | ||
|
|
e50fe63e02 | ||
|
|
7682054dea | ||
|
|
1e3c2f039b | ||
|
|
a832e56b42 | ||
|
|
3858cfd9ba | ||
|
|
5b4fd892ff | ||
|
|
4ffa88805c | ||
|
|
2a0b26f2fd | ||
|
|
30308eb308 | ||
|
|
5f8cbe524e | ||
|
|
a2f0142712 | ||
|
|
d2c6529d2a | ||
|
|
b23e32df7f | ||
|
|
a94a0a2f87 | ||
|
|
6fe40e9438 | ||
|
|
d4523e8e1d | ||
|
|
9fadef2a6e | ||
|
|
1970a1b47d | ||
|
|
19d090859c | ||
|
|
7fda77bd1e | ||
|
|
34c14c922c | ||
|
|
0f8a1057dc | ||
|
|
a74faca9cb | ||
|
|
336aa85cf8 | ||
|
|
43710a4c4d | ||
|
|
451cf90939 | ||
|
|
6713f48361 | ||
|
|
f6e3b35482 | ||
|
|
1d7e58d3bf | ||
|
|
b501cd374b | ||
|
|
e6f5723ecc | ||
|
|
998c79d331 | ||
|
|
a21d6e834d | ||
|
|
a4541dd764 | ||
|
|
e788dd543e | ||
|
|
f24fa81d87 | ||
|
|
20fb2a3e92 | ||
|
|
e7f77291e4 | ||
|
|
fa0848c8b2 | ||
|
|
8a740091b3 | ||
|
|
5fa3be5886 | ||
|
|
a9d2f097d8 | ||
|
|
450483acc7 | ||
|
|
43019185a8 | ||
|
|
f537b36662 | ||
|
|
98385b8b56 | ||
|
|
8d44046a90 | ||
|
|
9b1ab459a0 | ||
|
|
f4c0d19734 | ||
|
|
f088bdcf8b | ||
|
|
60600dbe2f | ||
|
|
eb95cc4b47 | ||
|
|
57dfdacffa | ||
|
|
0c839790fe | ||
|
|
1f29916e09 | ||
|
|
310023dc94 | ||
|
|
9448dcefb4 | ||
|
|
167e77ddf2 | ||
|
|
dc586ad82e | ||
|
|
6d331f882f | ||
|
|
b945760c72 | ||
|
|
98aa49c2c3 | ||
|
|
78feab88bf | ||
|
|
6f005d467d | ||
|
|
324011f01b | ||
|
|
0d97d2a02d | ||
|
|
37bec38524 | ||
|
|
847795c0ef | ||
|
|
aa1a5a1550 | ||
|
|
997b3cbecd | ||
|
|
652aced790 | ||
|
|
47af067c03 | ||
|
|
5b31e3eb87 | ||
|
|
0bb4b069e7 | ||
|
|
eded658d38 | ||
|
|
1caeb0ed6b | ||
|
|
611a1f0a04 | ||
|
|
13e58e6f80 | ||
|
|
d6853d381f | ||
|
|
b6cc14fe2f | ||
|
|
9b1f9fa9dd | ||
|
|
cca53b6376 | ||
|
|
1aa991f89f | ||
|
|
7407bbefdf | ||
|
|
40fb835d9c | ||
|
|
e4df92fb54 | ||
|
|
7b9760e376 | ||
|
|
52607545fa | ||
|
|
849756531d | ||
|
|
2e16240fb8 | ||
|
|
181beda455 | ||
|
|
d0f77f4b78 | ||
|
|
dea2f6c8d7 | ||
|
|
615fd414ec | ||
|
|
7296498410 | ||
|
|
554970c036 | ||
|
|
057abe6ba5 | ||
|
|
3b215eb7af | ||
|
|
1abaa0e5c5 | ||
|
|
0c5cb1686e | ||
|
|
21f0aabae0 | ||
|
|
e5458c1ab9 | ||
|
|
a30c0395aa | ||
|
|
0b9006faf3 | ||
|
|
adefb776fe | ||
|
|
ee089b0f31 | ||
|
|
44200458c5 | ||
|
|
5d2d4eae17 | ||
|
|
25f87cae53 | ||
|
|
1e4f11a6ce | ||
|
|
36b9dcaf43 | ||
|
|
ad3aff6a50 | ||
|
|
3bd6da6276 | ||
|
|
3ccc8cdd7b | ||
|
|
501f3a4eec | ||
|
|
cfc6f65da5 | ||
|
|
5853ac1823 | ||
|
|
3057b2a12f | ||
|
|
9ce90b76a4 | ||
|
|
e016a20c21 | ||
|
|
8fb8352c8d | ||
|
|
ed7ecd98c4 | ||
|
|
512c78e192 | ||
|
|
81b3082087 | ||
|
|
6fff929856 | ||
|
|
e636deb08e | ||
|
|
464d5bedda | ||
|
|
9cc70d4212 | ||
|
|
737cdb74bd | ||
|
|
a833139e13 | ||
|
|
4ec9377f78 | ||
|
|
e9e96f287f | ||
|
|
57745f5d0a | ||
|
|
515c2d1f60 | ||
|
|
decbde8d63 | ||
|
|
08c892d4ff | ||
|
|
850a31d172 | ||
|
|
6ae419eeee | ||
|
|
40bae13411 | ||
|
|
61946fe52e | ||
|
|
27cede0fad | ||
|
|
adae63eabb | ||
|
|
3ff5f74af7 | ||
|
|
c3c151b375 | ||
|
|
2163d09c08 | ||
|
|
ea70c2ef9e | ||
|
|
53f949571e | ||
|
|
1d64a6b799 | ||
|
|
84b5790ab2 | ||
|
|
6aa8de3506 | ||
|
|
c1b55139b6 | ||
|
|
670417dc6a | ||
|
|
bd1d1f8ae4 | ||
|
|
29a922e41f | ||
|
|
ac9fd5e618 | ||
|
|
9d6a74680a | ||
|
|
9d52cf27d8 | ||
|
|
35c38387e1 | ||
|
|
908997ddef | ||
|
|
cf0b95e955 | ||
|
|
5bf5d44c96 | ||
|
|
854776dac0 | ||
|
|
6e1ba35ca3 | ||
|
|
a5a41e3b0c | ||
|
|
e78114dd53 | ||
|
|
6174f3709c | ||
|
|
7f1f9b0221 | ||
|
|
0af4e2adb9 | ||
|
|
d5ab596749 | ||
|
|
3d128d4850 | ||
|
|
46aa6fcc48 | ||
|
|
60d1eb4e3c | ||
|
|
4b2c55d90e | ||
|
|
0023c0a4c6 | ||
|
|
0265793a3f | ||
|
|
b99d247ba5 | ||
|
|
bdc1e592a7 | ||
|
|
d3ef7e7f81 | ||
|
|
78dfec15d6 | ||
|
|
7a824e09a3 | ||
|
|
7c58355048 | ||
|
|
89662e7e2c | ||
|
|
718fc750d9 | ||
|
|
9e143fbb73 | ||
|
|
c561181bdf | ||
|
|
b45920109f | ||
|
|
07290fe7ce | ||
|
|
944f57b04a | ||
|
|
4079c6596e | ||
|
|
defe6c4f26 | ||
|
|
ed2a46e059 | ||
|
|
498a0ef7e8 | ||
|
|
06d34d8c55 | ||
|
|
cd670212a2 | ||
|
|
41e58e0bd6 | ||
|
|
b0af47a422 | ||
|
|
ccfb0c72dd | ||
|
|
be1b87a1af | ||
|
|
33ffb80241 | ||
|
|
42b61af93d | ||
|
|
cfdba225e0 | ||
|
|
8c0b3fd31d | ||
|
|
ef88d3e437 | ||
|
|
cbbb04655b | ||
|
|
956b768475 | ||
|
|
51768a5a27 | ||
|
|
4a58967590 | ||
|
|
bc879ee8e2 | ||
|
|
d3046fa588 | ||
|
|
ce8fefe9f8 | ||
|
|
f7369ef4ae | ||
|
|
c0cfb97034 | ||
|
|
c742e9fd31 | ||
|
|
1d1522a9c4 | ||
|
|
a9925b3f15 | ||
|
|
2ea9a58a41 | ||
|
|
9abf7bb45b | ||
|
|
6afaf462f8 | ||
|
|
b1ac913dd8 | ||
|
|
4e5b16c0e2 | ||
|
|
56b2a41eee | ||
|
|
8b32f29c2a | ||
|
|
52ad2e2ddc | ||
|
|
2edd5542f8 | ||
|
|
cb27f145a3 | ||
|
|
44cbe58486 | ||
|
|
1c8844c3c4 | ||
|
|
6c864ea59a | ||
|
|
9818685856 | ||
|
|
51e709acf6 | ||
|
|
f826899f45 | ||
|
|
b3f9aa3d28 | ||
|
|
d9c31f6661 | ||
|
|
2af3f15997 | ||
|
|
701e4bbdbb | ||
|
|
ce8e2597fe | ||
|
|
b185852271 | ||
|
|
7a2ac914df | ||
|
|
a0e3eb21c5 | ||
|
|
c9132b02a4 | ||
|
|
0e81b0f8c8 | ||
|
|
de3bd91d4d |
9
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
Normal file
9
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: Bug report (bluescreen crash) Bug报告 (蓝屏报错)
|
||||
about: Create a report of problems which made the crash with a bluescreen
|
||||
---
|
||||
Screenshot with crash information:
|
||||
*Image Here*
|
||||
|
||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button:
|
||||
*Details Here*
|
||||
9
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
Normal file
9
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: Bug report (unintended behaviors) Bug报告 (奇怪的现象)
|
||||
about: Create a report of unintended behaviors
|
||||
---
|
||||
Screenshot with unintended behaviors:
|
||||
*Image(s) Here*
|
||||
|
||||
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button:
|
||||
*Details Here*
|
||||
4
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_3.md
vendored
Normal file
4
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_3.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
name: Feature Request 添加新功能
|
||||
about: Suggest an idea that may improve Techmino 提一些有意思的新想法,让Techmino越来越好!
|
||||
---
|
||||
101
.github/workflows/build.yml
vendored
101
.github/workflows/build.yml
vendored
@@ -9,6 +9,17 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get CommitID
|
||||
run: |
|
||||
$CommitID=git rev-parse --short "${{ GITHUB.SHA }}"
|
||||
echo "CommitID=${CommitID}" >> $env:GITHUB_ENV
|
||||
- name: Get Version
|
||||
run: |
|
||||
$Version=python .github/workflows/getVersion.py
|
||||
echo "Version=${Version}" >> $env:GITHUB_ENV
|
||||
- name: Update Conf Version
|
||||
run: |
|
||||
python .github/workflows/updateConfVersion.py -H ${{ env.CommitID }}
|
||||
- name: Download love
|
||||
run: |
|
||||
curl -OL https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
@@ -26,16 +37,27 @@ jobs:
|
||||
copy /b love-11.3-win64\love.exe + game.love love-11.3-win64\Techmino.exe
|
||||
del love-11.3-win64\love.exe
|
||||
del love-11.3-win64\lovec.exe
|
||||
- name: Artifact
|
||||
uses: actions/upload-artifact@v1.0.0
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows
|
||||
name: Techmino_${{ env.Version }}_${{ env.CommitID }}_Windows
|
||||
path: love-11.3-win64
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get CommitID
|
||||
run: |
|
||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
||||
- name: Get Version
|
||||
run: |
|
||||
Version=$(python3 .github/workflows/getVersion.py)
|
||||
echo "Version=${Version}" >> $GITHUB_ENV
|
||||
- name: Update Conf Version
|
||||
run: |
|
||||
python3 .github/workflows/updateConfVersion.py -H ${{ env.CommitID }}
|
||||
- name: Download AppImageKit
|
||||
run: curl -OL https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage
|
||||
- name: Unpack and Repack
|
||||
@@ -49,16 +71,27 @@ jobs:
|
||||
cd ../../../..
|
||||
cp -r document media parts Zframework conf.lua font.ttf main.lua squashfs-root/usr/share/Techmino
|
||||
./appimagetool-x86_64.AppImage squashfs-root Techmino.AppImage
|
||||
- name: Artifact
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Linux
|
||||
name: Techmino_${{ env.Version }}_${{ env.CommitID }}_Linux
|
||||
path: Techmino.AppImage
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get CommitID
|
||||
run: |
|
||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
||||
- name: Get Version
|
||||
run: |
|
||||
Version=$(python3 .github/workflows/getVersion.py)
|
||||
echo "Version=${Version}" >> $GITHUB_ENV
|
||||
- name: Update Conf Version
|
||||
run: |
|
||||
python3 .github/workflows/updateConfVersion.py -H ${{ env.CommitID }}
|
||||
- name: Download Apktool
|
||||
run: curl -OL https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.5.0.jar
|
||||
- name: Unpack and Repack
|
||||
@@ -68,10 +101,10 @@ jobs:
|
||||
7z x -o. apk/assets/game.love libAndroid
|
||||
rm apk/assets/game.love Techmino.apk
|
||||
7z a -tzip apk/assets/game.love document libAndroid media parts Zframework conf.lua font.ttf main.lua
|
||||
python3 .github/workflows/updateVersion.py
|
||||
python3 .github/workflows/updateAndroidVersion.py
|
||||
java -jar apktool_2.5.0.jar b -o Techmino.apk apk
|
||||
- uses: 26F-Studio/sign-android-release@master
|
||||
name: Sign app APK
|
||||
name: Sign APK
|
||||
id: sign_app
|
||||
with:
|
||||
releaseDirectory: .
|
||||
@@ -81,8 +114,58 @@ jobs:
|
||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
||||
env:
|
||||
BUILD_TOOLS_VERSION: "30.0.2"
|
||||
- name: Artifact
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Android
|
||||
name: Techmino_${{ env.Version }}_${{ env.CommitID }}_Android
|
||||
path: ${{steps.sign_app.outputs.signedReleaseFile}}
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get CommitID
|
||||
run: |
|
||||
CommitID=$(git rev-parse --short "${{ GITHUB.SHA }}")
|
||||
echo "CommitID=${CommitID}" >> $GITHUB_ENV
|
||||
- name: Get Version
|
||||
run: |
|
||||
Version=$(python3 .github/workflows/getVersion.py)
|
||||
echo "Version=${Version}" >> $GITHUB_ENV
|
||||
- name: Update Conf Version
|
||||
run: |
|
||||
python3 .github/workflows/updateConfVersion.py -H ${{ env.CommitID }}
|
||||
- name: Pack love
|
||||
run: |
|
||||
zip -r Techmino.love document media parts Zframework conf.lua font.ttf main.lua
|
||||
- name: Download template
|
||||
run: |
|
||||
curl -OL https://github.com/26F-Studio/Techmino/releases/download/v0.15.1/Techmino.app.zip
|
||||
unzip Techmino.app.zip
|
||||
- name: Modify template
|
||||
run: |
|
||||
python3 .github/workflows/updateOSXVersion.py
|
||||
mv Techmino.love Techmino.app/Contents/Resources
|
||||
- name: Codesign executable
|
||||
# In secrets:
|
||||
# - MACOS_CERTIFICATE: the *.p12 Developer ID Certificate, encoded in base64
|
||||
# - MACOS_CERTIFICATE_PWD: The password
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
run: |
|
||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
||||
security create-keychain -p Techminohaowan build.keychain
|
||||
security default-keychain -s build.keychain
|
||||
security unlock-keychain -p Techminohaowan build.keychain
|
||||
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k Techminohaowan build.keychain
|
||||
/usr/bin/codesign --force --deep -s 79B81FC5EA155243C973B5417B0996501F00EF55 ./Techmino.app -v
|
||||
- name: Pack Techmino
|
||||
run: |
|
||||
zip -r -y Techmino-Packed.app.zip Techmino.app
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ env.Version }}_${{ env.CommitID }}_macOS
|
||||
path: Techmino-Packed.app.zip
|
||||
11
.github/workflows/getVersion.py
vendored
Normal file
11
.github/workflows/getVersion.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import re
|
||||
def getVersion():
|
||||
with open("conf.lua", "r", encoding="utf-8") as file:
|
||||
data = file.read()
|
||||
versionCode = re.search("build=(\\d+)", data).group(1)
|
||||
versionName = re.search('(?<=string=").*(?=@)', data).group()
|
||||
return versionCode, versionName
|
||||
|
||||
if __name__ == "__main__":
|
||||
versionCode, versionName = getVersion()
|
||||
print (versionName)
|
||||
@@ -1,12 +1,12 @@
|
||||
import re
|
||||
with open("conf.lua", "r") as file:
|
||||
data = file.read()
|
||||
versionCode = re.search("build=(\\d+)", data).group(1)
|
||||
versionName = re.search('short="([^"]+)', data).group(1)
|
||||
import getVersion
|
||||
|
||||
versionCode, versionName = getVersion.getVersion()
|
||||
|
||||
with open("apk/apktool.yml", "r+") as file:
|
||||
data = file.read()
|
||||
data = re.sub("versionCode:.+", f"versionCode: '{versionCode}'", data)
|
||||
data = re.sub("versionName:.+", f"versionName: {versionName}", data)
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.write(data)
|
||||
file.write(data)
|
||||
13
.github/workflows/updateConfVersion.py
vendored
Normal file
13
.github/workflows/updateConfVersion.py
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import argparse
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="用于更新conf.lua内编译版本号")
|
||||
parser.add_argument("-H", "--Hash", type=str, help = "Github提交Hash")
|
||||
args = parser.parse_args()
|
||||
with open("conf.lua", "r+", encoding="utf-8") as file:
|
||||
data = file.read()
|
||||
data = data.replace('@DEV', f'@{args.Hash[0:4]}')
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.flush()
|
||||
file.write(data)
|
||||
65
.github/workflows/updateOSXVersion.py
vendored
Normal file
65
.github/workflows/updateOSXVersion.py
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import datetime
|
||||
import getVersion
|
||||
info = r"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>19B88</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>love</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>iconfile</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.love2d.MrZ.Techmino</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Techmino</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>%s</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>LoVe</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>19B90</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.15</string>
|
||||
<key>DTXcode</key>
|
||||
<string>1130</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>11C504</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.7</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>©2020-%d 26F Studio, GNU LGPLv3.0</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
"""
|
||||
|
||||
versionCode, versionName = getVersion.getVersion()
|
||||
|
||||
print("Updating to", versionName)
|
||||
with open("Techmino.app/Contents/info.plist", "w") as file:
|
||||
file.write(info % (versionName, datetime.datetime.today().year))
|
||||
@@ -5,4 +5,4 @@
|
||||
|
||||
集合各种现代方块规则,更多玩法,全新体验。
|
||||
|
||||
官网(建设中) https://home.techmino.org
|
||||
官网(建设中) http://home.techmino.org
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
local printf=love.graphics.printf
|
||||
local draw=love.graphics.draw
|
||||
local aDraw={}
|
||||
function aDraw.str(obj,x,y)printf(obj,x-626,y,1252,'center')end
|
||||
function aDraw.simpX(obj,x,y)draw(obj,x-obj:getWidth()*.5,y)end
|
||||
function aDraw.simpY(obj,x,y)draw(obj,x,y-obj:getHeight()*.5)end
|
||||
function aDraw.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end
|
||||
function aDraw.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end
|
||||
function aDraw.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end
|
||||
function aDraw.outDraw(obj,div,x,y,a,k)
|
||||
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
|
||||
draw(obj,x-div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x-div,y+div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y+div,a,k,nil,w,h)
|
||||
end
|
||||
return aDraw
|
||||
@@ -1,6 +1,6 @@
|
||||
local gc_clear=love.graphics.clear
|
||||
local BGs={
|
||||
none={draw=function()gc_clear(.15,.15,.15)end}
|
||||
none={draw=function()gc_clear(.08,.08,.084)end}
|
||||
}
|
||||
local BGlist={'none'}
|
||||
local BG={
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local BGM={
|
||||
default=false,
|
||||
getList=function()error("Can't getList before initialized!")end,
|
||||
getList=function()error("Cannot getList before initialize!")end,
|
||||
getCount=function()return 0 end,
|
||||
play=NULL,
|
||||
freshVolume=NULL,
|
||||
@@ -13,10 +13,19 @@ function BGM.setDefault(bgm)
|
||||
end
|
||||
function BGM.init(list)
|
||||
BGM.init=nil
|
||||
local min=math.min
|
||||
local Sources={}function BGM.getList()return list end
|
||||
local Sources={}
|
||||
|
||||
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
|
||||
function BGM.getCount()return count end
|
||||
function BGM.loadAll()for name in next,Sources do load(name)end end
|
||||
|
||||
local count=#list function BGM.getCount()return count end
|
||||
local function fadeOut(src)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
@@ -32,7 +41,7 @@ function BGM.init(list)
|
||||
while true do
|
||||
coroutine.yield()
|
||||
local v=SETTING.bgm
|
||||
v=min(v,src:getVolume()+.025*v)
|
||||
v=math.min(v,src:getVolume()+.025*v)
|
||||
src:setVolume(v)
|
||||
if v>=SETTING.bgm then
|
||||
return true
|
||||
@@ -42,62 +51,59 @@ function BGM.init(list)
|
||||
local function removeCurFadeOut(task,code,src)
|
||||
return task.code==code and task.args[1]==src
|
||||
end
|
||||
local function load(skip)
|
||||
for i=1,count do
|
||||
local file='media/BGM/'..list[i]..'.ogg'
|
||||
if love.filesystem.getInfo(file)then
|
||||
Sources[list[i]]=love.audio.newSource(file,'stream')
|
||||
Sources[list[i]]:setLooping(true)
|
||||
Sources[list[i]]:setVolume(0)
|
||||
local function load(name)
|
||||
if type(Sources[name])=='string'then
|
||||
if love.filesystem.getInfo(Sources[name])then
|
||||
Sources[name]=love.audio.newSource(Sources[name],'stream')
|
||||
Sources[name]:setLooping(true)
|
||||
Sources[name]:setVolume(0)
|
||||
return true
|
||||
else
|
||||
MES.new('warn',"No BGM file: "..list[i],5)
|
||||
MES.new('warn',"No BGM file: "..Sources[name],5)
|
||||
end
|
||||
if not skip and i~=count then
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
BGM.loadOne=nil
|
||||
|
||||
function BGM.play(s)
|
||||
if not s then s=BGM.default end
|
||||
if SETTING.bgm==0 then
|
||||
BGM.nowPlay=s
|
||||
BGM.playing=Sources[s]
|
||||
return true
|
||||
end
|
||||
if s and Sources[s]then
|
||||
if BGM.nowPlay~=s then
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
TASK.removeTask_iterate(removeCurFadeOut,fadeOut,Sources[s])
|
||||
TASK.removeTask_code(fadeIn)
|
||||
|
||||
TASK.new(fadeIn,Sources[s])
|
||||
BGM.nowPlay=s
|
||||
BGM.playing=Sources[s]
|
||||
BGM.playing:play()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
function BGM.freshVolume()
|
||||
if BGM.playing then
|
||||
local v=SETTING.bgm
|
||||
if v>0 then
|
||||
BGM.playing:setVolume(v)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.stop()
|
||||
TASK.removeTask_code(fadeIn)
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
BGM.nowPlay,BGM.playing=nil
|
||||
elseif Sources[name]then
|
||||
return true
|
||||
elseif name then
|
||||
MES.new('warn',"No BGM: "..name,5)
|
||||
end
|
||||
end
|
||||
function BGM.play(name)
|
||||
if not name then name=BGM.default end
|
||||
if not load(name)then return end
|
||||
if SETTING.bgm==0 then
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
return true
|
||||
end
|
||||
if name and Sources[name]then
|
||||
if BGM.nowPlay~=name then
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
TASK.removeTask_iterate(removeCurFadeOut,fadeOut,Sources[name])
|
||||
TASK.removeTask_code(fadeIn)
|
||||
|
||||
BGM.loadOne=coroutine.wrap(load)
|
||||
function BGM.loadAll()load(true)end
|
||||
TASK.new(fadeIn,Sources[name])
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
BGM.playing:play()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
function BGM.freshVolume()
|
||||
if BGM.playing then
|
||||
local v=SETTING.bgm
|
||||
if v>0 then
|
||||
BGM.playing:setVolume(v)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.stop()
|
||||
TASK.removeTask_code(fadeIn)
|
||||
if BGM.nowPlay then TASK.new(fadeOut,BGM.playing)end
|
||||
BGM.nowPlay,BGM.playing=nil
|
||||
end
|
||||
end
|
||||
return BGM
|
||||
@@ -1,60 +1,60 @@
|
||||
local COLOR={
|
||||
red= {1.0, 0.0, 0.0},
|
||||
fire= {1.0, 0.4, 0.0},
|
||||
orange= {1.0, 0.6, 0.0},
|
||||
yellow= {1.0, 1.0, 0.0},
|
||||
lime= {0.7, 1.0, 0.0},
|
||||
jade= {0.5, 1.0, 0.0},
|
||||
green= {0.0, 1.0, 0.0},
|
||||
aqua= {0.0, 1.0, 0.6},
|
||||
cyan= {0.0, 1.0, 1.0},
|
||||
navy= {0.0, 0.7, 1.0},
|
||||
sea= {0.0, 0.4, 1.0},
|
||||
blue= {0.2, 0.2, 1.0},
|
||||
violet= {0.4, 0.0, 1.0},
|
||||
purple= {0.7, 0.0, 1.0},
|
||||
magenta= {1.0, 0.0, 1.0},
|
||||
wine= {1.0, 0.0, 0.5},
|
||||
red= {.92, .12, .12},
|
||||
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= {1.0, 0.5, 0.5},
|
||||
lFire= {1.0, 0.7, 0.5},
|
||||
lOrange= {1.0, 0.8, 0.3},
|
||||
lYellow= {1.0, 1.0, 0.5},
|
||||
lLime= {0.8, 1.0, 0.4},
|
||||
lJade= {0.6, 1.0, 0.4},
|
||||
lGreen= {0.5, 1.0, 0.5},
|
||||
lAqua= {0.4, 1.0, 0.7},
|
||||
lCyan= {0.5, 1.0, 1.0},
|
||||
lNavy= {0.5, 0.8, 1.0},
|
||||
lSea= {0.4, 0.7, 1.0},
|
||||
lBlue= {0.7, 0.7, 1.0},
|
||||
lViolet= {0.7, 0.4, 1.0},
|
||||
lPurple= {0.8, 0.4, 1.0},
|
||||
lMagenta= {1.0, 0.5, 1.0},
|
||||
lWine= {1.0, 0.4, 0.7},
|
||||
lRed= {.95, 0.5, 0.5},
|
||||
lFire= {.95, 0.7, 0.5},
|
||||
lOrange= {.95, 0.8, 0.3},
|
||||
lYellow= {.95, .95, 0.5},
|
||||
lLime= {0.8, .95, 0.4},
|
||||
lJade= {0.6, .95, 0.4},
|
||||
lGreen= {0.5, .95, 0.5},
|
||||
lAqua= {0.4, .95, 0.7},
|
||||
lCyan= {0.5, .95, .95},
|
||||
lNavy= {0.4, .85, .95},
|
||||
lSea= {0.5, 0.7, .95},
|
||||
lBlue= {0.7, 0.7, .95},
|
||||
lViolet= {0.7, 0.4, .95},
|
||||
lPurple= {0.8, 0.4, .95},
|
||||
lMagenta= {.95, 0.5, .95},
|
||||
lWine= {.95, 0.4, 0.7},
|
||||
|
||||
dRed= {0.6, 0.0, 0.0},
|
||||
dFire= {0.6, 0.3, 0.0},
|
||||
dOrange= {0.6, 0.4, 0.0},
|
||||
dYellow= {0.6, 0.6, 0.0},
|
||||
dLime= {0.5, 0.6, 0.0},
|
||||
dJade= {0.3, 0.6, 0.0},
|
||||
dGreen= {0.0, 0.6, 0.0},
|
||||
dAqua= {0.0, 0.6, 0.4},
|
||||
dCyan= {0.0, 0.6, 0.6},
|
||||
dNavy= {0.0, 0.4, 0.6},
|
||||
dSea= {0.0, 0.2, 0.6},
|
||||
dRed= {0.6, .08, .08},
|
||||
dFire= {0.6, 0.3, .08},
|
||||
dOrange= {0.6, 0.4, .08},
|
||||
dYellow= {0.6, 0.6, .08},
|
||||
dLime= {0.5, 0.6, .08},
|
||||
dJade= {0.3, 0.6, .08},
|
||||
dGreen= {.08, 0.6, .08},
|
||||
dAqua= {.08, 0.6, 0.4},
|
||||
dCyan= {.08, 0.6, 0.6},
|
||||
dNavy= {.08, 0.4, 0.6},
|
||||
dSea= {.08, 0.2, 0.6},
|
||||
dBlue= {0.1, 0.1, 0.6},
|
||||
dViolet= {0.2, 0.0, 0.6},
|
||||
dPurple= {0.4, 0.0, 0.6},
|
||||
dMagenta= {0.6, 0.0, 0.6},
|
||||
dWine= {0.6, 0.0, 0.3},
|
||||
dViolet= {0.2, .08, 0.6},
|
||||
dPurple= {0.4, .08, 0.6},
|
||||
dMagenta= {0.6, .08, 0.6},
|
||||
dWine= {0.6, .08, 0.3},
|
||||
|
||||
black= {0.0, 0.0, 0.0},
|
||||
black= {.05, .05, .05},
|
||||
dGray= {0.3, 0.3, 0.3},
|
||||
gray= {0.6, 0.6, 0.6},
|
||||
lGray= {0.8, 0.8, 0.8},
|
||||
white= {1.0, 1.0, 1.0},
|
||||
white= {.97, .97, .97},
|
||||
}
|
||||
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',
|
||||
@@ -93,29 +93,33 @@ end
|
||||
|
||||
do--Rainbow generators
|
||||
local sin=math.sin
|
||||
function COLOR.rainbow(phase)
|
||||
function COLOR.rainbow(phase,a)
|
||||
return
|
||||
sin(phase)*.4+.6,
|
||||
sin(phase+2.0944)*.4+.6,
|
||||
sin(phase-2.0944)*.4+.6
|
||||
sin(phase-2.0944)*.4+.6,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_light(phase)
|
||||
function COLOR.rainbow_light(phase,a)
|
||||
return
|
||||
sin(phase)*.2+.7,
|
||||
sin(phase+2.0944)*.2+.7,
|
||||
sin(phase-2.0944)*.2+.7
|
||||
sin(phase-2.0944)*.2+.7,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_dark(phase)
|
||||
function COLOR.rainbow_dark(phase,a)
|
||||
return
|
||||
sin(phase)*.2+.4,
|
||||
sin(phase+2.0944)*.2+.4,
|
||||
sin(phase-2.0944)*.2+.4
|
||||
sin(phase-2.0944)*.2+.4,
|
||||
a
|
||||
end
|
||||
function COLOR.rainbow_gray(phase)
|
||||
function COLOR.rainbow_gray(phase,a)
|
||||
return
|
||||
sin(phase)*.16+.5,
|
||||
sin(phase+2.0944)*.16+.5,
|
||||
sin(phase-2.0944)*.16+.5
|
||||
sin(phase-2.0944)*.16+.5,
|
||||
a
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ local cmds={
|
||||
|
||||
print="print",
|
||||
setFT=setFont,
|
||||
mText=ADRAW.str,
|
||||
mDraw=ADRAW.draw,
|
||||
mOutDraw=ADRAW.outDraw,
|
||||
mText=GC.str,
|
||||
mDraw=GC.draw,
|
||||
mOutDraw=GC.outDraw,
|
||||
|
||||
draw="draw",
|
||||
line="line",
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
local find=string.find
|
||||
local tabs={
|
||||
[0]="",
|
||||
"\t",
|
||||
"\t\t",
|
||||
"\t\t\t",
|
||||
"\t\t\t\t",
|
||||
"\t\t\t\t\t",
|
||||
}
|
||||
return function(L,t)
|
||||
local s
|
||||
if t then
|
||||
s="{\n"
|
||||
else
|
||||
s="return{\n"
|
||||
t=1
|
||||
if type(L)~='table'then
|
||||
return
|
||||
end
|
||||
end
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=='number'then
|
||||
if k==count then
|
||||
k=""
|
||||
count=count+1
|
||||
else
|
||||
k="["..k.."]="
|
||||
end
|
||||
elseif T=='string'then
|
||||
if find(k,"[^0-9a-zA-Z_]")then
|
||||
k="[\""..k.."\"]="
|
||||
else
|
||||
k=k.."="
|
||||
end
|
||||
elseif T=='boolean'then k="["..k.."]="
|
||||
else error("Error key type!")
|
||||
end
|
||||
T=type(v)
|
||||
if T=='number'then v=tostring(v)
|
||||
elseif T=='string'then v="\""..v.."\""
|
||||
elseif T=='table'then v=TABLE.dump(v,t+1)
|
||||
elseif T=='boolean'then v=tostring(v)
|
||||
else error("Error data type!")
|
||||
end
|
||||
s=s..tabs[t]..k..v..",\n"
|
||||
end
|
||||
return s..tabs[t-1].."}"
|
||||
end
|
||||
@@ -44,15 +44,20 @@ function FILE.save(data,name,mode)
|
||||
data=tostring(data)
|
||||
end
|
||||
|
||||
if mode:find'd'and fs.getInfo(name)then
|
||||
MES.new('error',text.saveError_duplicate)
|
||||
return
|
||||
end
|
||||
local F=fs.newFile(name)
|
||||
F:open'w'
|
||||
local success,mes=F:write(data)
|
||||
F:flush()F:close()
|
||||
if not success then
|
||||
if success then
|
||||
return true
|
||||
else
|
||||
MES.new('error',text.saveError..(mes or"unknown error"))
|
||||
MES.traceback()
|
||||
end
|
||||
return success
|
||||
end
|
||||
function FILE.clear(path)
|
||||
if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end
|
||||
|
||||
160
Zframework/gcExtend.lua
Normal file
160
Zframework/gcExtend.lua
Normal file
@@ -0,0 +1,160 @@
|
||||
local gc=love.graphics
|
||||
local setColor=gc.setColor
|
||||
local printf=gc.printf
|
||||
local draw=gc.draw
|
||||
local GC={}
|
||||
function GC.str(obj,x,y)printf(obj,x-626,y,1252,'center')end
|
||||
function GC.simpX(obj,x,y)draw(obj,x-obj:getWidth()*.5,y)end
|
||||
function GC.simpY(obj,x,y)draw(obj,x,y-obj:getHeight()*.5)end
|
||||
function GC.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end
|
||||
function GC.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end
|
||||
function GC.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end
|
||||
function GC.outDraw(obj,div,x,y,a,k)
|
||||
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
|
||||
draw(obj,x-div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x-div,y+div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y-div,a,k,nil,w,h)
|
||||
draw(obj,x+div,y+div,a,k,nil,w,h)
|
||||
end
|
||||
function GC.shadedPrint(str,x,y,mode,d,clr1,clr2)
|
||||
local w=1280
|
||||
if mode=='center'then
|
||||
x=x-w*.5
|
||||
elseif mode=='right'then
|
||||
x=x-w
|
||||
end
|
||||
if not d then d=1 end
|
||||
setColor(clr1 or COLOR.D)
|
||||
printf(str,x-d,y-d,w,mode)
|
||||
printf(str,x-d,y+d,w,mode)
|
||||
printf(str,x+d,y-d,w,mode)
|
||||
printf(str,x+d,y+d,w,mode)
|
||||
setColor(clr2 or COLOR.Z)
|
||||
printf(str,x,y,w,mode)
|
||||
end
|
||||
function GC.regularPolygon(mode,x,y,R,segments,r,phase)
|
||||
local X,Y={},{}
|
||||
local ang=phase or 0
|
||||
local angStep=6.283185307179586/segments
|
||||
for i=1,segments do
|
||||
X[i]=x+R*math.cos(ang)
|
||||
Y[i]=y+R*math.sin(ang)
|
||||
ang=ang+angStep
|
||||
end
|
||||
X[segments+1]=x+R*math.cos(ang)
|
||||
Y[segments+1]=y+R*math.sin(ang)
|
||||
local halfAng=6.283185307179586/segments/2
|
||||
local erasedLen=r*math.tan(halfAng)
|
||||
if mode=='line'then
|
||||
erasedLen=erasedLen+1--Fix 1px cover
|
||||
for i=1,segments do
|
||||
--Line
|
||||
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
|
||||
local dir=math.atan2(y2-y1,x2-x1)
|
||||
gc.line(x1+erasedLen*math.cos(dir),y1+erasedLen*math.sin(dir),x2-erasedLen*math.cos(dir),y2-erasedLen*math.sin(dir))
|
||||
|
||||
--Arc
|
||||
ang=ang+angStep
|
||||
local R2=R-r/math.cos(halfAng)
|
||||
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
|
||||
gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
|
||||
end
|
||||
elseif mode=='fill'then
|
||||
local L={}
|
||||
for i=1,segments do
|
||||
--Line
|
||||
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
|
||||
local dir=math.atan2(y2-y1,x2-x1)
|
||||
table.insert(L,x1+erasedLen*math.cos(dir))
|
||||
table.insert(L,y1+erasedLen*math.sin(dir))
|
||||
table.insert(L,x2-erasedLen*math.cos(dir))
|
||||
table.insert(L,y2-erasedLen*math.sin(dir))
|
||||
|
||||
--Arc
|
||||
ang=ang+angStep
|
||||
local R2=R-r/math.cos(halfAng)
|
||||
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
|
||||
gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
|
||||
end
|
||||
gc.polygon('fill',L)
|
||||
else
|
||||
error("Draw mode should be 'line' or 'fill'")
|
||||
end
|
||||
end
|
||||
do--function GC.DO(L)
|
||||
local cmds={
|
||||
origin="origin",
|
||||
move="translate",
|
||||
scale="scale",
|
||||
rotate="rotate",
|
||||
shear="shear",
|
||||
clear="clear",
|
||||
|
||||
setCL="setColor",
|
||||
setCM="setColorMask",
|
||||
setLW="setLineWidth",
|
||||
setLS="setLineStyle",
|
||||
setLJ="setLineJoin",
|
||||
|
||||
print="print",
|
||||
setFT=setFont,
|
||||
mText=GC.str,
|
||||
mDraw=GC.draw,
|
||||
mOutDraw=GC.outDraw,
|
||||
|
||||
draw="draw",
|
||||
line="line",
|
||||
fRect=function(...)gc.rectangle('fill',...)end,
|
||||
dRect=function(...)gc.rectangle('line',...)end,
|
||||
fCirc=function(...)gc.circle('fill',...)end,
|
||||
dCirc=function(...)gc.circle('line',...)end,
|
||||
fElps=function(...)gc.ellipse('fill',...)end,
|
||||
dElps=function(...)gc.ellipse('line',...)end,
|
||||
fPoly=function(...)gc.polygon('fill',...)end,
|
||||
dPoly=function(...)gc.polygon('line',...)end,
|
||||
|
||||
dPie=function(...)gc.arc('line',...)end,
|
||||
dArc=function(...)gc.arc('line','open',...)end,
|
||||
dBow=function(...)gc.arc('line','closed',...)end,
|
||||
fPie=function(...)gc.arc('fill',...)end,
|
||||
fArc=function(...)gc.arc('fill','open',...)end,
|
||||
fBow=function(...)gc.arc('fill','closed',...)end,
|
||||
|
||||
fRPol=function(...)GC.regularPolygon('fill',...)end,
|
||||
dRPol=function(...)GC.regularPolygon('line',...)end,
|
||||
}
|
||||
local sizeLimit=gc.getSystemLimits().texturesize
|
||||
function GC.DO(L)
|
||||
gc.push()
|
||||
::REPEAT_tryAgain::
|
||||
local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit))
|
||||
if not success then
|
||||
sizeLimit=math.floor(sizeLimit*.8)
|
||||
goto REPEAT_tryAgain
|
||||
end
|
||||
gc.setCanvas(canvas)
|
||||
gc.origin()
|
||||
gc.setColor(1,1,1)
|
||||
gc.setLineWidth(1)
|
||||
for i=3,#L do
|
||||
local cmd=L[i][1]
|
||||
if type(cmd)=='boolean'and cmd then
|
||||
table.remove(L[i],1)
|
||||
cmd=L[i][1]
|
||||
end
|
||||
if type(cmd)=='string'then
|
||||
local func=cmds[cmd]
|
||||
if type(func)=='string'then func=gc[func]end
|
||||
if func then
|
||||
func(unpack(L[i],2))
|
||||
else
|
||||
error("No gc command: "..cmd)
|
||||
end
|
||||
end
|
||||
end
|
||||
gc.setCanvas()
|
||||
gc.pop()
|
||||
return canvas
|
||||
end
|
||||
end
|
||||
return GC
|
||||
@@ -1,35 +1,26 @@
|
||||
local IMG={
|
||||
getCount=function()return 0 end,
|
||||
}
|
||||
local IMG={}
|
||||
function IMG.init(list)
|
||||
IMG.init=nil
|
||||
local count=0
|
||||
for k,v in next,list do
|
||||
count=count+1
|
||||
IMG[k]=v
|
||||
end
|
||||
function IMG.getCount()return count end
|
||||
local function load(skip)
|
||||
local loaded=0
|
||||
for k,v in next,list do
|
||||
if type(v)=='string'then
|
||||
IMG[k]=love.graphics.newImage('media/image/'..v)
|
||||
else
|
||||
for i=1,#v do
|
||||
v[i]=love.graphics.newImage('media/image/'..v[i])
|
||||
end
|
||||
IMG[k]=v
|
||||
end
|
||||
loaded=loaded+1
|
||||
if not skip and loaded~=count then
|
||||
coroutine.yield()
|
||||
|
||||
local null=love.graphics.newCanvas(1,1)
|
||||
setmetatable(IMG,{__index=function(self,name)
|
||||
if type(list[name])=='table'then
|
||||
self[name]={}
|
||||
for i=1,#list[name]do
|
||||
self[name][i]=love.graphics.newImage(list[name][i])
|
||||
end
|
||||
elseif type(list[name])=='string'then
|
||||
self[name]=love.graphics.newImage(list[name])
|
||||
else
|
||||
MES.new('warn',"No BGM: "..name,5)
|
||||
self[name]=null
|
||||
end
|
||||
IMG.loadOne=nil
|
||||
return self[name]
|
||||
end})
|
||||
|
||||
function IMG.loadAll()
|
||||
for k in next,list do local _=IMG[k]end
|
||||
IMG.loadAll=nil
|
||||
end
|
||||
|
||||
IMG.loadOne=coroutine.wrap(load)
|
||||
function IMG.loadAll()load(true)end
|
||||
end
|
||||
return IMG
|
||||
@@ -3,17 +3,17 @@ EDITING=""
|
||||
LOADED=false
|
||||
ERRDATA={}
|
||||
|
||||
require'Zframework.setFont'
|
||||
ADRAW=require'Zframework.aDraw'
|
||||
mStr=ADRAW.str
|
||||
mText=ADRAW.simpX
|
||||
mDraw=ADRAW.draw
|
||||
|
||||
SCR= require'Zframework.screen'
|
||||
COLOR= require'Zframework.color'
|
||||
SCN= require'Zframework.scene'
|
||||
WS= require'Zframework.websocket'
|
||||
|
||||
require'Zframework.setFont'
|
||||
GC=require'Zframework.gcExtend'
|
||||
mStr=GC.str
|
||||
mText=GC.simpX
|
||||
mDraw=GC.draw
|
||||
|
||||
LOADLIB=require'Zframework.loadLib'
|
||||
WHEELMOV=require'Zframework.wheelScroll'
|
||||
|
||||
@@ -25,7 +25,6 @@ VIB= require'Zframework.vibrate'
|
||||
SFX= require'Zframework.sfx'
|
||||
|
||||
LIGHT= require'Zframework.light'
|
||||
DOGC= require'Zframework.doGC'
|
||||
BG= require'Zframework.background'
|
||||
WIDGET= require'Zframework.widget'
|
||||
TEXT= require'Zframework.text'
|
||||
@@ -45,7 +44,7 @@ THEME= require'Zframework.theme'
|
||||
local ms,kb=love.mouse,love.keyboard
|
||||
|
||||
local gc=love.graphics
|
||||
local gc_push,gc_pop,gc_clear=gc.push,gc.pop,gc.clear
|
||||
local gc_push,gc_pop,gc_clear,gc_discard=gc.push,gc.pop,gc.clear,gc.discard
|
||||
local gc_replaceTransform,gc_present=gc.replaceTransform,gc.present
|
||||
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
||||
local gc_draw,gc_line,gc_print=gc.draw,gc.line,gc.print
|
||||
@@ -66,7 +65,7 @@ joysticks={}
|
||||
|
||||
local devMode
|
||||
|
||||
local batteryImg=DOGC{31,20,
|
||||
local batteryImg=GC.DO{31,20,
|
||||
{'fRect',1,0,26,2},
|
||||
{'fRect',1,18,26,2},
|
||||
{'fRect',0,1,2,18},
|
||||
@@ -97,12 +96,12 @@ local function updatePowerInfo()
|
||||
gc.rectangle('fill',76,6,pow*.22,14)
|
||||
if pow<100 then
|
||||
setFont(15)
|
||||
gc_setColor(0,0,0)
|
||||
gc.setColor(COLOR.D)
|
||||
gc_print(pow,77,1)
|
||||
gc_print(pow,77,3)
|
||||
gc_print(pow,79,1)
|
||||
gc_print(pow,79,3)
|
||||
gc_setColor(1,1,1)
|
||||
gc_setColor(COLOR.Z)
|
||||
gc_print(pow,78,2)
|
||||
end
|
||||
end
|
||||
@@ -149,10 +148,13 @@ end
|
||||
function love.mousereleased(x,y,k,touch)
|
||||
if touch or SCN.swapping then return end
|
||||
mx,my=ITP(xOy,x,y)
|
||||
WIDGET.release(mx,my)
|
||||
if SCN.mouseUp then SCN.mouseUp(mx,my,k)end
|
||||
if lastX and SCN.mouseClick and(mx-lastX)^2+(my-lastY)^2<62 then
|
||||
SCN.mouseClick(mx,my,k)
|
||||
if WIDGET.sel then
|
||||
WIDGET.release(mx,my)
|
||||
else
|
||||
if lastX and SCN.mouseClick and(mx-lastX)^2+(my-lastY)^2<62 then
|
||||
SCN.mouseClick(mx,my,k)
|
||||
end
|
||||
end
|
||||
end
|
||||
function love.wheelmoved(x,y)
|
||||
@@ -215,7 +217,7 @@ local function noDevkeyPressed(key)
|
||||
elseif key=="f4"then
|
||||
for _=1,8 do
|
||||
local P=PLY_ALIVE[rnd(#PLY_ALIVE)]
|
||||
if P~=PLAYERS[1]then
|
||||
if P and P~=PLAYERS[1]then
|
||||
P.lastRecv=PLAYERS[1]
|
||||
P:lose()
|
||||
end
|
||||
@@ -471,6 +473,7 @@ function love.errorhandler(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
love.threaderror=nil
|
||||
|
||||
love.draw,love.update=nil--remove default draw/update
|
||||
|
||||
@@ -492,47 +495,50 @@ local wsBottomImage do
|
||||
ins(L,{'setCL',1,1,1,i*.005})
|
||||
ins(L,{'fRect',i,0,1,18})
|
||||
end
|
||||
wsBottomImage=DOGC(L)
|
||||
wsBottomImage=GC.DO(L)
|
||||
end
|
||||
local ws_deadImg=DOGC{20,20,
|
||||
local ws_deadImg=GC.DO{20,20,
|
||||
{'setFT',20},
|
||||
{'setCL',1,.3,.3},
|
||||
{'print',"X",3,-4},
|
||||
}
|
||||
local ws_connectingImg=DOGC{20,20,
|
||||
local ws_connectingImg=GC.DO{20,20,
|
||||
{'setLW',3},
|
||||
{'dArc',11.5,10,6.26,1,5.28},
|
||||
}
|
||||
local ws_runningImg=DOGC{20,20,
|
||||
local ws_runningImg=GC.DO{20,20,
|
||||
{'setFT',20},
|
||||
{'setCL',.5,1,0},
|
||||
{'print',"R",3,-4},
|
||||
}
|
||||
local cursorImg=DOGC{16,16,
|
||||
{"fCirc",8,8,4},
|
||||
{"setCL",1,1,1,.7},
|
||||
{"fCirc",8,8,6},
|
||||
local cursorImg=GC.DO{16,16,
|
||||
{'fCirc',8,8,4},
|
||||
{'setCL',1,1,1,.7},
|
||||
{'fCirc',8,8,6},
|
||||
}
|
||||
local cursor_holdImg=DOGC{16,16,
|
||||
{"setLW",2},
|
||||
{"dCirc",8,8,7},
|
||||
{"fCirc",8,8,3},
|
||||
local cursor_holdImg=GC.DO{16,16,
|
||||
{'setLW',2},
|
||||
{'dCirc',8,8,7},
|
||||
{'fCirc',8,8,3},
|
||||
}
|
||||
function love.run()
|
||||
local love=love
|
||||
|
||||
local VOC,BG,SYSFX=VOC,BG,SYSFX
|
||||
local TASK,TEXT=TASK,TEXT
|
||||
|
||||
local TEXTURE,TIME=TEXTURE,TIME
|
||||
local SETTING,VERSION=SETTING,VERSION
|
||||
local BG=BG
|
||||
local TEXT_update,TEXT_draw=TEXT.update,TEXT.draw
|
||||
local MES_update,MES_draw=MES.update,MES.draw
|
||||
local WS_update=WS.update
|
||||
local TASK_update=TASK.update
|
||||
local SYSFX_update,SYSFX_draw=SYSFX.update,SYSFX.draw
|
||||
local WIDGET_update,WIDGET_draw=WIDGET.update,WIDGET.draw
|
||||
|
||||
local STEP,WAIT=love.timer.step,love.timer.sleep
|
||||
local FPS,MINI=love.timer.getFPS,love.window.isMinimized
|
||||
local PUMP,POLL=love.event.pump,love.event.poll
|
||||
|
||||
local frameTimeList={}
|
||||
local TIME,SETTING,VERSION=TIME,SETTING,VERSION
|
||||
|
||||
local frameTimeList={}
|
||||
local lastFrame=TIME()
|
||||
local lastFreshPow=lastFrame
|
||||
local FCT=0--Framedraw counter, from 0~99
|
||||
@@ -564,16 +570,16 @@ function love.run()
|
||||
|
||||
--UPDATE
|
||||
STEP()
|
||||
TASK.update()
|
||||
WS.update(dt)
|
||||
VOC.update()
|
||||
BG.update(dt)
|
||||
SYSFX.update(dt)
|
||||
TEXT_update()
|
||||
MES_update(dt)
|
||||
WS_update(dt)
|
||||
TASK_update()
|
||||
SYSFX_update(dt)
|
||||
if SCN.update then SCN.update(dt)end
|
||||
if SCN.swapping then SCN.swapUpdate()end
|
||||
WIDGET.update()
|
||||
TEXT.update()
|
||||
MES.update(dt)
|
||||
WIDGET_update()
|
||||
|
||||
--DRAW
|
||||
if not MINI()then
|
||||
@@ -581,32 +587,33 @@ function love.run()
|
||||
if FCT>=100 then
|
||||
FCT=FCT-100
|
||||
|
||||
local safeX=SCR.safeX
|
||||
gc_replaceTransform(SCR.origin)
|
||||
gc_setColor(1,1,1)
|
||||
BG.draw()
|
||||
gc_replaceTransform(SCR.xOy)
|
||||
if SCN.draw then SCN.draw()end
|
||||
WIDGET.draw()
|
||||
SYSFX.draw()
|
||||
TEXT.draw()
|
||||
WIDGET_draw()
|
||||
SYSFX_draw()
|
||||
TEXT_draw()
|
||||
|
||||
--Draw cursor
|
||||
if mouseShow then
|
||||
local R=int((time+1)/2)%7+1
|
||||
_=minoColor[SETTING.skin[R]]
|
||||
gc_setColor(_[1],_[2],_[3],min(abs(1-time%2),.3))
|
||||
_=SCS[R][0]
|
||||
_=DSCP[R][0]
|
||||
gc_draw(TEXTURE.miniBlock[R],mx,my,time%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(ms.isDown(1)and cursor_holdImg or cursorImg,mx,my,nil,nil,nil,8,8)
|
||||
end
|
||||
gc_replaceTransform(SCR.xOy_ul)
|
||||
MES.draw()
|
||||
MES_draw()
|
||||
gc_replaceTransform(SCR.origin)
|
||||
--Draw power info.
|
||||
if SETTING.powerInfo then
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(infoCanvas,SCR.safeX,0,0,SCR.k)
|
||||
gc_draw(infoCanvas,safeX,0,0,SCR.k)
|
||||
end
|
||||
|
||||
--Draw scene swapping animation
|
||||
@@ -624,17 +631,16 @@ function love.run()
|
||||
--Draw FPS
|
||||
setFont(15)
|
||||
gc_setColor(1,1,1)
|
||||
gc_print(FPS(),SCR.safeX+5,-20)
|
||||
gc_print(FPS(),safeX+5,-20)
|
||||
|
||||
--Debug info.
|
||||
if devMode then
|
||||
--Left-down infos
|
||||
gc_setColor(devColor[devMode])
|
||||
gc_print("MEM "..gcinfo(),SCR.safeX+5,-40)
|
||||
gc_print("Lines "..FREEROW.getCount(),SCR.safeX+5,-60)
|
||||
gc_print("Cursor "..int(mx+.5).." "..int(my+.5),SCR.safeX+5,-80)
|
||||
gc_print("Voices "..VOC.getQueueCount(),SCR.safeX+5,-100)
|
||||
gc_print("Tasks "..TASK.getCount(),SCR.safeX+5,-120)
|
||||
gc_print("MEM "..gcinfo(),safeX+5,-40)
|
||||
gc_print("Lines "..FREEROW.getCount(),safeX+5,-60)
|
||||
gc_print("Tasks "..TASK.getCount(),safeX+5,-80)
|
||||
gc_print("Voices "..VOC.getQueueCount(),safeX+5,-100)
|
||||
|
||||
--Update & draw frame time
|
||||
ins(frameTimeList,1,dt)rem(frameTimeList,126)
|
||||
@@ -643,30 +649,44 @@ function love.run()
|
||||
gc.rectangle('fill',150+2*i,-20,2,-frameTimeList[i]*4000)
|
||||
end
|
||||
|
||||
--Cursor pos disp
|
||||
gc_replaceTransform(SCR.origin)
|
||||
local x,y=SCR.xOy:transformPoint(mx,my)
|
||||
gc_setLineWidth(1)
|
||||
gc_line(x,0,x,SCR.h)
|
||||
gc_line(0,y,SCR.w,y)
|
||||
local t=int(mx+.5)..","..int(my+.5)
|
||||
gc.setColor(COLOR.D)
|
||||
gc_print(t,x+1,y)
|
||||
gc_print(t,x+1,y-1)
|
||||
gc_print(t,x+2,y-1)
|
||||
gc_setColor(COLOR.Z)
|
||||
gc_print(t,x+2,y)
|
||||
|
||||
gc_replaceTransform(SCR.xOy_dr)
|
||||
--Websocket status
|
||||
for i=1,6 do
|
||||
local status=WS.status(WSnames[i])
|
||||
gc_setColor(1,1,1)
|
||||
gc.draw(wsBottomImage,-79,20*i-139)
|
||||
if status=='dead'then
|
||||
gc_draw(ws_deadImg,-20,20*i-140)
|
||||
elseif status=='connecting'then
|
||||
gc_setColor(1,1,1,.5+.3*sin(time*6.26))
|
||||
gc_draw(ws_connectingImg,-20,20*i-140)
|
||||
elseif status=='running'then
|
||||
gc_draw(ws_runningImg,-20,20*i-140)
|
||||
--Websocket status
|
||||
for i=1,6 do
|
||||
local status=WS.status(WSnames[i])
|
||||
gc_setColor(1,1,1)
|
||||
gc.draw(wsBottomImage,-79,20*i-139)
|
||||
if status=='dead'then
|
||||
gc_draw(ws_deadImg,-20,20*i-140)
|
||||
elseif status=='connecting'then
|
||||
gc_setColor(1,1,1,.5+.3*sin(time*6.26))
|
||||
gc_draw(ws_connectingImg,-20,20*i-140)
|
||||
elseif status=='running'then
|
||||
gc_draw(ws_runningImg,-20,20*i-140)
|
||||
end
|
||||
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(.3,1,.3,t2)gc.rectangle('fill',-42,20*i-122,-16,-16)
|
||||
gc_setColor(1,.2,.2,t3)gc.rectangle('fill',-24,20*i-122,-16,-16)
|
||||
end
|
||||
local t1,t2,t3=WS.getTimers(WSnames[i])
|
||||
gc_setColor(1,1,1,t1)gc.rectangle('fill',-60,20*i-120,-20,-20)
|
||||
gc_setColor(0,1,0,t2)gc.rectangle('fill',-40,20*i-120,-20,-20)
|
||||
gc_setColor(1,0,0,t3)gc.rectangle('fill',-20,20*i-120,-20,-20)
|
||||
end
|
||||
end
|
||||
gc_present()
|
||||
|
||||
--SPEED UPUPUP!
|
||||
if SETTING.cleanCanvas then gc.discard()end
|
||||
if SETTING.cleanCanvas then gc_discard()end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -676,14 +696,18 @@ function love.run()
|
||||
updatePowerInfo()
|
||||
lastFreshPow=time
|
||||
end
|
||||
if gc.getWidth()~=SCR.w then
|
||||
if gc.getWidth()~=SCR.w or gc.getHeight()~=SCR.h then
|
||||
love.resize(gc.getWidth(),gc.getHeight())
|
||||
end
|
||||
end
|
||||
|
||||
--Slow devmode
|
||||
if devMode==3 then WAIT(.1)
|
||||
elseif devMode==4 then WAIT(.5)
|
||||
if devMode then
|
||||
if devMode==3 then
|
||||
WAIT(.1)
|
||||
elseif devMode==4 then
|
||||
WAIT(.5)
|
||||
end
|
||||
end
|
||||
|
||||
--Keep 60fps
|
||||
|
||||
@@ -34,6 +34,15 @@ return function(name,libName)
|
||||
return
|
||||
end
|
||||
return libFunc()
|
||||
elseif SYSTEM=="OS X" then
|
||||
local rtn = package.loadlib(libName["OS X"], libName.libFunc)
|
||||
if rtn then
|
||||
local a = rtn()
|
||||
MES.new('check',name.." lib loaded")
|
||||
return a
|
||||
else
|
||||
MES.new('error',"Cannot load "..name)
|
||||
end
|
||||
else
|
||||
MES.new('error',"No "..name.." for "..SYSTEM)
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@ local ins,rem=table.insert,table.remove
|
||||
|
||||
local mesList={}
|
||||
local mesIcon={
|
||||
check=DOGC{40,40,
|
||||
check=GC.DO{40,40,
|
||||
{'setLW',10},
|
||||
{'setCL',0,0,0},
|
||||
{'line',4,19,15,30,36,9},
|
||||
@@ -14,7 +14,7 @@ local mesIcon={
|
||||
{'setCL',.7,1,.6},
|
||||
{'line',5,20,15,30,35,10},
|
||||
},
|
||||
info=DOGC{40,40,
|
||||
info=GC.DO{40,40,
|
||||
{'setCL',.2,.25,.85},
|
||||
{'fCirc',20,20,15},
|
||||
{'setCL',1,1,1},
|
||||
@@ -23,7 +23,7 @@ local mesIcon={
|
||||
{'fRect',18,11,4,4},
|
||||
{'fRect',18,17,4,12},
|
||||
},
|
||||
broadcast=DOGC{40,40,
|
||||
broadcast=GC.DO{40,40,
|
||||
{'setCL',1,1,1},
|
||||
{'fRect',2,4,36,26,3},
|
||||
{'fPoly',2,27,2,37,14,25},
|
||||
@@ -31,7 +31,7 @@ local mesIcon={
|
||||
{'fRect',6,11,4,4},{'fRect',14,11,19,4},
|
||||
{'fRect',6,19,4,4},{'fRect',14,19,19,4},
|
||||
},
|
||||
warn=DOGC{40,40,
|
||||
warn=GC.DO{40,40,
|
||||
{'setCL',.95,.83,.4},
|
||||
{'fPoly',20.5,1,0,38,40,38},
|
||||
{'setCL',0,0,0},
|
||||
@@ -42,7 +42,7 @@ local mesIcon={
|
||||
{'fRect',18,11,5,16},
|
||||
{'fRect',18,30,5,5},
|
||||
},
|
||||
error=DOGC{40,40,
|
||||
error=GC.DO{40,40,
|
||||
{'setCL',.95,.3,.3},
|
||||
{'fCirc',20,20,19},
|
||||
{'setCL',0,0,0},
|
||||
@@ -92,7 +92,7 @@ function MES.new(icon,str,time)
|
||||
startTime=.5,
|
||||
endTime=.5,
|
||||
time=time or 3,
|
||||
canvas=DOGC(L),
|
||||
canvas=GC.DO(L),
|
||||
width=w,height=h,
|
||||
scale=h>400 and 1/math.min(h/400,2.6)or 1
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ local SCN={
|
||||
stat={
|
||||
tar=false, --Swapping target
|
||||
style=false,--Swapping style
|
||||
mid=false, --Loading point
|
||||
changeTime=false, --Loading point
|
||||
time=false, --Full swap time
|
||||
draw=false, --Swap draw func
|
||||
},
|
||||
@@ -50,7 +50,7 @@ end
|
||||
function SCN.swapUpdate()
|
||||
local S=SCN.stat
|
||||
S.time=S.time-1
|
||||
if S.time==S.mid then
|
||||
if S.time==S.changeTime then
|
||||
SCN.init(S.tar,SCN.cur)
|
||||
collectgarbage()
|
||||
--Scene swapped this moment
|
||||
@@ -103,36 +103,36 @@ function SCN.pop()
|
||||
end
|
||||
|
||||
local swap={
|
||||
none={1,0,function()end},--swapTime, changeTime, drawFunction
|
||||
flash={8,1,function()gc.clear(1,1,1)end},
|
||||
fade={30,15,function(t)
|
||||
none={duration=1,changeTime=0,draw=function()end},--swapTime, changeTime, drawFunction
|
||||
flash={duration=8,changeTime=1,draw=function()gc.clear(1,1,1)end},
|
||||
fade={duration=30,changeTime=15,draw=function(t)
|
||||
t=t>15 and 2-t/15 or t/15
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
fade_togame={120,20,function(t)
|
||||
fade_togame={duration=120,changeTime=20,draw=function(t)
|
||||
t=t>20 and(120-t)/100 or t/20
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
slowFade={180,90,function(t)
|
||||
slowFade={duration=180,changeTime=90,draw=function(t)
|
||||
t=t>90 and 2-t/90 or t/90
|
||||
gc.setColor(0,0,0,t)
|
||||
gc.rectangle('fill',0,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeL={30,15,function(t)
|
||||
swipeL={duration=30,changeTime=15,draw=function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(3-2*t)*2-1
|
||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeR={30,15,function(t)
|
||||
swipeR={duration=30,changeTime=15,draw=function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
|
||||
end},
|
||||
swipeD={30,15,function(t)
|
||||
swipeD={duration=30,changeTime=15,draw=function(t)
|
||||
t=t/30
|
||||
gc.setColor(.1,.1,.1,1-abs(t-.5))
|
||||
t=t*t*(2*t-3)*2+1
|
||||
@@ -146,8 +146,9 @@ function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
|
||||
SCN.swapping=true
|
||||
local S=SCN.stat
|
||||
S.tar,S.style=tar,style
|
||||
local s=swap[style]
|
||||
S.time,S.mid,S.draw=s[1],s[2],s[3]
|
||||
S.time=swap[style].duration
|
||||
S.changeTime=swap[style].changeTime
|
||||
S.draw=swap[style].draw
|
||||
end
|
||||
else
|
||||
MES.new('warn',"No Scene: "..tar)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
local SFX={
|
||||
getCount=function()return 0 end,
|
||||
loadAll=function()error("Cannot load before init!")end,
|
||||
fieldPlay=NULL,
|
||||
play=NULL,
|
||||
fplay=NULL,
|
||||
@@ -11,7 +12,7 @@ function SFX.init(list)
|
||||
local Sources={}
|
||||
|
||||
local count=#list function SFX.getCount()return count end
|
||||
local function load(skip)
|
||||
function SFX.loadAll()
|
||||
for i=1,count do
|
||||
local N='media/SFX/'..list[i]..'.ogg'
|
||||
if love.filesystem.getInfo(N)then
|
||||
@@ -19,11 +20,7 @@ function SFX.init(list)
|
||||
else
|
||||
MES.new('warn',"No SFX file: "..N,.1)
|
||||
end
|
||||
if not skip and i~=count then
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
SFX.loadOne=nil
|
||||
|
||||
function SFX.play(s,vol,pos)
|
||||
if SETTING.sfx==0 or vol==0 then return end
|
||||
@@ -86,8 +83,5 @@ function SFX.init(list)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SFX.loadOne=coroutine.wrap(load)
|
||||
function SFX.loadAll()load(true)end
|
||||
end
|
||||
return SFX
|
||||
@@ -2,6 +2,7 @@ local data=love.data
|
||||
local STRING={}
|
||||
local int,format=math.floor,string.format
|
||||
local find,sub,upper=string.find,string.sub,string.upper
|
||||
local char,byte=string.char,string.byte
|
||||
|
||||
do--function STRING.shiftChar(c)
|
||||
local shiftMap={
|
||||
@@ -81,9 +82,40 @@ do--function STRING.urlEncode(s)
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.vcsEncrypt(text,key)
|
||||
local keyLen=#key
|
||||
local result=""
|
||||
local buffer=""
|
||||
for i=0,#text-1 do
|
||||
buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32)
|
||||
if #buffer==26 then
|
||||
result=result..buffer
|
||||
buffer=""
|
||||
end
|
||||
end
|
||||
return result..buffer
|
||||
end
|
||||
function STRING.vcsDecrypt(text,key)
|
||||
local keyLen=#key
|
||||
local result=""
|
||||
local buffer=""
|
||||
for i=0,#text-1 do
|
||||
buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32)
|
||||
if #buffer==26 then
|
||||
result=result..buffer
|
||||
buffer=""
|
||||
end
|
||||
end
|
||||
return result..buffer
|
||||
end
|
||||
|
||||
function STRING.readLine(str)
|
||||
local p=str:find("\n")
|
||||
return str:sub(1,p-1),str:sub(p+1)
|
||||
if p then
|
||||
return str:sub(1,p-1),str:sub(p+1)
|
||||
else
|
||||
return str,""
|
||||
end
|
||||
end
|
||||
|
||||
function STRING.packBin(s)
|
||||
|
||||
@@ -3,7 +3,6 @@ local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
|
||||
local gc_draw,gc_line=gc.draw,gc.line
|
||||
local gc_rectangle,gc_circle=gc.rectangle,gc.circle
|
||||
|
||||
local sin,cos=math.sin,math.cos
|
||||
local max,min=math.max,math.min
|
||||
local rnd=math.random
|
||||
local ins,rem=table.insert,table.remove
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local find=string.find
|
||||
local next,type=next,type
|
||||
local TABLE={}
|
||||
|
||||
@@ -11,32 +12,41 @@ function TABLE.new(val,count)
|
||||
end
|
||||
|
||||
--Get a copy of [1~#] elements
|
||||
function TABLE.shift(org)
|
||||
function TABLE.shift(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for i=1,#org do
|
||||
if type(org[i])~='table'then
|
||||
if type(org[i])~='table'or depth==0 then
|
||||
L[i]=org[i]
|
||||
else
|
||||
L[i]=TABLE.shift(org[i])
|
||||
L[i]=TABLE.shift(org[i],depth-1)
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
--Get a full copy of a table
|
||||
function TABLE.copy(org)
|
||||
--Get a full copy of a table, depth = how many layers will be recreate, default to inf
|
||||
function TABLE.copy(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for k,v in next,org do
|
||||
if type(v)~='table'then
|
||||
if type(v)~='table'or depth==0 then
|
||||
L[k]=v
|
||||
else
|
||||
L[k]=TABLE.copy(v)
|
||||
L[k]=TABLE.copy(v,depth-1)
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
--For all things in new if same type in base, push to old
|
||||
--For all things in new, push to old
|
||||
function TABLE.cover(new,old)
|
||||
for k,v in next,new do
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
|
||||
--For all things in new if same type in old, push to old
|
||||
function TABLE.update(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)==type(old[k])then
|
||||
@@ -49,7 +59,7 @@ function TABLE.update(new,old)
|
||||
end
|
||||
end
|
||||
|
||||
--For all things in new if no val in base, push to old
|
||||
--For all things in new if no val in old, push to old
|
||||
function TABLE.complete(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)=='table'then
|
||||
@@ -96,7 +106,6 @@ end
|
||||
|
||||
--Dump a simple lua table
|
||||
do--function TABLE.dump(L,t)
|
||||
local find=string.find
|
||||
local tabs={
|
||||
[0]="",
|
||||
"\t",
|
||||
@@ -151,7 +160,6 @@ end
|
||||
|
||||
--Dump a simple lua table (no whitespaces)
|
||||
do--function TABLE.dumpDeflate(L,t)
|
||||
local find=string.find
|
||||
local function dump(L)
|
||||
local s="return{"
|
||||
if type(L)~='table'then return end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local VOC={
|
||||
getCount=function()return 0 end,
|
||||
getQueueCount=function()return 0 end,
|
||||
loadAll=function()error("Cannot load before init!")end,
|
||||
getFreeChannel=NULL,
|
||||
play=NULL,
|
||||
update=NULL,
|
||||
@@ -17,7 +18,7 @@ function VOC.init(list)
|
||||
local function loadVoiceFile(N,vocName)
|
||||
local fileName='media/VOICE/'..SETTING.cv..'/'..vocName..'.ogg'
|
||||
if love.filesystem.getInfo(fileName)then
|
||||
bank[vocName]={love.audio.newSource(fileName,'static')}
|
||||
bank[vocName]={love.audio.newSource(fileName,'stream')}
|
||||
table.insert(Source[N],vocName)
|
||||
return true
|
||||
end
|
||||
@@ -36,7 +37,7 @@ function VOC.init(list)
|
||||
return L[n]
|
||||
--Load voice with string
|
||||
end
|
||||
local function load(skip)
|
||||
function VOC.loadAll()
|
||||
for i=1,count do
|
||||
Source[list[i]]={}
|
||||
|
||||
@@ -49,11 +50,7 @@ function VOC.init(list)
|
||||
end
|
||||
end
|
||||
if not Source[list[i]][1]then Source[list[i]]=nil end
|
||||
if not skip and i~=count then
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
VOC.loadOne=nil
|
||||
|
||||
function VOC.getQueueCount()
|
||||
return #voiceQueue
|
||||
@@ -117,8 +114,5 @@ function VOC.init(list)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
VOC.loadOne=coroutine.wrap(load)
|
||||
function VOC.loadAll()load(true)end
|
||||
end
|
||||
return VOC
|
||||
@@ -6,228 +6,16 @@ local host=
|
||||
local port='10026'
|
||||
local path='/tech/socket/v1'
|
||||
|
||||
local debugMode=''--S:send, R:receive, M=mark
|
||||
|
||||
local wsThread=[[
|
||||
-- lua + LÖVE threading websocket client
|
||||
-- Original pure lua ver. by flaribbit and Particle_G
|
||||
-- Threading version by MrZ
|
||||
|
||||
local triggerCHN,sendCHN,readCHN,threadName=...
|
||||
|
||||
local CHN_demand,CHN_getCount=triggerCHN.demand,triggerCHN.getCount
|
||||
local CHN_push,CHN_pop=triggerCHN.push,triggerCHN.pop
|
||||
|
||||
local SOCK=require'socket'.tcp()
|
||||
local JSON=require'Zframework.json'
|
||||
|
||||
do--Connect
|
||||
local host=CHN_demand(sendCHN)
|
||||
local port=CHN_demand(sendCHN)
|
||||
local path=CHN_demand(sendCHN)
|
||||
local body=CHN_demand(sendCHN)
|
||||
local timeout=CHN_demand(sendCHN)
|
||||
|
||||
SOCK:settimeout(timeout)
|
||||
local res,err=SOCK:connect(host,port)
|
||||
if err then CHN_push(readCHN,err)return end
|
||||
|
||||
--WebSocket handshake
|
||||
if not body then body=''end
|
||||
SOCK:send(
|
||||
'GET '..path..' HTTP/1.1\r\n'..
|
||||
'Host: '..host..':'..port..'\r\n'..
|
||||
'Connection: Upgrade\r\n'..
|
||||
'Upgrade: websocket\r\n'..
|
||||
'Content-Type: application/json\r\n'..
|
||||
'Content-Length: '..#body..'\r\n'..
|
||||
'Sec-WebSocket-Version: 13\r\n'..
|
||||
'Sec-WebSocket-Key: osT3F7mvlojIvf3/8uIsJQ==\r\n\r\n'..--secKey
|
||||
body
|
||||
)
|
||||
|
||||
--First line of HTTP
|
||||
res,err=SOCK:receive('*l')
|
||||
if not res then CHN_push(readCHN,err)return end
|
||||
local code,ctLen
|
||||
code=res:find(' ')
|
||||
code=res:sub(code+1,code+3)
|
||||
|
||||
--Get body length from headers and remove headers
|
||||
repeat
|
||||
res,err=SOCK:receive('*l')
|
||||
if not res then CHN_push(readCHN,err)return end
|
||||
if not ctLen and res:find('length')then
|
||||
ctLen=tonumber(res:match('%d+'))
|
||||
end
|
||||
until res==''
|
||||
|
||||
--Result
|
||||
if ctLen then
|
||||
if code=='101'then
|
||||
CHN_push(readCHN,'success')
|
||||
else
|
||||
res,err=SOCK:receive(ctLen)
|
||||
if not res then
|
||||
CHN_push(readCHN,err)
|
||||
else
|
||||
res=JSON.decode(res)
|
||||
CHN_push(readCHN,(code or"XXX")..":"..(res and res.reason or"Server Error"))
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
SOCK:settimeout(0)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local byte=string.byte
|
||||
local band,shl=bit.band,bit.lshift
|
||||
|
||||
local _send do
|
||||
local char=string.char
|
||||
local bor,bxor=bit.bor,bit.bxor
|
||||
local shr=bit.rshift
|
||||
|
||||
local mask_key={1,14,5,14}
|
||||
local mask_str=char(unpack(mask_key))
|
||||
|
||||
function _send(op,message)
|
||||
]]..(debugMode:find'S'and''or'--')..[[print((">> %s[%d]:%s"):format(threadName,#message,message))
|
||||
--Message type
|
||||
SOCK:send(char(bor(0x80,op)))
|
||||
|
||||
if message then
|
||||
--Length
|
||||
local length=#message
|
||||
if length>65535 then
|
||||
SOCK:send(char(bor(127,0x80),0,0,0,0,band(shr(length,24),0xff),band(shr(length,16),0xff),band(shr(length,8),0xff),band(length,0xff)))
|
||||
elseif length>125 then
|
||||
SOCK:send(char(bor(126,0x80),band(shr(length,8),0xff),band(length,0xff)))
|
||||
else
|
||||
SOCK:send(char(bor(length,0x80)))
|
||||
end
|
||||
SOCK:send(mask_str)
|
||||
local msgbyte={byte(message,1,length)}
|
||||
for i=1,length do
|
||||
msgbyte[i]=bxor(msgbyte[i],mask_key[(i-1)%4+1])
|
||||
end
|
||||
return SOCK:send(char(unpack(msgbyte)))
|
||||
else
|
||||
SOCK:send('\128'..mask_str)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
local res,err
|
||||
local op,fin
|
||||
local length
|
||||
local lBuffer=""--Long multi-data buffer
|
||||
local UFF--Un-finished-frame mode
|
||||
local sBuffer=""--Short multi-frame buffer
|
||||
while true do--Running
|
||||
CHN_demand(triggerCHN)
|
||||
|
||||
--Send
|
||||
while CHN_getCount(sendCHN)>=2 do
|
||||
local op=CHN_pop(sendCHN)
|
||||
local message=CHN_pop(sendCHN)
|
||||
_send(op,message)
|
||||
end
|
||||
|
||||
--Read
|
||||
while true do
|
||||
if not UFF then--UNF process
|
||||
--Byte 0-1
|
||||
res,err=SOCK:receive(2)
|
||||
if err then break end
|
||||
|
||||
op=band(byte(res,1),0x0f)
|
||||
fin=band(byte(res,1),0x80)==0x80
|
||||
|
||||
--Calculating data length
|
||||
length=band(byte(res,2),0x7f)
|
||||
if length==126 then
|
||||
res=SOCK:receive(2)
|
||||
length=shl(byte(res,1),8)+byte(res,2)
|
||||
elseif length==127 then
|
||||
local b={byte(SOCK:receive(8),1,8)}
|
||||
length=shl(b[5],24)+shl(b[6],16)+shl(b[7],8)+b[8]
|
||||
end
|
||||
|
||||
if length>0 then
|
||||
--Receive data
|
||||
local s,_,p=SOCK:receive(length)
|
||||
if s then
|
||||
res=s
|
||||
elseif p then--UNF head
|
||||
]]..(debugMode:find'R'and''or'--')..[[print(("<< %s[%d/%d]:%s"):format(threadName,#p,length,#p<50 and p or p:sub(1,50)))
|
||||
UFF=true
|
||||
sBuffer=sBuffer..p
|
||||
length=length-#p
|
||||
break
|
||||
end
|
||||
else
|
||||
res=""
|
||||
end
|
||||
else
|
||||
local s,e,p=SOCK:receive(length)
|
||||
if s then
|
||||
]]..(debugMode:find'R'and''or'--')..[[print(("<< %s(%d):%s"):format(threadName,length,#s<50 and s or s:sub(1,50)))
|
||||
sBuffer=sBuffer..s
|
||||
length=length-#s
|
||||
elseif p then
|
||||
]]..(debugMode:find'R'and''or'--')..[[print(("<< %s(%d):%s"):format(threadName,length,#p<50 and p or p:sub(1,50)))
|
||||
sBuffer=sBuffer..p
|
||||
length=length-#p
|
||||
end
|
||||
if length==0 then
|
||||
res,sBuffer=sBuffer,""
|
||||
UFF=false
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
]]..(debugMode:find'R'and''or'--')..[[print(("<< %s[(%d)]:%s"):format(threadName,#res,#res<800 and res or res:sub(1,150).."\n...\n"..res:sub(-150)))
|
||||
|
||||
--React
|
||||
if op==8 then--8=close
|
||||
CHN_push(readCHN,op)
|
||||
SOCK:close()
|
||||
if type(res)=='string'then
|
||||
CHN_push(readCHN,res:sub(3))--Warning: with 2 bytes close code
|
||||
else
|
||||
CHN_push(readCHN,"WS Error")
|
||||
end
|
||||
elseif op==0 then--0=continue
|
||||
lBuffer=lBuffer..res
|
||||
if fin then
|
||||
]]..(debugMode:find'M'and''or'--')..[[print("FIN=1 (c")
|
||||
CHN_push(readCHN,lBuffer)
|
||||
lBuffer=""
|
||||
else
|
||||
]]..(debugMode:find'M'and''or'--')..[[print("FIN=0 (c")
|
||||
end
|
||||
else
|
||||
CHN_push(readCHN,op)
|
||||
if fin then
|
||||
]]..(debugMode:find'M'and''or'--')..[[print("OP: "..op.."\tFIN=1")
|
||||
CHN_push(readCHN,res)
|
||||
else
|
||||
]]..(debugMode:find'M'and''or'--')..[[print("OP: "..op.."\tFIN=0")
|
||||
sBuffer=res
|
||||
]]..(debugMode:find'M'and''or'--')..[[print("START pack: "..res)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
local type=type
|
||||
local timer=love.timer.getTime
|
||||
local CHN=love.thread.newChannel()
|
||||
local CHN_getCount,CHN_push,CHN_pop=CHN.getCount,CHN.push,CHN.pop
|
||||
local TRD=love.thread.newThread("\n")
|
||||
local TRD_isRunning=TRD.isRunning
|
||||
|
||||
local WS={}
|
||||
local wsList=setmetatable({},{
|
||||
@@ -255,22 +43,25 @@ function WS.switchHost(_1,_2,_3)
|
||||
end
|
||||
|
||||
function WS.connect(name,subPath,body,timeout)
|
||||
if wsList[name]and wsList[name].thread then
|
||||
wsList[name].thread:release()
|
||||
end
|
||||
local ws={
|
||||
real=true,
|
||||
thread=love.thread.newThread(wsThread),
|
||||
thread=love.thread.newThread('Zframework/websocket_thread.lua'),
|
||||
triggerCHN=love.thread.newChannel(),
|
||||
sendCHN=love.thread.newChannel(),
|
||||
readCHN=love.thread.newChannel(),
|
||||
lastPingTime=0,
|
||||
lastPongTime=timer(),
|
||||
pingInterval=12,
|
||||
pingInterval=6,
|
||||
status='connecting',--'connecting', 'running', 'dead'
|
||||
sendTimer=0,
|
||||
alertTimer=0,
|
||||
pongTimer=0,
|
||||
}
|
||||
wsList[name]=ws
|
||||
ws.thread:start(ws.triggerCHN,ws.sendCHN,ws.readCHN,name)
|
||||
ws.thread:start(ws.triggerCHN,ws.sendCHN,ws.readCHN)
|
||||
CHN_push(ws.sendCHN,host)
|
||||
CHN_push(ws.sendCHN,port)
|
||||
CHN_push(ws.sendCHN,path..subPath)
|
||||
@@ -295,7 +86,7 @@ end
|
||||
|
||||
function WS.alert(name)
|
||||
local ws=wsList[name]
|
||||
ws.alertTimer=2
|
||||
ws.alertTimer=2.6
|
||||
end
|
||||
|
||||
local OPcode={
|
||||
@@ -333,7 +124,11 @@ function WS.read(name)
|
||||
local ws=wsList[name]
|
||||
if ws.real and ws.status~='connecting'and CHN_getCount(ws.readCHN)>=2 then
|
||||
local op,message=CHN_pop(ws.readCHN),CHN_pop(ws.readCHN)
|
||||
if op==8 then ws.status='dead'end--8=close
|
||||
if op==8 then--8=close
|
||||
ws.status='dead'
|
||||
elseif op==9 then--9=ping
|
||||
WS.send(name,message or"",'pong')
|
||||
end
|
||||
ws.lastPongTime=timer()
|
||||
ws.pongTimer=1
|
||||
return message,OPname[op]or op
|
||||
@@ -352,36 +147,44 @@ end
|
||||
function WS.update(dt)
|
||||
local time=timer()
|
||||
for name,ws in next,wsList do
|
||||
if ws.real then
|
||||
if CHN_getCount(ws.triggerCHN)==0 then
|
||||
CHN_push(ws.triggerCHN,0)
|
||||
end
|
||||
if ws.status=='connecting'then
|
||||
local mes=CHN_pop(ws.readCHN)
|
||||
if mes then
|
||||
if mes=='success'then
|
||||
ws.status='running'
|
||||
ws.lastPingTime=time
|
||||
ws.lastPongTime=time
|
||||
ws.pongTimer=1
|
||||
else
|
||||
ws.status='dead'
|
||||
MES.new('warn',text.wsFailed..": "..(mes=="timeout"and text.netTimeout or mes))
|
||||
if ws.real and ws.status~='dead'then
|
||||
if TRD_isRunning(ws.thread)then
|
||||
if CHN_getCount(ws.triggerCHN)==0 then
|
||||
CHN_push(ws.triggerCHN,0)
|
||||
end
|
||||
if ws.status=='connecting'then
|
||||
local mes=CHN_pop(ws.readCHN)
|
||||
if mes then
|
||||
if mes=='success'then
|
||||
ws.status='running'
|
||||
ws.lastPingTime=time
|
||||
ws.lastPongTime=time
|
||||
ws.pongTimer=1
|
||||
else
|
||||
ws.status='dead'
|
||||
MES.new('warn',text.wsFailed..": "..(mes=="timeout"and text.netTimeout or mes))
|
||||
end
|
||||
end
|
||||
elseif ws.status=='running'then
|
||||
if time-ws.lastPingTime>ws.pingInterval then
|
||||
WS.send(name,"",'pong')
|
||||
end
|
||||
if time-ws.lastPongTime>6+2*ws.pingInterval then
|
||||
WS.close(name)
|
||||
end
|
||||
end
|
||||
elseif ws.status=='running'then
|
||||
if time-ws.lastPingTime>ws.pingInterval then
|
||||
CHN_push(ws.sendCHN,9)
|
||||
CHN_push(ws.sendCHN,"")--ping
|
||||
ws.lastPingTime=time
|
||||
end
|
||||
if time-ws.lastPongTime>6+2*ws.pingInterval then
|
||||
WS.close(name)
|
||||
if ws.sendTimer>0 then ws.sendTimer=ws.sendTimer-dt end
|
||||
if ws.pongTimer>0 then ws.pongTimer=ws.pongTimer-dt end
|
||||
if ws.alertTimer>0 then ws.alertTimer=ws.alertTimer-dt end
|
||||
else
|
||||
ws.status='dead'
|
||||
local err=ws.thread:getError()
|
||||
if err then
|
||||
err=err:sub((err:find(":",(err:find(":")or 0)+1)or 0)+1,(err:find("\n")or 0)-1)
|
||||
MES.new('warn',text.wsClose..err)
|
||||
WS.alert(name)
|
||||
end
|
||||
end
|
||||
if ws.sendTimer>0 then ws.sendTimer=ws.sendTimer-dt end
|
||||
if ws.pongTimer>0 then ws.pongTimer=ws.pongTimer-dt end
|
||||
if ws.alertTimer>0 then ws.alertTimer=ws.alertTimer-dt end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
191
Zframework/websocket_thread.lua
Normal file
191
Zframework/websocket_thread.lua
Normal file
@@ -0,0 +1,191 @@
|
||||
local triggerCHN,sendCHN,readCHN=...
|
||||
|
||||
local CHN_demand,CHN_getCount=triggerCHN.demand,triggerCHN.getCount
|
||||
local CHN_push,CHN_pop=triggerCHN.push,triggerCHN.pop
|
||||
|
||||
local SOCK=require'socket'.tcp()
|
||||
local JSON=require'Zframework.json'
|
||||
|
||||
do--Connect
|
||||
local host=CHN_demand(sendCHN)
|
||||
local port=CHN_demand(sendCHN)
|
||||
local path=CHN_demand(sendCHN)
|
||||
local body=CHN_demand(sendCHN)
|
||||
local timeout=CHN_demand(sendCHN)
|
||||
|
||||
SOCK:settimeout(timeout)
|
||||
local res,err=SOCK:connect(host,port)
|
||||
assert(res,err)
|
||||
|
||||
--WebSocket handshake
|
||||
if not body then body=''end
|
||||
SOCK:send(
|
||||
'GET '..path..' HTTP/1.1\r\n'..
|
||||
'Host: '..host..':'..port..'\r\n'..
|
||||
'Connection: Upgrade\r\n'..
|
||||
'Upgrade: websocket\r\n'..
|
||||
'Content-Type: application/json\r\n'..
|
||||
'Content-Length: '..#body..'\r\n'..
|
||||
'Sec-WebSocket-Version: 13\r\n'..
|
||||
'Sec-WebSocket-Key: osT3F7mvlojIvf3/8uIsJQ==\r\n\r\n'..--secKey
|
||||
body
|
||||
)
|
||||
|
||||
--First line of HTTP
|
||||
res,err=SOCK:receive('*l')
|
||||
assert(res,err)
|
||||
local code,ctLen
|
||||
code=res:find(' ')
|
||||
code=res:sub(code+1,code+3)
|
||||
|
||||
--Get body length from headers and remove headers
|
||||
repeat
|
||||
res,err=SOCK:receive('*l')
|
||||
assert(res,err)
|
||||
if not ctLen and res:find('length')then
|
||||
ctLen=tonumber(res:match('%d+'))
|
||||
end
|
||||
until res==''
|
||||
|
||||
--Result
|
||||
if ctLen then
|
||||
if code=='101'then
|
||||
CHN_push(readCHN,'success')
|
||||
else
|
||||
res,err=SOCK:receive(ctLen)
|
||||
res=JSON.decode(assert(res,err))
|
||||
error((code or"XXX")..":"..(res and res.reason or"Server Error"))
|
||||
end
|
||||
end
|
||||
SOCK:settimeout(0)
|
||||
end
|
||||
|
||||
local YIELD=coroutine.yield
|
||||
local byte,char=string.byte,string.char
|
||||
local band,bor,bxor=bit.band,bit.bor,bit.bxor
|
||||
local shl,shr=bit.lshift,bit.rshift
|
||||
|
||||
local mask_key={1,14,5,14}
|
||||
local mask_str=char(unpack(mask_key))
|
||||
local function _send(op,message)
|
||||
--Message type
|
||||
SOCK:send(char(bor(op,0x80)))
|
||||
|
||||
if message then
|
||||
--Length
|
||||
local length=#message
|
||||
if length>65535 then
|
||||
SOCK:send(char(bor(127,0x80),0,0,0,0,band(shr(length,24),0xff),band(shr(length,16),0xff),band(shr(length,8),0xff),band(length,0xff)))
|
||||
elseif length>125 then
|
||||
SOCK:send(char(bor(126,0x80),band(shr(length,8),0xff),band(length,0xff)))
|
||||
else
|
||||
SOCK:send(char(bor(length,0x80)))
|
||||
end
|
||||
local msgbyte={byte(message,1,length)}
|
||||
for i=1,length do
|
||||
msgbyte[i]=bxor(msgbyte[i],mask_key[(i-1)%4+1])
|
||||
end
|
||||
return SOCK:send(mask_str..char(unpack(msgbyte)))
|
||||
else
|
||||
SOCK:send('\128'..mask_str)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
local sendThread=coroutine.wrap(function()
|
||||
while true do
|
||||
while CHN_getCount(sendCHN)>=2 do
|
||||
_send(CHN_pop(sendCHN),CHN_pop(sendCHN))
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end)
|
||||
|
||||
local function _receive(sock,len)
|
||||
local buffer=""
|
||||
while true do
|
||||
local r,e,p=sock:receive(len)
|
||||
if r then
|
||||
buffer=buffer..r
|
||||
len=len-#r
|
||||
elseif p then
|
||||
buffer=buffer..p
|
||||
len=len-#p
|
||||
elseif e then
|
||||
return nil,e
|
||||
end
|
||||
if len==0 then
|
||||
return buffer
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end
|
||||
local readThread=coroutine.wrap(function()
|
||||
local res,err
|
||||
local op,fin
|
||||
local lBuffer=""--Long multi-pack buffer
|
||||
while true do
|
||||
--Byte 0-1
|
||||
res,err=_receive(SOCK,2)
|
||||
assert(res,err)
|
||||
|
||||
op=band(byte(res,1),0x0f)
|
||||
fin=band(byte(res,1),0x80)==0x80
|
||||
|
||||
--Calculating data length
|
||||
local length=band(byte(res,2),0x7f)
|
||||
if length==126 then
|
||||
res,err=_receive(SOCK,2)
|
||||
assert(res,err)
|
||||
length=shl(byte(res,1),8)+byte(res,2)
|
||||
elseif length==127 then
|
||||
local lenData
|
||||
lenData,err=_receive(SOCK,8)
|
||||
assert(res,err)
|
||||
local _,_,_,_,_5,_6,_7,_8=byte(lenData,1,8)
|
||||
length=shl(_5,24)+shl(_6,16)+shl(_7,8)+_8
|
||||
end
|
||||
res,err=_receive(SOCK,length)
|
||||
assert(res,err)
|
||||
|
||||
--React
|
||||
if op==8 then--8=close
|
||||
CHN_push(readCHN,8)--close
|
||||
if type(res)=='string'then
|
||||
CHN_push(readCHN,res:sub(3))--Warning: 2 bytes close code at start so :sub(3)
|
||||
else
|
||||
CHN_push(readCHN,"WS closed")
|
||||
end
|
||||
return
|
||||
elseif op==0 then--0=continue
|
||||
lBuffer=lBuffer..res
|
||||
if fin then
|
||||
CHN_push(readCHN,lBuffer)
|
||||
lBuffer=""
|
||||
end
|
||||
else
|
||||
CHN_push(readCHN,op)
|
||||
if fin then
|
||||
CHN_push(readCHN,res)
|
||||
lBuffer=""
|
||||
else
|
||||
lBuffer=res
|
||||
end
|
||||
end
|
||||
YIELD()
|
||||
end
|
||||
end)
|
||||
|
||||
local success,err
|
||||
|
||||
while true do--Running
|
||||
CHN_demand(triggerCHN)
|
||||
success,err=pcall(sendThread)
|
||||
if not success or err then break end
|
||||
success,err=pcall(readThread)
|
||||
if not success or err then break end
|
||||
end
|
||||
|
||||
SOCK:close()
|
||||
CHN_push(readCHN,8)--close
|
||||
CHN_push(readCHN,err or"Disconnected")
|
||||
error()
|
||||
@@ -1,18 +1,19 @@
|
||||
local floatWheel=0
|
||||
local love=love
|
||||
local max,min=math.max,math.min
|
||||
local float=0
|
||||
return function(y,key1,key2)
|
||||
if y>0 then
|
||||
if floatWheel<0 then floatWheel=0 end
|
||||
floatWheel=floatWheel+y^1.2
|
||||
float=max(float,0)+y^1.2
|
||||
elseif y<0 then
|
||||
if floatWheel>0 then floatWheel=0 end
|
||||
floatWheel=floatWheel-(-y)^1.2
|
||||
if float>0 then float=0 end
|
||||
float=min(float,0)-(-y)^1.2
|
||||
end
|
||||
while floatWheel>=1 do
|
||||
while float>=1 do
|
||||
love.keypressed(key1 or"up")
|
||||
floatWheel=floatWheel-1
|
||||
float=float-1
|
||||
end
|
||||
while floatWheel<=-1 do
|
||||
while float<=-1 do
|
||||
love.keypressed(key2 or"down")
|
||||
floatWheel=floatWheel+1
|
||||
float=float+1
|
||||
end
|
||||
end
|
||||
@@ -16,25 +16,25 @@ local int,ceil,abs=math.floor,math.ceil,math.abs
|
||||
local max,min=math.max,math.min
|
||||
local sub,ins,rem=string.sub,table.insert,table.remove
|
||||
local getFont,setFont,mStr=getFont,setFont,mStr
|
||||
local mDraw,mDraw_X,mDraw_Y=ADRAW.draw,ADRAW.simpX,ADRAW.simpY
|
||||
local mDraw,mDraw_X,mDraw_Y=GC.draw,GC.simpX,GC.simpY
|
||||
local xOy=SCR.xOy
|
||||
|
||||
local downArrowIcon=DOGC{40,25,{'fPoly',0,0,20,25,40,0}}
|
||||
local upArrowIcon=DOGC{40,25,{'fPoly',0,25,20,0,40,25}}
|
||||
local clearIcon=DOGC{40,40,
|
||||
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 clearIcon=GC.DO{40,40,
|
||||
{'fRect',16,5,8,3},
|
||||
{'fRect',8,8,24,3},
|
||||
{'fRect',11,14,18,21},
|
||||
}
|
||||
local sureIcon=DOGC{40,40,
|
||||
local sureIcon=GC.DO{40,40,
|
||||
{'setFT',35},
|
||||
{'mText',"?",20,-6},
|
||||
}
|
||||
local smallerThen=DOGC{20,20,
|
||||
local smallerThen=GC.DO{20,20,
|
||||
{'setLW',5},
|
||||
{'line',18,2,1,10,18,18},
|
||||
}
|
||||
local largerThen=DOGC{20,20,
|
||||
local largerThen=GC.DO{20,20,
|
||||
{'setLW',5},
|
||||
{'line',2,2,19,10,2,18},
|
||||
}
|
||||
@@ -166,39 +166,43 @@ function button:draw()
|
||||
local ATV=self.ATV
|
||||
local c=self.color
|
||||
local r,g,b=c[1],c[2],c[3]
|
||||
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
|
||||
gc_rectangle('fill',x-ATV,y-ATV,w+2*ATV,h+2*ATV)
|
||||
|
||||
--Button
|
||||
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)
|
||||
if ATV>0 then
|
||||
gc_setLineWidth(4)
|
||||
gc_setColor(1,1,1,ATV*.125)
|
||||
gc_rectangle('line',x-ATV+2,y-ATV+2,w+2*ATV-4,h+2*ATV-4)
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(.97,.97,.975,ATV*.125)
|
||||
gc_rectangle('line',x-ATV+2,y-ATV+2,w+2*ATV-4,h+2*ATV-4,3)
|
||||
end
|
||||
|
||||
--Object
|
||||
local obj=self.obj
|
||||
local y0=y+h*.5-ATV*.5
|
||||
gc_setColor(1,1,1,.2+ATV*.05)
|
||||
if self.align=='M'then
|
||||
local x0=x+w*.5
|
||||
mDraw(obj,x0-1.5,y0-1.5)
|
||||
mDraw(obj,x0-1.5,y0+1.5)
|
||||
mDraw(obj,x0+1.5,y0-1.5)
|
||||
mDraw(obj,x0+1.5,y0+1.5)
|
||||
gc_setColor(r*.5,g*.5,b*.5)
|
||||
mDraw(obj,x0-1,y0-1)
|
||||
mDraw(obj,x0-1,y0+1)
|
||||
mDraw(obj,x0+1,y0-1)
|
||||
mDraw(obj,x0+1,y0+1)
|
||||
gc_setColor(r*.55,g*.55,b*.55)
|
||||
mDraw(obj,x0,y0)
|
||||
elseif self.align=='L'then
|
||||
local edge=self.edge
|
||||
mDraw_Y(obj,x+edge-1.5,y0-1.5)
|
||||
mDraw_Y(obj,x+edge-1.5,y0+1.5)
|
||||
mDraw_Y(obj,x+edge+1.5,y0-1.5)
|
||||
mDraw_Y(obj,x+edge+1.5,y0+1.5)
|
||||
gc_setColor(r*.5,g*.5,b*.5)
|
||||
mDraw_Y(obj,x+edge-1,y0-1)
|
||||
mDraw_Y(obj,x+edge-1,y0+1)
|
||||
mDraw_Y(obj,x+edge+1,y0-1)
|
||||
mDraw_Y(obj,x+edge+1,y0+1)
|
||||
gc_setColor(r*.55,g*.55,b*.55)
|
||||
mDraw_Y(obj,x+edge,y0)
|
||||
elseif self.align=='R'then
|
||||
local x0=x+w-self.edge-obj:getWidth()
|
||||
mDraw_Y(obj,x0-1.5,y0-1.5)
|
||||
mDraw_Y(obj,x0-1.5,y0+1.5)
|
||||
mDraw_Y(obj,x0+1.5,y0-1.5)
|
||||
mDraw_Y(obj,x0+1.5,y0+1.5)
|
||||
gc_setColor(r*.5,g*.5,b*.5)
|
||||
mDraw_Y(obj,x0-1,y0-1)
|
||||
mDraw_Y(obj,x0-1,y0+1)
|
||||
mDraw_Y(obj,x0+1,y0-1)
|
||||
mDraw_Y(obj,x0+1,y0+1)
|
||||
gc_setColor(r*.55,g*.55,b*.55)
|
||||
mDraw_Y(obj,x0,y0)
|
||||
end
|
||||
end
|
||||
@@ -287,21 +291,38 @@ function key:draw()
|
||||
local x,y,w,h=self.x,self.y,self.w,self.h
|
||||
local ATV=self.ATV
|
||||
local c=self.color
|
||||
local align=self.align
|
||||
local r,g,b=c[1],c[2],c[3]
|
||||
|
||||
gc_setColor(1,1,1,ATV*.1)
|
||||
gc_rectangle('fill',x,y,w,h)
|
||||
--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
|
||||
|
||||
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
|
||||
gc_setLineWidth(4)
|
||||
gc_rectangle('line',x,y,w,h)
|
||||
--Fill
|
||||
if self.fShade then
|
||||
gc_setColor(r,g,b,ATV*.25)
|
||||
if align=='M'then
|
||||
mDraw(self.fShade,x+w*.5,y+h*.5)
|
||||
elseif align=='L'then
|
||||
mDraw_Y(self.fShade,x+self.edge,y+h*.5)
|
||||
elseif align=='R'then
|
||||
mDraw_Y(self.fShade,x+w-self.edge-self.fShade:getWidth(),y+h*.5)
|
||||
end
|
||||
else
|
||||
gc_setColor(1,1,1,ATV*.05)
|
||||
gc_rectangle('fill',x,y,w,h,3)
|
||||
end
|
||||
|
||||
gc_setColor(r,g,b,1.2)
|
||||
if self.align=='M'then
|
||||
--Object
|
||||
gc_setColor(r,g,b)
|
||||
if align=='M'then
|
||||
mDraw(self.obj,x+w*.5,y+h*.5)
|
||||
elseif self.align=='L'then
|
||||
elseif align=='L'then
|
||||
mDraw_Y(self.obj,x+self.edge,y+h*.5)
|
||||
elseif self.align=='R'then
|
||||
elseif align=='R'then
|
||||
mDraw_Y(self.obj,x+w-self.edge-self.obj:getWidth(),y+h*.5)
|
||||
end
|
||||
end
|
||||
@@ -312,7 +333,7 @@ function key:press(_,_,k)
|
||||
self.code(k)
|
||||
if self.sound then SFX.play('key')end
|
||||
end
|
||||
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
|
||||
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
|
||||
if not D.h then D.h=D.w end
|
||||
local _={
|
||||
name= D.name or"_",
|
||||
@@ -331,6 +352,8 @@ function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=true]
|
||||
},
|
||||
|
||||
fText= D.fText,
|
||||
fShade= D.fShade,
|
||||
noFrame=D.noFrame,
|
||||
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
|
||||
font= D.font or 30,
|
||||
sound= D.sound~=false,
|
||||
@@ -375,22 +398,22 @@ function switch:draw()
|
||||
local x,y=self.x,self.y-25
|
||||
local ATV=self.ATV
|
||||
|
||||
--Frame
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(1,1,1,.6+ATV*.1)
|
||||
gc_rectangle('line',x,y,50,50,3)
|
||||
|
||||
--Checked
|
||||
if ATV>0 then
|
||||
gc_setColor(1,1,1,ATV*.08)
|
||||
gc_rectangle('fill',x,y,50,50)
|
||||
gc_setColor(1,1,1,ATV*.06)
|
||||
gc_rectangle('fill',x,y,50,50,3)
|
||||
end
|
||||
if self.CHK>0 then
|
||||
gc_setColor(.9,1,.9,self.CHK/6)
|
||||
gc_setLineWidth(6)
|
||||
gc_setLineWidth(5)
|
||||
gc_line(x+5,y+25,x+18,y+38,x+45,y+11)
|
||||
end
|
||||
|
||||
--Frame
|
||||
gc_setLineWidth(4)
|
||||
gc_setColor(1,1,1,.6+ATV*.05)
|
||||
gc_rectangle('line',x,y,50,50)
|
||||
|
||||
--Drawable
|
||||
gc_setColor(self.color)
|
||||
mDraw_Y(self.obj,x-12-ATV-self.obj:getWidth(),y+25)
|
||||
@@ -501,16 +524,19 @@ function slider:draw()
|
||||
local cx=x+(x2-x)*self.pos/self.unit
|
||||
local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV
|
||||
gc_setColor(.8,.8,.8)
|
||||
gc_rectangle('fill',bx,by,bw,bh)
|
||||
gc_rectangle('fill',bx,by,bw,bh,3)
|
||||
|
||||
--Glow
|
||||
if ATV>0 then
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(1,1,1,ATV*.16)
|
||||
gc_rectangle('line',bx+1,by+1,bw-2,bh-2)
|
||||
gc_setColor(.97,.97,.975,ATV*.16)
|
||||
gc_rectangle('line',bx+1,by+1,bw-2,bh-2,3)
|
||||
end
|
||||
|
||||
--Float text
|
||||
if self.TAT>0 and self.show then
|
||||
setFont(25)
|
||||
gc_setColor(1,1,1,self.TAT/180)
|
||||
gc_setColor(.97,.97,.975,self.TAT/180)
|
||||
mStr(self:show(),cx,by-30)
|
||||
end
|
||||
|
||||
@@ -537,7 +563,7 @@ function slider:drag(x)
|
||||
if p~=P then
|
||||
self.code(P)
|
||||
end
|
||||
if self.change and TIME()-self.lastTime>.26 then
|
||||
if self.change and TIME()-self.lastTime>.5 then
|
||||
self.lastTime=TIME()
|
||||
self.change()
|
||||
end
|
||||
@@ -657,10 +683,12 @@ function selector:draw()
|
||||
local w=self.w
|
||||
local ATV=self.ATV
|
||||
|
||||
--Frame
|
||||
gc_setColor(1,1,1,.6+ATV*.1)
|
||||
gc_setLineWidth(3)
|
||||
gc_rectangle('line',x,y,w,60)
|
||||
gc_setLineWidth(2)
|
||||
gc_rectangle('line',x,y,w,60,3)
|
||||
|
||||
--Arrow
|
||||
gc_setColor(1,1,1,.2+ATV*.1)
|
||||
local t=(TIME()%.5)^.5
|
||||
if self.select>1 then
|
||||
@@ -681,7 +709,7 @@ function selector:draw()
|
||||
|
||||
--Drawable
|
||||
gc_setColor(self.color)
|
||||
ADRAW.simpX(self.obj,x+w*.5,y+17-21)
|
||||
GC.simpX(self.obj,x+w*.5,y+17-21)
|
||||
gc_setColor(1,1,1)
|
||||
setFont(30)
|
||||
mStr(self.selText,x+w*.5,y+43-21)
|
||||
@@ -815,11 +843,11 @@ function inputBox:draw()
|
||||
local ATV=self.ATV
|
||||
|
||||
gc_setColor(1,1,1,ATV*.08)
|
||||
gc_rectangle('fill',x,y,w,h)
|
||||
gc_rectangle('fill',x,y,w,h,3)
|
||||
|
||||
gc_setColor(1,1,1)
|
||||
gc_setLineWidth(3)
|
||||
gc_rectangle('line',x,y,w,h)
|
||||
gc_rectangle('line',x,y,w,h,3)
|
||||
|
||||
--Drawable
|
||||
setFont(self.font)
|
||||
@@ -971,12 +999,12 @@ function textBox:draw()
|
||||
|
||||
--Background
|
||||
gc_setColor(0,0,0,.4)
|
||||
gc_rectangle('fill',x,y,w,h)
|
||||
gc_rectangle('fill',x,y,w,h,3)
|
||||
|
||||
--Frame
|
||||
gc_setLineWidth(3)
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
|
||||
gc_rectangle('line',x,y,w,h)
|
||||
gc_rectangle('line',x,y,w,h,3)
|
||||
|
||||
--Texts
|
||||
setFont(self.font)
|
||||
@@ -987,12 +1015,12 @@ function textBox:draw()
|
||||
gc_setColor(1,1,1)
|
||||
if #texts>cap then
|
||||
local len=h*h/(#texts*lineH)
|
||||
gc_rectangle('fill',-15,(h-len)*scrollPos/((#texts-cap)*lineH),12,len)
|
||||
gc_rectangle('fill',-15,(h-len)*scrollPos/((#texts-cap)*lineH),12,len,3)
|
||||
end
|
||||
|
||||
--Clear button
|
||||
if not self.fix then
|
||||
gc_rectangle('line',w-40,0,40,40)
|
||||
gc_rectangle('line',w-40,0,40,40,3)
|
||||
gc_draw(self.sure==0 and clearIcon or sureIcon,w-40,0)
|
||||
end
|
||||
|
||||
@@ -1144,14 +1172,14 @@ function listBox:draw()
|
||||
|
||||
--Frame
|
||||
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
|
||||
gc_setLineWidth(3)
|
||||
gc_rectangle('line',0,0,w,h)
|
||||
gc_setLineWidth(2)
|
||||
gc_rectangle('line',0,0,w,h,3)
|
||||
|
||||
--Slider
|
||||
if #list>cap then
|
||||
gc_setColor(1,1,1)
|
||||
local len=h*h/(#list*lineH)
|
||||
gc_rectangle('fill',-15,(h-len)*scrollPos/((#list-cap)*lineH),12,len)
|
||||
gc_rectangle('fill',-15,(h-len)*scrollPos/((#list-cap)*lineH),12,len,3)
|
||||
end
|
||||
|
||||
--List
|
||||
@@ -1315,7 +1343,7 @@ function WIDGET.drag(x,y,dx,dy)
|
||||
local W=WIDGET.sel
|
||||
if W.drag then
|
||||
W:drag(x,y+WIDGET.scrollPos,dx,dy)
|
||||
elseif not W:isAbove(x,y)then
|
||||
elseif not W:isAbove(x,y+WIDGET.scrollPos)then
|
||||
WIDGET.unFocus(true)
|
||||
end
|
||||
else
|
||||
@@ -1443,7 +1471,7 @@ local widgetCover do
|
||||
ins(L,{'fRect',0,i,1,2})
|
||||
ins(L,{'fRect',0,360-i,1,2})
|
||||
end
|
||||
widgetCover=DOGC(L)
|
||||
widgetCover=GC.DO(L)
|
||||
end
|
||||
local scr_w,scr_h
|
||||
function WIDGET.resize(w,h)
|
||||
|
||||
13
conf.lua
13
conf.lua
@@ -1,10 +1,9 @@
|
||||
VERSION={
|
||||
build=344,
|
||||
code=1506,
|
||||
short="V0.15.6",
|
||||
string="Alpha V0.15.6",
|
||||
room="V1.0",
|
||||
name="强化装甲 Reinforced Armor",
|
||||
build=358,
|
||||
code=1600,
|
||||
string="V0.16.0@DEV",
|
||||
room="V1.1",
|
||||
name="空间站 Space station",
|
||||
}
|
||||
function love.conf(t)
|
||||
t.identity='Techmino'--Saving folder
|
||||
@@ -26,7 +25,7 @@ function love.conf(t)
|
||||
W.resizable=true
|
||||
W.fullscreen=false
|
||||
W.vsync=0--Unlimited FPS
|
||||
W.msaa=false--Num of samples to use with multi-sampled antialiasing
|
||||
W.msaa=10--Multi-sampled antialiasing
|
||||
W.depth=0--Bits/samp of depth buffer
|
||||
W.stencil=1--Bits/samp of stencil buffer
|
||||
W.display=1--Monitor ID
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
irs true 提前旋转
|
||||
ims true 提前移动
|
||||
|
||||
skin [设置值] 方块颜色,包含25个整数(1~16)的table
|
||||
face [设置值] 方块朝向,包含25个整数(0~3)的table
|
||||
skinSet [设置] 方块贴图,只能填写内置皮肤的名字
|
||||
skin [设置] 方块颜色,包含25个整数(1~16)的table
|
||||
face [设置] 方块朝向,包含25个整数(0~3)的table
|
||||
|
||||
block true 是否显示方块
|
||||
ghost 0.3 影子透明度(0~1)
|
||||
@@ -75,12 +76,13 @@
|
||||
fkey1 false 按下功能键1后执行的函数
|
||||
fkey2 false 按下功能键2后执行的函数
|
||||
keyCancel {} 包含禁止使用的按键的id,例如{1,2}就是禁止左移和右移
|
||||
fine [设置值] 是否开启非极简提示音
|
||||
fine [设置] 是否开启非极简提示音
|
||||
fineKill false 是否开启非极简即死
|
||||
b2bKill false 是否开启断b2b即死
|
||||
missionKill false 是否开启强制任务
|
||||
dropPiece NULL 放一块后要执行的函数,输入玩家对象
|
||||
task NULL 每帧会*继续执行*的函数,输入玩家对象,注意:使用协程技术
|
||||
noInitSZO false 是否禁止SZO块开局,如果禁止,开局序列会自动跳过最多连续五个SZO
|
||||
|
||||
bg 'none' 背景,只能填写内置背景的名字
|
||||
bgm 'race' 背景音乐名(或者列表随机,例如{'race','push'}),只能用内置音乐库的音乐名
|
||||
@@ -129,14 +131,14 @@ return{--返回一个table,你也可以在之前定义一些常量或者函数
|
||||
dropPiece=function(P)if P.stat.row>=40 then P win('finish')end end,
|
||||
bg='bg2',bgm='race',
|
||||
},
|
||||
load=function()--生成玩家
|
||||
load=function()--模式加载函数,这里只生成了一个玩家,常用的单人模式可以不写,默认使用这个函数
|
||||
PLY.newPlayer(1)--1是玩家编号,默认用户控制1号玩家
|
||||
end,
|
||||
mesDisp=function(P)--40行模式需要显示的信息
|
||||
setFont(55)
|
||||
local r=40-P.stat.row
|
||||
if r<0 then r=0 end
|
||||
mStr(r,69,265)--把计算出来的剩余行数r显示出来
|
||||
mStr(r,63,265)--把计算出来的剩余行数r显示出来
|
||||
PLY.draw.drawTargetLine(P,r)--使用自带的境界高度线绘制函数
|
||||
end,
|
||||
score=function(P)return{P.stat.time,P.stat.piece}end,--游戏结束时需要保存的本局关键信息
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小)
|
||||
|
||||
目前游戏内正在使用, 必须录制的音频文件名们:
|
||||
single, double, triple, techrash
|
||||
single, double, triple, techrash (读作\'tekrʌʃ\)
|
||||
以上直接念就可以,用于普通直接消行
|
||||
|
||||
mini, b2b, b2b2b
|
||||
@@ -21,10 +21,11 @@
|
||||
z-spin single
|
||||
z-spin double
|
||||
z-spin triple
|
||||
z-spin techrash
|
||||
(z-spin techrash)
|
||||
(z-spin pentacrash)
|
||||
(z-spin hexacrash)
|
||||
对于 S L J T O I 每一个都是这样, 五种语音, 加括号的是消5和消6, 一般不用所以可以不录
|
||||
对于 S L J T O I 每一个都是这样至少四条语音
|
||||
加括号一般不用所以可以不录(消5和消6),
|
||||
另:对于P, Q, F, E, U, V, W, X, R, Y, N, H
|
||||
这些方块也可以有上面那些语音,但由于仅在五连块使用还会显著增加语音包体积, 所以不录也可以
|
||||
|
||||
@@ -32,7 +33,7 @@
|
||||
这俩可以直接念也可以略做修改
|
||||
|
||||
win, lose, bye
|
||||
这几个可以自由发挥, 能用在三个场合就行
|
||||
这几个可以自由发挥, 能用在三个场合就行,尽量不要太长
|
||||
|
||||
test, happy, doubt, sad, egg
|
||||
这几个是特殊音效,具体使用情况不定
|
||||
|
||||
200
main.lua
200
main.lua
@@ -1,16 +1,16 @@
|
||||
--[[
|
||||
______ __ _
|
||||
/_ __/___ _____ / /_ ____ ___ (_)____ ____
|
||||
/ / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \
|
||||
/ / / __// /__ / / / // / / / / // // / / // /_/ /
|
||||
/_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/
|
||||
# ______ __ _ #
|
||||
# /_ __/___ _____ / /_ ____ ___ (_)____ ____ #
|
||||
# / / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \ #
|
||||
# / / / __// /__ / / / // / / / / // // / / // /_/ / #
|
||||
# /_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/ #
|
||||
Techmino is my first "huge project"
|
||||
optimization is welcomed if you also love tetromino stacking game
|
||||
|
||||
Instructions:
|
||||
1. I made a framework called Zframework, most code in Zframework are not directly relevant to game;
|
||||
2. "xxx" are texts for reading, 'xxx' are string values just in program;
|
||||
3. Some goto statement are used for better performance. All goto-labes have detailed names so don't afraid;
|
||||
1. I made a framework called Zframework, *most* code in Zframework are not directly relevant to game;
|
||||
2. "xxx" are texts for reading by player, 'xxx' are string values just used in program;
|
||||
3. Some goto statement are used for better performance. All goto-labes have detailed names so don't be afraid;
|
||||
4. Except "gcinfo" function of lua itself, other "gc" are short for "graphics";
|
||||
]]--
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
-- setmetatable(_G,{__newindex=function(self,k,v)print('>>'..k)print(debug.traceback():match("\n.-\n\t(.-): "))rawset(self,k,v)end})
|
||||
|
||||
--Declaration
|
||||
goto REM love=require"love"::REM::--Just tell IDE to load love-api, no actual usage
|
||||
local fs=love.filesystem
|
||||
TIME=love.timer.getTime
|
||||
YIELD=coroutine.yield
|
||||
@@ -28,6 +27,7 @@ MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
|
||||
SAVEDIR=fs.getSaveDirectory()
|
||||
|
||||
--Global Vars & Settings
|
||||
FIRSTLAUNCH=false
|
||||
DAILYLAUNCH=false
|
||||
|
||||
--System setting
|
||||
@@ -78,12 +78,37 @@ NET= require'parts.net'
|
||||
VK= require'parts.virtualKey'
|
||||
AIFUNC= require'parts.ai'
|
||||
AIBUILDER= require'parts.AITemplate'
|
||||
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
|
||||
PLY= require'parts.player'
|
||||
netPLY= require'parts.netPlayer'
|
||||
MODES= require'parts.modes'
|
||||
|
||||
--Initialize field[1]
|
||||
FIELD[1]=DATA.newBoard()
|
||||
--Load settings and statistics
|
||||
TABLE.cover(FILE.load('conf/user')or{},USER)
|
||||
TABLE.cover(FILE.load('conf/unlock')or{},RANKS)
|
||||
TABLE.update(FILE.load('conf/settings')or{},SETTING)
|
||||
TABLE.update(FILE.load('conf/data')or{},STAT)
|
||||
TABLE.cover(FILE.load('conf/key')or{},keyMap)
|
||||
TABLE.cover(FILE.load('conf/virtualkey')or{},VK_org)
|
||||
|
||||
--Initialize fields, sequence, missions, gameEnv for cutsom game
|
||||
local fieldData=FILE.load('conf/customBoards')
|
||||
if fieldData then
|
||||
fieldData=STRING.split(fieldData,"!")
|
||||
for i=1,#fieldData do
|
||||
DATA.pasteBoard(fieldData[i],i)
|
||||
end
|
||||
else
|
||||
FIELD[1]=DATA.newBoard()
|
||||
end
|
||||
local sequenceData=FILE.load('conf/customSequence')
|
||||
if sequenceData then DATA.pasteSequence(sequenceData)end
|
||||
local missionData=FILE.load('conf/customMissions')
|
||||
if missionData then DATA.pasteMission(missionData)end
|
||||
local customData=FILE.load('conf/customEnv')
|
||||
if customData and customData.version==VERSION.code then TABLE.complete(customData,CUSTOMENV)end
|
||||
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
||||
|
||||
|
||||
--First start for phones
|
||||
if not fs.getInfo('conf/settings')and MOBILE then
|
||||
@@ -96,62 +121,63 @@ if SETTING.fullscreen then love.window.setFullscreen(true)end
|
||||
|
||||
--Initialize image libs
|
||||
IMG.init{
|
||||
lock='mess/lock.png',
|
||||
dialCircle='mess/dialCircle.png',
|
||||
dialNeedle='mess/dialNeedle.png',
|
||||
lifeIcon='mess/life.png',
|
||||
badgeIcon='mess/badge.png',
|
||||
ctrlSpeedLimit='mess/ctrlSpeedLimit.png',
|
||||
speedLimit='mess/speedLimit.png',--Not used, for future C2-mode
|
||||
pay1='mess/pay1.png',
|
||||
pay2='mess/pay2.png',
|
||||
lock='media/image/mess/lock.png',
|
||||
dialCircle='media/image/mess/dialCircle.png',
|
||||
dialNeedle='media/image/mess/dialNeedle.png',
|
||||
lifeIcon='media/image/mess/life.png',
|
||||
badgeIcon='media/image/mess/badge.png',
|
||||
ctrlSpeedLimit='media/image/mess/ctrlSpeedLimit.png',
|
||||
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
|
||||
pay1='media/image/mess/pay1.png',
|
||||
pay2='media/image/mess/pay2.png',
|
||||
|
||||
nakiCH='characters/nakiharu.png',
|
||||
miyaCH='characters/miya.png',
|
||||
miyaF1='characters/miya_f1.png',
|
||||
miyaF2='characters/miya_f2.png',
|
||||
miyaF3='characters/miya_f3.png',
|
||||
miyaF4='characters/miya_f4.png',
|
||||
electric='characters/electric.png',
|
||||
hbm='characters/hbm.png',
|
||||
miyaCH='media/image/characters/miya.png',
|
||||
miyaF1='media/image/characters/miya_f1.png',
|
||||
miyaF2='media/image/characters/miya_f2.png',
|
||||
miyaF3='media/image/characters/miya_f3.png',
|
||||
miyaF4='media/image/characters/miya_f4.png',
|
||||
nakiCH='media/image/characters/nakiharu.png',
|
||||
xiaoyaCH='media/image/characters/xiaoya.png',
|
||||
electric='media/image/characters/electric.png',
|
||||
hbm='media/image/characters/hbm.png',
|
||||
|
||||
lanterns={
|
||||
'lanterns/1.png',
|
||||
'lanterns/2.png',
|
||||
'lanterns/3.png',
|
||||
'lanterns/4.png',
|
||||
'lanterns/5.png',
|
||||
'lanterns/6.png',
|
||||
'media/image/lanterns/1.png',
|
||||
'media/image/lanterns/2.png',
|
||||
'media/image/lanterns/3.png',
|
||||
'media/image/lanterns/4.png',
|
||||
'media/image/lanterns/5.png',
|
||||
'media/image/lanterns/6.png',
|
||||
},
|
||||
}
|
||||
SKIN.init{
|
||||
'crystal_scf',
|
||||
'matte_mrz',
|
||||
'contrast_mrz',
|
||||
'polkadots_scf',
|
||||
'toy_scf',
|
||||
'smooth_mrz',
|
||||
'simple_scf',
|
||||
'glass_scf',
|
||||
'penta_scf',
|
||||
'bubble_scf',
|
||||
'minoes_scf',
|
||||
'pure_mrz',
|
||||
'bright_scf',
|
||||
'glow_mrz',
|
||||
'plastic_mrz',
|
||||
'paper_mrz',
|
||||
'yinyang_scf',
|
||||
'cartooncup_earety',
|
||||
'jelly_miya',
|
||||
'brick_notypey',
|
||||
'gem_notypey',
|
||||
'classic',
|
||||
'ball_shaw',
|
||||
'retro_notypey',
|
||||
'textbone_mrz',
|
||||
'coloredbone_mrz',
|
||||
'wtf',
|
||||
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
|
||||
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
|
||||
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
|
||||
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
|
||||
{name="toy_scf",path='media/image/skin/toy_scf.png'},
|
||||
{name="smooth_mrz",path='media/image/skin/smooth_mrz.png'},
|
||||
{name="simple_scf",path='media/image/skin/simple_scf.png'},
|
||||
{name="glass_scf",path='media/image/skin/glass_scf.png'},
|
||||
{name="penta_scf",path='media/image/skin/penta_scf.png'},
|
||||
{name="bubble_scf",path='media/image/skin/bubble_scf.png'},
|
||||
{name="minoes_scf",path='media/image/skin/minoes_scf.png'},
|
||||
{name="pure_mrz",path='media/image/skin/pure_mrz.png'},
|
||||
{name="bright_scf",path='media/image/skin/bright_scf.png'},
|
||||
{name="glow_mrz",path='media/image/skin/glow_mrz.png'},
|
||||
{name="plastic_mrz",path='media/image/skin/plastic_mrz.png'},
|
||||
{name="paper_mrz",path='media/image/skin/paper_mrz.png'},
|
||||
{name="yinyang_scf",path='media/image/skin/yinyang_scf.png'},
|
||||
{name="cartooncup_earety",path='media/image/skin/cartooncup_earety.png'},
|
||||
{name="jelly_miya",path='media/image/skin/jelly_miya.png'},
|
||||
{name="brick_notypey",path='media/image/skin/brick_notypey.png'},
|
||||
{name="gem_notypey",path='media/image/skin/gem_notypey.png'},
|
||||
{name="classic",path='media/image/skin/classic.png'},
|
||||
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
|
||||
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
|
||||
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
|
||||
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
|
||||
{name="wtf",path='media/image/skin/wtf.png'},
|
||||
}
|
||||
|
||||
--Initialize sound libs
|
||||
@@ -170,7 +196,7 @@ BGM.init((function()
|
||||
local L={}
|
||||
for _,v in next,fs.getDirectoryItems('media/BGM')do
|
||||
if fs.getRealDirectory('media/BGM/'..v)~=SAVEDIR then
|
||||
table.insert(L,v:sub(1,-5))
|
||||
table.insert(L,{name=v:sub(1,-5),path='media/BGM/'..v})
|
||||
else
|
||||
MES.new('warn',"Dangerous file : %SAVE%/media/BGM/"..v)
|
||||
end
|
||||
@@ -241,39 +267,54 @@ end
|
||||
do
|
||||
local needSave
|
||||
|
||||
if not fs.getInfo('conf/data')then
|
||||
FIRSTLAUNCH=true
|
||||
needSave=true
|
||||
end
|
||||
if type(STAT.version)~='number'then
|
||||
STAT.version=0
|
||||
needSave=true
|
||||
end
|
||||
if STAT.version<1302 then
|
||||
if STAT.version<1500 then
|
||||
FILE.clear_s('')
|
||||
end
|
||||
if STAT.version<1405 then
|
||||
fs.remove('conf/user')
|
||||
fs.remove('conf/key')
|
||||
end
|
||||
if STAT.version<1505 then
|
||||
fs.remove('record/bigbang.rec')
|
||||
fs.remove('conf/replay')
|
||||
end
|
||||
if STAT.version==1506 then
|
||||
local temp1,temp2
|
||||
if fs.getInfo('record/master_l.rec')then temp1=fs.read('record/master_l.rec')end
|
||||
if fs.getInfo('record/master_u.rec')then temp2=fs.read('record/master_u.rec')end
|
||||
if temp1 then fs.write('record/master_u.rec',temp1)end
|
||||
if temp2 then fs.write('record/master_l.rec',temp2)end
|
||||
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
|
||||
if RANKS.tsd_u then RANKS.tsd_u=0 end
|
||||
needSave=true
|
||||
end
|
||||
if STAT.version~=VERSION.code then
|
||||
STAT.version=VERSION.code
|
||||
needSave=true
|
||||
love.event.quit('restart')
|
||||
end
|
||||
if SETTING.ghostType=='greyCell'then
|
||||
SETTING.ghostType='grayCell'
|
||||
needSave=true
|
||||
end
|
||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then
|
||||
SETTING.frameMul=100
|
||||
end
|
||||
SETTING.appLock=nil
|
||||
SETTING.dataSaving=nil
|
||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
||||
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
|
||||
if
|
||||
SETTING.RS=='ZRS'or SETTING.RS=='BRS'or
|
||||
SETTING.RS=='ASCplus'or SETTING.RS=='C2sym'
|
||||
then SETTING.RS='TRS'end
|
||||
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
|
||||
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
|
||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
|
||||
|
||||
for _,v in next,VK_org do v.color=nil end
|
||||
if RANKS.infinite then RANKS.infinite=0 end
|
||||
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
|
||||
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
|
||||
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
|
||||
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
|
||||
for k in next,RANKS do
|
||||
if type(k)=='number'then
|
||||
RANKS[k]=nil
|
||||
@@ -295,10 +336,6 @@ do
|
||||
fs.remove(k..'.rec')
|
||||
end
|
||||
end
|
||||
if not RANKS.sprint_10l then
|
||||
RANKS.sprint_10l=0
|
||||
needSave=true
|
||||
end
|
||||
|
||||
if needSave then
|
||||
FILE.save(SETTING,'conf/settings')
|
||||
@@ -308,10 +345,7 @@ do
|
||||
end
|
||||
|
||||
--Apply system setting
|
||||
LANG.set(SETTING.lang)
|
||||
VK.setShape(SETTING.VKSkin)
|
||||
applyBlockSatur(SETTING.blockSatur)
|
||||
applyFieldSatur(SETTING.fieldSatur)
|
||||
applySettings()
|
||||
|
||||
--Load replays
|
||||
for _,fileName in next,fs.getDirectoryItems('replay')do
|
||||
|
||||
BIN
media/BGM/beat5th.ogg
Normal file
BIN
media/BGM/beat5th.ogg
Normal file
Binary file not shown.
BIN
media/BGM/here.ogg
Normal file
BIN
media/BGM/here.ogg
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/BGM/secret8th remix.ogg
Normal file
BIN
media/BGM/secret8th remix.ogg
Normal file
Binary file not shown.
BIN
media/BGM/shift.ogg
Normal file
BIN
media/BGM/shift.ogg
Normal file
Binary file not shown.
BIN
media/BGM/there.ogg
Normal file
BIN
media/BGM/there.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/b2b_1.ogg
Normal file
BIN
media/VOICE/xiaoya/b2b_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/b2b_2.ogg
Normal file
BIN
media/VOICE/xiaoya/b2b_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/b3b_1.ogg
Normal file
BIN
media/VOICE/xiaoya/b3b_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/b3b_2.ogg
Normal file
BIN
media/VOICE/xiaoya/b3b_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/bye_1.ogg
Normal file
BIN
media/VOICE/xiaoya/bye_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/bye_2.ogg
Normal file
BIN
media/VOICE/xiaoya/bye_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/bye_3.ogg
Normal file
BIN
media/VOICE/xiaoya/bye_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/double_1.ogg
Normal file
BIN
media/VOICE/xiaoya/double_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/double_2.ogg
Normal file
BIN
media/VOICE/xiaoya/double_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/double_3.ogg
Normal file
BIN
media/VOICE/xiaoya/double_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/half_clear_1.ogg
Normal file
BIN
media/VOICE/xiaoya/half_clear_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/half_clear_2.ogg
Normal file
BIN
media/VOICE/xiaoya/half_clear_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ispin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/ispin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ispin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/ispin_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ispin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/ispin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ispin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/ispin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/jspin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/jspin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/jspin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/jspin_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/jspin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/jspin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/jspin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/jspin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lose_1.ogg
Normal file
BIN
media/VOICE/xiaoya/lose_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lose_2.ogg
Normal file
BIN
media/VOICE/xiaoya/lose_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lose_3.ogg
Normal file
BIN
media/VOICE/xiaoya/lose_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lspin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/lspin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lspin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/lspin_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lspin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/lspin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/lspin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/lspin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/mini_1.ogg
Normal file
BIN
media/VOICE/xiaoya/mini_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/mini_2.ogg
Normal file
BIN
media/VOICE/xiaoya/mini_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ospin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/ospin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ospin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/ospin_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ospin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/ospin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/ospin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/ospin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/perfect_clear_1.ogg
Normal file
BIN
media/VOICE/xiaoya/perfect_clear_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/perfect_clear_2.ogg
Normal file
BIN
media/VOICE/xiaoya/perfect_clear_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/single_1.ogg
Normal file
BIN
media/VOICE/xiaoya/single_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/single_2.ogg
Normal file
BIN
media/VOICE/xiaoya/single_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/single_3.ogg
Normal file
BIN
media/VOICE/xiaoya/single_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/sspin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/sspin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/sspin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/sspin_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/sspin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/sspin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/sspin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/sspin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/techrash_1.ogg
Normal file
BIN
media/VOICE/xiaoya/techrash_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/techrash_2.ogg
Normal file
BIN
media/VOICE/xiaoya/techrash_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/test_1.ogg
Normal file
BIN
media/VOICE/xiaoya/test_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/triple_1.ogg
Normal file
BIN
media/VOICE/xiaoya/triple_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/triple_2.ogg
Normal file
BIN
media/VOICE/xiaoya/triple_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/triple_3.ogg
Normal file
BIN
media/VOICE/xiaoya/triple_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/tspin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/tspin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/tspin_3.ogg
Normal file
BIN
media/VOICE/xiaoya/tspin_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/tspin_4.ogg
Normal file
BIN
media/VOICE/xiaoya/tspin_4.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/welcome_voc_1.ogg
Normal file
BIN
media/VOICE/xiaoya/welcome_voc_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/welcome_voc_2.ogg
Normal file
BIN
media/VOICE/xiaoya/welcome_voc_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/welcome_voc_3.ogg
Normal file
BIN
media/VOICE/xiaoya/welcome_voc_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/win_1.ogg
Normal file
BIN
media/VOICE/xiaoya/win_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/win_2.ogg
Normal file
BIN
media/VOICE/xiaoya/win_2.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/win_3.ogg
Normal file
BIN
media/VOICE/xiaoya/win_3.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/zspin_1.ogg
Normal file
BIN
media/VOICE/xiaoya/zspin_1.ogg
Normal file
Binary file not shown.
BIN
media/VOICE/xiaoya/zspin_2.ogg
Normal file
BIN
media/VOICE/xiaoya/zspin_2.ogg
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user