Author SHA1 Message Date
Furo e540cb454b Changes project.xml to project.hxp 2025-10-20 20:17:45 +02:00
131 changed files with 148156 additions and 13245 deletions
+1 -4
View File
@@ -37,7 +37,4 @@ f8b20774e3f035eeddb9211a28a391b20db74456
# Revert a revert (scripted cutscene path) # Revert a revert (scripted cutscene path)
d73f86d26ec2dbf031c01f588ba4be11842db09c d73f86d26ec2dbf031c01f588ba4be11842db09c
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
# Forgot the # in the commit message
484bbcb22aa8f28b62912abb6d8c89fb58e63889
+3 -2
View File
@@ -5,9 +5,10 @@
pages/** linguist-vendored pages/** linguist-vendored
# Include HScript files as Haxe # Include HScript files as Haxe
*.hxs linguist-language=Haxe
*.hsc linguist-language=Haxe
*.hscript linguist-language=Haxe *.hscript linguist-language=Haxe
*.hsc linguist-language=Haxe
*.hxs linguist-language=Haxe
*.hxp linguist-language=Haxe
# Include Shader files as GLSL # Include Shader files as GLSL
*.frag linguist-language=GLSL *.frag linguist-language=GLSL
+9 -77
View File
@@ -1,23 +1,22 @@
name: Linux Builds
name: Linux Build
on: on:
push: push:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: build:
name: Linux Build name: Linux Build
permissions: write-all permissions: write-all
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Pulling the new commit - name: Pulling the source
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Setting up Haxe - name: Setting up Haxe
uses: krdlab/setup-haxe@v2 uses: krdlab/setup-haxe@v2
with: with:
haxe-version: 4.3.7 haxe-version: 4.3.7
- name: Restore existing build cache for faster compilation - name: Restore existing build cache for faster compilation
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# not caching the bin folder to prevent asset duplication and stuff like that # not caching the bin folder to prevent asset duplication and stuff like that
key: cache-build-linux key: cache-build-linux
@@ -25,8 +24,8 @@ jobs:
.haxelib/ .haxelib/
export/release/linux/haxe/ export/release/linux/haxe/
export/release/linux/obj/ export/release/linux/obj/
- run: | restore-keys: |
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV cache-build-linux
- name: Installing LibVLC - name: Installing LibVLC
run: | run: |
sudo apt-get install libvlc-dev libvlccore-dev sudo apt-get install libvlc-dev libvlccore-dev
@@ -68,7 +67,7 @@ jobs:
} }
} }
- name: Uploading new cache - name: Uploading new cache
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# caching again since for some reason it doesnt work with the first post cache shit # caching again since for some reason it doesnt work with the first post cache shit
key: cache-build-linux key: cache-build-linux
@@ -76,72 +75,5 @@ jobs:
.haxelib/ .haxelib/
export/release/linux/haxe/ export/release/linux/haxe/
export/release/linux/obj/ export/release/linux/obj/
restore-keys: |
# 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) cache-build-linux
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/
+10 -75
View File
@@ -1,23 +1,22 @@
name: Mac OS Builds
name: Mac OS Build
on: on:
push: push:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: build:
name: Mac OS Build name: Mac OS Build
permissions: write-all permissions: write-all
runs-on: macos-14 runs-on: macos-13
steps: steps:
- name: Pulling the new commit - name: Pulling the new commit
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Setting up Haxe - name: Setting up Haxe
uses: krdlab/setup-haxe@v2 uses: krdlab/setup-haxe@v2
with: with:
haxe-version: 4.3.7 haxe-version: 4.3.7
- name: Restore existing build cache for faster compilation - name: Restore existing build cache for faster compilation
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# not caching the bin folder to prevent asset duplication and stuff like that # not caching the bin folder to prevent asset duplication and stuff like that
key: cache-build-mac key: cache-build-mac
@@ -25,14 +24,14 @@ jobs:
.haxelib/ .haxelib/
export/release/macos/haxe/ export/release/macos/haxe/
export/release/macos/obj/ export/release/macos/obj/
- run: | restore-keys: |
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV cache-build-mac
- name: Installing/Updating libraries - name: Installing/Updating libraries
run: | run: |
haxe -cp commandline -D analyzer-optimize --run Main setup -s haxe -cp commandline -D analyzer-optimize --run Main setup -s
- name: Building the game - name: Building the game
run: | run: |
arch -x86_64 haxelib run lime build mac haxelib run lime build mac
- name: Tar files - name: Tar files
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin . run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
- name: Uploading artifact (executable) - name: Uploading artifact (executable)
@@ -65,7 +64,7 @@ jobs:
} }
} }
- name: Uploading new cache - name: Uploading new cache
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# caching again since for some reason it doesnt work with the first post cache shit # caching again since for some reason it doesnt work with the first post cache shit
key: cache-build-mac key: cache-build-mac
@@ -73,69 +72,5 @@ jobs:
.haxelib/ .haxelib/
export/release/macos/haxe/ export/release/macos/haxe/
export/release/macos/obj/ export/release/macos/obj/
restore-keys: |
# 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) cache-build-mac
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/
+1 -1
View File
@@ -184,7 +184,7 @@ jobs:
name: Release ${{ github.event.inputs.tag_name }} name: Release ${{ github.event.inputs.tag_name }}
draft: true draft: true
prerelease: ${{ github.event.inputs.prerelease }} prerelease: ${{ github.event.inputs.prerelease }}
body: ${{ steps.build_body.outputs.body }} body: ${{ steps.build_body.outputs.body }}
generate_release_notes: true generate_release_notes: true
files: | files: |
renamed/Codename Engine-Windows.zip renamed/Codename Engine-Windows.zip
+8 -71
View File
@@ -1,9 +1,8 @@
name: Windows Builds
name: Windows Build
on: on:
push: push:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
build: build:
name: Windows Build name: Windows Build
@@ -11,13 +10,13 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- name: Pulling the new commit - name: Pulling the new commit
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Setting up Haxe - name: Setting up Haxe
uses: krdlab/setup-haxe@v2 uses: krdlab/setup-haxe@v2
with: with:
haxe-version: 4.3.7 haxe-version: 4.3.7
- name: Restore existing build cache for faster compilation - name: Restore existing build cache for faster compilation
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# not caching the bin folder to prevent asset duplication and stuff like that # not caching the bin folder to prevent asset duplication and stuff like that
key: cache-build-windows key: cache-build-windows
@@ -25,8 +24,8 @@ jobs:
.haxelib/ .haxelib/
export/release/windows/haxe/ export/release/windows/haxe/
export/release/windows/obj/ export/release/windows/obj/
- run: | restore-keys: |
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV cache-build-windows
- name: Installing/Updating libraries - name: Installing/Updating libraries
run: | run: |
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
@@ -63,7 +62,7 @@ jobs:
} }
} }
- name: Uploading new cache - name: Uploading new cache
uses: actions/cache@v4.2.3 uses: actions/cache@v3
with: with:
# caching again since for some reason it doesnt work with the first post cache shit # caching again since for some reason it doesnt work with the first post cache shit
key: cache-build-windows key: cache-build-windows
@@ -71,67 +70,5 @@ jobs:
.haxelib/ .haxelib/
export/release/windows/haxe/ export/release/windows/haxe/
export/release/windows/obj/ export/release/windows/obj/
restore-keys: |
# 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) cache-build-windows
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/
+4 -1
View File
@@ -1,12 +1,15 @@
{ {
"editor.detectIndentation": false, "editor.detectIndentation": false,
"editor.insertSpaces": false, "editor.insertSpaces": false,
"editor.tabSize": 4,
"files.associations": { "files.associations": {
"*.hx": "haxe", "*.hx": "haxe",
"*.hscript": "haxe", "*.hscript": "haxe",
"*.hsc": "haxe", "*.hsc": "haxe",
"*.hxs": "haxe" "*.hxs": "haxe",
"*.hxp": "haxe"
}, },
"lime.projectFile": "project.hxp",
"lime.targetConfigurations": [ "lime.targetConfigurations": [
{ {
"label": "Windows (Test Build)", "label": "Windows (Test Build)",
+1 -1
View File
@@ -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. - 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) - Editors for Charts and Characters (Stage coming soon)
- Undos/Redos supported - Undos/Redos supported
- Warning on closing unsaved work. - Warning on closing unsaved work
- Clean UI (for ocd freaks) - Clean UI (for ocd freaks)
- Mature Chart editor (Character editor rework soon) - Mature Chart editor (Character editor rework soon)
- Features not found in other editors! - Features not found in other editors!
+1 -1
View File
@@ -68,7 +68,7 @@ The engine uses [HaxeFlixel](https://haxeflixel.com/) and it mainly features:
</details> </details>
<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) Check out our guide [HERE](building/README.md)
</details> </details>
+10
View File
@@ -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.
+8
View File
@@ -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
+7
View File
@@ -2,6 +2,13 @@
<character x="115" y="325" sprite="gf-christmas" icon="gf" color="#A5004D"> <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="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="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="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"/> <anim name="sad" anim="gf sad" x="-51" y="306" fps="24" loop="true" indices="0..12"/>
</character> </character>
+12 -12
View File
@@ -1,14 +1,14 @@
<!DOCTYPE codename-engine-character> <!DOCTYPE codename-engine-character>
<character x="100" y="275" color="#A5004D"> <character x="100" y="275" sprite="gf" icon="gf" color="#A5004D">
<anim name="cheer" anim="GF Cheer"/> <anim name="cheer" anim="GF Cheer" x="0" y="0" fps="24" loop="false"/>
<anim name="singUP" anim="GF Up Note"/> <anim name="singUP" anim="GF Up Note" x="0" y="0" fps="24" loop="false"/>
<anim name="singLEFT" anim="GF left note"/> <anim name="singLEFT" anim="GF left note" x="0" y="0" fps="24" loop="false"/>
<anim name="singRIGHT" anim="GF Right Note"/> <anim name="singRIGHT" anim="GF Right Note" x="0" y="0" fps="24" loop="false"/>
<anim name="singDOWN" anim="GF Down Note"/> <anim name="singDOWN" anim="GF Down Note" x="0" y="0" fps="24" loop="false"/>
<anim name="danceLeft" anim="GF Dancing Beat" indices="0..14"/> <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" indices="15..30"/> <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" loop="true" indices="0..3"/> <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" indices="0..11"/> <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 " loop="true"/> <anim name="scared" anim="GF FEAR" x="0" y="0" fps="24" loop="true"/>
<anim name="sad" anim="gf sad" x="-51" y="315" loop="true" indices="0..12"/> <anim name="sad" anim="gf sad" x="0" y="0" fps="24" loop="true" indices="0..12"/>
</character> </character>
+1 -1
View File
@@ -11,7 +11,7 @@
<sprite name="fgSnow" x="-600" y="680" sprite="fgSnow"/> <sprite name="fgSnow" x="-600" y="680" sprite="fgSnow"/>
<girlfriend x="440" y="110"/> <girlfriend x="540" y="110"/>
<dad/> <dad/>
<boyfriend x="1030" camyoffset="-150" camxoffset="-150"/> <boyfriend x="1030" camyoffset="-150" camxoffset="-150"/>
File diff suppressed because it is too large Load Diff
+27 -27
View File
@@ -1,28 +1,28 @@
{"ATLAS":{"SPRITES":[ {"ATLAS": {"SPRITES":[
{"SPRITE":{"name":"0","x":1662,"y":282,"w":194,"h":117,"rotated":false}}, {"SPRITE" : {"name": "0000","x":1636,"y":275,"w":183,"h":115,"rotated": false}},
{"SPRITE":{"name":"1","x":1790,"y":417,"w":92,"h":136,"rotated":false}}, {"SPRITE" : {"name": "0001","x":215,"y":360,"w":84,"h":140,"rotated": false}},
{"SPRITE":{"name":"2","x":1193,"y":539,"w":259,"h":123,"rotated":false}}, {"SPRITE" : {"name": "0002","x":419,"y":358,"w":251,"h":121,"rotated": false}},
{"SPRITE":{"name":"3","x":483,"y":553,"w":125,"h":68,"rotated":false}}, {"SPRITE" : {"name": "0003","x":1636,"y":394,"w":120,"h":65,"rotated": false}},
{"SPRITE":{"name":"4","x":1662,"y":417,"w":110,"h":127,"rotated":false}}, {"SPRITE" : {"name": "0004","x":4,"y":360,"w":108,"h":126,"rotated": false}},
{"SPRITE":{"name":"5","x":1886,"y":0,"w":105,"h":149,"rotated":false}}, {"SPRITE" : {"name": "0005","x":674,"y":358,"w":102,"h":147,"rotated": false}},
{"SPRITE":{"name":"6","x":1886,"y":167,"w":97,"h":130,"rotated":false}}, {"SPRITE" : {"name": "0006","x":116,"y":360,"w":95,"h":130,"rotated": false}},
{"SPRITE":{"name":"7","x":1398,"y":0,"w":470,"h":264,"rotated":false}}, {"SPRITE" : {"name": "0007","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
{"SPRITE":{"name":"8","x":867,"y":0,"w":513,"h":254,"rotated":false}}, {"SPRITE" : {"name": "0008","x":4,"y":4,"w":411,"h":352,"rotated": false}},
{"SPRITE":{"name":"9","x":0,"y":372,"w":465,"h":270,"rotated":false}}, {"SPRITE" : {"name": "0009","x":419,"y":4,"w":398,"h":350,"rotated": false}},
{"SPRITE":{"name":"10","x":1900,"y":315,"w":101,"h":118,"rotated":false}}, {"SPRITE" : {"name": "0010","x":1303,"y":275,"w":329,"h":162,"rotated": false}},
{"SPRITE":{"name":"11","x":867,"y":272,"w":308,"h":367,"rotated":false}}, {"SPRITE" : {"name": "0011","x":303,"y":360,"w":90,"h":103,"rotated": false}},
{"SPRITE":{"name":"12","x":483,"y":371,"w":338,"h":164,"rotated":false}}, {"SPRITE" : {"name": "0012","x":1823,"y":4,"w":211,"h":236,"rotated": false}},
{"SPRITE":{"name":"13","x":0,"y":0,"w":422,"h":354,"rotated":false}}, {"SPRITE" : {"name": "0013","x":1823,"y":244,"w":208,"h":235,"rotated": false}},
{"SPRITE":{"name":"14","x":440,"y":0,"w":409,"h":353,"rotated":false}}, {"SPRITE" : {"name": "0014","x":821,"y":258,"w":478,"h":262,"rotated": false}},
{"SPRITE":{"name":"15","x":1900,"y":451,"w":92,"h":103,"rotated":false}}, {"SPRITE" : {"name": "0015","x":821,"y":4,"w":521,"h":250,"rotated": false}},
{"SPRITE":{"name":"16","x":1193,"y":282,"w":218,"h":239,"rotated":false}}, {"SPRITE" : {"name": "0016","x":1346,"y":4,"w":473,"h":267,"rotated": false}}
{"SPRITE":{"name":"17","x":1429,"y":282,"w":215,"h":237,"rotated":false}}]}, ]},
"meta":{ "meta": {
"app":"Adobe Animate (Better TA Extension)", "app": "Adobe Animate",
"version":"24.0.2.12", "version": "22.0.5.191",
"image":"spritemap1.png", "image": "spritemap1.png",
"format":"RGBA8888", "format": "RGBA8888",
"size":{"w":2031,"h":662}, "size": {"w":2043,"h":524},
"resolution":"1" "resolution": "1"
}
} }
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 74 KiB

File diff suppressed because it is too large Load Diff
@@ -1,40 +1,58 @@
{"ATLAS":{"SPRITES":[ {"ATLAS": {"SPRITES":[
{"SPRITE":{"name":"0","x":349,"y":867,"w":254,"h":136,"rotated":false}}, {"SPRITE" : {"name": "0000","x":994,"y":1029,"w":187,"h":118,"rotated": false}},
{"SPRITE":{"name":"1","x":1648,"y":328,"w":287,"h":363,"rotated":false}}, {"SPRITE" : {"name": "0001","x":1953,"y":524,"w":84,"h":140,"rotated": false}},
{"SPRITE":{"name":"2","x":1571,"y":709,"w":185,"h":117,"rotated":false}}, {"SPRITE" : {"name": "0002","x":471,"y":430,"w":258,"h":137,"rotated": false}},
{"SPRITE":{"name":"3","x":1686,"y":855,"w":86,"h":136,"rotated":false}}, {"SPRITE" : {"name": "0003","x":1300,"y":641,"w":122,"h":66,"rotated": false}},
{"SPRITE":{"name":"4","x":349,"y":1021,"w":122,"h":68,"rotated":false}}, {"SPRITE" : {"name": "0004","x":1825,"y":1078,"w":108,"h":126,"rotated": false}},
{"SPRITE":{"name":"5","x":1774,"y":709,"w":110,"h":128,"rotated":false}}, {"SPRITE" : {"name": "0005","x":360,"y":695,"w":103,"h":149,"rotated": false}},
{"SPRITE":{"name":"6","x":621,"y":867,"w":105,"h":148,"rotated":false}}, {"SPRITE" : {"name": "0006","x":1945,"y":867,"w":95,"h":130,"rotated": false}},
{"SPRITE":{"name":"7","x":1571,"y":844,"w":97,"h":131,"rotated":false}}, {"SPRITE" : {"name": "0007","x":2034,"y":4,"w":1,"h":4,"rotated": false}},
{"SPRITE":{"name":"8","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0008","x":943,"y":650,"w":309,"h":375,"rotated": false}},
{"SPRITE":{"name":"9","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0009","x":4,"y":4,"w":778,"h":422,"rotated": false}},
{"SPRITE":{"name":"10","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0010","x":786,"y":4,"w":761,"h":393,"rotated": false}},
{"SPRITE":{"name":"11","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0011","x":1551,"y":4,"w":411,"h":352,"rotated": false}},
{"SPRITE":{"name":"12","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0012","x":1551,"y":360,"w":398,"h":350,"rotated": false}},
{"SPRITE":{"name":"13","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0013","x":4,"y":1028,"w":329,"h":162,"rotated": false}},
{"SPRITE":{"name":"14","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0014","x":1945,"y":1001,"w":90,"h":103,"rotated": false}},
{"SPRITE":{"name":"15","x":800,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0015","x":1300,"y":401,"w":211,"h":236,"rotated": false}},
{"SPRITE":{"name":"16","x":1363,"y":1,"w":543,"h":308,"rotated":false}}, {"SPRITE" : {"name": "0016","x":782,"y":1029,"w":208,"h":235,"rotated": false}},
{"SPRITE":{"name":"17","x":1,"y":444,"w":771,"h":404,"rotated":false}}, {"SPRITE" : {"name": "0017","x":782,"y":910,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"18","x":791,"y":700,"w":302,"h":369,"rotated":false}}, {"SPRITE" : {"name": "0018","x":994,"y":1151,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"19","x":1111,"y":957,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0019","x":1937,"y":1108,"w":103,"h":83,"rotated": false}},
{"SPRITE":{"name":"20","x":1790,"y":855,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0020","x":1115,"y":1151,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"21","x":1790,"y":959,"w":106,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0021","x":1654,"y":714,"w":287,"h":360,"rotated": false}},
{"SPRITE":{"name":"22","x":1249,"y":957,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0022","x":471,"y":571,"w":179,"h":67,"rotated": false}},
{"SPRITE":{"name":"23","x":0,"y":0,"w":781,"h":425,"rotated":false}}, {"SPRITE" : {"name": "0023","x":654,"y":571,"w":118,"h":75,"rotated": false}},
{"SPRITE":{"name":"24","x":0,"y":867,"w":331,"h":164,"rotated":false}}, {"SPRITE" : {"name": "0024","x":1966,"y":223,"w":55,"h":112,"rotated": false}},
{"SPRITE":{"name":"25","x":799,"y":328,"w":413,"h":354,"rotated":false}}, {"SPRITE" : {"name": "0025","x":1966,"y":4,"w":64,"h":106,"rotated": false}},
{"SPRITE":{"name":"26","x":1230,"y":328,"w":400,"h":353,"rotated":false}}, {"SPRITE" : {"name": "0026","x":1185,"y":1029,"w":67,"h":70,"rotated": false}},
{"SPRITE":{"name":"27","x":1387,"y":954,"w":90,"h":103,"rotated":false}}, {"SPRITE" : {"name": "0027","x":337,"y":1182,"w":122,"h":62,"rotated": false}},
{"SPRITE":{"name":"28","x":1111,"y":700,"w":213,"h":239,"rotated":false}}, {"SPRITE" : {"name": "0028","x":1647,"y":1078,"w":174,"h":97,"rotated": false}},
{"SPRITE":{"name":"29","x":1342,"y":699,"w":211,"h":237,"rotated":false}}]}, {"SPRITE" : {"name": "0029","x":360,"y":870,"w":82,"h":14,"rotated": false}},
"meta":{ {"SPRITE" : {"name": "0030","x":1647,"y":1179,"w":128,"h":61,"rotated": false}},
"app":"Adobe Animate (Better TA Extension)", {"SPRITE" : {"name": "0031","x":463,"y":1182,"w":124,"h":58,"rotated": false}},
"version":"24.0.2.12", {"SPRITE" : {"name": "0032","x":1966,"y":114,"w":59,"h":105,"rotated": false}},
"image":"spritemap1.png", {"SPRITE" : {"name": "0033","x":1953,"y":360,"w":87,"h":160,"rotated": false}},
"format":"RGBA8888", {"SPRITE" : {"name": "0034","x":1945,"y":714,"w":92,"h":149,"rotated": false}},
"size":{"w":1965,"h":1089}, {"SPRITE" : {"name": "0035","x":1426,"y":641,"w":104,"h":42,"rotated": false}},
"resolution":"1" {"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"
}
} }
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 KiB

After

Width:  |  Height:  |  Size: 228 KiB

File diff suppressed because it is too large Load Diff
+56 -54
View File
@@ -1,55 +1,57 @@
{"ATLAS":{"SPRITES":[ {"ATLAS": {"SPRITES":[
{"SPRITE":{"name":"0","x":1129,"y":977,"w":86,"h":17,"rotated":false}}, {"SPRITE" : {"name": "0000","x":1623,"y":602,"w":287,"h":360,"rotated": false}},
{"SPRITE":{"name":"1","x":1690,"y":1012,"w":86,"h":17,"rotated":false}}, {"SPRITE" : {"name": "0001","x":1310,"y":269,"w":309,"h":375,"rotated": false}},
{"SPRITE":{"name":"2","x":1656,"y":852,"w":126,"h":64,"rotated":false}}, {"SPRITE" : {"name": "0002","x":4,"y":4,"w":420,"h":359,"rotated": false}},
{"SPRITE":{"name":"3","x":1915,"y":841,"w":121,"h":77,"rotated":false}}, {"SPRITE" : {"name": "0003","x":428,"y":4,"w":406,"h":358,"rotated": false}},
{"SPRITE":{"name":"4","x":1382,"y":980,"w":131,"h":64,"rotated":false}}, {"SPRITE" : {"name": "0004","x":4,"y":639,"w":336,"h":165,"rotated": false}},
{"SPRITE":{"name":"5","x":1132,"y":283,"w":420,"h":270,"rotated":false}}, {"SPRITE" : {"name": "0005","x":125,"y":808,"w":90,"h":103,"rotated": false}},
{"SPRITE":{"name":"6","x":1570,"y":277,"w":389,"h":273,"rotated":false}}, {"SPRITE" : {"name": "0006","x":1819,"y":4,"w":215,"h":242,"rotated": false}},
{"SPRITE":{"name":"7","x":0,"y":743,"w":397,"h":292,"rotated":false}}, {"SPRITE" : {"name": "0007","x":1217,"y":648,"w":213,"h":240,"rotated": false}},
{"SPRITE":{"name":"8","x":431,"y":267,"w":354,"h":332,"rotated":false}}, {"SPRITE" : {"name": "0008","x":606,"y":660,"w":191,"h":120,"rotated": false}},
{"SPRITE":{"name":"9","x":1592,"y":568,"w":190,"h":117,"rotated":false}}, {"SPRITE" : {"name": "0009","x":606,"y":784,"w":90,"h":151,"rotated": false}},
{"SPRITE":{"name":"10","x":1444,"y":826,"w":86,"h":136,"rotated":false}}, {"SPRITE" : {"name": "0010","x":344,"y":660,"w":258,"h":124,"rotated": false}},
{"SPRITE":{"name":"11","x":723,"y":852,"w":260,"h":123,"rotated":false}}, {"SPRITE" : {"name": "0011","x":448,"y":859,"w":122,"h":67,"rotated": false}},
{"SPRITE":{"name":"12","x":1548,"y":947,"w":124,"h":68,"rotated":false}}, {"SPRITE" : {"name": "0012","x":1914,"y":755,"w":108,"h":126,"rotated": false}},
{"SPRITE":{"name":"13","x":1001,"y":852,"w":110,"h":128,"rotated":false}}, {"SPRITE" : {"name": "0013","x":1914,"y":602,"w":103,"h":149,"rotated": false}},
{"SPRITE":{"name":"14","x":1933,"y":0,"w":106,"h":148,"rotated":false}}, {"SPRITE" : {"name": "0014","x":700,"y":784,"w":95,"h":130,"rotated": false}},
{"SPRITE":{"name":"15","x":1129,"y":828,"w":97,"h":131,"rotated":false}}, {"SPRITE" : {"name": "0015","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
{"SPRITE":{"name":"16","x":803,"y":283,"w":311,"h":369,"rotated":false}}, {"SPRITE" : {"name": "0016","x":838,"y":253,"w":468,"h":256,"rotated": false}},
{"SPRITE":{"name":"17","x":1592,"y":703,"w":167,"h":101,"rotated":false}}, {"SPRITE" : {"name": "0017","x":838,"y":4,"w":510,"h":245,"rotated": false}},
{"SPRITE":{"name":"18","x":1835,"y":852,"w":57,"h":105,"rotated":false}}, {"SPRITE" : {"name": "0018","x":1352,"y":4,"w":463,"h":261,"rotated": false}},
{"SPRITE":{"name":"19","x":1977,"y":270,"w":66,"h":104,"rotated":false}}, {"SPRITE" : {"name": "0019","x":4,"y":367,"w":418,"h":268,"rotated": false}},
{"SPRITE":{"name":"20","x":1910,"y":936,"w":70,"h":73,"rotated":false}}, {"SPRITE" : {"name": "0020","x":826,"y":513,"w":387,"h":271,"rotated": false}},
{"SPRITE":{"name":"21","x":1244,"y":828,"w":182,"h":69,"rotated":false}}, {"SPRITE" : {"name": "0021","x":428,"y":366,"w":394,"h":290,"rotated": false}},
{"SPRITE":{"name":"22","x":1690,"y":934,"w":127,"h":60,"rotated":false}}, {"SPRITE" : {"name": "0022","x":1623,"y":269,"w":352,"h":329,"rotated": false}},
{"SPRITE":{"name":"23","x":418,"y":617,"w":287,"h":363,"rotated":false}}, {"SPRITE" : {"name": "0023","x":1143,"y":788,"w":67,"h":70,"rotated": false}},
{"SPRITE":{"name":"24","x":1244,"y":915,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0024","x":1033,"y":875,"w":122,"h":62,"rotated": false}},
{"SPRITE":{"name":"25","x":1777,"y":748,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0025","x":1217,"y":513,"w":64,"h":106,"rotated": false}},
{"SPRITE":{"name":"26","x":1933,"y":166,"w":106,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0026","x":1979,"y":359,"w":55,"h":112,"rotated": false}},
{"SPRITE":{"name":"27","x":1915,"y":737,"w":120,"h":86,"rotated":false}}, {"SPRITE" : {"name": "0027","x":799,"y":788,"w":98,"h":118,"rotated": false}},
{"SPRITE":{"name":"28","x":1800,"y":568,"w":89,"h":162,"rotated":false}}, {"SPRITE" : {"name": "0028","x":1979,"y":250,"w":59,"h":105,"rotated": false}},
{"SPRITE":{"name":"29","x":1907,"y":568,"w":95,"h":151,"rotated":false}}, {"SPRITE" : {"name": "0029","x":1434,"y":749,"w":87,"h":160,"rotated": false}},
{"SPRITE":{"name":"30","x":1977,"y":392,"w":61,"h":107,"rotated":false}}, {"SPRITE" : {"name": "0030","x":1525,"y":749,"w":92,"h":149,"rotated": false}},
{"SPRITE":{"name":"31","x":415,"y":998,"w":107,"h":45,"rotated":false}}, {"SPRITE" : {"name": "0031","x":219,"y":887,"w":104,"h":42,"rotated": false}},
{"SPRITE":{"name":"32","x":727,"y":993,"w":77,"h":22,"rotated":false}}, {"SPRITE" : {"name": "0032","x":527,"y":811,"w":73,"h":18,"rotated": false}},
{"SPRITE":{"name":"33","x":634,"y":998,"w":75,"h":23,"rotated":false}}, {"SPRITE" : {"name": "0033","x":527,"y":788,"w":72,"h":19,"rotated": false}},
{"SPRITE":{"name":"34","x":822,"y":993,"w":75,"h":22,"rotated":false}}, {"SPRITE" : {"name": "0034","x":527,"y":833,"w":72,"h":18,"rotated": false}},
{"SPRITE":{"name":"35","x":540,"y":998,"w":76,"h":24,"rotated":false}}, {"SPRITE" : {"name": "0035","x":1217,"y":623,"w":73,"h":20,"rotated": false}},
{"SPRITE":{"name":"36","x":1445,"y":0,"w":470,"h":259,"rotated":false}}, {"SPRITE" : {"name": "0036","x":344,"y":788,"w":179,"h":67,"rotated": false}},
{"SPRITE":{"name":"37","x":431,"y":0,"w":513,"h":249,"rotated":false}}, {"SPRITE" : {"name": "0037","x":219,"y":808,"w":118,"h":75,"rotated": false}},
{"SPRITE":{"name":"38","x":962,"y":0,"w":465,"h":265,"rotated":false}}, {"SPRITE" : {"name": "0038","x":901,"y":875,"w":128,"h":61,"rotated": false}},
{"SPRITE":{"name":"39","x":723,"y":670,"w":331,"h":164,"rotated":false}}, {"SPRITE" : {"name": "0039","x":1914,"y":885,"w":124,"h":58,"rotated": false}},
{"SPRITE":{"name":"40","x":0,"y":0,"w":413,"h":354,"rotated":false}}, {"SPRITE" : {"name": "0040","x":901,"y":788,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"41","x":0,"y":372,"w":400,"h":353,"rotated":false}}, {"SPRITE" : {"name": "0041","x":1022,"y":788,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"42","x":1548,"y":826,"w":90,"h":103,"rotated":false}}, {"SPRITE" : {"name": "0042","x":341,"y":859,"w":103,"h":83,"rotated": false}},
{"SPRITE":{"name":"43","x":1132,"y":571,"w":213,"h":239,"rotated":false}}, {"SPRITE" : {"name": "0043","x":4,"y":808,"w":117,"h":83,"rotated": false}},
{"SPRITE":{"name":"44","x":1363,"y":571,"w":211,"h":237,"rotated":false}}]}, {"SPRITE" : {"name": "0044","x":1434,"y":648,"w":174,"h":97,"rotated": false}},
"meta":{ {"SPRITE" : {"name": "0045","x":1819,"y":250,"w":82,"h":14,"rotated": false}}
"app":"Adobe Animate (Better TA Extension)", ]},
"version":"24.0.2.12", "meta": {
"image":"spritemap1.png", "app": "Adobe Animate",
"format":"RGBA8888", "version": "21.0.1.37179",
"size":{"w":2064,"h":1065}, "image": "spritemap1.png",
"resolution":"1" "format": "RGBA8888",
"size": {"w":2043,"h":966},
"resolution": "1"
}
} }
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 165 KiB

File diff suppressed because it is too large Load Diff
@@ -1,60 +1,60 @@
{"ATLAS":{"SPRITES":[ {"ATLAS": {"SPRITES":[
{"SPRITE":{"name":"0","x":2834,"y":332,"w":12,"h":15,"rotated":false}}, {"SPRITE" : {"name": "0000","x":4076,"y":2,"w":9,"h":12,"rotated": false}},
{"SPRITE":{"name":"1","x":1476,"y":532,"w":527,"h":503,"rotated":false}}, {"SPRITE" : {"name": "0001","x":1957,"y":2,"w":524,"h":501,"rotated": false}},
{"SPRITE":{"name":"2","x":733,"y":0,"w":725,"h":623,"rotated":false}}, {"SPRITE" : {"name": "0002","x":716,"y":2,"w":721,"h":621,"rotated": false}},
{"SPRITE":{"name":"3","x":0,"y":659,"w":741,"h":304,"rotated":false}}, {"SPRITE" : {"name": "0003","x":2331,"y":505,"w":139,"h":109,"rotated": false}},
{"SPRITE":{"name":"4","x":2311,"y":0,"w":349,"h":540,"rotated":false}}, {"SPRITE" : {"name": "0004","x":3244,"y":725,"w":303,"h":170,"rotated": false}},
{"SPRITE":{"name":"5","x":759,"y":641,"w":583,"h":373,"rotated":false}}, {"SPRITE" : {"name": "0005","x":1691,"y":516,"w":248,"h":277,"rotated": false}},
{"SPRITE":{"name":"6","x":2021,"y":0,"w":272,"h":702,"rotated":false}}, {"SPRITE" : {"name": "0006","x":2495,"y":843,"w":173,"h":229,"rotated": false}},
{"SPRITE":{"name":"7","x":1476,"y":0,"w":518,"h":514,"rotated":false}}, {"SPRITE" : {"name": "0007","x":2,"y":642,"w":262,"h":221,"rotated": false}},
{"SPRITE":{"name":"8","x":0,"y":0,"w":715,"h":641,"rotated":false}}, {"SPRITE" : {"name": "0008","x":2331,"y":616,"w":118,"h":117,"rotated": false}},
{"SPRITE":{"name":"9","x":619,"y":1032,"w":205,"h":122,"rotated":false}}, {"SPRITE" : {"name": "0009","x":3549,"y":865,"w":261,"h":139,"rotated": false}},
{"SPRITE":{"name":"10","x":842,"y":1032,"w":205,"h":122,"rotated":false}}, {"SPRITE" : {"name": "0010","x":3209,"y":897,"w":202,"h":122,"rotated": false}},
{"SPRITE":{"name":"11","x":2311,"y":558,"w":115,"h":112,"rotated":false}}, {"SPRITE" : {"name": "0011","x":580,"y":913,"w":202,"h":122,"rotated": false}},
{"SPRITE":{"name":"12","x":2801,"y":947,"w":305,"h":172,"rotated":false}}, {"SPRITE" : {"name": "0012","x":2831,"y":304,"w":45,"h":42,"rotated": false}},
{"SPRITE":{"name":"13","x":2678,"y":0,"w":375,"h":314,"rotated":false}}, {"SPRITE" : {"name": "0013","x":1957,"y":505,"w":372,"h":311,"rotated": false}},
{"SPRITE":{"name":"14","x":2870,"y":332,"w":252,"h":328,"rotated":false}}, {"SPRITE" : {"name": "0014","x":1439,"y":516,"w":250,"h":325,"rotated": false}},
{"SPRITE":{"name":"15","x":3071,"y":0,"w":239,"h":290,"rotated":false}}, {"SPRITE" : {"name": "0015","x":716,"y":625,"w":235,"h":286,"rotated": false}},
{"SPRITE":{"name":"16","x":3135,"y":678,"w":220,"h":246,"rotated":false}}, {"SPRITE" : {"name": "0016","x":953,"y":625,"w":245,"h":249,"rotated": false}},
{"SPRITE":{"name":"17","x":3597,"y":248,"w":173,"h":231,"rotated":false}}, {"SPRITE" : {"name": "0017","x":3644,"y":373,"w":136,"h":133,"rotated": false}},
{"SPRITE":{"name":"18","x":3769,"y":0,"w":225,"h":190,"rotated":false}}, {"SPRITE" : {"name": "0018","x":2331,"y":735,"w":150,"h":91,"rotated": false}},
{"SPRITE":{"name":"19","x":1290,"y":1053,"w":131,"h":81,"rotated":false}}, {"SPRITE" : {"name": "0019","x":3644,"y":508,"w":151,"h":95,"rotated": false}},
{"SPRITE":{"name":"20","x":3905,"y":814,"w":132,"h":85,"rotated":false}}, {"SPRITE" : {"name": "0020","x":784,"y":913,"w":140,"h":90,"rotated": false}},
{"SPRITE":{"name":"21","x":1733,"y":1053,"w":122,"h":80,"rotated":false}}, {"SPRITE" : {"name": "0021","x":3644,"y":605,"w":149,"h":92,"rotated": false}},
{"SPRITE":{"name":"22","x":3905,"y":917,"w":129,"h":82,"rotated":false}}, {"SPRITE" : {"name": "0022","x":2670,"y":932,"w":144,"h":87,"rotated": false}},
{"SPRITE":{"name":"23","x":1589,"y":1053,"w":126,"h":78,"rotated":false}}, {"SPRITE" : {"name": "0023","x":2670,"y":843,"w":152,"h":87,"rotated": false}},
{"SPRITE":{"name":"24","x":1439,"y":1053,"w":132,"h":77,"rotated":false}}, {"SPRITE" : {"name": "0024","x":4087,"y":2,"w":1,"h":4,"rotated": false}},
{"SPRITE":{"name":"25","x":3778,"y":814,"w":109,"h":107,"rotated":false}}, {"SPRITE" : {"name": "0025","x":2831,"y":373,"w":411,"h":352,"rotated": false}},
{"SPRITE":{"name":"26","x":3124,"y":1123,"w":3,"h":7,"rotated":false}}, {"SPRITE" : {"name": "0026","x":3244,"y":373,"w":398,"h":350,"rotated": false}},
{"SPRITE":{"name":"27","x":3145,"y":1123,"w":3,"h":7,"rotated":false}}, {"SPRITE" : {"name": "0027","x":266,"y":642,"w":329,"h":162,"rotated": false}},
{"SPRITE":{"name":"28","x":3673,"y":497,"w":260,"h":141,"rotated":false}}, {"SPRITE" : {"name": "0028","x":597,"y":642,"w":90,"h":103,"rotated": false}},
{"SPRITE":{"name":"29","x":3788,"y":208,"w":237,"h":161,"rotated":false}}, {"SPRITE" : {"name": "0029","x":1200,"y":625,"w":211,"h":236,"rotated": false}},
{"SPRITE":{"name":"30","x":3542,"y":660,"w":218,"h":144,"rotated":false}}, {"SPRITE" : {"name": "0030","x":2831,"y":727,"w":208,"h":235,"rotated": false}},
{"SPRITE":{"name":"31","x":3124,"y":947,"w":301,"h":158,"rotated":false}}, {"SPRITE" : {"name": "0031","x":2483,"y":2,"w":738,"h":300,"rotated": false}},
{"SPRITE":{"name":"32","x":3371,"y":498,"w":284,"h":144,"rotated":false}}, {"SPRITE" : {"name": "0032","x":2483,"y":304,"w":346,"h":537,"rotated": false}},
{"SPRITE":{"name":"33","x":0,"y":981,"w":295,"h":150,"rotated":false}}, {"SPRITE" : {"name": "0033","x":2,"y":865,"w":235,"h":158,"rotated": false}},
{"SPRITE":{"name":"34","x":313,"y":981,"w":288,"h":145,"rotated":false}}, {"SPRITE" : {"name": "0034","x":3812,"y":865,"w":216,"h":141,"rotated": false}},
{"SPRITE":{"name":"35","x":3443,"y":942,"w":182,"h":212,"rotated":false}}, {"SPRITE" : {"name": "0035","x":2000,"y":818,"w":299,"h":155,"rotated": false}},
{"SPRITE":{"name":"36","x":3371,"y":255,"w":208,"h":225,"rotated":false}}, {"SPRITE" : {"name": "0036","x":1200,"y":863,"w":179,"h":208,"rotated": false}},
{"SPRITE":{"name":"37","x":3373,"y":660,"w":151,"h":264,"rotated":false}}, {"SPRITE" : {"name": "0037","x":1691,"y":818,"w":307,"h":154,"rotated": false}},
{"SPRITE":{"name":"38","x":3778,"y":656,"w":206,"h":140,"rotated":false}}, {"SPRITE" : {"name": "0038","x":3644,"y":702,"w":320,"h":161,"rotated": false}},
{"SPRITE":{"name":"39","x":3557,"y":0,"w":194,"h":230,"rotated":false}}, {"SPRITE" : {"name": "0039","x":266,"y":806,"w":312,"h":155,"rotated": false}},
{"SPRITE":{"name":"40","x":2678,"y":485,"w":47,"h":44,"rotated":false}}, {"SPRITE" : {"name": "0040","x":239,"y":963,"w":224,"h":108,"rotated": false}},
{"SPRITE":{"name":"41","x":2870,"y":678,"w":247,"h":251,"rotated":false}}, {"SPRITE" : {"name": "0041","x":3223,"y":2,"w":580,"h":369,"rotated": false}},
{"SPRITE":{"name":"42","x":2678,"y":332,"w":138,"h":135,"rotated":false}}, {"SPRITE" : {"name": "0042","x":3805,"y":2,"w":269,"h":698,"rotated": false}},
{"SPRITE":{"name":"43","x":1065,"y":1053,"w":207,"h":101,"rotated":false}}, {"SPRITE" : {"name": "0043","x":1413,"y":843,"w":205,"h":222,"rotated": false}},
{"SPRITE":{"name":"44","x":2452,"y":947,"w":331,"h":164,"rotated":false}}, {"SPRITE" : {"name": "0044","x":3041,"y":727,"w":166,"h":292,"rotated": false}},
{"SPRITE":{"name":"45","x":2021,"y":720,"w":413,"h":354,"rotated":false}}, {"SPRITE" : {"name": "0045","x":953,"y":876,"w":203,"h":137,"rotated": false}},
{"SPRITE":{"name":"46","x":2452,"y":558,"w":400,"h":353,"rotated":false}}, {"SPRITE" : {"name": "0046","x":1439,"y":2,"w":516,"h":512,"rotated": false}},
{"SPRITE":{"name":"47","x":3951,"y":387,"w":90,"h":103,"rotated":false}}, {"SPRITE" : {"name": "0047","x":2,"y":2,"w":712,"h":638,"rotated": false}},
{"SPRITE":{"name":"48","x":3140,"y":308,"w":213,"h":239,"rotated":false}}, {"SPRITE" : {"name": "0048","x":2301,"y":843,"w":192,"h":227,"rotated": false}}
{"SPRITE":{"name":"49","x":3328,"y":0,"w":211,"h":237,"rotated":false}}]}, ]},
"meta":{ "meta": {
"app":"Adobe Animate (Better TA Extension)", "app": "Adobe Animate",
"version":"24.0.2.12", "version": "21.0.1.37179",
"image":"spritemap1.png", "image": "spritemap1.png",
"format":"RGBA8888", "format": "RGBA8888",
"size":{"w":4061,"h":1154}, "size": {"w":4090,"h":1074},
"resolution":"1" "resolution": "1"
}
} }
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 KiB

After

Width:  |  Height:  |  Size: 344 KiB

-2
View File
@@ -433,8 +433,6 @@
<str id="position">Position (X, Y)</str> <str id="position">Position (X, Y)</str>
<str id="fps">FPS</str> <str id="fps">FPS</str>
<str id="indices">Indices (Frames)</str> <str id="indices">Indices (Frames)</str>
<str id="looping">Looping?</str>
<str id="label">Label</str>
</group> </group>
<group name="CharacterSpriteScreen" prefix="characterSpriteScreen."> <group name="CharacterSpriteScreen" prefix="characterSpriteScreen.">
-1
View File
@@ -48,7 +48,6 @@
<str id="category.engine">Engine</str> <str id="category.engine">Engine</str>
<group name="engine" prefix="engine."> <group name="engine" prefix="engine.">
<str id="switchMod">Switch Mod</str> <str id="switchMod">Switch Mod</str>
<str id="fpsCounter">FPS Counter</str>
</group> </group>
<str id="category.volume">Volume</str> <str id="category.volume">Volume</str>
+1 -2
View File
@@ -46,9 +46,8 @@
<group name="engine" prefix="engine."> <group name="engine" prefix="engine.">
<str id="switchMod">Cambiar Mod</str> <str id="switchMod">Cambiar Mod</str>
<str id="fpsCounter">Contador de FPS</str>
</group> </group>
<str id="category.volume">Volumen</str> <str id="category.volume">Volumen</str>
<str id="volume.up">Arriba</str> <str id="volume.up">Arriba</str>
<str id="volume.down">Abajo</str> <str id="volume.down">Abajo</str>
-1
View File
@@ -46,7 +46,6 @@
<group name="engine" prefix="engine."> <group name="engine" prefix="engine.">
<str id="switchMod">Cambia Mod</str> <str id="switchMod">Cambia Mod</str>
<str id="fpsCounter">Contatore FPS</str>
</group> </group>
<str id="volume.up">Su</str> <str id="volume.up">Su</str>
+1 -2
View File
@@ -44,9 +44,8 @@
<str id="category.engine">Silnik</str> <str id="category.engine">Silnik</str>
<group name="engine" prefix="engine."> <group name="engine" prefix="engine.">
<str id="switchMod">Zmień Moda</str> <str id="switchMod">Zmień Moda</str>
<str id="fpsCounter">Licznik FPS</str>
</group> </group>
<str id="category.volume">Głośność</str> <str id="category.volume">Głośność</str>
<str id="volume.up">Głóśniej</str> <str id="volume.up">Głóśniej</str>
<str id="volume.down">Ciszej</str> <str id="volume.down">Ciszej</str>
-1
View File
@@ -48,7 +48,6 @@
<str id="category.engine">Codename Engine</str> <str id="category.engine">Codename Engine</str>
<group name="engine" prefix="engine."> <group name="engine" prefix="engine.">
<str id="switchMod">Trocar Mod</str> <str id="switchMod">Trocar Mod</str>
<str id="fpsCounter">Contador de FPS</str>
</group> </group>
<str id="category.volume">Volume</str> <str id="category.volume">Volume</str>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -22
View File
@@ -1,6 +1,6 @@
# Compiling Codename Engine Here's the full guide on how to setup and compile Codename Engine!<br>
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.** > **Open the instructions for your platform**
<details> <details>
<summary>Windows</summary> <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> > 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). > 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. > - 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.
+6 -9
View File
@@ -1,17 +1,14 @@
[General] [general]
sample-type=float32 sample-type=float32
stereo-mode=speakers stereo-mode=speakers
stereo-encoding=panpot
hrtf=false hrtf=false
cf_level=0 cf_level=0
resampler=fast_bsinc24
front-stablizer=false
output-limiter=false output-limiter=false
front-stabilizer=false
volume-adjust=0 volume-adjust=0
period_size=441
sources=512
sends=64
dither=false
[decoder] [decoder]
hq-mode=true hq-mode=false
distance-comp=true distance-comp=false
nfc=false nfc=false
-13
View File
@@ -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."
-8
View File
@@ -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 -5
View File
@@ -4,8 +4,8 @@
<print pretty="true">Preparing installation...</print> <print pretty="true">Preparing installation...</print>
<!-- OpenFL & Lime (Required for Flixel) --> <!-- OpenFL & Lime (Required for Flixel) -->
<git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" ref="old" /> <git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" />
<lib name="lime" version="8.1.2" /> <lib name="lime" version="8.2.0" />
<!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed --> <!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed -->
<!-- Flixel --> <!-- Flixel -->
@@ -14,8 +14,9 @@
<!-- Other Libraries --> <!-- Other Libraries -->
<git name="hscript-improved" url="https://github.com/CodenameCrew/hscript-improved" ref="codename-dev" /> <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" /> <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" /> <lib name="hxvlc" version="1.9.3" skipDeps="true" />
<!-- Documentation and other features --> <!-- Documentation and other features -->
@@ -31,8 +32,6 @@
<lib global="true" name="format" /> <lib name="format" /> <lib global="true" name="format" /> <lib name="format" />
<git name="hxcpp" url="https://github.com/CodenameCrew/cne-hxcpp" /> <git name="hxcpp" url="https://github.com/CodenameCrew/cne-hxcpp" />
<git name="flixel-animate" url="https://github.com/MaybeMaru/flixel-animate/" skipDeps="true"/>
</if> </if>
<!-- Hxcpp Building --> <!-- Hxcpp Building -->
+4 -33
View File
@@ -19,7 +19,7 @@
<!--Switch Export with Unique ApplicationID and Icon--> <!--Switch Export with Unique ApplicationID and Icon-->
<set name="APP_ID" value="0x0100f6c013bbc000" /> <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" /> <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 <!--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 _______________________________ --> <!-- _________________________________ Engine Settings _______________________________ -->
<!-- Comment this out to disable updates !--> <!-- 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 !--> <!-- Comment this out to disable Discord RPC !-->
<section if="cpp"> <section if="cpp">
@@ -72,11 +72,7 @@
<!-- Comment this out to prevent extending classes in hscript. <!-- Comment this out to prevent extending classes in hscript.
Reduces compilation time at the cost of limited HScript flexibility. !--> Reduces compilation time at the cost of limited HScript flexibility. !-->
<define name="CUSTOM_CLASSES" unless="STRIPPED_COMPILE"/> <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"/>
<!-- Comment this out to disable multithreading !--> <!-- Comment this out to disable multithreading !-->
<haxedef name="ALLOW_MULTITHREADING" unless="web || flash" /> <haxedef name="ALLOW_MULTITHREADING" unless="web || flash" />
@@ -119,24 +115,6 @@
<!-- Disable a optimization, to allow reflection to use more functions --> <!-- Disable a optimization, to allow reflection to use more functions -->
<define name="FLX_NO_GENERIC" /> <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 ______________________________ --> <!-- _______________________________ Libraries ______________________________ -->
<!-- KEEP BOTH OF THESE AS THERE ARE SOME PARTICULAR CASES! --> <!-- KEEP BOTH OF THESE AS THERE ARE SOME PARTICULAR CASES! -->
@@ -152,7 +130,7 @@
<haxelib name="hxvlc" if="VIDEO_CUTSCENES" /> <haxelib name="hxvlc" if="VIDEO_CUTSCENES" />
<haxelib name="away3d" if="THREE_D_SUPPORT" /> <haxelib name="away3d" if="THREE_D_SUPPORT" />
<haxelib name="format" /> <haxelib name="format" />
<haxelib name="flixel-animate" /> <haxelib name="flxanimate" />
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/> <haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
<haxelib name="hscript-improved" /> <haxelib name="hscript-improved" />
@@ -194,8 +172,6 @@
<!-- ______________________________ Haxedefines _____________________________ --> <!-- ______________________________ Haxedefines _____________________________ -->
<haxeflag name="--macro" value="funkin.backend.system.macros.BuildInfo.printBuildInfo()" unless="display" />
<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" /> <haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!--> <!--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="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" /> <haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
<!-- Disable it for more concise compilation errors. -->
<haxedef name="message.reporting" value="pretty" />
<!-- _________________________________ Custom _______________________________ --> <!-- _________________________________ Custom _______________________________ -->
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)--> <!--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()"/> <haxeflag name="--macro" value="modchart.backend.macros.Macro.includeFiles()"/>
</section> </section>
<section if="COMPILE_ALL_CLASSES"> <section if="COMPILE_ALL_CLASSES">
<haxeflag name="-dce" value="no" /> <haxeflag name="-dce" value="no" />
<haxeflag name="--macro" value="funkin.backend.system.macros.Macros.addAdditionalClasses()" /> <haxeflag name="--macro" value="funkin.backend.system.macros.Macros.addAdditionalClasses()" />
</section> </section>
+494
View File
@@ -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);
}
}
+39 -70
View File
@@ -21,7 +21,6 @@ import flixel.math.FlxMath;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.system.FlxAssets.FlxSoundAsset; import flixel.system.FlxAssets.FlxSoundAsset;
import flixel.tweens.FlxTween; import flixel.tweens.FlxTween;
import flixel.util.FlxDestroyUtil;
import flixel.util.FlxSignal; import flixel.util.FlxSignal;
import flixel.util.FlxStringUtil; import flixel.util.FlxStringUtil;
import flixel.FlxBasic; import flixel.FlxBasic;
@@ -137,18 +136,11 @@ class FlxSound extends FlxBasic {
public var radius:Float; public var radius:Float;
/** /**
* Whether the proximity alters the pan or not. * Whether the proximity alters the pan or not
* @since raltyMod * @since raltyMod
*/ */
public var proximityPan:Bool; 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. * Stores for how much channels are in the loaded sound.
* @since raltyMod * @since raltyMod
@@ -310,8 +302,6 @@ class FlxSound extends FlxBasic {
_lastTime = null; _lastTime = null;
if (destroySound) { if (destroySound) {
scrollFactor = FlxDestroyUtil.put(scrollFactor);
if (group != null) group.remove(this); if (group != null) group.remove(this);
if (_channel != null) { if (_channel != null) {
@@ -358,24 +348,15 @@ class FlxSound extends FlxBasic {
_amplitudeUpdate = true; _amplitudeUpdate = true;
// Distance-based volume control // Distance-based volume control (TODO for Ralty: REDO THIS)
if (target != null) { if (target != null) {
var targetPosition = target.getPosition(), position = getPosition(); var targetPosition = target.getPosition();
var camera = camera; var radialMultiplier = targetPosition.distanceTo(FlxPoint.weak(x, y)) / radius;
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;
targetPosition.put(); targetPosition.put();
position.put(); radialMultiplier = 1 - FlxMath.bound(radialMultiplier, 0, 1);
_volumeAdjust = radialMultiplier;
if (proximityPan) _panAdjust = (x - target.x) / radius;
} }
else else
_volumeAdjust = 1.0; _volumeAdjust = 1.0;
@@ -555,15 +536,12 @@ class FlxSound extends FlxBasic {
* @param Pan Whether panning should be used in addition to the volume changes. * @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). * @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); setPosition(x, y);
if (targetObject != null) this.target = targetObject; if (targetObject != null) this.target = targetObject;
if (radius != null) this.radius = radius; if (radius != null) this.radius = radius;
proximityPan = pan; proximityPan = pan;
if (this.scrollFactor == null) this.scrollFactor = FlxPoint.get(1, 1);
if (scrollFactor != null) this.scrollFactor.copyFrom(scrollFactor);
return this; return this;
} }
@@ -571,28 +549,14 @@ class FlxSound extends FlxBasic {
* Helper function to set the coordinates of this object. * Helper function to set the coordinates of this object.
* Sound positioning is used in conjunction with proximity/panning. * Sound positioning is used in conjunction with proximity/panning.
* *
* @param x The new x position * @param x The new x position
* @param y The new y 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.x = x;
this.y = y; 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. * Call this function to play the sound - also works on paused sounds.
* *
@@ -718,7 +682,7 @@ class FlxSound extends FlxBasic {
_paused = false; _paused = false;
_time = startTime; _time = startTime;
_lastTime = FlxG.game.getTicks(); _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(); makeChannel();
if (_channel != null) { if (_channel != null) {
@@ -769,8 +733,7 @@ class FlxSound extends FlxBasic {
_lastTime = FlxG.game.getTicks(); _lastTime = FlxG.game.getTicks();
_time = loopTime; _time = loopTime;
} }
else if (_source != null) else _channel.loops = 999;
_source.loops = 999;
} }
/** /**
@@ -800,7 +763,7 @@ class FlxSound extends FlxBasic {
} }
inline function get_playing():Bool @:privateAccess inline function get_playing():Bool @:privateAccess
return _source != null && _source.playing; return _channel != null && _channel.__isValid && _source.playing;
inline function get_volume():Float inline function get_volume():Float
return _volume; return _volume;
@@ -833,12 +796,12 @@ class FlxSound extends FlxBasic {
inline function get_buffer():AudioBuffer inline function get_buffer():AudioBuffer
@:privateAccess return _sound != null ? _sound.__buffer : null; @:privateAccess return _sound != null ? _sound.__buffer : null;
inline function update_amplitude():Void @:privateAccess { function update_amplitude():Void @:privateAccess {
if (_channel != null && _channel.__updatePeaks(get_time()) && _amplitudeUpdate) { if (_channel == null || !_channel.__updatePeaks(get_time()) || !_amplitudeUpdate) return;
_amplitudeUpdate = false;
_amplitudeLeft = _channel.__leftPeak; _amplitudeUpdate = false;
_amplitudeRight = _channel.__rightPeak; _amplitudeLeft = _channel.__leftPeak;
} _amplitudeRight = _channel.__rightPeak;
} }
inline function get_amplitudeLeft():Float { inline function get_amplitudeLeft():Float {
@@ -866,27 +829,30 @@ class FlxSound extends FlxBasic {
inline function get_pitch():Float inline function get_pitch():Float
return _pitch; return _pitch;
inline function set_pitch(v:Float):Float { function set_pitch(v:Float):Float {
_realPitch = (_pitch = v) * _timeScaleAdjust; _realPitch = (_pitch = v) * _timeScaleAdjust;
if (_source != null) _source.pitch = _realPitch; if (_channel != null) _channel.pitch = _realPitch;
return _pitch; return _pitch;
} }
#end #end
function set_looped(v:Bool):Bool { 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; return looped = v;
} }
function set_loopTime(v:Float):Float { function set_loopTime(v:Float):Float {
if (playing) _source.loopTime = v; if (playing) _channel.loopTime = v;
return loopTime = v; return loopTime = v;
} }
function set_endTime(v:Null<Float>):Null<Float> { function set_endTime(v:Null<Float>):Null<Float> {
if (playing) { if (playing) {
if (v != null && v > 0 && v < _length) _source.length = v; if (v != null && v > 0 && v < _length) _channel.endTime = v;
else _source.length = null; else _channel.endTime = null;
} }
return endTime = v; return endTime = v;
} }
@@ -898,7 +864,7 @@ class FlxSound extends FlxBasic {
return _time; return _time;
} }
function get_time():Float { 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; final sourceTime = _source.currentTime - _source.offset - _offset;
if (!_source.playing || _realPitch <= 0) { if (!_source.playing || _realPitch <= 0) {
@@ -937,21 +903,24 @@ class FlxSound extends FlxBasic {
return _time = time; return _time = time;
} }
function get_offset():Float return _offset; inline function get_offset():Float return _offset;
function set_offset(offset:Float):Float { inline function set_offset(offset:Float):Float {
if (_offset == (_offset = offset)) return offset; if (_offset == (_offset = offset)) return offset;
//time = time + _offset; //time = time + _offset;
return 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 { override function toString():String {
return FlxStringUtil.getDebugString([ return FlxStringUtil.getDebugString([
LabelValuePair.weak("playing", playing), LabelValuePair.weak("playing", playing),
LabelValuePair.weak("time", time), LabelValuePair.weak("time", _time),
LabelValuePair.weak("length", length), LabelValuePair.weak("length", length),
LabelValuePair.weak("volume", volume), LabelValuePair.weak("volume", volume),
LabelValuePair.weak("pitch", pitch) LabelValuePair.weak("pitch", pitch)
+92
View File
@@ -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;
}
}
+144 -111
View File
@@ -1,7 +1,5 @@
package funkin.backend; package funkin.backend;
import animate.FlxAnimate;
import animate.FlxAnimateController.FlxAnimateAnimation;
import flixel.addons.effects.FlxSkewedSprite; import flixel.addons.effects.FlxSkewedSprite;
import flixel.animation.FlxAnimation; import flixel.animation.FlxAnimation;
import flixel.math.FlxMatrix; import flixel.math.FlxMatrix;
@@ -9,6 +7,7 @@ import flixel.math.FlxPoint;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import flixel.system.FlxAssets.FlxGraphicAsset; import flixel.system.FlxAssets.FlxGraphicAsset;
import flixel.util.typeLimit.OneOfTwo; import flixel.util.typeLimit.OneOfTwo;
import flxanimate.animate.FlxAnim.FlxSymbolAnimation;
import funkin.backend.scripting.events.sprite.PlayAnimContext; import funkin.backend.scripting.events.sprite.PlayAnimContext;
import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.backend.system.interfaces.IOffsetCompatible; 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.BeatAnim;
import funkin.backend.utils.XMLUtil.IXMLEvents; import funkin.backend.utils.XMLUtil.IXMLEvents;
import haxe.io.Path; import haxe.io.Path;
import flixel.graphics.frames.FlxFrame;
import flixel.math.FlxAngle;
import animate.internal.RenderTexture;
import animate.FlxAnimateFrames;
enum abstract XMLAnimType(Int) 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> = []; 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 animEnabled:Bool = true;
public var zoomFactorEnabled:Bool = true; public var zoomFactorEnabled:Bool = true;
//Backwards compatibility
public var animateAtlas(get, never):FunkinSprite;
public var globalCurFrame(get, set):Int; 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 beatOffset:Int = 0;
public var skipNegativeBeats:Bool = false; public var skipNegativeBeats:Bool = false;
public var animateSettings:FlxAnimateSettings = {}; public var animateAtlas:FlxAnimate;
@:noCompletion public var atlasPlayingAnim:String;
var _rect2:FlxRect; @:noCompletion public var atlasPath:String;
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset) 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; moves = false;
applyStageMatrix = true;
} }
/** /**
@@ -107,6 +98,8 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
@:privateAccess { @:privateAccess {
spr.setPosition(source.x, source.y); spr.setPosition(source.x, source.y);
spr.frames = source.frames; spr.frames = source.frames;
if (casted != null && casted.animateAtlas != null && casted.atlasPath != null)
spr.loadSprite(casted.atlasPath);
spr.animation.copyFrom(source.animation); spr.animation.copyFrom(source.animation);
spr.visible = source.visible; spr.visible = source.visible;
spr.alpha = source.alpha; spr.alpha = source.alpha;
@@ -116,8 +109,9 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
if (casted != null) { if (casted != null) {
spr.skew.set(casted.skew.x, casted.skew.y); spr.skew.set(casted.skew.x, casted.skew.y);
spr.transformMatrix = casted.transformMatrix;
spr.matrixExposed = casted.matrixExposed;
spr.animOffsets = casted.animOffsets.copy(); spr.animOffsets = casted.animOffsets.copy();
spr.zoomFactor = casted.zoomFactor;
} }
} }
return spr; return spr;
@@ -126,6 +120,8 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
public override function update(elapsed:Float) public override function update(elapsed:Float)
{ {
super.update(elapsed); super.update(elapsed);
if (animateAtlas != null)
animateAtlas.update(elapsed);
// hate how it looks like but hey at least its optimized and fast - Nex // hate how it looks like but hey at least its optimized and fast - Nex
if (!debugMode && isAnimFinished()) { 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) public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
{ {
var noExt = Path.withoutExtension(path); 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; return this;
} }
@@ -175,9 +174,48 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
// ANIMATE ATLAS DRAWING // ANIMATE ATLAS DRAWING
#if REGION #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() public override function destroy()
{ {
animateAtlas = FlxDestroyUtil.destroy(animateAtlas);
if (animOffsets != null) { if (animOffsets != null) {
for (key in animOffsets.keys()) { for (key in animOffsets.keys()) {
final point = animOffsets[key]; final point = animOffsets[key];
@@ -188,8 +226,6 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
animOffsets = null; animOffsets = null;
} }
super.destroy(); super.destroy();
_rect2 = FlxDestroyUtil.put(_rect2);
} }
#end #end
@@ -197,21 +233,27 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
private inline function __shouldDoZoomFactor() private inline function __shouldDoZoomFactor()
return zoomFactorEnabled && zoomFactor != 1; return zoomFactorEnabled && zoomFactor != 1;
private inline function __prepareZoomFactor(?rect:FlxRect, camera:FlxCamera):FlxRect { public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
if (Flags.USE_LEGACY_ZOOM_FACTOR) {
return (rect ?? FlxRect.get()).set( if (camera == null)
camera.width * 0.5, camera = FlxG.camera;
camera.height * 0.5,
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)), var r = super.getScreenBounds(newRect, camera);
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor))
); if(__shouldDoZoomFactor()) {
else r.x -= camera.width / 2;
return (rect ?? FlxRect.get()).set( r.y -= camera.height / 2;
camera.width * 0.5 + camera.scroll.x * scrollFactor.x,
camera.height * 0.5 + camera.scroll.y * scrollFactor.y, var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor));
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)), r.x *= ratio;
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor)) 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 override public function isOnScreen(?camera:FlxCamera):Bool
@@ -228,6 +270,20 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
return camera.containsRect(bounds); 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 // OFFSETTING
#if REGION #if REGION
public var animOffsets:Map<String, FlxPoint> = new Map<String, FlxPoint>(); 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; 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); var daOffset = getAnimOffset(AnimName);
frameOffset.set(daOffset.x, daOffset.y); frameOffset.set(daOffset.x, daOffset.y);
@@ -268,7 +330,7 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
lastAnimContext = Context; 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, { return XMLUtil.addAnimToSprite(this, {
name: name, name: name,
@@ -279,16 +341,22 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
x: x, x: x,
y: y, y: y,
indices: indices, indices: indices,
forced: forced, forced: forced
label: animateAtlasLabel
}); });
} }
public inline function removeAnim(name:String) { public inline function removeAnim(name:String)
animation.remove(name); {
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); return animation.getByName(name);
} }
@@ -299,26 +367,40 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
return FlxPoint.weak(0, 0); return FlxPoint.weak(0, 0);
} }
public inline function hasAnim(AnimName:String):Bool public inline function hasAnim(AnimName:String):Bool @:privateAccess
return animation.exists(AnimName); return animateAtlas != null ? (animateAtlas.anim.animsMap.exists(AnimName)
|| animateAtlas.anim.symbolDictionary.exists(AnimName)) : animation.exists(AnimName);
public inline function getAnimName() public inline function getAnimName() {
return animation.name; return (animateAtlas != null) ? atlasPlayingAnim : animation.name;
}
public inline function isAnimReversed():Bool public inline function isAnimReversed():Bool {
return animation.curAnim?.reversed ?? false; return animateAtlas != null ? animateAtlas.anim.reversed : animation.curAnim != null ? animation.curAnim.reversed : false;
}
public inline function getNameList():Array<String> public inline function getNameList():Array<String> {
return animation.getNameList(); if (animateAtlas != null)
return [for (name in @:privateAccess animateAtlas.anim.animsMap.keys()) name];
else
return animation.getNameList();
}
public inline function stopAnim() public inline function stopAnim()
animation.stop(); {
if (animateAtlas != null)
animateAtlas.anim.pause();
else
animation.stop();
}
public inline function isAnimFinished() public inline function isAnimFinished() {
return animation.curAnim?.finished ?? true; return animateAtlas != null ? animateAtlas.anim.finished : (animation.curAnim != null ? animation.curAnim.finished : true);
}
public inline function isAnimAtEnd() public inline function isAnimAtEnd() {
return animation.curAnim?.isAtEnd ?? false; return animateAtlas != null ? animateAtlas.anim.isAtEnd : (animation.curAnim != null ? animation.curAnim.isAtEnd : false);
}
override function updateAnimation(elapsed:Float) { override function updateAnimation(elapsed:Float) {
if (animEnabled) if (animEnabled)
@@ -340,59 +422,10 @@ class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffse
return beatInterval = v; return beatInterval = v;
} }
@:noCompletion @:noCompletion private inline function get_globalCurFrame() {
@:deprecated("`FunkinSprite.animateAtlas` is deprecated, just use `FunkinSprite` instead") return animateAtlas != null ? (animateAtlas.anim.curFrame) : (animation.curAnim != null ? animation.curAnim.curFrame : 0);
public function get_animateAtlas():FunkinSprite }
return isAnimate ? this : null;
@:noCompletion private inline function get_globalCurFrame()
return animation.curAnim?.curFrame ?? 0;
@:noCompletion private inline function set_globalCurFrame(val:Int) { @:noCompletion private inline function set_globalCurFrame(val:Int) {
if (animation.curAnim != null) return animateAtlas != null ? (animateAtlas.anim.curFrame = val) : (animation.curAnim != null ? animation.curAnim.curFrame = val : val);
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;
} }
} }
@@ -236,12 +236,6 @@ class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState); 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) { public override function onResize(w:Int, h:Int) {
super.onResize(w, h); super.onResize(w, h);
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null)); event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
+6 -2
View File
@@ -114,8 +114,12 @@ class MusicBeatTransition extends MusicBeatSubstate {
} }
if (transitionSprite != null) { if (transitionSprite != null) {
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height); if (transitionSprite.animateAtlas == null) {
transitionSprite.updateHitbox(); transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
transitionSprite.updateHitbox();
} else {
transitionSprite.screenCenter();
}
} }
} }
@@ -5,7 +5,6 @@ import funkin.backend.assets.TranslatedAssetLibrary;
#end #end
import funkin.backend.assets.IModsAssetLibrary; import funkin.backend.assets.IModsAssetLibrary;
import lime.utils.AssetLibrary; import lime.utils.AssetLibrary;
import haxe.ds.Map;
class AssetsLibraryList extends AssetLibrary { class AssetsLibraryList extends AssetLibrary {
public var libraries:Array<AssetLibrary> = []; public var libraries:Array<AssetLibrary> = [];
@@ -142,16 +141,6 @@ class AssetsLibraryList extends AssetLibrary {
public override inline function getAsset(id:String, type:String):Dynamic public override inline function getAsset(id:String, type:String):Dynamic
return getSpecificAsset(id, type, BOTH); 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) { public override function isLocal(id:String, type:String) {
return true; return true;
} }
@@ -149,22 +149,6 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
} }
return true; 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 #end
// Backwards compat // Backwards compat
+3 -9
View File
@@ -8,7 +8,6 @@ import funkin.backend.scripting.Script;
import haxe.io.Path; import haxe.io.Path;
import lime.utils.AssetLibrary; import lime.utils.AssetLibrary;
import openfl.utils.Assets as OpenFlAssets; import openfl.utils.Assets as OpenFlAssets;
import animate.FlxAnimateFrames;
using StringTools; using StringTools;
@@ -175,9 +174,6 @@ class Paths
inline static public function getSparrowAtlas(key:String, ?library:String, ?ext:String) inline static public function getSparrowAtlas(key:String, ?library:String, ?ext:String)
return FlxAtlasFrames.fromSparrow(image(key, library, ext), file('images/$key.xml', library)); 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) inline static public function getSparrowAtlasAlt(key:String, ?ext:String)
return FlxAtlasFrames.fromSparrow('$key.${ext != null ? ext : Flags.IMAGE_EXT}', '$key.xml'); 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 key Path to the frames
* @param library (Additional) library to load the frames from. * @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)) { if (tempFramesCache.exists(key)) {
var frames = tempFramesCache[key]; var frames = tempFramesCache[key];
if (frames != null && frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable) if (frames != null && frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable)
@@ -209,7 +205,7 @@ class Paths
else else
tempFramesCache.remove(key); 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. * @param Ext Extension of the image.
* @return FlxFramesCollection Frames * @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 noExt = Path.withoutExtension(path);
var ext = Ext != null ? Ext : Flags.IMAGE_EXT; var ext = Ext != null ? Ext : Flags.IMAGE_EXT;
@@ -267,8 +263,6 @@ class Paths
cur++; cur++;
} }
return finalFrames; return finalFrames;
} else if (Assets.exists('$noExt/Animation.json')) {
return Paths.getAnimateAtlasAlt(noExt, animateSettings);
} else if (Assets.exists('$noExt.xml')) { } else if (Assets.exists('$noExt.xml')) {
return Paths.getSparrowAtlasAlt(noExt, ext); return Paths.getSparrowAtlasAlt(noExt, ext);
} else if (Assets.exists('$noExt.txt')) { } else if (Assets.exists('$noExt.txt')) {
@@ -108,8 +108,6 @@ class TranslatedAssetLibrary extends AssetLibrary implements IModsAssetLibrary {
return null; return null;
} }
// TODO: list support for TranslatedAssetLibrary (idk how it works)
#if MOD_SUPPORT #if MOD_SUPPORT
public var _parsedAsset:String = null; // Theres no need to actually make this work - Nex 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 = SysZip.openFromFile(basePath);
zip.read(); zip.read();
for(entry in zip.entries) { 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; lowerCaseAssets[entry.fileName.toLowerCase()] = assets[entry.fileName.toLowerCase()] = assets[entry.fileName] = entry;
nameMap.set(entry.fileName.toLowerCase(), entry.fileName); nameMap.set(entry.fileName.toLowerCase(), entry.fileName);
} }
@@ -157,10 +154,6 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
return content; return content;
} }
public override function list(type:String):Array<String> {
return[for(k=>e in nameMap) '$prefix$e'];
}
// Backwards compat // Backwards compat
@:noCompletion public var zipPath(get, set):String; @:noCompletion public var zipPath(get, set):String;
-1
View File
@@ -300,7 +300,6 @@ class Chart {
var eventsPath = '$songPath/events$variantSuffix.json', events = filterEventsForSaving(chart.events, false, true); 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)); 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 #end
+1 -3
View File
@@ -179,8 +179,7 @@ class EventsData {
finalParams.push({ finalParams.push({
name: paramData.name, name: paramData.name,
type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)), type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
defValue: paramData.defaultValue, defValue: paramData.defaultValue
saveIfDefault: paramData.saveIfDefault
}); });
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);} } catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
} }
@@ -197,7 +196,6 @@ typedef EventInfoFile = {
var name:String; var name:String;
var type:String; var type:String;
var defaultValue:Dynamic; var defaultValue:Dynamic;
var ?saveIfDefault:Bool;
}>; }>;
} }
+1 -1
View File
@@ -60,7 +60,7 @@ class PsychParser {
note.time, // TIME note.time, // TIME
note.id, // DATA note.id, // DATA
note.sLen, // SUSTAIN LENGTH 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) || if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
@@ -55,6 +55,9 @@ class GlobalScript {
reloading = false; reloading = false;
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload; MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
} }
if (PlayerSettings.solo.controls.DEV_CONSOLE)
NativeAPI.allocConsole();
}); });
FlxG.signals.preDraw.add(function() { FlxG.signals.preDraw.add(function() {
call("preDraw"); call("preDraw");
@@ -1,8 +1,14 @@
package funkin.backend.scripting; package funkin.backend.scripting;
#if ALLOW_MULTITHREADING
import sys.thread.Thread;
#end
import hscript.IHScriptCustomBehaviour; import hscript.IHScriptCustomBehaviour;
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour { class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
/** /**
* Script being ran. * Script being ran.
*/ */
@@ -40,6 +46,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
script.load(); 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)); __variables = Type.getInstanceFields(Type.getClass(this));
} }
@@ -56,7 +69,7 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
public function call(func:String, args:Array<Dynamic>) { public function call(func:String, args:Array<Dynamic>) {
#if ALLOW_MULTITHREADING #if ALLOW_MULTITHREADING
funkin.backend.utils.ThreadUtil.execAsync(() -> { thread.events.run(function() {
callEnded = false; callEnded = false;
returnValue = script.call(func, args); returnValue = script.call(func, args);
callEnded = true; callEnded = true;
@@ -72,5 +85,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
script.call("destroy"); script.call("destroy");
script.destroy(); script.destroy();
} }
#if ALLOW_MULTITHREADING
if (thread != null) {
thread.events.runPromised(function() {
// close the thing
});
}
#end
} }
} }
+1 -2
View File
@@ -91,7 +91,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
"FunkinShader" => funkin.backend.shaders.FunkinShader, "FunkinShader" => funkin.backend.shaders.FunkinShader,
"CustomShader" => funkin.backend.shaders.CustomShader, "CustomShader" => funkin.backend.shaders.CustomShader,
"FunkinText" => funkin.backend.FunkinText, "FunkinText" => funkin.backend.FunkinText,
"FlxAnimate" => animate.FlxAnimate, "FlxAnimate" => funkin.backend.FlxAnimate,
"FunkinSprite" => funkin.backend.FunkinSprite, "FunkinSprite" => funkin.backend.FunkinSprite,
"Alphabet" => funkin.menus.ui.Alphabet, "Alphabet" => funkin.menus.ui.Alphabet,
"Flags" => funkin.backend.system.Flags, "Flags" => funkin.backend.system.Flags,
@@ -102,7 +102,6 @@ class Script extends FlxBasic implements IFlxDestroyable {
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end #if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil, "MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
"EngineUtil" => funkin.backend.utils.EngineUtil, "EngineUtil" => funkin.backend.utils.EngineUtil,
"ThreadUtil" => funkin.backend.utils.ThreadUtil,
"MemoryUtil" => funkin.backend.utils.MemoryUtil, "MemoryUtil" => funkin.backend.utils.MemoryUtil,
"BitmapUtil" => funkin.backend.utils.BitmapUtil, "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 unmuteVocals:Bool = true;
@:dox(hide) public var enableCamZooming:Bool = true; @:dox(hide) public var enableCamZooming:Bool = true;
@:dox(hide) public var autoHitLastSustain:Bool = true; @:dox(hide) public var autoHitLastSustain:Bool = true;
@:dox(hide) public var clipSustain:Bool = true;
/** /**
* Whenever a miss should be added. * Whenever a miss should be added.
@@ -146,13 +145,6 @@ final class NoteHitEvent extends CancellableEvent {
deleteNote = true; 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. * 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; if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
else throw "Missing name for shader script, please provide a scriptName, or use CustomShader"; 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 = Script.create(Paths.script('shaders/$scriptName'));
script.setParent(shader); script.setParent(shader);
script.set("shader", shader); script.set("shader", shader);
-6
View File
@@ -25,7 +25,6 @@ enum Control
CHANGE_MODE; CHANGE_MODE;
//CHEAT; //CHEAT;
SWITCHMOD; SWITCHMOD;
FPS_COUNTER;
// Debugs // Debugs
DEV_ACCESS; DEV_ACCESS;
@@ -162,11 +161,6 @@ class Controls extends FlxActionSet
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool; @:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
@:justReleased("switchmod") public var SWITCHMOD_R(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 @:devModeOnly
@:gamepad([]) @:gamepad([])
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool; @:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
+18 -37
View File
@@ -15,18 +15,14 @@ import lime.utils.AssetType;
*/ */
@:build(funkin.backend.system.macros.FlagMacro.build()) @:build(funkin.backend.system.macros.FlagMacro.build())
class Flags { class Flags {
public static var overridenFlags:Map<String, Bool> = [];
// -- Codename's Addon Config -- // -- Codename's Addon Config --
@:bypass public static var addonFlags:Map<String, Dynamic> = []; @:bypass public static var addonFlags:Map<String, Dynamic> = [];
public static var CURRENT_API_VERSION:Int = 2;
// -- Codename's Mod Config -- // -- Codename's Mod Config --
public static var MOD_NAME:String = ""; public static var MOD_NAME:String = "";
public static var MOD_DESCRIPTION:String = ""; public static var MOD_DESCRIPTION:String = "";
public static var MOD_AUTHOR: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_DOWNLOAD_LINK:String = "";
public static var MOD_DEPENDENCIES:Array<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_PATH:String = haxe.macro.Compiler.getDefine("SAVE_PATH");
@:lazy public static var SAVE_NAME:String = haxe.macro.Compiler.getDefine("SAVE_NAME"); @: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_NUMBER:Int = GitCommitMacro.commitNumber;
public static var COMMIT_HASH:String = GitCommitMacro.commitHash; public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)'; 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 TITLE:String = Application.current.meta.get('name');
@:lazy public static var VERSION:String = Application.current.meta.get('version'); @:lazy public static var VERSION:String = Application.current.meta.get('version');
@@ -128,16 +125,12 @@ class Flags {
@:also(funkin.game.PlayState.opponentMode) @:also(funkin.game.PlayState.opponentMode)
public static var DEFAULT_OPPONENT_MODE:Bool = false; 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_MS_LIMIT:Float = 1500;
public static var DEFAULT_NOTE_SCALE:Float = 0.7; public static var DEFAULT_NOTE_SCALE:Float = 0.7;
#if MODCHARTING_FEATURES #if MODCHARTING_FEATURES
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4; public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
#end #end
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER) @:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead"; 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_HUD_ZOOM_MULT:Float = 0.03;
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05; public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
public static var DEFAULT_HUD_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 // Font configuration
public static var DEFAULT_FONT:String = "vcr.ttf"; public static var DEFAULT_FONT:String = "vcr.ttf";
@@ -286,6 +277,8 @@ class Flags {
@:bypass public static var customFlags:Map<String, String> = []; @:bypass public static var customFlags:Map<String, String> = [];
public static function loadFromData(flags:Map<String, String>, data:String) { public static function loadFromData(flags:Map<String, String>, data:String) {
WINDOW_TITLE_USE_MOD_NAME = false;
if (!(data.length > 0)) return; if (!(data.length > 0)) return;
var res = IniUtil.parseString(data); var res = IniUtil.parseString(data);
@@ -302,39 +295,28 @@ class Flags {
else trace('Invalid section $name'); 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() { public static function loadFromDatas(datas:Array<String>) {
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> {
var flags:Map<String, String> = []; var flags:Map<String, String> = [];
for (data in datas) { for(data in datas) {
if (data != null) if(data != null)
loadFromData(flags, data); loadFromData(flags, data);
} }
loadPost();
return flags; return flags;
} }
public static function parseFlags(flags:Map<String, String>) { public static function parseFlags(flags:Map<String, String>) {
var parsed:Bool; for(name=>value in flags)
for (name => value in flags) switch (name) { if(!parse(name, value))
case "MOD_API_VERSION": customFlags.set(name, value);
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
Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS; Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS;
#end
} }
/** /**
@@ -383,6 +365,5 @@ class Flags {
parseFlags(flags); parseFlags(flags);
} }
} }
loadPost();
} }
} }
+27 -19
View File
@@ -1,5 +1,7 @@
package funkin.backend.system; package funkin.backend.system;
import sys.io.File;
import sys.FileSystem;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
import flixel.addons.transition.TransitionData; import flixel.addons.transition.TransitionData;
@@ -7,22 +9,21 @@ import flixel.graphics.FlxGraphic;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.math.FlxRect; import flixel.math.FlxRect;
import flixel.system.ui.FlxSoundTray; import flixel.system.ui.FlxSoundTray;
import funkin.backend.assets.AssetSource;
import funkin.backend.assets.AssetsLibraryList; import funkin.backend.assets.AssetsLibraryList;
import funkin.backend.assets.ModsFolder; 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.framerate.SystemInfo;
import funkin.backend.system.modules.*; import funkin.backend.system.modules.*;
import funkin.backend.utils.ThreadUtil;
import funkin.editors.SaveWarning; import funkin.editors.SaveWarning;
import funkin.options.PlayerSettings;
import openfl.Assets; import openfl.Assets;
import openfl.Lib; import openfl.Lib;
import openfl.display.Sprite; import openfl.display.Sprite;
import openfl.text.TextFormat; import openfl.text.TextFormat;
import openfl.utils.AssetLibrary; import openfl.utils.AssetLibrary;
import sys.FileSystem;
import sys.io.File; #if ALLOW_MULTITHREADING
import sys.thread.Thread;
#end
#if android #if android
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
@@ -39,7 +40,7 @@ class Main extends Sprite
public static var scaleMode:FunkinRatioScaleMode; public static var scaleMode:FunkinRatioScaleMode;
#if !mobile #if !mobile
public static var framerateSprite:Framerate; public static var framerateSprite:funkin.backend.system.framerate.Framerate;
#end #end
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels). 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. // 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() { public static function preInit() {
funkin.backend.utils.NativeAPI.registerAsDPICompatible(); funkin.backend.utils.NativeAPI.registerAsDPICompatible();
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args()); 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)); addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
#if (!mobile && !web) #if (!mobile && !web)
addChild(framerateSprite = new Framerate()); addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
SystemInfo.init(); SystemInfo.init();
#end #end
} }
@@ -92,8 +97,16 @@ class Main extends Sprite
#end; #end;
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #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 { private static function getTimer():Int {
return time = Lib.getTimer(); return time = Lib.getTimer();
@@ -105,6 +118,10 @@ class Main extends Sprite
MemoryUtil.init(); MemoryUtil.init();
@:privateAccess @:privateAccess
FlxG.game.getTimer = getTimer; FlxG.game.getTimer = getTimer;
#if ALLOW_MULTITHREADING
for(i in 0...4)
gameThreads.push(Thread.createWithEventLoop(function() {Thread.current().events.promise();}));
#end
FunkinCache.init(); FunkinCache.init();
Paths.assetsTree = new AssetsLibraryList(); Paths.assetsTree = new AssetsLibraryList();
@@ -139,7 +156,6 @@ class Main extends Sprite
FlxG.signals.focusGained.add(onFocus); FlxG.signals.focusGained.add(onFocus);
FlxG.signals.preStateSwitch.add(onStateSwitch); FlxG.signals.preStateSwitch.add(onStateSwitch);
FlxG.signals.postStateSwitch.add(onStateSwitchPost); FlxG.signals.postStateSwitch.add(onStateSwitchPost);
FlxG.signals.postUpdate.add(onUpdate);
FlxG.mouse.useSystemCursor = true; FlxG.mouse.useSystemCursor = true;
#if DARK_MODE_WINDOW #if DARK_MODE_WINDOW
@@ -194,14 +210,6 @@ class Main extends Sprite
scaleMode.resetSize(); 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() { private static function onStateSwitchPost() {
// manual asset clearing since base openfl one does'nt clear lime one // manual asset clearing since base openfl one does'nt clear lime one
// does'nt clear bitmaps since flixel fork does it auto // 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; import funkin.backend.assets.ScriptedAssetLibrary;
class AssetTreeInfo extends FramerateCategory { class AssetTreeInfo extends FramerateCategory {
private var lastUpdateTime:Float = 1;
public function new() { public function new() {
super("Asset Libraries Tree Info"); super("Asset Libraries Tree Info");
} }
public override function __enterFrame(t:Int) { public override function __enterFrame(t:Int) {
if (alpha <= 0.05) return; if (alpha <= 0.05) return;
if ((lastUpdateTime += FlxG.rawElapsed) < 1)
return;
lastUpdateTime = 0;
var text = 'Not initialized yet\n'; var text = 'Not initialized yet\n';
if (Paths.assetsTree != null){ if (Paths.assetsTree != null){
text = ""; text = "";
@@ -53,6 +53,13 @@ class Framerate extends Sprite {
x = 10; x = 10;
y = 2; 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) if (__bitmap == null)
__bitmap = new BitmapData(1, 1, 0xFF000000); __bitmap = new BitmapData(1, 1, 0xFF000000);
@@ -9,13 +9,6 @@ class FramerateCounter extends Sprite {
public var fpsLabel:TextField; public var fpsLabel:TextField;
public var lastFPS:Float = 0; 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() { public function new() {
super(); super();
@@ -34,40 +27,15 @@ class FramerateCounter extends Sprite {
} }
} }
public function reload() { public function reload() {}
lastUpdateTime = 0;
}
public override function __enterFrame(t:Int) { public override function __enterFrame(t:Int) {
if (alpha <= 0.05) return; if (alpha <= 0.05) return;
super.__enterFrame(t); super.__enterFrame(t);
frameCount++; lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.rawElapsed == 0 ? 0 : (1 / FlxG.rawElapsed), 0.25);
fpsNum.text = Std.string(Math.floor(lastFPS));
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
{
fpsLabel.x = fpsNum.x + fpsNum.width; fpsLabel.x = fpsNum.x + fpsNum.width;
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height; fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
} }
} }
@@ -36,21 +36,11 @@ class MemoryCounter extends Sprite {
if (alpha <= 0.05) return; if (alpha <= 0.05) return;
super.__enterFrame(t); super.__enterFrame(t);
final mem = MemoryUtil.currentMemUsage(); memory = MemoryUtil.currentMemUsage();
if (mem == memory) {
updateLabelPosition();
return;
}
memory = mem;
if (memoryPeak < memory) memoryPeak = memory; if (memoryPeak < memory) memoryPeak = memory;
memoryText.text = CoolUtil.getSizeString(memory); memoryText.text = CoolUtil.getSizeString(memory);
memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}'; memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
updateLabelPosition();
}
private inline function updateLabelPosition():Void
memoryPeakText.x = memoryText.x + memoryText.width; memoryPeakText.x = memoryText.x + memoryText.width;
}
} }
@@ -115,7 +115,8 @@ class SystemInfo extends FramerateCategory {
if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0) if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0)
Logs.trace('Unable to grab GPU VRAM', ERROR, RED); Logs.trace('Unable to grab GPU VRAM', ERROR, RED);
else { else {
vRAM = getSizeString(vRAMBytes / 1024); var vRAMBytesFloat:#if cpp Float64 #else Float #end = vRAMBytes*1024;
vRAM = CoolUtil.getSizeString64(vRAMBytesFloat);
} }
} }
} else } else
@@ -154,17 +155,6 @@ class SystemInfo extends FramerateCategory {
if (totalMem != "Unknown" && memType != "Unknown") __formattedSysText += '\nTotal MEM: $totalMem $memType'; 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() { public function new() {
super("System Info"); 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 // INTERNAL MACROS
#if REGION #if REGION
private static macro function __getDefines():Expr { private static macro function __getDefines() {
#if display #if display
return macro $v{([]:Map<String, Dynamic>)}; return macro $v{[]};
#else #else
return macro $v{Context.getDefines()}; return macro $v{Context.getDefines()};
#end #end
@@ -64,7 +64,7 @@ class GitCommitMacro {
// INTERNAL MACROS // INTERNAL MACROS
#if REGION #if REGION
private static macro function __getCommitHash() { private static macro function __getCommitHash() {
#if LIME_DISPLAY #if display
return macro $v{"-"}; return macro $v{"-"};
#else #else
try { try {
@@ -78,7 +78,7 @@ class GitCommitMacro {
} }
private static macro function __getCommitNumber() { private static macro function __getCommitNumber() {
#if LIME_DISPLAY #if display
return macro $v{0}; return macro $v{0};
#else #else
try { try {
@@ -92,7 +92,7 @@ class GitCommitMacro {
} }
private static macro function __getCommitHashLong() { private static macro function __getCommitHashLong() {
#if LIME_DISPLAY #if display
return macro $v{"-"}; return macro $v{"-"};
#else #else
try { try {
@@ -106,7 +106,7 @@ class GitCommitMacro {
} }
private static macro function __getCommitMessage() { private static macro function __getCommitMessage() {
#if LIME_DISPLAY #if display
return macro $v{"-"}; return macro $v{"-"};
#else #else
try { try {
@@ -124,7 +124,7 @@ class GitCommitMacro {
} }
private static macro function __getCommitAuthor() { private static macro function __getCommitAuthor() {
#if LIME_DISPLAY #if display
return macro $v{"-"}; return macro $v{"-"};
#else #else
try { try {
@@ -138,8 +138,8 @@ class GitCommitMacro {
} }
private static macro function __getCommitDate() { private static macro function __getCommitDate() {
#if LIME_DISPLAY #if display
return macro Date.now(); return macro $v{Date.now()};
#else #else
try { try {
// get the time in UTC format // get the time in UTC format
@@ -164,7 +164,7 @@ class GitCommitMacro {
} }
private static macro function __getCurrentBranch() { private static macro function __getCurrentBranch() {
#if LIME_DISPLAY #if display
return macro $v{"-"}; return macro $v{"-"};
#else #else
try { try {
@@ -179,7 +179,7 @@ class GitCommitMacro {
} }
private static macro function __getHasUncommittedChanges() { private static macro function __getHasUncommittedChanges() {
#if LIME_DISPLAY #if display
return macro $v{false}; return macro $v{false};
#else #else
try { try {
@@ -23,7 +23,7 @@ class Macros {
#if VIDEO_CUTSCENES "hxvlc.flixel", "hxvlc.openfl", #end #if VIDEO_CUTSCENES "hxvlc.flixel", "hxvlc.openfl", #end
#if NAPE_ENABLED "nape", "flixel.addons.nape", #end #if NAPE_ENABLED "nape", "flixel.addons.nape", #end
// BASE HAXE // 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); Compiler.include(inc);
@@ -58,11 +58,6 @@ class Macros {
final macroPath = 'funkin.backend.system.macros.Macros'; final macroPath = 'funkin.backend.system.macros.Macros';
Compiler.addMetadata('@:build($macroPath.buildLimeAssetLibrary())', 'lime.utils.AssetLibrary'); 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> { 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.GitHub;
import funkin.backend.system.github.GitHubRelease; import funkin.backend.system.github.GitHubRelease;
#if ALLOW_MULTITHREADING
import funkin.backend.utils.ThreadUtil;
#end
import lime.app.Application; import lime.app.Application;
import sys.thread.Mutex;
import sys.thread.Thread;
import sys.FileSystem; import sys.FileSystem;
import haxe.io.Path; import haxe.io.Path;
#if (target.threaded)
import sys.thread.Thread;
import sys.thread.Mutex;
#end
using funkin.backend.system.github.GitHub; using funkin.backend.system.github.GitHub;
class UpdateUtil { class UpdateUtil {
public static var lastUpdateCheck:Null<UpdateCheckCallback>; public static var lastUpdateCheck:Null<UpdateCheckCallback>;
#if (target.threaded)
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>; private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
private static var __mutex:Mutex; private static var __mutex:Mutex;
#end
public static function init() { public static function init() {
// deletes old bak file if it exists // deletes old bak file if it exists
@@ -34,34 +26,26 @@ class UpdateUtil {
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath); if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
#end #end
#if (target.threaded)
__waitCallbacks = []; __waitCallbacks = [];
__mutex = new Mutex(); __mutex = new Mutex();
Thread.create(checkForUpdates.bind(true, false));
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(true, false));
#end
} }
public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) { public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) {
#if (target.threaded)
if (__mutex.tryAcquire()) { if (__mutex.tryAcquire()) {
__mutex.release(); __mutex.release();
if (__shouldCheck(lazy) || force) { if (__shouldCheck(lazy) || force) {
__waitCallbacks.push(callback); __waitCallbacks.push(callback);
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(force, false)); Thread.create(checkForUpdates.bind(force, false));
} }
else else
callback(lastUpdateCheck); callback(lastUpdateCheck);
} }
else else
__waitCallbacks.push(callback); __waitCallbacks.push(callback);
#else
callback(checkForUpdates(true, false));
#end
} }
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback { public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
#if (target.threaded)
var wasAcquired = !__mutex.tryAcquire(); var wasAcquired = !__mutex.tryAcquire();
if (wasAcquired) __mutex.acquire(); if (wasAcquired) __mutex.acquire();
@@ -76,19 +60,8 @@ class UpdateUtil {
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks); FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
return lastUpdateCheck; 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 { static function __checkForUpdates():UpdateCheckCallback {
var curTag = 'v' + (Flags.VERSION == null ? Application.current.meta.get('version') : Flags.VERSION), error = false; 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) -> { var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_OWNER, Flags.REPO_NAME, (e) -> {
@@ -109,6 +82,11 @@ class UpdateUtil {
static function __shouldCheck(lazy:Bool):Bool static function __shouldCheck(lazy:Bool):Bool
return lastUpdateCheck == null || !lazy && (!lastUpdateCheck.newUpdate || Date.now().getTime() - lastUpdateCheck.date.getTime() > 1800000); 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) { static function __doReleaseFiltering(releases:Array<GitHubRelease>, currentVersionTag:String) {
releases = releases.filterReleases(Options.betaUpdates, false); releases = releases.filterReleases(Options.betaUpdates, false);
if (releases.length <= 0) if (releases.length <= 0)
+20 -20
View File
@@ -20,7 +20,8 @@ typedef AudioAnalyzerCallback = Int->Int->Void;
* An utility that analyze FlxSounds, * An utility that analyze FlxSounds,
* can be used to make waveform or real-time audio visualizer. * 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 { final class AudioAnalyzer {
/** /**
@@ -95,9 +96,9 @@ final class AudioAnalyzer {
static var __twiddleImags:Array<Array<Float>> = []; static var __twiddleImags:Array<Array<Float>> = [];
static var __freqReals:Array<Array<Float>> = []; static var __freqReals:Array<Array<Float>> = [];
static var __freqImags:Array<Array<Float>> = []; static var __freqImags:Array<Array<Float>> = [];
static var __freqCalculating:Int = 0;
#if (target.threaded) #if (target.threaded)
static var __mutex:Mutex = new Mutex(); static var __mutex:Mutex = new Mutex();
static var __freqCalculating:Int = 0;
#end #end
/** /**
@@ -295,7 +296,7 @@ final class AudioAnalyzer {
__check(); __check();
} }
function __check() if (sound != null && sound.buffer != buffer) { function __check() if (sound.buffer != buffer) {
byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1); byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1);
#if (lime_cffi && lime_vorbis) #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). * @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. * @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); 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). * @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
* @return Output of frequencies. * @return Output of frequencies.
*/ */
public function getFrequencies(?startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float> 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); 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. * 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; @:privateAccess return sound._source != null && sound._source.__backend != null && sound._source.__backend.playing;
inline function __readStream(startPos:Float, endPos:Float, callback:AudioAnalyzerCallback):Float @:privateAccess { 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 n = Math.floor((endPos - startPos) * __toBits);
var i = backend.bufferLengths.length - backend.requestBuffers - 1, time:Float; if (startPos >= time && startPos < backend.bufferTimes[backend.bufferSizes.length - 1] * 1000) {
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.bufferSizes[i], c = 0;
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferLengths[i], c = 0;
while (pos >= size) { while (pos >= size) {
if (++i >= backend.bufferLengths.length) break; if (++i >= backend.bufferSizes.length) {
n = 0;
break;
}
pos -= size; pos -= size;
buf = backend.bufferDatas[i].buffer; buf = backend.bufferDatas[i].buffer;
size = backend.bufferLengths[i]; size = backend.bufferSizes[i];
} }
if (i >= backend.bufferLengths.length) break; pos -= pos % __sampleSize;
if ((pos -= pos % __sampleSize) < 0) pos = 0;
n -= pos % __sampleSize; n -= pos % __sampleSize;
while (n > 0) { while (n > 0) {
callback(getByte(buf, pos, __wordSize), c); callback(getByte(buf, pos, __wordSize), c);
if (++c > buffer.channels) c = 0; if (++c > buffer.channels) c = 0;
if ((pos += __wordSize) >= size) { if ((pos += __wordSize) >= size) {
if (++i >= backend.bufferLengths.length) break; if (++i >= backend.bufferSizes.length) break;
pos = 0; pos = 0;
buf = backend.bufferDatas[i].buffer; buf = backend.bufferDatas[i].buffer;
size = backend.bufferLengths[i]; size = backend.bufferSizes[i];
} }
n -= __wordSize; n -= __wordSize;
} }
break;
} }
return endPos - (n / __toBits); return endPos - (n / __toBits);
+7 -28
View File
@@ -21,6 +21,7 @@ import flixel.util.FlxAxes;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import flixel.util.typeLimit.OneOfThree; import flixel.util.typeLimit.OneOfThree;
import flixel.util.typeLimit.OneOfTwo; import flixel.util.typeLimit.OneOfTwo;
import flxanimate.data.AnimationData.AnimAtlas;
import funkin.backend.system.Conductor; import funkin.backend.system.Conductor;
import funkin.backend.utils.XMLUtil.TextFormat; import funkin.backend.utils.XMLUtil.TextFormat;
import haxe.CallStack; import haxe.CallStack;
@@ -33,8 +34,6 @@ import haxe.xml.Access;
import lime.utils.Assets; import lime.utils.Assets;
import openfl.display.BitmapData; import openfl.display.BitmapData;
import openfl.geom.ColorTransform; import openfl.geom.ColorTransform;
import animate.FlxAnimateJson;
import flixel.animation.FlxAnimationController;
using StringTools; using StringTools;
@@ -575,29 +574,6 @@ final class CoolUtil
anim2.frames = old; 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. * 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 * @param sprite Sprite to apply the new graphic size to
@@ -1276,20 +1252,23 @@ final class CoolUtil
return animsList; return animsList;
} }
public static function getAnimsListFromAtlas(atlas:AnimationJson):Array<String> { public static function getAnimsListFromAtlas(atlas:AnimAtlas):Array<String> {
if (atlas == null) return []; if (atlas == null) return [];
var animsList:Array<String> = []; var animsList:Array<String> = [];
if (atlas.AN.SN != null) animsList.push(atlas.AN.SN); if (atlas.AN.SN != null) animsList.push(atlas.AN.SN);
if (atlas.SD != null) if (atlas.SD != null)
for (symbol in atlas.SD) for (symbol in atlas.SD.S)
if (symbol.SN != null) animsList.push(symbol.SN); if (symbol.SN != null) animsList.push(symbol.SN);
return animsList; return animsList;
} }
public static function getAnimsListFromSprite(spr:FunkinSprite):Array<String> { 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 // TODO: check this for bugs
@@ -38,7 +38,7 @@ class FunkinParentDisabler extends FlxBasic {
for(c in __cameras) c.paused = true; for(c in __cameras) c.paused = true;
// sounds // 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(); for(s in __sounds) s.pause();
} }
} }
@@ -71,4 +71,4 @@ class FunkinParentDisabler extends FlxBasic {
for(s in __sounds) s.play(); for(s in __sounds) s.play();
} }
} }
} }
+136 -8
View File
@@ -34,23 +34,151 @@ final class MatrixUtil {
//if(_height == -1) _height = sprite.height; //if(_height == -1) _height = sprite.height;
if(camera == null) camera = sprite.camera; if(camera == null) camera = sprite.camera;
if(points is FlxBasePoint) points = [points]; 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.zoom = camera.zoom;
nc.scroll.set(camera.scroll.x, camera.scroll.y); nc.scroll.set(camera.scroll.x, camera.scroll.y);
nc.pixelPerfectRender = camera.pixelPerfectRender; nc.pixelPerfectRender = camera.pixelPerfectRender;
var points:Array<FlxPoint> = cast points; var points:Array<FlxPoint> = cast points;
if(sprite is IPrePostDraw) { if(isAnimateAtlas) {
var postDraw = cast(sprite, IPrePostDraw); var cnc = FakeCallCamera.instance;
postDraw.preDraw(); var sprite = funkinSprite;
sprite.drawComplex(nc); var oldOnDraw = cnc.onDraw;
postDraw.postDraw();
// 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 { } 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; return points;
} }
+19 -84
View File
@@ -1,97 +1,32 @@
package funkin.backend.utils; package funkin.backend.utils;
#if (target.threaded) #if ALLOW_MULTITHREADING
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
final class ThreadUtil { 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. * Creates a new Thread with an error handler.
* @param func Function to execute * @param func Function to execute
* @param autoRestart Whenever the thread should auto restart itself after crashing. * @param autoRestart Whenever the thread should auto restart itself after crashing.
*/ */
public static function createSafe(func:Void->Void, autoRestart:Bool = false):Thread { public static function createSafe(func:Void->Void, autoRestart:Bool = false) {
#if (target.threaded) if (autoRestart) {
try { return sys.thread.Thread.create(function() {
return if (autoRestart) Thread.create(() -> { while(true) {
var restart = true; try {
while (restart) try { func();
} catch(e) {
trace(e.details());
}
}
});
} else {
return sys.thread.Thread.create(function() {
try {
func(); 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 #end
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
}
}
+8 -24
View File
@@ -14,7 +14,6 @@ import funkin.backend.scripting.ScriptPack;
import flixel.util.typeLimit.OneOfTwo; import flixel.util.typeLimit.OneOfTwo;
import funkin.backend.system.interfaces.IOffsetCompatible; import funkin.backend.system.interfaces.IOffsetCompatible;
import haxe.xml.Access; import haxe.xml.Access;
import animate.FlxAnimateFrames;
using StringTools; using StringTools;
@@ -128,9 +127,6 @@ final class XMLUtil {
spr.spriteAnimType = XMLAnimType.fromString(node.att.type, spr.spriteAnimType); 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) { if(node.has.x) {
var x:Null<Float> = Std.parseFloat(node.att.x); var x:Null<Float> = Std.parseFloat(node.att.x);
if (x.isNotNull()) spr.x = x; if (x.isNotNull()) spr.x = x;
@@ -229,8 +225,7 @@ final class XMLUtil {
animType: spr.spriteAnimType, animType: spr.spriteAnimType,
x: 0, x: 0,
y: 0, y: 0,
indices: [for(i in 0...spr.frames.frames.length) i], indices: [for(i in 0...spr.frames.frames.length) i]
label: false
}); });
} }
@@ -266,8 +261,7 @@ final class XMLUtil {
animType: animType, animType: animType,
x: 0, x: 0,
y: 0, y: 0,
indices: [], indices: []
label: false
}; };
if (anim.has.name) animData.name = anim.att.name; 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.loop) animData.loop = anim.att.loop == "true";
if (anim.has.forced) animData.forced = anim.att.forced == "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.indices) animData.indices = CoolUtil.parseNumberRange(anim.att.indices);
if (anim.has.label) animData.label = anim.att.label == "true";
return animData; return animData;
} }
@@ -306,23 +299,15 @@ final class XMLUtil {
if (animData.name != null) { if (animData.name != null) {
if (animData.fps <= 0 #if web || animData.fps == null #end) animData.fps = 24; 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) if(animData.anim == null)
return MISSING_PROPERTY; return MISSING_PROPERTY;
var animateAnim = cast(sprite, FunkinSprite).anim; if (animData.indices != null && animData.indices.length > 0)
animateAnim.addBySymbolIndices(animData.name, animData.anim, animData.indices, animData.fps, animData.loop);
if (animData.label) { else
if (animData.indices != null && animData.indices.length > 0) animateAnim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop);
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);
}
} else { } else {
if (animData.indices != null && animData.indices.length > 0) { if (animData.indices != null && animData.indices.length > 0) {
if (animData.anim == null) if (animData.anim == null)
@@ -478,7 +463,6 @@ typedef AnimData = {
var y:Float; var y:Float;
var indices:Array<Int>; var indices:Array<Int>;
var animType:XMLAnimType; var animType:XMLAnimType;
var label:Bool;
var ?forced:Bool; var ?forced:Bool;
} }
@@ -204,9 +204,6 @@ final class Windows {
freopen("CONIN$", "r", stdin); freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr); freopen("CONOUT$", "w", stderr);
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
') ')
public static function allocConsole() { public static function allocConsole() {
} }
+1 -2
View File
@@ -41,8 +41,7 @@ class Week {
weekObj.songs.push({ weekObj.songs.push({
name: name, name: name,
hide: song.getAtt('hide').getDefault('false') == "true", hide: song.getAtt('hide').getDefault('false') == "true",
displayName: song.getAtt('displayName'), displayName: song.getAtt('displayName')
variation: song.getAtt('variation')
}); });
} catch(e) { } catch(e) {
Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING); Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING);
+2 -2
View File
@@ -9,7 +9,7 @@ class ModConfigWarning extends UIState {
var library:ModsFolderLibrary = null; var library:ModsFolderLibrary = null;
var goToState:Class<FlxState>; 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. '[Common] # This section applies the \'MOD_\' prefix to the flags so you don\'t have to.
NAME="YOUR MOD NAME HERE" NAME="YOUR MOD NAME HERE"
DESCRIPTION="YOUR MOD DESCRIPTION HERE" DESCRIPTION="YOUR MOD DESCRIPTION HERE"
@@ -17,7 +17,7 @@ AUTHOR="YOU/YOUR TEAM HERE"
VERSION="YOUR MOD\'S VERSION HERE" VERSION="YOUR MOD\'S VERSION HERE"
# DO NOT EDIT!! this is used to check for version compatibility! # 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" DOWNLOAD_LINK="YOUR MOD PAGE LINK HERE"
@@ -2,13 +2,18 @@ package funkin.editors.character;
import flixel.text.FlxText.FlxTextFormat; import flixel.text.FlxText.FlxTextFormat;
import flixel.text.FlxText.FlxTextFormatMarkerPair; 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.graphics.frames.FlxFrame;
import flixel.animation.FlxAnimation; import flixel.animation.FlxAnimation;
import openfl.geom.Rectangle; import openfl.geom.Rectangle;
import funkin.backend.utils.XMLUtil.AnimData; import funkin.backend.utils.XMLUtil.AnimData;
import flixel.math.FlxPoint; import flixel.math.FlxPoint;
import flixel.util.FlxColor; import flixel.util.FlxColor;
import funkin.editors.character.CharacterAnimsWindow;
using StringTools; using StringTools;
@@ -21,7 +26,6 @@ class CharacterAnimButton extends UIButton {
public var animationDisplayBG:UISliceSprite; public var animationDisplayBG:UISliceSprite;
public var nameTextBox:UITextBox; public var nameTextBox:UITextBox;
public var animTextBox:UIAutoCompleteTextBox; public var animTextBox:UIAutoCompleteTextBox;
public var animLabelCheckbox:UICheckbox;
public var positionXStepper:UINumericStepper; public var positionXStepper:UINumericStepper;
public var positionYStepper:UINumericStepper; public var positionYStepper:UINumericStepper;
public var fpsStepper:UINumericStepper; public var fpsStepper:UINumericStepper;
@@ -112,20 +116,13 @@ class CharacterAnimButton extends UIButton {
foldableButtons.push(fpsStepper); foldableButtons.push(fpsStepper);
addLabelOn(fpsStepper, translate("fps"), 12); 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);}; loopedCheckbox.onChecked = (newLooping:Bool) -> {this.changeLooping(newLooping);};
members.push(loopedCheckbox); members.push(loopedCheckbox);
foldableButtons.push(loopedCheckbox); foldableButtons.push(loopedCheckbox);
loopedCheckbox.x += 8; loopedCheckbox.y += 6; 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 = new UITextBox(nameTextBox.x, nameTextBox.y, CoolUtil.formatNumberRange(animData.indices.getDefault([]), ", "), 278, 22, false, true);
indicesTextBox.onChange = (text:String) -> { indicesTextBox.onChange = (text:String) -> {
this.changeIndicies(CoolUtil.parseNumberRange(text)); this.changeIndicies(CoolUtil.parseNumberRange(text));
@@ -207,7 +204,6 @@ class CharacterAnimButton extends UIButton {
fpsStepper.follow(this, 282, 118); fpsStepper.follow(this, 282, 118);
loopedCheckbox.follow(this, 336, 122); loopedCheckbox.follow(this, 336, 122);
animLabelCheckbox?.follow(this, 336, 98);
indicesTextBox.follow(this, 158, 164); indicesTextBox.follow(this, 158, 164);
@@ -235,12 +231,18 @@ class CharacterAnimButton extends UIButton {
} }
var oldName:String = anim; var oldName:String = anim;
if (parent.character.animateAtlas != null) {
var flxAnimation:FlxAnimation = __getFlxAnimation(); var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
flxAnimation.name = newName;
parent.character.animation._animations.remove(anim); parent.character.animateAtlas.anim.animsMap.remove(anim);
parent.character.animation._animations.set(newName, flxAnimation); 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]; var animData:AnimData = parent.character.animDatas[anim];
animData.name = newName; animData.name = newName;
@@ -252,7 +254,7 @@ class CharacterAnimButton extends UIButton {
parent.character.animOffsets.remove(anim); parent.character.animOffsets.remove(anim);
parent.character.animOffsets.set(newName, animOffset); 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.remove(anim);
parent.displayAnimsFramesList.set(newName, displayFrame); parent.displayAnimsFramesList.set(newName, displayFrame);
@@ -274,20 +276,23 @@ class CharacterAnimButton extends UIButton {
var oldAnim:String = animData.anim; var oldAnim:String = animData.anim;
animData.anim = newAnim; animData.anim = newAnim;
var flxAnimation:FlxAnimation = __getFlxAnimation(); if (parent.character.animateAtlas != null)
flxAnimation.prefix = newAnim; __refreshAnimation();
else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.prefix = newAnim;
refreshAnimation(__getFlxAnimation(), data); refreshFlxAnimationFrames(flxAnimation, animData);
if (valid) { if (valid) {
parent.buildAnimDisplay(anim, data); parent.buildAnimDisplay(anim, data);
animationDisplayBG.alpha = 1; animationDisplayBG.alpha = 1;
} else { } else {
parent.removeAnimDisplay(anim); parent.removeAnimDisplay(anim);
animationDisplayBG.alpha = 0.4; animationDisplayBG.alpha = 0.4;
}
} }
if (parent.character.getAnimName() == anim) if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim); CharacterEditor.instance.playAnimation(anim);
@@ -325,8 +330,13 @@ class CharacterAnimButton extends UIButton {
var oldFPS:Float = animData.fps; var oldFPS:Float = animData.fps;
animData.fps = newFPS; animData.fps = newFPS;
var flxAnimation:FlxAnimation = __getFlxAnimation(); if (parent.character.animateAtlas != null) {
flxAnimation.frameRate = newFPS; var animSymbol:FlxSymbolAnimation = __getAnimationSymbol();
animSymbol.frameRate = newFPS;
} else {
var flxAnimation:FlxAnimation = __getFlxAnimation();
flxAnimation.frameRate = newFPS;
}
if (parent.character.getAnimName() == anim) if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim); CharacterEditor.instance.playAnimation(anim);
@@ -341,8 +351,13 @@ class CharacterAnimButton extends UIButton {
animData.loop = newLooping; animData.loop = newLooping;
var flxAnimation:FlxAnimation = __getFlxAnimation(); if (parent.character.animateAtlas != null) {
flxAnimation.looped = animData.loop; 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) if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim); CharacterEditor.instance.playAnimation(anim);
@@ -352,19 +367,6 @@ class CharacterAnimButton extends UIButton {
if (addToUndo) CharacterEditor.undos.addToUndo(CAnimEditLooping(ID, newLooping)); 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 { public function changeIndicies(indicies:Array<Int>, addToUndo:Bool = true) @:privateAccess {
var animData:AnimData = parent.character.animDatas[anim]; var animData:AnimData = parent.character.animDatas[anim];
var oldIndices:Array<Int> = animData.indices.copy(); var oldIndices:Array<Int> = animData.indices.copy();
@@ -401,6 +403,50 @@ class CharacterAnimButton extends UIButton {
CharacterEditor.undos.addToUndo(CAnimEditIndices(ID, oldIndices, indicies)); 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() { public function toggleGhost() {
if (valid && parent.ghosts.indexOf(anim) == -1) { if (valid && parent.ghosts.indexOf(anim) == -1) {
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND)); FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND));
@@ -420,8 +466,8 @@ class CharacterAnimButton extends UIButton {
super.draw(); super.draw();
if (!closed && parent.displayAnimsFramesList.exists(anim)) { if (!closed && parent.displayAnimsFramesList.exists(anim)) {
var displayData:DisplayAnimFrameEntry = parent.displayAnimsFramesList.get(anim); var displayData:{frame:Int, scale:Float, animBounds:Rectangle} = parent.displayAnimsFramesList.get(anim);
parent.displayWindowSprite.frame = displayData.frame; parent.displayWindowSprite.frame = parent.displayWindowSprite.frames.frames[displayData.frame];
parent.displayWindowSprite.scale.x = parent.displayWindowSprite.scale.y = displayData.scale; parent.displayWindowSprite.scale.x = parent.displayWindowSprite.scale.y = displayData.scale;
parent.displayWindowSprite.updateHitbox(); parent.displayWindowSprite.updateHitbox();
@@ -475,26 +521,16 @@ class CharacterAnimButton extends UIButton {
return parent.character.animation._animations[anim]; return parent.character.animation._animations[anim];
} }
public inline function refreshAnimation(anim:FlxAnimation, animData:AnimData) @:privateAccess { public inline function __getAnimationSymbol():Null<FlxSymbolAnimation> @:privateAccess {
var refreshed:Bool = false; if (!parent.character.animateAtlas.anim.animsMap.exists(anim))
XMLUtil.addAnimToSprite(parent.character, data);
parent.character.animation.remove(animData.name); return parent.character.animateAtlas.anim.animsMap[anim];
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();
} }
@:noCompletion function __refreshAnimation() @:privateAccess { @:noCompletion function __refreshAnimation() @:privateAccess {
refreshAnimation(__getFlxAnimation(), data); if (parent.character.animateAtlas != null) refreshSymbolKeyFrames(__getAnimationSymbol(), data);
else refreshFlxAnimationFrames(__getFlxAnimation(), data);
if (valid) { if (valid) {
parent.buildAnimDisplay(anim, data); parent.buildAnimDisplay(anim, data);
@@ -8,24 +8,15 @@ import openfl.geom.Rectangle;
import flixel.graphics.frames.FlxFrame; import flixel.graphics.frames.FlxFrame;
import funkin.game.Character; import funkin.game.Character;
import flixel.animation.FlxPrerotatedAnimation; import flixel.animation.FlxPrerotatedAnimation;
import animate.internal.RenderTexture;
import flixel.graphics.frames.FlxFrame;
import funkin.backend.system.Logs;
using funkin.backend.utils.BitmapUtil; using funkin.backend.utils.BitmapUtil;
typedef DisplayAnimFrameEntry = {
scale:Float,
frame:FlxFrame,
renderTexture:RenderTexture
}
class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> { class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
public var character:CharacterGhost; public var character:CharacterGhost;
public var displayWindowSprite:FlxSprite; public var displayWindowSprite:FlxSprite;
public var displayWindowGraphic:FlxGraphic; 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 animButtons:Map<String, CharacterAnimButton> = [];
public var animsList:Array<String> = []; public var animsList:Array<String> = [];
@@ -39,7 +30,7 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
buttonCameras.pixelPerfectRender = true; 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)); displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false));
displayWindowSprite = new FlxSprite(); displayWindowSprite = new FlxSprite();
@@ -78,45 +69,34 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
} }
public function buildAnimDisplay(name:String, anim:AnimData) @:privateAccess { public function buildAnimDisplay(name:String, anim:AnimData) @:privateAccess {
var anim:FlxAnimation = character.animation._animations[anim.name]; if (character.animateAtlas == null) {
if (anim == null) return; 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 frameIndex:Int = anim.frames.getDefault([0])[0];
var frame:FlxFrame = displayWindowSprite.frames.frames[frameIndex]; 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 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; var animBounds:Rectangle = displayWindowGraphic != null ? displayWindowGraphic.bitmap.bounds(frameRect) : frameRect;
displayAnimsFramesList.set(name, { displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/Math.max(animBounds.width, animBounds.height), animBounds: animBounds});
frame: character.frames.frames[anim.frames.getDefault([0])[0]], } else {
scale: 104/Math.max(animBounds.width, animBounds.height), character.storeAtlasState();
renderTexture: null
}); /*
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) { public function removeAnimDisplay(name:String)
if (displayAnimsFramesList.exists(name))
displayAnimsFramesList[name].renderTexture?.destroy();
displayAnimsFramesList.remove(name); displayAnimsFramesList.remove(name);
}
public function clearDisplayAnims() {
for(k=>e in displayAnimsFramesList)
e.renderTexture?.destroy();
displayAnimsFramesList.clear();
}
public function deleteAnimation(button:CharacterAnimButton, addToUndo:Bool = true) { public function deleteAnimation(button:CharacterAnimButton, addToUndo:Bool = true) {
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND)); FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND));
@@ -124,7 +104,6 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
if (character.getAnimName() == button.anim) if (character.getAnimName() == button.anim)
@:privateAccess CharacterEditor.instance._animation_down(null); @:privateAccess CharacterEditor.instance._animation_down(null);
character.ghosts.remove(button.anim);
character.removeAnimation(button.anim); character.removeAnimation(button.anim);
if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim); if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim);
if (character.animDatas.exists(button.anim)) character.animDatas.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, x: 0, y: 0,
indices: [], indices: [],
animType: NONE, animType: NONE,
label: false
}; };
addAnimation(animData); addAnimation(animData);
} }
@@ -554,9 +554,6 @@ class CharacterEditor extends UIState {
case CAnimEditLooping(animID, newLooping): case CAnimEditLooping(animID, newLooping):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID]; var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeLooping(!newLooping, false); button.changeLooping(!newLooping, false);
case CAnimEditLabel(animID, newLabel):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeLabel(!newLabel, false);
case CAnimEditIndices(animID, oldIndicies, newIndicies): case CAnimEditIndices(animID, oldIndicies, newIndicies):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID]; var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeIndicies(oldIndicies, false); button.changeIndicies(oldIndicies, false);
@@ -628,9 +625,6 @@ class CharacterEditor extends UIState {
case CAnimEditLooping(animID, newLooping): case CAnimEditLooping(animID, newLooping):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID]; var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeLooping(newLooping, false); button.changeLooping(newLooping, false);
case CAnimEditLabel(animID, newLabel):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeLabel(newLabel, false);
case CAnimEditIndices(animID, oldIndicies, newIndicies): case CAnimEditIndices(animID, oldIndicies, newIndicies):
var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID]; var button:CharacterAnimButton = characterAnimsWindow.buttons.members[animID];
button.changeIndicies(newIndicies, false); button.changeIndicies(newIndicies, false);
@@ -942,7 +936,6 @@ enum CharacterEditorChange {
CAnimEditFPS(animID:Int, oldFPS:Float, newFPS:Float); CAnimEditFPS(animID:Int, oldFPS:Float, newFPS:Float);
CAnimEditLooping(animID:Int, newLooping:Bool); CAnimEditLooping(animID:Int, newLooping:Bool);
CAnimEditIndices(animID:Int, oldIndicies:Array<Int>, newIndicies:Array<Int>); CAnimEditIndices(animID:Int, oldIndicies:Array<Int>, newIndicies:Array<Int>);
CAnimEditLabel(animID:Int, newLabel:Bool);
CCharClearOffsets(oldOffsets:Map<String, FlxPoint>); CCharClearOffsets(oldOffsets:Map<String, FlxPoint>);
} }
@@ -4,8 +4,6 @@ import funkin.backend.system.FakeCamera.FakeCallCamera;
import openfl.geom.ColorTransform; import openfl.geom.ColorTransform;
import flixel.animation.FlxAnimation; import flixel.animation.FlxAnimation;
import funkin.game.Character; import funkin.game.Character;
import haxe.xml.Access;
import animate.internal.RenderTexture;
typedef AtlasState = { typedef AtlasState = {
var oldAnim:String; var oldAnim:String;
@@ -16,35 +14,39 @@ typedef AtlasState = {
class CharacterGhost extends Character { class CharacterGhost extends Character {
public var ghosts:Array<String> = []; 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 { public override function draw() @:privateAccess {
ghostDraw = FakeCallCamera.instance.ignoreDraws = true; ghostDraw = FakeCallCamera.instance.ignoreDraws = true;
var wasInvalidFrame:Bool = !colorTransform.__isDefault(false); var wasInvalidFrame:Bool = !colorTransform.__isDefault(false);
colorTransform.__identity(); colorTransform.__identity();
var animName = animation.curAnim?.name ?? null; if (animateAtlas != null) {
var animFrame = animation.curAnim?.curFrame ?? 0; storeAtlasState();
var animFrameTimer = animation.curAnim?._frameTimer ?? 0; 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); if (ghosts.length > 0) restoreAtlasState();
animation.play(anim, true, false, flxanim.frames.length - 1);
setAnimOffset(anim);
super.draw();
} }
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) if (ghosts.length > 0)
frame = frames.frames[animation.frameIndex]; frame = frames.frames[animation.frameIndex];
}
ghostDraw = FakeCallCamera.instance.ignoreDraws = false; ghostDraw = FakeCallCamera.instance.ignoreDraws = false;
alpha = 1; color = 0xFFFFFFFF; alpha = 1; color = 0xFFFFFFFF;
@@ -52,12 +54,8 @@ class CharacterGhost extends Character {
frameOffset.set(0, 0); frameOffset.set(0, 0);
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y); offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
colorTransform.color = 0xFFEF0202; colorTransform.color = 0xFFEF0202;
} else { } else
animation.play(animName, true, false, animFrame); setAnimOffset(animateAtlas != null ? atlasPlayingAnim : animation.name);
setAnimOffset(animName);
if (animation.curAnim != null)
animation.curAnim._frameTimer = animFrameTimer;
}
super.draw(); super.draw();
} }
@@ -72,45 +70,22 @@ class CharacterGhost extends Character {
offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y); offset.set(globalOffset.x * (isPlayer != playerOffsets ? 1 : -1), -globalOffset.y);
} }
public function generateRenderTextureForAnim(anim:String):RenderTexture @:privateAccess { // This gets annoying lmao -lunar
if (!isAnimate) return null; private var atlasState:AtlasState = null;
public function storeAtlasState():AtlasState @:privateAccess {
var wasInvalidFrame:Bool = !colorTransform.__isDefault(false); return atlasState = {
colorTransform.__identity(); oldAnim: atlasPlayingAnim,
oldFrame: animateAtlas.anim.curFrame,
var animName = animation.curAnim?.name ?? null; oldTick: animateAtlas.anim._tick,
var animFrame = animation.curAnim?.curFrame ?? 0; oldPlaying: animateAtlas.anim.isPlaying,
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 public function restoreAtlasState(state:AtlasState = null) @:privateAccess {
// it's gone now <3 -yosh 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; package funkin.editors.character;
import funkin.backend.FlxAnimate;
import haxe.io.Path; import haxe.io.Path;
import funkin.editors.character.CharacterInfoScreen.CharacterExtraInfo; import funkin.editors.character.CharacterInfoScreen.CharacterExtraInfo;
import funkin.game.Character; import funkin.game.Character;
@@ -183,15 +184,31 @@ class CharacterPropertiesWindow extends UISliceSprite {
character.sprite = sprite; character.sprite = sprite;
animsWindow.displayWindowSprite.animation.reset(); animsWindow.displayWindowSprite.animation.reset();
animsWindow.clearDisplayAnims(); animsWindow.displayAnimsFramesList.clear();
if (animsWindow.displayWindowGraphic != null) if (animsWindow.displayWindowGraphic != null)
animsWindow.displayWindowGraphic.destroy(); 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); character.atlasPath = noExt;
if (Assets.exists(Paths.image('characters/${character.sprite}'))) character.animateAtlas.loadAtlas(noExt);
animsWindow.displayWindowGraphic = FlxG.bitmap.add(Assets.getBitmapData(Paths.image('characters/${character.sprite}'), true, false)); } 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(); character.animDatas.clear();
for (anim in animsWindow.buttons) anim.checkValid(); // Re-add all animations for (anim in animsWindow.buttons) anim.checkValid(); // Re-add all animations
+3 -4
View File
@@ -80,7 +80,6 @@ class Charter extends UIState {
public var metronome:FlxSound; public var metronome:FlxSound;
public var vocals:FlxSound; public var vocals:FlxSound;
public var voicesMuted:Bool = false;
public var quant:Int = 16; public var quant:Int = 16;
public var quants:Array<Int> = [4, 8, 12, 16, 20, 24, 32, 48, 64, 192]; // different quants 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)); t.icon = 1 - Std.int(Math.ceil(FlxG.sound.music.volume));
} }
function _song_mutevoices(t) { function _song_mutevoices(t) {
vocals.volume = (voicesMuted = !voicesMuted) ? 0 : 1; vocals.volume = vocals.volume > 0 ? 0 : 1;
for (strumLine in strumLines.members) strumLine.updateVoicesVolume(); for (strumLine in strumLines.members) strumLine.vocals.volume = strumLine.vocals.volume > 0 ? 0 : 1;
t.icon = voicesMuted ? 1 : 0; t.icon = 1 - Std.int(Math.ceil(vocals.volume));
} }
function _playback_back(_) { function _playback_back(_) {
if (FlxG.sound.music.playing) return; if (FlxG.sound.music.playing) return;
+5 -42
View File
@@ -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 * [0] Event Name
* [1] Event Script * [1] Event Script
* [2] Event JSON Info * [2] Event JSON Info
@@ -276,47 +276,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
} }
case "Camera Movement": case "Camera Movement":
var shouldDoArrow:Bool = false; // camera movement, use health icon
var icon:Null<FlxSprite> = null; if(event.params != null) {
if (event.params != null) { var icon = getIconFromStrumline(event.params[0]);
shouldDoArrow = event.params[1] && event.params[3] != "CLASSIC"; // is Tweened and isnt Lerped if(icon != null) return icon;
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;
} }
} }
return generateDefaultIcon(event.name); return generateDefaultIcon(event.name);
@@ -17,7 +17,7 @@ class CharterEventGroup extends FlxTypedGroup<CharterEvent> {
if (autoSort && members.length != __lastSort) if (autoSort && members.length != __lastSort)
sortEvents(); 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 { 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')); 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)); 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))); for (v in s.variants) if (s.metas.get(v) != null) screen.add(makeVariationOption(s.metas.get(v)));
#if sys #if sys
@@ -48,13 +48,13 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
parent.openSubState(new ChartCreationScreen(saveChart)); parent.openSubState(new ChartCreationScreen(saveChart));
})); }));
if (!first) screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 1 : 0; if (!first) screen.curSelected = 1;
else { else {
cast(screen.members[0], NewOption).itemHeight = 120; cast(screen.members[0], NewOption).itemHeight = 120;
screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> { screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> {
parent.openSubState(new VariationCreationScreen(s, saveSong)); parent.openSubState(new VariationCreationScreen(s, saveSong));
})); }));
screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 2 : 1; screen.curSelected = 2;
} }
#end #end
@@ -22,7 +22,6 @@ class CharterStrumline extends UISprite {
public var curMenu:UIContextMenu = null; public var curMenu:UIContextMenu = null;
public var vocals:FlxSound; public var vocals:FlxSound;
public var voicesMuted:Bool = false;
public var keyCount:Int = 4; public var keyCount:Int = 4;
public var startingID(get, null):Int; public var startingID(get, null):Int;
@@ -148,10 +147,6 @@ class CharterStrumline extends UISprite {
} }
vocals.group = FlxG.sound.defaultMusicGroup; vocals.group = FlxG.sound.defaultMusicGroup;
} }
public function updateVoicesVolume() {
vocals.volume = (voicesMuted || (Charter.instance?.voicesMuted ?? false)) ? 0 : 1;
}
} }
class CharterStrumlineOptions extends UITopMenuButton { class CharterStrumlineOptions extends UITopMenuButton {
@@ -181,10 +176,9 @@ class CharterStrumlineOptions extends UITopMenuButton {
{ {
label: TU.translate("charter.strumLine.muteVocals"), label: TU.translate("charter.strumLine.muteVocals"),
onSelect: function(_) { onSelect: function(_) {
strLine.voicesMuted = !strLine.voicesMuted; strLine.vocals.volume = strLine.vocals.volume > 0 ? 0 : 1;
strLine.updateVoicesVolume();
}, },
icon: strLine.voicesMuted ? 1 : 0 icon: strLine.vocals.volume > 0 ? 0 : 1
}, },
null, null,
{ {
@@ -435,7 +435,7 @@ class SongCreationScreen extends UISubstateWindow {
color: colorWheel.curColor, color: colorWheel.curColor,
opponentModeAllowed: opponentModeCheckbox.checked, opponentModeAllowed: opponentModeCheckbox.checked,
coopAllowed: coopAllowedCheckbox.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({ if (onSave != null) onSave({

Some files were not shown because too many files have changed in this diff Show More