Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e540cb454b |
@@ -37,7 +37,4 @@ f8b20774e3f035eeddb9211a28a391b20db74456
|
||||
|
||||
# Revert a revert (scripted cutscene path)
|
||||
d73f86d26ec2dbf031c01f588ba4be11842db09c
|
||||
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
||||
|
||||
# Forgot the # in the commit message
|
||||
484bbcb22aa8f28b62912abb6d8c89fb58e63889
|
||||
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
||||
@@ -5,9 +5,10 @@
|
||||
pages/** linguist-vendored
|
||||
|
||||
# Include HScript files as Haxe
|
||||
*.hxs linguist-language=Haxe
|
||||
*.hsc linguist-language=Haxe
|
||||
*.hscript linguist-language=Haxe
|
||||
*.hsc linguist-language=Haxe
|
||||
*.hxs linguist-language=Haxe
|
||||
*.hxp linguist-language=Haxe
|
||||
|
||||
# Include Shader files as GLSL
|
||||
*.frag linguist-language=GLSL
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
name: Linux Builds
|
||||
|
||||
name: Linux Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Pulling the source
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-linux
|
||||
@@ -25,8 +24,8 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
- name: Installing LibVLC
|
||||
run: |
|
||||
sudo apt-get install libvlc-dev libvlccore-dev
|
||||
@@ -68,7 +67,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-linux
|
||||
@@ -76,72 +75,5 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Linux Debug Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-linux-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/linux/haxe/
|
||||
export/debug/linux/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing LibVLC
|
||||
run: |
|
||||
sudo apt-get install libvlc-dev libvlccore-dev
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build linux -debug
|
||||
# - name: Tar files
|
||||
# run: tar -zcvf CodenameEngine.tar.gz -C export/debug/linux/bin .
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: export/debug/linux/bin/
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-linux-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-linux-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/linux/haxe/
|
||||
export/debug/linux/obj/
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
name: Mac OS Builds
|
||||
|
||||
name: Mac OS Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Mac OS Build
|
||||
permissions: write-all
|
||||
runs-on: macos-14
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-mac
|
||||
@@ -25,14 +24,14 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
arch -x86_64 haxelib run lime build mac
|
||||
haxelib run lime build mac
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
|
||||
- name: Uploading artifact (executable)
|
||||
@@ -65,7 +64,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-mac
|
||||
@@ -73,69 +72,5 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Mac OS Debug Build
|
||||
permissions: write-all
|
||||
runs-on: macos-14
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-mac-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/macos/haxe/
|
||||
export/debug/macos/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
arch -x86_64 haxelib run lime build mac -debug
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/debug/macos/bin .
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: CodenameEngine.tar.gz
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-mac-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-mac-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/macos/haxe/
|
||||
export/debug/macos/obj/
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
|
||||
@@ -184,7 +184,7 @@ jobs:
|
||||
name: Release ${{ github.event.inputs.tag_name }}
|
||||
draft: true
|
||||
prerelease: ${{ github.event.inputs.prerelease }}
|
||||
body: ${{ steps.build_body.outputs.body }}
|
||||
body: ${{ steps.build_body.outputs.body }}
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
renamed/Codename Engine-Windows.zip
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
name: Windows Builds
|
||||
|
||||
name: Windows Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Windows Build
|
||||
@@ -11,13 +10,13 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-windows
|
||||
@@ -25,8 +24,8 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
||||
@@ -63,7 +62,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-windows
|
||||
@@ -71,67 +70,5 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Windows Debug Build
|
||||
permissions: write-all
|
||||
runs-on: windows-latest
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-windows-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/windows/haxe/
|
||||
export/debug/windows/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build windows -debug
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: export/debug/windows/bin
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-windows-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-windows-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/windows/haxe/
|
||||
export/debug/windows/obj/
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
{
|
||||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.tabSize": 4,
|
||||
"files.associations": {
|
||||
"*.hx": "haxe",
|
||||
"*.hscript": "haxe",
|
||||
"*.hsc": "haxe",
|
||||
"*.hxs": "haxe"
|
||||
"*.hxs": "haxe",
|
||||
"*.hxp": "haxe"
|
||||
},
|
||||
"lime.projectFile": "project.hxp",
|
||||
"lime.targetConfigurations": [
|
||||
{
|
||||
"label": "Windows (Test Build)",
|
||||
|
||||
@@ -73,7 +73,7 @@ _**QOL = Quality of Life**_
|
||||
- If you need to rearrange the weeks in-game, you can use the `data/weeks/weeks.txt` file.
|
||||
- Editors for Charts and Characters (Stage coming soon)
|
||||
- Undos/Redos supported
|
||||
- Warning on closing unsaved work.
|
||||
- Warning on closing unsaved work
|
||||
- Clean UI (for ocd freaks)
|
||||
- Mature Chart editor (Character editor rework soon)
|
||||
- Features not found in other editors!
|
||||
|
||||
@@ -68,7 +68,7 @@ The engine uses [HaxeFlixel](https://haxeflixel.com/) and it mainly features:
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>How to setup and build the engine and its documentation</h2></summary>
|
||||
<summary><h2>How to setup and build</h2></summary>
|
||||
|
||||
Check out our guide [HERE](building/README.md)
|
||||
</details>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
## DEV (PRIVATE) REPO INSTRUCTIONS TO SYNC UP WITH IT INSTEAD OF SYNCING WITH THE PUBLIC ONE
|
||||
- Open a Command Prompt window in the public codename repo folder
|
||||
- Type those commands:
|
||||
- `git remote add dev https://www.github.com/YoshiCrafter29/CodenameEngine-Dev`
|
||||
- `git branch --set-upstream-to dev/main`
|
||||
- GitHub desktop should be synchronized with the dev repo now. If you're unsure,
|
||||
- Repo name should still say "CodenameEngine"
|
||||
- Current branch should still say "main"
|
||||
- "Fetch" button should say "Fetch dev"
|
||||
- You shouldn't have any commit to push.
|
||||
@@ -0,0 +1,8 @@
|
||||
@ECHO OFF
|
||||
cd ..
|
||||
echo Building Game...
|
||||
lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
echo art
|
||||
|
||||
echo Generated the api xml file at docs/doc.xml
|
||||
echo Please put this in codename-website/api-generator/api/doc.xml
|
||||
@@ -2,6 +2,13 @@
|
||||
<character x="115" y="325" sprite="gf-christmas" icon="gf" color="#A5004D">
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="GF Down Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="GF left note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="scared" anim="GF FEAR" x="0" y="-9" fps="24" loop="true"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" x="0" y="-9" fps="24" loop="false" indices="0..3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" x="0" y="-9" fps="24" loop="false" indices="0..11"/>
|
||||
<anim name="cheer" anim="GF Cheer" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="sad" anim="gf sad" x="-51" y="306" fps="24" loop="true" indices="0..12"/>
|
||||
</character>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="100" y="275" color="#A5004D">
|
||||
<anim name="cheer" anim="GF Cheer"/>
|
||||
<anim name="singUP" anim="GF Up Note"/>
|
||||
<anim name="singLEFT" anim="GF left note"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note"/>
|
||||
<anim name="singDOWN" anim="GF Down Note"/>
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" indices="15..30"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" loop="true" indices="0..3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" indices="0..11"/>
|
||||
<anim name="scared" anim="GF FEAR " loop="true"/>
|
||||
<anim name="sad" anim="gf sad" x="-51" y="315" loop="true" indices="0..12"/>
|
||||
<character x="100" y="275" sprite="gf" icon="gf" color="#A5004D">
|
||||
<anim name="cheer" anim="GF Cheer" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="GF left note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="GF Down Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" x="0" y="0" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" x="0" y="0" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" x="0" y="0" fps="24" loop="true" indices="0,1,2,3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" x="0" y="0" fps="24" loop="false" indices="0..11"/>
|
||||
<anim name="scared" anim="GF FEAR" x="0" y="0" fps="24" loop="true"/>
|
||||
<anim name="sad" anim="gf sad" x="0" y="0" fps="24" loop="true" indices="0..12"/>
|
||||
</character>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<sprite name="fgSnow" x="-600" y="680" sprite="fgSnow"/>
|
||||
|
||||
|
||||
<girlfriend x="440" y="110"/>
|
||||
<girlfriend x="540" y="110"/>
|
||||
<dad/>
|
||||
<boyfriend x="1030" camyoffset="-150" camxoffset="-150"/>
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":1662,"y":282,"w":194,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1790,"y":417,"w":92,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1193,"y":539,"w":259,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":483,"y":553,"w":125,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":1662,"y":417,"w":110,"h":127,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1886,"y":0,"w":105,"h":149,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":1886,"y":167,"w":97,"h":130,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1398,"y":0,"w":470,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":867,"y":0,"w":513,"h":254,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":0,"y":372,"w":465,"h":270,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":1900,"y":315,"w":101,"h":118,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":867,"y":272,"w":308,"h":367,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":483,"y":371,"w":338,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":0,"y":0,"w":422,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":440,"y":0,"w":409,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":1900,"y":451,"w":92,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":1193,"y":282,"w":218,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1429,"y":282,"w":215,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":2031,"h":662},
|
||||
"resolution":"1"
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":1636,"y":275,"w":183,"h":115,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":215,"y":360,"w":84,"h":140,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":419,"y":358,"w":251,"h":121,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":1636,"y":394,"w":120,"h":65,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":4,"y":360,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":674,"y":358,"w":102,"h":147,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":116,"y":360,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":4,"y":4,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":419,"y":4,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":1303,"y":275,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":303,"y":360,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1823,"y":4,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1823,"y":244,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":821,"y":258,"w":478,"h":262,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":821,"y":4,"w":521,"h":250,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":1346,"y":4,"w":473,"h":267,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "22.0.5.191",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2043,"h":524},
|
||||
"resolution": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 74 KiB |
@@ -1,40 +1,58 @@
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":349,"y":867,"w":254,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1648,"y":328,"w":287,"h":363,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1571,"y":709,"w":185,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":1686,"y":855,"w":86,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":349,"y":1021,"w":122,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1774,"y":709,"w":110,"h":128,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":621,"y":867,"w":105,"h":148,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1571,"y":844,"w":97,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":1363,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1,"y":444,"w":771,"h":404,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":791,"y":700,"w":302,"h":369,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1111,"y":957,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":1790,"y":855,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1790,"y":959,"w":106,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":1249,"y":957,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":0,"y":0,"w":781,"h":425,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":0,"y":867,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":799,"y":328,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":1230,"y":328,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":1387,"y":954,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":1111,"y":700,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":1342,"y":699,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":1965,"h":1089},
|
||||
"resolution":"1"
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":994,"y":1029,"w":187,"h":118,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1953,"y":524,"w":84,"h":140,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":471,"y":430,"w":258,"h":137,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":1300,"y":641,"w":122,"h":66,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":1825,"y":1078,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":360,"y":695,"w":103,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":1945,"y":867,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2034,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":943,"y":650,"w":309,"h":375,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":4,"y":4,"w":778,"h":422,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":786,"y":4,"w":761,"h":393,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":1551,"y":4,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1551,"y":360,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":4,"y":1028,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":1945,"y":1001,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":1300,"y":401,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":782,"y":1029,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":782,"y":910,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":994,"y":1151,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":1937,"y":1108,"w":103,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":1115,"y":1151,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":1654,"y":714,"w":287,"h":360,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":471,"y":571,"w":179,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":654,"y":571,"w":118,"h":75,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":1966,"y":223,"w":55,"h":112,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":1966,"y":4,"w":64,"h":106,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":1185,"y":1029,"w":67,"h":70,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":337,"y":1182,"w":122,"h":62,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":1647,"y":1078,"w":174,"h":97,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":360,"y":870,"w":82,"h":14,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":1647,"y":1179,"w":128,"h":61,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":463,"y":1182,"w":124,"h":58,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":1966,"y":114,"w":59,"h":105,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":1953,"y":360,"w":87,"h":160,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":1945,"y":714,"w":92,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":1426,"y":641,"w":104,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":1953,"y":692,"w":73,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":1426,"y":687,"w":72,"h":19,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":360,"y":848,"w":72,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":1953,"y":668,"w":73,"h":20,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":471,"y":650,"w":468,"h":256,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":786,"y":401,"w":510,"h":245,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":4,"y":430,"w":463,"h":261,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":360,"y":910,"w":418,"h":268,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":1256,"y":1008,"w":387,"h":271,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":1256,"y":714,"w":394,"h":290,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0046","x":4,"y":695,"w":352,"h":329,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "22.0.5.191",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2044,"h":1283},
|
||||
"resolution": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 228 KiB |
@@ -1,55 +1,57 @@
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":1129,"y":977,"w":86,"h":17,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1690,"y":1012,"w":86,"h":17,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1656,"y":852,"w":126,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":1915,"y":841,"w":121,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":1382,"y":980,"w":131,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1132,"y":283,"w":420,"h":270,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":1570,"y":277,"w":389,"h":273,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":0,"y":743,"w":397,"h":292,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":431,"y":267,"w":354,"h":332,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":1592,"y":568,"w":190,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":1444,"y":826,"w":86,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":723,"y":852,"w":260,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":1548,"y":947,"w":124,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":1001,"y":852,"w":110,"h":128,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":1933,"y":0,"w":106,"h":148,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":1129,"y":828,"w":97,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":803,"y":283,"w":311,"h":369,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1592,"y":703,"w":167,"h":101,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":1835,"y":852,"w":57,"h":105,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1977,"y":270,"w":66,"h":104,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":1910,"y":936,"w":70,"h":73,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1244,"y":828,"w":182,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":1690,"y":934,"w":127,"h":60,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":418,"y":617,"w":287,"h":363,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":1244,"y":915,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":1777,"y":748,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":1933,"y":166,"w":106,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":1915,"y":737,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":1800,"y":568,"w":89,"h":162,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":1907,"y":568,"w":95,"h":151,"rotated":false}},
|
||||
{"SPRITE":{"name":"30","x":1977,"y":392,"w":61,"h":107,"rotated":false}},
|
||||
{"SPRITE":{"name":"31","x":415,"y":998,"w":107,"h":45,"rotated":false}},
|
||||
{"SPRITE":{"name":"32","x":727,"y":993,"w":77,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"33","x":634,"y":998,"w":75,"h":23,"rotated":false}},
|
||||
{"SPRITE":{"name":"34","x":822,"y":993,"w":75,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"35","x":540,"y":998,"w":76,"h":24,"rotated":false}},
|
||||
{"SPRITE":{"name":"36","x":1445,"y":0,"w":470,"h":259,"rotated":false}},
|
||||
{"SPRITE":{"name":"37","x":431,"y":0,"w":513,"h":249,"rotated":false}},
|
||||
{"SPRITE":{"name":"38","x":962,"y":0,"w":465,"h":265,"rotated":false}},
|
||||
{"SPRITE":{"name":"39","x":723,"y":670,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"40","x":0,"y":0,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"41","x":0,"y":372,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"42","x":1548,"y":826,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"43","x":1132,"y":571,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"44","x":1363,"y":571,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":2064,"h":1065},
|
||||
"resolution":"1"
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":1623,"y":602,"w":287,"h":360,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1310,"y":269,"w":309,"h":375,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":4,"y":4,"w":420,"h":359,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":428,"y":4,"w":406,"h":358,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":4,"y":639,"w":336,"h":165,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":125,"y":808,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":1819,"y":4,"w":215,"h":242,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":1217,"y":648,"w":213,"h":240,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":606,"y":660,"w":191,"h":120,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":606,"y":784,"w":90,"h":151,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":344,"y":660,"w":258,"h":124,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":448,"y":859,"w":122,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1914,"y":755,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1914,"y":602,"w":103,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":700,"y":784,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":838,"y":253,"w":468,"h":256,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":838,"y":4,"w":510,"h":245,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":1352,"y":4,"w":463,"h":261,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":4,"y":367,"w":418,"h":268,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":826,"y":513,"w":387,"h":271,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":428,"y":366,"w":394,"h":290,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":1623,"y":269,"w":352,"h":329,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":1143,"y":788,"w":67,"h":70,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":1033,"y":875,"w":122,"h":62,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":1217,"y":513,"w":64,"h":106,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":1979,"y":359,"w":55,"h":112,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":799,"y":788,"w":98,"h":118,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":1979,"y":250,"w":59,"h":105,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":1434,"y":749,"w":87,"h":160,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":1525,"y":749,"w":92,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":219,"y":887,"w":104,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":527,"y":811,"w":73,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":527,"y":788,"w":72,"h":19,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":527,"y":833,"w":72,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":1217,"y":623,"w":73,"h":20,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":344,"y":788,"w":179,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":219,"y":808,"w":118,"h":75,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":901,"y":875,"w":128,"h":61,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":1914,"y":885,"w":124,"h":58,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":901,"y":788,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":1022,"y":788,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":341,"y":859,"w":103,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":4,"y":808,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":1434,"y":648,"w":174,"h":97,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":1819,"y":250,"w":82,"h":14,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "21.0.1.37179",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2043,"h":966},
|
||||
"resolution": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 265 KiB After Width: | Height: | Size: 165 KiB |
@@ -1,60 +1,60 @@
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":2834,"y":332,"w":12,"h":15,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1476,"y":532,"w":527,"h":503,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":733,"y":0,"w":725,"h":623,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":0,"y":659,"w":741,"h":304,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":2311,"y":0,"w":349,"h":540,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":759,"y":641,"w":583,"h":373,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":2021,"y":0,"w":272,"h":702,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1476,"y":0,"w":518,"h":514,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":0,"y":0,"w":715,"h":641,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":619,"y":1032,"w":205,"h":122,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":842,"y":1032,"w":205,"h":122,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":2311,"y":558,"w":115,"h":112,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":2801,"y":947,"w":305,"h":172,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":2678,"y":0,"w":375,"h":314,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":2870,"y":332,"w":252,"h":328,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":3071,"y":0,"w":239,"h":290,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":3135,"y":678,"w":220,"h":246,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":3597,"y":248,"w":173,"h":231,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":3769,"y":0,"w":225,"h":190,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1290,"y":1053,"w":131,"h":81,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":3905,"y":814,"w":132,"h":85,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1733,"y":1053,"w":122,"h":80,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":3905,"y":917,"w":129,"h":82,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":1589,"y":1053,"w":126,"h":78,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":1439,"y":1053,"w":132,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":3778,"y":814,"w":109,"h":107,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":3124,"y":1123,"w":3,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":3145,"y":1123,"w":3,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":3673,"y":497,"w":260,"h":141,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":3788,"y":208,"w":237,"h":161,"rotated":false}},
|
||||
{"SPRITE":{"name":"30","x":3542,"y":660,"w":218,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"31","x":3124,"y":947,"w":301,"h":158,"rotated":false}},
|
||||
{"SPRITE":{"name":"32","x":3371,"y":498,"w":284,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"33","x":0,"y":981,"w":295,"h":150,"rotated":false}},
|
||||
{"SPRITE":{"name":"34","x":313,"y":981,"w":288,"h":145,"rotated":false}},
|
||||
{"SPRITE":{"name":"35","x":3443,"y":942,"w":182,"h":212,"rotated":false}},
|
||||
{"SPRITE":{"name":"36","x":3371,"y":255,"w":208,"h":225,"rotated":false}},
|
||||
{"SPRITE":{"name":"37","x":3373,"y":660,"w":151,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"38","x":3778,"y":656,"w":206,"h":140,"rotated":false}},
|
||||
{"SPRITE":{"name":"39","x":3557,"y":0,"w":194,"h":230,"rotated":false}},
|
||||
{"SPRITE":{"name":"40","x":2678,"y":485,"w":47,"h":44,"rotated":false}},
|
||||
{"SPRITE":{"name":"41","x":2870,"y":678,"w":247,"h":251,"rotated":false}},
|
||||
{"SPRITE":{"name":"42","x":2678,"y":332,"w":138,"h":135,"rotated":false}},
|
||||
{"SPRITE":{"name":"43","x":1065,"y":1053,"w":207,"h":101,"rotated":false}},
|
||||
{"SPRITE":{"name":"44","x":2452,"y":947,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"45","x":2021,"y":720,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"46","x":2452,"y":558,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"47","x":3951,"y":387,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"48","x":3140,"y":308,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"49","x":3328,"y":0,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":4061,"h":1154},
|
||||
"resolution":"1"
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":4076,"y":2,"w":9,"h":12,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1957,"y":2,"w":524,"h":501,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":716,"y":2,"w":721,"h":621,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":2331,"y":505,"w":139,"h":109,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":3244,"y":725,"w":303,"h":170,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":1691,"y":516,"w":248,"h":277,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":2495,"y":843,"w":173,"h":229,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2,"y":642,"w":262,"h":221,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":2331,"y":616,"w":118,"h":117,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":3549,"y":865,"w":261,"h":139,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":3209,"y":897,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":580,"y":913,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":2831,"y":304,"w":45,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1957,"y":505,"w":372,"h":311,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":1439,"y":516,"w":250,"h":325,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":716,"y":625,"w":235,"h":286,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":953,"y":625,"w":245,"h":249,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":3644,"y":373,"w":136,"h":133,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":2331,"y":735,"w":150,"h":91,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":3644,"y":508,"w":151,"h":95,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":784,"y":913,"w":140,"h":90,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":3644,"y":605,"w":149,"h":92,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":2670,"y":932,"w":144,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":2670,"y":843,"w":152,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":4087,"y":2,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":2831,"y":373,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":3244,"y":373,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":266,"y":642,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":597,"y":642,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":1200,"y":625,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":2831,"y":727,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":2483,"y":2,"w":738,"h":300,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":2483,"y":304,"w":346,"h":537,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":2,"y":865,"w":235,"h":158,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":3812,"y":865,"w":216,"h":141,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":2000,"y":818,"w":299,"h":155,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":1200,"y":863,"w":179,"h":208,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":1691,"y":818,"w":307,"h":154,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":3644,"y":702,"w":320,"h":161,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":266,"y":806,"w":312,"h":155,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":239,"y":963,"w":224,"h":108,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":3223,"y":2,"w":580,"h":369,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":3805,"y":2,"w":269,"h":698,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":1413,"y":843,"w":205,"h":222,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":3041,"y":727,"w":166,"h":292,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":953,"y":876,"w":203,"h":137,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0046","x":1439,"y":2,"w":516,"h":512,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0047","x":2,"y":2,"w":712,"h":638,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0048","x":2301,"y":843,"w":192,"h":227,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "21.0.1.37179",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":4090,"h":1074},
|
||||
"resolution": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 535 KiB After Width: | Height: | Size: 344 KiB |
@@ -433,8 +433,6 @@
|
||||
<str id="position">Position (X, Y)</str>
|
||||
<str id="fps">FPS</str>
|
||||
<str id="indices">Indices (Frames)</str>
|
||||
<str id="looping">Looping?</str>
|
||||
<str id="label">Label</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterSpriteScreen" prefix="characterSpriteScreen.">
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
<str id="category.engine">Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Switch Mod</str>
|
||||
<str id="fpsCounter">FPS Counter</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
|
||||
@@ -46,9 +46,8 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambiar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Volumen</str>
|
||||
<str id="volume.up">Arriba</str>
|
||||
<str id="volume.down">Abajo</str>
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambia Mod</str>
|
||||
<str id="fpsCounter">Contatore FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="volume.up">Su</str>
|
||||
|
||||
@@ -44,9 +44,8 @@
|
||||
<str id="category.engine">Silnik</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Zmień Moda</str>
|
||||
<str id="fpsCounter">Licznik FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Głośność</str>
|
||||
<str id="volume.up">Głóśniej</str>
|
||||
<str id="volume.down">Ciszej</str>
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
<str id="category.engine">Codename Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Trocar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Compiling Codename Engine
|
||||
Do you want to turn your source code into a playable build to play? Then you want to **compile the source code**, follow this guide.
|
||||
> **Open the instructions for your platform.**
|
||||
Here's the full guide on how to setup and compile Codename Engine!<br>
|
||||
|
||||
> **Open the instructions for your platform**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
@@ -38,22 +38,3 @@ Do you want to turn your source code into a playable build to play? Then you wan
|
||||
> You can also run `./cne-windows.bat -help` or `./cne-unix.sh -help` (depending on your platform) to check out more useful commands!<br>
|
||||
> For example `./cne-windows test` or `./cne-unix.sh test` builds the game and uses the source assets folder instead of the export one for easier development (although you can still use `lime test` normally).
|
||||
> - If you're running the terminal from the project's main folder, use instead `./building/cne-windows.bat -COMMAND HERE` or `./building/cne-unix.sh -COMMAND HERE` depending on your platform.
|
||||
|
||||
# Generating Codename Engine's API documentation
|
||||
**Mainly recommended if you intend to fork the engine and make your own custom version to publish.**<br>Do you want to generate an API documentation so people can understand and mod your playable build? This documentation can be uploaded to your website.<br>If you just want to compile the engine normally for your hardcoded mod or for yourself you can skip this step.
|
||||
> **Select your platform to continue.**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
1. Run `generate-docs-windows.bat` using cmd or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS/Linux</summary>
|
||||
|
||||
1. Run `generate-docs-unix.sh` using the terminal or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
|
||||
2. You can use this `doc.xml` file to generate a full HTML documentation (that you can open in your browser for example) using Haxe's [dox](https://github.com/HaxeFoundation/dox) generator; check [Codename Engine's webiste](https://github.com/CodenameCrew/codename-website/tree/main/api-generator) for example.
|
||||
|
||||
> [!CAUTION]
|
||||
> The doc.xml might contain some sensible paths of your computer: make sure to filter the file before publishing it for everyone if you want to keep those paths private!<br>To filter and delete those paths, you may use Codename Engine's website's [doc filter Python script](https://github.com/CodenameCrew/codename-website/blob/main/api-generator/api/filter.py) by simply running it in the same folder of your `doc.xml` file. This script will also delete everything irrelevant to the engine that was generated in your documentation, such as libraries' (like OpenFL or Flixel) APIs.
|
||||
@@ -1,17 +1,14 @@
|
||||
[General]
|
||||
[general]
|
||||
sample-type=float32
|
||||
stereo-mode=speakers
|
||||
stereo-encoding=panpot
|
||||
hrtf=false
|
||||
cf_level=0
|
||||
resampler=fast_bsinc24
|
||||
front-stablizer=false
|
||||
output-limiter=false
|
||||
front-stabilizer=false
|
||||
volume-adjust=0
|
||||
period_size=441
|
||||
sources=512
|
||||
sends=64
|
||||
dither=false
|
||||
|
||||
[decoder]
|
||||
hq-mode=true
|
||||
distance-comp=true
|
||||
hq-mode=false
|
||||
distance-comp=false
|
||||
nfc=false
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
echo "Generating documentation..."
|
||||
if [ $(uname) == "Darwin" ]; then
|
||||
echo "Platform is macOS"
|
||||
haxelib run lime build mac --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
else
|
||||
echo "Platform is not macOS; assuming platform to be Linux compatible"
|
||||
haxelib run lime build linux --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
fi
|
||||
|
||||
echo "The XML file for the API documentation has been generated at docs/doc.xml."
|
||||
echo "For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above."
|
||||
@@ -1,8 +0,0 @@
|
||||
@ECHO OFF
|
||||
cd /d "%~dp0.."
|
||||
echo Generating documentation...
|
||||
echo Platform is based on Windows
|
||||
haxelib run lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
|
||||
echo The XML file for the API documentation has been generated at docs/doc.xml.
|
||||
echo For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above.
|
||||
@@ -4,8 +4,8 @@
|
||||
<print pretty="true">Preparing installation...</print>
|
||||
|
||||
<!-- OpenFL & Lime (Required for Flixel) -->
|
||||
<git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" ref="old" />
|
||||
<lib name="lime" version="8.1.2" />
|
||||
<git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" />
|
||||
<lib name="lime" version="8.2.0" />
|
||||
<!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed -->
|
||||
|
||||
<!-- Flixel -->
|
||||
@@ -14,8 +14,9 @@
|
||||
|
||||
<!-- Other Libraries -->
|
||||
<git name="hscript-improved" url="https://github.com/CodenameCrew/hscript-improved" ref="codename-dev" />
|
||||
<git name="flxanimate" url="https://github.com/CodenameCrew/cne-flxanimate" />
|
||||
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" skipDeps="true" />
|
||||
<lib name="funkin-modchart" version="1.2.4" skipDeps="true" />
|
||||
<git name="funkin-modchart" url="https://github.com/TheoDevelops/FunkinModchart" ref="f30676579d8de7ccac7d12e13b664e8b2c42c6bf" skipDeps="true" />
|
||||
<lib name="hxvlc" version="1.9.3" skipDeps="true" />
|
||||
|
||||
<!-- Documentation and other features -->
|
||||
@@ -31,8 +32,6 @@
|
||||
<lib global="true" name="format" /> <lib name="format" />
|
||||
|
||||
<git name="hxcpp" url="https://github.com/CodenameCrew/cne-hxcpp" />
|
||||
|
||||
<git name="flixel-animate" url="https://github.com/MaybeMaru/flixel-animate/" skipDeps="true"/>
|
||||
</if>
|
||||
|
||||
<!-- Hxcpp Building -->
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<!--Switch Export with Unique ApplicationID and Icon-->
|
||||
<set name="APP_ID" value="0x0100f6c013bbc000" />
|
||||
|
||||
<!-- DO NOT REMOVE!! -->
|
||||
<!-- DO NOT REMOVE!! ALLOWS ME TO DO REGIONS LIKE IN C# AND KEEP CODE ORGANIZED. REMOVING IT WOULD BREAK THE ENGINE -->
|
||||
<haxedef name="REGION" />
|
||||
|
||||
<!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file
|
||||
@@ -50,7 +50,7 @@
|
||||
<!-- _________________________________ Engine Settings _______________________________ -->
|
||||
|
||||
<!-- Comment this out to disable updates !-->
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko || debug"/>
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko"/>
|
||||
|
||||
<!-- Comment this out to disable Discord RPC !-->
|
||||
<section if="cpp">
|
||||
@@ -72,11 +72,7 @@
|
||||
|
||||
<!-- Comment this out to prevent extending classes in hscript.
|
||||
Reduces compilation time at the cost of limited HScript flexibility. !-->
|
||||
<define name="CUSTOM_CLASSES" unless="STRIPPED_COMPILE"/>
|
||||
|
||||
<!-- Comment this out to disable support for abstracts in hscript.
|
||||
Reduces compilation time at the cost of limited HScript flexibility. !-->
|
||||
<define name="HSCRIPT_ABSTRACT_SUPPORT" unless="STRIPPED_COMPILE"/>
|
||||
<define name="CUSTOM_CLASSES" unless="STRIPPED_COMPILE" />
|
||||
|
||||
<!-- Comment this out to disable multithreading !-->
|
||||
<haxedef name="ALLOW_MULTITHREADING" unless="web || flash" />
|
||||
@@ -119,24 +115,6 @@
|
||||
<!-- Disable a optimization, to allow reflection to use more functions -->
|
||||
<define name="FLX_NO_GENERIC" />
|
||||
|
||||
<!-- _______________________________ Display Server ______________________________ -->
|
||||
|
||||
<haxedef name="LIME_CMD" value="${project.command}"/>
|
||||
<define name="LIME_DISPLAY" if="${project.command == update} || ${project.command == display} || display || display_details" />
|
||||
<haxedef name="LIME_DISPLAY" if="LIME_DISPLAY" />
|
||||
|
||||
<section if="LIME_DISPLAY">
|
||||
<!-- For display server -->
|
||||
<undefine name="COMPILE_ALL_CLASSES" />
|
||||
<unset name="COMPILE_ALL_CLASSES" />
|
||||
|
||||
<undefine name="HSCRIPT_ABSTRACT_SUPPORT" />
|
||||
<unset name="HSCRIPT_ABSTRACT_SUPPORT" />
|
||||
|
||||
<undefine name="CUSTOM_CLASSES" />
|
||||
<unset name="CUSTOM_CLASSES" />
|
||||
</section>
|
||||
|
||||
<!-- _______________________________ Libraries ______________________________ -->
|
||||
|
||||
<!-- KEEP BOTH OF THESE AS THERE ARE SOME PARTICULAR CASES! -->
|
||||
@@ -152,7 +130,7 @@
|
||||
<haxelib name="hxvlc" if="VIDEO_CUTSCENES" />
|
||||
<haxelib name="away3d" if="THREE_D_SUPPORT" />
|
||||
<haxelib name="format" />
|
||||
<haxelib name="flixel-animate" />
|
||||
<haxelib name="flxanimate" />
|
||||
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
|
||||
|
||||
<haxelib name="hscript-improved" />
|
||||
@@ -194,8 +172,6 @@
|
||||
|
||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||
|
||||
<haxeflag name="--macro" value="funkin.backend.system.macros.BuildInfo.printBuildInfo()" unless="display" />
|
||||
|
||||
<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />
|
||||
|
||||
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
||||
@@ -211,9 +187,6 @@
|
||||
<haxedef name="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
|
||||
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
|
||||
|
||||
<!-- Disable it for more concise compilation errors. -->
|
||||
<haxedef name="message.reporting" value="pretty" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
|
||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||
@@ -241,10 +214,8 @@
|
||||
<haxeflag name="--macro" value="modchart.backend.macros.Macro.includeFiles()"/>
|
||||
</section>
|
||||
|
||||
|
||||
<section if="COMPILE_ALL_CLASSES">
|
||||
<haxeflag name="-dce" value="no" />
|
||||
|
||||
<haxeflag name="--macro" value="funkin.backend.system.macros.Macros.addAdditionalClasses()" />
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
// funkin source classes cannot be imported here
|
||||
import haxe.io.Path;
|
||||
import hxp.*;
|
||||
import lime.tools.*;
|
||||
import sys.FileSystem;
|
||||
import sys.io.Process;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class Project extends HXProject
|
||||
{
|
||||
static final TITLE:String = "Friday Night Funkin' - Codename Engine";
|
||||
static final EXECUTABLE:String = "CodenameEngine";
|
||||
static final VERSION:String = "1.0.1";
|
||||
static final COMPANY:String = "Yoshman29";
|
||||
static final PACKAGE:String = "com.codenamecrew.codenameengine";
|
||||
static final MAIN_CLASS:String = "funkin.backend.system.MainApplication";
|
||||
|
||||
static final PRELOADER:String = "flixel.system.FlxPreloader";
|
||||
static final SOURCE_FOLDERS:Array<String> = ["source"];
|
||||
|
||||
// Compile Flags
|
||||
static final EMBED_ASSETS:CompileFlag = CompileFlag.get("EMBED_ASSETS");
|
||||
static final PRELOAD_ALL:CompileFlag = CompileFlag.get("PRELOAD_ALL");
|
||||
static final STRIPPED_COMPILE:CompileFlag = CompileFlag.get("STRIPPED_COMPILE");
|
||||
static final UPDATE_CHECKING:CompileFlag = CompileFlag.get("UPDATE_CHECKING");
|
||||
static final DISCORD_RPC:CompileFlag = CompileFlag.get("DISCORD_RPC");
|
||||
static final MODCHARTING_FEATURES:CompileFlag = CompileFlag.get("MODCHARTING_FEATURES");
|
||||
static final GITHUB_API:CompileFlag = CompileFlag.get("GITHUB_API");
|
||||
static final COMPILE_ALL_CLASSES:CompileFlag = CompileFlag.get("COMPILE_ALL_CLASSES");
|
||||
static final CUSTOM_CLASSES:CompileFlag = CompileFlag.get("CUSTOM_CLASSES");
|
||||
static final ALLOW_MULTITHREADING:CompileFlag = CompileFlag.get("ALLOW_MULTITHREADING");
|
||||
static final MOD_SUPPORT:CompileFlag = CompileFlag.get("MOD_SUPPORT");
|
||||
static final TRANSLATIONS_SUPPORT:CompileFlag = CompileFlag.get("TRANSLATIONS_SUPPORT");
|
||||
static final GLOBAL_SCRIPT:CompileFlag = CompileFlag.get("GLOBAL_SCRIPT");
|
||||
static final SOFTCODED_STATES:CompileFlag = CompileFlag.get("SOFTCODED_STATES");
|
||||
static final NDLLS_SUPPORTED:CompileFlag = CompileFlag.get("NDLLS_SUPPORTED");
|
||||
static final USE_ADAPTED_ASSETS:CompileFlag = CompileFlag.get("USE_ADAPTED_ASSETS");
|
||||
static final THREE_D_SUPPORT:CompileFlag = CompileFlag.get("THREE_D_SUPPORT");
|
||||
static final NAPE_ENABLED:CompileFlag = CompileFlag.get("NAPE_ENABLED");
|
||||
static final VIDEO_CUTSCENES:CompileFlag = CompileFlag.get("VIDEO_CUTSCENES");
|
||||
static final SHOW_BUILD_ON_FPS:CompileFlag = CompileFlag.get("SHOW_BUILD_ON_FPS");
|
||||
static final DARK_MODE_WINDOW:CompileFlag = CompileFlag.get("DARK_MODE_WINDOW");
|
||||
|
||||
public function new():Void
|
||||
{
|
||||
super();
|
||||
|
||||
CompileFlag.project = this;
|
||||
|
||||
haxe.Log.trace = (v:Dynamic, ?info:haxe.PosInfos) ->
|
||||
{
|
||||
if (!isDisplay())
|
||||
Sys.println(v);
|
||||
};
|
||||
|
||||
doWelcomeHeader();
|
||||
trace("Configuring project...");
|
||||
trace("");
|
||||
configureApp();
|
||||
configureCompileFlags();
|
||||
configureAssets();
|
||||
configureLibs();
|
||||
configureIcons();
|
||||
trace("");
|
||||
trace("Configured project");
|
||||
trace("Starting build...");
|
||||
trace("");
|
||||
}
|
||||
|
||||
function getHaxeVersion():String {
|
||||
var process = new Process("haxe", ["-version"]);
|
||||
var version:String = "";
|
||||
|
||||
try {
|
||||
version = process.stdout.readAll().toString().trim();
|
||||
} catch (e) {}
|
||||
|
||||
process.close();
|
||||
return version;
|
||||
}
|
||||
|
||||
function doWelcomeHeader() {
|
||||
var haxeVersion = getHaxeVersion().trim();
|
||||
var sleepChangeVersion = false;
|
||||
|
||||
var width = 60; // total banner width
|
||||
|
||||
inline function centerText(text:String, width:Int):String {
|
||||
var innerWidth = width - 2;
|
||||
var padding = Std.int(Math.max(0, Std.int((innerWidth - text.length) / 2)));
|
||||
var left = StringTools.lpad("", " ", padding);
|
||||
var right = StringTools.lpad("", " ", innerWidth - text.length - padding);
|
||||
return "=" + left + text + right + "=";
|
||||
}
|
||||
|
||||
inline function infoLine(label:String, value:String):String {
|
||||
var innerWidth = width - 2;
|
||||
if (label.length == 0) {
|
||||
// no label: center the value
|
||||
var padding = Std.int(Math.max(0, (innerWidth - value.length) / 2));
|
||||
var left = StringTools.lpad("", " ", padding);
|
||||
var right = StringTools.lpad("", " ", innerWidth - value.length - padding);
|
||||
return "=" + left + value + right + "=";
|
||||
} else {
|
||||
var colonPos = Std.int(innerWidth / 2);
|
||||
var labelPart = StringTools.lpad(label, " ", Std.int(Math.max(0, colonPos - 2)));
|
||||
var valuePart = value;
|
||||
var remainingSpace = Std.int(Math.max(0, innerWidth - (labelPart.length + 3 + valuePart.length)));
|
||||
var rightPad = StringTools.lpad("", " ", remainingSpace);
|
||||
return "=" + labelPart + " : " + valuePart + rightPad + "=";
|
||||
}
|
||||
}
|
||||
|
||||
var unicode = #if (target.unicode) true #else false #end;
|
||||
|
||||
trace('');
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
trace(centerText(TITLE, width));
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
trace(infoLine("Engine Version", 'v${VERSION}'));
|
||||
trace(infoLine("Haxe Version", 'v${haxeVersion}'));
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
|
||||
try {
|
||||
var lastBuiltWith:Null<String> = null;
|
||||
var compiling = isDebug() ? "debug" : "release";
|
||||
var target = isWeb() ? "html5" : (isIOS() ? "ios" : (isAndroid() ? "android" : (isWindows() ? "windows" : (isMac() ? "macos" : (isLinux() ? "linux" : "")))));
|
||||
|
||||
if (target == "") throw "Unknown target";
|
||||
|
||||
var exportPath = Sys.getCwd() + "/export/" + compiling + "/" + target + "/obj/Options.txt";
|
||||
var options = sys.io.File.getContent(exportPath);
|
||||
|
||||
for (option in options.split("\n")) {
|
||||
if (option.startsWith("haxe=")) {
|
||||
lastBuiltWith = option.substr(5).trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBuiltWith != null && lastBuiltWith.length > 0 && lastBuiltWith != haxeVersion) {
|
||||
trace(infoLine("", unicode ? "⚠️ Haxe version mismatch!" : "[WARNING] Haxe version mismatch!"));
|
||||
trace(infoLine("Last Built With", lastBuiltWith));
|
||||
trace(infoLine("Current Version", haxeVersion));
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
trace(infoLine("", "!!! Make sure to DELETE your EXPORT folders !!!"));
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
sleepChangeVersion = true;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
var targetPlatform = isWeb() ? "Web (HTML5)" : (isIOS() ? "iOS" : (isAndroid() ? "Android" : (isWindows() ? "Windows" : (isMac() ? "Mac" : (isLinux() ? "Linux" : "Unknown")))));
|
||||
|
||||
if (isHashLink())
|
||||
targetPlatform = "Hashlink (" + targetPlatform + ")";
|
||||
|
||||
trace(infoLine("Target Platform", targetPlatform));
|
||||
trace(infoLine("Build Type", isDebug() ? "Debug" : "Release"));
|
||||
trace(infoLine("Build Date", Date.now().toString()));
|
||||
trace(StringTools.lpad("", "=", width));
|
||||
trace('');
|
||||
|
||||
if (sleepChangeVersion)
|
||||
Sys.sleep(5);
|
||||
}
|
||||
|
||||
function configureApp():Void
|
||||
{
|
||||
trace("Configuring game...");
|
||||
meta.title = TITLE;
|
||||
meta.version = VERSION;
|
||||
meta.company = COMPANY;
|
||||
meta.packageName = PACKAGE;
|
||||
|
||||
app.main = MAIN_CLASS;
|
||||
app.file = EXECUTABLE;
|
||||
app.preloader = PRELOADER;
|
||||
|
||||
var buildDir = 'export/${isDebug() ? 'debug' : 'release'}/';
|
||||
trace('Output directory: $buildDir');
|
||||
app.path = buildDir;
|
||||
|
||||
sources = SOURCE_FOLDERS;
|
||||
templatePaths.push(Path.combine(Haxelib.getPath(new Haxelib(#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end));
|
||||
|
||||
window.hardware = true;
|
||||
window.vsync = false;
|
||||
window.allowHighDPI = true;
|
||||
|
||||
if (isWeb())
|
||||
window.resizable = true;
|
||||
|
||||
if (isDesktop())
|
||||
{
|
||||
window.orientation = Orientation.LANDSCAPE;
|
||||
window.fullscreen = false;
|
||||
window.resizable = true;
|
||||
window.vsync = false;
|
||||
} else if (isMobile())
|
||||
{
|
||||
window.orientation = Orientation.LANDSCAPE;
|
||||
window.fullscreen = true;
|
||||
window.resizable = false;
|
||||
window.borderless = true;
|
||||
window.width = 0;
|
||||
window.height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function configureCompileFlags()
|
||||
{
|
||||
trace("Configuring compile flags...");
|
||||
|
||||
setDefine("disable-version-check");
|
||||
setHaxedef("disable-version-check");
|
||||
setHaxedef("no-deprecation-warnings");
|
||||
|
||||
// DO NOT REMOVE!! ALLOWS ME TO DO REGIONS LIKE IN C# AND KEEP CODE ORGANIZED. REMOVING IT WOULD BREAK THE ENGINE
|
||||
setHaxedef("REGION");
|
||||
|
||||
setHaxedef("SAVE_PATH", EXECUTABLE);
|
||||
setHaxedef("SAVE_NAME", "save-default");
|
||||
setHaxedef("SAVE_OPTIONS_PATH", EXECUTABLE);
|
||||
setHaxedef("SAVE_OPTIONS_NAME", "options");
|
||||
|
||||
PRELOAD_ALL.integrate(!isWeb());
|
||||
EMBED_ASSETS.integrate(false);
|
||||
|
||||
UPDATE_CHECKING.integrate(!isWeb() && !isHashLink());
|
||||
DISCORD_RPC.integrate(isCPP() && isDesktop());
|
||||
STRIPPED_COMPILE.integrate(false); //should be isRelease() if you want to use it
|
||||
MODCHARTING_FEATURES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||
GITHUB_API.integrate(!isWeb() && !isHashLink());
|
||||
COMPILE_ALL_CLASSES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||
CUSTOM_CLASSES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||
ALLOW_MULTITHREADING.integrate(!isWeb());
|
||||
MOD_SUPPORT.integrate(!isWeb());
|
||||
TRANSLATIONS_SUPPORT.integrate(true);
|
||||
GLOBAL_SCRIPT.integrate(true);
|
||||
SOFTCODED_STATES.integrate(true);
|
||||
NDLLS_SUPPORTED.integrate(!isWeb() && !isHashLink());
|
||||
USE_ADAPTED_ASSETS.integrate(!isWeb());
|
||||
THREE_D_SUPPORT.integrate(STRIPPED_COMPILE.isDisabled());
|
||||
NAPE_ENABLED.integrate(STRIPPED_COMPILE.isDisabled());
|
||||
VIDEO_CUTSCENES.integrate(isCPP() && (isDesktop() || isMobile()));
|
||||
SHOW_BUILD_ON_FPS.integrate(true);
|
||||
DARK_MODE_WINDOW.integrate(true);
|
||||
|
||||
setDefine("FLX_NO_GENERIC"); // Disable a optimization, to allow reflection to use more functions
|
||||
|
||||
if (DISCORD_RPC.isEnabled())
|
||||
setHaxedef("DISCORD_DISABLE_IO_THREAD");
|
||||
|
||||
if (MODCHARTING_FEATURES.isEnabled())
|
||||
{
|
||||
setHaxedef("FM_ENGINE", "CODENAME");
|
||||
setHaxedef("FM_ENGINE_VERSION", "1.0");
|
||||
addMacroFlag("modchart.backend.macros.Macro.includeFiles()");
|
||||
}
|
||||
|
||||
if (COMPILE_ALL_CLASSES.isEnabled())
|
||||
{
|
||||
addHaxeFlag("-dce no");
|
||||
addMacroFlag("funkin.backend.system.macros.Macros.addAdditionalClasses()");
|
||||
}
|
||||
|
||||
addMacroFlag("funkin.backend.system.macros.Macros.initMacros()");
|
||||
|
||||
if (isDebug())
|
||||
setHaxedef("HXCPP_DEBUG_LINK");
|
||||
|
||||
environment.set("HAXEPATH", "./");
|
||||
|
||||
setHaxedef("HXCPP_CHECK_POINTER");
|
||||
setHaxedef("HXCPP_STACK_LINE");
|
||||
setHaxedef("HXCPP_CATCH_SEGV");
|
||||
setHaxedef("hscriptPos");
|
||||
setHaxedef("EXPERIMENTAL_FLXGRAPHIC_DESTROY_FIX");
|
||||
setHaxedef("FLX_NO_FOCUS_LOST_SCREEN");
|
||||
|
||||
if (isRelease())
|
||||
{
|
||||
setHaxedef("FLX_NO_DEBUG");
|
||||
setHaxedef("analyzer-optimize");
|
||||
}
|
||||
setHaxedef("openfl_dpi_aware");
|
||||
}
|
||||
|
||||
function configureAssets()
|
||||
{
|
||||
trace("Configuring assets...");
|
||||
|
||||
var shouldPreload = PRELOAD_ALL.isEnabled();
|
||||
var shouldEmbed = EMBED_ASSETS.isEnabled();
|
||||
|
||||
includeAssetLibrary("default", shouldEmbed, shouldPreload);
|
||||
addAssetPath("assets", shouldEmbed);
|
||||
addAsset("art/readme.txt", "do NOT readme.txt", false);
|
||||
|
||||
if (isDesktop())
|
||||
addAsset("building/alsoft.txt", 'plugins/alsoft.${isWindows() ? "ini" : "conf"}', false);
|
||||
}
|
||||
|
||||
function configureLibs()
|
||||
{
|
||||
trace("Configuring libraries...");
|
||||
|
||||
includeHaxelib("flixel");
|
||||
includeHaxelib("flixel-addons");
|
||||
includeHaxelib("format");
|
||||
includeHaxelib("flxanimate");
|
||||
includeHaxelib("hscript-improved");
|
||||
includeHaxelib("markdown");
|
||||
|
||||
if (VIDEO_CUTSCENES.isEnabled())
|
||||
includeHaxelib("hxvlc");
|
||||
if (THREE_D_SUPPORT.isEnabled())
|
||||
includeHaxelib("away3d");
|
||||
if (NAPE_ENABLED.isEnabled())
|
||||
includeHaxelib("nape-haxe4");
|
||||
if (DISCORD_RPC.isEnabled())
|
||||
includeHaxelib("hxdiscord_rpc");
|
||||
if (MODCHARTING_FEATURES.isEnabled())
|
||||
includeHaxelib("funkin-modchart");
|
||||
if (isDebug())
|
||||
includeHaxelib("hxcpp-debug-server");
|
||||
}
|
||||
|
||||
function configureIcons()
|
||||
{
|
||||
trace("Configuring app icons...");
|
||||
// TODO: ADD MOBILE ICONS
|
||||
for (size in [16, 32, 64])
|
||||
addIcon('art/icon${size}.png', size);
|
||||
addIcon("art/icons/iconOG.png");
|
||||
}
|
||||
|
||||
function includeHaxelib(name:String, version:String = ""):Void
|
||||
{
|
||||
haxelibs.push(new Haxelib(name, version));
|
||||
}
|
||||
|
||||
function addAsset(path:String, ?rename:String, embed:Bool = false):Void
|
||||
{
|
||||
var asset = new Asset(path, rename, null, embed, true);
|
||||
asset.library = "default";
|
||||
assets.push(asset);
|
||||
}
|
||||
|
||||
public function addAssetPath(path:String, ?rename:String, embed:Bool = false):Void
|
||||
{
|
||||
if (path == "") return;
|
||||
|
||||
var targetPath = Path.addTrailingSlash(rename ?? path);
|
||||
|
||||
if (!FileSystem.exists(path))
|
||||
trace('[ERROR] Path "${path}" was not found');
|
||||
else if (!FileSystem.isDirectory(path))
|
||||
trace('[ERROR] Path "${path}" needs to be a directory.');
|
||||
|
||||
for (file in FileSystem.readDirectory(path))
|
||||
{
|
||||
if (FileSystem.isDirectory('${path}/${file}'))
|
||||
addAssetPath('${path}/${file}', '${targetPath}${file}', embed);
|
||||
else
|
||||
addAsset('${path}/${file}', '${targetPath}${file}', embed);
|
||||
}
|
||||
}
|
||||
|
||||
function includeAssetLibrary(name:String, embed:Bool = false, preload:Bool = false):Void
|
||||
{
|
||||
this.libraries.push(new Library('', name, null, embed, preload, false, ""));
|
||||
}
|
||||
|
||||
inline function addIcon(icon:String, ?size:Int):Void
|
||||
icons.push(new Icon(icon, size));
|
||||
|
||||
inline function addHaxeFlag(value:String):Void
|
||||
haxeflags.push(value);
|
||||
|
||||
inline function addMacroFlag(value:String):Void
|
||||
addHaxeFlag('--macro ${value}');
|
||||
|
||||
inline function isDebug():Bool
|
||||
return debug;
|
||||
|
||||
inline function isRelease():Bool
|
||||
return !isDebug();
|
||||
|
||||
inline function isDisplay():Bool
|
||||
return command == "display";
|
||||
|
||||
inline function isWeb():Bool
|
||||
return platformType == PlatformType.WEB;
|
||||
|
||||
inline function isMobile():Bool
|
||||
return platformType == PlatformType.MOBILE;
|
||||
|
||||
inline function isDesktop():Bool
|
||||
return platformType == PlatformType.DESKTOP;
|
||||
|
||||
inline function isWindows():Bool
|
||||
return target == Platform.WINDOWS;
|
||||
|
||||
inline function isMac():Bool
|
||||
return target == Platform.MAC;
|
||||
|
||||
inline function isLinux():Bool
|
||||
return target == Platform.LINUX;
|
||||
|
||||
inline function isAndroid():Bool
|
||||
return target == Platform.ANDROID;
|
||||
|
||||
inline function isIOS():Bool
|
||||
return target == Platform.IOS;
|
||||
|
||||
inline function isHashLink():Bool
|
||||
return targetFlags.exists("hl");
|
||||
|
||||
inline function isCPP():Bool
|
||||
return defines.exists("cpp");
|
||||
|
||||
public inline function getHaxedef(name:String):Null<Dynamic>
|
||||
return haxedefs.get(name);
|
||||
|
||||
public inline function setHaxedef(name:String, ?value:String):Void
|
||||
haxedefs.set(name, value ?? "");
|
||||
|
||||
public inline function unsetHaxedef(name:String):Void
|
||||
haxedefs.remove(name);
|
||||
|
||||
public inline function getDefine(name:String):Null<Dynamic>
|
||||
return defines.get(name);
|
||||
|
||||
public inline function setDefine(name:String, ?value:String):Void
|
||||
defines.set(name, value ?? "");
|
||||
|
||||
public inline function unsetDefine(name:String):Void
|
||||
defines.remove(name);
|
||||
}
|
||||
|
||||
class CompileFlag {
|
||||
public static final INVERSION:String = "NO_";
|
||||
public static var project:Project;
|
||||
|
||||
public static function get(name:String):CompileFlag {
|
||||
return new CompileFlag(name);
|
||||
}
|
||||
|
||||
var name:String;
|
||||
public function new(name:String) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public function enable(stopPropagation:Bool = false):Void
|
||||
{
|
||||
project.setHaxedef(name);
|
||||
project.setDefine(name);
|
||||
if (!stopPropagation)
|
||||
getInverse().disable(true);
|
||||
}
|
||||
|
||||
public function disable(stopPropagation:Bool = false):Void
|
||||
{
|
||||
project.unsetHaxedef(name);
|
||||
project.unsetDefine(name);
|
||||
if (!stopPropagation)
|
||||
getInverse().enable(true);
|
||||
}
|
||||
|
||||
public function integrate(defaultEnabled:Bool = false):Void {
|
||||
var inverse = getInverse();
|
||||
|
||||
if (isEnabled()) inverse.disable(true); // Makes sure the inverse is disabled if it wasn't already
|
||||
else if (inverse.isEnabled()) disable(true); // If the inverse is enabled, disable this
|
||||
else (defaultEnabled ? enable : disable)(true); // Set to the default state otherwise
|
||||
}
|
||||
|
||||
public function isEnabled():Bool {
|
||||
return project.haxedefs.exists(name) || project.defines.exists(name);
|
||||
}
|
||||
|
||||
public function isDisabled():Bool {
|
||||
return getInverse().isEnabled() || !isEnabled();
|
||||
}
|
||||
|
||||
function getInverse():CompileFlag {
|
||||
var inversionName = name;
|
||||
if (!inversionName.startsWith(INVERSION))
|
||||
inversionName = INVERSION + inversionName;
|
||||
return new CompileFlag(inversionName);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import flixel.math.FlxMath;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxSignal;
|
||||
import flixel.util.FlxStringUtil;
|
||||
import flixel.FlxBasic;
|
||||
@@ -137,18 +136,11 @@ class FlxSound extends FlxBasic {
|
||||
public var radius:Float;
|
||||
|
||||
/**
|
||||
* Whether the proximity alters the pan or not.
|
||||
* Whether the proximity alters the pan or not
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var proximityPan:Bool;
|
||||
|
||||
/**
|
||||
* Controls how much this object is affected by camera scrolling. `0` = no movement (e.g. a static sound),
|
||||
* This is only useful if used with proximity (Initialized once proximity is used).
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var scrollFactor(default, null):FlxPoint;
|
||||
|
||||
/**
|
||||
* Stores for how much channels are in the loaded sound.
|
||||
* @since raltyMod
|
||||
@@ -310,8 +302,6 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = null;
|
||||
|
||||
if (destroySound) {
|
||||
scrollFactor = FlxDestroyUtil.put(scrollFactor);
|
||||
|
||||
if (group != null) group.remove(this);
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -358,24 +348,15 @@ class FlxSound extends FlxBasic {
|
||||
|
||||
_amplitudeUpdate = true;
|
||||
|
||||
// Distance-based volume control
|
||||
// Distance-based volume control (TODO for Ralty: REDO THIS)
|
||||
if (target != null) {
|
||||
var targetPosition = target.getPosition(), position = getPosition();
|
||||
var camera = camera;
|
||||
if (camera != null) {
|
||||
targetPosition.subtract(camera.scroll.x * target.scrollFactor.x, camera.scroll.y * target.scrollFactor.y);
|
||||
if (scrollFactor != null) position.subtract(camera.scroll.x * scrollFactor.x, camera.scroll.y * scrollFactor.y);
|
||||
else position.subtract(camera.scroll.x, camera.scroll.y);
|
||||
}
|
||||
|
||||
var radialMultiplier = targetPosition.distanceTo(position) / radius;
|
||||
|
||||
// Make it so it affects the 3d position of the source and not just the panning?
|
||||
_volumeAdjust = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
if (proximityPan) _panAdjust = (position.x - targetPosition.x) / radius;
|
||||
|
||||
var targetPosition = target.getPosition();
|
||||
var radialMultiplier = targetPosition.distanceTo(FlxPoint.weak(x, y)) / radius;
|
||||
targetPosition.put();
|
||||
position.put();
|
||||
radialMultiplier = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
|
||||
_volumeAdjust = radialMultiplier;
|
||||
if (proximityPan) _panAdjust = (x - target.x) / radius;
|
||||
}
|
||||
else
|
||||
_volumeAdjust = 1.0;
|
||||
@@ -555,15 +536,12 @@ class FlxSound extends FlxBasic {
|
||||
* @param Pan Whether panning should be used in addition to the volume changes.
|
||||
* @return This FlxSound instance (nice for chaining stuff together, if you're into that).
|
||||
*/
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true, ?scrollFactor:FlxPoint):FlxSound {
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true):FlxSound {
|
||||
setPosition(x, y);
|
||||
if (targetObject != null) this.target = targetObject;
|
||||
if (radius != null) this.radius = radius;
|
||||
proximityPan = pan;
|
||||
|
||||
if (this.scrollFactor == null) this.scrollFactor = FlxPoint.get(1, 1);
|
||||
if (scrollFactor != null) this.scrollFactor.copyFrom(scrollFactor);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -571,28 +549,14 @@ class FlxSound extends FlxBasic {
|
||||
* Helper function to set the coordinates of this object.
|
||||
* Sound positioning is used in conjunction with proximity/panning.
|
||||
*
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
*/
|
||||
public function setPosition(x = 0.0, y = 0.0):Void {
|
||||
public inline function setPosition(x = 0.0, y = 0.0):Void {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world position of this object.
|
||||
*
|
||||
* @param result Optional arg for the returning point.
|
||||
* @return The world position of this object.
|
||||
* @since raltyMod
|
||||
*/
|
||||
public function getPosition(?result:FlxPoint):FlxPoint {
|
||||
if (result == null)
|
||||
result = FlxPoint.get();
|
||||
|
||||
return result.set(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to play the sound - also works on paused sounds.
|
||||
*
|
||||
@@ -718,7 +682,7 @@ class FlxSound extends FlxBasic {
|
||||
_paused = false;
|
||||
_time = startTime;
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed #end)
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed || _source.__backend.handle == null #end)
|
||||
makeChannel();
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -769,8 +733,7 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
_time = loopTime;
|
||||
}
|
||||
else if (_source != null)
|
||||
_source.loops = 999;
|
||||
else _channel.loops = 999;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -800,7 +763,7 @@ class FlxSound extends FlxBasic {
|
||||
}
|
||||
|
||||
inline function get_playing():Bool @:privateAccess
|
||||
return _source != null && _source.playing;
|
||||
return _channel != null && _channel.__isValid && _source.playing;
|
||||
|
||||
inline function get_volume():Float
|
||||
return _volume;
|
||||
@@ -833,12 +796,12 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_buffer():AudioBuffer
|
||||
@:privateAccess return _sound != null ? _sound.__buffer : null;
|
||||
|
||||
inline function update_amplitude():Void @:privateAccess {
|
||||
if (_channel != null && _channel.__updatePeaks(get_time()) && _amplitudeUpdate) {
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
}
|
||||
function update_amplitude():Void @:privateAccess {
|
||||
if (_channel == null || !_channel.__updatePeaks(get_time()) || !_amplitudeUpdate) return;
|
||||
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
}
|
||||
|
||||
inline function get_amplitudeLeft():Float {
|
||||
@@ -866,27 +829,30 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_pitch():Float
|
||||
return _pitch;
|
||||
|
||||
inline function set_pitch(v:Float):Float {
|
||||
function set_pitch(v:Float):Float {
|
||||
_realPitch = (_pitch = v) * _timeScaleAdjust;
|
||||
if (_source != null) _source.pitch = _realPitch;
|
||||
if (_channel != null) _channel.pitch = _realPitch;
|
||||
return _pitch;
|
||||
}
|
||||
#end
|
||||
|
||||
function set_looped(v:Bool):Bool {
|
||||
if (playing) _source.loops = v ? 999 : 0;
|
||||
if (playing) {
|
||||
if (v) _channel.loops = 999;
|
||||
else _channel.loops = 0;
|
||||
}
|
||||
return looped = v;
|
||||
}
|
||||
|
||||
function set_loopTime(v:Float):Float {
|
||||
if (playing) _source.loopTime = v;
|
||||
if (playing) _channel.loopTime = v;
|
||||
return loopTime = v;
|
||||
}
|
||||
|
||||
function set_endTime(v:Null<Float>):Null<Float> {
|
||||
if (playing) {
|
||||
if (v != null && v > 0 && v < _length) _source.length = v;
|
||||
else _source.length = null;
|
||||
if (v != null && v > 0 && v < _length) _channel.endTime = v;
|
||||
else _channel.endTime = null;
|
||||
}
|
||||
return endTime = v;
|
||||
}
|
||||
@@ -898,7 +864,7 @@ class FlxSound extends FlxBasic {
|
||||
return _time;
|
||||
}
|
||||
function get_time():Float {
|
||||
if (_source == null || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
if (_channel == null || @:privateAccess !_channel.__isValid || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
|
||||
final sourceTime = _source.currentTime - _source.offset - _offset;
|
||||
if (!_source.playing || _realPitch <= 0) {
|
||||
@@ -937,21 +903,24 @@ class FlxSound extends FlxBasic {
|
||||
return _time = time;
|
||||
}
|
||||
|
||||
function get_offset():Float return _offset;
|
||||
function set_offset(offset:Float):Float {
|
||||
inline function get_offset():Float return _offset;
|
||||
inline function set_offset(offset:Float):Float {
|
||||
if (_offset == (_offset = offset)) return offset;
|
||||
//time = time + _offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
function get_length():Float return _length - _offset;
|
||||
inline function get_length():Float return _length - _offset;
|
||||
|
||||
//function get_latency():Float return _source != null ? _source.latency : 0;
|
||||
/*function get_latency():Float {
|
||||
if (_channel != null) return _source.latency;
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
override function toString():String {
|
||||
return FlxStringUtil.getDebugString([
|
||||
LabelValuePair.weak("playing", playing),
|
||||
LabelValuePair.weak("time", time),
|
||||
LabelValuePair.weak("time", _time),
|
||||
LabelValuePair.weak("length", length),
|
||||
LabelValuePair.weak("volume", volume),
|
||||
LabelValuePair.weak("pitch", pitch)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package funkin.backend;
|
||||
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.math.FlxMatrix;
|
||||
import openfl.display.BlendMode;
|
||||
import openfl.geom.ColorTransform;
|
||||
|
||||
class FlxAnimate extends flxanimate.FlxAnimate {
|
||||
static var rMatrix = new FlxMatrix();
|
||||
|
||||
override function drawLimb(limb:FlxFrame, _rMatrix:FlxMatrix, ?colorTransform:ColorTransform, ?blendMode:BlendMode)
|
||||
{
|
||||
if (alpha == 0 || colorTransform != null && (colorTransform.alphaMultiplier == 0 || colorTransform.alphaOffset == -255) || limb == null || limb.type == EMPTY)
|
||||
return;
|
||||
|
||||
if (blendMode == null)
|
||||
blendMode = BlendMode.NORMAL;
|
||||
|
||||
for (camera in cameras)
|
||||
{
|
||||
rMatrix.identity();
|
||||
limb.prepareMatrix(rMatrix, FlxFrameAngle.ANGLE_0, _checkFlipX() != camera.flipX, _checkFlipY() != camera.flipY);
|
||||
rMatrix.concat(_rMatrix);
|
||||
if (!camera.visible || !camera.exists || !limbOnScreen(limb, _rMatrix, camera))
|
||||
return;
|
||||
|
||||
getScreenPosition(_point, camera).subtractPoint(offset);
|
||||
rMatrix.translate(-origin.x, -origin.y);
|
||||
if (limb != _pivot) {
|
||||
if (frameOffsetAngle != null && frameOffsetAngle != angle)
|
||||
{
|
||||
var angleOff = (frameOffsetAngle - angle) * FlxAngle.TO_RAD;
|
||||
var cos = Math.cos(angleOff);
|
||||
var sin = Math.sin(angleOff);
|
||||
// cos doesn't need to be negated
|
||||
rMatrix.rotateWithTrig(cos, -sin);
|
||||
rMatrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
rMatrix.rotateWithTrig(cos, sin);
|
||||
}
|
||||
else
|
||||
{
|
||||
rMatrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
}
|
||||
rMatrix.scale(scale.x, scale.y);
|
||||
|
||||
if (!matrixExposed && bakedRotationAngle <= 0)
|
||||
{
|
||||
updateTrig();
|
||||
|
||||
if (angle != 0)
|
||||
rMatrix.rotateWithTrig(_cosAngle, _sinAngle);
|
||||
}
|
||||
}
|
||||
else
|
||||
rMatrix.a = rMatrix.d = 0.7 / camera.zoom;
|
||||
|
||||
if (matrixExposed)
|
||||
{
|
||||
rMatrix.concat(transformMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
rMatrix.concat(@:privateAccess flxanimate.FlxAnimate._skewMatrix);
|
||||
}
|
||||
|
||||
_point.addPoint(origin);
|
||||
if (isPixelPerfectRender(camera))
|
||||
{
|
||||
_point.floor();
|
||||
}
|
||||
|
||||
rMatrix.translate(_point.x, _point.y);
|
||||
camera.drawPixels(limb, null, rMatrix, colorTransform, blendMode, antialiasing, shaderEnabled ? shader : null);
|
||||
#if FLX_DEBUG
|
||||
FlxBasic.visibleCount++;
|
||||
#end
|
||||
}
|
||||
|
||||
// doesn't work, needs to be remade
|
||||
// #if FLX_DEBUG
|
||||
// if (FlxG.debugger.drawDebug)
|
||||
// drawDebug();
|
||||
// #end
|
||||
}
|
||||
|
||||
override function limbOnScreen(limb:FlxFrame, m:FlxMatrix, ?Camera:FlxCamera)
|
||||
{
|
||||
// TODO: ACTUAL OPTIMIZATION
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package funkin.backend;
|
||||
|
||||
import animate.FlxAnimate;
|
||||
import animate.FlxAnimateController.FlxAnimateAnimation;
|
||||
import flixel.addons.effects.FlxSkewedSprite;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import flixel.math.FlxMatrix;
|
||||
@@ -9,6 +7,7 @@ import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.FlxAssets.FlxGraphicAsset;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import flxanimate.animate.FlxAnim.FlxSymbolAnimation;
|
||||
import funkin.backend.scripting.events.sprite.PlayAnimContext;
|
||||
import funkin.backend.system.interfaces.IBeatReceiver;
|
||||
import funkin.backend.system.interfaces.IOffsetCompatible;
|
||||
@@ -16,10 +15,6 @@ import funkin.backend.utils.XMLUtil.AnimData;
|
||||
import funkin.backend.utils.XMLUtil.BeatAnim;
|
||||
import funkin.backend.utils.XMLUtil.IXMLEvents;
|
||||
import haxe.io.Path;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.math.FlxAngle;
|
||||
import animate.internal.RenderTexture;
|
||||
import animate.FlxAnimateFrames;
|
||||
|
||||
enum abstract XMLAnimType(Int)
|
||||
{
|
||||
@@ -48,7 +43,7 @@ enum abstract XMLAnimType(Int)
|
||||
}
|
||||
}
|
||||
|
||||
class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
|
||||
class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
|
||||
{
|
||||
public var extra:Map<String, Dynamic> = [];
|
||||
|
||||
@@ -61,9 +56,6 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
public var animEnabled:Bool = true;
|
||||
public var zoomFactorEnabled:Bool = true;
|
||||
|
||||
//Backwards compatibility
|
||||
public var animateAtlas(get, never):FunkinSprite;
|
||||
|
||||
public var globalCurFrame(get, set):Int;
|
||||
|
||||
/**
|
||||
@@ -74,9 +66,9 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
public var beatOffset:Int = 0;
|
||||
public var skipNegativeBeats:Bool = false;
|
||||
|
||||
public var animateSettings:FlxAnimateSettings = {};
|
||||
|
||||
var _rect2:FlxRect;
|
||||
public var animateAtlas:FlxAnimate;
|
||||
@:noCompletion public var atlasPlayingAnim:String;
|
||||
@:noCompletion public var atlasPath:String;
|
||||
|
||||
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
||||
{
|
||||
@@ -91,7 +83,6 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
}
|
||||
|
||||
moves = false;
|
||||
applyStageMatrix = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +98,8 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
@:privateAccess {
|
||||
spr.setPosition(source.x, source.y);
|
||||
spr.frames = source.frames;
|
||||
if (casted != null && casted.animateAtlas != null && casted.atlasPath != null)
|
||||
spr.loadSprite(casted.atlasPath);
|
||||
spr.animation.copyFrom(source.animation);
|
||||
spr.visible = source.visible;
|
||||
spr.alpha = source.alpha;
|
||||
@@ -116,8 +109,9 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
|
||||
if (casted != null) {
|
||||
spr.skew.set(casted.skew.x, casted.skew.y);
|
||||
spr.transformMatrix = casted.transformMatrix;
|
||||
spr.matrixExposed = casted.matrixExposed;
|
||||
spr.animOffsets = casted.animOffsets.copy();
|
||||
spr.zoomFactor = casted.zoomFactor;
|
||||
}
|
||||
}
|
||||
return spr;
|
||||
@@ -126,6 +120,8 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
public override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
if (animateAtlas != null)
|
||||
animateAtlas.update(elapsed);
|
||||
|
||||
// hate how it looks like but hey at least its optimized and fast - Nex
|
||||
if (!debugMode && isAnimFinished()) {
|
||||
@@ -135,15 +131,18 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
}
|
||||
}
|
||||
|
||||
override function initVars() {
|
||||
super.initVars();
|
||||
_rect2 = FlxRect.get();
|
||||
}
|
||||
|
||||
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
|
||||
{
|
||||
var noExt = Path.withoutExtension(path);
|
||||
frames = Paths.getFrames(path, true, null, null, animateSettings);
|
||||
if (Assets.exists('$noExt/Animation.json'))
|
||||
{
|
||||
atlasPath = noExt;
|
||||
animateAtlas = new FlxAnimate(x, y, noExt);
|
||||
}
|
||||
else
|
||||
{
|
||||
frames = Paths.getFrames(path, true);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -175,9 +174,48 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
|
||||
// ANIMATE ATLAS DRAWING
|
||||
#if REGION
|
||||
public override function draw()
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
{
|
||||
copyAtlasValues();
|
||||
animateAtlas.draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
public function copyAtlasValues()
|
||||
{
|
||||
@:privateAccess {
|
||||
animateAtlas.cameras = cameras; // investigate if we can use _cameras
|
||||
animateAtlas.scrollFactor = scrollFactor;
|
||||
animateAtlas.scale = scale;
|
||||
animateAtlas.offset = offset;
|
||||
animateAtlas.frameOffset = frameOffset;
|
||||
animateAtlas.x = x;
|
||||
animateAtlas.y = y;
|
||||
animateAtlas.angle = angle;
|
||||
animateAtlas.alpha = alpha;
|
||||
animateAtlas.visible = visible;
|
||||
animateAtlas.flipX = flipX;
|
||||
animateAtlas.flipY = flipY;
|
||||
animateAtlas.shader = shader;
|
||||
animateAtlas.shaderEnabled = shaderEnabled;
|
||||
animateAtlas.antialiasing = antialiasing;
|
||||
animateAtlas.skew = skew;
|
||||
animateAtlas.transformMatrix = transformMatrix;
|
||||
animateAtlas.matrixExposed = matrixExposed;
|
||||
animateAtlas.colorTransform = colorTransform;
|
||||
}
|
||||
}
|
||||
|
||||
public override function destroy()
|
||||
{
|
||||
animateAtlas = FlxDestroyUtil.destroy(animateAtlas);
|
||||
|
||||
if (animOffsets != null) {
|
||||
for (key in animOffsets.keys()) {
|
||||
final point = animOffsets[key];
|
||||
@@ -188,8 +226,6 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
animOffsets = null;
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
_rect2 = FlxDestroyUtil.put(_rect2);
|
||||
}
|
||||
#end
|
||||
|
||||
@@ -197,21 +233,27 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
private inline function __shouldDoZoomFactor()
|
||||
return zoomFactorEnabled && zoomFactor != 1;
|
||||
|
||||
private inline function __prepareZoomFactor(?rect:FlxRect, camera:FlxCamera):FlxRect {
|
||||
if (Flags.USE_LEGACY_ZOOM_FACTOR)
|
||||
return (rect ?? FlxRect.get()).set(
|
||||
camera.width * 0.5,
|
||||
camera.height * 0.5,
|
||||
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)),
|
||||
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor))
|
||||
);
|
||||
else
|
||||
return (rect ?? FlxRect.get()).set(
|
||||
camera.width * 0.5 + camera.scroll.x * scrollFactor.x,
|
||||
camera.height * 0.5 + camera.scroll.y * scrollFactor.y,
|
||||
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)),
|
||||
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor))
|
||||
);
|
||||
public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
|
||||
{
|
||||
if (camera == null)
|
||||
camera = FlxG.camera;
|
||||
|
||||
var r = super.getScreenBounds(newRect, camera);
|
||||
|
||||
if(__shouldDoZoomFactor()) {
|
||||
r.x -= camera.width / 2;
|
||||
r.y -= camera.height / 2;
|
||||
|
||||
var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor));
|
||||
r.x *= ratio;
|
||||
r.y *= ratio;
|
||||
r.width *= ratio;
|
||||
r.height *= ratio;
|
||||
|
||||
r.x += camera.width / 2;
|
||||
r.y += camera.height / 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
override public function isOnScreen(?camera:FlxCamera):Bool
|
||||
@@ -228,6 +270,20 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
return camera.containsRect(bounds);
|
||||
}
|
||||
|
||||
// ZOOM FACTOR RENDERING
|
||||
public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera)
|
||||
{
|
||||
super.doAdditionalMatrixStuff(matrix, camera);
|
||||
if(__shouldDoZoomFactor()) {
|
||||
matrix.translate(-camera.width / 2, -camera.height / 2);
|
||||
|
||||
var requestedZoom = (camera.zoom >= 0 ? Math.max : Math.min)(FlxMath.lerp(1, camera.zoom, zoomFactor), 0);
|
||||
var diff = requestedZoom / camera.zoom;
|
||||
matrix.scale(diff, diff);
|
||||
matrix.translate(camera.width / 2, camera.height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSETTING
|
||||
#if REGION
|
||||
public var animOffsets:Map<String, FlxPoint> = new Map<String, FlxPoint>();
|
||||
@@ -259,7 +315,13 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
Force = anim != null && anim.forced;
|
||||
}
|
||||
|
||||
animation.play(AnimName, Force, Reversed, Frame);
|
||||
if (animateAtlas != null)
|
||||
{
|
||||
@:privateAccess
|
||||
animateAtlas.anim.play(AnimName, Force, Reversed, Frame);
|
||||
atlasPlayingAnim = AnimName;
|
||||
}
|
||||
else animation.play(AnimName, Force, Reversed, Frame);
|
||||
|
||||
var daOffset = getAnimOffset(AnimName);
|
||||
frameOffset.set(daOffset.x, daOffset.y);
|
||||
@@ -268,7 +330,7 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
lastAnimContext = Context;
|
||||
}
|
||||
|
||||
public inline function addAnim(name:String, prefix:String, frameRate:Float = 24, ?looped:Bool, ?forced:Bool, ?indices:Array<Int>, x:Float = 0, y:Float = 0, animType:XMLAnimType = NONE, animateAtlasLabel:Bool = false)
|
||||
public inline function addAnim(name:String, prefix:String, frameRate:Float = 24, ?looped:Bool, ?forced:Bool, ?indices:Array<Int>, x:Float = 0, y:Float = 0, animType:XMLAnimType = NONE)
|
||||
{
|
||||
return XMLUtil.addAnimToSprite(this, {
|
||||
name: name,
|
||||
@@ -279,16 +341,22 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
x: x,
|
||||
y: y,
|
||||
indices: indices,
|
||||
forced: forced,
|
||||
label: animateAtlasLabel
|
||||
forced: forced
|
||||
});
|
||||
}
|
||||
|
||||
public inline function removeAnim(name:String) {
|
||||
animation.remove(name);
|
||||
public inline function removeAnim(name:String)
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
@:privateAccess animateAtlas.anim.animsMap.remove(name);
|
||||
else
|
||||
animation.remove(name);
|
||||
}
|
||||
|
||||
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxAnimateAnimation> {
|
||||
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxSymbolAnimation>
|
||||
{
|
||||
if(animateAtlas != null)
|
||||
return animateAtlas.anim.getByName(name);
|
||||
return animation.getByName(name);
|
||||
}
|
||||
|
||||
@@ -299,26 +367,40 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
return FlxPoint.weak(0, 0);
|
||||
}
|
||||
|
||||
public inline function hasAnim(AnimName:String):Bool
|
||||
return animation.exists(AnimName);
|
||||
public inline function hasAnim(AnimName:String):Bool @:privateAccess
|
||||
return animateAtlas != null ? (animateAtlas.anim.animsMap.exists(AnimName)
|
||||
|| animateAtlas.anim.symbolDictionary.exists(AnimName)) : animation.exists(AnimName);
|
||||
|
||||
public inline function getAnimName()
|
||||
return animation.name;
|
||||
public inline function getAnimName() {
|
||||
return (animateAtlas != null) ? atlasPlayingAnim : animation.name;
|
||||
}
|
||||
|
||||
public inline function isAnimReversed():Bool
|
||||
return animation.curAnim?.reversed ?? false;
|
||||
public inline function isAnimReversed():Bool {
|
||||
return animateAtlas != null ? animateAtlas.anim.reversed : animation.curAnim != null ? animation.curAnim.reversed : false;
|
||||
}
|
||||
|
||||
public inline function getNameList():Array<String>
|
||||
return animation.getNameList();
|
||||
public inline function getNameList():Array<String> {
|
||||
if (animateAtlas != null)
|
||||
return [for (name in @:privateAccess animateAtlas.anim.animsMap.keys()) name];
|
||||
else
|
||||
return animation.getNameList();
|
||||
}
|
||||
|
||||
public inline function stopAnim()
|
||||
animation.stop();
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
animateAtlas.anim.pause();
|
||||
else
|
||||
animation.stop();
|
||||
}
|
||||
|
||||
public inline function isAnimFinished()
|
||||
return animation.curAnim?.finished ?? true;
|
||||
public inline function isAnimFinished() {
|
||||
return animateAtlas != null ? animateAtlas.anim.finished : (animation.curAnim != null ? animation.curAnim.finished : true);
|
||||
}
|
||||
|
||||
public inline function isAnimAtEnd()
|
||||
return animation.curAnim?.isAtEnd ?? false;
|
||||
public inline function isAnimAtEnd() {
|
||||
return animateAtlas != null ? animateAtlas.anim.isAtEnd : (animation.curAnim != null ? animation.curAnim.isAtEnd : false);
|
||||
}
|
||||
|
||||
override function updateAnimation(elapsed:Float) {
|
||||
if (animEnabled)
|
||||
@@ -340,59 +422,10 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
|
||||
return beatInterval = v;
|
||||
}
|
||||
|
||||
@:noCompletion
|
||||
@:deprecated("`FunkinSprite.animateAtlas` is deprecated, just use `FunkinSprite` instead")
|
||||
public function get_animateAtlas():FunkinSprite
|
||||
return isAnimate ? this : null;
|
||||
|
||||
@:noCompletion private inline function get_globalCurFrame()
|
||||
return animation.curAnim?.curFrame ?? 0;
|
||||
|
||||
@:noCompletion private inline function get_globalCurFrame() {
|
||||
return animateAtlas != null ? (animateAtlas.anim.curFrame) : (animation.curAnim != null ? animation.curAnim.curFrame : 0);
|
||||
}
|
||||
@:noCompletion private inline function set_globalCurFrame(val:Int) {
|
||||
if (animation.curAnim != null)
|
||||
animation.curAnim.curFrame = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
override function prepareDrawMatrix(matrix:FlxMatrix, camera:FlxCamera):Void {
|
||||
matrix.translate(-origin.x, -origin.y);
|
||||
|
||||
if (frameOffsetAngle != null && frameOffsetAngle != angle)
|
||||
{
|
||||
var angleOff = (frameOffsetAngle - angle) * FlxAngle.TO_RAD;
|
||||
var cos = Math.cos(angleOff);
|
||||
var sin = Math.sin(angleOff);
|
||||
// cos doesnt need to be negated
|
||||
matrix.rotateWithTrig(cos, -sin);
|
||||
matrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
matrix.rotateWithTrig(cos, sin);
|
||||
}
|
||||
else
|
||||
matrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
|
||||
matrix.translate(origin.x, origin.y);
|
||||
|
||||
super.prepareDrawMatrix(matrix, camera);
|
||||
|
||||
applyZoomFactor(matrix, camera);
|
||||
}
|
||||
|
||||
function applyZoomFactor(matrix:FlxMatrix, camera:FlxCamera) {
|
||||
if(__shouldDoZoomFactor()) {
|
||||
__prepareZoomFactor(_rect2, camera);
|
||||
matrix.setTo(
|
||||
matrix.a * _rect2.width, matrix.b * _rect2.height,
|
||||
matrix.c * _rect2.width, matrix.d * _rect2.height,
|
||||
(matrix.tx - _rect2.x) * _rect2.width + _rect2.x,
|
||||
(matrix.ty - _rect2.y) * _rect2.height + _rect2.y,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
override function checkFlipX() {
|
||||
return super.checkFlipX() != camera.flipX;
|
||||
}
|
||||
override function checkFlipY() {
|
||||
return super.checkFlipY() != camera.flipY;
|
||||
return animateAtlas != null ? (animateAtlas.anim.curFrame = val) : (animation.curAnim != null ? animation.curAnim.curFrame = val : val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,12 +236,6 @@ class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
|
||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
||||
}
|
||||
|
||||
public override function closeSubState() {
|
||||
var e = event("onCloseSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
if (!e.cancelled)
|
||||
super.closeSubState();
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
|
||||
|
||||
@@ -114,8 +114,12 @@ class MusicBeatTransition extends MusicBeatSubstate {
|
||||
}
|
||||
|
||||
if (transitionSprite != null) {
|
||||
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
|
||||
transitionSprite.updateHitbox();
|
||||
if (transitionSprite.animateAtlas == null) {
|
||||
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
|
||||
transitionSprite.updateHitbox();
|
||||
} else {
|
||||
transitionSprite.screenCenter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import funkin.backend.assets.TranslatedAssetLibrary;
|
||||
#end
|
||||
import funkin.backend.assets.IModsAssetLibrary;
|
||||
import lime.utils.AssetLibrary;
|
||||
import haxe.ds.Map;
|
||||
|
||||
class AssetsLibraryList extends AssetLibrary {
|
||||
public var libraries:Array<AssetLibrary> = [];
|
||||
@@ -142,16 +141,6 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
public override inline function getAsset(id:String, type:String):Dynamic
|
||||
return getSpecificAsset(id, type, BOTH);
|
||||
|
||||
public override function list(type:String):Array<String> {
|
||||
// idk if there's a more efficient way tbh, correct if u find better
|
||||
var files:Map<String, Bool> = [];
|
||||
for(k=>l in libraries) {
|
||||
for(f in l.list(type))
|
||||
files.set(f, false);
|
||||
}
|
||||
return [for(k=>e in files) k];
|
||||
}
|
||||
|
||||
public override function isLocal(id:String, type:String) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -149,22 +149,6 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override function list(type:String):Array<String> {
|
||||
var result = [];
|
||||
__listAppend(result, '');
|
||||
return result;
|
||||
}
|
||||
|
||||
function __listAppend(arr:Array<String>, folder:String) {
|
||||
for(file in FileSystem.readDirectory('$basePath/$folder')) {
|
||||
var fullPath = '$basePath/$folder/$file';
|
||||
if (FileSystem.isDirectory(fullPath))
|
||||
__listAppend(arr, '$folder$file/');
|
||||
else
|
||||
arr.push('$prefix$folder$file');
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
// Backwards compat
|
||||
|
||||
@@ -8,7 +8,6 @@ import funkin.backend.scripting.Script;
|
||||
import haxe.io.Path;
|
||||
import lime.utils.AssetLibrary;
|
||||
import openfl.utils.Assets as OpenFlAssets;
|
||||
import animate.FlxAnimateFrames;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -175,9 +174,6 @@ class Paths
|
||||
inline static public function getSparrowAtlas(key:String, ?library:String, ?ext:String)
|
||||
return FlxAtlasFrames.fromSparrow(image(key, library, ext), file('images/$key.xml', library));
|
||||
|
||||
inline static public function getAnimateAtlasAlt(key:String, ?settings:FlxAnimateSettings)
|
||||
return FlxAnimateFrames.fromAnimate(key, null, null, null, false, settings);
|
||||
|
||||
inline static public function getSparrowAtlasAlt(key:String, ?ext:String)
|
||||
return FlxAtlasFrames.fromSparrow('$key.${ext != null ? ext : Flags.IMAGE_EXT}', '$key.xml');
|
||||
|
||||
@@ -201,7 +197,7 @@ class Paths
|
||||
* @param key Path to the frames
|
||||
* @param library (Additional) library to load the frames from.
|
||||
*/
|
||||
public static function getFrames(key:String, assetsPath:Bool = false, ?library:String, ?ext:String = null, ?animateSettings:FlxAnimateSettings) {
|
||||
public static function getFrames(key:String, assetsPath:Bool = false, ?library:String, ?ext:String = null) {
|
||||
if (tempFramesCache.exists(key)) {
|
||||
var frames = tempFramesCache[key];
|
||||
if (frames != null && frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable)
|
||||
@@ -209,7 +205,7 @@ class Paths
|
||||
else
|
||||
tempFramesCache.remove(key);
|
||||
}
|
||||
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true, ext), false, null, false, ext, animateSettings);
|
||||
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true, ext), false, null, false, ext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +242,7 @@ class Paths
|
||||
* @param Ext Extension of the image.
|
||||
* @return FlxFramesCollection Frames
|
||||
*/
|
||||
static function loadFrames(path:String, Unique:Bool = false, Key:String = null, SkipAtlasCheck:Bool = false, SkipMultiCheck:Bool = false, ?Ext:String = null, ?animateSettings:FlxAnimateSettings):FlxFramesCollection {
|
||||
static function loadFrames(path:String, Unique:Bool = false, Key:String = null, SkipAtlasCheck:Bool = false, SkipMultiCheck:Bool = false, ?Ext:String = null):FlxFramesCollection {
|
||||
var noExt = Path.withoutExtension(path);
|
||||
var ext = Ext != null ? Ext : Flags.IMAGE_EXT;
|
||||
|
||||
@@ -267,8 +263,6 @@ class Paths
|
||||
cur++;
|
||||
}
|
||||
return finalFrames;
|
||||
} else if (Assets.exists('$noExt/Animation.json')) {
|
||||
return Paths.getAnimateAtlasAlt(noExt, animateSettings);
|
||||
} else if (Assets.exists('$noExt.xml')) {
|
||||
return Paths.getSparrowAtlasAlt(noExt, ext);
|
||||
} else if (Assets.exists('$noExt.txt')) {
|
||||
|
||||
@@ -108,8 +108,6 @@ class TranslatedAssetLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: list support for TranslatedAssetLibrary (idk how it works)
|
||||
|
||||
#if MOD_SUPPORT
|
||||
public var _parsedAsset:String = null; // Theres no need to actually make this work - Nex
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
zip = SysZip.openFromFile(basePath);
|
||||
zip.read();
|
||||
for(entry in zip.entries) {
|
||||
if (entry.fileName.length < 0 || entry.fileName.endsWith("/"))
|
||||
continue;
|
||||
|
||||
lowerCaseAssets[entry.fileName.toLowerCase()] = assets[entry.fileName.toLowerCase()] = assets[entry.fileName] = entry;
|
||||
nameMap.set(entry.fileName.toLowerCase(), entry.fileName);
|
||||
}
|
||||
@@ -157,10 +154,6 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return content;
|
||||
}
|
||||
|
||||
public override function list(type:String):Array<String> {
|
||||
return[for(k=>e in nameMap) '$prefix$e'];
|
||||
}
|
||||
|
||||
// Backwards compat
|
||||
|
||||
@:noCompletion public var zipPath(get, set):String;
|
||||
|
||||
@@ -300,7 +300,6 @@ class Chart {
|
||||
var eventsPath = '$songPath/events$variantSuffix.json', events = filterEventsForSaving(chart.events, false, true);
|
||||
|
||||
if (events.length != 0) CoolUtil.safeSaveFile(eventsPath, Json.stringify({events: events}, null, prettyPrint));
|
||||
else if (FileSystem.exists(eventsPath)) FileSystem.deleteFile(eventsPath); // If there's no events to save, then get rid of the file (if it exists already).
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
@@ -179,8 +179,7 @@ class EventsData {
|
||||
finalParams.push({
|
||||
name: paramData.name,
|
||||
type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
|
||||
defValue: paramData.defaultValue,
|
||||
saveIfDefault: paramData.saveIfDefault
|
||||
defValue: paramData.defaultValue
|
||||
});
|
||||
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
|
||||
}
|
||||
@@ -197,7 +196,6 @@ typedef EventInfoFile = {
|
||||
var name:String;
|
||||
var type:String;
|
||||
var defaultValue:Dynamic;
|
||||
var ?saveIfDefault:Bool;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class PsychParser {
|
||||
note.time, // TIME
|
||||
note.id, // DATA
|
||||
note.sLen, // SUSTAIN LENGTH
|
||||
chart.noteTypes.getDefault([""])[note.type - 1] // NOTE TYPE
|
||||
chart.noteTypes.getDefault([""])[note.type] // NOTE TYPE
|
||||
];
|
||||
|
||||
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
|
||||
|
||||
@@ -55,6 +55,9 @@ class GlobalScript {
|
||||
reloading = false;
|
||||
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
|
||||
}
|
||||
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
});
|
||||
FlxG.signals.preDraw.add(function() {
|
||||
call("preDraw");
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package funkin.backend.scripting;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#end
|
||||
|
||||
import hscript.IHScriptCustomBehaviour;
|
||||
|
||||
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
||||
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
||||
|
||||
/**
|
||||
* Script being ran.
|
||||
*/
|
||||
@@ -40,6 +46,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
script.load();
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
thread = Thread.createWithEventLoop(function() {
|
||||
// Prevent the thread from being auto deleted
|
||||
Thread.current().events.promise();
|
||||
});
|
||||
#end
|
||||
|
||||
__variables = Type.getInstanceFields(Type.getClass(this));
|
||||
}
|
||||
|
||||
@@ -56,7 +69,7 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
public function call(func:String, args:Array<Dynamic>) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
funkin.backend.utils.ThreadUtil.execAsync(() -> {
|
||||
thread.events.run(function() {
|
||||
callEnded = false;
|
||||
returnValue = script.call(func, args);
|
||||
callEnded = true;
|
||||
@@ -72,5 +85,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
script.call("destroy");
|
||||
script.destroy();
|
||||
}
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
if (thread != null) {
|
||||
thread.events.runPromised(function() {
|
||||
// close the thing
|
||||
});
|
||||
}
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"FunkinShader" => funkin.backend.shaders.FunkinShader,
|
||||
"CustomShader" => funkin.backend.shaders.CustomShader,
|
||||
"FunkinText" => funkin.backend.FunkinText,
|
||||
"FlxAnimate" => animate.FlxAnimate,
|
||||
"FlxAnimate" => funkin.backend.FlxAnimate,
|
||||
"FunkinSprite" => funkin.backend.FunkinSprite,
|
||||
"Alphabet" => funkin.menus.ui.Alphabet,
|
||||
"Flags" => funkin.backend.system.Flags,
|
||||
@@ -102,7 +102,6 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
|
||||
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
|
||||
"EngineUtil" => funkin.backend.utils.EngineUtil,
|
||||
"ThreadUtil" => funkin.backend.utils.ThreadUtil,
|
||||
"MemoryUtil" => funkin.backend.utils.MemoryUtil,
|
||||
"BitmapUtil" => funkin.backend.utils.BitmapUtil,
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
@:dox(hide) public var unmuteVocals:Bool = true;
|
||||
@:dox(hide) public var enableCamZooming:Bool = true;
|
||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||
@:dox(hide) public var clipSustain:Bool = true;
|
||||
|
||||
/**
|
||||
* Whenever a miss should be added.
|
||||
@@ -146,13 +145,6 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
deleteNote = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the sustain from being cut. Only works if the note is a sustain.
|
||||
*/
|
||||
public function preventSustainClip() {
|
||||
clipSustain = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the vocals volume from being set to 1 after pressing the note.
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,6 @@ class ScriptableShader extends FlxBasic implements IHScriptCustomBehaviour {
|
||||
if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
|
||||
else throw "Missing name for shader script, please provide a scriptName, or use CustomShader";
|
||||
|
||||
this.shader = shader;
|
||||
|
||||
script = Script.create(Paths.script('shaders/$scriptName'));
|
||||
script.setParent(shader);
|
||||
script.set("shader", shader);
|
||||
|
||||
@@ -25,7 +25,6 @@ enum Control
|
||||
CHANGE_MODE;
|
||||
//CHEAT;
|
||||
SWITCHMOD;
|
||||
FPS_COUNTER;
|
||||
|
||||
// Debugs
|
||||
DEV_ACCESS;
|
||||
@@ -162,11 +161,6 @@ class Controls extends FlxActionSet
|
||||
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
|
||||
@:justReleased("switchmod") public var SWITCHMOD_R(get, set): Bool;
|
||||
|
||||
@:gamepad([])
|
||||
@:justPressed("fps-counter") public var FPS_COUNTER(get, set): Bool;
|
||||
@:pressed("fps-counter") public var FPS_COUNTER_HOLD(get, set): Bool;
|
||||
@:justReleased("fps-counter") public var FPS_COUNTER_R(get, set): Bool;
|
||||
|
||||
@:devModeOnly
|
||||
@:gamepad([])
|
||||
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
|
||||
|
||||
@@ -15,18 +15,14 @@ import lime.utils.AssetType;
|
||||
*/
|
||||
@:build(funkin.backend.system.macros.FlagMacro.build())
|
||||
class Flags {
|
||||
public static var overridenFlags:Map<String, Bool> = [];
|
||||
|
||||
// -- Codename's Addon Config --
|
||||
@:bypass public static var addonFlags:Map<String, Dynamic> = [];
|
||||
|
||||
public static var CURRENT_API_VERSION:Int = 2;
|
||||
|
||||
// -- Codename's Mod Config --
|
||||
public static var MOD_NAME:String = "";
|
||||
public static var MOD_DESCRIPTION:String = "";
|
||||
public static var MOD_AUTHOR:String = "";
|
||||
@:lazy public static var MOD_API_VERSION:Null<Int> = null;
|
||||
public static var MOD_API_VERSION:Int = 1;
|
||||
public static var MOD_DOWNLOAD_LINK:String = "";
|
||||
public static var MOD_DEPENDENCIES:Array<String> = [];
|
||||
|
||||
@@ -45,11 +41,12 @@ class Flags {
|
||||
@:lazy public static var SAVE_PATH:String = haxe.macro.Compiler.getDefine("SAVE_PATH");
|
||||
@:lazy public static var SAVE_NAME:String = haxe.macro.Compiler.getDefine("SAVE_NAME");
|
||||
|
||||
public static var CURRENT_API_VERSION:Int = 1;
|
||||
public static var COMMIT_NUMBER:Int = GitCommitMacro.commitNumber;
|
||||
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
|
||||
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
|
||||
|
||||
@:lazy public static var WINDOW_TITLE_USE_MOD_NAME:Null<Bool> = null;
|
||||
@:bypass public static var WINDOW_TITLE_USE_MOD_NAME:Bool = false;
|
||||
@:lazy public static var TITLE:String = Application.current.meta.get('name');
|
||||
@:lazy public static var VERSION:String = Application.current.meta.get('version');
|
||||
|
||||
@@ -128,16 +125,12 @@ class Flags {
|
||||
@:also(funkin.game.PlayState.opponentMode)
|
||||
public static var DEFAULT_OPPONENT_MODE:Bool = false;
|
||||
|
||||
public static var USE_LEGACY_TIMING:Null<Bool> = null;
|
||||
|
||||
public static var DEFAULT_NOTE_MS_LIMIT:Float = 1500;
|
||||
public static var DEFAULT_NOTE_SCALE:Float = 0.7;
|
||||
#if MODCHARTING_FEATURES
|
||||
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
|
||||
#end
|
||||
|
||||
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
|
||||
|
||||
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
|
||||
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
|
||||
|
||||
@@ -155,8 +148,6 @@ class Flags {
|
||||
public static var DEFAULT_HUD_ZOOM_MULT:Float = 0.03;
|
||||
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
|
||||
public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05;
|
||||
|
||||
public static var USE_LEGACY_ZOOM_FACTOR:Null<Bool> = null;
|
||||
|
||||
// Font configuration
|
||||
public static var DEFAULT_FONT:String = "vcr.ttf";
|
||||
@@ -286,6 +277,8 @@ class Flags {
|
||||
@:bypass public static var customFlags:Map<String, String> = [];
|
||||
|
||||
public static function loadFromData(flags:Map<String, String>, data:String) {
|
||||
WINDOW_TITLE_USE_MOD_NAME = false;
|
||||
|
||||
if (!(data.length > 0)) return;
|
||||
var res = IniUtil.parseString(data);
|
||||
|
||||
@@ -302,39 +295,28 @@ class Flags {
|
||||
else trace('Invalid section $name');
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags.exists("WINDOW_TITLE_USE_MOD_NAME")) WINDOW_TITLE_USE_MOD_NAME = !flags.exists('TITLE') && flags.exists('MOD_NAME');
|
||||
else WINDOW_TITLE_USE_MOD_NAME = parseBool(flags.get("WINDOW_TITLE_USE_MOD_NAME"));
|
||||
|
||||
flags.remove("WINDOW_TITLE_USE_MOD_NAME");
|
||||
}
|
||||
|
||||
private static function loadPost() {
|
||||
if (MOD_API_VERSION == null) MOD_API_VERSION = CURRENT_API_VERSION;
|
||||
if (WINDOW_TITLE_USE_MOD_NAME == null) WINDOW_TITLE_USE_MOD_NAME = !overridenFlags.exists('TITLE') && overridenFlags.exists('MOD_NAME');
|
||||
if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION < 2;
|
||||
if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION < 2;
|
||||
if (SUSTAINS_AS_ONE_NOTE == null) SUSTAINS_AS_ONE_NOTE = MOD_API_VERSION >= 2;
|
||||
}
|
||||
|
||||
public static function loadFromDatas(datas:Array<String>):Map<String, String> {
|
||||
public static function loadFromDatas(datas:Array<String>) {
|
||||
var flags:Map<String, String> = [];
|
||||
for (data in datas) {
|
||||
if (data != null)
|
||||
for(data in datas) {
|
||||
if(data != null)
|
||||
loadFromData(flags, data);
|
||||
}
|
||||
loadPost();
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static function parseFlags(flags:Map<String, String>) {
|
||||
var parsed:Bool;
|
||||
for (name => value in flags) switch (name) {
|
||||
case "MOD_API_VERSION":
|
||||
var version = Std.parseInt(value) ?? CURRENT_API_VERSION;
|
||||
if (version > MOD_API_VERSION || MOD_API_VERSION == null) MOD_API_VERSION = version;
|
||||
default:
|
||||
if (!(parsed = parse(name, value))) customFlags.set(name, value);
|
||||
if (!overridenFlags.exists(name)) overridenFlags.set(name, parsed);
|
||||
}
|
||||
#if MODCHARTING_FEATURES
|
||||
for(name=>value in flags)
|
||||
if(!parse(name, value))
|
||||
customFlags.set(name, value);
|
||||
|
||||
Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS;
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,6 +365,5 @@ class Flags {
|
||||
parseFlags(flags);
|
||||
}
|
||||
}
|
||||
loadPost();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.backend.system;
|
||||
|
||||
import sys.io.File;
|
||||
import sys.FileSystem;
|
||||
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
import flixel.addons.transition.TransitionData;
|
||||
@@ -7,22 +9,21 @@ import flixel.graphics.FlxGraphic;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.ui.FlxSoundTray;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.assets.AssetsLibraryList;
|
||||
import funkin.backend.assets.ModsFolder;
|
||||
import funkin.backend.system.framerate.Framerate;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.system.framerate.SystemInfo;
|
||||
import funkin.backend.system.modules.*;
|
||||
import funkin.backend.utils.ThreadUtil;
|
||||
import funkin.editors.SaveWarning;
|
||||
import funkin.options.PlayerSettings;
|
||||
import openfl.Assets;
|
||||
import openfl.Lib;
|
||||
import openfl.display.Sprite;
|
||||
import openfl.text.TextFormat;
|
||||
import openfl.utils.AssetLibrary;
|
||||
import sys.FileSystem;
|
||||
import sys.io.File;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#end
|
||||
#if android
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
@@ -39,7 +40,7 @@ class Main extends Sprite
|
||||
|
||||
public static var scaleMode:FunkinRatioScaleMode;
|
||||
#if !mobile
|
||||
public static var framerateSprite:Framerate;
|
||||
public static var framerateSprite:funkin.backend.system.framerate.Framerate;
|
||||
#end
|
||||
|
||||
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels).
|
||||
@@ -57,6 +58,10 @@ class Main extends Sprite
|
||||
|
||||
// You can pretty much ignore everything from here on - your code should go in your states.
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
public static var gameThreads:Array<Thread> = [];
|
||||
#end
|
||||
|
||||
public static function preInit() {
|
||||
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
|
||||
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
|
||||
@@ -74,7 +79,7 @@ class Main extends Sprite
|
||||
addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
|
||||
|
||||
#if (!mobile && !web)
|
||||
addChild(framerateSprite = new Framerate());
|
||||
addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
|
||||
SystemInfo.init();
|
||||
#end
|
||||
}
|
||||
@@ -92,8 +97,16 @@ class Main extends Sprite
|
||||
#end;
|
||||
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #end;
|
||||
|
||||
// DEPRECATED
|
||||
@:dox(hide) public static function execAsync(func:Void->Void) ThreadUtil.execAsync(func);
|
||||
|
||||
private static var __threadCycle:Int = 0;
|
||||
public static function execAsync(func:Void->Void) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
var thread = gameThreads[(__threadCycle++) % gameThreads.length];
|
||||
thread.events.run(func);
|
||||
#else
|
||||
func();
|
||||
#end
|
||||
}
|
||||
|
||||
private static function getTimer():Int {
|
||||
return time = Lib.getTimer();
|
||||
@@ -105,6 +118,10 @@ class Main extends Sprite
|
||||
MemoryUtil.init();
|
||||
@:privateAccess
|
||||
FlxG.game.getTimer = getTimer;
|
||||
#if ALLOW_MULTITHREADING
|
||||
for(i in 0...4)
|
||||
gameThreads.push(Thread.createWithEventLoop(function() {Thread.current().events.promise();}));
|
||||
#end
|
||||
FunkinCache.init();
|
||||
Paths.assetsTree = new AssetsLibraryList();
|
||||
|
||||
@@ -139,7 +156,6 @@ class Main extends Sprite
|
||||
FlxG.signals.focusGained.add(onFocus);
|
||||
FlxG.signals.preStateSwitch.add(onStateSwitch);
|
||||
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
|
||||
FlxG.signals.postUpdate.add(onUpdate);
|
||||
|
||||
FlxG.mouse.useSystemCursor = true;
|
||||
#if DARK_MODE_WINDOW
|
||||
@@ -194,14 +210,6 @@ class Main extends Sprite
|
||||
scaleMode.resetSize();
|
||||
}
|
||||
|
||||
public static function onUpdate() {
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
|
||||
if (PlayerSettings.solo.controls.FPS_COUNTER)
|
||||
Framerate.debugMode = (Framerate.debugMode + 1) % 3;
|
||||
}
|
||||
|
||||
private static function onStateSwitchPost() {
|
||||
// manual asset clearing since base openfl one does'nt clear lime one
|
||||
// does'nt clear bitmaps since flixel fork does it auto
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package funkin.backend.system;
|
||||
|
||||
import lime.app.Application;
|
||||
import funkin.backend.system.Main;
|
||||
|
||||
class MainApplication extends Application {
|
||||
public function new() {
|
||||
super();
|
||||
|
||||
#if openfl
|
||||
openfl.Lib.current.stage.addChild(new Main());
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,12 @@ import funkin.backend.assets.IModsAssetLibrary;
|
||||
import funkin.backend.assets.ScriptedAssetLibrary;
|
||||
|
||||
class AssetTreeInfo extends FramerateCategory {
|
||||
private var lastUpdateTime:Float = 1;
|
||||
|
||||
public function new() {
|
||||
super("Asset Libraries Tree Info");
|
||||
}
|
||||
|
||||
public override function __enterFrame(t:Int) {
|
||||
if (alpha <= 0.05) return;
|
||||
|
||||
if ((lastUpdateTime += FlxG.rawElapsed) < 1)
|
||||
return;
|
||||
|
||||
lastUpdateTime = 0;
|
||||
|
||||
var text = 'Not initialized yet\n';
|
||||
if (Paths.assetsTree != null){
|
||||
text = "";
|
||||
|
||||
@@ -53,6 +53,13 @@ class Framerate extends Sprite {
|
||||
x = 10;
|
||||
y = 2;
|
||||
|
||||
FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent) {
|
||||
switch(e.keyCode) {
|
||||
case #if web Keyboard.NUMBER_3 #else Keyboard.F3 #end: // 3 on web or F3 on windows, linux and other things that runs code
|
||||
debugMode = (debugMode + 1) % 3;
|
||||
}
|
||||
});
|
||||
|
||||
if (__bitmap == null)
|
||||
__bitmap = new BitmapData(1, 1, 0xFF000000);
|
||||
|
||||
|
||||
@@ -9,13 +9,6 @@ class FramerateCounter extends Sprite {
|
||||
public var fpsLabel:TextField;
|
||||
public var lastFPS:Float = 0;
|
||||
|
||||
private var frameCount:Int = 0;
|
||||
|
||||
private var accumulatedTime:Float = openfl.Lib.getTimer();
|
||||
|
||||
private final updateInterval:Float = 1 / 15;
|
||||
private var lastUpdateTime:Float = 0;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
|
||||
@@ -34,40 +27,15 @@ class FramerateCounter extends Sprite {
|
||||
}
|
||||
}
|
||||
|
||||
public function reload() {
|
||||
lastUpdateTime = 0;
|
||||
}
|
||||
public function reload() {}
|
||||
|
||||
public override function __enterFrame(t:Int) {
|
||||
if (alpha <= 0.05) return;
|
||||
|
||||
super.__enterFrame(t);
|
||||
|
||||
frameCount++;
|
||||
|
||||
if ((lastUpdateTime += FlxG.rawElapsed) < updateInterval)
|
||||
{
|
||||
updateLabelPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
final timer = openfl.Lib.getTimer();
|
||||
|
||||
final time = timer - accumulatedTime;
|
||||
|
||||
accumulatedTime = timer;
|
||||
|
||||
lastFPS = FlxMath.lerp(lastFPS, time <= 0 ? 0 : (1000 / time * frameCount), 1.0 - Math.pow(0.75, time * 0.06));
|
||||
|
||||
fpsNum.text = Std.string(Math.round(lastFPS));
|
||||
lastUpdateTime = frameCount = 0;
|
||||
|
||||
updateLabelPosition();
|
||||
}
|
||||
|
||||
private inline function updateLabelPosition():Void
|
||||
{
|
||||
lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.rawElapsed == 0 ? 0 : (1 / FlxG.rawElapsed), 0.25);
|
||||
fpsNum.text = Std.string(Math.floor(lastFPS));
|
||||
fpsLabel.x = fpsNum.x + fpsNum.width;
|
||||
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,21 +36,11 @@ class MemoryCounter extends Sprite {
|
||||
if (alpha <= 0.05) return;
|
||||
super.__enterFrame(t);
|
||||
|
||||
final mem = MemoryUtil.currentMemUsage();
|
||||
|
||||
if (mem == memory) {
|
||||
updateLabelPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
memory = mem;
|
||||
memory = MemoryUtil.currentMemUsage();
|
||||
if (memoryPeak < memory) memoryPeak = memory;
|
||||
memoryText.text = CoolUtil.getSizeString(memory);
|
||||
memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
|
||||
|
||||
updateLabelPosition();
|
||||
}
|
||||
|
||||
private inline function updateLabelPosition():Void
|
||||
memoryPeakText.x = memoryText.x + memoryText.width;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,8 @@ class SystemInfo extends FramerateCategory {
|
||||
if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0)
|
||||
Logs.trace('Unable to grab GPU VRAM', ERROR, RED);
|
||||
else {
|
||||
vRAM = getSizeString(vRAMBytes / 1024);
|
||||
var vRAMBytesFloat:#if cpp Float64 #else Float #end = vRAMBytes*1024;
|
||||
vRAM = CoolUtil.getSizeString64(vRAMBytesFloat);
|
||||
}
|
||||
}
|
||||
} else
|
||||
@@ -154,17 +155,6 @@ class SystemInfo extends FramerateCategory {
|
||||
if (totalMem != "Unknown" && memType != "Unknown") __formattedSysText += '\nTotal MEM: $totalMem $memType';
|
||||
}
|
||||
|
||||
static function getSizeString(size:Float):String {
|
||||
if (size < 1024)
|
||||
return Std.int(size) + " MB";
|
||||
else if (size < 1024 * 1024)
|
||||
return Std.int(size / 1024) + " GB";
|
||||
else {
|
||||
var tb = size / (1024 * 1024);
|
||||
return Std.int(tb) + "." + CoolUtil.addZeros(Std.string(Std.int((tb % 1) * 100)), 2) + " TB";
|
||||
}
|
||||
}
|
||||
|
||||
public function new() {
|
||||
super("System Info");
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
package funkin.backend.system.macros;
|
||||
|
||||
#if macro
|
||||
import sys.io.File;
|
||||
import haxe.macro.ComplexTypeTools;
|
||||
import haxe.macro.Printer;
|
||||
import haxe.macro.Expr.Position;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr.Field;
|
||||
import haxe.macro.Expr;
|
||||
|
||||
class AliasMacro {
|
||||
public static var aliasMetadata:Metadata = [{
|
||||
name: ":keep",
|
||||
pos: Context.currentPos()
|
||||
},{
|
||||
name: ":dox",
|
||||
pos: Context.currentPos(),
|
||||
params: [
|
||||
{
|
||||
expr: EConst(CIdent("hide")),
|
||||
pos: Context.currentPos()
|
||||
}
|
||||
]
|
||||
}];
|
||||
|
||||
public static function build():Array<Field> {
|
||||
#if LIME_DISPLAY
|
||||
return Context.getBuildFields();
|
||||
#end
|
||||
|
||||
var fields = Context.getBuildFields();
|
||||
var ogFieldCount = fields.length;
|
||||
|
||||
for(i in 0...ogFieldCount) {
|
||||
var field = fields[i];
|
||||
if (field.meta == null) continue;
|
||||
|
||||
var previousAliases:Array<{name:String, pos:Position}> = [];
|
||||
for(meta in field.meta) {
|
||||
if (meta.name == ":alias" && meta.params != null) {
|
||||
for(p in meta.params) {
|
||||
switch(p.expr) {
|
||||
case EConst(CString(s, kind)):
|
||||
previousAliases.push({
|
||||
name: s,
|
||||
pos: p.pos
|
||||
});
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (previousAliases.length == 0) continue;
|
||||
|
||||
var ghostAccess = field.access.copy();
|
||||
ghostAccess.remove(AOverride);
|
||||
ghostAccess.remove(APublic);
|
||||
|
||||
for(alias in previousAliases) {
|
||||
var ghostField:Field = {
|
||||
name: alias.name,
|
||||
pos: alias.pos,
|
||||
kind: null,
|
||||
access: ghostAccess,
|
||||
meta: aliasMetadata
|
||||
};
|
||||
|
||||
switch(field.kind) {
|
||||
case FFun(f):
|
||||
var args:Array<Expr> = [for(a in f.args) {
|
||||
expr: EConst(CIdent(a.name)),
|
||||
pos: Context.currentPos()
|
||||
}];
|
||||
|
||||
ghostField.kind = FFun({
|
||||
args: f.args,
|
||||
params: f.params,
|
||||
ret: f.ret,
|
||||
expr: macro return $i{field.name}($a{args})
|
||||
});
|
||||
|
||||
default:
|
||||
var type = null;
|
||||
switch(field.kind) {
|
||||
case FVar(t, e):
|
||||
type = t;
|
||||
case FProp(get, set, t, e):
|
||||
type = t;
|
||||
default:
|
||||
}
|
||||
ghostField.kind = FProp("get", "set", type, null);
|
||||
|
||||
fields.push({
|
||||
name: 'get_${alias.name}',
|
||||
kind: FFun({
|
||||
args: [],
|
||||
expr: macro return $i{field.name},
|
||||
ret: type
|
||||
}),
|
||||
pos: alias.pos,
|
||||
meta: aliasMetadata
|
||||
});
|
||||
fields.push({
|
||||
name: 'set_${alias.name}',
|
||||
kind: FFun({
|
||||
args: [{
|
||||
name: '_${field.name}',
|
||||
type: type
|
||||
}],
|
||||
expr: macro return ($i{field.name} = $i{'_${field.name}'}),
|
||||
ret: type
|
||||
}),
|
||||
pos: alias.pos,
|
||||
meta: aliasMetadata
|
||||
});
|
||||
}
|
||||
|
||||
fields.push(ghostField);
|
||||
}
|
||||
|
||||
var docFooter = '_Aliases: ${[for(alias in previousAliases) '`${alias.name}`'].join(", ")}_';
|
||||
if (field.doc != null)
|
||||
field.doc += '\n\n$docFooter';
|
||||
else
|
||||
field.doc = docFooter;
|
||||
}
|
||||
trace(fields);
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -1,68 +0,0 @@
|
||||
package funkin.backend.system.macros;
|
||||
|
||||
using StringTools;
|
||||
|
||||
#if macro
|
||||
class BuildInfo {
|
||||
public static function printBuildInfo() {
|
||||
if(haxe.macro.Context.defined("display") || haxe.macro.Context.defined("display-details")) return;
|
||||
var haxeVersion = haxe.macro.Context.definedValue("haxe").trim();
|
||||
var sleepChangeVersion = false;
|
||||
|
||||
Sys.println('[ BUILD INFO ]');
|
||||
Sys.println('Haxe Version: ${haxeVersion}');
|
||||
try {
|
||||
var lastBuiltWith:Null<String> = null;
|
||||
var compiling = #if final "release" #elseif debug "debug" #else "release" #end;
|
||||
var target = #if hl "hl"
|
||||
#elseif html5 "html5"
|
||||
#elseif ios "ios"
|
||||
#elseif android "android"
|
||||
#elseif windows "windows"
|
||||
#elseif (mac || macos) "macos"
|
||||
#elseif linux "linux"
|
||||
#else ""
|
||||
#end;
|
||||
if(target == "") throw "Unknown target";
|
||||
var exportPath = Sys.getCwd() + "/export/" + compiling + "/" + target + "/";
|
||||
exportPath += "obj/Options.txt";
|
||||
|
||||
var options = sys.io.File.getContent(exportPath);
|
||||
for(option in options.split("\n")) {
|
||||
if(option.startsWith("haxe=")) {
|
||||
lastBuiltWith = option.substr(5).trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(lastBuiltWith != null && lastBuiltWith.length > 0 && lastBuiltWith != haxeVersion) {
|
||||
Sys.println('Last Built With Haxe: ${lastBuiltWith} [!!!! MAKE SURE IF YOU SWITCHED VERSIONS YOU DELETE EXPORT FOLDERS !!!!]');
|
||||
sleepChangeVersion = true;
|
||||
}
|
||||
} catch(e) {}
|
||||
var targetPlatform = #if html5 "Web (HTML5)"
|
||||
#elseif ios "iOS"
|
||||
#elseif android "Android"
|
||||
#elseif windows "Windows"
|
||||
#elseif (mac || macos) "Mac"
|
||||
#elseif linux "Linux"
|
||||
#else "Unknown"
|
||||
#end;
|
||||
|
||||
if(haxe.macro.Context.defined("hl")) {
|
||||
targetPlatform = "Hashlink (" + targetPlatform + ")";
|
||||
}
|
||||
Sys.println('Target Platform: ' + targetPlatform);
|
||||
Sys.println('Build Date: ${Date.now().toString()}');
|
||||
Sys.println('');
|
||||
|
||||
if(sleepChangeVersion) {
|
||||
Sys.println('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
Sys.println('!!!! MAKE SURE IF YOU SWITCHED VERSIONS YOU DELETE EXPORT FOLDERS !!!!');
|
||||
Sys.println('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
||||
Sys.println('');
|
||||
Sys.sleep(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -19,9 +19,9 @@ class DefinesMacro {
|
||||
|
||||
// INTERNAL MACROS
|
||||
#if REGION
|
||||
private static macro function __getDefines():Expr {
|
||||
private static macro function __getDefines() {
|
||||
#if display
|
||||
return macro $v{([]:Map<String, Dynamic>)};
|
||||
return macro $v{[]};
|
||||
#else
|
||||
return macro $v{Context.getDefines()};
|
||||
#end
|
||||
|
||||
@@ -64,7 +64,7 @@ class GitCommitMacro {
|
||||
// INTERNAL MACROS
|
||||
#if REGION
|
||||
private static macro function __getCommitHash() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{"-"};
|
||||
#else
|
||||
try {
|
||||
@@ -78,7 +78,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCommitNumber() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{0};
|
||||
#else
|
||||
try {
|
||||
@@ -92,7 +92,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCommitHashLong() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{"-"};
|
||||
#else
|
||||
try {
|
||||
@@ -106,7 +106,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCommitMessage() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{"-"};
|
||||
#else
|
||||
try {
|
||||
@@ -124,7 +124,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCommitAuthor() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{"-"};
|
||||
#else
|
||||
try {
|
||||
@@ -138,8 +138,8 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCommitDate() {
|
||||
#if LIME_DISPLAY
|
||||
return macro Date.now();
|
||||
#if display
|
||||
return macro $v{Date.now()};
|
||||
#else
|
||||
try {
|
||||
// get the time in UTC format
|
||||
@@ -164,7 +164,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getCurrentBranch() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{"-"};
|
||||
#else
|
||||
try {
|
||||
@@ -179,7 +179,7 @@ class GitCommitMacro {
|
||||
}
|
||||
|
||||
private static macro function __getHasUncommittedChanges() {
|
||||
#if LIME_DISPLAY
|
||||
#if display
|
||||
return macro $v{false};
|
||||
#else
|
||||
try {
|
||||
|
||||
@@ -23,7 +23,7 @@ class Macros {
|
||||
#if VIDEO_CUTSCENES "hxvlc.flixel", "hxvlc.openfl", #end
|
||||
#if NAPE_ENABLED "nape", "flixel.addons.nape", #end
|
||||
// BASE HAXE
|
||||
"DateTools", "EReg", "Lambda", "StringBuf", "haxe.crypto", "haxe.display", "haxe.exceptions", "haxe.extern", "scripting", "animate"
|
||||
"DateTools", "EReg", "Lambda", "StringBuf", "haxe.crypto", "haxe.display", "haxe.exceptions", "haxe.extern", "scripting"
|
||||
])
|
||||
Compiler.include(inc);
|
||||
|
||||
@@ -58,11 +58,6 @@ class Macros {
|
||||
|
||||
final macroPath = 'funkin.backend.system.macros.Macros';
|
||||
Compiler.addMetadata('@:build($macroPath.buildLimeAssetLibrary())', 'lime.utils.AssetLibrary');
|
||||
|
||||
//Adds Compat for #if hscript blocks when you have hscript improved
|
||||
if (Context.defined("hscript_improved") && !Context.defined("hscript")) {
|
||||
Compiler.define('hscript');
|
||||
}
|
||||
}
|
||||
|
||||
public static function buildLimeAssetLibrary():Array<Field> {
|
||||
|
||||
@@ -2,30 +2,22 @@ package funkin.backend.system.updating;
|
||||
|
||||
import funkin.backend.system.github.GitHub;
|
||||
import funkin.backend.system.github.GitHubRelease;
|
||||
#if ALLOW_MULTITHREADING
|
||||
import funkin.backend.utils.ThreadUtil;
|
||||
#end
|
||||
|
||||
import lime.app.Application;
|
||||
|
||||
import sys.thread.Mutex;
|
||||
import sys.thread.Thread;
|
||||
import sys.FileSystem;
|
||||
|
||||
import haxe.io.Path;
|
||||
|
||||
#if (target.threaded)
|
||||
import sys.thread.Thread;
|
||||
import sys.thread.Mutex;
|
||||
#end
|
||||
|
||||
using funkin.backend.system.github.GitHub;
|
||||
|
||||
class UpdateUtil {
|
||||
public static var lastUpdateCheck:Null<UpdateCheckCallback>;
|
||||
|
||||
#if (target.threaded)
|
||||
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
|
||||
private static var __mutex:Mutex;
|
||||
#end
|
||||
|
||||
public static function init() {
|
||||
// deletes old bak file if it exists
|
||||
@@ -34,34 +26,26 @@ class UpdateUtil {
|
||||
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
|
||||
#end
|
||||
|
||||
#if (target.threaded)
|
||||
__waitCallbacks = [];
|
||||
__mutex = new Mutex();
|
||||
|
||||
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(true, false));
|
||||
#end
|
||||
Thread.create(checkForUpdates.bind(true, false));
|
||||
}
|
||||
|
||||
public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) {
|
||||
#if (target.threaded)
|
||||
if (__mutex.tryAcquire()) {
|
||||
__mutex.release();
|
||||
if (__shouldCheck(lazy) || force) {
|
||||
__waitCallbacks.push(callback);
|
||||
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(force, false));
|
||||
Thread.create(checkForUpdates.bind(force, false));
|
||||
}
|
||||
else
|
||||
callback(lastUpdateCheck);
|
||||
}
|
||||
else
|
||||
__waitCallbacks.push(callback);
|
||||
#else
|
||||
callback(checkForUpdates(true, false));
|
||||
#end
|
||||
}
|
||||
|
||||
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
|
||||
#if (target.threaded)
|
||||
var wasAcquired = !__mutex.tryAcquire();
|
||||
if (wasAcquired) __mutex.acquire();
|
||||
|
||||
@@ -76,19 +60,8 @@ class UpdateUtil {
|
||||
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
|
||||
|
||||
return lastUpdateCheck;
|
||||
#else
|
||||
if (!__shouldCheck(lazy)) return lastUpdateCheck;
|
||||
return lastUpdateCheck = __checkForUpdates();
|
||||
#end
|
||||
}
|
||||
|
||||
#if (target.threaded)
|
||||
static function __callWaitCallbacks() {
|
||||
for (callback in __waitCallbacks) callback(lastUpdateCheck);
|
||||
__waitCallbacks.resize(0);
|
||||
}
|
||||
#end
|
||||
|
||||
static function __checkForUpdates():UpdateCheckCallback {
|
||||
var curTag = 'v' + (Flags.VERSION == null ? Application.current.meta.get('version') : Flags.VERSION), error = false;
|
||||
var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_OWNER, Flags.REPO_NAME, (e) -> {
|
||||
@@ -109,6 +82,11 @@ class UpdateUtil {
|
||||
static function __shouldCheck(lazy:Bool):Bool
|
||||
return lastUpdateCheck == null || !lazy && (!lastUpdateCheck.newUpdate || Date.now().getTime() - lastUpdateCheck.date.getTime() > 1800000);
|
||||
|
||||
static function __callWaitCallbacks() {
|
||||
for (callback in __waitCallbacks) callback(lastUpdateCheck);
|
||||
__waitCallbacks.resize(0);
|
||||
}
|
||||
|
||||
static function __doReleaseFiltering(releases:Array<GitHubRelease>, currentVersionTag:String) {
|
||||
releases = releases.filterReleases(Options.betaUpdates, false);
|
||||
if (releases.length <= 0)
|
||||
|
||||
@@ -20,7 +20,8 @@ typedef AudioAnalyzerCallback = Int->Int->Void;
|
||||
* An utility that analyze FlxSounds,
|
||||
* can be used to make waveform or real-time audio visualizer.
|
||||
*
|
||||
* FlxSound.amplitude works so if any case if your only checking for peak of current time, use that instead.
|
||||
* FlxSound.amplitude does work in CNE so if any case if your only checking for peak of current
|
||||
* time, use that instead.
|
||||
*/
|
||||
final class AudioAnalyzer {
|
||||
/**
|
||||
@@ -95,9 +96,9 @@ final class AudioAnalyzer {
|
||||
static var __twiddleImags:Array<Array<Float>> = [];
|
||||
static var __freqReals:Array<Array<Float>> = [];
|
||||
static var __freqImags:Array<Array<Float>> = [];
|
||||
static var __freqCalculating:Int = 0;
|
||||
#if (target.threaded)
|
||||
static var __mutex:Mutex = new Mutex();
|
||||
static var __freqCalculating:Int = 0;
|
||||
#end
|
||||
|
||||
/**
|
||||
@@ -295,7 +296,7 @@ final class AudioAnalyzer {
|
||||
__check();
|
||||
}
|
||||
|
||||
function __check() if (sound != null && sound.buffer != buffer) {
|
||||
function __check() if (sound.buffer != buffer) {
|
||||
byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1);
|
||||
|
||||
#if (lime_cffi && lime_vorbis)
|
||||
@@ -323,7 +324,7 @@ final class AudioAnalyzer {
|
||||
* @param maxFreq The maximum frequency to cap (Optional, default 22000.0, Above 23000.0 is not recommended).
|
||||
* @return Output of levels/bars that ranges from 0 to 1.
|
||||
*/
|
||||
public function getLevels(?startPos:Float, ?volume:Float, barCount:Int, ?levels:Array<Float>, ?ratio:Float, ?minDb:Float, ?maxDb:Float, ?minFreq:Float, ?maxFreq:Float):Array<Float>
|
||||
public function getLevels(startPos:Float, ?volume:Float, barCount:Int, ?levels:Array<Float>, ?ratio:Float, ?minDb:Float, ?maxDb:Float, ?minFreq:Float, ?maxFreq:Float):Array<Float>
|
||||
return inline getLevelsFromFrequencies(__frequencies = getFrequencies(startPos, volume, __frequencies), buffer.sampleRate, barCount, levels, ratio, minDb, maxDb, minFreq, maxFreq);
|
||||
|
||||
/**
|
||||
@@ -333,8 +334,8 @@ final class AudioAnalyzer {
|
||||
* @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
|
||||
* @return Output of frequencies.
|
||||
*/
|
||||
public function getFrequencies(?startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float>
|
||||
return inline getFrequenciesFromSamples(__freqSamples = getSamples(startPos != null ? startPos : sound.time, fftN, true, -1, volume, __freqSamples), fftN, useWindowingFFT, frequencies);
|
||||
public function getFrequencies(startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float>
|
||||
return inline getFrequenciesFromSamples(__freqSamples = getSamples(startPos, fftN, true, -1, volume, __freqSamples), fftN, useWindowingFFT, frequencies);
|
||||
|
||||
/**
|
||||
* Analyzes an attached FlxSound from startPos to endPos in milliseconds to get the amplitudes.
|
||||
@@ -466,37 +467,36 @@ final class AudioAnalyzer {
|
||||
@:privateAccess return sound._source != null && sound._source.__backend != null && sound._source.__backend.playing;
|
||||
|
||||
inline function __readStream(startPos:Float, endPos:Float, callback:AudioAnalyzerCallback):Float @:privateAccess {
|
||||
final backend = sound._source.__backend;
|
||||
var backend = sound._source.__backend;
|
||||
var i = backend.bufferSizes.length - backend.queuedBuffers;
|
||||
var time = backend.bufferTimes[i] * 1000;
|
||||
|
||||
// TODO: Wrap it with try until i figured it out an effective way to do this...
|
||||
// So... sometimes it just uses the decoder even if it looks good?? please help
|
||||
var n = Math.floor((endPos - startPos) * __toBits);
|
||||
var i = backend.bufferLengths.length - backend.requestBuffers - 1, time:Float;
|
||||
while (++i < backend.bufferLengths.length) if (startPos >= (time = backend.bufferTimes[i] * 1000)) {
|
||||
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferLengths[i], c = 0;
|
||||
if (startPos >= time && startPos < backend.bufferTimes[backend.bufferSizes.length - 1] * 1000) {
|
||||
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferSizes[i], c = 0;
|
||||
while (pos >= size) {
|
||||
if (++i >= backend.bufferLengths.length) break;
|
||||
if (++i >= backend.bufferSizes.length) {
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
pos -= size;
|
||||
buf = backend.bufferDatas[i].buffer;
|
||||
size = backend.bufferLengths[i];
|
||||
size = backend.bufferSizes[i];
|
||||
}
|
||||
if (i >= backend.bufferLengths.length) break;
|
||||
if ((pos -= pos % __sampleSize) < 0) pos = 0;
|
||||
pos -= pos % __sampleSize;
|
||||
n -= pos % __sampleSize;
|
||||
|
||||
while (n > 0) {
|
||||
callback(getByte(buf, pos, __wordSize), c);
|
||||
if (++c > buffer.channels) c = 0;
|
||||
if ((pos += __wordSize) >= size) {
|
||||
if (++i >= backend.bufferLengths.length) break;
|
||||
if (++i >= backend.bufferSizes.length) break;
|
||||
pos = 0;
|
||||
buf = backend.bufferDatas[i].buffer;
|
||||
size = backend.bufferLengths[i];
|
||||
size = backend.bufferSizes[i];
|
||||
}
|
||||
n -= __wordSize;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return endPos - (n / __toBits);
|
||||
|
||||
@@ -21,6 +21,7 @@ import flixel.util.FlxAxes;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.typeLimit.OneOfThree;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import flxanimate.data.AnimationData.AnimAtlas;
|
||||
import funkin.backend.system.Conductor;
|
||||
import funkin.backend.utils.XMLUtil.TextFormat;
|
||||
import haxe.CallStack;
|
||||
@@ -33,8 +34,6 @@ import haxe.xml.Access;
|
||||
import lime.utils.Assets;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.geom.ColorTransform;
|
||||
import animate.FlxAnimateJson;
|
||||
import flixel.animation.FlxAnimationController;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -575,29 +574,6 @@ final class CoolUtil
|
||||
anim2.frames = old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps two animations on an animation controller.
|
||||
* @param animation Animation controller
|
||||
* @param anim1 First animation
|
||||
* @param anim2 Second animation
|
||||
*/
|
||||
public static function swapAnims(animation:FlxAnimationController, anim1:String, anim2:String) @:privateAccess {
|
||||
var flxAnim1 = animation.getByName(anim1);
|
||||
animation._animations.remove(anim1);
|
||||
|
||||
var flxAnim2 = animation.getByName(anim2);
|
||||
animation._animations.remove(anim2);
|
||||
|
||||
if (flxAnim1 != null) {
|
||||
flxAnim1.name = anim2;
|
||||
animation._animations.set(anim2, flxAnim1);
|
||||
}
|
||||
if (flxAnim2 != null) {
|
||||
flxAnim2.name = anim1;
|
||||
animation._animations.set(anim1, flxAnim2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to set a graphic size (ex: 150x150), with proper hitbox without a stretched sprite.
|
||||
* @param sprite Sprite to apply the new graphic size to
|
||||
@@ -1276,20 +1252,23 @@ final class CoolUtil
|
||||
return animsList;
|
||||
}
|
||||
|
||||
public static function getAnimsListFromAtlas(atlas:AnimationJson):Array<String> {
|
||||
public static function getAnimsListFromAtlas(atlas:AnimAtlas):Array<String> {
|
||||
if (atlas == null) return [];
|
||||
|
||||
var animsList:Array<String> = [];
|
||||
if (atlas.AN.SN != null) animsList.push(atlas.AN.SN);
|
||||
if (atlas.SD != null)
|
||||
for (symbol in atlas.SD)
|
||||
for (symbol in atlas.SD.S)
|
||||
if (symbol.SN != null) animsList.push(symbol.SN);
|
||||
|
||||
return animsList;
|
||||
}
|
||||
|
||||
public static function getAnimsListFromSprite(spr:FunkinSprite):Array<String> {
|
||||
return getAnimsListFromFrames(spr.frames);
|
||||
if (spr.animateAtlas != null) {
|
||||
return [for (symbol => timeline in spr.animateAtlas.anim.symbolDictionary) symbol];
|
||||
} else
|
||||
return getAnimsListFromFrames(spr.frames);
|
||||
}
|
||||
|
||||
// TODO: check this for bugs
|
||||
|
||||
@@ -38,7 +38,7 @@ class FunkinParentDisabler extends FlxBasic {
|
||||
for(c in __cameras) c.paused = true;
|
||||
|
||||
// sounds
|
||||
__sounds = [for(s in FlxG.sound.list) if (s.playing && !s.persist) s];
|
||||
__sounds = [for(s in FlxG.sound.list) if (s.playing) s];
|
||||
for(s in __sounds) s.pause();
|
||||
}
|
||||
}
|
||||
@@ -71,4 +71,4 @@ class FunkinParentDisabler extends FlxBasic {
|
||||
for(s in __sounds) s.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,23 +34,151 @@ final class MatrixUtil {
|
||||
//if(_height == -1) _height = sprite.height;
|
||||
if(camera == null) camera = sprite.camera;
|
||||
if(points is FlxBasePoint) points = [points];
|
||||
var isFunkinSprite = sprite is FunkinSprite;
|
||||
var funkinSprite:FunkinSprite = null;
|
||||
if(isFunkinSprite) funkinSprite = cast sprite;
|
||||
var isAnimateAtlas = isFunkinSprite && funkinSprite.animateAtlas != null;
|
||||
|
||||
var nc:FakeCamera = FakeCamera.instance;
|
||||
var nc:FakeCamera = isAnimateAtlas ? FakeCallCamera.instance : FakeCamera.instance;
|
||||
nc.zoom = camera.zoom;
|
||||
nc.scroll.set(camera.scroll.x, camera.scroll.y);
|
||||
nc.pixelPerfectRender = camera.pixelPerfectRender;
|
||||
|
||||
var points:Array<FlxPoint> = cast points;
|
||||
|
||||
if(sprite is IPrePostDraw) {
|
||||
var postDraw = cast(sprite, IPrePostDraw);
|
||||
postDraw.preDraw();
|
||||
sprite.drawComplex(nc);
|
||||
postDraw.postDraw();
|
||||
if(isAnimateAtlas) {
|
||||
var cnc = FakeCallCamera.instance;
|
||||
var sprite = funkinSprite;
|
||||
var oldOnDraw = cnc.onDraw;
|
||||
|
||||
// TODO: fix rotation
|
||||
// TODO: fix skew
|
||||
|
||||
var boundsTopLeft = new FlxPoint(Math.POSITIVE_INFINITY, Math.POSITIVE_INFINITY);
|
||||
var boundsTopRight = new FlxPoint(Math.NEGATIVE_INFINITY, Math.POSITIVE_INFINITY);
|
||||
var boundsBottomLeft = new FlxPoint(Math.POSITIVE_INFINITY, Math.NEGATIVE_INFINITY);
|
||||
var boundsBottomRight = new FlxPoint(Math.NEGATIVE_INFINITY, Math.NEGATIVE_INFINITY);
|
||||
|
||||
cnc.onDraw = function(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false, ?shader:FlxShader) {
|
||||
// cnc is already perfect rn
|
||||
// so we need to manually process the limb
|
||||
var points = [
|
||||
// corners
|
||||
FlxPoint.get(0, 0),
|
||||
FlxPoint.get(1, 0),
|
||||
FlxPoint.get(0, 1),
|
||||
FlxPoint.get(1, 1)
|
||||
];
|
||||
|
||||
rawTransformPoints(points, matrix, frame.sourceSize.x, frame.sourceSize.y);
|
||||
|
||||
// sort the points, incase like they were transformed with a scale -1 matrix
|
||||
|
||||
var topLeft:FlxPoint = points[0];
|
||||
var topRight:FlxPoint = points[1];
|
||||
var bottomLeft:FlxPoint = points[2];
|
||||
var bottomRight:FlxPoint = points[3];
|
||||
|
||||
if (points[0].y > points[1].y) {
|
||||
topLeft = points[1];
|
||||
topRight = points[0];
|
||||
}
|
||||
if (points[2].y > points[3].y) {
|
||||
bottomLeft = points[3];
|
||||
bottomRight = points[2];
|
||||
}
|
||||
|
||||
if (topLeft.x > topRight.x) {
|
||||
var temp = topLeft;
|
||||
topLeft = topRight;
|
||||
topRight = temp;
|
||||
}
|
||||
|
||||
if (bottomLeft.x > bottomRight.x) {
|
||||
var temp = bottomLeft;
|
||||
bottomLeft = bottomRight;
|
||||
bottomRight = temp;
|
||||
}
|
||||
|
||||
// points should now contain the corners of the limb
|
||||
|
||||
// trace("Corners of limb: " + points);
|
||||
|
||||
// set the max bounds of each corner of the limb
|
||||
if(topLeft.x < boundsTopLeft.x) boundsTopLeft.x = topLeft.x;
|
||||
if(topLeft.y < boundsTopLeft.y) boundsTopLeft.y = topLeft.y;
|
||||
if(topRight.x > boundsTopRight.x) boundsTopRight.x = topRight.x;
|
||||
if(topRight.y < boundsTopRight.y) boundsTopRight.y = topRight.y;
|
||||
if(bottomLeft.x < boundsBottomLeft.x) boundsBottomLeft.x = bottomLeft.x;
|
||||
if(bottomLeft.y > boundsBottomLeft.y) boundsBottomLeft.y = bottomLeft.y;
|
||||
if(bottomRight.x > boundsBottomRight.x) boundsBottomRight.x = bottomRight.x;
|
||||
if(bottomRight.y > boundsBottomRight.y) boundsBottomRight.y = bottomRight.y;
|
||||
|
||||
// recycle the points
|
||||
for(point in points) point.put();
|
||||
}
|
||||
var cameras = sprite._cameras;
|
||||
var oldVisible = cnc.visible;
|
||||
cnc.visible = true;
|
||||
sprite._cameras = [cnc];
|
||||
sprite.draw();
|
||||
sprite._cameras = cameras;
|
||||
cnc.visible = oldVisible;
|
||||
cnc.onDraw = oldOnDraw;
|
||||
|
||||
// fake transform
|
||||
|
||||
//trace("");
|
||||
//trace("topLeft: " + boundsTopLeft);
|
||||
//trace("topRight: " + boundsTopRight);
|
||||
//trace("bottomLeft: " + boundsBottomLeft);
|
||||
//trace("bottomRight: " + boundsBottomRight);
|
||||
//trace("Before transform");
|
||||
//trace(points);
|
||||
|
||||
for(point in points) {
|
||||
//var x = matrix.__transformX(point.x * _width, point.y * _height);
|
||||
//var y = matrix.__transformY(point.x * _width, point.y * _height);
|
||||
// apply using boundsTopLeft, boundsTopRight, boundsBottomLeft, boundsBottomRight
|
||||
// matrix doesnt work for this
|
||||
var x = FlxMath.lerp(
|
||||
FlxMath.lerp(boundsTopLeft.x, boundsTopRight.x, point.x),
|
||||
FlxMath.lerp(boundsBottomLeft.x, boundsBottomRight.x, point.x),
|
||||
point.y
|
||||
);
|
||||
var y = FlxMath.lerp(
|
||||
FlxMath.lerp(boundsTopLeft.y, boundsTopRight.y, point.x),
|
||||
FlxMath.lerp(boundsBottomLeft.y, boundsBottomRight.y, point.x),
|
||||
point.y
|
||||
);
|
||||
|
||||
//trace("(" + point.x + ", " + point.y + ") -> (" + x + ", " + y + ")");
|
||||
|
||||
// reset to ingame coords
|
||||
x += camera.scroll.x;
|
||||
y += camera.scroll.y;
|
||||
|
||||
if(isFunkinSprite) {
|
||||
var ratio = 1 - FlxMath.lerp(1 / camera.zoom, 1, funkinSprite.zoomFactor);
|
||||
x += camera.width / 2 * ratio;
|
||||
y += camera.height / 2 * ratio;
|
||||
}
|
||||
point.set(x, y);
|
||||
}
|
||||
|
||||
//trace("After transform");
|
||||
//trace(points);
|
||||
} else {
|
||||
sprite.drawComplex(nc);
|
||||
if(sprite is IPrePostDraw) {
|
||||
var postDraw = cast(sprite, IPrePostDraw);
|
||||
postDraw.preDraw();
|
||||
sprite.drawComplex(nc);
|
||||
postDraw.postDraw();
|
||||
} else {
|
||||
sprite.drawComplex(nc);
|
||||
}
|
||||
transformPoints(sprite, points, sprite._matrix, camera, _width, _height);
|
||||
}
|
||||
transformPoints(sprite, points, sprite._matrix, camera, _width, _height);
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
@@ -1,97 +1,32 @@
|
||||
package funkin.backend.utils;
|
||||
|
||||
#if (target.threaded)
|
||||
import sys.thread.Deque;
|
||||
import sys.thread.Thread;
|
||||
import sys.thread.Mutex;
|
||||
#else
|
||||
private typedef Thread = Dynamic;
|
||||
#end
|
||||
|
||||
#if !macro
|
||||
import funkin.backend.system.Logs;
|
||||
#end
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
final class ThreadUtil {
|
||||
inline static function error(text:String) {
|
||||
#if macro
|
||||
trace(text);
|
||||
#else
|
||||
FlxG.signals.preUpdate.addOnce(Logs.error.bind(text));
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Thread with an error handler.
|
||||
* @param func Function to execute
|
||||
* @param autoRestart Whenever the thread should auto restart itself after crashing.
|
||||
*/
|
||||
public static function createSafe(func:Void->Void, autoRestart:Bool = false):Thread {
|
||||
#if (target.threaded)
|
||||
try {
|
||||
return if (autoRestart) Thread.create(() -> {
|
||||
var restart = true;
|
||||
while (restart) try {
|
||||
public static function createSafe(func:Void->Void, autoRestart:Bool = false) {
|
||||
if (autoRestart) {
|
||||
return sys.thread.Thread.create(function() {
|
||||
while(true) {
|
||||
try {
|
||||
func();
|
||||
} catch(e) {
|
||||
trace(e.details());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return sys.thread.Thread.create(function() {
|
||||
try {
|
||||
func();
|
||||
restart = false;
|
||||
} catch(e) {
|
||||
trace(e.details());
|
||||
}
|
||||
catch (e) error(e.details());
|
||||
})
|
||||
else Thread.create(() -> {
|
||||
try {func();}
|
||||
catch (e) error(e.details());
|
||||
});
|
||||
}
|
||||
catch (e) error("Failed to safely create a thread: " + e.details());
|
||||
#end
|
||||
return null;
|
||||
}
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
public static var maxThreads:Int = 4;
|
||||
|
||||
static var __threads:Array<Thread> = [];
|
||||
static var __pendingExecs:Deque<Void->Void> = new Deque();
|
||||
static var __threadMutex:Mutex = new Mutex();
|
||||
static var __threadUsed:Int = 0;
|
||||
|
||||
static function __threadExecAsync() {
|
||||
var callback:Void->Void;
|
||||
while ((callback = __pendingExecs.pop(true)) != null) {
|
||||
__threadMutex.acquire();
|
||||
__threadUsed++;
|
||||
__threadMutex.release();
|
||||
|
||||
callback();
|
||||
|
||||
__threadMutex.acquire();
|
||||
__threadUsed--;
|
||||
__threadMutex.release();
|
||||
}
|
||||
__threadMutex.acquire();
|
||||
__threads.remove(Thread.current());
|
||||
__threadMutex.release();
|
||||
}
|
||||
#end
|
||||
|
||||
public static function execAsync(func:Void->Void) {
|
||||
if (func == null) return;
|
||||
|
||||
#if (ALLOW_MULTITHREADING && !macro)
|
||||
__pendingExecs.add(func);
|
||||
if (__threadUsed >= __threads.length) {
|
||||
if (__threads.length == maxThreads) return;
|
||||
|
||||
__threadMutex.acquire();
|
||||
try {
|
||||
var thread = Thread.create(__threadExecAsync);
|
||||
__threads.push(thread);
|
||||
}
|
||||
catch (e) Logs.warn(e.details());
|
||||
__threadMutex.release();
|
||||
}
|
||||
#else
|
||||
func();
|
||||
#end
|
||||
}
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -14,7 +14,6 @@ import funkin.backend.scripting.ScriptPack;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import funkin.backend.system.interfaces.IOffsetCompatible;
|
||||
import haxe.xml.Access;
|
||||
import animate.FlxAnimateFrames;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -128,9 +127,6 @@ final class XMLUtil {
|
||||
spr.spriteAnimType = XMLAnimType.fromString(node.att.type, spr.spriteAnimType);
|
||||
}
|
||||
|
||||
if (node.has.applyStageMatrix) spr.applyStageMatrix = node.att.applyStageMatrix == "true";
|
||||
if (node.has.useRenderTexture) spr.useRenderTexture = node.att.useRenderTexture == "true";
|
||||
|
||||
if(node.has.x) {
|
||||
var x:Null<Float> = Std.parseFloat(node.att.x);
|
||||
if (x.isNotNull()) spr.x = x;
|
||||
@@ -229,8 +225,7 @@ final class XMLUtil {
|
||||
animType: spr.spriteAnimType,
|
||||
x: 0,
|
||||
y: 0,
|
||||
indices: [for(i in 0...spr.frames.frames.length) i],
|
||||
label: false
|
||||
indices: [for(i in 0...spr.frames.frames.length) i]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -266,8 +261,7 @@ final class XMLUtil {
|
||||
animType: animType,
|
||||
x: 0,
|
||||
y: 0,
|
||||
indices: [],
|
||||
label: false
|
||||
indices: []
|
||||
};
|
||||
|
||||
if (anim.has.name) animData.name = anim.att.name;
|
||||
@@ -279,7 +273,6 @@ final class XMLUtil {
|
||||
if (anim.has.loop) animData.loop = anim.att.loop == "true";
|
||||
if (anim.has.forced) animData.forced = anim.att.forced == "true";
|
||||
if (anim.has.indices) animData.indices = CoolUtil.parseNumberRange(anim.att.indices);
|
||||
if (anim.has.label) animData.label = anim.att.label == "true";
|
||||
|
||||
return animData;
|
||||
}
|
||||
@@ -306,23 +299,15 @@ final class XMLUtil {
|
||||
if (animData.name != null) {
|
||||
if (animData.fps <= 0 #if web || animData.fps == null #end) animData.fps = 24;
|
||||
|
||||
if (sprite.frames is FlxAnimateFrames) {
|
||||
if (sprite is FunkinSprite && cast(sprite, FunkinSprite).animateAtlas != null) {
|
||||
var animateAnim = cast(sprite, FunkinSprite).animateAtlas.anim;
|
||||
if(animData.anim == null)
|
||||
return MISSING_PROPERTY;
|
||||
|
||||
var animateAnim = cast(sprite, FunkinSprite).anim;
|
||||
|
||||
if (animData.label) {
|
||||
if (animData.indices != null && animData.indices.length > 0)
|
||||
animateAnim.addByFrameLabelIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
|
||||
else
|
||||
animateAnim.addByFrameLabel(animData.name, animData.anim, animData.fps, animData.loop);
|
||||
} else {
|
||||
if (animData.indices != null && animData.indices.length > 0)
|
||||
animateAnim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
|
||||
else
|
||||
animateAnim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop);
|
||||
}
|
||||
if (animData.indices != null && animData.indices.length > 0)
|
||||
animateAnim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
|
||||
else
|
||||
animateAnim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop);
|
||||
} else {
|
||||
if (animData.indices != null && animData.indices.length > 0) {
|
||||
if (animData.anim == null)
|
||||
@@ -478,7 +463,6 @@ typedef AnimData = {
|
||||
var y:Float;
|
||||
var indices:Array<Int>;
|
||||
var animType:XMLAnimType;
|
||||
var label:Bool;
|
||||
var ?forced:Bool;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,9 +204,6 @@ final class Windows {
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
|
||||
SetConsoleOutputCP(65001);
|
||||
SetConsoleCP(65001);
|
||||
')
|
||||
public static function allocConsole() {
|
||||
}
|
||||
|
||||
@@ -41,8 +41,7 @@ class Week {
|
||||
weekObj.songs.push({
|
||||
name: name,
|
||||
hide: song.getAtt('hide').getDefault('false') == "true",
|
||||
displayName: song.getAtt('displayName'),
|
||||
variation: song.getAtt('variation')
|
||||
displayName: song.getAtt('displayName')
|
||||
});
|
||||
} catch(e) {
|
||||
Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING);
|
||||
|
||||
@@ -9,7 +9,7 @@ class ModConfigWarning extends UIState {
|
||||
var library:ModsFolderLibrary = null;
|
||||
var goToState:Class<FlxState>;
|
||||
|
||||
public static var defaultModConfigText =
|
||||
public static inline var defaultModConfigText =
|
||||
'[Common] # This section applies the \'MOD_\' prefix to the flags so you don\'t have to.
|
||||
NAME="YOUR MOD NAME HERE"
|
||||
DESCRIPTION="YOUR MOD DESCRIPTION HERE"
|
||||
@@ -17,7 +17,7 @@ AUTHOR="YOU/YOUR TEAM HERE"
|
||||
VERSION="YOUR MOD\'S VERSION HERE"
|
||||
|
||||
# DO NOT EDIT!! this is used to check for version compatibility!
|
||||
API_VERSION=${Flags.CURRENT_API_VERSION}
|
||||
API_VERSION=1
|
||||
|
||||
DOWNLOAD_LINK="YOUR MOD PAGE LINK HERE"
|
||||
|
||||
|
||||
@@ -2,13 +2,18 @@ package funkin.editors.character;
|
||||
|
||||
import flixel.text.FlxText.FlxTextFormat;
|
||||
import flixel.text.FlxText.FlxTextFormatMarkerPair;
|
||||
import flxanimate.animate.FlxAnim.FlxSymbolAnimation;
|
||||
import flxanimate.animate.FlxSymbol;
|
||||
import flxanimate.animate.FlxElement;
|
||||
import flxanimate.animate.SymbolParameters;
|
||||
import flxanimate.animate.FlxKeyFrame;
|
||||
import flxanimate.animate.FlxTimeline;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import openfl.geom.Rectangle;
|
||||
import funkin.backend.utils.XMLUtil.AnimData;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.editors.character.CharacterAnimsWindow;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -21,7 +26,6 @@ class CharacterAnimButton extends UIButton {
|
||||
public var animationDisplayBG:UISliceSprite;
|
||||
public var nameTextBox:UITextBox;
|
||||
public var animTextBox:UIAutoCompleteTextBox;
|
||||
public var animLabelCheckbox:UICheckbox;
|
||||
public var positionXStepper:UINumericStepper;
|
||||
public var positionYStepper:UINumericStepper;
|
||||
public var fpsStepper:UINumericStepper;
|
||||
@@ -112,20 +116,13 @@ class CharacterAnimButton extends UIButton {
|
||||
foldableButtons.push(fpsStepper);
|
||||
addLabelOn(fpsStepper, translate("fps"), 12);
|
||||
|
||||
loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, translate("looping"), animData.loop, 0, true);
|
||||
loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, "Looping?", animData.loop, 0, true);
|
||||
loopedCheckbox.onChecked = (newLooping:Bool) -> {this.changeLooping(newLooping);};
|
||||
members.push(loopedCheckbox);
|
||||
foldableButtons.push(loopedCheckbox);
|
||||
|
||||
loopedCheckbox.x += 8; loopedCheckbox.y += 6;
|
||||
|
||||
if (parent.character.isAnimate) {
|
||||
animLabelCheckbox = new UICheckbox(loopedCheckbox.x, animTextBox.y + 26, translate("label"), animData.label, 0, true);
|
||||
animLabelCheckbox.onChecked = (newLabel:Bool) -> {this.changeLabel(newLabel);};
|
||||
members.push(animLabelCheckbox);
|
||||
foldableButtons.push(animLabelCheckbox);
|
||||
}
|
||||
|
||||
indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y, CoolUtil.formatNumberRange(animData.indices.getDefault([]), ", "), 278, 22, false, true);
|
||||
indicesTextBox.onChange = (text:String) -> {
|
||||
this.changeIndicies(CoolUtil.parseNumberRange(text));
|
||||
@@ -207,7 +204,6 @@ class CharacterAnimButton extends UIButton {
|
||||
|
||||
fpsStepper.follow(this, 282, 118);
|
||||
loopedCheckbox.follow(this, 336, 122);
|
||||
animLabelCheckbox?.follow(this, 336, 98);
|
||||
|
||||
indicesTextBox.follow(this, 158, 164);
|
||||
|
||||
@@ -235,12 +231,18 @@ class CharacterAnimButton extends UIButton {
|
||||
}
|
||||
|
||||
var oldName:String = anim;
|
||||
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.name = newName;
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
|
||||
|
||||
parent.character.animation._animations.remove(anim);
|
||||
parent.character.animation._animations.set(newName, flxAnimation);
|
||||
parent.character.animateAtlas.anim.animsMap.remove(anim);
|
||||
parent.character.animateAtlas.anim.animsMap.set(newName, animSymbol);
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.name = newName;
|
||||
|
||||
parent.character.animation._animations.remove(anim);
|
||||
parent.character.animation._animations.set(newName, flxAnimation);
|
||||
}
|
||||
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
animData.name = newName;
|
||||
@@ -252,7 +254,7 @@ class CharacterAnimButton extends UIButton {
|
||||
parent.character.animOffsets.remove(anim);
|
||||
parent.character.animOffsets.set(newName, animOffset);
|
||||
|
||||
var displayFrame:DisplayAnimFrameEntry = parent.displayAnimsFramesList[anim];
|
||||
var displayFrame:{scale:Float, animBounds:Rectangle, frame:Int} = parent.displayAnimsFramesList[anim];
|
||||
parent.displayAnimsFramesList.remove(anim);
|
||||
parent.displayAnimsFramesList.set(newName, displayFrame);
|
||||
|
||||
@@ -274,20 +276,23 @@ class CharacterAnimButton extends UIButton {
|
||||
var oldAnim:String = animData.anim;
|
||||
animData.anim = newAnim;
|
||||
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.prefix = newAnim;
|
||||
if (parent.character.animateAtlas != null)
|
||||
__refreshAnimation();
|
||||
else {
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.prefix = newAnim;
|
||||
|
||||
refreshAnimation(__getFlxAnimation(), data);
|
||||
refreshFlxAnimationFrames(flxAnimation, animData);
|
||||
|
||||
if (valid) {
|
||||
parent.buildAnimDisplay(anim, data);
|
||||
animationDisplayBG.alpha = 1;
|
||||
} else {
|
||||
parent.removeAnimDisplay(anim);
|
||||
animationDisplayBG.alpha = 0.4;
|
||||
if (valid) {
|
||||
parent.buildAnimDisplay(anim, data);
|
||||
animationDisplayBG.alpha = 1;
|
||||
} else {
|
||||
parent.removeAnimDisplay(anim);
|
||||
animationDisplayBG.alpha = 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
|
||||
@@ -325,8 +330,13 @@ class CharacterAnimButton extends UIButton {
|
||||
var oldFPS:Float = animData.fps;
|
||||
animData.fps = newFPS;
|
||||
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.frameRate = newFPS;
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
|
||||
animSymbol.frameRate = newFPS;
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.frameRate = newFPS;
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
@@ -341,8 +351,13 @@ class CharacterAnimButton extends UIButton {
|
||||
|
||||
animData.loop = newLooping;
|
||||
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.looped = animData.loop;
|
||||
if (parent.character.animateAtlas != null) {
|
||||
var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
|
||||
animSymbol.instance.symbol.loop = animData.loop ? Loop : PlayOnce;
|
||||
} else {
|
||||
var flxAnimation:FlxAnimation = __getFlxAnimation();
|
||||
flxAnimation.looped = animData.loop;
|
||||
}
|
||||
|
||||
if (parent.character.getAnimName() == anim)
|
||||
CharacterEditor.instance.playAnimation(anim);
|
||||
@@ -352,19 +367,6 @@ class CharacterAnimButton extends UIButton {
|
||||
if (addToUndo) CharacterEditor.undos.addToUndo(CAnimEditLooping(ID, newLooping));
|
||||
}
|
||||
|
||||
public function changeLabel(newLabel:Bool, addToUndo:Bool = true) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
|
||||
animData.label = newLabel;
|
||||
|
||||
if (animLabelCheckbox != null)
|
||||
animLabelCheckbox.checked = newLabel;
|
||||
|
||||
__refreshAnimation();
|
||||
|
||||
if (addToUndo) CharacterEditor.undos.addToUndo(CAnimEditLabel(ID, newLabel));
|
||||
}
|
||||
|
||||
public function changeIndicies(indicies:Array<Int>, addToUndo:Bool = true) @:privateAccess {
|
||||
var animData:AnimData = parent.character.animDatas[anim];
|
||||
var oldIndices:Array<Int> = animData.indices.copy();
|
||||
@@ -401,6 +403,50 @@ class CharacterAnimButton extends UIButton {
|
||||
CharacterEditor.undos.addToUndo(CAnimEditIndices(ID, oldIndices, indicies));
|
||||
}
|
||||
|
||||
|
||||
public inline function refreshFlxAnimationFrames(flxAnimation:FlxAnimation, animData:AnimData) @:privateAccess {
|
||||
try {
|
||||
if (animData.indices.length > 0) {
|
||||
var frameIndices:Array<Int> = new Array<Int>();
|
||||
parent.character.animation.byIndicesHelper(frameIndices, flxAnimation.prefix, animData.indices, "");
|
||||
|
||||
flxAnimation.frames = frameIndices;
|
||||
} else {
|
||||
final animFrames:Array<FlxFrame> = new Array<FlxFrame>();
|
||||
parent.character.animation.findByPrefix(animFrames, flxAnimation.prefix);
|
||||
|
||||
final frameIndices:Array<Int> = [];
|
||||
parent.character.animation.byPrefixHelper(frameIndices, animFrames, flxAnimation.prefix);
|
||||
|
||||
flxAnimation.frames = frameIndices;
|
||||
}
|
||||
|
||||
if (flxAnimation.frames.length <= 0) invalidate();
|
||||
else validate();
|
||||
} catch (e) {
|
||||
trace('ERROR REFRESHING FLXANIMATION FRAMES: $e');
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public inline function refreshSymbolKeyFrames(symbol:FlxSymbolAnimation, animData:AnimData) @:privateAccess {
|
||||
var wasRefreshed:Bool = false;
|
||||
|
||||
try {
|
||||
parent.character.animateAtlas.anim.animsMap.remove(animData.name);
|
||||
if (animData.indices.length > 0)
|
||||
parent.character.animateAtlas.anim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
|
||||
else
|
||||
parent.character.animateAtlas.anim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop);
|
||||
wasRefreshed = parent.character.animateAtlas.anim.animsMap.exists(animData.name);
|
||||
if (!wasRefreshed) __getAnimationSymbol();
|
||||
} catch (e) {
|
||||
trace('ERROR REFRESHING SYMBOL FRAMES: $e');
|
||||
}
|
||||
|
||||
validate(wasRefreshed);
|
||||
}
|
||||
|
||||
public function toggleGhost() {
|
||||
if (valid && parent.ghosts.indexOf(anim) == -1) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND));
|
||||
@@ -420,8 +466,8 @@ class CharacterAnimButton extends UIButton {
|
||||
super.draw();
|
||||
|
||||
if (!closed && parent.displayAnimsFramesList.exists(anim)) {
|
||||
var displayData:DisplayAnimFrameEntry = parent.displayAnimsFramesList.get(anim);
|
||||
parent.displayWindowSprite.frame = displayData.frame;
|
||||
var displayData:{frame:Int, scale:Float, animBounds:Rectangle} = parent.displayAnimsFramesList.get(anim);
|
||||
parent.displayWindowSprite.frame = parent.displayWindowSprite.frames.frames[displayData.frame];
|
||||
|
||||
parent.displayWindowSprite.scale.x = parent.displayWindowSprite.scale.y = displayData.scale;
|
||||
parent.displayWindowSprite.updateHitbox();
|
||||
@@ -475,26 +521,16 @@ class CharacterAnimButton extends UIButton {
|
||||
return parent.character.animation._animations[anim];
|
||||
}
|
||||
|
||||
public inline function refreshAnimation(anim:FlxAnimation, animData:AnimData) @:privateAccess {
|
||||
var refreshed:Bool = false;
|
||||
|
||||
parent.character.animation.remove(animData.name);
|
||||
parent.character.animation._curAnim = null;
|
||||
|
||||
XMLUtil.addAnimToSprite(parent.character, animData);
|
||||
|
||||
var anim = parent.character.animation.getByName(animData.name);
|
||||
|
||||
if (anim != null && anim.frames.length > 0) {
|
||||
validate();
|
||||
parent.character.animation.play(animData.name);
|
||||
}
|
||||
else
|
||||
invalidate();
|
||||
public inline function __getAnimationSymbol():Null<FlxSymbolAnimation> @:privateAccess {
|
||||
if (!parent.character.animateAtlas.anim.animsMap.exists(anim))
|
||||
XMLUtil.addAnimToSprite(parent.character, data);
|
||||
return parent.character.animateAtlas.anim.animsMap[anim];
|
||||
}
|
||||
|
||||
|
||||
@:noCompletion function __refreshAnimation() @:privateAccess {
|
||||
refreshAnimation(__getFlxAnimation(), data);
|
||||
if (parent.character.animateAtlas != null) refreshSymbolKeyFrames(__getAnimationSymbol(), data);
|
||||
else refreshFlxAnimationFrames(__getFlxAnimation(), data);
|
||||
|
||||
if (valid) {
|
||||
parent.buildAnimDisplay(anim, data);
|
||||
|
||||
@@ -8,24 +8,15 @@ import openfl.geom.Rectangle;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import funkin.game.Character;
|
||||
import flixel.animation.FlxPrerotatedAnimation;
|
||||
import animate.internal.RenderTexture;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import funkin.backend.system.Logs;
|
||||
|
||||
using funkin.backend.utils.BitmapUtil;
|
||||
|
||||
typedef DisplayAnimFrameEntry = {
|
||||
scale:Float,
|
||||
frame:FlxFrame,
|
||||
renderTexture:RenderTexture
|
||||
}
|
||||
|
||||
class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
public var character:CharacterGhost;
|
||||
|
||||
public var displayWindowSprite:FlxSprite;
|
||||
public var displayWindowGraphic:FlxGraphic;
|
||||
public var displayAnimsFramesList:Map<String, DisplayAnimFrameEntry> = [];
|
||||
public var displayAnimsFramesList:Map<String, {scale:Float, animBounds:Rectangle, frame:OneOfTwo<Int, String>}> = [];
|
||||
|
||||
public var animButtons:Map<String, CharacterAnimButton> = [];
|
||||
public var animsList:Array<String> = [];
|
||||
@@ -39,7 +30,7 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
|
||||
buttonCameras.pixelPerfectRender = true;
|
||||
|
||||
if (Assets.exists(Paths.image('characters/${character.sprite}')))
|
||||
if (Assets.exists(Paths.image('characters/${character.sprite}')) && character.animateAtlas == null)
|
||||
displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
|
||||
|
||||
displayWindowSprite = new FlxSprite();
|
||||
@@ -78,45 +69,34 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
}
|
||||
|
||||
public function buildAnimDisplay(name:String, anim:AnimData) @:privateAccess {
|
||||
var anim:FlxAnimation = character.animation._animations[anim.name];
|
||||
if (anim == null) return;
|
||||
if (character.animateAtlas == null) {
|
||||
var anim:FlxAnimation = character.animation._animations[anim.name];
|
||||
if (anim == null || anim.frames.length <= 0) return;
|
||||
|
||||
if (character.isAnimate) {
|
||||
var renderTex = character.generateRenderTextureForAnim(name);
|
||||
var frame = renderTex.graphic.imageFrame.frame;
|
||||
|
||||
displayAnimsFramesList.set(name, {
|
||||
frame: frame,
|
||||
scale: 104/Math.max(frame.frame.width, frame.frame.height),
|
||||
renderTexture: renderTex
|
||||
});
|
||||
} else {
|
||||
var frameIndex:Int = anim.frames.getDefault([0])[0];
|
||||
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex];
|
||||
|
||||
|
||||
var frameRect:Rectangle = new Rectangle(frame.offset.x, frame.offset.y, frame.sourceSize.x, frame.sourceSize.y);
|
||||
var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
|
||||
|
||||
displayAnimsFramesList.set(name, {
|
||||
frame: character.frames.frames[anim.frames.getDefault([0])[0]],
|
||||
scale: 104/Math.max(animBounds.width, animBounds.height),
|
||||
renderTexture: null
|
||||
});
|
||||
|
||||
displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/Math.max(animBounds.width, animBounds.height), animBounds: animBounds});
|
||||
} else {
|
||||
character.storeAtlasState();
|
||||
|
||||
/*
|
||||
character.animateAtlas.anim.play(anim.name, true, false, 0);
|
||||
character.animateAtlas.anim.stop();
|
||||
|
||||
var animBounds:Rectangle = MatrixUtil.getBounds(character).copyToFlash();
|
||||
displayAnimsFramesList.set(name, {frame: anim.anim, scale: 104/animBounds.height, animBounds: animBounds});
|
||||
*/
|
||||
|
||||
character.restoreAtlasState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function removeAnimDisplay(name:String) {
|
||||
if (displayAnimsFramesList.exists(name))
|
||||
displayAnimsFramesList[name].renderTexture?.destroy();
|
||||
public function removeAnimDisplay(name:String)
|
||||
displayAnimsFramesList.remove(name);
|
||||
}
|
||||
|
||||
public function clearDisplayAnims() {
|
||||
for(k=>e in displayAnimsFramesList)
|
||||
e.renderTexture?.destroy();
|
||||
displayAnimsFramesList.clear();
|
||||
}
|
||||
|
||||
public function deleteAnimation(button:CharacterAnimButton, addToUndo:Bool = true) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND));
|
||||
@@ -124,7 +104,6 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
if (character.getAnimName() == button.anim)
|
||||
@:privateAccess CharacterEditor.instance._animation_down(null);
|
||||
|
||||
character.ghosts.remove(button.anim);
|
||||
character.removeAnimation(button.anim);
|
||||
if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim);
|
||||
if (character.animDatas.exists(button.anim)) character.animDatas.remove(button.anim);
|
||||
@@ -154,7 +133,6 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
x: 0, y: 0,
|
||||
indices: [],
|
||||
animType: NONE,
|
||||
label: false
|
||||
};
|
||||
addAnimation(animData);
|
||||
}
|
||||
|
||||
@@ -554,9 +554,6 @@ class CharacterEditor extends UIState {
|
||||
case CAnimEditLooping(animID, newLooping):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeLooping(!newLooping, false);
|
||||
case CAnimEditLabel(animID, newLabel):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeLabel(!newLabel, false);
|
||||
case CAnimEditIndices(animID, oldIndicies, newIndicies):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeIndicies(oldIndicies, false);
|
||||
@@ -628,9 +625,6 @@ class CharacterEditor extends UIState {
|
||||
case CAnimEditLooping(animID, newLooping):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeLooping(newLooping, false);
|
||||
case CAnimEditLabel(animID, newLabel):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeLabel(newLabel, false);
|
||||
case CAnimEditIndices(animID, oldIndicies, newIndicies):
|
||||
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
|
||||
button.changeIndicies(newIndicies, false);
|
||||
@@ -942,7 +936,6 @@ enum CharacterEditorChange {
|
||||
CAnimEditFPS(animID:Int, oldFPS:Float, newFPS:Float);
|
||||
CAnimEditLooping(animID:Int, newLooping:Bool);
|
||||
CAnimEditIndices(animID:Int, oldIndicies:Array<Int>, newIndicies:Array<Int>);
|
||||
CAnimEditLabel(animID:Int, newLabel:Bool);
|
||||
|
||||
CCharClearOffsets(oldOffsets:Map<String, FlxPoint>);
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import funkin.backend.system.FakeCamera.FakeCallCamera;
|
||||
import openfl.geom.ColorTransform;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import funkin.game.Character;
|
||||
import haxe.xml.Access;
|
||||
import animate.internal.RenderTexture;
|
||||
|
||||
typedef AtlasState = {
|
||||
var oldAnim:String;
|
||||
@@ -16,35 +14,39 @@ typedef AtlasState = {
|
||||
|
||||
class CharacterGhost extends Character {
|
||||
public var ghosts:Array<String> = [];
|
||||
|
||||
|
||||
public override function buildCharacter(xml:Access) {
|
||||
useRenderTexture = true; // per request from maru heh, still overridable
|
||||
super.buildCharacter(xml);
|
||||
}
|
||||
|
||||
public override function draw() @:privateAccess {
|
||||
ghostDraw = FakeCallCamera.instance.ignoreDraws = true;
|
||||
|
||||
var wasInvalidFrame:Bool = !colorTransform.__isDefault(false);
|
||||
colorTransform.__identity();
|
||||
|
||||
var animName = animation.curAnim?.name ?? null;
|
||||
var animFrame = animation.curAnim?.curFrame ?? 0;
|
||||
var animFrameTimer = animation.curAnim?._frameTimer ?? 0;
|
||||
if (animateAtlas != null) {
|
||||
storeAtlasState();
|
||||
for (anim in ghosts) {
|
||||
animateAtlas.anim.play(anim, true, false, 0);
|
||||
setAnimOffset(anim);
|
||||
|
||||
for (anim in ghosts) @:privateAccess {
|
||||
alpha = 0.4; color = 0xFFAEAEAE;
|
||||
alpha = 0.4; color = 0xFFAEAEAE;
|
||||
super.draw();
|
||||
}
|
||||
|
||||
var flxanim:FlxAnimation = animation._animations.get(anim);
|
||||
animation.play(anim, true, false, flxanim.frames.length - 1);
|
||||
|
||||
setAnimOffset(anim);
|
||||
super.draw();
|
||||
if (ghosts.length > 0) restoreAtlasState();
|
||||
}
|
||||
else {
|
||||
for (anim in ghosts) @:privateAccess {
|
||||
alpha = 0.4; color = 0xFFAEAEAE;
|
||||
|
||||
var flxanim:FlxAnimation = animation._animations.get(anim);
|
||||
var frameIndex:Int = flxanim.frames.getDefault([0])[0];
|
||||
frame = frames.frames[frameIndex];
|
||||
|
||||
setAnimOffset(anim);
|
||||
super.draw();
|
||||
}
|
||||
|
||||
if (ghosts.length > 0)
|
||||
frame = frames.frames[animation.frameIndex];
|
||||
if (ghosts.length > 0)
|
||||
frame = frames.frames[animation.frameIndex];
|
||||
}
|
||||
ghostDraw = FakeCallCamera.instance.ignoreDraws = false;
|
||||
|
||||
alpha = 1; color = 0xFFFFFFFF;
|
||||
@@ -52,12 +54,8 @@ class CharacterGhost extends Character {
|
||||
frameOffset.set(0, 0);
|
||||
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
|
||||
colorTransform.color = 0xFFEF0202;
|
||||
} else {
|
||||
animation.play(animName, true, false, animFrame);
|
||||
setAnimOffset(animName);
|
||||
if (animation.curAnim != null)
|
||||
animation.curAnim._frameTimer = animFrameTimer;
|
||||
}
|
||||
} else
|
||||
setAnimOffset(animateAtlas != null ? atlasPlayingAnim : animation.name);
|
||||
|
||||
super.draw();
|
||||
}
|
||||
@@ -72,45 +70,22 @@ class CharacterGhost extends Character {
|
||||
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
|
||||
}
|
||||
|
||||
public function generateRenderTextureForAnim(anim:String):RenderTexture @:privateAccess {
|
||||
if (!isAnimate) return null;
|
||||
|
||||
var wasInvalidFrame:Bool = !colorTransform.__isDefault(false);
|
||||
colorTransform.__identity();
|
||||
|
||||
var animName = animation.curAnim?.name ?? null;
|
||||
var animFrame = animation.curAnim?.curFrame ?? 0;
|
||||
var animFrameTimer = animation.curAnim?._frameTimer ?? 0;
|
||||
|
||||
var oldRenderTexture:RenderTexture = this._renderTexture;
|
||||
var oldRenderTextureDirty = _renderTextureDirty;
|
||||
var oldAlpha = alpha;
|
||||
|
||||
this._renderTexture = null;
|
||||
this._renderTextureDirty = true;
|
||||
this.alpha = 256.0/257.0;
|
||||
|
||||
animation.play(anim, true, false, 0);
|
||||
|
||||
drawAnimate(FakeCallCamera.instance);
|
||||
|
||||
var renderTex = this._renderTexture;
|
||||
|
||||
this._renderTexture = oldRenderTexture;
|
||||
this._renderTextureDirty = oldRenderTextureDirty;
|
||||
this.alpha = oldAlpha;
|
||||
|
||||
if (wasInvalidFrame) {
|
||||
colorTransform.color = 0xFFEF0202;
|
||||
} else {
|
||||
animation.play(animName, true, false, animFrame);
|
||||
if (animation.curAnim != null)
|
||||
animation.curAnim._frameTimer = animFrameTimer;
|
||||
}
|
||||
|
||||
return renderTex;
|
||||
// This gets annoying lmao -lunar
|
||||
private var atlasState:AtlasState = null;
|
||||
public function storeAtlasState():AtlasState @:privateAccess {
|
||||
return atlasState = {
|
||||
oldAnim: atlasPlayingAnim,
|
||||
oldFrame: animateAtlas.anim.curFrame,
|
||||
oldTick: animateAtlas.anim._tick,
|
||||
oldPlaying: animateAtlas.anim.isPlaying,
|
||||
};
|
||||
}
|
||||
|
||||
// This gets annoying lmao -lunar
|
||||
// it's gone now <3 -yosh
|
||||
public function restoreAtlasState(state:AtlasState = null) @:privateAccess {
|
||||
if (state == null) state = atlasState;
|
||||
|
||||
animateAtlas.anim.play(state.oldAnim, true, false, state.oldFrame);
|
||||
animateAtlas.anim._tick = state.oldTick;
|
||||
animateAtlas.anim.isPlaying = state.oldPlaying;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
package funkin.editors.character;
|
||||
|
||||
import funkin.backend.FlxAnimate;
|
||||
import haxe.io.Path;
|
||||
import funkin.editors.character.CharacterInfoScreen.CharacterExtraInfo;
|
||||
import funkin.game.Character;
|
||||
@@ -183,15 +184,31 @@ class CharacterPropertiesWindow extends UISliceSprite {
|
||||
character.sprite = sprite;
|
||||
|
||||
animsWindow.displayWindowSprite.animation.reset();
|
||||
animsWindow.clearDisplayAnims();
|
||||
animsWindow.displayAnimsFramesList.clear();
|
||||
if (animsWindow.displayWindowGraphic != null)
|
||||
animsWindow.displayWindowGraphic.destroy();
|
||||
|
||||
character.frames = Paths.getFrames(path, true);
|
||||
if (Assets.exists('$noExt/Animation.json')) {
|
||||
if (character.animateAtlas == null) {
|
||||
character.animation.reset();
|
||||
character.animateAtlas = new FlxAnimate(character.x, character.y);
|
||||
} else
|
||||
character.animateAtlas.anim.stop();
|
||||
|
||||
animsWindow.displayWindowSprite.loadGraphicFromSprite(character);
|
||||
if (Assets.exists(Paths.image('characters/${character.sprite}')))
|
||||
animsWindow.displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
|
||||
character.atlasPath = noExt;
|
||||
character.animateAtlas.loadAtlas(noExt);
|
||||
} else {
|
||||
if (character.animateAtlas != null) {
|
||||
character.animateAtlas.destroy();
|
||||
character.animateAtlas = null;
|
||||
character.atlasPlayingAnim = character.atlasPath = null;
|
||||
}
|
||||
character.frames = Paths.getFrames(path, true);
|
||||
|
||||
animsWindow.displayWindowSprite.loadGraphicFromSprite(character);
|
||||
if (Assets.exists(Paths.image('characters/${character.sprite}')))
|
||||
animsWindow.displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
|
||||
}
|
||||
|
||||
character.animDatas.clear();
|
||||
for (anim in animsWindow.buttons) anim.checkValid(); // Re-add all animations
|
||||
|
||||
@@ -80,7 +80,6 @@ class Charter extends UIState {
|
||||
public var metronome:FlxSound;
|
||||
|
||||
public var vocals:FlxSound;
|
||||
public var voicesMuted:Bool = false;
|
||||
|
||||
public var quant:Int = 16;
|
||||
public var quants:Array<Int> = [4, 8, 12, 16, 20, 24, 32, 48, 64, 192]; // different quants
|
||||
@@ -1813,9 +1812,9 @@ class Charter extends UIState {
|
||||
t.icon = 1 - Std.int(Math.ceil(FlxG.sound.music.volume));
|
||||
}
|
||||
function _song_mutevoices(t) {
|
||||
vocals.volume = (voicesMuted = !voicesMuted) ? 0 : 1;
|
||||
for (strumLine in strumLines.members) strumLine.updateVoicesVolume();
|
||||
t.icon = voicesMuted ? 1 : 0;
|
||||
vocals.volume = vocals.volume > 0 ? 0 : 1;
|
||||
for (strumLine in strumLines.members) strumLine.vocals.volume = strumLine.vocals.volume > 0 ? 0 : 1;
|
||||
t.icon = 1 - Std.int(Math.ceil(vocals.volume));
|
||||
}
|
||||
function _playback_back(_) {
|
||||
if (FlxG.sound.music.playing) return;
|
||||
|
||||
@@ -82,7 +82,7 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack data is a list of 5 strings separated by `________PACKSEP________`
|
||||
* Pack data is a list of 4 strings separated by `________PACKSEP________`
|
||||
* [0] Event Name
|
||||
* [1] Event Script
|
||||
* [2] Event JSON Info
|
||||
@@ -276,47 +276,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
||||
}
|
||||
|
||||
case "Camera Movement":
|
||||
var shouldDoArrow:Bool = false;
|
||||
var icon:Null<FlxSprite> = null;
|
||||
if (event.params != null) {
|
||||
shouldDoArrow = event.params[1] && event.params[3] != "CLASSIC"; // is Tweened and isnt Lerped
|
||||
icon = getIconFromStrumline(event.params[0]); // camera movement, use health icon
|
||||
}
|
||||
|
||||
if (icon == null) icon = generateDefaultIcon(event.name);
|
||||
|
||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
||||
var group = new EventIconGroup();
|
||||
group.add(icon);
|
||||
group.members[0].x -= 8;
|
||||
group.members[0].y -= 8;
|
||||
generateEventIconDurationArrow(group, event.params[2]);
|
||||
return group;
|
||||
} else
|
||||
return icon;
|
||||
|
||||
case "Camera Position":
|
||||
var shouldDoArrow:Bool = false;
|
||||
if (event.params != null)
|
||||
shouldDoArrow = event.params[2] && event.params[4] != "CLASSIC"; // is Tweened and isnt Lerped
|
||||
|
||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon(event.name));
|
||||
generateEventIconDurationArrow(group, event.params[3]);
|
||||
return group;
|
||||
}
|
||||
|
||||
case "Camera Zoom":
|
||||
var shouldDoArrow:Bool = false;
|
||||
if (event.params != null)
|
||||
shouldDoArrow = event.params[0];
|
||||
|
||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
||||
var group = new EventIconGroup();
|
||||
group.add(generateDefaultIcon(event.name));
|
||||
generateEventIconDurationArrow(group, event.params[3]);
|
||||
return group;
|
||||
// camera movement, use health icon
|
||||
if(event.params != null) {
|
||||
var icon = getIconFromStrumline(event.params[0]);
|
||||
if(icon != null) return icon;
|
||||
}
|
||||
}
|
||||
return generateDefaultIcon(event.name);
|
||||
|
||||
@@ -17,7 +17,7 @@ class CharterEventGroup extends FlxTypedGroup<CharterEvent> {
|
||||
if (autoSort && members.length != __lastSort)
|
||||
sortEvents();
|
||||
|
||||
eventsRowText.y = FlxMath.lerp(eventsRowText.y, -40 + (members[0] != null ? Math.min(members[0].y, 0) : 0), 1/10);
|
||||
eventsRowText.y = FlxMath.lerp(eventsRowText.y, -40 + (members[0] != null ? Math.min(members[0].y, 0) : 0), 1/20);
|
||||
}
|
||||
|
||||
public override function remove(v:CharterEvent, force:Bool = true):CharterEvent {
|
||||
|
||||
@@ -40,7 +40,7 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
|
||||
var screen = new EditorTreeMenuScreen((first || !isVariant) ? (s.name + (isVariant ? ' (${s.variant})' : '')) : s.variant, getID('selectDifficulty'));
|
||||
|
||||
for (d in s.difficulties) if (d != '') screen.add(makeChartOption(d, isVariant ? s.variant : null, s.name));
|
||||
if (s.difficulties.length > 0 && s.variants.length > 0) screen.add(new Separator()); // Create a separator only when there are both difficulty and variant options available.
|
||||
screen.add(new Separator());
|
||||
for (v in s.variants) if (s.metas.get(v) != null) screen.add(makeVariationOption(s.metas.get(v)));
|
||||
|
||||
#if sys
|
||||
@@ -48,13 +48,13 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
|
||||
parent.openSubState(new ChartCreationScreen(saveChart));
|
||||
}));
|
||||
|
||||
if (!first) screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 1 : 0;
|
||||
if (!first) screen.curSelected = 1;
|
||||
else {
|
||||
cast(screen.members[0], NewOption).itemHeight = 120;
|
||||
screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> {
|
||||
parent.openSubState(new VariationCreationScreen(s, saveSong));
|
||||
}));
|
||||
screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 2 : 1;
|
||||
screen.curSelected = 2;
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ class CharterStrumline extends UISprite {
|
||||
public var curMenu:UIContextMenu = null;
|
||||
|
||||
public var vocals:FlxSound;
|
||||
public var voicesMuted:Bool = false;
|
||||
|
||||
public var keyCount:Int = 4;
|
||||
public var startingID(get, null):Int;
|
||||
@@ -148,10 +147,6 @@ class CharterStrumline extends UISprite {
|
||||
}
|
||||
vocals.group = FlxG.sound.defaultMusicGroup;
|
||||
}
|
||||
|
||||
public function updateVoicesVolume() {
|
||||
vocals.volume = (voicesMuted || (Charter.instance?.voicesMuted ?? false)) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
class CharterStrumlineOptions extends UITopMenuButton {
|
||||
@@ -181,10 +176,9 @@ class CharterStrumlineOptions extends UITopMenuButton {
|
||||
{
|
||||
label: TU.translate("charter.strumLine.muteVocals"),
|
||||
onSelect: function(_) {
|
||||
strLine.voicesMuted = !strLine.voicesMuted;
|
||||
strLine.updateVoicesVolume();
|
||||
strLine.vocals.volume = strLine.vocals.volume > 0 ? 0 : 1;
|
||||
},
|
||||
icon: strLine.voicesMuted ? 1 : 0
|
||||
icon: strLine.vocals.volume > 0 ? 0 : 1
|
||||
},
|
||||
null,
|
||||
{
|
||||
|
||||
@@ -435,7 +435,7 @@ class SongCreationScreen extends UISubstateWindow {
|
||||
color: colorWheel.curColor,
|
||||
opponentModeAllowed: opponentModeCheckbox.checked,
|
||||
coopAllowed: coopAllowedCheckbox.checked,
|
||||
difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) if (diff.length > 0) diff.trim()]
|
||||
difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()]
|
||||
});
|
||||
|
||||
if (onSave != null) onSave({
|
||||
|
||||