67 Commits
Author SHA1 Message Date
FuroandGitHub 3a6f4819a9 1.0.1-rc2 2025-08-08 22:41:20 +03:00
FuroandGitHub e24a62a0b7 macOS executable path is different 2025-08-08 21:17:58 +03:00
Ralty 59b54dfbae Fix WINDOW_TITLE_USE_MOD_NAME 2025-08-08 19:06:22 +07:00
Ralty a83f62ab8a Merge remote-tracking branch 'upstream/main' 2025-08-08 18:11:01 +07:00
Frakits f86773223b Merge remote-tracking branch 'origin/main' 2025-08-08 13:57:25 +03:00
Frakits b1133171c7 Merge remote-tracking branch 'origin/main' 2025-08-08 13:57:16 +03:00
Ralty 05006802ee Bring back needsVoices, add vocalsSuffix in meta 2025-08-08 17:54:39 +07:00
Frakits 0eaffe3ea9 you may now disable the updater. 2025-08-08 13:51:35 +03:00
Verwex 03df52c542 flipX and flipY for alphabet XMLs 2025-08-08 12:34:30 +02:00
Verwex 1ca4b64402 Translatable Mod Config Warning
The Translation Strings Used in Editors.xml:
- editor.notNow
- editor.yes
- modConfigWarning.warningTitle
- modConfigWarning.warningDesc
- modConfigWarning.createdTitle
- modConfigWarning.createdDesc

Only English & Polish variants are provided beacuse I speak those.
2025-08-08 11:10:25 +02:00
FrakitsandGitHub b8b8d08be5 Update issue templates 2025-08-08 11:43:28 +03:00
FrakitsandGitHub 406f76af5d improve lagspike? 2025-08-07 23:38:31 +03:00
Verwex 1a855e5061 Freeplay Change Mode Keybind
The Co-Op Mode Switch has been given its own keybind, approved by Frakits.

FOR TRANSLATORS:
The translation string in Options.xml is category.ui.changeMode
2025-08-07 21:13:37 +02:00
FrakitsandGitHub 41474738c7 Update Chart.hx 2025-08-07 21:07:33 +03:00
Ralty bcbfa90f37 Fix Freeplay Difficulty Inst Suffix 2025-08-08 00:38:03 +07:00
Ralty b39f0d993e Whoops 2025-08-08 00:25:23 +07:00
Ralty 65839283e5 Quick fix crash freeplay 2025-08-08 00:19:01 +07:00
Ralty d2a113907a instSuffix, meta.metas for freeplay preview 2025-08-08 00:07:49 +07:00
Ralty d3ef27b9c7 ChartData no longer needs needsVoices (pun) 2025-08-07 23:18:43 +07:00
Ralty 90fc02c128 Oh thats why 2025-08-07 22:43:27 +07:00
Ralty cbaa5a6155 Don't resync Inst too in resyncVocals, stupid 2025-08-07 22:32:30 +07:00
Ralty 1f479a5b16 fix beatHit twice during start 2025-08-07 22:29:44 +07:00
Ralty 967bd4cf01 An attempt to fix stutters for low-end computers 2025-08-07 22:23:45 +07:00
Ralty 3074107322 Async Checking for Updates 2025-08-07 21:54:59 +07:00
Ralty 9c7cc22a47 An attempt to fix skipping the next song randomly 2025-08-07 20:01:23 +07:00
Ralty 7c8dd987dd Fix __readStream out of bound 2025-08-07 20:00:12 +07:00
Verwex 48624554cd Merge branch 'main' of https://github.com/CodenameCrew/CodenameEngine 2025-08-07 13:55:32 +02:00
Verwex a86749953f Camera Position & Camera Zoom Event Icons 2025-08-07 13:55:11 +02:00
KolzeandGitHub 482c213079 prevent crash when vocal suffix doesnt exist (#709)
pls merge adding erects is hell
2025-08-07 14:42:57 +03:00
Verwex 8d8e6e453a Separated volume keybind labels for translations 2025-08-07 13:32:31 +02:00
TilandGitHub d6937e866c fix a buncha stuff in saveSongInfo for SongCreationScreen (#704) 2025-08-07 18:27:08 +07:00
Verwex 9ce1486269 PL Translation - Credits Btn - Kolze's Suggestion 2025-08-07 13:18:04 +02:00
Verwex 44a19340a4 PL Translation - Freeplay btn - Kolze's suggestion 2025-08-07 12:54:07 +02:00
rufiusandGitHub 74d37f60f3 fix a few README links to minimize redirects (#698) 2025-08-07 12:50:35 +03:00
Frakits f5b79bb332 Merge remote-tracking branch 'origin/main' 2025-08-07 12:49:48 +03:00
Frakits dbc3a79e62 begin the grandiose release. 2025-08-07 12:49:41 +03:00
FuroandGitHub a262b7e683 Fix some strings that werent showing (#707) 2025-08-07 12:43:47 +03:00
Frakits b43221d527 remove traces 2025-08-07 12:34:06 +03:00
Frakits 7a9a510c47 got the auto-updater working and removed russian translations 2025-08-07 12:32:04 +03:00
Frakits 1716dc48ab oh yeah i almost forgot 2025-08-07 11:03:50 +03:00
Frakits 522256a3cf ok whatever 2025-08-07 10:50:54 +03:00
Frakits 4e3d5d75ec Merge remote-tracking branch 'origin/main' 2025-08-07 10:45:13 +03:00
Frakits 3196195790 remove traces 2025-08-07 10:45:03 +03:00
Verwex e08fac35d0 Story Menu assets for the Polish Translation 2025-08-07 00:27:13 +02:00
Verwex 69f67ce3f9 Merge branch 'main' of https://github.com/CodenameCrew/CodenameEngine 2025-08-07 00:26:04 +02:00
Ralty d961fcec30 Fix WINDOW_TITLE_USE_MOD_NAME 2025-08-07 05:21:36 +07:00
Ralty de41464364 Fix Window Mod TItle, Icon 2025-08-07 05:17:06 +07:00
Ralty 75cc052c7b Fix Icon transition only appliying to atlas? 2025-08-07 04:58:32 +07:00
Verwex 991a168686 Merge branch 'main' of https://github.com/CodenameCrew/CodenameEngine 2025-08-06 23:32:03 +02:00
FrakitsandGitHub 1cdaf62088 fix translation fail 2025-08-07 00:17:55 +03:00
Frakits 537883d2f4 FIXED!! 2025-08-06 23:38:46 +03:00
Frakits 6a1bbb72e3 warning: this crashes (on linux) 2025-08-06 23:15:53 +03:00
Verwex 8b43664327 main menu buttons for the Polish translation 2025-08-06 20:56:14 +02:00
Verwex d1fa0e5fa7 Merge branch 'main' of https://github.com/CodenameCrew/CodenameEngine 2025-08-06 17:48:38 +02:00
FrakitsandGitHub e89c0411c6 Update UIUtil.hx 2025-08-06 18:04:12 +03:00
Ralty 1993d205ca Camera Bop 2025-08-06 21:06:28 +07:00
Ralty f8aa7201c0 camGameZoomMult, camHudZoomMult 2025-08-06 19:22:26 +07:00
Verwex 07086b5e38 Title Enter text for the Polish translation 2025-08-06 14:16:37 +02:00
Ralty 70195051ec Zoom Multiplier for camZooming 2025-08-06 17:51:13 +07:00
Ralty 9570de76a8 Fix week7-balledLines 2025-08-06 05:14:33 +07:00
Ralty 17539a6f39 Add cancelConductorUpdate, deathStart 2025-08-06 05:13:17 +07:00
Ralty 16b080bf84 Fix crashes on unseekable or pure empty vorbis files 2025-08-06 04:54:25 +07:00
Ralty 549c1ad441 ACTUALLY FIX THE EVENTS 2025-08-06 02:37:46 +07:00
Ralty be812cd2ec Fix unstacked chart events 2025-08-06 02:26:29 +07:00
Ralty 272f862c69 Attempt to fix linux not loading songs? 2025-08-05 18:23:58 +07:00
Ralty cf5a689918 u got to be kidding me 2025-08-05 05:22:04 +07:00
Ralty 84c153d69c fix WarningState not booting in ModConfigWarning 2025-08-05 05:18:36 +07:00
88 changed files with 768 additions and 344 deletions
+8 -2
View File
@@ -2,12 +2,18 @@
name: Bug Report
about: Report a bug or critical performance issue
title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]'
labels: bug
labels: ''
assignees: ''
---
[weed]: <> (MAKE SURE THAT THE ISSUE IS AS COMPLETE AS POSSIBLE. ISSUES THAT HAVE BARELY ANY INFORMATION OR IS ONLY MADE FOR TROLLING WILL BE INSTANTLY CLOSED.)
[weed]: <> (MAKE SURE TO ADD YOUR TARGET OR IT'LL BE IGNORED!)
### What version of the engine are you using?
[weed]: <> (IF YOU COMPILED THE ENGINE PLEASE PROVIDE A COMMIT HASH THAT WE CAN BASE OFF OF)
Version:
### Which target are you using?
[weed]: <> (CHANGE [ ] TO [x] IN FRONT OF YOUR TARGET!)
@@ -17,4 +23,4 @@ labels: bug
### Explain your issue
##### Please check first if your issue haven't already been reported yet.
[weed]: <> (MAKE SURE TO ADD A SCREENSHOT OF THE CRASH HANDLER, IF AVAILABLE, AND STEPS TO REPRODUCE THE BUG!)
[weed]: <> (MAKE SURE TO ADD A SCREENSHOT OF THE CRASH HANDLER, IF AVAILABLE, AND STEPS TO REPRODUCE THE BUG!)
+5 -2
View File
@@ -1,8 +1,11 @@
---
name: Compiling help
about: If you need help compiling the game, and you're running into issues. (Look through the 'compiling help' label in case it's been solved!)
about: If you need help compiling the game, and you're running into issues. (Look
through the 'compiling help' label in case it's been solved!)
title: 'Compiling help: [BRIEF DESCRIPTION / ERROR MESSAGE OUTPUT]'
labels: compiling help
labels: ''
assignees: ''
---
[weed]: <> (MAKE SURE THAT THE ISSUE IS AS COMPLETE AS POSSIBLE. ISSUES THAT HAVE BARELY ANY INFORMATION OR IS ONLY MADE FOR TROLLING WILL BE INSTANTLY CLOSED.)
+4 -1
View File
@@ -2,7 +2,10 @@
name: Enhancement
about: Suggest a new feature
title: 'Enhancement: '
labels: enhancement
labels: ''
assignees: ''
---
#### Please check for duplicates or similar issues before creating this issue.
## What is your suggestion, and why should it be implemented?
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: Codename Engine (Executable Only)
path: export/release/macos/bin/CodenameEngine
path: export/release/macos/bin/CodenameEngine.app/Contents/MacOS/CodenameEngine
- name: Uploading artifact (entire build)
uses: actions/upload-artifact@v4
with:
+33 -1
View File
@@ -6,5 +6,37 @@
"*.hscript": "haxe",
"*.hsc": "haxe",
"*.hxs": "haxe"
}
},
"lime.targetConfigurations": [
{
"label": "Windows (Test Build)",
"target": "windows",
"args": ["-DTEST_BUILD"]
},
{
"label": "Linux (Test Build)",
"target": "linux",
"args": ["-DTEST_BUILD"]
},
{
"label": "MacOS (Test Build)",
"target": "macos",
"args": ["-DTEST_BUILD"]
},
{
"label": "Windows / Debug (Test Build)",
"target": "windows",
"args": ["-debug", "-DTEST_BUILD"]
},
{
"label": "Linux / Debug (Test Build)",
"target": "linux",
"args": ["-debug", "-DTEST_BUILD"]
},
{
"label": "MacOS / Debug (Test Build)",
"target": "macos",
"args": ["-debug", "-DTEST_BUILD"]
},
]
}
+2 -2
View File
@@ -18,10 +18,10 @@ Codename Engine is a new Friday Night Funkin' Engine aimed at simplifying moddin
## How to download
Latest builds for the engine can be found in the [Actions](https://github.com/YoshiCrafter29/CodenameEngine/actions) tab.<br>
Latest builds for the engine can be found in the [Actions](https://github.com/CodenameCrew/CodenameEngine/actions) tab.<br>
In the future (when the engine won't be a WIP anymore) we're gonna also publish the engine on platforms like Gamebanana; stay tuned!
If you don't have a github account please go onto https://fnf-cne-devs.github.io/ and click the download button for the respective operating system.
If you don't have a github account please go onto https://codename-engine.com/ and click the download button for the respective operating system.
<details>
<summary><h2>How to build</h2></summary>
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -51,7 +51,7 @@
<stepper name="alphaStepper" label="${translate('alpha')}" value="char.alpha / 0.75" x="col(0)" y="curY" precision="2" step="0.01" width="100" />
<stepper name="angleStepper" label="${translate('angle')}" value="char.angle" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
<stepper name="zoomFactorStepper" label="${translate('zoomFactor')" value="char.zoomFactor" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
<stepper name="zoomFactorStepper" label="${translate('zoomFactor')}" value="char.zoomFactor" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
<section if="!StringTools.startsWith(char.name, 'NO_DELETE_')">
<textbox name="charName" label="${translate('positionName')}" value="char.name" x="col(2)" y="curY" width="100"/>
+7 -5
View File
@@ -1,9 +1,11 @@
var sound:Sound;
var sound:FlxSound;
function create()
sound = Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, !Options.naughtyness ? [1, 3, 8, 13, 17, 21] : null));
function create() {
sound = FlxG.sound.load(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, !Options.naughtyness ? [1, 3, 8, 13, 17, 21] : null)));
sound.onComplete = () -> FlxG.sound.music.fadeIn(4, 0.2, 1);
}
function beatHit(cur:Int) if (cur == 0) {
FlxG.sound.play(sound, 1, false, null, true, () -> if (!isEnding) FlxG.sound.music.fadeIn(4, 0.2, 1));
function postDeathStart() {
sound.play();
FlxG.sound.music.volume = 0.2;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

+13 -2
View File
@@ -9,6 +9,8 @@
<str id="save">Save</str>
<str id="saveClose">Save &amp; Close</str>
<str id="close">Close</str>
<str id="notNow">Not Now</str>
<str id="yes">Yes</str>
</group>
<group name="UIImageExplorer" prefix="uiImageExplorer.">
@@ -111,6 +113,7 @@
<str id="color">Color</str>
<str id="difficulties">Difficulties</str>
<str id="customValues">Custom Values (Advanced)</str>
<str id="needsVoices">Needs Voices</str>
<str id="opponentMode">Opponent Mode</str>
<str id="coopAllowed">Co-op Mode</str>
@@ -236,7 +239,7 @@
<group name="BookmarkMenu" prefix="bookmarks.">
<str id="addBookmarkHere">Add Bookmark Here</str>
<str id="editBookmarkList">Edit Bookmark List</str>
<str id="goto">Go to "{0}"</str>
<str id="goTo">Go to "{0}"</str>
<str id="createBookmarkTitle">Creating New Bookmark...</str>
<str id="createBookmarkName">Bookmark Name:</str>
<str id="createBookmarkColor">Bookmark Color:</str>
@@ -571,7 +574,7 @@
</group>
</group>
<group name="StageInfoScreen" prefix="stageInfoScreen">
<group name="StageInfoScreen" prefix="stageInfoScreen.">
<str id="win-title">Editing Stage "{0}" Infos</str>
<str id="title">Stage Info</str>
<str id="stageName">Stage Name</str>
@@ -665,4 +668,12 @@
<str id="saveAndExitToMenu">Save &amp; Exit To Menu</str>
<str id="cancel">Cancel</str>
</group>
<group name="ModConfigWarning" prefix="modConfigWarning.">
<str id="warningTitle">Missing mod folder configuration!</str>
<str id="warningDesc">Your mod is currently missing a mod config file!\n\nWould you like to automatically generate one?\n\n(PS: If this is not your mod please disable Developer mode to stop this popup from appearing.)</str>
<str id="createdTitle">Created mod config!</str>
<str id="createdDesc">Your mod config file has been created at {0}!</str>
</group>
</language>
+3
View File
@@ -42,6 +42,7 @@
<str id="back">Back</str>
<str id="reset">Reset</str>
<str id="pause">Pause</str>
<str id="changeMode">Change Mode</str>
</group>
<str id="category.engine">Engine</str>
@@ -50,6 +51,8 @@
</group>
<str id="category.volume">Volume</str>
<str id="volume.up">Up</str>
<str id="volume.down">Down</str>
<str id="volume.mute">Mute</str>
<str id="category.developer">Developer</str>
+3 -2
View File
@@ -105,6 +105,7 @@
<str id="modesAllowed">Modos Permitidos</str>
<str id="difficulties">Difficultades</str>
<str id="customValues">Valores Especiales (Avanzado)</str>
<str id="needsVoices">Necesita Voces</str>
<str id="opponentMode">Modo Oponente</str>
<str id="coopAllowed">Modo Co-op</str>
@@ -225,7 +226,7 @@
<group name="BookmarkMenu" prefix="bookmarks.">
<str id="addBookmarkHere">Añadir Marcador Aquí</str>
<str id="editBookmarkList">Editar Lista de Marcadores</str>
<str id="goto">Ir hacia "{0}"</str>
<str id="goTo">Ir hacia "{0}"</str>
<str id="createBookmarkTitle">Creando Nuevo Marcador...</str>
<str id="createBookmarkName">Nombre de Marcador:</str>
<str id="createBookmarkColor">Color de Marcador:</str>
@@ -544,7 +545,7 @@
<str id="stagePath">Ubicación de Imágenes</str>
</group>
<group name="StageInfoScreen" prefix="stageInfoScreen">
<group name="StageInfoScreen" prefix="stageInfoScreen.">
<str id="win-title">Editando info. del escenario: "{0}"</str>
<str id="title">Info. del Escenario</str>
<str id="stageName">Nombre del Escenario</str>
+2
View File
@@ -49,6 +49,8 @@
</group>
<str id="category.volume">Volumen</str>
<str id="volume.up">Arriba</str>
<str id="volume.down">Abajo</str>
<str id="volume.mute">mutear</str>
<str id="category.developer">Desarrollador</str>
+4 -3
View File
@@ -108,8 +108,9 @@
<str id="color">Colore</str>
<str id="difficulties">Difficoltà</str>
<str id="customValues">Valori Personalizzati (Avanzato)</str>
<str id="needsVoices">Bisogno Voci</str>
<str id="opponentMode">Modalità Avvers.</str>
<str id="opponentMode">Modalità Avvers</str>
<str id="coopAllowed">Modalità Co-op</str>
</group>
@@ -231,7 +232,7 @@
<group name="BookmarkMenu" prefix="bookmarks.">
<str id="addBookmarkHere">Aggiungi Segnalibro Qui</str>
<str id="editBookmarkList">Modifica Lista Segnalibri</str>
<str id="goto">Vai a "{0}"</str>
<str id="goTo">Vai a "{0}"</str>
<str id="createBookmarkTitle">Creazione nuovo Segnalibro...</str>
<str id="createBookmarkName">Nome Segnalibro:</str>
<str id="createBookmarkColor">Colore Segnalibro:</str>
@@ -554,7 +555,7 @@
<str id="stagePath">Percorso file Palcoscenico</str>
</group>
<group name="StageInfoScreen" prefix="stageInfoScreen">
<group name="StageInfoScreen" prefix="stageInfoScreen.">
<str id="win-title">Modificando Informazioni Palcoscenico "{0}"</str>
<str id="title">Informazioni Palcoscenico</str>
<str id="stageName">Nome Palcoscenico</str>
+2
View File
@@ -48,6 +48,8 @@
<str id="switchMod">Cambia Mod</str>
</group>
<str id="volume.up">Su</str>
<str id="volume.down">Giù</str>
<str id="volume.mute">Muto</str>
<str id="category.developer">Sviluppatore</str>
+13 -2
View File
@@ -9,6 +9,8 @@
<str id="save">Zapisz</str>
<str id="saveClose">Zapisz i Zamknij</str>
<str id="close">Zamknij</str>
<str id="notNow">Nie Teraz</str>
<str id="yes">Tak</str>
</group>
<group name="UIImageExplorer" prefix="uiImageExplorer.">
@@ -109,6 +111,7 @@
<str id="color">Kolor</str>
<str id="difficulties">Trudności</str>
<str id="customValues">Własna Waluta (Zaawansowane)</str>
<str id="needsVoices">Potrzebne Wokale</str>
<str id="opponentMode">Tryb Przeciwnika</str>
<str id="coopAllowed">Tryb Ko-operacyjny</str>
@@ -234,7 +237,7 @@
<group name="BookmarkMenu" prefix="bookmarks.">
<str id="addBookmarkHere">Dodaj Zakładkę Tutaj</str>
<str id="editBookmarkList">Edytuj Listę Zakładek</str>
<str id="goto">Idź do "{0}"</str>
<str id="goTo">Idź do "{0}"</str>
<str id="createBookmarkTitle">Tworzenie Nowej Zakładki...</str>
<str id="createBookmarkName">Nazwa Zakładki:</str>
<str id="createBookmarkColor">Kolor Zakładki:</str>
@@ -559,7 +562,7 @@
<str id="stagePath">Ścieżka Plikowa Sceny</str>
</group>
<group name="StageInfoScreen" prefix="stageInfoScreen">
<group name="StageInfoScreen" prefix="stageInfoScreen.">
<str id="win-title">Edytowanie Info Sceny "{0}"</str>
<str id="title">Info Sceny</str>
<str id="stageName">Nazwa Sceny</str>
@@ -653,4 +656,12 @@
<str id="saveAndExitToMenu">Zapisz i Wyjdź do Menu</str>
<str id="cancel">Anuluj</str>
</group>
<group name="ModConfigWarning" prefix="modConfigWarning.">
<str id="warningTitle">Brakujący plik konfiguracyjny modu!</str>
<str id="warningDesc">Twój mod obecnie brakuje jego pliku konfiguracyjnego!\n\nCzy chcesz go automatycznie wygenerować?\n\n(PS: Jeżeli to nie twój mod, wyłącz Tryb Dewelopera, aby zapobiec wyskakiwaniu się tego okienka.)</str>
<str id="createdTitle">Utworzono konfigurację modu!</str>
<str id="createdDesc">Twój plik konfiguracyjny modu został utworzony w {0}!</str>
</group>
</language>
+1 -1
View File
@@ -57,7 +57,7 @@
<str id="credits.allContributors">Wszyscy współpracownicy silnika! - Naciśnij RESET aby zaktualizować listę (Jeden reset co 2 minuty).</str>
</group>
<group name="CreditsMain">
<str id="credits.name">Kredyty</str>
<str id="credits.name">Twórcy</str>
<str id="credits.madePossible">Ludzie którzy to umożliwili!</str>
<str id="credits.selectCodename">Wybierz to aby zobaczyć wszystkich współpracowników!</str>
<str id="credits.selectBase">Wybierz to aby otworzyć stronę itch.io oryginalnej gry!</str>
+3
View File
@@ -38,6 +38,7 @@
<str id="back">Wstecz</str>
<str id="reset">Reset</str>
<str id="pause">Pauza</str>
<str id="changeMode">Zmień Tryb</str>
</group>
<str id="category.engine">Silnik</str>
@@ -46,6 +47,8 @@
</group>
<str id="category.volume">Głośność</str>
<str id="volume.up">Głóśniej</str>
<str id="volume.down">Ciszej</str>
<str id="volume.mute">Wycisz</str>
<str id="category.developer">Deweloper</str>
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TextureAtlas imagePath="credits.png" width="3341" height="162">
<SubTexture name="credits basic0000" x="1" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0001" x="1" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0002" x="1" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0003" x="443" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0004" x="443" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0005" x="443" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0006" x="885" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0007" x="885" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits basic0008" x="885" y="1" width="440" height="116" frameX="-0" frameY="-0" frameWidth="440" frameHeight="116"/>
<SubTexture name="credits white0000" x="2668" y="1" width="672" height="160" frameX="-0" frameY="25" frameWidth="672" frameHeight="160"/>
<SubTexture name="credits white0001" x="1327" y="1" width="669" height="156" frameX="-2" frameY="24" frameWidth="672" frameHeight="160"/>
<SubTexture name="credits white0002" x="1998" y="1" width="668" height="157" frameX="-4" frameY="22" frameWidth="672" frameHeight="160"/>
</TextureAtlas>
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TextureAtlas imagePath="freeplay.png" width="1027" height="927">
<SubTexture name="freeplay basic0000" x="1" y="556" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0001" x="1" y="556" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0002" x="1" y="556" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0003" x="1" y="680" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0004" x="1" y="680" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0005" x="1" y="680" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0006" x="1" y="804" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0007" x="1" y="804" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay basic0008" x="1" y="804" width="701" height="122" frameX="-0" frameY="-0" frameWidth="701" frameHeight="122"/>
<SubTexture name="freeplay white0000" x="1" y="373" width="1020" height="181" frameX="-7" frameY="30" frameWidth="1027" frameHeight="188"/>
<SubTexture name="freeplay white0001" x="1" y="187" width="1021" height="184" frameX="-4" frameY="30" frameWidth="1027" frameHeight="188"/>
<SubTexture name="freeplay white0002" x="1" y="1" width="1025" height="184" frameX="-0" frameY="26" frameWidth="1027" frameHeight="188"/>
</TextureAtlas>
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TextureAtlas imagePath="options.png" width="2449" height="159">
<SubTexture name="options basic0000" x="1" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0001" x="1" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0002" x="1" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0003" x="346" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0004" x="346" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0005" x="346" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0006" x="691" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0007" x="691" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options basic0008" x="691" y="1" width="343" height="113" frameX="-0" frameY="-0" frameWidth="343" frameHeight="113"/>
<SubTexture name="options white0000" x="1036" y="1" width="474" height="156" frameX="-0" frameY="15" frameWidth="474" frameHeight="157"/>
<SubTexture name="options white0001" x="1512" y="1" width="465" height="156" frameX="-6" frameY="14" frameWidth="474" frameHeight="157"/>
<SubTexture name="options white0002" x="1979" y="1" width="469" height="157" frameX="-4" frameY="15" frameWidth="474" frameHeight="157"/>
</TextureAtlas>
Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<TextureAtlas imagePath="story mode.png" width="1230" height="556">
<SubTexture name="story mode basic0000" x="734" y="1" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0001" x="734" y="1" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0002" x="734" y="1" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0003" x="734" y="119" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0004" x="734" y="119" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0005" x="734" y="119" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0006" x="730" y="237" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0007" x="730" y="237" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode basic0008" x="730" y="237" width="495" height="116" frameX="-0" frameY="-0" frameWidth="495" frameHeight="116"/>
<SubTexture name="story mode white0000" x="1" y="375" width="732" height="180" frameX="-0" frameY="28" frameWidth="732" frameHeight="186"/>
<SubTexture name="story mode white0001" x="1" y="1" width="731" height="185" frameX="-0" frameY="30" frameWidth="732" frameHeight="186"/>
<SubTexture name="story mode white0002" x="1" y="188" width="727" height="185" frameX="-0" frameY="29" frameWidth="732" frameHeight="186"/>
</TextureAtlas>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
-->
<TextureAtlas imagePath="titleEnter.png" width="1186" height="2650">
<SubTexture name="ENTER PRESSED0000" x="1" y="1" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0001" x="1" y="107" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0002" x="1" y="1" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0003" x="1" y="107" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0004" x="1" y="1" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0005" x="1" y="107" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0006" x="1" y="1" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="ENTER PRESSED0007" x="1" y="107" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0000" x="1" y="213" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0001" x="1" y="319" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0002" x="1" y="425" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0003" x="1" y="531" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0004" x="1" y="637" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0005" x="1" y="743" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0006" x="1" y="849" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0007" x="1" y="955" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0008" x="1" y="1061" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0009" x="1" y="1167" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0010" x="1" y="1273" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0011" x="1" y="1379" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0012" x="1" y="1485" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0013" x="1" y="1591" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0014" x="1" y="1697" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0015" x="1" y="1803" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0016" x="1" y="1909" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0017" x="1" y="2015" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0018" x="1" y="2121" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0019" x="1" y="2227" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0020" x="1" y="2333" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0021" x="1" y="2439" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0022" x="1" y="2545" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0023" x="1" y="2545" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0024" x="1" y="2439" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0025" x="1" y="2333" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0026" x="1" y="2227" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0027" x="1" y="2121" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0028" x="1" y="2015" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0029" x="1" y="1909" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0030" x="1" y="1803" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0031" x="1" y="1697" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0032" x="1" y="1591" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0033" x="1" y="1485" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0034" x="1" y="1379" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0035" x="1" y="1273" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0036" x="1" y="1167" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0037" x="1" y="1061" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0038" x="1" y="955" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0039" x="1" y="849" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0040" x="1" y="743" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0041" x="1" y="637" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0042" x="1" y="531" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0043" x="1" y="425" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0044" x="1" y="319" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
<SubTexture name="Press Enter to Begin0045" x="1" y="213" width="1184" height="104" frameX="-143" frameY="-1" frameWidth="1494" frameHeight="110"/>
</TextureAtlas>
+2 -2
View File
@@ -1,3 +1,3 @@
name="Polski"
credits="GlitchDotSmh & Kolze"
version="1.0.0"
credits="GlitchDotSmh, Kolze & Verwex"
version="1.1.0"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 KiB

@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
-->
<TextureAtlas imagePath="titleEnter.png" width="1258" height="1991">
<SubTexture name="ENTER PRESSED0001" x="1" y="1" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0002" x="1" y="77" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0003" x="1" y="1" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0004" x="1" y="77" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0005" x="1" y="1" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0006" x="1" y="77" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0007" x="1" y="1" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="ENTER PRESSED0008" x="1" y="77" width="1256" height="73" frameX="-105" frameY="-0" frameWidth="1478" frameHeight="78"/>
<SubTexture name="Press Enter to Begin0001" x="1" y="153" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0002" x="1" y="233" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0003" x="1" y="313" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0004" x="1" y="393" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0005" x="1" y="473" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0006" x="1" y="553" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0007" x="1" y="633" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0008" x="1" y="713" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0009" x="1" y="793" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0010" x="1" y="873" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0011" x="1" y="953" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0012" x="1" y="1033" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0013" x="1" y="1113" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0014" x="1" y="1193" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0015" x="1" y="1273" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0016" x="1" y="1353" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0017" x="1" y="1433" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0018" x="1" y="1513" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0019" x="1" y="1593" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0020" x="1" y="1673" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0021" x="1" y="1753" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0022" x="1" y="1833" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0023" x="1" y="1913" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0024" x="1" y="1913" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0025" x="1" y="1833" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0026" x="1" y="1753" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0027" x="1" y="1673" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0028" x="1" y="1593" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0029" x="1" y="1513" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0030" x="1" y="1433" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0031" x="1" y="1353" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0032" x="1" y="1273" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0033" x="1" y="1193" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0034" x="1" y="1113" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0035" x="1" y="1033" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0036" x="1" y="953" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0037" x="1" y="873" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0038" x="1" y="793" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0039" x="1" y="713" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0040" x="1" y="633" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0041" x="1" y="553" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0042" x="1" y="473" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0043" x="1" y="393" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0044" x="1" y="313" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0045" x="1" y="233" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
<SubTexture name="Press Enter to Begin0046" x="1" y="153" width="1255" height="77" frameX="-112" frameY="-3" frameWidth="1494" frameHeight="96"/>
</TextureAtlas>
+2 -2
View File
@@ -5,7 +5,7 @@
title="Friday Night Funkin' - Codename Engine" main="funkin.backend.system.Main"
file="CodenameEngine" packageName="com.yoshman29.codenameengine"
package="com.yoshman29.codenameengine"
version="1.0.0" company="Yoshman29" />
version="1.0.1-rc2" company="Yoshman29" />
<!--
CHANGE THE SAVE PATH & NAME FOR YOUR MOD HERE!
@@ -50,7 +50,7 @@
<!-- _________________________________ Engine Settings _______________________________ -->
<!-- Comment this out to disable updates !-->
<!-- <define name="UPDATE_CHECKING" unless="web || hl || neko"/> -->
<define name="UPDATE_CHECKING" unless="web || hl || neko"/>
<!-- Comment this out to disable Discord RPC !-->
<section if="cpp">
+2 -1
View File
@@ -11,13 +11,14 @@ import funkin.backend.system.Controls;
import funkin.backend.system.GraphicCacheSprite;
import funkin.backend.system.framerate.Framerate;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.backend.system.interfaces.IBeatCancellableReceiver;
import funkin.options.PlayerSettings;
/**
* Base class for all the states.
* Handles the scripts, the transitions, and the beat and step events.
**/
class MusicBeatState extends FlxState implements IBeatReceiver
class MusicBeatState extends FlxState implements IBeatCancellableReceiver
{
private var lastBeat:Float = 0;
private var lastStep:Float = 0;
+7 -1
View File
@@ -9,17 +9,23 @@ import funkin.backend.scripting.events.*;
import funkin.backend.system.Conductor;
import funkin.backend.system.Controls;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.backend.system.interfaces.IBeatCancellableReceiver;
import funkin.options.PlayerSettings;
/**
* Base class for all the sub states.
* Handles the scripts, the transitions, and the beat and step events.
**/
class MusicBeatSubstate extends FlxSubState implements IBeatReceiver
class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
{
private var lastBeat:Float = 0;
private var lastStep:Float = 0;
/**
* Whenever the Conductor auto update should be enabled or not.
*/
public var cancelConductorUpdate:Bool = false;
/**
* Whether this specific substate can open custom transitions
*/
+29 -8
View File
@@ -23,8 +23,29 @@ class Paths
});
}
public static inline function getPath(file:String, ?library:String)
return library != null ? '$library:assets/$library/$file' : 'assets/$file';
public static inline function getPath(file:String, ?library:String) {
var returnedPath:String = library != null ? '$library:assets/$library/$file' : 'assets/$file';
#if (sys && !windows)
returnedPath = Path.normalize(returnedPath);
if (OpenFlAssets.exists(returnedPath)) return returnedPath;
var fixedPath:String = library != null ? '$library:assets/$library/' : 'assets/';
var parts:Array<String> = returnedPath.split("/");
for (it=>part in parts) {
if (it == 0) continue;
var entries:Array<String> = null;
if (Path.extension(part) == "") entries = assetsTree.getFolders(fixedPath);
else entries = assetsTree.getFiles(fixedPath);
for (entry in entries) {
if (entry.toLowerCase() == part.toLowerCase()) {
fixedPath += entry + (it != parts.length - 1 ? "/" : "");
break;
}
}
}
if (returnedPath.toLowerCase() == fixedPath.toLowerCase()) returnedPath = fixedPath;
#end
return returnedPath;
}
public static inline function video(key:String, ?ext:String)
return getPath('videos/$key.${ext != null ? ext : Flags.VIDEO_EXT}');
@@ -68,18 +89,18 @@ class Paths
inline static public function music(key:String, ?library:String, ?ext:String)
return getPath('music/$key.${ext != null ? ext : Flags.SOUND_EXT}', library);
inline static public function voices(song:String, ?difficulty:String, ?prefix:String = "", ?ext:String) {
inline static public function voices(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Voices$prefix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Voices$prefix.${ext}', null);
var diff = getPath('songs/$song/song/Voices$suffix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Voices$suffix.${ext}', null);
}
inline static public function inst(song:String, ?difficulty:String, ?prefix:String = "", ?ext:String) {
inline static public function inst(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Inst$prefix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Inst$prefix.${ext}', null);
var diff = getPath('songs/$song/song/Inst$suffix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Inst$suffix.${ext}', null);
}
static public function image(key:String, ?library:String, checkForAtlas:Bool = false, ?ext:String) {
+32 -16
View File
@@ -83,13 +83,11 @@ class Chart {
return data;
}
public static function loadChartMeta(songName:String, ?difficulty:String, fromMods:Bool = true):ChartMetaData {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
public static function loadChartMeta(songName:String, difficulty:String = '', fromMods:Bool = true, includeMetaDifficulties:Bool = true):ChartMetaData {
var metaPath = Paths.file('songs/${songName}/meta.json');
var metaDiffPath = Paths.file('songs/${songName}/meta-${difficulty}.json');
var data:ChartMetaData = null;
var data:ChartMetaData = null, fromDifficulty = false;
var fromMods:Bool = fromMods;
for (path in [metaDiffPath, metaPath]) if (Assets.exists(path)) {
fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS);
@@ -98,24 +96,33 @@ class Chart {
tempData.color = CoolUtil.getColorFromDynamic(tempData.color).getDefault(Flags.DEFAULT_COLOR);
data = tempData;
} catch(e) Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR);
if (data != null) break;
if (data != null) {
fromDifficulty = path == metaDiffPath;
break;
}
}
if (data == null) data = {
name: songName,
bpm: 100
};
if (data == null) {
data = {
name: songName,
bpm: Flags.DEFAULT_BPM
};
}
else {
data.name = songName;
data.setFieldDefault("bpm", Flags.DEFAULT_BPM);
}
data.setFieldDefault("name", songName);
data.setFieldDefault("bpm", Flags.DEFAULT_BPM);
data.setFieldDefault("displayName", data.name);
data.setFieldDefault("beatsPerMeasure", Flags.DEFAULT_BEATS_PER_MEASURE);
data.setFieldDefault("stepsPerBeat", Flags.DEFAULT_STEPS_PER_BEAT);
data.setFieldDefault("needsVoices", true);
data.setFieldDefault("icon", Flags.DEFAULT_HEALTH_ICON);
data.setFieldDefault("difficulties", []);
data.setFieldDefault("coopAllowed", Flags.DEFAULT_COOP_ALLOWED);
data.setFieldDefault("opponentModeAllowed", Flags.DEFAULT_OPPONENT_MODE_ALLOWED);
data.setFieldDefault("displayName", data.name);
data.setFieldDefault("instSuffix", "");
data.setFieldDefault("vocalsSuffix", "");
data.setFieldDefault("needsVoices", true);
if (data.difficulties.length <= 0) {
data.difficulties = [for(f in Paths.getFolderContent('songs/${songName}/charts/', false, fromMods ? MODS : SOURCE)) if (Path.extension(f.toUpperCase()) == "JSON") Path.withoutExtension(f)];
@@ -132,6 +139,14 @@ class Chart {
}
}
if (includeMetaDifficulties && !fromDifficulty) {
data.metas = [];
for (difficulty in data.difficulties) {
if (!data.metas.exists(difficulty) && Assets.exists(Paths.file('songs/${songName}/meta-${difficulty}.json')))
data.metas.set(difficulty, loadChartMeta(songName, difficulty, fromMods, false));
}
}
return data;
}
@@ -265,7 +280,7 @@ class Chart {
CoolUtil.safeSaveFile(chartPath, Json.stringify(filteredChart, null, saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null));
if (saveSettings.overrideExistingMeta == true || !FileSystem.exists(metaPath))
if (meta != null && (saveSettings.overrideExistingMeta || !FileSystem.exists(metaPath)))
CoolUtil.safeSaveFile(metaPath, makeMetaSaveable(meta));
#end
return filteredChart;
@@ -305,7 +320,8 @@ class Chart {
public static inline function makeMetaSaveable(meta:ChartMetaData, prettyPrint:Bool = true):String {
var data:Dynamic = Reflect.copy(meta);
if (data.color != null) data.color = new FlxColor(data.color).toWebString(); // dont even ask me - Nex
if (data.color != null) data.color = FlxColor.fromInt(data.color).toWebString(); // dont even ask me - Nex
Reflect.deleteField(data, 'metas');
return Json.stringify(data, null, prettyPrint ? Flags.JSON_PRETTY_PRINT : null);
}
}
@@ -317,4 +333,4 @@ typedef ChartSaveSettings = {
var ?saveGlobalEvents:Bool;
var ?prettyPrint:Bool;
var ?folder:String;
}
}
+3
View File
@@ -28,6 +28,9 @@ typedef ChartMetaData = {
public var ?coopAllowed:Bool;
public var ?opponentModeAllowed:Bool;
public var ?customValues:Dynamic;
public var ?metas:Map<String, ChartMetaData>;
public var ?instSuffix:String;
public var ?vocalsSuffix:String;
public var ?needsVoices:Bool;
}
+4 -1
View File
@@ -10,7 +10,7 @@ import openfl.Assets;
using StringTools;
class EventsData {
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Camera Position", "Add Camera Zoom", "Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Continuous BPM Change", "Time Signature Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation"];
public static var defaultEventsList:Array<String> = ["HScript Call", "Camera Movement", "Camera Position", "Add Camera Zoom", "Camera Bop", "Camera Zoom", "Camera Modulo Change", "Camera Flash", "BPM Change", "Continuous BPM Change", "Time Signature Change", "Scroll Speed Change", "Alt Animation Toggle", "Play Animation"];
public static var defaultEventsParams:Map<String, Array<EventParamInfo>> = [
"HScript Call" => [
{name: "Function Name", type: TString, defValue: "myFunc"},
@@ -56,6 +56,9 @@ class EventsData {
{name: "Amount", type: TFloat(-10, 10, 0.01, 2), defValue: 0.05},
{name: "Camera", type: TDropDown(['camGame', 'camHUD']), defValue: "camGame"}
],
"Camera Bop" => [
{name: "Amount", type: TFloat(-10, 10, 0.1, 2), defValue: 0.1}
],
"Camera Zoom" => [
{name: "Tween Zoom?", type: TBool, defValue: true},
{name: "New Zoom", type: TFloat(-10, 10, 0.01, 2), defValue: 1},
+1 -1
View File
@@ -67,7 +67,7 @@ class VSliceParser {
var timeChanges = metadata.timeChanges;
result.meta.bpm = timeChanges[0].bpm;
result.meta.needsVoices = true;
result.meta.needsVoices = false;
for (note in data)
{
+9 -2
View File
@@ -4,6 +4,7 @@ import flixel.FlxState;
import flixel.util.FlxSignal.FlxTypedSignal;
import funkin.backend.chart.ChartData;
import funkin.backend.system.interfaces.IBeatReceiver;
import funkin.backend.system.interfaces.IBeatCancellableReceiver;
import funkin.editors.charter.Charter;
enum BeatType {
@@ -371,8 +372,14 @@ final class Conductor
private static var __updateMeasure:Bool;
private static function update() {
if (FlxG.state != null && FlxG.state is MusicBeatState && cast(FlxG.state, MusicBeatState).cancelConductorUpdate) return;
if (FlxG.state == null) return;
else {
var state = FlxG.state;
while (state != null) {
if (state is IBeatCancellableReceiver && cast(FlxG.state, IBeatCancellableReceiver).cancelConductorUpdate) return;
state = state.subState;
}
}
__updateSongPos(FlxG.elapsed);
var oldStep = curStep, oldBeat = curBeat, oldMeasure = curMeasure, oldChangeIndex = curChangeIndex;
+6
View File
@@ -22,6 +22,7 @@ enum Control
ACCEPT;
BACK;
PAUSE;
CHANGE_MODE;
//CHEAT;
SWITCHMOD;
@@ -145,6 +146,11 @@ class Controls extends FlxActionSet
@:pressed("reset") public var RESET_HOLD(get, set): Bool;
@:justReleased("reset") public var RESET_R(get, set): Bool;
@:gamepad([FlxGamepadInputID.BACK]) // select button
@:justPressed("change-mode") public var CHANGE_MODE(get, set): Bool;
@:pressed("change-mode") public var CHANGE_MODE_HOLD(get, set): Bool;
@:justReleased("change-mode") public var CHANGE_MODE_R(get, set): Bool;
//@:gamepad([])
//@:justPressed("cheat") public var CHEAT(get, set): Bool;
//@:pressed("cheat") public var CHEAT_HOLD(get, set): Bool;
+16 -7
View File
@@ -26,8 +26,8 @@ class Flags {
public static var MOD_DOWNLOAD_LINK:String = "";
public static var MOD_DEPENDENCIES:Array<String> = [];
@:noCompletion public static var MOD_ICON64:String = "";
@:noCompletion public static var MOD_ICON32:String = "";
@:noCompletion public static var MOD_ICON24:String = "";
@:noCompletion public static var MOD_ICON16:String = "";
public static var MOD_ICON:String = "";
@@ -46,6 +46,7 @@ class Flags {
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
@:bypass public static var WINDOW_TITLE_USE_MOD_NAME:Bool = false;
@:lazy public static var TITLE:String = Application.current.meta.get('name');
@:lazy public static var VERSION:String = Application.current.meta.get('version');
@@ -136,7 +137,14 @@ class Flags {
public static var DEFAULT_CAM_ZOOM_STRENGTH:Int = 1;
public static var DEFAULT_CAM_ZOOM:Float = 1.05; // what zoom level it defaults to
public static var DEFAULT_HUD_ZOOM:Float = 1.0;
public static var MAX_CAMERA_ZOOM_MULT:Float = 1.35;
public static var DEFAULT_ZOOM:Float = 1.0;
public static var DEFAULT_ZOOM_LERP:Float = 0.05;
public static var MAX_CAMERA_ZOOM_MULT:Float = 10;
public static var USE_CAM_ZOOM_MULT:Bool = true;
public static var DEFAULT_CAM_ZOOM_MULT:Float = 0.015;
public static var DEFAULT_HUD_ZOOM_MULT:Float = 0.03;
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05;
// to translate these you need to convert them into ids
// Resume -> pause.resume
@@ -164,11 +172,6 @@ class Flags {
public static var DEFAULT_INTRO_LENGTH:Int = 5;
public static var DEFAULT_INTRO_SPRITES:Array<String> = [null, 'game/ready', 'game/set', 'game/go'];
public static var CAM_BOP_STRENGTH:Float = 0.015;
public static var HUD_BOP_STRENGTH:Float = 0.03;
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05;
public static var MAX_SPLASHES:Int = 8;
public static var STUNNED_TIME:Float = 5 / 60;
@@ -193,6 +196,7 @@ class Flags {
public static var DISABLE_WARNING_SCREEN:Bool = true;
public static var DISABLE_TRANSITIONS:Bool = false;
public static var DISABLE_LANGUAGES:Bool = false;
public static var DISABLE_AUTOUPDATER:Bool = false;
@:also(funkin.backend.MusicBeatTransition.script)
public static var DEFAULT_TRANSITION_SCRIPT:String = "";
@@ -281,6 +285,11 @@ class Flags {
else trace('Invalid section $name');
}
}
if (!flags.exists("WINDOW_TITLE_USE_MOD_NAME")) WINDOW_TITLE_USE_MOD_NAME = !flags.exists('TITLE');
else WINDOW_TITLE_USE_MOD_NAME = parseBool(flags.get("WINDOW_TITLE_USE_MOD_NAME"));
flags.remove("WINDOW_TITLE_USE_MOD_NAME");
}
public static function loadFromDatas(datas:Array<String>) {
+6 -4
View File
@@ -112,7 +112,8 @@ class MainState extends FlxState {
TranslationUtil.setLanguage(Flags.DISABLE_LANGUAGES ? Flags.DEFAULT_LANGUAGE : null);
ModsFolder.onModSwitch.dispatch(ModsFolder.currentModFolder); // Loads global.hx
MusicBeatTransition.script = Flags.DEFAULT_TRANSITION_SCRIPT;
WindowUtils.resetTitle();
WindowUtils.resetAffixes(false);
WindowUtils.setWindow();
Main.refreshAssets();
DiscordUtil.init();
EventsData.reloadEvents();
@@ -126,6 +127,8 @@ class MainState extends FlxState {
CoolUtil.safeAddAttributes('./.temp/', NativeAPI.FileAttribute.HIDDEN);
#end
var startState:Class<FlxState> = Flags.DISABLE_WARNING_SCREEN ? TitleState : funkin.menus.WarningState;
if (Options.devMode && Options.allowConfigWarning) {
var lib:ModsFolderLibrary;
for (e in Paths.assetsTree.libraries) if ((lib = cast AssetsLibraryList.getCleanLibrary(e)) is ModsFolderLibrary
@@ -133,12 +136,11 @@ class MainState extends FlxState {
{
if (lib.exists(Paths.ini("config/modpack"), lime.utils.AssetType.TEXT)) break;
FlxG.switchState(new ModConfigWarning(lib));
FlxG.switchState(new ModConfigWarning(lib, startState));
return;
}
}
if (!Flags.DISABLE_WARNING_SCREEN) FlxG.switchState(new funkin.menus.WarningState());
else FlxG.switchState(new TitleState());
FlxG.switchState(cast Type.createInstance(startState, []));
}
}
+23 -29
View File
@@ -12,13 +12,13 @@ import haxe.Exception;
* Requires the `GITHUB_API` macro to be defined.
* This has no authentication, so it's limited to unauthenticated requests, and rate limits.
**/
class GitHub {
final class GitHub {
/**
* Gets all the releases from a specific GitHub repository using the GitHub API.
* @param user The user/organization that owns the repository
* @param repository The repository name
* @param onError Error Callback
* @return Releases
* @param user The user/organization that owns the repository.
* @param repository The repository name.
* @param onError Error Callback.
* @return Releases in Array.
*/
public static function getReleases(user:String, repository:String, ?onError:Exception->Void):Array<GitHubRelease> {
#if GITHUB_API
@@ -38,17 +38,16 @@ class GitHub {
/**
* Gets the contributors list from a specific GitHub repository using the GitHub API.
* @param user The user/organization that owns the repository
* @param repository The repository name
* @param onError Error Callback
* @return Contributors List
* @param user The user/organization that owns the repository.
* @param repository The repository name.
* @param onError Error Callback.
* @return Contributors List as Array.
*/
public static function getContributors(user:String, repository:String, ?onError:Exception->Void):Array<GitHubContributor> {
#if GITHUB_API
try {
var data = Json.parse(HttpUtil.requestText('https://api.github.com/repos/${user}/${repository}/contributors'));
if (!(data is Array))
throw __parseGitHubException(data);
if (!(data is Array)) throw __parseGitHubException(data);
return data;
} catch(e) {
@@ -61,16 +60,15 @@ class GitHub {
/**
* Gets a specific GitHub organization using the GitHub API.
* @param org The organization to get
* @param onError Error Callback
* @return Organization
* @param org The organization to get.
* @param onError Error Callback.
* @return Organization.
*/
public static function getOrganization(org:String, ?onError:Exception->Void):GitHubOrganization {
#if GITHUB_API
try {
var data = Json.parse(HttpUtil.requestText('https://api.github.com/orgs/$org'));
if (Reflect.hasField(data, "documentation_url"))
throw __parseGitHubException(data);
if (Reflect.hasField(data, "documentation_url")) throw __parseGitHubException(data);
return data;
} catch(e) {
@@ -84,16 +82,15 @@ class GitHub {
/**
* Gets the members list from a specific GitHub organization using the GitHub API.
* NOTE: Members use Contributors' structure!
* @param org The organization to get the members from
* @param onError Error Callback
* @return Members List
* @param org The organization to get the members from.
* @param onError Error Callback.
* @return Members List as Array
*/
public static function getOrganizationMembers(org:String, ?onError:Exception->Void):Array<GitHubContributor> {
#if GITHUB_API
try {
var data = Json.parse(HttpUtil.requestText('https://api.github.com/orgs/$org/members'));
if (Reflect.hasField(data, "documentation_url"))
throw __parseGitHubException(data);
if (Reflect.hasField(data, "documentation_url")) throw __parseGitHubException(data);
return data;
} catch(e) {
@@ -107,18 +104,15 @@ class GitHub {
/**
* Gets a specific GitHub user/organization using the GitHub API.
* NOTE: If organization, it will be returned with the structure of a normal user; use `getOrganization` if you specifically want an organization!
* @param user The user/organization to get
* @param onError Error Callback
* @return User/Organization
* @param user The user/organization to get.
* @param onError Error Callback.
* @return User/Organization.
*/
public static function getUser(user:String, ?onError:Exception->Void):GitHubUser {
#if GITHUB_API
try {
var url = 'https://api.github.com/users/$user';
var data = Json.parse(HttpUtil.requestText(url));
if (Reflect.hasField(data, "documentation_url"))
throw __parseGitHubException(data);
var data = Json.parse(HttpUtil.requestText('https://api.github.com/users/$user'));
if (Reflect.hasField(data, "documentation_url")) throw __parseGitHubException(data);
return data;
} catch(e) {
@@ -0,0 +1,5 @@
package funkin.backend.system.interfaces;
interface IBeatCancellableReceiver extends IBeatReceiver {
public var cancelConductorUpdate:Bool;
}
@@ -33,11 +33,9 @@ class FlagMacro {
resetExprs.push(macro $i{"customFlags"} = $v{[]});
for (field in fields) {
var skip = field.meta.hasMeta(":bypass");
if (field.meta.hasMeta(":bypass")) continue;
var hasLazy = field.meta.hasMeta(":lazy");
if (skip) continue;
switch (field.kind) {
case FVar(type, expr):
var isNullable = false;
@@ -24,7 +24,11 @@ class UpdateAvailableScreen extends MusicBeatState {
public function new(check:UpdateCheckCallback) {
super();
this.check = check;
if (Date.now().getTime() - check.date.getTime() > 15000) {
if ((check = UpdateUtil.checkForUpdates(true)).newUpdate) this.check = check;
}
}
public override function create() {
@@ -56,7 +56,7 @@ class UpdateScreen extends MusicBeatState {
generalProgress.alignment = CENTER;
add(generalProgress);
overSound = FlxG.sound.load(Paths.sound(Flags.DEFAULT_GAMEOVER_RETRY_SFX));
overSound = FlxG.sound.load(Paths.sound(Flags.DEFAULT_GAMEOVEREND_SOUND));
updater.execute();
@@ -2,60 +2,97 @@ package funkin.backend.system.updating;
import funkin.backend.system.github.GitHub;
import funkin.backend.system.github.GitHubRelease;
import haxe.io.Path;
import lime.app.Application;
import sys.thread.Mutex;
import sys.thread.Thread;
import sys.FileSystem;
import haxe.io.Path;
using funkin.backend.system.github.GitHub;
class UpdateUtil {
public static var lastUpdateCheck:Null<UpdateCheckCallback>;
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
private static var __mutex:Mutex;
public static function init() {
// deletes old bak file if it exists
#if sys
var bakPath = '${Path.withoutExtension(Sys.programPath())}.bak';
if (FileSystem.exists(bakPath))
FileSystem.deleteFile(bakPath);
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
#end
__waitCallbacks = [];
__mutex = new Mutex();
Thread.create(checkForUpdates.bind(true, false));
}
public static function checkForUpdates():UpdateCheckCallback {
var curTag = 'v${Flags.VERSION}';
trace(curTag);
public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) {
if (__mutex.tryAcquire()) {
__mutex.release();
if (__shouldCheck(lazy) || force) {
__waitCallbacks.push(callback);
Thread.create(checkForUpdates.bind(force, false));
}
else
callback(lastUpdateCheck);
}
else
__waitCallbacks.push(callback);
}
var error = false;
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
var wasAcquired = !__mutex.tryAcquire();
if (wasAcquired) __mutex.acquire();
var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_NAME, Flags.REPO_OWNER, function(e) {
if ((!force || wasAcquired) && !__shouldCheck(lazy)) {
__mutex.release();
return lastUpdateCheck;
}
lastUpdateCheck = __checkForUpdates();
__mutex.release();
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
return lastUpdateCheck;
}
static function __checkForUpdates():UpdateCheckCallback {
var curTag = 'v${Flags.VERSION}', error = false;
var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_OWNER, Flags.REPO_NAME, (e) -> {
error = true;
}), curTag);
if (error) return {
success: false,
newUpdate: false
};
if (newUpdates.length <= 0) {
return {
success: true,
newUpdate: false
};
var updateCheck:UpdateCheckCallback = {
success: !error,
newUpdate: !error && newUpdates.length > 0,
currentVersionTag: curTag,
date: Date.now()
}
return {
success: true,
newUpdate: true,
currentVersionTag: curTag,
newVersionTag: newUpdates.last().tag_name,
updates: newUpdates
};
if (updateCheck.newUpdate) updateCheck.newVersionTag = (updateCheck.updates = newUpdates).last().tag_name;
return updateCheck;
}
static function __shouldCheck(lazy:Bool):Bool
return lastUpdateCheck == null || !lazy && (!lastUpdateCheck.newUpdate || Date.now().getTime() - lastUpdateCheck.date.getTime() > 1800000);
static function __callWaitCallbacks() {
for (callback in __waitCallbacks) callback(lastUpdateCheck);
__waitCallbacks.resize(0);
}
static var __curVersionPos = -2;
static function __doReleaseFiltering(releases:Array<GitHubRelease>, currentVersionTag:String) {
releases = releases.filterReleases(Options.betaUpdates, false);
if (releases.length <= 0)
return releases;
var newArray:Array<GitHubRelease> = [];
var newArray:Array<GitHubRelease> = [], __curVersionPos = -2;
var skipNextBinaryChecks:Bool = false;
for(index in 0...releases.length) {
@@ -73,13 +110,9 @@ class UpdateUtil {
}
if (containsBinary) {
skipNextBinaryChecks = true; // no need to check for older versions
if (release.tag_name == currentVersionTag) {
__curVersionPos = -1;
}
if (release.tag_name == currentVersionTag) __curVersionPos = -1;
newArray.insert(0, release);
if (__curVersionPos > -2)
__curVersionPos++;
trace(release.tag_name);
if (__curVersionPos > -2) __curVersionPos++;
}
}
if (__curVersionPos < -1)
@@ -99,4 +132,6 @@ typedef UpdateCheckCallback = {
@:optional var newVersionTag:String;
@:optional var updates:Array<GitHubRelease>;
@:optional var date:Date;
}
+2 -1
View File
@@ -474,7 +474,7 @@ final class AudioAnalyzer {
var n = Math.floor((endPos - startPos) * __toBits);
if (startPos >= time && startPos < backend.bufferTimes[backend.bufferSizes.length - 1] * 1000) {
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferSizes[i], c = 0;
while (pos > size) {
while (pos >= size) {
if (++i >= backend.bufferSizes.length) {
n = 0;
break;
@@ -484,6 +484,7 @@ final class AudioAnalyzer {
size = backend.bufferSizes[i];
}
pos -= pos % __sampleSize;
n -= pos % __sampleSize;
while (n > 0) {
callback(getByte(buf, pos, __wordSize), c);
+12 -10
View File
@@ -29,9 +29,6 @@ final class WindowUtils {
public static inline function resetClosing() __triedClosing = false;
@:dox(hide) public static inline function init() {
resetTitle();
resetClosing();
Lib.application.window.onClose.add(function () {
if (preventClosing && !__triedClosing) {
Lib.application.window.onClose.cancel();
@@ -45,16 +42,17 @@ final class WindowUtils {
* Resets the window title to the application name and resets the prefix and suffix.
**/
public static inline function resetTitle() {
title = Flags.TITLE == null ? Lib.application.meta.get('name') : Flags.TITLE;
resetAffixes();
resetAffixes(false);
title = Flags.TITLE;
}
/**
* Resets the prefix and suffix.
* @param update Should it update window title.
**/
public static inline function resetAffixes() {
public static inline function resetAffixes(update = true) {
prefix = suffix = "";
updateTitle();
if (update) updateTitle();
}
/**
@@ -62,9 +60,13 @@ final class WindowUtils {
* @param title The title to set.
* @param image The image to set as the icon.
**/
public static inline function setWindow(?name:String, ?image:String)
{ Lib.application.window.setIcon(lime.graphics.Image.fromBytes(Assets.getBytes(image != null ? image : Flags.MOD_ICON)));
title = name != null ? name : Flags.MOD_NAME;
public static inline function setWindow(?title:String, ?image:String)
{
// TODO: Implement ICON SIZES in Flags.
WindowUtils.title = title != null ? title : (Flags.WINDOW_TITLE_USE_MOD_NAME ? Flags.MOD_NAME : Flags.TITLE);
var iconPath = image != null ? image : Flags.MOD_ICON;
if (Assets.exists(Paths.image(iconPath))) Lib.application.window.setIcon(lime.graphics.Image.fromBytes(Assets.getBytes(Paths.image(iconPath))));
}
/**
+5 -5
View File
@@ -56,9 +56,9 @@ LOGO_TEXT=""
super.createPost();
hadPopup = true;
var substate = new UIWarningSubstate("Missing mod folder configuration!", "Your mod is currently missing a mod config file!\n\nWould you like to automatically generate one?\n\n(PS: If this is not your mod please disable Developer mode to stop this popup from appearing.)", [
var substate = new UIWarningSubstate(TU.translate("modConfigWarning.warningTitle"), TU.translate("modConfigWarning.warningDesc"), [
{
label: "Not Now",
label: TU.translate("editor.notNow"),
color: 0x969533,
onClick: function (_) {
MusicBeatState.skipTransOut = MusicBeatState.skipTransIn = false;
@@ -66,13 +66,13 @@ LOGO_TEXT=""
}
},
{
label: "Yes",
label: TU.translate("editor.yes"),
onClick: function(_) {
var path = '${library.folderPath}/data/config/modpack.ini';
CoolUtil.safeSaveFile(path, defaultModConfigText);
openSubState(new UIWarningSubstate("Created mod config!", "Your mod config file has been created at " + path + "!", [
openSubState(new UIWarningSubstate(TU.translate("modConfigWarning.createdTitle"), TU.translate("modConfigWarning.createdDesc", [path]), [
{
label: "Ok",
label: TU.translate("editor.ok"),
onClick: function (_) {
MusicBeatState.skipTransOut = MusicBeatState.skipTransIn = false;
FlxG.switchState(cast Type.createInstance(goToState, []));
@@ -209,6 +209,9 @@ class AlphabetEditor extends UIState {
scaleX: 1,
scaleY: 1,
flipX: false,
flipY: false,
hasColorMode: false,
colorMode: bigLetter.colorMode
};
@@ -204,6 +204,9 @@ UPPERLETTER and LOWERLETTTER can be used in any backup prefix.";
cos: 1.0,
sin: 0.0,
flipX: false,
flipY: false,
hasColorMode: false,
colorMode: 0
}],
@@ -11,6 +11,9 @@ class GlyphInfoWindow extends UIWindow {
public var angleBox:UINumericStepper;
public var colorModeDrop:UIDropDown;
public var flipXBox:UICheckbox;
public var flipYBox:UICheckbox;
public var outlineTitle:UIText;
public var outlineSep:UISprite;
public var outlineCheck:UICheckbox;
@@ -145,6 +148,9 @@ class GlyphInfoWindow extends UIWindow {
cos: compon.cos,
sin: compon.sin,
flipX: compon.flipX,
flipY: compon.flipY,
hasColorMode: compon.hasColorMode,
colorMode: compon.colorMode
};
@@ -159,6 +165,22 @@ class GlyphInfoWindow extends UIWindow {
}
members.push(outlineCheck);
flipXBox = new UICheckbox(outlineCheck.x, outlineCheck.y - outlineCheck.height - 8, "Flip X?");
flipXBox.onChecked = function(check:Bool) {
compon.flipX = check;
if (outlineCheck.checked)
data.components[compon.outIndex].flipX = check;
}
members.push(flipXBox);
flipYBox = new UICheckbox(flipXBox.x + flipXBox.width + itemMargin * 5, flipXBox.y, "Flip Y?");
flipYBox.onChecked = function(check:Bool) {
compon.flipY = check;
if (outlineCheck.checked)
data.components[compon.outIndex].flipY = check;
}
members.push(flipYBox);
outlineTitle = new UIText(colorModeDrop.x, colorModeDrop.y + colorModeDrop.bHeight + itemMargin, 0, "Outline Data");
members.push(outlineTitle);
outlineSep = new UISprite(x + itemMargin, colorModeDrop.y + colorModeDrop.bHeight + itemMargin + 19);
@@ -239,6 +261,8 @@ class GlyphInfoWindow extends UIWindow {
angleBox.value = com.angle;
@:privateAccess colorModeDrop.index = com.hasColorMode ? com.colorMode : AlphabetEditor.instance.tape.colorMode;
@:privateAccess colorModeDrop.label.text = colorModeDrop.options[colorModeDrop.index];
flipXBox.checked = com.flipX;
flipYBox.checked = com.flipY;
outlineCheck.checked = com.outIndex != null;
outlineBox.label.text = "";
+12 -16
View File
@@ -601,11 +601,13 @@ class Charter extends UIState {
Conductor.setupSong(PlayState.SONG);
noteTypes = PlayState.SONG.noteTypes;
FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff)));
if (PlayState.SONG.meta.needsVoices != false && Assets.exists(Paths.voices(__song, __diff))) // null or true
vocals = FlxG.sound.load(Paths.voices(__song, __diff));
FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff, PlayState.SONG.meta.instSuffix)));
if (Assets.exists(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix)))
vocals = FlxG.sound.load(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix));
else
vocals = new FlxSound();
vocals.muted = !PlayState.SONG.meta.needsVoices;
vocals.group = FlxG.sound.defaultMusicGroup;
gridBackdrops.createGrids(PlayState.SONG.strumLines.length);
@@ -633,22 +635,16 @@ class Charter extends UIState {
// create events
rightEventsGroup.autoSort = leftEventsGroup.autoSort = false;
var lastLeftEvents:CharterEvent = null, lastRightEvents:CharterEvent = null, lastEvents:CharterEvent;
var lastLeftTime = Math.NaN, lastRightTime = Math.NaN, lastTime:Float;
var lastLeftEvents:CharterEvent = null, lastRightEvents:CharterEvent = null;
var lastLeftTime = Math.NaN, lastRightTime = Math.NaN;
for (e in PlayState.SONG.events) if (e != null) {
if (e.global) {
lastEvents = lastRightEvents;
lastTime = lastRightTime;
if (lastRightEvents != null && lastRightTime == e.time) lastRightEvents.events.push(e);
else rightEventsGroup.add(lastRightEvents = new CharterEvent(Conductor.getStepForTime(lastRightTime = e.time), [e], e.global));
}
else {
lastEvents = lastLeftEvents;
lastTime = lastLeftTime;
}
if (lastEvents != null && lastTime == e.time) lastEvents.events.push(e);
else {
lastEvents = new CharterEvent(Conductor.getStepForTime(lastTime = e.time), [e], e.global);
(e.global ? rightEventsGroup : leftEventsGroup).add(lastEvents);
if (lastLeftEvents != null && lastLeftTime == e.time) lastLeftEvents.events.push(e);
else leftEventsGroup.add(lastLeftEvents = new CharterEvent(Conductor.getStepForTime(lastLeftTime = e.time), [e], e.global));
}
}
@@ -689,7 +685,7 @@ class Charter extends UIState {
if (FlxG.sound.music.loaded)
wavesToGenerate.push({name: "Inst.ogg", sound: FlxG.sound.music});
if (PlayState.SONG.meta.needsVoices != false && vocals.loaded)
if (vocals.loaded)
wavesToGenerate.push({name: "Voices.ogg", sound: vocals});
for (strumLine in strumLines)
@@ -23,6 +23,7 @@ class CharterMetaDataScreen extends UISubstateWindow {
public var iconSprite:HealthIcon;
public var opponentModeCheckbox:UICheckbox;
public var coopAllowedCheckbox:UICheckbox;
public var needsVoicesCheckbox:UICheckbox;
public var colorWheel:UIColorwheel;
public var difficultiesTextBox:UITextBox;
@@ -68,6 +69,9 @@ class CharterMetaDataScreen extends UISubstateWindow {
denominatorStepper = new UINumericStepper(beatsPerMeasureStepper.x + 30 + 24, beatsPerMeasureStepper.y, Math.floor(16 / metadata.stepsPerBeat), 1, 0, 1, null, 54);
add(denominatorStepper);
needsVoicesCheckbox = new UICheckbox(beatsPerMeasureStepper.x + 100, beatsPerMeasureStepper.y + 6, translate("needsVoices"), metadata.needsVoices);
add(needsVoicesCheckbox);
add(title = new UIText(songNameTextBox.x, songNameTextBox.y + 10 + 46, 0, translate("menusData"), 28));
displayNameTextBox = new UITextBox(title.x, title.y + title.height + 36, metadata.displayName);
@@ -149,6 +153,7 @@ class CharterMetaDataScreen extends UISubstateWindow {
PlayState.SONG.meta = {
name: songNameTextBox.label.text,
bpm: bpmStepper.value,
needsVoices: needsVoicesCheckbox.checked,
beatsPerMeasure: Std.int(beatsPerMeasureStepper.value),
stepsPerBeat: Std.int(16 / denominatorStepper.value),
displayName: displayNameTextBox.label.text,
@@ -161,5 +166,6 @@ class CharterMetaDataScreen extends UISubstateWindow {
};
Charter.instance.updateBPMEvents();
Charter.instance.vocals.muted = !needsVoicesCheckbox.checked;
}
}
@@ -171,7 +171,7 @@ class CharterStrumlineScreen extends UISubstateWindow {
}
}
vocalsSuffixDropDown = new UIDropDown(typeDropdown.x, hudScaleStepper.y + 128, 200, 32, suffixList, strumLine.vocalsSuffix != null && strumLine.vocalsSuffix != "" ? suffixList.indexOf(strumLine.vocalsSuffix) : 0);
vocalsSuffixDropDown = new UIDropDown(typeDropdown.x, hudScaleStepper.y + 128, 200, 32, suffixList, strumLine.vocalsSuffix != null && strumLine.vocalsSuffix != "" && Assets.exists(Paths.voices(Charter.__song.toLowerCase(), "", strumLine.vocalsSuffix)) ? suffixList.indexOf(strumLine.vocalsSuffix) : 0);
add(vocalsSuffixDropDown);
addLabelOn(vocalsSuffixDropDown, TU.translate("charterStrumLine.vocalSuffix"));
@@ -7,6 +7,7 @@ import funkin.backend.chart.ChartData;
import funkin.backend.chart.FNFLegacyParser.SwagSong;
import funkin.backend.chart.PsychParser;
import funkin.backend.chart.VSliceParser;
import funkin.backend.utils.ZipUtil;
import funkin.backend.utils.ZipUtil.ZipReader;
import funkin.game.HealthIcon;
import haxe.Json;
@@ -360,11 +361,11 @@ class SongCreationScreen extends UISubstateWindow {
{
try switch(engineDropdown.index)
{
case 0 /*"V-Slice Project (.fnfc)"*/:
case 2 /*"V-Slice Project (.fnfc)"*/:
var files:Map<String, Any> = [];
for (field in new ZipReader(new BytesInput(importChartFile.file)).read()) {
var fileName = field.fileName;
var fileContent = field.data;
var fileContent = ZipUtil.unzip(field);
files.set(fileName, fileContent);
}
saveFromVSlice(files);
@@ -405,8 +406,8 @@ class SongCreationScreen extends UISubstateWindow {
CoolUtil.safeSaveFile('$songFolder/charts/${songId}.json', Json.stringify(base, Flags.JSON_PRETTY_PRINT));
#end
});
} catch (e) {
openSubState(new UIWarningSubstate("Importing Song/Charts: Error!", Std.string(e), [
} catch (e:haxe.Exception) {
openSubState(new UIWarningSubstate("Importing Song/Charts: Error!", e.details(), [
{label: "Ok", color: 0xFFFF0000, onClick: function(t) {}}
]));
}
+2 -2
View File
@@ -150,7 +150,7 @@ class UIUtil {
} else if (member is UITextBox) @:privateAccess {
var textbox:UITextBox = cast member;
if (textbox.__wasFocused) {
textbox.onChange(textbox.label.text);
if (textbox.onChange != null) textbox.onChange(textbox.label.text);
textbox.__wasFocused = false;
}
}
@@ -159,4 +159,4 @@ class UIUtil {
confirmUISelections(cast member);
}
}
}
}
+10 -8
View File
@@ -87,6 +87,7 @@ class GameOverSubstate extends MusicBeatSubstate
lossSFX = FlxG.sound.play(Paths.sound(lossSFXName));
Conductor.changeBPM(gameOverSongBPM);
cancelConductorUpdate = true;
DiscordUtil.call("onGameOver", []);
gameoverScript.call("postCreate");
@@ -106,22 +107,23 @@ class GameOverSubstate extends MusicBeatSubstate
if (!isEnding && ((!lossSFX.playing) || (character.getAnimName() == "firstDeath" && character.isAnimFinished())) && (FlxG.sound.music == null || !FlxG.sound.music.playing))
{
var event = new CancellableEvent();
gameoverScript.call("deathStart", [event]);
if (event.cancelled) return;
CoolUtil.playMusic(Paths.music(gameOverSong), false, 1, true, Flags.DEFAULT_BPM);
beatHit(0);
character.playAnim("deathLoop", true, DANCE);
cancelConductorUpdate = false;
gameoverScript.call("postDeathStart");
}
}
override function beatHit(curBeat:Int)
{
super.beatHit(curBeat);
gameoverScript.call("beatHit", [curBeat]);
if (__cancelDefault)
return;
if (FlxG.sound.music != null && FlxG.sound.music.playing)
character.playAnim("deathLoop", true, DANCE);
}
override function stepHit(curStep:Int)
+1 -1
View File
@@ -388,7 +388,7 @@ class HealthIcon extends FunkinSprite
}) + sprTrackerOffset.x, sprTracker.y + sprTrackerOffset.y);
}
if (animation.curAnim != null || (this.animated && animateAtlas != null)) {
if (animation.curAnim != null || this.animated) {
var data = getIconAnim(health);
var localAnimState = data.animState;
+77 -46
View File
@@ -362,6 +362,10 @@ class PlayState extends MusicBeatState
* Speed at which the game camera zoom lerps to.
*/
public var camGameZoomLerp:Float = Flags.DEFAULT_CAM_ZOOM_LERP;
/**
* The current multiplier for game camera zooming.
*/
public var camGameZoomMult:Float = Flags.DEFAULT_CAM_ZOOM_MULT;
/**
* Camera zoom at which the hud lerps to.
@@ -371,6 +375,21 @@ class PlayState extends MusicBeatState
* Speed at which the hud camera zoom lerps to.
*/
public var camHUDZoomLerp:Float = Flags.DEFAULT_HUD_ZOOM_LERP;
/**
* The current multiplier for game camera zooming.
*/
public var camHUDZoomMult:Float = Flags.DEFAULT_HUD_ZOOM_MULT;
/**
* Camera zoom at which the cameras that zooms lerps to.
* (Only used if useCamZoomMult is on).
*/
public var defaultZoom:Float = Flags.DEFAULT_ZOOM;
/**
* Speed at which the cameras that zooms zoom lerps to.
* (Only used if useCamZoomMult is on).
*/
public var camZoomLerp:Float = Flags.DEFAULT_ZOOM_LERP;
/**
* Whenever cam zooming is enabled, enables on a note hit if not cancelled.
@@ -401,15 +420,24 @@ class PlayState extends MusicBeatState
*/
public var camZoomingStrength:Float = Flags.DEFAULT_CAM_ZOOM_STRENGTH;
/**
* Default multiplier for `maxCamZoom`.
*/
* Default multiplier for `maxCamZoom`.
*/
public var maxCamZoomMult:Float = Flags.MAX_CAMERA_ZOOM_MULT;
/**
* Maximum amount of zoom for the camera (based on `maxCamZoomMult` and the camera's zoom IF not set).
*/
* Whether it should use a implementation where it multiplies the current camera zoom instead.
*/
public var useCamZoomMult:Bool = Flags.USE_CAM_ZOOM_MULT;
/**
* The current multiplier for camera zooming.
* (Only used if useCamZoomMult is on).
*/
public var camZoomingMult:Float = Flags.DEFAULT_ZOOM;
/**
* Maximum amount of zoom for the camera (based on `maxCamZoomMult` and the camera's zoom IF not set).
*/
public var maxCamZoom(get, default):Float = Math.NaN;
private inline function get_maxCamZoom() return Math.isNaN(maxCamZoom) ? maxCamZoomMult * defaultCamZoom : maxCamZoom;
private inline function get_maxCamZoom() return Math.isNaN(maxCamZoom) ? defaultCamZoom + (camZoomingMult * camGameZoomMult) : maxCamZoom;
/**
* Zoom for the pixel assets.
@@ -524,7 +552,7 @@ class PlayState extends MusicBeatState
@:noCompletion @:dox(hide) private var _endSongCalled:Bool = false;
@:dox(hide)
var __vocalSyncTimer:Float = 0;
var __vocalSyncTimer:Float = 1;
private function get_accuracy():Float {
if (accuracyPressedNotes <= 0) return -1;
@@ -1085,9 +1113,11 @@ class PlayState extends MusicBeatState
curSong = songData.meta.name.toLowerCase();
curSongID = curSong.replace(" ", "-");
FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty))));
if (SONG.meta.needsVoices != false && Assets.exists(Paths.voices(SONG.meta.name, difficulty))) // null or true
vocals = FlxG.sound.load(Options.streamedVocals ? Assets.getMusic(Paths.voices(SONG.meta.name, difficulty)) : Paths.voices(SONG.meta.name, difficulty));
FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty, SONG.meta.instSuffix))));
var vocalsPath = Paths.voices(SONG.meta.name, difficulty, SONG.meta.vocalsSuffix);
if (SONG.meta.needsVoices && Assets.exists(vocalsPath))
vocals = FlxG.sound.load(Options.streamedVocals ? Assets.getMusic(vocalsPath) : vocalsPath);
else
vocals = new FlxSound();
@@ -1196,7 +1226,7 @@ class PlayState extends MusicBeatState
var time = Conductor.songPosition + Conductor.songOffset;
for (strumLine in strumLines.members) strumLine.vocals.play(true, time);
vocals.play(true, time);
inst.play(true, time);
if (!inst.playing) inst.play(true, time);
gameAndCharsCall("onVocalsResync");
}
@@ -1324,12 +1354,17 @@ class PlayState extends MusicBeatState
if (canAccessDebugMenus && chartingMode && controls.DEV_ACCESS)
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false));
if (Options.camZoomOnBeat && camZooming && FlxG.camera.zoom < maxCamZoom) {
if (Options.camZoomOnBeat && camZooming) {
var beat = Conductor.getBeats(camZoomingEvery, camZoomingInterval, camZoomingOffset);
if (camZoomingLastBeat != beat) {
camZoomingLastBeat = beat;
FlxG.camera.zoom += 0.015 * camZoomingStrength;
camHUD.zoom += 0.03 * camZoomingStrength;
if (useCamZoomMult) {
if (camZoomingMult < maxCamZoomMult) camZoomingMult += camZoomingStrength;
}
else if (FlxG.camera.zoom < maxCamZoom) {
FlxG.camera.zoom += camGameZoomMult * camZoomingStrength;
camHUD.zoom += camHUDZoomMult * camZoomingStrength;
}
}
}
@@ -1342,20 +1377,19 @@ class PlayState extends MusicBeatState
updateIconPositions();
if (startingSong) {
if (startedCountdown) {
Conductor.songPosition += Conductor.songOffset + elapsed * 1000;
if (Conductor.songPosition >= 0)
startSong();
if (startedCountdown && (Conductor.songPosition += Conductor.songOffset + elapsed * 1000) >= 0) {
Conductor.songPosition = Conductor.songOffset;
startSong();
}
}
else if (FlxG.sound.music != null && (__vocalSyncTimer -= elapsed) < 0) {
__vocalSyncTimer = 1;
var instTime = FlxG.sound.music.getActualTime();
var isOffsync:Bool = vocals.loaded && Math.abs(instTime - vocals.getActualTime()) > 30;
var isOffsync:Bool = vocals.loaded && Math.abs(instTime - vocals.getActualTime()) > 100;
if (!isOffsync) {
for (strumLine in strumLines.members) {
if ((isOffsync = strumLine.vocals.loaded && Math.abs(instTime - strumLine.vocals.getActualTime()) > 30)) break;
if ((isOffsync = strumLine.vocals.loaded && Math.abs(instTime - strumLine.vocals.getActualTime()) > 100)) break;
}
}
@@ -1372,6 +1406,12 @@ class PlayState extends MusicBeatState
moveCamera();
if (camZooming) {
if (useCamZoomMult) {
camZoomingMult = lerp(camZoomingMult, defaultZoom, camZoomLerp) - defaultZoom;
FlxG.camera.zoomMultiplier = camZoomingMult * camGameZoomMult + defaultZoom;
camHUD.zoomMultiplier = camZoomingMult * camHUDZoomMult + defaultZoom;
camZoomingMult += defaultZoom;
}
FlxG.camera.zoom = lerp(FlxG.camera.zoom, defaultCamZoom, camGameZoomLerp);
camHUD.zoom = lerp(camHUD.zoom, defaultHudZoom, camHUDZoomLerp);
}
@@ -1530,6 +1570,8 @@ class PlayState extends MusicBeatState
case "Add Camera Zoom":
var camera:FlxCamera = event.params[1] == "camHUD" ? camHUD : camGame;
camera.zoom += event.params[0];
case "Camera Bop":
camZoomingMult += event.params[0];
case "Camera Zoom":
var cam = event.params[2] == "camHUD" ? camHUD : camGame;
var name = (event.params[2] == "camHUD" ? "camHUD" : "camGame") + ".zoom"; // avoiding having different values from these 2 - Nex
@@ -1648,17 +1690,12 @@ class PlayState extends MusicBeatState
endingSong = true;
gameAndCharsCall("onSongEnd");
canPause = false;
inst.volume = 0;
vocals.volume = 0;
for (strumLine in strumLines.members) {
strumLine.vocals.volume = 0;
strumLine.vocals.pause();
}
inst.pause();
vocals.pause();
if (validScore)
{
for (strumLine in strumLines.members) strumLine.vocals.stop();
inst.stop();
vocals.stop();
if (validScore) {
#if !switch
FunkinSave.setSongHighscore(SONG.meta.name, difficulty, {
score: songScore,
@@ -1686,20 +1723,18 @@ class PlayState extends MusicBeatState
* Immediately switches to the next song, or goes back to the Story/Freeplay menu.
*/
public function nextSong() {
if (isStoryMode)
{
if (isStoryMode) {
campaignScore += songScore;
campaignMisses += misses;
campaignAccuracyTotal += accuracy;
campaignAccuracyCount++;
storyPlaylist.shift();
if (storyPlaylist.length <= 0)
{
if (storyPlaylist.length <= 0) {
FlxG.switchState(new StoryMenuState());
if (validScore)
{
if (validScore) {
#if !switch
// TODO: more week info saving
FunkinSave.setWeekHighscore(storyWeek.id, difficulty, {
score: campaignScore,
@@ -1708,29 +1743,23 @@ class PlayState extends MusicBeatState
hits: [],
date: Date.now().toString()
});
#end
}
FlxG.save.flush();
}
else
{
else {
Logs.infos('Loading next song (${storyPlaylist[0].toLowerCase()}/$difficulty)', "PlayState");
registerSmoothTransition();
FlxG.sound.music.stop();
__loadSong(storyPlaylist[0], difficulty);
FlxG.switchState(new PlayState());
}
}
else if (chartingMode)
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false));
else
{
if (chartingMode)
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false));
else
FlxG.switchState(new FreeplayState());
}
FlxG.switchState(new FreeplayState());
}
public function registerSmoothTransition() {
@@ -1902,6 +1931,8 @@ class PlayState extends MusicBeatState
}
if (event.deleteNote) strumLine.deleteNote(note);
gameAndCharsEvent("onPostNoteHit", event);
}
public function displayRating(myRating:String, ?evt:NoteHitEvent = null):Void {
+66 -31
View File
@@ -19,6 +19,16 @@ class FreeplayState extends MusicBeatState
*/
public var songs:Array<ChartMetaData> = [];
/**
* Current song metadata
*/
public var curSong:Null<ChartMetaData>;
/**
* Current song metadata difficulty
*/
public var curSongDifficulty:Null<String>;
/**
* Currently selected song
*/
@@ -43,7 +53,7 @@ class FreeplayState extends MusicBeatState
public var diffText:FlxText;
/**
* Text containing the current coop/opponent mode ([TAB] Co-Op mode)
* Text containing the current coop/opponent mode ([KEYBINDS] Co-Op mode)
*/
public var coopText:FlxText;
@@ -107,7 +117,9 @@ class FreeplayState extends MusicBeatState
curSelected = k;
}
}
if (songs[curSelected] != null) {
updateCurSongMeta();
if (curSong != null) {
for(k=>diff in songs[curSelected].difficulties) {
if (diff == Options.freeplayLastDifficulty) {
curDifficulty = k;
@@ -225,7 +237,7 @@ class FreeplayState extends MusicBeatState
if (canSelect) {
changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0) - FlxG.mouse.wheel);
changeDiff((controls.LEFT_P ? -1 : 0) + (controls.RIGHT_P ? 1 : 0));
changeCoopMode((FlxG.keys.justPressed.TAB ? 1 : 0)); // TODO: make this configurable
changeCoopMode((controls.CHANGE_MODE ? 1 : 0)); // TODO: make this configurable
// putting it before so that its actually smooth
updateOptionsAlpha();
}
@@ -238,14 +250,14 @@ class FreeplayState extends MusicBeatState
scoreText.x = coopText.x = scoreBG.x + 4;
diffText.x = Std.int(scoreBG.x + ((scoreBG.width - diffText.width) / 2));
interpColor.fpsLerpTo(songs[curSelected].color, 0.0625);
interpColor.fpsLerpTo(curSong.color, 0.0625);
bg.color = interpColor.color;
#if PRELOAD_ALL
var dontPlaySongThisFrame = false;
autoplayElapsed += elapsed;
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay || FlxG.keys.justPressed.SPACE)) {
if (curPlayingInst != (curPlayingInst = Paths.inst(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty]))) {
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay)) {
if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curSongDifficulty, curSong.instSuffix))) {
var streamed = false;
if (Options.streamedMusic) {
var sound = Assets.getMusic(curPlayingInst, true, false);
@@ -253,7 +265,7 @@ class FreeplayState extends MusicBeatState
if (streamed && autoplayShouldPlay) {
FlxG.sound.playMusic(sound, 0);
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
Conductor.changeBPM(curSong.bpm, curSong.beatsPerMeasure, curSong.stepsPerBeat);
}
}
@@ -268,7 +280,7 @@ class FreeplayState extends MusicBeatState
if (sound != null && autoplayShouldPlay) {
FlxG.sound.playMusic(sound, 0);
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
Conductor.changeBPM(curSong.bpm, curSong.beatsPerMeasure, curSong.stepsPerBeat);
}
}
if (!disableAsyncLoading) Main.execAsync(huh);
@@ -302,7 +314,6 @@ class FreeplayState extends MusicBeatState
function updateCoopModes() {
__opponentMode = false;
__coopMode = false;
var curSong = songs[curSelected];
if (curSong.coopAllowed && curSong.opponentModeAllowed) {
__opponentMode = curCoopMode % 2 == 1;
__coopMode = curCoopMode >= 2;
@@ -321,7 +332,7 @@ class FreeplayState extends MusicBeatState
if (songs[curSelected].difficulties.length <= 0) return;
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], __opponentMode, __coopMode));
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(curSong.name, curSongDifficulty, __opponentMode, __coopMode));
if (event.cancelled) return;
@@ -329,17 +340,17 @@ class FreeplayState extends MusicBeatState
autoplayShouldPlay = false;
#end
Options.freeplayLastSong = songs[curSelected].name;
Options.freeplayLastDifficulty = songs[curSelected].difficulties[curDifficulty];
Options.freeplayLastSong = curSong.name;
Options.freeplayLastDifficulty = curSongDifficulty;
PlayState.loadSong(event.song, event.difficulty, event.opponentMode, event.coopMode);
FlxG.switchState(new PlayState());
}
public function convertChart() {
trace('Converting ${songs[curSelected].name} (${songs[curSelected].difficulties[curDifficulty]}) to Codename format...');
var chart = Chart.parse(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty]);
Chart.save('${Main.pathBack}assets/songs/${songs[curSelected].name}', chart, songs[curSelected].difficulties[curDifficulty]);
trace('Converting ${curSong.name} (${curSongDifficulty}) to Codename format...');
var chart = Chart.parse(curSong.name, curSongDifficulty);
Chart.save('${Main.pathBack}assets/songs/${curSong.name}', chart, curSongDifficulty);
}
/**
@@ -351,20 +362,31 @@ class FreeplayState extends MusicBeatState
{
if (change == 0 && !force) return;
var curSong = songs[curSelected];
var validDifficulties = curSong.difficulties.length > 0;
var event = event("onChangeDiff", EventManager.get(MenuChangeEvent).recycle(curDifficulty, validDifficulties ? FlxMath.wrap(curDifficulty + change, 0, curSong.difficulties.length-1) : 0, change));
var song = songs[curSelected];
var validDifficulties = song.difficulties.length > 0;
var event = event("onChangeDiff", EventManager.get(MenuChangeEvent).recycle(curDifficulty, validDifficulties ? FlxMath.wrap(curDifficulty + change, 0, song.difficulties.length-1) : 0, change));
if (event.cancelled) return;
if (event.cancelled) {
if (force) updateCurSongMeta();
return;
}
var prevInstSuffix = curSong.instSuffix;
curDifficulty = event.value;
updateCurSongMeta();
updateScore();
if (curSong.difficulties.length > 1)
diffText.text = '< ${curSong.difficulties[curDifficulty].toUpperCase()} >';
#if PRELOAD_ALL
if (curSong.instSuffix != prevInstSuffix) {
autoplayElapsed = 0;
songInstPlaying = false;
}
#end
if (song.difficulties.length > 1)
diffText.text = '< ${song.difficulties[curDifficulty].toUpperCase()} >';
else
diffText.text = validDifficulties ? curSong.difficulties[curDifficulty].toUpperCase() : "-";
diffText.text = validDifficulties ? song.difficulties[curDifficulty].toUpperCase() : "-";
}
function updateScore() {
@@ -376,7 +398,7 @@ class FreeplayState extends MusicBeatState
var changes:Array<HighscoreChange> = [];
if (__coopMode) changes.push(CCoopMode);
if (__opponentMode) changes.push(COpponentMode);
var saveData = FunkinSave.getSongHighscore(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], changes);
var saveData = FunkinSave.getSongHighscore(curSong.name, curSongDifficulty, changes);
intendedScore = saveData.score;
}
@@ -397,9 +419,9 @@ class FreeplayState extends MusicBeatState
*/
public function changeCoopMode(change:Int = 0, force:Bool = false) {
if (change == 0 && !force) return;
if (!songs[curSelected].coopAllowed && !songs[curSelected].opponentModeAllowed) return;
if (!curSong.coopAllowed && !curSong.opponentModeAllowed) return;
var bothEnabled = songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed;
var bothEnabled = curSong.coopAllowed && curSong.opponentModeAllowed;
var event = event("onChangeCoopMode", EventManager.get(MenuChangeEvent).recycle(curCoopMode, FlxMath.wrap(curCoopMode + change, 0, bothEnabled ? 3 : 1), change));
if (event.cancelled) return;
@@ -408,12 +430,16 @@ class FreeplayState extends MusicBeatState
updateScore();
var key = "[TAB] "; // TODO: make this configurable
var coopBinds = [CoolUtil.keyToString(Options.P1_CHANGE_MODE[0]), CoolUtil.keyToString(Options.P2_CHANGE_MODE[0])].filter(x -> x != "---");
if (coopBinds.length == 2 && coopBinds[1] == coopBinds[0]) coopBinds.pop();
else if (coopBinds.length == 0) coopBinds.push("---");
var key = '[${coopBinds.join(" / ")}] ';
if (bothEnabled) {
coopText.text = key + coopLabels[curCoopMode];
} else {
coopText.text = key + coopLabels[curCoopMode * (songs[curSelected].coopAllowed ? 2 : 1)];
coopText.text = key + coopLabels[curCoopMode * (curSong.coopAllowed ? 2 : 1)];
}
}
@@ -426,7 +452,6 @@ class FreeplayState extends MusicBeatState
{
if (change == 0 && !force) return;
var bothEnabled = songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed;
var event = event("onChangeSelection", EventManager.get(MenuChangeEvent).recycle(curSelected, FlxMath.wrap(curSelected + change, 0, songs.length-1), change));
if (event.cancelled) return;
@@ -440,7 +465,7 @@ class FreeplayState extends MusicBeatState
songInstPlaying = false;
#end
coopText.visible = songs[curSelected].coopAllowed || songs[curSelected].opponentModeAllowed;
coopText.visible = curSong.coopAllowed || curSong.opponentModeAllowed;
}
function updateOptionsAlpha() {
@@ -465,6 +490,16 @@ class FreeplayState extends MusicBeatState
item.alpha = selectedAlpha;
}
}
function updateCurSongMeta() {
var song = songs[curSelected];
if (song == null) {
curSong = null;
curSongDifficulty = null;
}
else if ((curSong = song.metas.get(curSongDifficulty = song.difficulties[curDifficulty])) == null)
curSong = song;
}
}
class FreeplaySonglist {
@@ -485,7 +520,7 @@ class FreeplaySonglist {
}
if (songsFound == null) songsFound = Paths.getFolderDirectories("songs", false, source);
if (songsFound.length > 0) {
for (s in songsFound) songs.push(Chart.loadChartMeta(s, Flags.DEFAULT_DIFFICULTY, source == MODS));
for (s in songsFound) songs.push(Chart.loadChartMeta(s, source == MODS));
return false;
}
return true;
+20
View File
@@ -25,6 +25,8 @@ class MainMenuState extends MusicBeatState
var camFollow:FlxObject;
var versionText:FunkinText;
var devModeWarning:FunkinText;
public var canAccessDebugMenus:Bool = !Flags.DISABLE_EDITORS;
override function create()
@@ -85,10 +87,17 @@ class MainMenuState extends MusicBeatState
add(versionText);
changeItem();
devModeWarning = new FunkinText(0, FlxG.height - 50, 1280, "You have to enable DEVELOPER MODE in the miscellaneous settings!", 24);
devModeWarning.alignment = CENTER;
add(devModeWarning);
devModeWarning.scrollFactor.set();
devModeWarning.alpha = 0;
}
var selectedSomethin:Bool = false;
var forceCenterX:Bool = true;
var devModeCount:Int = 0;
override function update(elapsed:Float)
{
@@ -111,6 +120,17 @@ class MainMenuState extends MusicBeatState
}
*/
}
if (!Options.devMode && FlxG.keys.justPressed.SEVEN) {
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND));
if (devModeCount++ == 2) {
FlxTween.tween(devModeWarning, {alpha: 1}, 0.4);
}
FlxTween.completeTweensOf(devModeWarning);
FlxTween.color(devModeWarning, 0.2, 0xFFFF0000, 0xFFFFFFFF);
FlxTween.shake(devModeWarning, 0.005, 0.3);
devModeWarning.y = FlxG.height - 75;
FlxTween.tween(devModeWarning, {y: FlxG.height - 50}, 0.4);
}
var upP = controls.UP_P;
var downP = controls.DOWN_P;
+13 -11
View File
@@ -129,7 +129,7 @@ class TitleState extends MusicBeatState
if (pressedEnter && transitioning && skippedIntro) {
FlxG.camera.stopFX();// FlxG.camera.visible = false;
goToMainMenu();
goToMainMenu(false);
}
if (pressedEnter && !transitioning && skippedIntro)
@@ -152,22 +152,24 @@ class TitleState extends MusicBeatState
transitioning = true;
// FlxG.sound.music.stop();
new FlxTimer().start(2, (_) -> goToMainMenu());
new FlxTimer().start(2, (_) -> goToMainMenu(false));
}
function goToMainMenu() {
function goToMainMenu(force = true) {
#if UPDATE_CHECKING
var report = hasCheckedUpdates ? null : funkin.backend.system.updating.UpdateUtil.checkForUpdates();
hasCheckedUpdates = true;
if (!force && !Flags.DISABLE_AUTOUPDATER) {
funkin.backend.system.updating.UpdateUtil.waitForUpdates(false, (report) -> {
hasCheckedUpdates = true;
if (FlxG.state != this) return;
if (report != null && report.newUpdate) {
FlxG.switchState(new funkin.backend.system.updating.UpdateAvailableScreen(report));
} else {
if (!report.newUpdate) goToMainMenu(true);
else FlxG.switchState(new funkin.backend.system.updating.UpdateAvailableScreen(report));
}, true);
}
else
#end {
FlxG.switchState(new MainMenuState());
}
#else
FlxG.switchState(new MainMenuState());
#end
}
public function createCoolText(textArray:Array<String>)
+27 -3
View File
@@ -37,6 +37,9 @@ final class AlphabetComponent {
public var scaleX:Float;
public var scaleY:Float;
public var flipX:Bool;
public var flipY:Bool;
public var hasColorMode:Bool;
public var colorMode:ColorMode;
}
@@ -346,9 +349,9 @@ class Alphabet extends FlxSprite {
_matrix.translate(_frame.frame.width * -0.5, _frame.frame.height * -0.5);
if (__useDrawScale)
_matrix.scale(__drawScale.x, __drawScale.y);
_matrix.scale(__drawScale.x * (__component.flipX ? -1 : 1), __drawScale.y * (__component.flipY ? -1 : 1));
else
_matrix.scale(__component.scaleX, __component.scaleY);
_matrix.scale(__component.scaleX * (__component.flipX ? -1 : 1), __component.scaleY * (__component.flipY ? -1 : 1));
if(__component.shouldRotate)
_matrix.rotateWithTrig(__component.cos, __component.sin);
_matrix.translate(_frame.frame.width * 0.5, _frame.frame.height * 0.5);
@@ -558,6 +561,9 @@ class Alphabet extends FlxSprite {
cos: angleCos,
sin: angleSin,
flipX: node.get("flipX") == "true",
flipY: node.get("flipY") == "true",
hasColorMode: false,
colorMode: 0
}],
@@ -593,6 +599,9 @@ class Alphabet extends FlxSprite {
var colorMode = ["tint", "offsets", "none"].indexOf(component.get("colorMode"));
var xFlip = component.get("flipX") == "true";
var yFlip = component.get("flipY") == "true";
if (component.get("hasOutline") == "true") {
components.insert(startIndex, {
refIndex: componentsPushed,
@@ -608,6 +617,9 @@ class Alphabet extends FlxSprite {
cos: angleCos,
sin: angleSin,
flipX: xFlip,
flipY: yFlip,
hasColorMode: colorMode >= 0,
colorMode: colorMode,
});
@@ -628,6 +640,9 @@ class Alphabet extends FlxSprite {
cos: angleCos,
sin: angleSin,
flipX: xFlip,
flipY: yFlip,
hasColorMode: colorMode >= 0,
colorMode: colorMode,
});
@@ -659,6 +674,9 @@ class Alphabet extends FlxSprite {
var yScale:Float = Std.parseFloat(node.get("scaleY")).getDefaultFloat(1.0);
var advance:Float = Std.parseFloat(node.get("advance"));
var xFlip = node.get("flipX") == "true";
var yFlip = node.get("flipY") == "true";
var colorMode = ["tint", "offsets", "none"].indexOf(node.get("colorMode"));
var components:Array<AlphabetComponent> = [];
@@ -677,6 +695,9 @@ class Alphabet extends FlxSprite {
cos: angleCos,
sin: angleSin,
flipX: xFlip,
flipY: yFlip,
hasColorMode: colorMode >= 0,
colorMode: colorMode,
});
@@ -696,6 +717,9 @@ class Alphabet extends FlxSprite {
cos: angleCos,
sin: angleSin,
flipX: xFlip,
flipY: yFlip,
hasColorMode: colorMode >= 0,
colorMode: colorMode,
});
@@ -758,7 +782,7 @@ class Alphabet extends FlxSprite {
}
private static var alphabetProperties:Array<String> = ["fps", "advance", "lineGap", "forceCasing", "useColorOffsets", "antialiasing"];
private static var componentProperties:Array<String> = ["name", "anim", "x", "y", "scaleX", "scaleY", "angle", "offsetX", "offsetY"];
private static var componentProperties:Array<String> = ["name", "anim", "x", "y", "scaleX", "scaleY", "angle", "offsetX", "offsetY", "flipX", "flipY"];
public function buildXML():Xml {
var xml = Xml.createElement("alphabet");
+3
View File
@@ -117,6 +117,7 @@ class Options
public static var P1_ACCEPT:Array<FlxKey> = [ENTER];
public static var P1_BACK:Array<FlxKey> = [BACKSPACE];
public static var P1_PAUSE:Array<FlxKey> = [ENTER];
public static var P1_CHANGE_MODE:Array<FlxKey> = [TAB];
// Misc
public static var P1_RESET:Array<FlxKey> = [R];
@@ -148,6 +149,7 @@ class Options
public static var P2_ACCEPT:Array<FlxKey> = [SPACE];
public static var P2_BACK:Array<FlxKey> = [ESCAPE];
public static var P2_PAUSE:Array<FlxKey> = [ESCAPE];
public static var P2_CHANGE_MODE:Array<FlxKey> = [];
// Misc
public static var P2_RESET:Array<FlxKey> = [];
@@ -179,6 +181,7 @@ class Options
public static var SOLO_ACCEPT(get, null):Array<FlxKey>;
public static var SOLO_BACK(get, null):Array<FlxKey>;
public static var SOLO_PAUSE(get, null):Array<FlxKey>;
public static var SOLO_CHANGE_MODE(get, null):Array<FlxKey>;
// Misc
public static var SOLO_RESET(get, null):Array<FlxKey>;
@@ -11,11 +11,11 @@ class MiscOptions extends TreeMenuScreen {
#if UPDATE_CHECKING
add(new Checkbox(getNameID('betaUpdates'), getDescID('betaUpdates'), 'betaUpdates'));
add(new TextOption(getNameID('checkForUpdates'), getDescID('checkForUpdates'), () -> {
var report = funkin.backend.system.updating.UpdateUtil.checkForUpdates();
var report = funkin.backend.system.updating.UpdateUtil.checkForUpdates(true);
if (report.newUpdate) FlxG.switchState(new funkin.backend.system.updating.UpdateAvailableScreen(report));
else {
CoolUtil.playMenuSFX(CANCEL);
updateDescText(translate('checkForUpdates-noUpdateFound'));
//updateDescText(translate('checkForUpdates-noUpdateFound'));
}
}));
#end
@@ -97,17 +97,21 @@ class KeybindsOptions extends MusicBeatSubstate {
name: translate("ui.pause"),
control: 'PAUSE'
},
{
name: translate("ui.changeMode"),
control: 'CHANGE_MODE'
},
]
},
{
name: translate("category.volume"),
settings: [
{
name: translate("up"),
name: translate("volume.up"),
control: 'VOLUME_UP'
},
{
name: translate("down"),
name: translate("volume.down"),
control: 'VOLUME_DOWN'
},
{
@@ -25,10 +25,10 @@ import lime.utils.ArrayBufferView;
@:access(lime.media.AudioBuffer)
@:access(lime.utils.ArrayBufferView)
class NativeAudioSource {
private static var STREAM_BUFFER_SAMPLES:Int = 0x1000;
private static var STREAM_MAX_BUFFERS:Int = 32;
private static var STREAM_BUFFER_SAMPLES:Int = 0x4000;
private static var STREAM_MAX_BUFFERS:Int = 8;
private static var STREAM_TIMER_FREQUENCY:Int = 100;
private static var STREAM_BUFFER_FREQUENCY:Int = 6;
private static var STREAM_BUFFER_FREQUENCY:Int = 3;
private var parent:AudioSource;
private var disposed:Bool;
@@ -372,7 +372,7 @@ class NativeAudioSource {
if (playing) {
var timeRemaining = (getLength() - value) / getPitch();
if (timeRemaining < 8) complete();
if (timeRemaining < 8 && value > 8) complete();
else {
completed = streamEnded = false;
if (streamed) {
+18 -1
View File
@@ -312,12 +312,29 @@ class AudioBuffer
if (vorbisFile == null) return null;
var info = vorbisFile.info();
if (info == null) return null;
var audioBuffer = new AudioBuffer();
audioBuffer.channels = info.channels;
audioBuffer.sampleRate = info.rate;
audioBuffer.bitsPerSample = 16;
audioBuffer.__srcVorbisFile = vorbisFile;
if (!vorbisFile.seekable() ||
vorbisFile.pcmTotal() < #if lime_cffi @:privateAccess lime._internal.backend.native.NativeAudioSource.STREAM_BUFFER_SAMPLES #else 0x4000 #end)
{
// convert it to static if its too short or unseekable.
vorbisFile.rawSeek(0);
var isBigEndian = lime.system.System.endianness == lime.system.Endian.BIG_ENDIAN;
var bytes:Bytes = Bytes.alloc(Std.int(haxe.Int64.toInt(vorbisFile.pcmTotal()) * info.channels * 2));
var total = 0, result = 0;
do {
total += (result = vorbisFile.read(bytes, total, 0x1000, isBigEndian, 2, true));
} while (result > 0);
audioBuffer.data = new UInt8Array(bytes);
}
else audioBuffer.__srcVorbisFile = vorbisFile;
return audioBuffer;
}