1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2025-08-30 10:25:00 +00:00

Compare commits

...

1203 commits

Author SHA1 Message Date
Til 211ae319d0
Merge 6178f4b62b into 9c1e22309b 2025-08-03 22:32:53 +00:00
TechnikTil 6178f4b62b
oops 2025-08-03 16:32:49 -06:00
JackXson-Real 9c1e22309b decrease preview volume from 80% to 70% 2025-08-03 15:59:12 -05:00
JackXson-Real 4ecef6db74 increase preview volume to 80% 2025-08-03 15:59:12 -05:00
Kolo b128741075 mb gang 2025-08-03 15:49:36 -05:00
AwesomezPro99 86e69cfbd1 Fixed Window Title When Pressing F4 2025-08-03 15:36:26 -05:00
TechnikTil 2071e5e913
change submodules to be the same as upstream/develop 2025-08-03 13:43:19 -06:00
TechnikTil 18c2063355
fully remake pausing during a cutscene 2025-08-03 13:38:04 -06:00
Karim Akra aa8690fce3
Merge pull request #1489 from FunkinCrew/pr-5565/SrtHero278/pointer-fixes
[PUBLIC PR] Properly add the touch pointer on playstate
2025-08-03 17:45:12 +03:00
MrMadera e281bdddca south button now works! 2025-08-03 21:29:29 +08:00
MoonDroid 19fdda7cd9 fix: Call Math.round and FlxMath.clamp for better readability and slightly better functionality
what a mouthful :(
2025-08-03 15:54:16 +03:00
MoonDroid d72b989bf5 Delete useless line 2025-08-03 15:54:16 +03:00
Lasercar cd99905bdf Fix volumes being reset to 100% after playtest 2025-08-03 15:54:16 +03:00
Lasercar 3f82f3792b Set playspeed after variation load 2025-08-03 15:54:16 +03:00
trofim.al 1d8ed5198c api version 0.7.0
Update example mod's API version so it actually loads. part 2.
2025-08-03 13:41:33 +03:00
AwesomezPro99 8cd3785e3c Fix Blazin' Death Pause 2025-08-03 13:01:13 +03:00
MAJigsaw77 7e01e7332b Fix html5 compile. 2025-08-03 12:48:54 +07:00
MAJigsaw77 c3a837b054 Dont compile the android classes on other targets. 2025-08-03 12:48:54 +07:00
MAJigsaw77 a92567886c Relocate the external folder outside of mobile package. 2025-08-03 12:48:54 +07:00
Abnormal 4cbfaefc1a Slightly longer fade transition
Co-authored-by: VirtuGuy <103977942+VirtuGuy@users.noreply.github.com>
2025-08-02 22:10:26 +03:00
AwesomezPro99 705e6b3308 Add Camera Fade To Song Select 2025-08-02 22:10:26 +03:00
Abnormal 56878befef update the haxelibs.......yippee...... 2025-08-02 21:59:30 +03:00
Abnormal 44cdbb08c4 asset changes wooooooooooooooo 2025-08-02 17:18:18 +03:00
Kolo d6fe54ee79 gyafyhaswguhyshbughsd 2025-08-02 17:18:18 +03:00
Kolo 32c775ef3f tooltips....BUT FOR NOTES! 2025-08-02 17:18:18 +03:00
PurSnake 1605514424 Seriously? 2025-08-02 17:02:31 +03:00
Hyper_ 743e8b13c2 me...................................................................................... 2025-08-02 16:22:18 +03:00
Kolo 661ddb15f7 me......................................................................... 2025-08-02 07:16:05 -05:00
cyn0x8 3170346b83 Create ModStore.hx 2025-08-02 11:32:44 +03:00
anysad e6d737125e feature: are you sure? 2025-08-02 11:28:17 +03:00
AwesomezPro99 3d88fbb11f Update PreferencesMenu.hx 2025-08-02 11:10:03 +03:00
JVN-Pixels 0d6bc2bedd Fix NOR in Freeplay after spamming the letter keybinds 2025-08-02 11:07:04 +03:00
anysad da5f691865 fix: no more animation editor crash 2025-08-02 11:03:23 +03:00
Hyper_ f63cbf073a Restore a lost change from #4787 2025-08-02 10:55:58 +03:00
Kolo 30721c3a30 tfw changeDiff wasn't even being called 2025-08-02 10:49:15 +03:00
JackXson-Real 2b1f346097 Add enter/exit animation for charSelect nametag part 2 2025-08-02 10:38:32 +03:00
Mihai Alexandru 12117557c7
Merge branch 'master' into pr-5565/SrtHero278/pointer-fixes 2025-08-02 10:33:33 +03:00
Abnormal 2dcc528847 bump polymod to optimize some shiiiiiiiiiiiiiiiit 2025-08-02 02:19:14 +08:00
ExcodeFNF 5cb33e895c Freeplay CoolColors Array Removal 2025-08-02 02:01:36 +08:00
AwesomezPro99 1b91f3b57c Fixed DJ Flicker After New Rank 2025-08-02 01:28:14 +08:00
Eric e5e3270fef Update hmm.json to optimize FlxAnimate 2025-08-02 00:43:57 +08:00
EliteMasterEric e003a38cab Exclude the debug print function when we aren't in the build step 2025-08-01 18:32:37 +03:00
SrtHero278 890d1dafcb include the camera parameter in the comment 2025-08-01 19:48:39 +07:00
SrtHero278 9d2cfa9686 Fix touch pointer positioning when in PlayState 2025-08-01 19:48:39 +07:00
Karim Akra e6fd5d9b12
Make the Android back button close the game when in TitleState
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 13:59:02 +07:00
Cameron Taylor 967397311b remove tiny uncommented code, and simplify an unneeded variable initialization 2025-08-01 13:15:56 +07:00
Cameron Taylor 542f59ef72 tallyCompletion() function for cleanup + constency 2025-08-01 13:15:56 +07:00
Kade 065ee74aea
Scoreable notekinds
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 13:05:11 +07:00
Mihai Alexandru 312b5c8812
Flair adjustments to the build process
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 12:05:21 +07:00
Mihai Alexandru e9aa6872a3
Bump libs refs
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 12:03:58 +07:00
Karim Akra 4f9b63f22c
Configure the android adaptive icons through lime & moved the icons stuff to art submodule
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-08-01 01:17:29 +07:00
MAJigsaw77 962519e7f0 Fix android compile. 2025-07-28 10:41:31 +03:00
MAJigsaw77 34bae4a431 Fix compile once again. 2025-07-28 10:41:31 +03:00
Karim Akra 79478080f6 oops 2025-07-28 10:41:31 +03:00
Karim Akra 65a3ccc8fe add the same changes to the .env parser on project.hxp !! 2025-07-28 10:41:31 +03:00
Karim Akra 4ac851c387 add support for target specific environment values
and renamed `GLOBAL_ADMOB_PUBLISHER` to `MOBILE_GLOBAL_ADMOB_PUBLISHER` !!
2025-07-28 10:41:31 +03:00
MAJigsaw77 70d5730b70 Fix compile. 2025-07-27 00:56:31 -05:00
Abnormal c527fed70c conflict stuffs lol 2025-07-27 00:56:31 -05:00
TechnikTil 054a5cd00b fix fullscreen bug and show clear save data if logged out of ng 2025-07-27 00:56:31 -05:00
TechnikTil 19c5de8fe2 HOPEFULLY FIX EVERYTHING WRONG (this time it was tested between two computers) 2025-07-27 00:56:31 -05:00
TechnikTil dbc26fd621 hopefully fix everything with load from ng 2025-07-27 00:56:31 -05:00
TechnikTil eb1986b246 move clear save data to the top, add clear ng save data 2025-07-27 00:56:31 -05:00
TechnikTil d661d93184 rewrite NGSaveSlot.load to be async, dont precache assets, error handling 2025-07-27 00:56:31 -05:00
TechnikTil 4a07d0a347 make newgrounds functions in Save static and only available if newgrounds feature flag is enabled, make sure base save slot is loaded and is not empty, and recover save data in case newgrounds doesnt wanna play nice 2025-07-27 00:56:31 -05:00
TechnikTil 832f01345f Add Save Data Options, also allow user to load and save with Newgrounds Save Slots. 2025-07-27 00:56:31 -05:00
MAJigsaw77 e8d41c938c Use no-traces define instead of the flag. 2025-07-26 13:46:48 -05:00
MAJigsaw77 a94bd7f36c Fix compiling. 2025-07-26 13:43:19 -05:00
EliteMasterEric c185f10e65 Move Discord client ID to .env 2025-07-26 13:43:19 -05:00
Cameron Taylor 52f3c63071 mobile fix where the capsules don't properly shift away from the letter sorting crap 2025-07-26 12:31:38 +03:00
Cameron Taylor e71062b914 some lil variable renaming in SongMenuItem.hx 2025-07-26 12:31:38 +03:00
Cameron Taylor 3aa6a36b5e small function renaming 2025-07-26 12:31:38 +03:00
MAJigsaw77 a89fa9c121 Acually fix it (oops). 2025-07-26 11:55:36 +03:00
MAJigsaw77 cb2015f51a Fix a workflow compile error. 2025-07-26 11:55:36 +03:00
MAJigsaw77 139ce3847c Fix for env vars that contain = as one of thier characters. 2025-07-26 11:55:36 +03:00
EliteMasterEric 87b40c1203 Obsolete NewgroundsCredentials.hx for storing secret keys in favor of .env 2025-07-26 11:55:36 +03:00
Kade b9852c316b
offset menu changes
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-26 10:36:29 +03:00
Cameron Taylor 444697620c
Use round instead of floor to fix rounding errors in Preferences.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-26 10:04:00 +03:00
sector-a 6abeefb15d
Set cliprect for clear percent.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 17:43:34 +03:00
sector-a 530bd1f11d
Add onPause callback to pause substate.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 17:36:34 +03:00
sector-a 76c0dea92b
Move results and death haptics to scripts. 2025-07-25 17:23:04 +03:00
Karim Akra 2d7a2202f5
Fix song restarting bug (for good??).
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:45:55 +03:00
sector-a 1f18a3d1f4
Fix diff dots alignment.
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:37:39 +03:00
sector-a 0d57f61ffa
Scale up the bg in debug menu on widescreen
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-25 16:19:46 +03:00
MAJigsaw77 9fa70775b9 Use funkin.Assets instead of openfl.utils.Assets. 2025-07-25 16:15:51 +03:00
sector-a 463afb43c0 assets submod 2025-07-25 16:15:51 +03:00
sector-a 2833827fbf Change the way game searches for pixel icons 2025-07-25 16:15:51 +03:00
Hundrec b4e52df156 3 2025-07-22 07:56:14 +08:00
Hundrec cf70bf2c6c Friday Night Funkin' if it was good 2025-07-22 07:56:14 +08:00
Hyper_ fb6d1b36d3 lasercar................................................................................................................................................................................................. 2025-07-22 07:43:15 +08:00
MoonDroid 0c0c63bc03 fix: Move hasInitialized to onPurchasesUpdate instead. 2025-07-21 19:08:14 -04:00
Hyper_ 01620fda9b The most deranged line loss of all time 2025-07-22 06:41:46 +08:00
cherry 3bcd6813c1 Clear key from correct map 2025-07-22 06:12:56 +08:00
sector-a d44966efd2 Prevent AA calculations if AA_STAGES are 0 in DropShadow shaders 2025-07-21 18:02:18 -04:00
sector-a 79c3e2de11
assets ref
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-22 04:50:15 +07:00
Karim Akra 8372d47d11 Fixed the menu item getting disabled if you hit back during the transition 2025-07-22 05:21:40 +08:00
MoonDroid d89ebdf58f Attempt to fix the soft lock issue for Main Menu. 2025-07-22 05:21:40 +08:00
kade-github 1e8c472084 holy shit 2025-07-21 23:16:43 +03:00
kade-github 17cef6f897 fix for winblows 2025-07-21 23:16:43 +03:00
kade-github 2cc43ee1f6 text fix for my mobile fellas 2025-07-21 23:16:43 +03:00
Eric 2277acccfa Update hmm.json 2025-07-22 04:00:29 +08:00
Hundrec ed86b326ab i forgot my milkshake 2025-07-18 09:03:05 -05:00
Hundrec 596c5813d7 Someone get me a typewriter 2025-07-18 16:09:16 +08:00
Hundrec ae68925911 They say you can never have enough Changelog 2025-07-18 16:09:16 +08:00
Hundrec d7c3799562 Even more Changelog entries 2025-07-18 16:09:16 +08:00
Hundrec 47ab14a855 More Changelog adjustments 2025-07-18 16:09:16 +08:00
Hundrec 940e165612 Another change 2025-07-18 16:09:16 +08:00
Hundrec 5181023887 How can I play this? There's no ' 2025-07-18 16:09:16 +08:00
Hundrec 32e774b005 Additional entries for 0.7.2 2025-07-18 16:09:16 +08:00
Hundrec c353cc54a1 god effing damnit 2025-07-18 15:45:53 +08:00
Abnormal 48d0798e5f fix bf perfect gold results anim 2025-07-18 14:03:31 +08:00
EliteMasterEric 0463b4e26b Fix a bug where flames would show during the new rank animation 2025-07-18 12:24:30 +08:00
MAJigsaw77 0c1842038f Update hmm.json 2025-07-18 04:49:03 +07:00
Karim Akra aa0b8cbbbe Fixed the main menu options not working on Desktop 2025-07-17 17:19:17 -04:00
EliteMasterEric 52cd4f6c36 one-line bug fix for freeplay flame positions :O 2025-07-18 05:09:17 +08:00
EliteMasterEric 6be7e89222 OK I tested it like 15 times in a row so if the bug still exists I'm going to blow a gasket 2025-07-17 14:50:28 -04:00
EliteMasterEric abea46939f Fix a softlock when tapping multiple buttons on the main menu at the same time 2025-07-17 14:50:28 -04:00
EliteMasterEric 3a5f1e14cf This made the flag always false? I blame the mobile people for this 2025-07-17 14:50:28 -04:00
Karim Akra 849e413bb7 update assets 2025-07-18 02:47:05 +08:00
Mihai Alexandru b4a7bd7462
Fix compile pref. (#1439) 2025-07-17 21:32:10 +03:00
MoonDroid beb64528fb Properly manage swipe threshold on states. 2025-07-18 02:08:46 +08:00
luckydog7 eac940bccb temp credits font fix 2025-07-17 10:55:15 -07:00
MoonDroid aa1c71cafd Properly get the store's IAP in main menu 2025-07-17 10:54:02 -07:00
EliteMasterEric f4bedc359a Update Polymod version 2025-07-18 01:47:30 +08:00
Karim Akra 01428dd5cf
Fixed a tiny issue that caused cutscenes to softlock (#1432) 2025-07-17 12:51:06 +03:00
MoonDroid c6e19c8512
Merge pull request #1423 from FunkinCrew/feature/haptics-intensity-pref 2025-07-17 04:11:16 +07:00
MoonDroid e30a4ebb7b Merge branch 'master' into feature/haptics-intensity-pref 2025-07-17 04:08:51 +07:00
Cameron Taylor 949f409cff a few little FreeplayScore tidying perhaps 2025-07-17 04:28:52 +08:00
Cameron Taylor 4c5aa9743e a few little FreeplayState tidying perhaps 2025-07-17 04:28:52 +08:00
Cameron Taylor 3fa2b3574b potential fix for FUNK-2563 (incorrectly rounds to negative integer limit?) 2025-07-17 04:28:52 +08:00
TechnikTil 1e41ac3052 make currentCharacterId the actual current character ID. also get the style from the style id instead of the character 2025-07-16 23:26:22 +03:00
MoonDroid 936812ae1e assets submod 2025-07-17 03:05:16 +07:00
MoonDroid ad3bf2d2d2 Update haptic values to compensate for default 1 multiplier 2025-07-17 03:04:54 +07:00
kade-github 1b1c2a124b STOP MAKING IT PRIVATE!!! 2025-07-17 03:58:03 +08:00
kade-github 2aff2fa201 downscroll... 2025-07-17 03:58:03 +08:00
kade-github 7ec602f6ec forgot dis 2025-07-17 03:58:03 +08:00
kade-github 4fbeffb57c extra sync logic fix 2025-07-17 03:58:03 +08:00
kade-github f029a27a3f external devices and what not 2025-07-17 03:58:03 +08:00
sector-a 8a99fa4184
Add toggling the old icon by touching the player icon
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-17 02:22:17 +07:00
MAJigsaw77 f21b015292 Update hmm.json 2025-07-17 03:14:09 +08:00
Karim Akra bc8e35409b update assets submod to fix the stage vanishing when getting hit by can in practice mode 2025-07-17 03:01:25 +08:00
Karim Akra 006f1dce0a Fixed the crash in 2hot and blazin 2025-07-17 03:01:25 +08:00
Karim Akra 78186188d7 Revert "openalsoft audio fix"
This reverts commit 4029e92181.
2025-07-17 02:51:44 +08:00
Karim Akra 762486639e Revert "run da formatter"
This reverts commit b5bb9721da.
2025-07-17 02:51:44 +08:00
Abnormal b5bb9721da run da formatter 2025-07-16 10:29:48 -07:00
cyn0x8 4029e92181 openalsoft audio fix
Co-authored-by: Smokey <78874128+Smokey555@users.noreply.github.com>
Co-authored-by: Cobalt Bar <79053181+CobaltBar@users.noreply.github.com>
2025-07-16 10:29:48 -07:00
sector-a 9c7f87c225 Disable the nametag mosaic sequence on menu startup 2025-07-16 23:33:51 +08:00
sector-a 43420092f3 Change minimal intensity multiplier to 0.1 2025-07-16 17:34:41 +03:00
sector-a d8cd580535 Make haptics intensity on ios and android the same 2025-07-16 16:51:02 +03:00
sector-a 13c08b285d Add haptics intensity preference 2025-07-16 16:51:02 +03:00
Abnormal 6238b72d8c bump polymod to fix a pico mix crash 2025-07-16 21:26:49 +08:00
Eric bf92bf3f60 Update hmm.json 2025-07-15 18:21:25 -07:00
Cameron Taylor 6467cd75a8
IAP compiler conditional fix (#1416) 2025-07-16 01:39:12 +03:00
Karim Akra 32dc25bbf6 Fix the credits menu on iOS 2025-07-15 18:14:47 -04:00
Karim Akra 11cb409bd2 Fixed the crash in game over 2025-07-16 00:41:43 +03:00
Mihai Alexandru f245365ed3
Merge pull request #1413 from FunkinCrew/mob-320/controls-menu-back-button
[MOB-320] Add back button to controls menu.
2025-07-16 00:22:32 +03:00
Karim Akra e0d0230b88
Dont show the toast if the theres no debug message (#1405) 2025-07-16 00:17:22 +03:00
Cameron Taylor f8634e2b81 tidy: small preloader code removing 2025-07-16 00:54:35 +07:00
Cameron Taylor 4f68f63e2d preloader lookin alright on iOS now 2025-07-16 00:54:35 +07:00
Cameron Taylor e9e0567f8b preloader placement wips
more preloader placeholder wips
2025-07-16 00:54:35 +07:00
Cameron Taylor 8db768fd2a tidy(preloader): some variable renaming 2025-07-16 00:54:35 +07:00
Cameron Taylor cf814ee4e2 tidy(preloader): stop the preloader from spamming traces after completing 2025-07-16 00:54:35 +07:00
Mihai Alexandru 43b7be4e71
Merge branch 'master' into bugfix/android-toast-iap 2025-07-15 20:50:35 +03:00
MoonDroid 7d555b4155 Update credits 2025-07-15 20:47:11 +03:00
MAJigsaw77 88ad99c3ef Merge branch 'master' into bugfix/android-toast-iap 2025-07-15 20:33:44 +03:00
MAJigsaw77 d92b7ff3f5 Merge branch 'master' into bugfix/android-toast-iap 2025-07-15 20:33:19 +03:00
MoonDroid 66c6a78319 Properly set hasInitilaized on android 2025-07-16 00:32:52 +07:00
MoonDroid e6a2a09801 Make the IAP product value actually saved into the game save file. 2025-07-16 00:32:52 +07:00
MAJigsaw77 8944e07fe1 Use a separated case here. 2025-07-16 00:32:52 +07:00
MAJigsaw77 188260ea81 Correctly handle iap callbacks when purchasing. 2025-07-16 00:32:52 +07:00
Hundrec 22c6ce42ba Blazin' fix changelog entry 2025-07-16 00:53:17 +08:00
EliteMasterEric d8445fe54a Update assets submodule 2025-07-16 00:53:17 +08:00
Abnormal c3592ee6f5 bump versionnn to 0.7.2 FUUUUUCKKK 2025-07-15 19:47:10 +08:00
MAJigsaw77 e402328969 Merge branch 'master' into bugfix/android-toast-iap 2025-07-15 12:46:04 +03:00
Abnormal 150a1d5b0a erm......lol? 2025-07-15 17:42:06 +08:00
MAJigsaw77 d468477663 Dont show the toast if the theres no debug message 2025-07-15 12:27:20 +03:00
Abnormal ecaf51ef41 add 2 missing entires 2025-07-15 17:12:17 +08:00
Abnormal 05627a50d5 0.7.2 changeloggyyyyyyyy 2025-07-15 17:12:17 +08:00
kade-github efe333da92 fix jump note GOD DAM NIT 2025-07-15 15:11:13 +08:00
kade-github e946b54249 sync fixies... can't hurt 2025-07-15 15:11:13 +08:00
Abnormal 1d4a94041b enable traces only on debuggggg 2025-07-15 00:01:14 -07:00
Abnormal 11da19ce1e zack got pissed off about this in vc so im making a pr for this 2025-07-15 00:01:14 -07:00
Cameron Taylor 126ed3a67a use unicode in the iOS app title to force spacing 2025-07-15 14:54:35 +08:00
Hundrec 468197e74e 0.7.1 Changelog 2025-07-14 23:52:10 -07:00
Cameron Taylor 7f17ad8bb8
Merge pull request #1400 from FunkinCrew/jni-conditionals
quick android conditionals
2025-07-14 15:34:17 -04:00
Hundrec e9ef340c63 missed one 2025-07-14 13:49:24 -05:00
Cameron Taylor 61bda6c2c2
Merge pull request #1394 from FunkinCrew/freeplay-sound-fix
Freeplay sound fix and other little freeplay cleanups and tidyings
2025-07-14 14:48:28 -04:00
Cameron Taylor 07f649ca37 LetterSort was causing that freeplay sound bug 2025-07-14 14:47:24 -04:00
Cameron Taylor 11ecd07606 various tiny lil tidyings in FreeplayState 2025-07-14 14:47:24 -04:00
Cameron Taylor 822c5ba405 use controls.active instead of busy for FreeplayState 2025-07-14 14:47:24 -04:00
Cameron Taylor d61f89b0e4 make quick and easy little currentCapsule getter 2025-07-14 14:47:24 -04:00
Cameron Taylor 9dfae07225 capsule song text no longer exposed 2025-07-14 14:47:24 -04:00
Cameron Taylor 01fad012f2 quick android conditionals 2025-07-14 14:45:06 -04:00
Abnormal 9843f9549c final changelog for 0.7.0 2025-07-15 02:44:46 +08:00
Cameron Taylor 044106e8a9 WaveformDataParser memory optimize + speed optimize perhaps + refactor mini 2025-07-14 10:38:27 -07:00
Cameron Taylor d338be9270 removed some unused code in WaveformDataParser.hx 2025-07-14 10:38:27 -07:00
Cameron Taylor e4d3e18e4f charteditor: player and opponent toolboxes are disabled, so we don't want to run their handler code (since it initalizes them, which takes about 0.5s extra to load!) 2025-07-14 10:38:27 -07:00
Abnormal dd104365e7 bump flixel AGAIN 2025-07-14 08:54:56 +08:00
Abnormal b0581f728a bump flixel 2025-07-13 16:06:31 +08:00
MAJigsaw77 5e50432b30 Add Intent.FLAG_GRANT_WRITE_URI_PERMISSION. 2025-07-13 08:49:32 +03:00
MAJigsaw77 314d8af9c8 Some adjustments 2025-07-13 08:49:32 +03:00
MAJigsaw77 f91261f748 Small adjustment to ReloadAssetsDebugPlugin. 2025-07-13 08:49:32 +03:00
Karim Akra 0567849665 Added a button in options menu to open the data folder
The game also reloads mods after closing the folder!!

Co-Authored-By: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-07-13 08:49:32 +03:00
MAJigsaw77 a701e6a4a9 Some fixes. 2025-07-13 08:49:32 +03:00
MAJigsaw77 abfc4ca79c Fix formatting and properly delete folders recursevely. 2025-07-13 08:49:32 +03:00
Karim Akra 797a8bfcba fix the docy provider 2025-07-13 08:49:32 +03:00
MAJigsaw77 d70838cca9 Bruh what 2025-07-13 08:49:32 +03:00
MAJigsaw77 0d845154ef Add @:unreflective here. 2025-07-13 08:49:32 +03:00
MAJigsaw77 9e04db2c5c Adjustments 2025-07-13 08:49:32 +03:00
luckydog7 c0d3b9daa2 isChildDocument implementation 2025-07-13 08:49:32 +03:00
luckydog7 0f336ae0e6 Add provider 2025-07-13 08:49:32 +03:00
kade-github 8c8eedf17a sector!!!! 2025-07-12 19:05:04 +08:00
EliteMasterEric 793b533b88 Fix being able to modify final constants 2025-07-12 18:39:26 +08:00
EliteMasterEric 852a74c33d Bump Polymod version 2025-07-12 18:39:26 +08:00
EliteMasterEric bfdafd7f37 You can now access abstracts properly! 2025-07-12 18:39:26 +08:00
EliteMasterEric 37d0d1b14e Latest experimental Polymod 2025-07-12 18:39:26 +08:00
EliteMasterEric 2649e247fa Update Polymod and HScript to include the latest fixes. 2025-07-12 18:39:26 +08:00
EliteMasterEric fafe157a70 Update the variation list when switching difficulties forces a song switch. 2025-07-12 16:51:08 +08:00
kade-github 39a4292dc5 fix jump note 2025-07-12 16:48:48 +08:00
EliteMasterEric aad0a0afb6 Fix a crash related to pausing stage sounds on HTML5 2025-07-11 17:22:52 -05:00
Karim Akra f8516cfb4d Fix sustain trail notes being flipped on upscroll in keyboards on mobile 2025-07-09 13:36:43 -07:00
Hundrec 3987445bd6 Bump resync threshold to 40 again... 2025-07-09 19:14:49 +08:00
Abnormal eea829ca7d
[MOBILE] Freeplay swiping fixes (#1386)
* I Have No Idea What Zack Fixed Here Please Help Me

* I Have No Idea What Zack Fixed Here Please Help Me

* fix: Slight scroll velocity issue with diff swipes

---------

Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-09 11:11:57 +00:00
Abnormal d98628ca0f fix: Fix a bug preventing FNF Legacy files from being imported on macOS 2025-07-09 05:27:24 -05:00
kade-github a6b3eb0b81 right lined 2025-07-09 05:20:34 -05:00
Abnormal 49e64a517e fix animation indices for darnell and spooky kids 2025-07-09 04:56:48 -05:00
Abnormal ef9fd48ab2 update submod 2025-07-09 17:54:55 +08:00
fabs efdc869206 fix dot position on mobile 2025-07-09 01:19:15 -05:00
fabs 077e0c920f assets submod 2025-07-09 01:19:15 -05:00
fabs bb714f210b implement dots into freeplay 2025-07-09 01:19:15 -05:00
fabs f0a112f185 difficulty dot code 2025-07-09 01:19:15 -05:00
EliteMasterEric 1025fed57f Use cyn0x8's Sequence class to fix the nametags. 2025-07-09 01:02:55 -05:00
cyn0x8 9e182f70d2 timer sequence 2025-07-09 01:02:55 -05:00
Abnormal 87fea7674b fuck it remove this as well 2025-07-09 00:02:53 -04:00
Abnormal e309bac626 fix compiling error 2025-07-09 00:02:53 -04:00
luckydog7 8c6324641e fixed bug when notes are offset when touching in keyboard mode 2025-07-09 03:11:13 +07:00
Karim Akra 6b7b5d0bf7 fixed controls few menus with keyboard 2025-07-09 03:11:13 +07:00
Karim Akra a74dcbc6f9 Fix keyboard & gamepad support on menus and playstate 2025-07-09 03:11:13 +07:00
Abnormal d6d7a0886f remove a useless boolean from freeplay 2025-07-08 18:46:30 +08:00
Kolo 7e76cf6634 maz................................................................. 2025-07-07 18:27:40 -07:00
Lasercar 48013168ef Open hold note context menu if note is hold note 2025-07-07 18:27:14 -07:00
MoonDroid 1201a781c9
assets submod (#1375) 2025-07-08 00:56:03 +03:00
Karim Akra 9ad5126806 Set the gradle project directory to bin-bundle on bundle builds (& bump lime for the changes) 2025-07-08 03:52:10 +07:00
Karim Akra c2755a745c de-bump FlxAnimate 2025-07-08 04:29:14 +08:00
Abnormal a73b879fee add new desktop icons 2025-07-08 03:19:04 +08:00
VioletSnowLeopard e7c4b1ba38 start gameover retry music after stopping death quotes 2025-07-07 11:16:09 -04:00
Lasercar 62d24fcf4c Selection context menu fix
Can someone please tell me why there's a button to select everything in the selection context menu????
2025-07-07 11:04:11 -04:00
Abnormal 3b897417fb small scripted class additions...... 2025-07-07 10:47:09 -04:00
Kolo 7bb2336972 spare some script class pie for sparrow dawg 2025-07-07 10:47:09 -04:00
Abnormal f13eb5be53 multiple week 3 fixes
Co-authored-by: ShadzXD <136199318+ShadzXD@users.noreply.github.com>
2025-07-07 22:35:34 +08:00
Lasercar 7aa77a11cf Sort the default difficulties 2025-07-07 10:35:26 -04:00
Keoiki f54e140b65 Load FreeplayStyles on asset reload. 2025-07-07 07:16:28 -05:00
Kolo 0ea42e18e9 cancel tweens of txtCopyNotif 2025-07-07 04:07:05 -05:00
Abnormal a8a99c327d Restore "Fix several Polymod-related bugs" 2025-07-07 12:29:37 +08:00
Abnormal e2722434e0
fix: Fix playback rate being busted on mobile
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-06 15:56:03 +07:00
Mihai Alexandru a08ada7e69
Show toast on Android IAP purchase update.
Co-authored-by: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-07-06 15:47:16 +07:00
Cameron Taylor 21e5501835 difficulty touch controls implementation 2025-07-06 15:23:18 +07:00
Cameron Taylor 125aa0a438 some cute guard clauses 2025-07-06 15:23:18 +07:00
Cameron Taylor 6591fd8f2a remove some unused/redundant variables 2025-07-06 15:23:18 +07:00
Cameron Taylor b205a0b931 top left freeplay text grab stuff take it out 2025-07-06 15:23:18 +07:00
Cameron Taylor 7a6326b178 freeplay backingCard proper null safety 2025-07-06 15:23:18 +07:00
Cameron Taylor df1dbeaef0 tidy: removed unused import in Freeplay 2025-07-06 15:23:18 +07:00
Cameron Taylor 91a16f6dc3 put DifficultySprite into it's own class lil cleanup in progres 2025-07-06 15:23:18 +07:00
Cameron Taylor acd10ffbe5 some lil null safety fix for SwipeUtil 2025-07-06 15:23:18 +07:00
sector-a 86241d53da Add adaptive icon
Co-Authored-By: Karim Akra <144803230+KarimAkra@users.noreply.github.com>
2025-07-05 21:30:25 +03:00
Mihai Alexandru 99769cb50b
Merge pull request #1360 from FunkinCrew/feature/num-pref-dragging
Add dragging for the NumberPreferenceItem
2025-07-05 21:21:35 +03:00
MAJigsaw77 9036f94970 Remove traces from NumberPreferenceItem. 2025-07-05 21:18:04 +03:00
sector-a f00f631db8
Merge branch 'master' into feature/num-pref-dragging 2025-07-05 18:42:15 +03:00
sector-a d0b64fe4da Add dragging for the NumberPreferenceItem 2025-07-05 18:35:23 +03:00
kade-github f378c0adb6 comments and qol stuff 2025-07-04 18:53:58 -07:00
Hundrec ae6562f42b
change resync threshold back to 30 2025-07-04 03:39:38 +07:00
kade-github 313cf4b253 new music 2025-07-02 17:40:16 -05:00
Hundrec dbd52a5bf1 Nudge notification box away from playbar
Thanks Kolo and Lasercar!

Co-Authored-By: Kolo <67389779+koloindacrib@users.noreply.github.com>
Co-Authored-By: Lasercar <64717068+lasercar@users.noreply.github.com>
2025-07-02 14:33:10 -05:00
Mihai Alexandru 810162de27
mobile: update extension-iapcore to 1.0..3. (#1346) 2025-07-03 00:24:22 +07:00
Abnormal 711656bcf4 run haxe formatter on project.hxp and assets 2025-07-01 17:29:02 +08:00
Abnormal 95262b316a bring them back but for mobile 2025-07-01 14:11:39 +08:00
Abnormal 82bbb9d30d use delta time for the conductor update 2025-07-01 14:11:39 +08:00
Hundrec b06a28e79c Changelog's back! 2025-06-30 12:17:27 -05:00
kade-github 811cc4b4b0 hacky fix to get the game out 2025-06-30 19:08:38 +08:00
kade-github 00a4f47e42 no offsets in the charting state 2025-06-30 18:37:00 +08:00
Abnormal d703609a0a remove conductor arguments from update() 2025-06-30 14:49:01 +08:00
kade-github 2c035d77cc the newline fix of the century 2025-06-30 00:00:02 -05:00
T5mpler 96d1324af1 Fix a bug where holding down a note after dropping a previous one would sometimes not make its cover show. 2025-06-29 22:30:29 -05:00
Abnormal 543d6454f6 fix: Fix a hang when playtesting Week 6 songs in Story Mode 2025-06-29 17:38:10 -05:00
kade-github c414de48f2 non-negative offsets 2025-06-29 17:34:23 +08:00
kade-github 70fbd200bd video offsets 2025-06-29 10:04:25 +03:00
Kade ec10f273b6
Merge pull request #1298 from FunkinCrew/kade-github/new-offsets 2025-06-28 22:44:27 -07:00
MAJigsaw77 2f223f84f5 Add FEATURE_DEBUG_MENU and FEATURE_ANIMATION_EDITOR defines. 2025-06-29 07:45:07 +03:00
Abnormal 32f32ba0bd blacklist FlxSave 2025-06-28 20:52:41 -05:00
EliteMasterEric 25bf04d581 Implement a stub Discord API for builds where the client is disabled. 2025-06-28 19:23:34 -05:00
EliteMasterEric f036593037 Fix error messages from the game trying to pre-cache the note style 2025-06-28 19:23:34 -05:00
kade-github 9ec7a5068a
change RESYNC_THRESHOLD to 70 2025-06-28 16:17:56 -07:00
kade-github 55e1967423
Merge branch 'master' into kade-github/new-offsets 2025-06-28 13:55:32 -07:00
kade-github d3207de231
fixes 2025-06-28 13:47:28 -07:00
kade-github afc08e285c
Bug Fixes for Offsets 2025-06-28 13:47:28 -07:00
kade-github 28fc5109d4
Offset menu Final maybe 2025-06-28 13:47:27 -07:00
kade-github 2b5ba8dfa9
Offsets menu wip 2025-06-28 13:47:27 -07:00
kade-github 0ef1df33c9
calculate note y is in GRhythmUtil now 2025-06-28 13:47:07 -07:00
kade-github b3aa6a0b8d
Hit Window process in it's own file 2025-06-28 13:47:07 -07:00
Mihai Alexandru 126da44a95
Merge pull request #1310 from FunkinCrew/resync-vocals-song-start
Resync vocals on song start
2025-06-28 14:39:12 +03:00
Mihai Alexandru f6d9acb63a
Merge branch 'master' into resync-vocals-song-start 2025-06-28 14:32:01 +03:00
Mihai Alexandru f78431da3c
Merge pull request #1261 from FunkinCrew/pr-2655/lemz1/recycle-credits-lines
[PUBLIC PR] Recycle Credits Lines
2025-06-28 14:29:34 +03:00
Mihai Alexandru 21bbef5542
Merge branch 'master' into pr-2655/lemz1/recycle-credits-lines 2025-06-28 14:18:23 +03:00
Abnormal 46c40f67cc the lime bump of the century 2025-06-28 18:59:38 +08:00
Mihai Alexandru cdfce1af12
Merge pull request #1326 from FunkinCrew/touch-controls-define-gets-some-actual-use
Allow `TouchUtil` functions to be used on desktop
2025-06-28 13:51:45 +03:00
Mihai Alexandru 8aff75b308
Merge branch 'master' into touch-controls-define-gets-some-actual-use 2025-06-28 13:43:28 +03:00
Abnormal 58f101bf01 chore: Run Haxe Formatter on the source code 2025-06-28 18:41:49 +08:00
Hundrec c49666c4b4
Fix remaining smoothLerp deprecations 2025-06-28 13:18:24 +03:00
Abnormal 73ec37a473
Move resync threshold to a constant variable 2025-06-28 10:50:59 +03:00
MAJigsaw77 adf2b49a72 update haxeui-flixel. 2025-06-28 02:32:59 -05:00
MAJigsaw77 a11bde6f76 update haxeui-core and remove flixel-text-input. 2025-06-28 02:32:59 -05:00
Hundrec 8b6b91cc23 Fix build errors for MathUtil 2025-06-28 01:11:18 -05:00
cyn0x8 94eae116c7 MathUtil additions + lerp fix 2025-06-28 01:11:18 -05:00
MoonDroid faadf406c3
Merge pull request #1321 from FunkinCrew/moon/hacky-gc-calls 2025-06-28 12:09:11 +07:00
Abnormal d4c7339373 allow TouchUtil functions to be used outside of FEATURE_TOUCH_CONTROLS 2025-06-27 22:46:00 -05:00
Hundrec 55d34c3c9d Disable keys before Senpai dialogue 2025-06-27 20:06:16 -05:00
Abnormal 7ed374f1e5 hundrec's suggestion 2025-06-28 08:54:37 +08:00
Abnormal 4e87c7d40c added a bunch of new changelog entries 2025-06-28 08:54:37 +08:00
Mihai Alexandru 377697a358
Limit gyro panning 2025-06-28 01:23:32 +07:00
MAJigsaw77 32701d9ab0 fix a tiny mistake 2025-06-27 03:59:02 -04:00
MoonDroid c897d89b35 fix: Properly check if touch overlaps difficulty to prevent double-swiping 2025-06-27 03:59:02 -04:00
MoonDroid 1f65a9c5a1 Update lime ref 2025-06-27 03:59:02 -04:00
MoonDroid d061ba4e43 Update grig.audio ref 2025-06-27 03:59:02 -04:00
MoonDroid d4d52a1394 Exclude titleEnter sprite from compression 2025-06-27 03:59:02 -04:00
MoonDroid cedf17fb99 fix: Fix temporary softlocking in main-menu 2025-06-27 03:59:02 -04:00
MoonDroid 97620e6038 chore: Reduce margin of error of desyncs to 30 2025-06-27 03:59:02 -04:00
MoonDroid 1d3b5eb246 Attempt to fix callback mishap for IAP
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-06-27 03:59:02 -04:00
Abnormal 40c292127d add mobile platforms to platformutil 2025-06-27 01:33:58 -04:00
Hundrec 79cc20ffe8 fix car reset positions + remove redundant resets 2025-06-26 23:41:02 -05:00
Abnormal 4eb3c764ab is that... *gulps* a submod update (lasercar charting field fix) 2025-06-26 22:39:26 -05:00
Hundrec e2efd2bc81 adjust song metadata trace 2025-06-26 22:39:26 -05:00
Lasercar 894d8cb463 Fix chart(er)
The charter is literally never ever set in the new or clone function of the songMetadata. HOW????
2025-06-26 22:39:26 -05:00
Abnormal 3fd80504e3 fix the most annoying chart editor bug ever 2025-06-27 10:17:48 +08:00
MoonDroid 42ec7f7796 Call GC only for IPhones above 12 2025-06-27 07:31:32 +07:00
MoonDroid bc4c944d4d Call GC after results if there is no stickers. 2025-06-27 07:28:53 +07:00
MoonDroid 715d2ba65f feat: Add DeviceUtil class 2025-06-27 06:44:35 +07:00
MoonDroid 067b56c5fa
Merge pull request #1320 from FunkinCrew/patch/default-astc-value 2025-06-27 05:43:58 +07:00
Karim Akra d73eb4e392
minor spelling mistake (Thanks Abnormal)
Co-authored-by: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2025-06-27 01:11:49 +03:00
Karim Akra 5a19397481 Add a default value for FEATURE_COMPRESSED_TEXTURES on project.hxp 2025-06-27 00:54:03 +03:00
VioletSnowLeopard eb80a52841 fix null safety for CompiledClassList.get
Co-Authored-By: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
2025-06-26 16:48:31 +08:00
VioletSnowLeopard 57d0871b5c null safe registries in funkin.data 2025-06-26 16:48:31 +08:00
Hundrec 066ed53a6d minor spelling mistake 2025-06-26 16:42:45 +08:00
Abnormal 6f35209d63 add hundrec's changelog revisions
Co-authored-by: Hundrec <hundrecard@gmail.com>
2025-06-26 16:42:45 +08:00
MAJigsaw77 5be5abf4c9 chore: fix multiple warnings. 2025-06-26 04:00:57 -04:00
EliteMasterEric ab89cd33f9 What a stupid change, what kind of dumbass made this? 2025-06-26 02:48:46 -05:00
Abnormal 7febe5b5ad update submod for optimized shit 2025-06-26 02:10:47 -04:00
Abnormal 4cc922c373 add the long awaited tap to enter for mobile.... 2025-06-26 02:10:47 -04:00
Abnormal 4557a681d1 This desync is Pissing me off... I'm the original Starwalker 2025-06-26 00:17:19 -05:00
EliteMasterEric 2e99737485 Update hmm.json 2025-06-26 12:21:25 +08:00
Cameron Taylor 7db71574d1 TracyProfiler.hx more frame mark functions 2025-06-26 12:21:25 +08:00
Hundrec b1376f7401 Hundrec's second batch of charting fixes 2025-06-26 12:14:38 +08:00
Hyper_ 06a440f21c fix: (and refactor) Fix some issues with chart editor sustain trails
Fixes the sustain height not being updated when undoing/redoing length commands
Fixes hanging duplicate sustain trail when dragging the notes
Refactored the displayed hold note sprite kill checks and removed an unnecessary check
2025-06-25 23:21:02 -04:00
Lasercar 6dcec592f4 mute/ zero volume disables visualiser 2025-06-26 11:00:05 +08:00
Hundrec a0d3f8ec55 default gamepad freeplay jump binds
Co-Authored-By: MrMadera <90923803+mrmadera@users.noreply.github.com>
2025-06-25 21:17:11 -05:00
EliteMasterEric 9f9af722ca Fix a breaking build error on HTML5 2025-06-25 21:05:57 -05:00
Karim Akra 3962989f83
Merge pull request #1306 from FunkinCrew/null-safety/fix-touch-hitboxes
Fix wonky main menu hitboxes thanks to recent null-safety changes
2025-06-26 01:29:34 +03:00
Karim Akra b3d1adbd7f make menuItems nullable and initialize it inside of create() 2025-06-26 01:14:10 +03:00
MoonDroid cf0da45dd8 fix: Call camera reset BEFORE menuItems to prevent wonky touch hitboxes
sigh!!
2025-06-26 04:56:15 +07:00
MoonDroid 68695329cf Fix compile errors related to null-safety 2025-06-25 14:32:59 -05:00
lemz 1b68c3a8d6 squashed commits 2025-06-25 13:45:43 -05:00
EliteMasterEric 647ce880e1 Add a bunch more classes to null safety. 2025-06-25 13:42:24 -05:00
EliteMasterEric e9915e52fa Fix compile issues. 2025-06-25 09:07:48 -04:00
Hyper_ 18fe868233 chore: Add null-safety for some classes in funkin.ui 2025-06-25 09:07:48 -04:00
EliteMasterEric 0869362fa1 Fix a compilation issue. 2025-06-25 08:36:19 -04:00
Lasercar 87a09cae21 Null safe some graphics classes 2025-06-25 08:36:19 -04:00
Abnormal 4766a92946 Run Haxe Formatter on every script within preload/scripts 2025-06-25 18:34:24 +08:00
MoonDroid 74b30c0be4 feat: Properly call pause() on tabbing out, including for conversations and cutscenes 2025-06-24 18:44:27 -04:00
MoonDroid d0ff60ad0a feat: Make cutscene/conversation pauses call the pause function 2025-06-24 18:44:27 -04:00
MoonDroid 1dd6fb8dd4 chore: Use Preferences.autoPause instead of FlxG.autoPause 2025-06-24 18:44:27 -04:00
MoonDroid 2042f3db8a refactor: Rewrite how pause() works in PlayState and adding different modes 2025-06-24 18:44:27 -04:00
MoonDroid b67cbc132d assets submod 2025-06-24 18:44:27 -04:00
Abnormal 720d279f89 okay well that didn't work 2025-06-24 17:39:38 -04:00
Abnormal 97754e5ed3 wonder if this fixes it 2025-06-24 17:39:38 -04:00
Abnormal e2e8c383cd hundrec's req changes
Co-authored-by: Kolo <67389779+KoloInDaCrib@users.noreply.github.com>
2025-06-24 17:39:38 -04:00
Kolo 19d1a8c593 remove the greed from weekend 1's title 2025-06-24 17:39:38 -04:00
Abnormal 8dd007a7c2 the evil is defeated 2025-06-24 17:17:31 -04:00
Abnormal 3747b94246 fix: Check if TERM starts with xterm instead of directly checking 2025-06-24 17:17:31 -04:00
VioletSnowLeopard 7cc9464573 refresh song list when changing difficulties 2025-06-24 16:35:12 -04:00
Abnormal 7b9bce3b4e fix: Fix pixel strumline being weird as shit on downscroll 2025-06-25 03:56:22 +08:00
Hundrec 91550181f5 Remove misses from Gold (Perfect) debug 2025-06-24 14:27:00 -05:00
Abnormal c5308ccbb9 feat: add perfect (gold) to results debug 2025-06-24 14:27:00 -05:00
anysad dcac362003 bye combomilestone comments 2025-06-23 23:31:06 -05:00
Abnormal ae51c2ea5a update submod 2025-06-23 21:40:19 -05:00
Hyper_ 905181c9af Add labels for current beat and step in ChartEditorState (replaces previous display) 2025-06-23 21:40:19 -05:00
Hyper_ 11d9998e5c Fix Debug Results not showing proper rank 2025-06-23 21:25:40 -05:00
Hyper_ 37dc66bc18 i hate these yanderedev ass if-elses but I just wanna fix this bug 2025-06-23 19:26:52 -04:00
MoonDroid 74627795d2 Fix compile-time error for desktop builds 2025-06-23 17:06:48 -05:00
EliteMasterEric 903ca851bc Disable CI builds on Android for now. 2025-06-23 16:35:34 -05:00
sector-a 24c469dc31
Merge pull request #1287 from FunkinCrew/feature/increase-diff-hitbox
Hitbox changes for Freeplay's difficulty sprite
2025-06-24 00:28:18 +03:00
cyn0x8 eb6becc03f scriptable class changes 2025-06-23 17:24:36 -04:00
Abnormal fbd80ea41f kolo........................................................................................................................................
Co-authored-by: Kolo <67389779+KoloInDaCrib@users.noreply.github.com>
2025-06-23 17:13:07 -04:00
Kolo ccd0148e9b easy pico shall not be easy default....... 2025-06-23 17:13:07 -04:00
MoonDroid 3a7379e851 fix: Decrease boundaries for diff swipes and add a swipe check. 2025-06-24 03:58:34 +07:00
MoonDroid a7055efb27 fix: Prevent wacky multi-swipes on difficulty sprite 2025-06-24 03:57:46 +07:00
MoonDroid 98cd45453b fix: Increase hitbox vertically for difficulty sprite 2025-06-24 03:56:59 +07:00
Hyper_ c13167ece8 chore: Add null-safety for Leaderboards and Medals 2025-06-23 16:37:17 -04:00
VioletSnowLeopard 7d9a9f452d null safety for legacy importer 2025-06-23 16:34:17 -04:00
Abnormal c30b519bc4 chore: Add null safety for most of the classes in funkin.audio.* 2025-06-23 16:20:40 -04:00
Lasercar 9b06bd6b11 NuN safety 2025-06-23 16:05:43 -04:00
Lasercar f3db69cca8 Null safety
For real this time!
2025-06-23 15:45:27 -04:00
Lasercar 9174b83c93 Text Null Safety 2025-06-23 15:20:06 -04:00
anysad 74a8b8862e goodbye nulls! 2025-06-23 15:07:03 -04:00
Hyper_ 88ed66affa chore: Add null safety to various utility and plugin classes
And add a bit of error handling to CharSelectGF & CharSelectSubState

Co-Authored-By: Linus Torvalds <torvalds@linux-foundation.org>
2025-06-23 14:13:35 -04:00
Lasercar 3ac2a02291 funkin null safe 2025-06-23 13:49:32 -04:00
sector-a c1d4bba813
Merge pull request #1257 from FunkinCrew/mobile/button-fixes
Fix various menu button issues for Mobile
2025-06-23 17:06:39 +03:00
MoonDroid 80f3fb6150 fix: the stupid fucking alpha i fucking hate you i hope you DIE
i love you alpha -sigma
2025-06-23 20:57:50 +07:00
MoonDroid 94742eb9ba fix: Properly play the back button animation in Freeplay 2025-06-23 20:21:47 +07:00
MoonDroid 5c06d263b2 fix: Prevent the buttons to be pressed mid-transition to also prevent softlocking
I HATE THIS
2025-06-23 20:21:31 +07:00
Abnormal be60e52725 fix: Fix the stage editor crashing if an FNFS file is loaded through the Recent File section 2025-06-23 05:54:51 +08:00
Hundrec 9e07f5dd5a forgor a semicolon 2025-06-23 04:51:40 +08:00
Hundrec f1bef04165 Unlock Pico, restore input offsets on Desktop 2025-06-23 04:51:40 +08:00
MoonDroid 9687cff9d4 assets submod 2025-06-22 15:49:32 -05:00
Kolo f9c1f7a5f7 clear up styleSheet be4 entering 2025-06-23 03:02:19 +08:00
Lasercar 3d3e2bd378 Intro done right 2025-06-19 22:18:26 -05:00
Abnormal 9804111583 [insert the name of the person that added an extra check for onConfirm idk man]........................................................................................................................................................................................... 2025-06-19 22:15:01 -05:00
Eric 7cbb896a57
Fix several script errors (#1258) 2025-06-19 23:25:40 +00:00
Kolo 0001017c00 the grand reopening 2025-06-19 17:57:12 -04:00
Eric 7d6a4cb763
Changelog for mobile build (#1202)
* First draft of the changelog for mobile build

* first batch of public prs

* mention astc (suggestion by kade)

* add the remaining main repo prs

* ALL OF THEM. ARE DONE.

* some adjustments

* mention haptics

* Some minor cleanup.

---------

Co-authored-by: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
2025-06-19 21:35:38 +00:00
MoonDroid fee5ab49af assets submod 2025-06-19 17:31:13 -04:00
MoonDroid 5201160973 assets submod 2025-06-19 17:31:13 -04:00
MoonDroid 4772dfdc13 Prevent overlapping transitions and checks for both backbutton and optionsbutton
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-06-19 22:12:13 +07:00
MoonDroid 9e3efc0de7 fix: Prevent options back-queuing 2025-06-19 22:09:44 +07:00
MoonDroid c4d24e6d3e refactor: Rework both backButton and optionsButton for better callbacks and readability
Co-authored-by: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com>
2025-06-19 22:07:27 +07:00
MoonDroid fc82b79c9a fix: Prevent back queueing in Options 2025-06-19 17:08:50 +07:00
MoonDroid a98f6f9778 fix: Prevent queuing the back button in Main Menu 2025-06-19 17:08:02 +07:00
MoonDroid 4ca42c3975 fix: Add missing import
hi kade
2025-06-19 17:07:34 +07:00
MoonDroid 51127dfd87 refactor: Change how callbacks are called and added extra checks to avoid softlocking for BackButton 2025-06-19 17:07:18 +07:00
MoonDroid cae7c8a785 fix: Properly check if the state is busy or not for back button in Freeplay 2025-06-19 17:06:43 +07:00
CrusherNotDrip 204501779d This should be 0.0 2025-06-18 22:46:01 -05:00
Abnormal d7c83a5b70 fix a syntax error 2025-06-18 19:53:53 -04:00
Lasercar 4e31003a0f New highscore plays twice fix 2025-06-18 19:53:53 -04:00
Hyper_ cce8c18822 Reduce calls to hold note trail graphic update 2025-06-18 13:02:01 -07:00
zackaryowo ea6cb75b77 A different approach
Let's just override the original implementation with our own!
2025-06-18 13:01:16 -07:00
zackaryowo 9bd2c0b13b Fix dialogue hanging bug
...wait, it's just one line?
2025-06-18 13:01:16 -07:00
GitRan af716f9273 Allow disabling cool funcitons !! 2025-06-18 13:01:16 -07:00
GitRan 88d0e8c3b0 FunkinTypeText: Account for dialogue text wrapping 2025-06-18 13:01:16 -07:00
MoonDroid 6114dfcedb
Merge pull request #1185 from FunkinCrew/feature/mobile-unlock-everything 2025-06-18 18:32:09 +07:00
MoonDroid 52d891c8ff fix: Prevent char select transition to be spam-triggered in Freeplay 2025-06-18 18:31:26 +07:00
sector-a d040e1f72f
assets submod 2025-06-18 18:12:43 +07:00
Mihai Alexandru 8393c789e2
admob: dont run interstitial ads within the rank bg tween.
Co-authored-by: Hundrec <hundrecard@gmail.com>
2025-06-18 17:58:22 +07:00
JackXson-Real 39104fe77f "Auto Pause" -> "Pause on Unfocus" 2025-06-18 01:54:03 -05:00
EliteMasterEric 0e9bb20592 Use a version of OpenFL with improved shader error handling 2025-06-17 16:56:31 -07:00
Kolo 56a18e1cf6 2bugs2fix 2025-06-17 19:17:27 -04:00
EliteMasterEric 948030ef1d Fix several null reference issues tied to the Game Over substate. 2025-06-17 17:19:36 -05:00
Kade 8dce8afdfc add shader teehee 2025-06-17 17:13:43 -05:00
kade-github e7c6798f44 remove unused imports 2025-06-17 17:13:43 -05:00
kade-github 5482dee750 Stop everything, kris get the colorTransform 2025-06-17 17:13:43 -05:00
Lasercar 5549fddec3 Get deselected 2025-06-17 16:50:08 -05:00
Lasercar 65461d839b Close the toolboxes 2025-06-17 16:50:08 -05:00
Hundrec 2a63c1a7ba Stage Editor exit button rename
Co-Authored-By: Lasercar <64717068+lasercar@users.noreply.github.com>
2025-06-17 17:11:00 -04:00
Lasercar fee29f69ec I.. quit (to the menu)! 2025-06-17 17:11:00 -04:00
Lasercar 539720f84d There's a reason it's called the MAIN menu 2025-06-17 17:11:00 -04:00
Lasercar 576f8e54ff Stage editor - Ctrl+N new stage
Also windows target configuration preset for straight to stage editor (not to be confused with the stage builder)
2025-06-17 17:11:00 -04:00
Kade 50ca508fdd Exclude the censored versions for diff platforms 2025-06-17 16:57:11 -04:00
Abnormal 8824a382b9 update submod for censored cutscenes 2025-06-17 16:57:11 -04:00
Hundrec d6ec32f334
assets submod for close button fix (#1241) 2025-06-17 20:18:04 +00:00
Kade d356cfaee6 bump lime-mobile for linux ndlls 2025-06-17 15:13:29 -04:00
EliteMasterEric 49eff01afd Fixed locked characters not showing up properly when selected 2025-06-17 15:08:48 -04:00
EliteMasterEric c4aff95886 Fix inverted condition (whoops) 2025-06-17 15:08:48 -04:00
EliteMasterEric 9f41e22428 Always disable character unlock animations when UNLOCK_EVERYTHING is enabled 2025-06-17 15:08:48 -04:00
EliteMasterEric 123c9396ba Apply UNLOCK_EVERYTHING on mobile by default. 2025-06-17 15:08:48 -04:00
Lasercar 136a5dfad4 Fix Are you sure?
Also they now dance to Artistic Expression
2025-06-18 02:54:37 +08:00
Abnormal f23eddcf2c
forgot vocals aren't included (#1240)
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
2025-06-17 18:49:51 +00:00
Mihai Alexandru 13d8127e75
Merge pull request #1237 from FunkinCrew/gyro-damping
Gyro damping
2025-06-17 17:42:31 +03:00
MAJigsaw77 7d0772170f Merge branch 'master' into gyro-damping 2025-06-17 17:32:25 +03:00
Mihai Alexandru 43bf102d68
Merge pull request #1093 from FunkinCrew/bugfix/ios-simulator
Improvements to iOS simulator, and iOS build documentation
2025-06-17 08:30:40 +03:00
Mihai Alexandru 24101d654d
Merge branch 'master' into bugfix/ios-simulator 2025-06-17 08:29:46 +03:00
Abnormal e82b578eb8 fix a crash when returning to the chart editor on release builds 2025-06-16 23:41:45 -05:00
Hundrec 3eace5a7c8
Adjust GCD MathUtil comments 2025-06-17 12:32:11 +08:00
Cameron Taylor 153f2be177 soften (and sorta limit?) the panning on main menu 2025-06-16 19:51:54 -04:00
Cameron Taylor 380f9e70d5 document the GCD function in MathUtil 2025-06-16 19:50:28 -04:00
Kade ff2dff0635
Merge pull request #1235 from FunkinCrew/html5-build-fix-gyro 2025-06-16 16:37:11 -07:00
EliteMasterEric 24d1116deb Preload all the graphics of a note style before the song starts, greatly reduces stutters early in the song. 2025-06-16 16:34:07 -07:00
EliteMasterEric 8e085171d5 Updated OpenFL to fix HTML5 build issues, tied to gyro functions 2025-06-16 18:37:20 -04:00
Lasercar 4819a74c29 Charselect remember character 2025-06-16 16:08:17 -04:00
Eric f95258358c
Format and re-arrange project.hxp (#1233)
* Format and re-arrange project.hxp

* Remove merge conflict
2025-06-16 19:34:03 +00:00
Eric 962d0b0dc2
Document how to install mods on mobile (#1219)
* Gotta document how to install mods on mobile

* iOS mod installation steps

* Update mod installation docs for all platforms

* Fix weird merge issue in mod install docs.

---------

Co-authored-by: Hundrec <hundrecard@gmail.com>
2025-06-16 16:17:18 +00:00
100ec 6fa4280e31 Re-enable Input Offsets menu for Desktop oopsies 2025-06-16 09:13:05 -07:00
Hundrec 0d2a737a8a finish a comment in project.hxp 2025-06-16 09:12:35 -07:00
Kade 779919d11b
Merge pull request #1224 from FunkinCrew/doppelganger-assets-update 2025-06-16 09:11:57 -07:00
100ec 4a9e8490fc Bump assets for doppelganger cutscene crash 2025-06-16 10:05:35 -05:00
Abnormal 80db44be2b bump flxanimate to fix an issue with the turntable lights 2025-06-16 00:45:48 -04:00
Eric 0f85b4a85d
Update Lime submodule to fix Github Actions build issues (#1226)
* Update Lime submodule to fix build issues

* Disable automatic iOS builds in Github Actions until we fix build issues
2025-06-16 04:44:02 +00:00
Hyper_ c0e0523651 fix: Clear waveform data when destroying audio
This fixes an issue where recycled sounds would use the previous sound's waveform data.
2025-06-16 02:45:44 +08:00
Abnormal 41a246c9a5
add missing 0.6.4 prs
the people will get their fixed debris in pico great results animation
2025-06-14 20:36:37 -05:00
Abnormal cfed20983b add the missing pull requests from 0.6.4 2025-06-14 20:33:10 -05:00
Mihai Alexandru 2273a1b346
Merge pull request #1214 from FunkinCrew/back-button-tweaks
Back Button fixes
2025-06-14 22:11:29 +03:00
MAJigsaw77 a69e08e986 Merge branch 'master' into back-button-tweaks 2025-06-14 22:06:18 +03:00
Mihai Alexandru 1c7abb6391
Merge pull request #1216 from FunkinCrew/bugfix/fix-menus-widescreen-alignment
[WIDE SCREE] Fix some aligment for the UI in some menus
2025-06-14 22:01:45 +03:00
MAJigsaw77 839ff43123 Merge branch 'master' into bugfix/fix-menus-widescreen-alignment 2025-06-14 21:30:03 +03:00
Mihai Alexandru 84e0104984
Merge pull request #1220 from FunkinCrew/gyro
gyroscope panning funzies on main menu
2025-06-14 21:28:01 +03:00
MAJigsaw77 092732a535 Merge branch 'gyro' of https://github.com/FunkinCrew/Funkin-secret into gyro 2025-06-14 21:26:52 +03:00
MAJigsaw77 ff6aea9efd hmm update the refs for android gyro fixes 2025-06-14 21:26:37 +03:00
Mihai Alexandru f1c15c8a84
Merge branch 'master' into gyro 2025-06-14 21:22:25 +03:00
Cameron Taylor beab53a489 hmm update for gyro related branches 2025-06-13 22:37:05 -04:00
Abnormal 8bbdc8c0f4
Merge pull request #1189 from FunkinCrew/feat/naughtyness-off-mobile
Add `FEATURE_NAUGHTYNESS` and `CENSOR_EXPLITIVES` flags
2025-06-13 21:36:17 -05:00
Abnormal 80948ba4ad update assets submod to fix missing imports 2025-06-13 21:26:21 -05:00
Abnormal 5c2cc82340 missed a spot 2025-06-13 21:17:14 -04:00
EliteMasterEric d8a6abc48d Rename the variable to CENSOR_EXPLETIVES 2025-06-13 21:17:09 -04:00
EliteMasterEric 5cbea2851c Update assets submodule 2025-06-13 21:16:54 -04:00
EliteMasterEric 2cf29a67d9 Added a separate variable specifically for mobile censorship. 2025-06-13 21:16:42 -04:00
Abnormal e8cd87c1f1 Add FEATURE_NAUGHTYNESS and turn it off for mobile builds 2025-06-13 21:16:41 -04:00
Abnormal 075f03235d fix: Fix an issue where the album didn't update when switching variations 2025-06-13 21:09:10 -04:00
Cameron Taylor fcb5fe85ff gyroscope panning funzies on main menu 2025-06-13 20:47:09 -04:00
Abnormal bbd598a560 add the remaining asset changes that got lost in the rebase 2025-06-13 11:34:26 -05:00
EliteMasterEric 5ca21d1bb3 Update Polymod to include some moderate optimizations 2025-06-12 23:52:36 -07:00
MoonDroid a9ba2a7a1c
Merge pull request #1213 from FunkinCrew/feature/various-haptic-changes 2025-06-13 11:12:48 +07:00
KarimAkra a2c0625137 Fixed title state aligment 2025-06-13 07:10:55 +03:00
KarimAkra d0d1d3c376 story menu state aligments 2025-06-13 07:10:43 +03:00
Karim Akra d0fe228e21
Scale the pico accept backing card for wide screen 2025-06-13 09:53:52 +07:00
MoonDroid 1b7dc5f1ac fix: Make backing out of options instant 2025-06-13 09:45:55 +07:00
MoonDroid ea0e4ee56d fix: Remove all callbacks when destroyed 2025-06-13 09:45:36 +07:00
MoonDroid 1b1d0a978d Play cancelMenu when backing out 2025-06-13 09:45:19 +07:00
sector-a bf007e2a2c art submod 2025-06-13 05:01:57 +03:00
sector-a aa24e08fdb Merge branch 'master' into feature/various-haptic-changes 2025-06-13 05:00:36 +03:00
sector-a d72b2bb2da assets submod 2025-06-13 04:57:29 +03:00
sector-a 49693f06e9 winter horrorland haptics 2025-06-13 04:57:23 +03:00
KarimAkra 99ad45997e Push the strums a bit back to the left 2025-06-13 04:21:21 +03:00
MoonDroid 849553e0f0
Merge pull request #1212 from FunkinCrew/character-select-extensions 2025-06-13 06:52:58 +07:00
KarimAkra 48ca0ecef3 Update art 2025-06-13 02:48:29 +03:00
KarimAkra 403c6250f8 Merge branch 'master' into character-select-extensions 2025-06-13 02:48:19 +03:00
KarimAkra ffbc8c80c8 nudge the speakers a bit to cover the curtain properly 2025-06-13 02:42:05 +03:00
Karim Akra aacb200638
Merge pull request #1207 from FunkinCrew/mobile/freeplay-tweaks
Couple of Freeplay tweaks for final release
2025-06-13 02:04:25 +03:00
KarimAkra 603e370908 assets submodule !! 2025-06-13 01:29:26 +03:00
MoonDroid 43d8b522cb
Merge pull request #1210 from FunkinCrew/bugfix/freeze-video-restarting 2025-06-13 05:24:07 +07:00
KarimAkra b75cfcb833 Fixed last few issues with ios for notch and centering on character select 2025-06-13 01:18:22 +03:00
KarimAkra dc800dc48e added logicalSize to FullScreenScaleMode 2025-06-13 00:32:09 +03:00
MAJigsaw77 9706a55eca Merge branch 'master' into bugfix/freeze-video-restarting 2025-06-13 00:04:07 +03:00
KarimAkra 6b11f8b852 slight refactor for FullScreenScaleMode to fix some wide screen related issue 2025-06-12 23:45:50 +03:00
KutikiPlayz 6ad9ffc7f9 notes move freaking normally 2025-06-12 13:21:39 -07:00
MAJigsaw77 895eeed852 fix: restart on video cutscenes. 2025-06-12 17:56:26 +03:00
MAJigsaw77 4541f91d84 hmm: update hxvlc version. 2025-06-12 17:49:38 +03:00
luckydog7 068a995cdd
ios: tweaking audiosession to fix some bugs 2025-06-12 18:17:35 +07:00
MAJigsaw77 1a07e082c9 fix: freeze when restarting a video cutscene. 2025-06-12 12:47:36 +03:00
EliteMasterEric 4fa12a3486 Try to add mobile to the build-game workflows 2025-06-12 03:33:34 -05:00
EliteMasterEric 0a9ac0e93c Try to fix "Cancel merged branches" workflow 2025-06-12 03:33:34 -05:00
EliteMasterEric 974a78919d Additional documentation for workflows 2025-06-12 03:33:34 -05:00
EliteMasterEric fb9bf59a7e Fix a null error caused by calling Constants.VERSION too early. 2025-06-12 03:33:34 -05:00
Cameron Taylor e0b4c30719
icon update for iOS 2025-06-12 15:23:37 +07:00
Abnormal 80ffe6faa7 asset submod for stage editor 2025-06-12 02:08:27 -06:00
Kolo 15083a4776 delete logic fix + 2 new feats
feat 1: new objects now have the zIndex 1 higher than the last one (thanks hundrec)
feat 2: chars to test as are now saved (thanks imverybad)
2025-06-12 00:47:24 -06:00
Kolo 0dbffa6875 even more fixes and missing features 2025-06-12 00:47:24 -06:00
Kolo a776ce1a81 stage editor bugfixes + features :D 2025-06-12 00:47:24 -06:00
MoonDroid 738bd8b7c7 Increase arrows touch hitbox for Freeplay 2025-06-12 13:32:15 +07:00
MoonDroid d79f99475e Remove swipe right to exit on Freeplay 2025-06-12 13:31:46 +07:00
Hundrec 221c3db6e6 Restore camera events for Pico Erect 2025-06-12 01:01:53 -05:00
MoonDroid e92c6ec8f7
Merge pull request #1200 from FunkinCrew/bugfix/hide-pause-button-and-bring-resume-back 2025-06-12 12:00:35 +07:00
EliteMasterEric de0a56ec95 Temporarily disable the input offsets feature until we get it fully functioning again. 2025-06-11 20:15:55 -07:00
EliteMasterEric aefa8d149f Fix typos preventing builds on "master" branch 2025-06-11 20:29:51 -06:00
EliteMasterEric 29ee386dfe Update Polymod to allow mods with versions v0.6.3 or v0.7.0. 2025-06-11 19:21:00 -06:00
sector-a 0d965ba91c Fix pause button hiding 2025-06-12 04:06:56 +03:00
Kade a29e20098b
Merge pull request #1174 from FunkinCrew/bugfix/html5-reflectutil-nullsafety 2025-06-11 17:36:40 -07:00
Kade a2c5758112
Merge branch 'master' into bugfix/html5-reflectutil-nullsafety 2025-06-11 17:36:11 -07:00
EliteMasterEric 01fd37e08b Remove the redundant TimerUtil class. 2025-06-11 17:35:01 -07:00
Lasercar 5eecef17a1 Try push unique the difficulties for the notes 2025-06-11 17:32:44 -07:00
Lasercar 9df5395ff8 Load meta/chartdata fix
Deletes the song serialiser class, it has no use anymore
Also fixes the BPM changes
Note style is properly set when metadata toolbox is refreshed
Add variation dialog now fills note style dropdown with note styles and sets it properly afterwards
Also makes a few optimisations for the chart editor
2025-06-11 17:32:44 -07:00
Kolo 50d9584a38 another 20 trillion sandboxed classes 2025-06-11 17:31:40 -07:00
zackaryowo 0e24ae911f Fixed instrumentalOffset goofiness :D 2025-06-11 19:24:46 -05:00
zackaryowo c87a39b6c2 Oops, don't need this here
Thank you @NotHyper-474!
2025-06-11 19:24:46 -05:00
zackaryowo 760190d135 Update source/funkin/Conductor.hx
thank you https://github.com/cyn0x8 for reminding me FlxMath.bound exists

Co-Authored-By: cyn <cyn0x8+git@gmail.com>
2025-06-11 19:24:46 -05:00
GitRan 9f8e42bd3c Alter countdown + conductor behavior
Conductor's minimum songPosition when music is playing is now combinedOffset.

resyncVocals is also no longer used when the song starts, as it complicates matters and causes weird double-upping whatever due to the song being played, paused, and then played again
2025-06-11 19:24:46 -05:00
GitRan 1f75a641e0 Fix audio offset interactions with song start
Don't use combined offset here-- using it will cause the instrumental to skip forwards due to your offset. Just use instrumental offset, and don't play it when the song starts-- let resyncVocals do that
2025-06-11 19:24:46 -05:00
sector-a 47f0fc7236 Bring back the resume entry in pause in cutscenes 2025-06-12 02:55:43 +03:00
sector-a 79185596c1 Hide the pause button on ending cutscenes 2025-06-12 02:53:42 +03:00
Hundrec 8cae34eed7
[PUBLIC PR] Hyper's Stacked Notes Viewer (#1165)
Co-authored-by: Hundrec <hundrecard@gmail.com>
Co-authored-by: Hyper_ <survivaltemer@gmail.com>
Co-authored-by: lemz1 <ismael.amjad07@gmail.com>
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: Kade <26305836+Kade-github@users.noreply.github.com>
2025-06-11 16:24:30 -07:00
Mihai Alexandru a0ae4de5e8
mobile: make changing difficulties add to ad counter 2025-06-12 05:29:37 +07:00
Eric e7df920e74 Revert "rank anim only plays when entering freeplay or changing difficulties"
This reverts commit 55221646b8.
2025-06-11 16:29:17 -06:00
Mihai Alexandru 07958590a4
fix: iap not working correctly when upgrading 2025-06-12 05:18:19 +07:00
Mihai Alexandru bc01d5cffa
fix: audio desync when restarting a video cutscene. 2025-06-12 04:41:01 +07:00
MAJigsaw77 295e6f652e fix: fix gitaroo pause menu on wide screen. 2025-06-11 04:42:33 -06:00
KarimAkra ea01052b18 Fixed static guy and some resolution dependant issues 2025-06-11 12:46:21 +03:00
Hundrec cacb95bdd3 Tiny mobile link adjustments 2025-06-11 03:21:10 -06:00
MoonDroid 44fa64542a Exclude chart-editor, soundtray and stageBuild from ASTC compression
also reorganizes the list
2025-06-11 03:21:10 -06:00
MoonDroid 43c7f4e883 Update lime ref 2025-06-11 03:21:10 -06:00
MoonDroid 157a0a36dc assets submod 2025-06-11 03:21:10 -06:00
MoonDroid 034a861c69 Set minimum iOS version to be 16.0 2025-06-11 03:21:10 -06:00
MoonDroid 333e5326a2 Update readme to include links for mobile builds 2025-06-11 03:21:10 -06:00
EliteMasterEric 8e7de54aa0 Disable initial caching of "shared" assets on HTML5. 2025-06-11 05:08:37 -04:00
EliteMasterEric ea81e061d2 Fix null safety issues specific to HTML5 2025-06-11 05:08:37 -04:00
Abnormal cd3b7d7b95 ???????????????????????? 2025-06-11 02:52:05 -06:00
Abnormal 5d4e1d276b additional revision made after pr was pulled internally
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
2025-06-11 02:52:05 -06:00
VioletSnowLeopard 55221646b8 rank anim only plays when entering freeplay or changing difficulties 2025-06-11 04:26:55 -04:00
Cameron Taylor f599e53448 update grig to cam branch 2025-06-10 19:22:53 -04:00
MoonDroid 7629a1a92d Update lime ref 2025-06-10 19:22:53 -04:00
MoonDroid 1c8f320a54 Update grig.audio refs to FunkinCrew's 2025-06-10 19:22:53 -04:00
EliteMasterEric e7ddf9fbc8 Move hmm schema to its own file. 2025-06-10 18:16:17 -04:00
Cameron Taylor 9d6450454e json schema for hmm.json files (json schema testing) 2025-06-10 18:16:17 -04:00
Abnormal b80a8d60af fix: Fix the Stage Editor button in the Debug Menu not doing anything 2025-06-10 17:57:22 -04:00
Hyper_ d968fb271c Make sound effects pause with the game 2025-06-10 17:23:46 -04:00
Abnormal 70f0a54191 feat: Options Menu scrolling 2025-06-10 08:57:55 -07:00
Abnormal 29b94ea736 add cache to Assets 2025-06-10 08:57:14 -07:00
MoonDroid 8ca4d933aa
Merge pull request #1182 from FunkinCrew/mobile/admob-and-iapcore-fixes 2025-06-10 20:43:47 +07:00
MAJigsaw77 20e8a4566d mobile: make MAX_BEFORE_AD final. 2025-06-10 15:32:17 +03:00
MAJigsaw77 69c5c05039 mobile: adjust admob and iapcore variables a little. 2025-06-10 15:29:08 +03:00
MAJigsaw77 299a720575 mobile: multiiple fixes to admob and iapcore code. 2025-06-10 14:52:06 +03:00
sector-a 8d7500e8c0
assets submod 2025-06-10 18:40:22 +07:00
Hyper_ cadfa3b7ce Polymod: Blacklist funkin.util.macro.*
It has `CompiledClassList` which allows access to `sys` and Newgrounds API functions.
2025-06-10 06:23:37 -05:00
MoonDroid 5342601f8b fix: Call the callbacks if the upgrade is purchased 2025-06-10 05:01:30 -06:00
MoonDroid f6b1ff13bc
Merge pull request #1169 from FunkinCrew/mobile-main-menu 2025-06-10 17:52:38 +07:00
MoonDroid d43e9506b3 Merge branch 'master' into mobile-main-menu 2025-06-10 17:38:08 +07:00
MoonDroid 753f51dcf6 assets submod
two
2025-06-10 17:31:58 +07:00
MoonDroid 9303e4c272 Force FPS, pause on unfocus, and debug display to be a set value on mobile 2025-06-10 17:15:41 +07:00
MoonDroid b0f4a075b5 fix: Tweak back button position in Preferences 2025-06-10 17:15:12 +07:00
MoonDroid 031f888a25 Remove debug display, pause on unfocus, and FPS from Mobile 2025-06-10 17:14:52 +07:00
MoonDroid bc94a5a6ac fix: Remove control schemes and add back button into Options 2025-06-10 17:13:56 +07:00
MoonDroid 2450961b28 Add IAP functionality to the upgrade item in Main Menu 2025-06-10 17:13:04 +07:00
Hundrec 8b8737006f
Add "Team Organizers" to credits 2025-06-10 16:44:28 +07:00
Hundrec 5c4fa108c0 stages go wiiide 2025-06-09 18:53:17 -07:00
sector-a f4245ee0da
assets submod (#1168) 2025-06-10 03:57:05 +07:00
fabs aa8f5087b5 set upgraded to true on pc always 2025-06-09 21:43:28 +01:00
fabs edc668dad5 add options button to main menu + upgrade button tweaks 2025-06-09 21:21:09 +01:00
fabs 2771a13d5e tweak behavior for main menu items on mobile 2025-06-09 21:20:54 +01:00
fabs b63e02d9e7 make freeplay back button instant 2025-06-09 21:20:32 +01:00
fabs 9d3595c855 implement new back button + options button to musicbeatstates 2025-06-09 21:20:16 +01:00
fabs 250b5cb54f add options button 2025-06-09 21:19:48 +01:00
fabs e457b3e03b add instant option for back button 2025-06-09 21:19:36 +01:00
fabs 38e0cb6ab1 remove trace from sparkles 2025-06-09 21:19:11 +01:00
fabs 4746e8d7a5 assets submod 2025-06-09 17:50:16 +01:00
fabs db2644c0ff add upgrade button to main menu + simple logic 2025-06-09 17:49:37 +01:00
fabs f9aff5b11b upgrade sparkles.. 2025-06-09 17:49:27 +01:00
KarimAkra cc9797c452 adjust character select for wide screen
small bug, the static guy is off position sorry will fix it later i need ot go now TwT
2025-06-09 11:14:57 +03:00
MAJigsaw77 a97acfe18e mobile: move ad banner to the top left. 2025-06-09 01:31:19 -06:00
Hyper_ 65ed58350b Fix implementation of fastIndexOf causing duplicate notes in displayedNoteData 2025-06-08 23:59:33 -04:00
fabs 9e6c17507f assets submod 2025-06-09 03:15:05 +01:00
fabs 3360493444 implement extended assets 2025-06-09 03:14:57 +01:00
Hundrec e657bc900b
save ALL params grrrrr
Co-authored-by: Kolo <67389779+JustKolosaki@users.noreply.github.com>
2025-06-09 08:03:05 +07:00
MoonDroid 5a5f1f83f3
[PUBLIC PR + TWEAKS] Always display charSelectHint after unlocking character, and adjust message for mobile (#1157) 2025-06-09 08:02:23 +07:00
Hundrec 277416b6a3
Nudge metadata differently for mobile 2025-06-09 08:00:43 +07:00
Hundrec 37a40c24a1 super secret change don't look 2025-06-08 20:10:54 -04:00
Mihai Alexandru e90b74f788
Comment the failed ad banner placeholder code. 2025-06-09 06:53:55 +07:00
Hundrec ad11fb26b9 Kolo's mommy mearest pixel fix yay 2025-06-08 19:35:48 -04:00
sector-a 287603ad30
Assets submod 2025-06-09 06:03:45 +07:00
Lasercar 1c25713464 Use first difficulty as fallback 2025-06-08 16:57:34 -06:00
Hundrec 7cbc5b0dc7 Adjust character select hint message for mobile 2025-06-08 16:51:31 -06:00
Hundrec 7ccf75cd86 Always display charSelectHint after unlocking character 2025-06-08 16:49:09 -06:00
Mihai Alexandru eec304f42f
mobile: add RESTORE PURCHASES button on the options menu. 2025-06-09 05:41:16 +07:00
MoonDroid 7e4508f991 fix: Re-add the ability for the user to hold-scroll on Freeplay 2025-06-08 13:36:08 -06:00
MoonDroid f74d1655d5 fix: Change ACCEPT to ENTER
Having it on ACCEPT only speeds it up for a frame
2025-06-08 13:30:58 -06:00
Mihai Alexandru 5057f3d1de
Merge pull request #1147 from FunkinCrew/fix/menu-cleanup
[MOBILE] Small menu fixes for mobile release
2025-06-08 21:32:55 +03:00
MoonDroid a103b9641f
Merge pull request #1154 from FunkinCrew/bugfix/admob-running-no-any-state 2025-06-08 20:33:39 +07:00
MAJigsaw77 9e58ef70fb Adjutements to how playing counter work aswell as playing an ad in the pause menu before restarting the song. 2025-06-08 16:29:33 +03:00
MoonDroid f5a453b2e7
Merge pull request #1151 from FunkinCrew/mobile-pause-plus-back 2025-06-08 20:23:05 +07:00
MoonDroid d432e086cc Merge branch 'master' into mobile-pause-plus-back 2025-06-08 20:19:01 +07:00
MoonDroid f2280b1c0f fix: Move the backbutton correctly to the bottom right, remove forced color 2025-06-08 19:22:46 +07:00
MoonDroid 7f619640f2 fix: Increase GLOBAL_PLAYING_COUNTER when resetting PlayState in Pause Menu 2025-06-08 18:52:01 +07:00
MoonDroid 9d5613cc95 fix: Move pause metadata to bottom right on mobile 2025-06-08 18:43:01 +07:00
Mihai Alexandru 96c788a420
mobile: don't initialize the VolumePlugin. 2025-06-08 17:19:51 +07:00
Mihai Alexandru 07f792e358
hmm: update mobile extensions refs. 2025-06-08 17:12:08 +07:00
MoonDroid 24db9235e1 fix: Add targetStateFactory to prevent Stickers to be called during an ad. 2025-06-08 16:50:28 +07:00
MAJigsaw77 370e00c9b9 Move the metadata buttom right. 2025-06-08 12:22:19 +03:00
fabs 6d5767aef2 assets submod 2025-06-08 04:09:45 +01:00
fabs b3ebfd0910 pause button/pause screen rework 2025-06-08 04:09:40 +01:00
fabs a9a4dad511 forgot these oooops 2025-06-08 04:09:27 +01:00
fabs dc04ff23d7 move back button + swap class names 2025-06-08 04:09:20 +01:00
fabs 72f7317db2 rework freeplay back button 2025-06-08 04:07:56 +01:00
fabs 57ebeb25e4 i feel like this makes more sense 2025-06-08 04:06:30 +01:00
fabs 7fd1d312d7 rename FunkinBackspace + back button rework 2025-06-08 04:05:52 +01:00
Eric c2643c3873
Update project.hxp 2025-06-07 21:17:10 -04:00
Eric a1c1187b43
Use the official team ID 2025-06-07 21:16:55 -04:00
MoonDroid a7e46ed55b fix: Prevent difficulty sprite from just disappearing 2025-06-07 22:26:12 +07:00
MoonDroid 22c24f53f6 fix: Push the difficulty sprites slightly to the left for Story Menu 2025-06-07 22:25:47 +07:00
MoonDroid 262c4fb9a1 chore: Moved haptics preference option up 2025-06-07 22:24:40 +07:00
sector-a 75aea15539
Fix death haptics not working on some variations 2025-06-07 21:56:52 +07:00
MoonDroid 6e8494e615 Merge branch 'bugfix/admob-running-no-any-state' of https://github.com/FunkinCrew/Funkin-secret into bugfix/admob-running-no-any-state 2025-06-07 21:41:20 +07:00
MoonDroid 4392f5e642 fix: prevent death quote looping in Game Over 2025-06-07 21:41:08 +07:00
MAJigsaw77 21616e9399 Combine both ad counters into GLOBAL_PLAYING_COUNTER. 2025-06-07 17:26:38 +03:00
MAJigsaw77 814c563c55 Move gameover ads loading to gameover state. 2025-06-07 16:38:38 +03:00
MAJigsaw77 537c7cb5a1 Add a callback when the ad finishes showing. 2025-06-07 15:34:57 +03:00
Karim Akra 1801c542a6
Merge pull request #1133 from FunkinCrew/chore/invert-freeplay-swipes
More inverted difficulty anim fixes
2025-06-07 15:05:08 +03:00
MoonDroid f854a6e07a
Merge pull request #1130 from FunkinCrew/Hyper/fix-countdown-stacking 2025-06-07 08:24:23 +07:00
VioletSnowLeopard e193f7392a set selected after changing difficulties or unfavoriting a song 2025-06-06 21:22:36 -04:00
Hyper_ eb8d878aeb Prevent vwoosh timer from running outside PlayState 2025-06-06 21:10:03 -04:00
Hyper_ f19ae72b27 Improve vwoosh timer behaviour (no freezing the whole game this time) 2025-06-06 21:10:03 -04:00
Kolo 63eca96c98 run checks if timer's running 2025-06-06 21:10:03 -04:00
Lasercar b008f88e0d I sawed this playbackspeed in half! 2025-06-06 21:05:56 -04:00
Lasercar a50a014de3 Whoops, didn't save and load the stuff properly 2025-06-06 21:05:56 -04:00
Lasercar f78ab4da1d Save chart editor vocal volume and playback speed
Also opponent hitsounds
2025-06-06 21:05:56 -04:00
Hundrec 1d1c1403c3 second batch of public assets PRs 2025-06-06 20:56:49 -04:00
MoonDroid 743462d96e
Merge pull request #1134 from FunkinCrew/perf/sustain-trail-leak 2025-06-07 07:51:24 +07:00
EliteMasterEric 72a6b92daf Remove auto-rebuilding of HXCPP (it forces the game to clean build every time) 2025-06-06 20:46:50 -04:00
EliteMasterEric 285a607d9a Stop recreating the Hold Note graphic every time it is revived. This plugs a memory leak. 2025-06-06 20:45:23 -04:00
EliteMasterEric c6526527f1 Add HXCPP build to Prebuild, and add timer to Prebuild script 2025-06-06 20:45:23 -04:00
EliteMasterEric 7b3c9f1131 Update HXCPP to support the latest version of Tracy, check out the flame graph! 2025-06-06 20:45:23 -04:00
Eric 402f2707b3
Merge pull request #1140 from FunkinCrew/abnormalpoof/discordrpc-trace-removal
[PUBLIC PR] Remove spammy traces from DiscordClient
2025-06-06 20:33:39 -04:00
Abnormal e89f9f50dc fix: Remove spammy trace calls from DiscordClient 2025-06-06 20:33:31 -04:00
Hundrec 4eaa3842c6 apply these latencystate changes very important!!!
Co-Authored-By: Kade <26305836+Kade-github@users.noreply.github.com>
2025-06-06 17:21:54 -07:00
JackXson-Real 1d9e34359c OptionsState now remembers selection 2025-06-06 17:21:54 -07:00
JackXson-Real 5361df2544 latency state exits to options state 2025-06-06 17:21:54 -07:00
Eric 60a707b963
Merge pull request #1126 from FunkinCrew/Hundrec/hide-debug-cursor
[PUBLIC PR] Hide debug cursor when Title Screen starts
2025-06-06 20:08:23 -04:00
Hundrec 6222c389e3 Hide cursor when Title Screen starts 2025-06-06 20:03:51 -04:00
Eric 6265d751f8
Merge pull request #1125 from FunkinCrew/Hundrec/faves-week-sort
[PUBLIC PR] Sort Favorites by Week order, not alphabetically
2025-06-06 20:01:50 -04:00
Eric aff83bab4d
Merge pull request #1136 from FunkinCrew/KoloInDaCrib/move-sustains-with-notes
[PUBLIC PR] Move Hold Trails with Note Heads in Chart Editor
2025-06-06 19:48:56 -04:00
Kolo d3d8aaae7b move da hold note trails 2025-06-06 19:16:29 -04:00
Eric c263b4bc83
Merge pull request #1127 from FunkinCrew/Hundrec/fix-playstate-typos
[PUBLIC PR] Fix typos and errors in PlayState comments
2025-06-06 19:15:00 -04:00
Hundrec 7a2be205b9 Fix typos and errors in PlayState comments
Co-Authored-By: VioletSnowLeopard <202548129+violetsnowleopard@users.noreply.github.com>
2025-06-06 19:14:46 -04:00
Eric cd0e8a301d
Merge pull request #1135 from FunkinCrew/VioletSnowLeopard/squashed-capsule
[PUBLIC PR] Fix Two Issues With Song Text on Freeplay Capsules
2025-06-06 19:10:44 -04:00
VioletSnowLeopard 8b80478229 Fix squashed text for real this time 2025-06-06 15:54:19 -06:00
VioletSnowLeopard 0c62428fc8 fix song text remaining highlighted
unintentionally fixes song text squishing
2025-06-06 15:54:19 -06:00
EliteMasterEric 2904e660e9 Add confirmation sound and animation before transitioning to Chart Editor in Freeplay 2025-06-06 15:05:08 -06:00
EliteMasterEric e2b9cc9ed5 Provide difficulty and variation to Chart Editor when transitioning from Freeplay 2025-06-06 15:05:08 -06:00
EliteMasterEric 5ac9cee76c Fix Freeplay -> Chart Editor debug key not being processed properly 2025-06-06 15:05:08 -06:00
MoonDroid 62fa3ef934 Switch values for capsule swipes 2025-06-07 01:33:23 +07:00
MoonDroid d81e409d93
Merge pull request #1117 from FunkinCrew/mob-96/week3-train-haptics 2025-06-07 01:28:56 +07:00
MoonDroid aac09f86fe Merge branch 'master' into mob-96/week3-train-haptics 2025-06-07 01:28:15 +07:00
MoonDroid 428c5443f6 Update assets submodule ref 2025-06-07 01:23:01 +07:00
MoonDroid 1e5ec7850f Update art submodule ref 2025-06-07 00:36:26 +07:00
MoonDroid 2e0dfab9fb chore: Properly animate difficulty swipes and invert swipes for capsule/diff drags 2025-06-07 00:36:07 +07:00
sector-a d78117e377 Assets submod 2025-06-06 14:39:20 +03:00
sector-a 7aa0db844b Solve merge conflicts 2025-06-06 14:30:14 +03:00
sector-a d72d93083f Merge branch 'rewrite/master' into mob-96/week3-train-haptics 2025-06-06 14:29:58 +03:00
Eric 9769a626bc
Merge pull request #1131 from FunkinCrew/assets/public-batch-one
[ASSETS] First batch of public assets PRs
2025-06-06 02:45:52 -04:00
Hundrec afcf9a26cc first batch of public assets PRs 2025-06-06 00:30:29 -06:00
Karim Akra 28363652ef
Added outline for circle hints 2025-06-06 12:57:50 +07:00
Eric 42ff442ef8
Merge pull request #1128 from FunkinCrew/Raltyro/lit-up-id
[PUBLIC PR] Fix Lit Up being impossible to submit score into
2025-06-06 01:21:35 -04:00
Ralty 183cec62dc Fix Lit Up being impossible to submit score into 2025-06-05 22:34:42 -06:00
Hundrec da0964a7b7 Remove alphabetical sort from Favorites 2025-06-05 21:53:33 -06:00
sector-a fabc16d265
Add haptics preference 2025-06-06 04:10:25 +07:00
sector-a 57bb462a38
Merge pull request #1119 from FunkinCrew/admob/pause-banner-top-center
[Admob] Use `TOP_CENTER` for the `AD` banner on the pause menu.
2025-06-05 13:03:18 +03:00
MAJigsaw77 2f647127b1 Use TOP_CENTER for the AD banner on the pause menu. 2025-06-05 10:05:28 +03:00
Cameron Taylor bbddb34853
Merge pull request #1112 from FunkinCrew/lasercar/chart-editor-tweens
[PUBLIC PR] Add additional tween types to Chart Editor events
2025-06-05 02:29:55 -04:00
Cameron Taylor 1d88ec473e
Merge pull request #1114 from FunkinCrew/nothyper/tracy-framemark
[PUBLIC PR] Remove unnecessary Tracy frame mark
2025-06-05 02:25:38 -04:00
sector-a bb98883807 art submod 2025-06-05 04:35:18 +03:00
Eric 451d4d1399
Fix typo in project.hxp (#1116) 2025-06-05 04:03:31 +03:00
Eric b66a955d65
Merge pull request #1109 from FunkinCrew/violetsnowleopard/fix-combo
[PUBLIC PR] Fix Combo Drop animations
2025-06-04 20:36:39 -04:00
VioletSnowLeopard 34d5ed1169 Fix combo drop animations 2025-06-04 20:30:21 -04:00
Eric ea6e2aef7b
Merge pull request #1098 from FunkinCrew/chore/disable-lime-asset-cache-version-macro
[CHORE] Disable the lime.utils.AssetCache version macro
2025-06-04 20:24:38 -04:00
Eric 099d1b3eb1
Merge pull request #1108 from FunkinCrew/lasercar/rank-smash
[PUBLIC PR] New rank doesn't SMASH old rank
2025-06-04 20:08:41 -04:00
Lasercar ab817bb1ea Fake rank now visible
Also fixes the song text clipping the rank area when getting a new rank
2025-06-04 19:56:36 -04:00
Eric 6077ba67f7
Merge pull request #1107 from FunkinCrew/lasercar/character-select-no-character
[PUBLIC PR] Fix crash in character select menu
2025-06-04 19:38:35 -04:00
Lasercar 3bbb4b06c8 no character? 2025-06-04 19:38:04 -04:00
Eric f92fe3ff15
Merge pull request #1105 from FunkinCrew/violetsnowleopard/unnecesarryline
[PUBLIC PR] Remove an unnecessary line from `FreeplayState.hx`
2025-06-04 19:27:00 -04:00
VioletSnowLeopard 067a04e069 Remove this unnecessary line
`curSelected` is always set to 0 directly above this
2025-06-04 19:26:35 -04:00
sector-a e9697e6f40 Make sharpness changeable 2025-06-05 01:34:09 +03:00
sector-a 0345107e71
Disable inst select menu on mobile 2025-06-05 05:17:33 +07:00
Lasercar 5177e1275e Add all tween types 2025-06-04 17:31:26 -04:00
Karim Akra be57d2fa3c
Merge pull request #1104 from FunkinCrew/menu-cleanup
Clean up Menu code and fix a few menu-related issues.
2025-06-04 22:27:53 +03:00
MoonDroid ff7b7b5d3e
Increase verticle hitbox for the default control scheme (#1103) 2025-06-04 22:24:17 +03:00
MoonDroid e7c42dae0c
fix: Invert difficulty change and its animations. (#1102) 2025-06-04 21:57:34 +03:00
Karim Akra 07ad53a09b
Merge pull request #1101 from FunkinCrew/refactor/pause-layout
Refactor pause menu layout
2025-06-04 21:54:35 +03:00
MoonDroid 113326089a
Merge pull request #1096 from FunkinCrew/feature/in-app-review 2025-06-05 00:05:31 +07:00
Karim Akra ed0abb8215
Use proper insets for IOS notch rectangle 2025-06-04 23:54:56 +07:00
MoonDroid 405fe21c53 fix: Further improve scrolling in Story Menu by preventing unintended diagonal scrolling behavior 2025-06-04 23:44:32 +07:00
MoonDroid e5b280c646 Turn off FEATURE_NEWGROUNDS for Mobile platforms 2025-06-04 23:43:49 +07:00
MoonDroid 36cbfe91bb Disable launchStoryboard temporarily until we find a fix 2025-06-04 23:43:21 +07:00
MoonDroid 4081f329d2 chore: Remove test purchase flow from OptionsState 2025-06-04 23:42:14 +07:00
MoonDroid 402d5b730b refactor: lock scrolling in Main Menu, and prevent accidental tapping in Options Menu 2025-06-04 23:41:47 +07:00
MoonDroid 5e7e2f45f3 Remove merch from Main Menu on mobile. 2025-06-04 23:31:25 +07:00
MoonDroid 80393bbc6d Revert "Push the pausebutton slightly further onto the left for iOS."
This reverts commit 7689c7d2e4.
2025-06-04 22:17:31 +07:00
MoonDroid 2c44785c39 Move pause metadata text to bottom-right corner
also fix an issue where the countdown keeps running during pause.
2025-06-04 22:12:54 +07:00
KarimAkra 329be321eb Merge branch 'feature/in-app-review' of github.com:FunkinCrew/Funkin-secret into feature/in-app-review 2025-06-04 17:57:54 +03:00
KarimAkra e79d4e69c2 Properly add IOS support for IAR 2025-06-04 17:57:48 +03:00
MoonDroid fda944a9f7 fix: Prevent accidental taps by distinguishing swipes from taps 2025-06-04 21:18:52 +07:00
MoonDroid ab00a126fa refactor: Move pause and countdown logic into function, trigger on tab-out 2025-06-04 21:17:53 +07:00
MoonDroid 7689c7d2e4 Push the pausebutton slightly further onto the left for iOS. 2025-06-04 21:16:03 +07:00
EliteMasterEric 91d1fb74f7 Enable IAR on iOS 2025-06-04 10:06:27 -04:00
KarimAkra a5921ab96c Disable the lime.utils.AssetCache version macro 2025-06-04 16:31:15 +03:00
Eric 7fca9d4c7e
Additional mobile build configuration 2025-06-04 07:17:01 +07:00
EliteMasterEric 0e26f9d936 Implement in-app reviews 2025-06-03 20:00:34 -04:00
Karim Akra af71c3acd7
Fix the freeplay flames position 2025-06-04 05:42:06 +07:00
Karim Akra 9e8c4f1fa1
Set ASTC blocksize to 10x10 (#1095) 2025-06-04 05:41:25 +07:00
Eric 268166b7e0
Merge pull request #1046 from FunkinCrew/fix/attract-state-touch
Fix AttractState skipping for mobile
2025-06-03 09:58:22 -04:00
KarimAkra 9bd65a4782 Added a FlxPieDial meter to AttractState for skipping the video 2025-06-03 09:47:41 -04:00
EliteMasterEric 8a3e623d28 Improvements to iOS simulator build documentation 2025-06-03 06:06:24 -04:00
Cameron Taylor 9d671888ef
Merge pull request #1057 from FunkinCrew/charlesisfeline/polymod-unserializer-2
[PUBLIC PR] Fix script blacklisting of haxe.Unserializer.
2025-06-03 03:41:03 -04:00
fabs 1fc71a3852 assets submod.............. 2025-06-03 03:37:46 -04:00
fabs af546a14a2 assets submod 2025-06-03 03:34:03 -04:00
fabs 7d5904b539 assets submod 2025-06-03 03:24:02 -04:00
Cameron Taylor fb2d587a15 Merge branch 'abnormal/playstate-instance-crash' into rewrite/master 2025-06-03 03:22:22 -04:00
Cameron Taylor 2b4a42ac0a Merge branch 'hundrec/chart-editor-ms-display' into rewrite/master 2025-06-03 03:17:47 -04:00
Eric 0f36a05311
Merge pull request #1090 from FunkinCrew/xcode-deploy
bump lime for some xcode helpers
2025-06-03 03:15:05 -04:00
Cameron Taylor 12fc467312 bump lime for some xcode helpers 2025-06-03 03:14:56 -04:00
Hundrec f3dbd763d2 0.7 chart tweaks assets submod 2025-06-03 03:14:12 -04:00
Cameron Taylor 9ed4d7e8fc bump hmm FlxAnimate version for reflection changes 2025-06-03 02:59:26 -04:00
Cameron Taylor 43abebcafd Merge branch 'abnormal/format-hxp' into rewrite/master 2025-06-03 02:54:53 -04:00
Eric a5ae068801
Merge pull request #1091 from FunkinCrew/fix-assets-submod
Point assets submodule to latest secret commit
2025-06-02 19:24:34 -04:00
Hundrec 3f8e96965b Fix assets submod
It was pointing to the public submod again
2025-06-02 19:24:10 -04:00
Karim Akra 367c56c5e7
Merge pull request #1047 from FunkinCrew/invert-difficutly-capsule-drag
Invert difficulty drag
2025-06-03 00:47:01 +03:00
KarimAkra b2aa111b71 Fixed scrollig upwards being too sensitive compared to dawnwards 2025-06-03 00:45:30 +03:00
Mihai Alexandru c6c48bd9a8
chore: backlist mobile extensions access.
"backlist"
2025-06-03 04:33:57 +07:00
Mihai Alexandru 835b79e3de
chore: use trace instead of using Sys.println on mobile utils. (#1088) 2025-06-03 03:59:13 +07:00
Karim Akra ba12d505d6
Merge pull request #1056 from FunkinCrew/feature/bandaid-memory
Band-aid memory fixes to help the game run better.
2025-06-02 23:52:21 +03:00
KarimAkra 193f83e000 Improved memory cleaning by including the weeks directories to the textures purge 2025-06-02 23:45:39 +03:00
EliteMasterEric b69ef72d51 Remove spam from the README 2025-06-02 11:41:22 -07:00
EliteMasterEric 44eb13ef9b Fix issue where prebuild script wouldn't get called properly. 2025-06-02 11:41:22 -07:00
Karim Akra 3fca9cee63
remove the shadowed lime.utils.Log class (#1040) 2025-06-02 08:11:16 +07:00
Karim Akra e7a460042b
fix the opponent strums being misaligned on wide screens 2025-06-02 07:12:48 +07:00
Mihai Alexandru ad1021ee33
feature: add a placeholder solid color graphic when a banner advertisement fails to load. 2025-06-02 07:12:16 +07:00
Mihai Alexandru e9c411f770
[BUGFIX] Fix Android compile with Admob and add openAdInspector function. (#1070) 2025-06-02 07:10:33 +07:00
Mihai Alexandru 8711db49c7
hmm: update extension-haptics to 1.0.2 to fix some issues on iOS. (#1069) 2025-06-02 07:07:28 +07:00
MoonDroid 7485bc990e
Merge pull request #1076 from FunkinCrew/bugfix/better-capsule-scrolling-hitbox 2025-06-02 06:59:21 +07:00
MoonDroid c333bbaa23
Merge branch 'rewrite/master' into feature/bandaid-memory 2025-06-02 06:57:12 +07:00
MoonDroid 28d3999797
Merge pull request #1085 from FunkinCrew/feature/polymod-blacklist-fixes 2025-06-02 06:55:41 +07:00
MoonDroid 8f216ada02 Fix build error for admob on Android 2025-06-02 06:53:16 +07:00
EliteMasterEric 52dfee61fa Fix null safety on ReflectUtil 2025-06-01 18:42:19 -04:00
EliteMasterEric a62d2b94a9 Fix several merge conflicts causing builds to fail. 2025-06-01 18:33:34 -04:00
EliteMasterEric 2e486d987b Add "hscript" to the HScript blacklist 2025-06-01 18:05:24 -04:00
EliteMasterEric 83e1e1f68f Full documentation and null safety for ReflectUtil, and add FIELD_NAME_BLACKLIST to prevent abuse. 2025-06-01 18:02:42 -04:00
EliteMasterEric 3d6882c282 Disable complaints about alignment of conditional compilation 2025-06-01 18:01:41 -04:00
MoonDroid 11383e9385
Merge branch 'rewrite/master' into feature/bandaid-memory 2025-06-02 02:13:19 +07:00
MoonDroid 7d567de24f fix: Increase scroll hitbox slightly and make it so flicks can only be triggered on the htibox. 2025-06-01 18:16:26 +07:00
Lasercar dc56ccada5 ctrl click on hold note null reference fix 2025-05-30 19:49:58 -07:00
Hyper_ d3490f8c99 Fix possible crash when trying to open nonexistent folders 2025-05-30 19:49:33 -07:00
Lasercar 1959a5250f Difficulty no longer always set to normal 2025-05-30 19:49:00 -07:00
Lasercar ae2c2db28f fixed success message (also forgor playstate change) 2025-05-30 19:49:00 -07:00
Lasercar 82af988dce chart editor target song variation parameter 2025-05-30 19:49:00 -07:00
Lasercar e3fca16793 chart editor target song difficulty parameter 2025-05-30 19:49:00 -07:00
Eric 2221594883
[PUBLIC PR] Press Chart Editor key in Freeplay to open that song (#1061)
Co-authored-by: Lasercar <B_l_u_t_a_c_k@hotmail.com.au>
2025-05-30 19:48:22 -07:00
Hundrec be7313453f Make it 500, actually 2025-05-30 19:47:24 -07:00
Hundrec c9c284787e Raise max fps cap to 360 2025-05-30 19:47:24 -07:00
Eric 93e4f799f4
Remove JPEG (#1065)
Co-authored-by: Lasercar <64717068+Lasercar@users.noreply.github.com>
2025-05-30 19:46:34 -07:00
anysad c7abb19698 fix playhead width 2025-05-30 19:45:32 -07:00
Hundrec 7c7dc11f18 Prevent the playhead from scrolling before song start 2025-05-30 19:45:02 -07:00
anysad b883ad3d50 bye bye trace! 2025-05-30 19:44:27 -07:00
Lasercar 426a9c0c10 Clear un/redo history on song load 2025-05-30 19:44:03 -07:00
Hyper_ 0b7a94b1cc Remove V-Sync option from in PreferencesMenu on web builds 2025-05-30 19:43:26 -07:00
EliteMasterEric 711d3896cb Update FlxAnimate to optimize deconstruction 2025-05-30 18:29:57 -04:00
Eric 98236a541a
Merge pull request #1075 from FunkinCrew/kade-github/revert-asset-changes
[CLEANUP] Fix asset submodule
2025-05-29 17:33:17 -04:00
KarimAkra 3179d33a17 Adjust the capsule scroll hitbox size for easier navigation on wider screens 2025-05-29 23:17:41 +03:00
kade-github 3f23b79087
sub fix 2025-05-29 12:17:54 -07:00
kade-github f16b8630ff
Revert "assets submod" 2025-05-29 12:09:21 -07:00
kade-github 1c747657d2 master switch for submod 2025-05-29 10:51:59 -07:00
fabs 924f72f96c assets submod 2025-05-29 10:51:59 -07:00
Hundrec 26dc895a27 Fix chart editor playbar ms display 2025-05-29 00:12:19 -04:00
Hyper_ 58257f6ac1 fix: Cleanup on LatencyState not being performed when closed/destroyed by state switch 2025-05-28 23:21:40 -04:00
CrusherNotDrip b52c73f2b0 Fix crash when mashing I or D on title state. 2025-05-28 23:14:43 -04:00
Lasercar 564d679f96 fix: Fixes a bug where you open the user guide in the stage editor multiple times 2025-05-28 23:04:48 -04:00
Lasercar 5695bc20e7 Cancel state change on debug menu 2025-05-28 22:57:56 -04:00
charlesisfeline 3dc7699aac silly typo... 2025-05-28 21:24:42 -04:00
MoonDroid dc60c12963 fix: properly reset variables and checks for capsule clicks 2025-05-29 08:17:10 +07:00
MoonDroid 6b63884e38 Merge remote-tracking branch 'origin/rewrite/master' into feature/bandaid-memory 2025-05-29 08:10:54 +07:00
MoonDroid 4eff23a6f2 chore: update compression-excludes.txt with additional exclusions
Some of these if compressed will benefit us with nothing but app size increase.
2025-05-29 08:03:49 +07:00
MoonDroid d8db5f7d88 refactor: optimize clearFreeplay() to improve cleanup of freeplay assets 2025-05-29 08:01:49 +07:00
MoonDroid 23d31ff73b feat: add clearStickers() to clean sticker data from memory, alongside purging cache in StickerSubState 2025-05-29 08:01:15 +07:00
MoonDroid a89351f083 feat: add null safety to FunkinMemory class for improved stability 2025-05-29 07:53:38 +07:00
MoonDroid fb3277ea35 fix: update memory management during state transitions 2025-05-29 07:33:47 +07:00
MoonDroid 71cadd31ed Change block size value from 4x4 to 12x12 2025-05-29 07:03:51 +07:00
Eric 1bd281830e
Merge pull request #1051 from FunkinCrew/kade-github/fixup
fix a fuck up by me (sorry)
2025-05-28 19:53:59 -04:00
kade-github 751f569e69
Merge branch 'merge-from-public' into kade-github/fixup 2025-05-28 16:48:46 -07:00
kade-github c363a53f9d
Revert "Merge public commits to MAIN and DEVELOP (#1045)"
This reverts commit d61cc1d5be.
2025-05-28 16:46:04 -07:00
EliteMasterEric fc83685b0f Remove a bunch of deprecation warnings 2025-05-28 16:33:10 -07:00
MoonDroid 25e04cf061 Fix private access errors and remove iOS compiler block 2025-05-28 16:24:57 -07:00
MAJigsaw77 8965bb059e fix: ensure admob doesnt stop the audio session on iOS. 2025-05-28 16:24:57 -07:00
Eric d61cc1d5be
Merge public commits to MAIN and DEVELOP (#1045)
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: Lasercar <64717068+Lasercar@users.noreply.github.com>
Co-authored-by: Hundrec <hundrecard@gmail.com>
Co-authored-by: Lasercar <B_l_u_t_a_c_k@hotmail.com.au>
Co-authored-by: anysad <anysadiscool@gmail.com>
Co-authored-by: VioletSnowLeopard <ngzeretzke@gmail.com>
Co-authored-by: unknown <47027981+ACrazyTown@users.noreply.github.com>
Co-authored-by: kade-github <26305836+Kade-github@users.noreply.github.com>
Co-authored-by: JackXson-Real <32755192+JackXson-Real@users.noreply.github.com>
Co-authored-by: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
Co-authored-by: CrusherNotDrip <90648119+CrusherNotDrip@users.noreply.github.com>
Co-authored-by: cyn0x8 <cyn0x8+git@gmail.com>
Co-authored-by: ChillyBeanBAM <109490279+ChillyBeanBAM@users.noreply.github.com>
2025-05-28 16:06:35 -07:00
MoonDroid 45bcb93c21 Invert capsule difficulty drag to the correct values. 2025-05-28 22:14:37 +07:00
EliteMasterEric 2e8338a5dc Merge remote-tracking branch 'public/develop' into merge-from-public 2025-05-27 16:13:23 -04:00
EliteMasterEric cb43dd34b4 Merge remote-tracking branch 'public/main' into rewrite/master 2025-05-27 16:11:39 -04:00
Hyper_ 83216e171c Remove unnecessary Tracy frame mark
This is already done by OpenFL
2025-05-26 17:46:36 -03:00
Eric 3b55c5b15f
Merge pull request #1039 from FunkinCrew/feature/unlock-everything
Make the flag `UNLOCK_EVERYTHING` work properly.
2025-05-26 01:59:10 -04:00
MoonDroid d4ef73fb93
Merge branch 'rewrite/master' into feature/unlock-everything 2025-05-25 09:34:15 +07:00
MoonDroid 7f924cd563 fix(mobile): Made freeplay scrolling more consistent and less buggy when dragging diagonally. 2025-05-23 16:00:06 -04:00
MoonDroid bbfbce6404 Update lime and astc-compressor refs 2025-05-23 15:42:18 -04:00
KarimAkra 91e9d5d55c Fixed the dark bar being missing (small) on the boyfriend backing card 2025-05-23 15:17:27 -04:00
Kade 6ec380e699
Merge pull request #1026 from FunkinCrew/flick-math 2025-05-22 13:20:37 -07:00
MoonDroid d311a16459 Merge remote-tracking branch 'origin/rewrite/master' into flick-math 2025-05-22 19:09:51 +07:00
MoonDroid a5b4a7d2cc Make UNLOCK_EVERYTHING work properly with songs. 2025-05-22 16:55:51 +07:00
MAJigsaw77 59a2b4ce6f hmm: update hxvlc and androidtools to fix some issues. 2025-05-20 21:23:12 -07:00
sector-a 5788d04890 Prevent stacked amplitude from not working and fix hold note end vibration 2025-05-20 10:34:56 -07:00
sector-a 30e9b2fb67 Improve the way note vibrations are handled and tweak hold note vibrations 2025-05-20 10:34:56 -07:00
MoonDroid a60560e36c fix: ensure draggingDifficulty is set correctly during swipe interactions 2025-05-20 10:34:33 -07:00
MoonDroid 511fd88ee9 fix: replace #if mobile with #if FEATURE_TOUCH_CONTROLS for clarity and consistency 2025-05-20 10:34:33 -07:00
MoonDroid a73ba04706 feat(mobile): improve touch interaction with granular state tracking and enhanced flick scrolling
- Added detailed touch state tracking to improve drag and selection behavior in FreeplayState
- Enhanced capsule scrolling with better flick handling for smoother touch device interaction
2025-05-20 10:34:33 -07:00
MoonDroid 17f614ea06 refactor: replace FlxSprite with FlxObject for touch hitboxes 2025-05-20 10:34:33 -07:00
MoonDroid 29143505cc chore: clean up unused and reorder imports in FreeplayState 2025-05-20 10:34:33 -07:00
MAJigsaw77 c462a5f8d0 videos: initialize hxvlc's handle early for faster loading speeds. 2025-05-20 10:32:54 -07:00
MAJigsaw77 0d5fd4a0c5 hmm: update hxvlc to 2.2.0. 2025-05-20 10:32:54 -07:00
mint 54547e7dd1 ci-checkout v7.3.3 2025-05-16 10:34:21 -04:00
mint 4b58cd0812 v7.3 of actions/checkout :3 2025-05-16 10:34:21 -04:00
mint dd809e0455 get more debug info out of ci-checkout 2025-05-16 10:34:21 -04:00
mint 22d2b95e7f test new submodule alias feature in funkin:actions/checkout 2025-05-16 10:34:21 -04:00
mint 310c074d78 ci: update checkout action 2025-05-16 10:34:21 -04:00
Cameron Taylor 94f1720870 accomodate notch positioning for different orientations 2025-05-12 14:13:20 -04:00
Cameron Taylor 4f3f43d6e7 tidy(iOS): rename some variables in ScreenUtil.hx 2025-05-12 14:13:20 -04:00
Cameron Taylor 6689ae9e9d fix(iOS): fix the notch size math on iOS 2025-05-12 14:13:20 -04:00
Cameron Taylor 8e7ddc0f53 bump lime to latest from lime-mobile/main 2025-05-12 14:13:20 -04:00
Cameron Taylor fda719ae7b reorganize hmm alphabetically (automatically done by hmm) 2025-05-12 14:13:20 -04:00
MoonDroid 666b57a1cb Increase scroll camera's height to account for bigger screens. 2025-05-12 12:52:24 -04:00
Abnormal a413318782 chore: Format the project.hxp file 2025-05-11 18:43:45 -05:00
MoonDroid 6289dfdd02 Adjust touch movement scaling in FreeplayState
New flixel ref has DPI Scaling for flicks, and added DPI scaling to freeplay's scroll too.
2025-05-12 06:24:13 +07:00
Abnormal c77e164513
NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
Co-authored-by: Hundrec <hundrecard@gmail.com>
2025-05-11 20:23:33 +00:00
Abnormal d2acb5d167 fix: Fix the game crashing when hot reloading with F5 2025-05-11 15:13:27 -05:00
MoonDroid adfd73d6ab Enhance touch controls by adding capsule hitbox and updating hit detection logic 2025-05-10 10:21:25 -07:00
MAJigsaw77 728558b279 Update extension-haptics. 2025-05-10 10:19:53 -07:00
MAJigsaw77 d104e3381b Update extension-iapcore. 2025-05-10 10:19:53 -07:00
MAJigsaw77 14e8e1f42f Update extension-androidtools. 2025-05-10 10:19:53 -07:00
MAJigsaw77 24e535c90a Update extension-admob. 2025-05-10 10:19:53 -07:00
Cameron Taylor cbff9a3719 freeplay momentum scrolling on mobile 2025-05-09 22:58:06 -04:00
kade-github 9a3e58a7d4 lock sync for static man 2025-05-09 12:55:10 -04:00
sector-a c8a86d3df8 Add the pressAction method in TouchUtil and use it everywhere it's useful 2025-05-09 12:54:45 -04:00
Eric 44c32cb0fc
More public 0.6.4 fixes (#1016)
Co-authored-by: Hyper_ <40342021+NotHyper-474@users.noreply.github.com>
Co-authored-by: Lasercar <64717068+Lasercar@users.noreply.github.com>
Co-authored-by: Lasercar <B_l_u_t_a_c_k@hotmail.com.au>
Co-authored-by: anysad <anysadiscool@gmail.com>
Co-authored-by: Hundrec <hundrecard@gmail.com>
Co-authored-by: VioletSnowLeopard <ngzeretzke@gmail.com>
Co-authored-by: unknown <47027981+ACrazyTown@users.noreply.github.com>
Co-authored-by: kade-github <26305836+Kade-github@users.noreply.github.com>
Co-authored-by: Abnormal <86753001+AbnormalPoof@users.noreply.github.com>
Co-authored-by: CrusherNotDrip <90648119+CrusherNotDrip@users.noreply.github.com>
Co-authored-by: cyn0x8 <cyn0x8+git@gmail.com>
2025-05-08 10:28:39 -07:00
Cameron Taylor 35f7113091 assets submod 2025-05-06 18:09:16 -04:00
MAJigsaw77 83d198493c Implement IAP on iOS.
Co-Authored-By: MoonDroid <zdgzackda@gmail.com>
2025-05-06 18:08:26 -04:00
MAJigsaw77 cd71102f8d Update hxcpp ref. 2025-05-06 18:08:26 -04:00
KarimAkra 283d7c0971 Fixed wide screen cap making the game position look off
Co-Authored-By: luckydog7 <59097731+luckydog7@users.noreply.github.com>
2025-05-06 18:08:26 -04:00
sector-a e9b1d5fc04 Make downscroll unavailable if Arrows scheme is selected 2025-05-06 18:08:26 -04:00
sector-a 13a2b192b9 Add available to menu items 2025-05-06 18:08:26 -04:00
sector-a 27b1cd32b7 fix wrong class path 2025-05-06 18:08:26 -04:00
KarimAkra fffea09270 Chore: rename Desktop with Native in places where the stuff apply for both Mobile & Desktop 2025-05-06 18:08:26 -04:00
KarimAkra d3705042cf Use NO_TESTING_ADS instead of !TESTING_ADS 2025-05-06 18:08:26 -04:00
KarimAkra f9b0acb998 these aren't needed actually 2025-05-06 18:08:26 -04:00
KarimAkra 377626c279 minimum SDK is supposed to be 28? 2025-05-06 18:08:26 -04:00
KarimAkra b536619773 silly me! 2025-05-06 18:08:26 -04:00
KarimAkra b189518383 update assets for 2hot cutscene pause button pos fix 2025-05-06 18:08:26 -04:00
KarimAkra f6569907c8 delete this old unused scrapped hag 2025-05-06 18:08:26 -04:00
KarimAkra a34cbaf87f Made FunkinBackspace automatically take android's back button as a back action
so now on Android you can use the phone's back button instead of always having to press the button in game!
2025-05-06 18:08:26 -04:00
KarimAkra ec5a736be6 move the DPad control scheme by the notch & give it tweens 2025-05-06 18:08:26 -04:00
MoonDroid 00b54150a4 Adjust target position calculations for fullscreen scaling in SongMenuItem. 2025-05-06 18:08:26 -04:00
MoonDroid b0c3c020e0 Fix an issue where the songs dont refresh when you change the difficulty through capsule. 2025-05-06 18:08:26 -04:00
KarimAkra 045b240949 Automated the ASTC textures compression process to be in build time 2025-05-06 18:08:26 -04:00
KarimAkra b84b531a2c Fixed VSync getting automatically enabled on focus lost/gained in Mobile 2025-05-06 18:08:26 -04:00
KarimAkra fc78eeee4f Fixed un-indexed freeplay scrolling with touch 2025-05-06 18:08:26 -04:00
KarimAkra 910500ea26 fixed the astc textures excludes 2025-05-06 18:08:26 -04:00
KarimAkra 3dc693f8b6 not unofficial anymore !! 2025-05-06 18:08:26 -04:00
KarimAkra a7b4f3d420 Format project.hxp 2025-05-06 18:08:26 -04:00
sector-a c992180f7c Fix capsules behavior in freeplay being a little bit weird 2025-05-06 18:08:26 -04:00
sector-a b0468fa056 Set target android SDK version in Project.hxp 2025-05-06 18:08:26 -04:00
sector-a c026c104f5 Fix Strumline for the Arrows controls scheme 2025-05-06 18:08:26 -04:00
sector-a 353f1780d1 Added nullSafety back in MusicBeat(Sub)State and fixed the errors 2025-05-06 18:08:26 -04:00
Cameron Taylor c648a5dbf2 art submod (macos code notarize script 2025-05-06 18:02:40 -04:00
Cameron Taylor 2777ec03a4 add team id for iOS compiling 2025-05-05 23:06:42 -07:00
Cameron Taylor 86ead7096e tidy(preloader): remove old progressBar code (i believe this was a solid progress bar, we use pieces now 2025-05-05 23:05:47 -07:00
Cameron Taylor bdb8857d5c tidy(preloader): remove unused site lock things, unplanned feature 2025-05-05 23:05:47 -07:00
Cameron Taylor 2325317902 tidy(preloader): guard clause readability change for updateProgressLeftText() 2025-05-05 23:05:47 -07:00
Cameron Taylor adb74b4539 tidy(preloader): cleanup relating to displaying current status. We get the string info from our enum abstract instead 2025-05-05 23:05:47 -07:00
Cameron Taylor f737ce6ed3 tidy(preloader): remove some old preloader code relating to logo 2025-05-05 23:05:47 -07:00
Eric a2e647ac8b
Merge pull request #984 from FunkinCrew/funkin-mobile/main
The BIG Mobile branch
2025-05-01 22:06:08 -04:00
EliteMasterEric c823bba3d1 Fix some merge conflict issues 2025-05-01 22:03:50 -04:00
EliteMasterEric e917da0a7b Merge branch 'rewrite/master' into funkin-mobile/main 2025-05-01 21:46:20 -04:00
EliteMasterEric 8de74c361c Additional cleanup 2025-05-01 19:55:44 -04:00
MoonDroid 6c842fea20 Make widescreen not mobile only.
Fix a typo in Main too.
Reposositon
2025-05-02 00:26:59 +07:00
MoonDroid 41ce874595 Update Android setup docs. 2025-05-01 23:27:05 +07:00
MoonDroid 9216fff9b0 Move InAppPurchasesUtil and AdMobUtil to funkin/api/mobile 2025-05-01 23:24:51 +07:00
EliteMasterEric 0253df7269 Feature flag cleanup 2025-04-30 00:31:31 -04:00
EliteMasterEric 40f44ece5b Dependency cleanup 2025-04-30 00:30:51 -04:00
KarimAkra 49114c5d37 Merge branch 'funkin-mobile/main' of github.com:FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-29 19:02:21 +03:00
MoonDroid 9b8330ced1 Merge branch 'funkin-mobile/main' of https://github.com/FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-29 22:33:14 +07:00
MoonDroid 1baf7fea80 Update mobile compiling guide with detailed setup instructions for Android on Windows and macOS 2025-04-29 22:33:02 +07:00
KarimAkra 588eea019d fixed memory counter position 2025-04-29 17:06:55 +03:00
KarimAkra 9307f514fe Added safety checks for ASTC textures 2025-04-29 17:05:20 +03:00
sector-a e6df6d5116 Temporarily remove nullSafety in two classes 2025-04-29 04:13:25 +03:00
sector-a d82d231539 Set minimal android sdk version through Project.hxp 2025-04-29 03:56:09 +03:00
EliteMasterEric 0d7c78305d Split up the compiling guide for mobile into its own file to keep things organized (may need additional proofreading) 2025-04-28 14:09:40 -04:00
EliteMasterEric e71bd1f5a4 Remove outdated unused chart docs 2025-04-28 14:09:13 -04:00
EliteMasterEric 7e62782fa1 Merge branch 'rewrite/master' into funkin-mobile/main 2025-04-28 13:49:40 -04:00
KarimAkra 7fe621a839 Small implementation to ASTC textures 2025-04-27 14:33:34 +03:00
Karim Akra 7dc4bb940c
Set screen metrics for launch storyboard 2025-04-27 04:09:12 +03:00
sector-a 5279aefec9 Assets ref 2025-04-21 18:46:18 +03:00
KarimAkra b541c5d974 disable DPI awareness as it causes issues 2025-04-21 01:11:17 +03:00
KarimAkra 4d77d21b15 Refactor menus UI positioning for notch size to look cleaner 2025-04-21 01:10:37 +03:00
KarimAkra 7f19faabc4 Merge branch 'funkin-mobile/main' of github.com:FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-20 22:09:59 +03:00
KarimAkra 2ba225265f Apply a custom LaunchScreen.storyboard for iOS
This makes the app use a proper logcal resolution (point per pixel res, not native idk why & i hate iOS)
2025-04-20 22:09:56 +03:00
MoonDroid 10d58c26b0 Merge branch 'funkin-mobile/main' of https://github.com/FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-20 21:09:16 +07:00
MoonDroid e0e660f357 Update art ref. 2025-04-20 21:09:11 +07:00
MAJigsaw77 647b69bb0c Use gradients on labels. 2025-04-20 10:42:31 +03:00
MAJigsaw77 94cd22e243 Follow the notch possition on CreditsState. 2025-04-20 10:41:09 +03:00
MAJigsaw77 324ef37505 Follow the notch possition on StoryMenuState. 2025-04-20 10:40:44 +03:00
MAJigsaw77 3cc189869b Some formatting on InAppPurchasesUtil. 2025-04-20 10:39:47 +03:00
MAJigsaw77 cc7def5178 Somewhat finished the IAP implementation. 2025-04-20 00:39:14 +03:00
sector-a 842d1a72a4 DialogueBox tweaks for fullscreen 2025-04-19 23:11:58 +03:00
KarimAkra 3d52aab7a3 Use correct path for the .env file for iOS 2025-04-19 12:26:39 +03:00
KarimAkra f3b20dbbd3 properly calculate gameNotchSize and gameNotchPosition 2025-04-19 12:24:12 +03:00
KarimAkra a54bf9c7fd Merge branch 'funkin-mobile/main' of github.com:FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-19 12:21:35 +03:00
KarimAkra 2ae503cfec Properly define openfl_dpi_aware in Project.hxp 2025-04-19 12:21:31 +03:00
MoonDroid b8db4947d6 Merge branch 'funkin-mobile/main' of https://github.com/FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-19 16:09:36 +07:00
MoonDroid 53794ab4cc Fix compiling for desktop platforms by adding missing conditionals in some classes. 2025-04-19 16:09:19 +07:00
MoonDroid 804984b8c1 Add conditional path for DATA_FILE_BASE_PATH for iOS. 2025-04-19 16:08:30 +07:00
MoonDroid 63ec721aa1 Fix notch calculation for iOS. 2025-04-19 16:06:57 +07:00
MAJigsaw77 0444d47458 Dont add the fpsCounter on Main.
I think this was a left over?
2025-04-18 23:44:42 +03:00
MAJigsaw77 2ac0627063 Update extensions on hmm.json. 2025-04-18 18:28:36 +03:00
MAJigsaw77 b755ed8d98 Implement extension-iapcore and testing for it. 2025-04-18 18:28:09 +03:00
KarimAkra 64126a3df5 fixed StickerSubState import on PauseSubState 2025-04-18 17:08:46 +03:00
KarimAkra e78d3ecf8f remove VSync option from mobile 2025-04-18 14:47:56 +03:00
KarimAkra c246de1ee1 these workflows shouldn't be here 2025-04-18 14:43:03 +03:00
KarimAkra a7ef5580a4 Merge branch 'rewrite/master' of github.com:FunkinCrew/Funkin-secret into funkin-mobile/main 2025-04-18 14:41:20 +03:00
KarimAkra f961b1cae2 update assets submodule 2025-04-18 14:38:14 +03:00
KarimAkra 827066b589 Added extension-haptics, extension-admob and extension-androidtools to hmm.json 2025-04-18 14:35:11 +03:00
KarimAkra 1dfe8866ab Don't touch the flixel soundtray on mobile targets
FlxG.game.soundTray stays null on mobile targets
2025-04-18 14:34:32 +03:00
sector-a 14cf382192 Update assets 2025-04-17 21:34:02 +03:00
sector-a 1f22313b8a Force downscroll mode for Arrows controls scheme 2025-04-17 21:33:58 +03:00
sector-a e359dad1e8 Remove option item for HitboxShowcase 2025-04-17 21:07:44 +03:00
sector-a 4d88df2120 Don't create Launch in Fullscreen preference item on mobile 2025-04-17 20:37:43 +03:00
sector-a 1c11a7003f Fix controls scheme menu 2025-04-17 20:23:13 +03:00
sector-a 2932c24418 Add UNLOCK_EVERYTHING for testing purpose 2025-04-17 20:04:05 +03:00
sector-a bb46b699eb Prevent SoundTray crash and Update Assets 2025-04-17 19:53:11 +03:00
sector-a dc000b33eb Add FEATURE_HAPTICS 2025-04-17 19:51:36 +03:00
MoonDroid 75d8101030 Comment this out temporarily until we fix up flixel. 2025-04-17 21:53:12 +07:00
MoonDroid 90fb8a1883 Fix black screen bug in StoryMenuState. 2025-04-17 21:52:51 +07:00
MoonDroid 50baf0c869 Fix idling difficulty position in FreeplayState. 2025-04-17 21:52:51 +07:00
MoonDroid 9e133b0a8a Fix a lil typo from the project file. 2025-04-17 20:27:44 +07:00
KarimAkra da3f5a48c9 Updated assets submodule 2025-04-17 16:20:59 +03:00
KarimAkra 36d361aa22 fixed the admob app id env being incorrect lol 2025-04-17 16:14:59 +03:00
KarimAkra b6e31e581a Fixed building errors 2025-04-17 14:51:33 +03:00
KarimAkra 5dd26101f2 Added environment config for getting android keystore & admob IDs 2025-04-17 14:22:45 +03:00
MoonDroid 81c92fc11f Fix a bug with freeplay's difficulty swiping where it freezes the capsule. 2025-04-17 13:16:23 +03:00
MoonDroid 44e166d411 Turn off non-exempt encryption config for iOS 2025-04-17 13:16:06 +03:00
KarimAkra 5b8b943b99 allow changing difficulty on story mode by swiping left and right 2025-04-17 13:15:06 +03:00
MoonDroid c9138e4d1f Small clean up to the new code in Freeplay. 2025-04-17 13:14:40 +03:00
MoonDroid 2bfc24f22b Add the ability to swipe on the mp3 capsules to change difficulty. 2025-04-17 13:14:16 +03:00
MoonDroid ebb9d373c3 Refactor handleInput() into smaller neater functions, and add an extra difficulty check to avoid swipe issues. 2025-04-17 13:13:54 +03:00
sector-a fc2e28ab18 Adjust strumline background for Arrows scheme 2025-04-17 13:12:41 +03:00
sector-a b4f30c341e Fix strumline background 2025-04-17 13:12:18 +03:00
sector-a 995f6c5adb Do not create screenshot options if FEATURE_SCREENSHOTS is disabled 2025-04-17 13:11:57 +03:00
Karim Akra 7dee8e6e54 Give bundles a designated gradle project folder for building 2025-04-17 13:10:11 +03:00
sector-a bcdbe2993c Fix selection in Freeplay 2025-04-17 13:09:57 +03:00
sector-a 8bf14b7d0c Scale the dialogue box and speaker on fullscreen 2025-04-17 13:09:44 +03:00
sector-a 261a237934 Fix difficulty stars position 2025-04-17 13:09:09 +03:00
KarimAkra ede705987c Possibly fixed notch calculation for iOS 2025-04-17 13:08:27 +03:00
MAJigsaw77 edfcfc8c55 Disable screenshots for mobile platforms 2025-04-17 13:08:07 +03:00
MoonDroid 828de1c512 Add grpDifficulty back to freeplay. 2025-04-17 13:06:01 +03:00
MoonDroid 85e77486f7 Properly fixed the strumline crash and visual bugs for mobile. 2025-04-17 13:06:01 +03:00
MoonDroid 50f467c366 Temporary crash fix for strumlines on mobile. 2025-04-17 13:03:27 +03:00
MAJigsaw77 97f8de0de4 Fixed notch position with createPrefItemEnum. 2025-04-17 13:03:27 +03:00
Karim Akra dfa8e635f1 Use pad delivery assets on bundles only 2025-04-17 13:03:27 +03:00
sector-a ed5b7fbb31 Do not initialize NewgroundsMedalPlugin if newgrounds feature is disabled 2025-04-17 13:03:27 +03:00
sector-a 418f7d71f9 Small fixes 2025-04-17 13:03:27 +03:00
sector-a 7111492578 Don't make it inline 2025-04-17 13:03:27 +03:00
sector-a baaaaddead Small fix 2025-04-17 13:03:27 +03:00
sector-a c2956cd253 Put newgrounds related code in a define 2025-04-17 13:03:27 +03:00
sector-a 999557b501 Add private access to get funnyCam 2025-04-17 13:03:27 +03:00
sector-a 73914c6858 Don't build credentials if newgrounds feature is disabled 2025-04-17 13:03:27 +03:00
sector-a 4976a099af Fix FunkinHitbox 2025-04-17 13:03:27 +03:00
sector-a ec5f8344ed Put onEventLogged under a define 2025-04-17 13:03:26 +03:00
sector-a 219c46f56b Fix an import path 2025-04-17 13:03:26 +03:00
sector-a 4f5b0f2453 Put newground imports in Events class under a define 2025-04-17 13:03:26 +03:00
sector-a 0d2c48c374 Don't enable newgrounds API features on mobile 2025-04-17 13:03:01 +03:00
MAJigsaw77 359e40bf4d Add lerping to the fps & memory counters reposition. 2025-04-17 12:56:58 +03:00
MAJigsaw77 bd39e2023c Change the duration and ampl of the sticker vibration. 2025-04-17 12:55:56 +03:00
MAJigsaw77 809f4107ab Fix hitbox's hint's label tweening. 2025-04-17 12:55:43 +03:00
MAJigsaw77 e838fef8e6 Update to extension-haptics and update extension-admob aswell. 2025-04-17 12:55:12 +03:00
MoonDroid 2c5c66286a Move admob interstitial trigger from transition to targetState switching in ResultState. 2025-04-17 12:54:10 +03:00
MoonDroid a64f7aa5d3 Fix bundling gradle error for android. 2025-04-17 12:53:07 +03:00
MoonDroid 5ca22a6910 Fix options menu hitboxes 2025-04-17 12:52:19 +03:00
MAJigsaw77 bed90dc230 Add InAppPurchasesUtil. 2025-04-17 12:50:25 +03:00
sector-a ff144cf30b Fix a typo in options desc 2025-04-17 12:49:17 +03:00
MoonDroid 58468abba7 Slightly push the album art and title upwards to fix the overlapping issue with the back button on mobile. 2025-04-17 12:46:45 +03:00
MAJigsaw77 5d26f8b433 Move the banner to top-left and fix some offsets inside the pause menu. 2025-04-17 12:46:10 +03:00
sector-a b68ba97ca6 Add tween out for backbutton in freeplay when the menu gets closed. 2025-04-17 12:44:30 +03:00
sector-a ba449cabd6 Added vibrations to the sticker transition 2025-04-17 12:44:07 +03:00
MoonDroid 61f1bdd89a Refactor the new flick and scroll code for mobile, aswell as fix a few unnoticable bugs. 2025-04-17 12:43:23 +03:00
MoonDroid 6d6441de6f Tweak hitbox values for the default control scheme on mobile. 2025-04-17 12:43:15 +03:00
MoonDroid f7f502dd92 Tweak scrolling values for mobile & fix flick wrapping for mobile in Freeplay. 2025-04-17 12:42:50 +03:00
zackdroidcoder 6133087c2c Remove project file's attempt at signing, add noalpha icons for iOS 2025-04-17 12:41:26 +03:00
zacksgamerz 4226ba8978 Work in progress sketch for new flicks and scrolls on freeplay 2025-04-17 12:40:21 +03:00
Karim Akra b012096151 Update signing method 2025-04-17 12:39:20 +03:00
KarimAkra 39313be86b revert things i accidentally comitted 2025-04-17 12:38:15 +03:00
Mihai Alexandru b1986fb9c5 Fix boundingBoxColor nullSafety. 2025-04-17 12:36:28 +03:00
KarimAkra 4d74ccbc4e add a -test compile flag 2025-04-17 12:36:12 +03:00
KarimAkra bef3815901 Fixed freeplay highlight and selection 2025-04-17 12:34:17 +03:00
KarimAkra 37fa11fe08 revamp songs selection and highlight on freeplay 2025-04-17 12:34:17 +03:00
KarimAkra e8d3fa8a35 simplfy the un-indexed freeplay scrolling logic 2025-04-17 12:34:17 +03:00
KarimAkra 0a0789faea Fixed selection 2025-04-17 12:32:28 +03:00
KarimAkra 5d6e44d5f1 Un-index freeplay
that's experimental
there's a weird bug when selecting a song where it confirms instead of selecting for some reason
2025-04-17 12:26:10 +03:00
zacksgamerz 7119d6a476 Tune the size of the hitboxes, strums, and incoming notes to be slighlty bigger. 2025-04-17 12:24:45 +03:00
sector-a 1093dd3400 Make pico playable haptics also work for dark and christmas versions 2025-04-17 12:24:29 +03:00
MAJigsaw77 c7906edc1e Some things
* Fixed some other checkstyle issues.
* The controls schemes options menu now shows the hitboxes without a gradient to look better.
* Attempted to rewrite the tweeing system on the FunkinHint, needs more looking.
2025-04-17 12:22:56 +03:00
sector-a 3fcc2cc5bc Add unique haptics for each game over animation 2025-04-17 12:22:56 +03:00
MAJigsaw77 34f97e3e3e One lined tweens for the bg. 2025-04-17 12:22:56 +03:00
Mihai Alexandru e0fcd655e7 Change the pointers for iOS at ScreenUtil 2025-04-17 12:22:32 +03:00
MAJigsaw77 b1089958c7 Tween the bg color to gray when entering demo mode. 2025-04-17 12:20:40 +03:00
MAJigsaw77 ea2b63b1bb Updated some stuff
* Fixed some check-style warnings
* Merged polygon button and normal button together
* Updated `funkin.haptic` ref.
* Simplified `getNotchRect` for `iOS`.
2025-04-17 12:19:24 +03:00
MAJigsaw77 7fb5d8c65c Fixed a checkstyle issue with admob util. 2025-04-17 12:15:10 +03:00
MAJigsaw77 86f8cb76f2 Simplified some logic in the admob util. 2025-04-17 12:14:55 +03:00
sector-a b03eef01ca Add sharpness for vibrations (iOS only) 2025-04-17 12:13:47 +03:00
sector-a 5d7517b839 Fix sustain notes vibrations for pixel notes 2025-04-17 12:08:23 +03:00
sector-a 1790c13fac Changed vibration at rank tally animation end in results screen 2025-04-17 12:08:13 +03:00
sector-a 180ec17ce3 Prevent sustained vibrations not ending 2025-04-17 12:07:59 +03:00
KarimAkra 5a39439fcc Align the pause button with the notch 2025-04-17 12:07:17 +03:00
sector-a 2f6e6ef7cd Bound hitbox showcases x axis on dragging 2025-04-17 12:07:03 +03:00
KarimAkra 75e0992509 Fixed notch rect on ios platforms (??) 2025-04-17 12:06:50 +03:00
KarimAkra 67f0425e89 Fixed the result screen scroll text not being aligned properly on notched displays 2025-04-17 12:06:43 +03:00
sector-a 3a084accc9 Force amplitude to be bigger on iOS 2025-04-17 12:06:01 +03:00
zacksgamerz 31c96bc6a1 Added mobile compiler flag for the size change. 2025-04-17 12:04:09 +03:00
zacksgamerz f439624404 Scaled down the size of the incomming notes for the player for the default control scheme. 2025-04-17 12:03:58 +03:00
zacksgamerz 0b2bb3391c Fix the difficulty sprites not showing up in Freeplay. 2025-04-17 12:03:52 +03:00
zacksgamerz ffee837bcd Fixed flooring mistake for haptics in pico's freeplay.
What happens if you floor 0.3? it returns ZERO :D
2025-04-17 12:03:42 +03:00
zacksgamerz e4733f9a5c Tune the size for the player strumline a tiny bit. 2025-04-17 12:03:32 +03:00
Mihai Alexandru 4dcaae5786 Add iap extension in da repo. 2025-04-17 12:03:16 +03:00
sector-a 8fa6809723 Add vibration for locked selection in Character Select menu 2025-04-17 01:04:17 +03:00
sector-a 6b3fb46ae5 Forgot some few vars 2025-04-17 01:03:58 +03:00
Mihai Alexandru d05a3519a3 Forgot to iInitialize funkin.haptic in InitState... 2025-04-17 01:03:36 +03:00
zacksgamerz 1a75c094b3 Refactored Tweening for TouchPointerPlugin, and added skipTween argument to removeAll() 2025-04-17 01:02:28 +03:00
zacksgamerz def86a44eb Refactored the middle offset code for the default control scheme, added amplification and increased it by 15 px. 2025-04-17 01:02:28 +03:00
zacksgamerz 3b3f4543b4 Increased player strumline size by 0.05 percent for the default control scheme. 2025-04-17 01:02:28 +03:00
zacksgamerz d92d3130c8 Fixed opponentStrumline wacky positioning. 2025-04-17 01:02:28 +03:00
zacksgamerz 01cc9f1ae4 Added aspect ratio amplification to opponent's strumline in default controls. 2025-04-17 01:02:28 +03:00
zacksgamerz 9775034d7a Add tapping to LetterSort for Freeplay. 2025-04-17 01:01:40 +03:00
Mihai Alexandru 824767af66 Replace the traditional lime Haptics with funkin.haptic
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-17 01:01:26 +03:00
Karim Akra 07818b84fd Added IOS signing place holder 2025-04-17 00:42:39 +03:00
sector-a ae4384453c Tweak freeplay scrolling vibrations a lil bit 2025-04-17 00:42:39 +03:00
sector-a a80e3df799 Add vibrateByPreset method for calling vibrations using VibrationPresets 2025-04-17 00:42:35 +03:00
sector-a 52929de50a Rework hitbox items scrolling in scheme menu 2025-04-17 00:40:30 +03:00
zacksgamerz b81ff3c136 Fixed an issue where the touch pointer would permanently persist after switching states. Re-arranged imports in TouchPointerPlugin. 2025-04-17 00:38:35 +03:00
zacksgamerz f11d7e8147 Disabled wrapping in Story Menu and fixed an unknown bug with the swipe threshold. 2025-04-17 00:38:23 +03:00
zacksgamerz 8f123e4ab9 Made it so you need to tap on LetterSort first so it would receive input. 2025-04-17 00:38:20 +03:00
zacksgamerz 25d27e62ce Refactored scroll up and down logic in Freeplay. 2025-04-17 00:37:32 +03:00
zacksgamerz b9230b6eb2 Add swipe gesture to back out in Freeplay. 2025-04-17 00:36:49 +03:00
KarimAkra 2236865f0f Remove the unused FullScreenScaleMode class 2025-04-17 00:33:23 +03:00
KarimAkra e197b7325a Fixed the Preferences Menu options not aligning correctly on notched displays 2025-04-17 00:33:07 +03:00
KarimAkra 6080cd5bf3 Fixed the freeplay rating stars flames position to align properly with the notch 2025-04-17 00:32:53 +03:00
zacksgamerz ef35ba759e Added pointer fade out to each individual touch pointer. Changed the color of the touch pointer and added a "screen" blendmode. 2025-04-17 00:32:29 +03:00
zacksgamerz f246fa2e6c Fix tween cancellation and update flick direction logic in FreeplayState. 2025-04-17 00:32:17 +03:00
Karim Akra 2973b65c69 Check for resolution validity on desktop only 2025-04-17 00:31:51 +03:00
zacksgamerz f6ee1c8f92 Cancel existing tweens for difficulty groups before starting a new tween in FreeplayState. 2025-04-17 00:31:19 +03:00
zacksgamerz 3389eaef96 Changed justSwiped to swipe in StoryMenuState. 2025-04-17 00:31:19 +03:00
zacksgamerz 86d050a11f Refactor swipe threshold calculation to use SwipeUtil across multiple states. 2025-04-17 00:31:19 +03:00
Mihai Alexandru 5c0de03a74 Adjust the preferences options x to follow the cutout. 2025-04-17 00:31:18 +03:00
zacksgamerz afe0087591 Invert flicks for a hotfix. 2025-04-17 00:30:33 +03:00
KarimAkra 616004d7f6 move FullScreenScaleMode from flixel.system.scaleModes to funkin.ui 2025-04-17 00:29:45 +03:00
Karim Akra 854f62ba54 Use correct arguments for aspect ratio validity check 2025-04-17 00:28:11 +03:00
zacksgamerz 7374986c05 Fix aspect ratio validation by using gameHeight instead of gameWidth 2025-04-17 00:28:11 +03:00
KarimAkra 6a064dc7f7 Fixed an issue with the game looking off on invalid aspect ratios 2025-04-17 00:28:11 +03:00
KarimAkra d9bc989b91 Fixed notch rectangle calculations for iOS (??) 2025-04-17 00:28:11 +03:00
zacksgamerz 7bd6e09dcf Slightly adjust the hitbox's width for the default control scheme on mobile. 2025-04-17 00:28:11 +03:00
zacksgamerz 45986f34c1 Adjust note hitbox calculations for mobile to be more wide-screen friendly. 2025-04-17 00:27:30 +03:00
Mihai Alexandru 3386d62951 Video Playback Optimization. 2025-04-17 00:27:13 +03:00
zacksgamerz 85330f73a1 Small readability tuning for initNoteHitbox in PlayState. 2025-04-17 00:26:46 +03:00
zacksgamerz 318e73a030 Fixed a small typo in playstate. 2025-04-17 00:26:20 +03:00
zacksgamerz 62acfd8365 Add TODO comment to address touch pointer positioning issue in PlayState 2025-04-17 00:25:56 +03:00
zacksgamerz cbc3b6c0b5 Enhance documentation and reorganize imports for the TouchPointerPlugin class 2025-04-17 00:25:56 +03:00
zacksgamerz 3e71f12871 Remove unused strength calculation in HapticUtil 2025-04-17 00:25:56 +03:00
zacksgamerz 1a28e48434 Adjust hitbox dimensions for the default mobile controls scheme. 2025-04-17 00:25:56 +03:00
zacksgamerz d57409ca20 Character Select Menu Fixed the issue where it instantly selects the item when you first tap into it. 2025-04-17 00:25:56 +03:00
zacksgamerz 195e3082df Remove gamepad rumble in HapticUtil since it got reverted in openfl & flixel. 2025-04-16 23:42:51 +03:00
KarimAkra 27adb17a38 Fixed the null object refrence in AttractState on mobile platforms 2025-04-16 23:41:55 +03:00
sector-a 85f3f4b047 Bound currentIndex in Controls Scheme Menu for targets with touch support 2025-04-16 23:41:53 +03:00
sector-a 16f8678d0f Bound currentEntry in Pause SubState for targets with touch support 2025-04-16 23:41:18 +03:00
sector-a 64877bc999 Rename MobileControlsSchemeMenu to ControlsSchemeMenu 2025-04-16 23:41:11 +03:00
Mihai Alexandru 6b2572c176 Disable logging for AdMobUtil. 2025-04-16 23:38:58 +03:00
zacksgamerz 7a747993e7 Fixed issues with pixel notes' hitboxes on the default control scheme, adjusted positioning and scaled down the size even further. 2025-04-16 23:32:22 +03:00
Mihai Alexandru 5d2bd38f72 Attempt to implement controller rumble to HapticUtil
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-16 23:31:49 +03:00
Mihai Alexandru 1e40568ca9 Fixed minor issues in AdMobUtil 2025-04-16 23:25:13 +03:00
KarimAkra 51b82a0a7c Fixed minor issues with swipes and Pointer Plugin 2025-04-16 16:07:59 +03:00
sector-a 6c2ff099da Uncomment swipeThreshold.set() calls 2025-04-16 16:05:53 +03:00
KarimAkra 8119dcca8e Fixed a tiny mistake in TouchPointerPlugin to make it use the instance variable 2025-04-16 16:05:43 +03:00
KarimAkra a289fb7f54 Fixed common issues with the Pointer Plugin 2025-04-16 16:05:20 +03:00
zacksgamerz 6f9b8f0284 Add TouchPointerPlugin integration and update pointer group initialization 2025-04-16 16:04:58 +03:00
zacksgamerz 46d10ede43 Comment out pointer group addition and fix variable assignments in TouchPointer 2025-04-16 16:04:38 +03:00
zacksgamerz 16884ba28e Implement TouchPointerPlugin and remove old legacy TouchPointer code. 2025-04-16 16:04:22 +03:00
KarimAkra c636024f75 Fixed pausing in PlayState when fake cutouts are present. 2025-04-16 15:59:28 +03:00
KarimAkra a4207c1020 Allow skipping the video after holding the screen for 1.5 seconds with touch 2025-04-16 15:56:44 +03:00
KarimAkra a2c2b8d9dd Fixed the FPS counter position and removed skipping with touch from AttractState 2025-04-16 15:54:38 +03:00
KarimAkra c466e1aa12 Refactor positioning of FPS and memory counters for mobile 2025-04-16 15:51:27 +03:00
KarimAkra 3bdd7b20b0 Added fake cutouts functions 2025-04-16 15:49:40 +03:00
Mihai Alexandru 5b4ed6e726 Use untyped on width/height setter.
Also simplified something.
2025-04-16 15:44:31 +03:00
luckydog7 96ce6086e1 Implementing the maximum aspect ratio 2025-04-16 15:38:12 +03:00
sector-a 0e256021b1 Made note vibrations weaker, removed HAPTIC_VIBRATIONS define, moved vibration option from mobileOptions to options 2025-04-16 15:29:26 +03:00
zacksgamerz 18dcb8f446 Replaced all old flick checks, swipe checks, etc. with the proper checks from Flixel. Updated flixel ref. Removed justFlicked checks as they are unused.
Replace swipeThreshold updates with the one in FlxTouchManager

Temporarily remove swipeThreshold sets for testing.

Proper SwipeUtil refactoring. Completely replaced all flick and movement checks with the one in Flixel. Rewrote most of the documentation to be more accurate.

Invert flick checks as it already comes inverted from FlxFlick.

Define fixes for SwipeUtil

Fixed null safety issues on compiling.
2025-04-16 15:22:10 +03:00
sector-a ca391c6e32 Add Sustain Note vibration 2025-04-16 15:15:15 +03:00
sector-a 5ae73361b0 Move noteVibrations variable to Strumline and Add Sustain note splash vibration 2025-04-16 15:15:15 +03:00
sector-a 4cee6a9d56 Make Note Vibrations stacked amplitude work as intended 2025-04-16 15:15:15 +03:00
KarimAkra c3ed2019b5 Change System.allowScreenTimeout on state/substate destroy instead of close 2025-04-16 15:10:46 +03:00
KarimAkra 6720f7f9ca one shall stand one shall fall 2025-04-16 15:07:36 +03:00
KarimAkra 6b090542f1 added some args that are missing from the FunkinHitbox hitbox constructor 2025-04-16 15:06:20 +03:00
KarimAkra eb3022a0fc Oopsie 2025-04-16 15:06:20 +03:00
KarimAkra ea9938a318 rename DISABLE_ADMOB_ADS to FEATURE_ADMOB_ADS 2025-04-16 15:06:07 +03:00
zacksgamerz f17b9d234c Scale down the strumline size visually but increase the hitbox to be bigger for the default control scheme. Added double note overlap. 2025-04-16 15:03:07 +03:00
zacksgamerz 5b9bd1af00 Removw justMoved check as it makes confirming the selected song significantly harder. 2025-04-16 15:00:52 +03:00
zacksgamerz 9d48a04564 Fixed issue where you can't confirm your selection by tapping the icons in the character select menu. 2025-04-16 15:00:52 +03:00
sector-a f970ea6acf Move TouchUtil and SwipeUtil to funkin.util 2025-04-16 15:00:02 +03:00
sector-a 8b1b81a925 Add mobile support to Latency State 2025-04-16 14:57:33 +03:00
sector-a 2d8a493897 Add directionsOverride and colorsOverride to FunkinHitbox 2025-04-16 14:57:33 +03:00
zacksgamerz 3bcb63cb84 Made minor changes to the overlap checks in CharSelectSubState, and added another way for the player to accept by tapping on the character. Replaced FlxSprite hitboxes with FlxObject. 2025-04-16 14:56:44 +03:00
zacksgamerz 0d35b66903 Refactored the drag difficulty checks in Freeplay to be more clean and readable. 2025-04-16 14:56:15 +03:00
zacksgamerz db84186627 Made intuitive swipe controls for LetterSort. 2025-04-16 14:55:26 +03:00
sector-a e3e98dc057 Note vibrations with stackable amplitude 2025-04-16 14:54:31 +03:00
sector-a 5d70cdbeb2 scheme menu fixes for widescreen 2025-04-16 14:37:10 +03:00
KarimAkra 3e75701c1c Adjust Arrows control scheme notes sizes for easier reading & pressing
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-16 14:35:28 +03:00
KarimAkra 0fc5b84237 Implement Google Play Asset Delivery, Added some flags & refactored bundle system
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
2025-04-16 14:29:08 +03:00
KarimAkra f23a6a8ac8 Adjust notes scale & spacing for Arrows control scheme
Co-Authored-By: luckydog7 <59097731+luckydog7@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-16 13:52:00 +03:00
sector-a 4b797d3526 allow input offset on mobile and gameover input delay 2025-04-16 13:39:04 +03:00
KarimAkra 82a9dabc7f Added ability to swipe on difficulties to change them on FreeplayState
Co-Authored-By: Karim Akra <144803230+karimakra@users.noreply.github.com>
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-04-16 13:21:16 +03:00
sector-a 3f7ae02d54 Scheme menu and its components code refactor 2025-04-16 13:05:35 +03:00
KarimAkra e9b1800ec9 Improves HapticUtil's code a bit
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: Karim Akra <144803230+karimakra@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-16 00:22:56 +03:00
sector-a bee846ec8c Rename NoteDPad controls scheme to Arrows
my bad
2025-04-16 00:09:46 +03:00
KarimAkra e5f3223e76 Refactor FullScreenScaleMode
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: Karim Akra <144803230+karimakra@users.noreply.github.com>
2025-04-15 23:50:40 +03:00
KarimAkra d80afc35b4 Fixed a few issues with touch controls & flicks
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-04-15 23:39:17 +03:00
KarimAkra 5c9d76791b Added a FeatureFlag to build an Android App Bundle (.AAB)
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
2025-04-15 23:23:08 +03:00
KarimAkra 2a6720da2e Added a new "Note DPad" control scheme
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
Co-Authored-By: luckydog7 <59097731+luckydog7@users.noreply.github.com>
2025-04-15 22:54:00 +03:00
KarimAkra 068747b01a Optimized Memory Usage & Added FunkinMemory
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-04-15 22:20:01 +03:00
sector-a 4962d55b22 hide hitbox if game is paused
forgot something!!!!
2025-04-15 21:37:29 +03:00
KarimAkra 66e6ea9d41 Fixed few issues with extension-admob implementation
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
2025-04-15 21:37:22 +03:00
KarimAkra d43dfac3e4 Added vibrations to most ResultState ranks and more!
* Vibrations for most ranks
* Vibrations when scrolling through FreeplayState
* Vibrations for notes hits
* Vibrations for game over

Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:37:14 +03:00
KarimAkra 9cf134fc2a Made more menus adapted to wide-screens & fixed some bugs
* Made stuff on the edge of the screen get moved away by the notch
* Made FreeplayState look better on wide-screens
* Adapted StoryMenuState to wide-screens
* Fixed the transition being small on some screen sizes
* refactored some code
2025-04-15 21:37:06 +03:00
KarimAkra 7b1abe437f Add proper configuration for AdMob ads
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
Co-Authored-By: Lily <egzozu.be.bas@gmail.com>
2025-04-15 21:37:00 +03:00
KarimAkra 193d293dea Added HapticUtil and some vibrations to some menus & scenes!
Added vibrations to:

* TitleState on beat hits during into
* Freeplay when a new rank is slammed to the capsule
* Some vibrations on ResultState (such as when the tally counter increases...)

Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:36:54 +03:00
sector-a 530ca0d929 play video ad after results screen instead of in it 2025-04-15 21:36:49 +03:00
sector-a c99778266b Scheme Menu is basically done! 2025-04-15 21:36:43 +03:00
KarimAkra 2680b064fe Blacklist admob from Polymod HScript 2025-04-15 21:36:37 +03:00
KarimAkra 9dc48978f8 Massive Touch Controls Overhaul
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>

This overhaul includes:

* Flicks on menus
* Changing options by sliding the finger over screen
* Changing options by pressing the option itself
* Touch Pointers
* And more!

Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:36:28 +03:00
KarimAkra f6a261e5bd Adjusted back button position on Scheme Menu
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:36:19 +03:00
KarimAkra a707472270 Got a functional Scheme Menu for mobile
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:36:12 +03:00
KarimAkra 7babcfaf6b Implement extension-admob for mobile ads
forgor that

videos and fixed banner size

make this a define

keep thes demo units when using TESTING_ADS only

always enable it on debug builds (?)

Update AdMobUtil.hx

admob features

Update PlayState.hx

Update AdMobUtil.hx

Update AdMobUtil.hx

Show privacy options form if required.

Update Main.hx

Update Main.hx

Update PlayState.hx

Update AdMobUtil.hx

Update AdMobUtil.hx

Update AdMobUtil.hx

Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
2025-04-15 21:36:05 +03:00
KarimAkra 1b2f75395f Added a missing import in FunkinButton
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
2025-04-15 21:35:57 +03:00
sector-a 8704666edb some back button fixes! 2025-04-15 21:35:48 +03:00
KarimAkra 66683c11a0 Fixed a bug with circle buttons overlap check (last time I swear)
that's better ig
2025-04-15 21:35:41 +03:00
KarimAkra 5d624fe1b9 Attempt to add native code for obtaining notch size on iOS
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: Lily <egzozu.be.bas@gmail.com>
2025-04-15 21:35:35 +03:00
KarimAkra c4bb161865 Fixed a bug with circle buttons overlap 2025-04-15 21:35:28 +03:00
KarimAkra b1b30ed09f Formatted some code for freeplay & fixed strumlines position on wide-screens 2025-04-15 21:35:19 +03:00
sector-a f5ffdbe82d Scheme menu rework (unfinished) 2025-04-15 21:34:44 +03:00
KarimAkra ad4b1ce51b Adjusted freeplay to work on wide-screens
fixed some backing cards and the capsule ranking position
2025-04-15 21:34:00 +03:00
KarimAkra 9657b7eb72 Add proper overlap and input check for circle buttons scheme
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
2025-04-15 21:33:50 +03:00
Mihai Alexandru 381bc6521c Fix an issue with FunkinButton overlap checks
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
2025-04-15 21:33:41 +03:00
KarimAkra 8a60bc26b5 Experimental full screen scale mode for mobile 2025-04-15 21:33:32 +03:00
KarimAkra a732d27e93 Fix the background text of ResultState going off of FlxGame bounds 2025-04-15 21:33:18 +03:00
KarimAkra 944141292d Move part of the code from the old repository
Co-Authored-By: sector-a <82838084+sector-a@users.noreply.github.com>
Co-Authored-By: mcagabe19 <egzozu.be.bas@gmail.com>
Co-Authored-By: Mihai Alexandru <77043862+majigsaw77@users.noreply.github.com>
Co-Authored-By: MoonDroid <81515012+moondroidcoder@users.noreply.github.com>
Co-Authored-By: luckydog7 <59097731+luckydog7@users.noreply.github.com>
2025-04-15 21:32:39 +03:00
347 changed files with 20807 additions and 7386 deletions

View file

@ -25,6 +25,8 @@ body:
- Itch.io (Downloadable Build) - Windows
- Itch.io (Downloadable Build) - MacOS
- Itch.io (Downloadable Build) - Linux
- Google Playstore - Android
- App Store - iOS
- Compiled from GitHub Source Code
validations:
required: true

View file

@ -1,3 +1,6 @@
# Builds the game on all platforms, to ensure it compiles on all target platforms.
# This helps to ensure workers focus on the master branch.
name: Build and Upload nightly game builds
on:
@ -21,7 +24,7 @@ jobs:
trigger-build: ${{ steps.should-trigger.outputs.result }}
steps:
- name: Checkout repo
uses: funkincrew/ci-checkout@v6
uses: funkincrew/ci-checkout@v7.3.3
with:
submodules: false
- uses: dorny/paths-filter@v3
@ -93,7 +96,7 @@ jobs:
packages: write
steps:
- name: Checkout repo
uses: funkincrew/ci-checkout@v6
uses: funkincrew/ci-checkout@v7.3.3
with:
submodules: false
- name: Log into GitHub Container Registry
@ -125,6 +128,9 @@ jobs:
runs-on: windows
- target: macos
runs-on: macos
# TODO: Install XCode to build iOS
# - target: ios
# runs-on: macos
runs-on:
- ${{ matrix.runs-on }}
defaults:
@ -144,11 +150,14 @@ jobs:
private-key: ${{ secrets.APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout repo
uses: funkincrew/ci-checkout@v6
uses: funkincrew/ci-checkout@v7.3.3
with:
submodules: 'recursive'
token: ${{ steps.app_token.outputs.token }}
persist-credentials: false
submodule-aliases: |
https://github.com/FunkinCrew/Funkin.assets > https://github.com/FunkinCrew/Funkin-assets-secret
https://github.com/FunkinCrew/Funkin.art > https://github.com/FunkinCrew/Funkin-art-secret
- name: Setup build environment
uses: ./.github/actions/setup-haxe
with:
@ -190,6 +199,7 @@ jobs:
include:
- target: linux
- target: html5
# - target: android
defaults:
run:
shell: bash
@ -204,11 +214,14 @@ jobs:
private-key: ${{ secrets.APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout repo
uses: funkincrew/ci-checkout@v6
uses: funkincrew/ci-checkout@v7.3.3
with:
submodules: 'recursive'
token: ${{ steps.app_token.outputs.token }}
persist-credentials: false
submodule-aliases: |
https://github.com/FunkinCrew/Funkin.assets > https://github.com/FunkinCrew/Funkin-assets-secret
https://github.com/FunkinCrew/Funkin.art > https://github.com/FunkinCrew/Funkin-art-secret
- name: Config haxelib
run: |
haxelib --never newrepo

View file

@ -1,3 +1,6 @@
# When a pull request is merged, cancel all queued workflows for that branch
# This helps to ensure workers focus on the master branch.
name: Cancel queued workflows on PR merge
on:
@ -23,7 +26,7 @@ jobs:
let branch_workflows = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: "build-shit.yml",
workflow_id: "build-game.yml",
status: "queued",
branch: "${{ github.event.pull_request.head.ref }}"
});

View file

@ -1,5 +1,6 @@
# Perform actions when labels are applied to issues, discussions, or pull requests
# See .github/label-actions.yml
name: 'Label Actions'
on:

View file

@ -1,9 +1,13 @@
# Applies the following labels to pull requests when created:
# - status: pending triage
name: "Pull Request Labeler 2 (Runs on PR creation)"
on:
pull_request_target:
types:
- opened
jobs:
# Apply `status: pending triage` to newly created pull requests
apply-pending-triage:

View file

@ -1,7 +1,19 @@
# Applies the following labels to pull requests whenver they are created or modified:
# - pr: documentation
# - pr: haxe
# - pr: github
# - size: tiny
# - size: small
# - size: medium
# - size: large
# - size: huge
# see .github/labeler.yml and .github/changed-lines-count-labeler.yml
name: "Pull Request Labeler"
on:
- pull_request_target
jobs:
# Apply labels to pull requests based on which files were edited
labeler:

9
.gitignore vendored
View file

@ -3,14 +3,21 @@
.vs/
APIStuff.hx
dump/
temp/
docs/temp/
export/
project/
astc-textures/
RECOVER_*.fla
shitAudio/
.build_time
.swp
NewgroundsCredentials.hx
# Mobile signing stuff
.apple/
.env
key.keystore
# Exclude JS stuff
node_modules/
package.json

66
.vscode/schema/hmm.json vendored Normal file
View file

@ -0,0 +1,66 @@
{
"type": "object",
"properties": {
"dependencies": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"description": "The name of the Haxe library"
},
"type": {
"title": "Type",
"type": "string",
"description": "one of haxelib, git, hg, or dev",
"enum": ["haxelib", "git", "hg", "dev"]
},
"ref": {
"type": "string",
"description": "the git/hg ref (branch, commit, tag, etc.)"
},
"url": {
"title": "URL",
"type": "string",
"description": "the git/hg URL"
},
"version": {
"title": "Version",
"type": "string",
"description": "the haxelib library version. Must be in SemVer format (MAJOR.MINOR.PATCH)",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
}
},
"required": ["name", "type"],
"dependentSchemas": {
"type": {
"if": {
"properties": {
"type": {
"const": "git"
}
}
},
"then": {
"required": ["url"]
},
"else": {
"if": {
"properties": {
"type": {
"const": "haxelib"
}
}
},
"then": {
"required": ["version"]
}
}
}
}
}
}
}
}

25
.vscode/settings.json vendored
View file

@ -90,6 +90,8 @@
"haxecheckstyle.configurationFile": "checkstyle.json",
"haxecheckstyle.codeSimilarityBufferSize": 100,
"lime.projectFile": "project.hxp",
"lime.targetConfigurations": [
{
"label": "Windows / Debug (Discord)",
@ -150,6 +152,16 @@
"target": "windows",
"args": ["-debug", "-DRESULTS"]
},
{
"label": "Windows / Debug (Straight to Stage Editor)",
"target": "windows",
"args": ["-debug", "-DSTAGING", "-DFEATURE_DEBUG_FUNCTIONS"]
},
{
"label": "Windows / Debug (Straight to Stage Builder)",
"target": "windows",
"args": ["-debug", "-DSTAGEBUILD", "-DFEATURE_DEBUG_FUNCTIONS"]
},
{
"label": "Windows / Debug (Straight to Animation Editor)",
"target": "windows",
@ -158,7 +170,7 @@
{
"label": "Windows / Debug (Debug hxvlc)",
"target": "windows",
"args": ["-debug", "-DHXC_LIBVLC_LOGGING", "-DFEATURE_DEBUG_FUNCTIONS"]
"args": ["-debug", "-DHXVLC_LOGGING", "-DFEATURE_DEBUG_FUNCTIONS"]
},
{
"label": "HashLink / Debug (Straight to Animation Editor)",
@ -201,6 +213,10 @@
"label": "Debug",
"args": ["-debug", "-DFEATURE_DEBUG_FUNCTIONS"]
},
{
"label": "Debug (Unlock Everything)",
"args": ["-debug", "-DUNLOCK_EVERYTHING"]
},
{
"label": "Debug (Tracy)",
"args": ["-debug", "-DFEATURE_DEBUG_TRACY", "-DFEATURE_DEBUG_FUNCTIONS"]
@ -225,5 +241,12 @@
"coverage.xml",
"jacoco.xml",
"coverage.cobertura.xml"
],
"vscord.app.privacyMode.enable": true,
"json.schemas": [
{
"fileMatch": ["/hmm.json"],
"url": "./.vscode/schema/hmm.json"
}
]
}

View file

@ -4,6 +4,303 @@ All notable changes will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.7.3] - 2025-07-21
### Fixed
- Fixed stuttering throughout the game caused by the Polymod upgrade. (Thanks NotHyper-474!)
- [MOBILE] Fixed buttons in the Main Menu not working.
- [iOS] The Upgrade button no longer appears if you have already purchased it (actually this time).
- Fixed the countdown overlapping itself when restarting the song. (Thanks NotHyper-474!)
- Optimized the Week 6 Erect stage.
- Fixed an oversight when clearing the cache. (Thanks cherrythecool!)
- The Input Offset Test menu text now displays in the correct position.
- Fixed script errors appearing in the Week 3 Erect stage.
- Fixed adding variations in the Chart Editor erasing difficulties. (Thanks NotHyper-474!)
## New Contributors for 0.7.3
* @cherrythecool made their first contribution in [#5458](https://github.com/FunkinCrew/Funkin/pull/5458)
## [0.7.2] - 2025-07-18
### Added
- [ANDROID] Added a button in the Options menu to access the mods folder.
- [MOBILE] Added a preference to adjust the intensity of haptic feedback, ranging from 0.1 to 5.
- [MOBILE] Added an easter egg when tapping the player's healthbar icon.
### Changed
- Changed default OpenAL configuration settings to improve audio quality. (Thanks Smokey555, cyn0x8, and CCobaltDev!)
- The difference may be more or less noticeable on different devices and hardware.
- Applies to Desktop and Android, but not iOS yet.
- Made several improvements to Polymod and HScript. These changes might break some mods, so please update them accordingly!
- Fixed an issue where scripted classes can define two or more fields with the same name.
- Fixed an issue causing some syntax errors (such as missing commas) to be ignored by the parser.
- Scripted classes can now create static fields and functions.
- Scripted classes can now create variables with the `final` keyword.
- Scripted classes can now access variables from another scripted class with `class.someVariable`, instead of `class.scriptGet("someVariable")`
- This applies to functions too: `class.someFunction()`
- Scripted classes that don't extend another class can now be created!
- This only works if you access the class in a static context. Creating an instance of said class doesn't work just yet!
- Added support for properties (`get_` and `set_` functions) (Thanks KoloInDaCrib!)
- Added support for abstracts in a static context. (Thanks lemz1!)
- You can now use classes like `FlxColor` properly!
- Added support for creating and using enums. (Thanks lemz1!)
- You can import them in another script as usual.
- Added support for renaming imported classes using the `as` keyword. (Thanks KoloInDaCrib!)
- Fixed `try`/`catch` blocks not working properly. (Thanks NotHyper-474!)
- Fixed null-safe field access not working properly for functions (ex. `class?.someFunction()). (Thanks KoloInDaCrib!)
### Fixed
- [MOBILE] Weekend 1 Story Mode no longer crashes before loading into Blazin'.
- [MOBILE] Beating 2hot from Freeplay no longer crashes in the Results screen.
- [MOBILE] Retrying and pressing the Back button at the same time no longer crashes the game.
- [MOBILE] Pressing the Options and Back buttons at the same time no longer softlocks the game.
- [HTML5] Pausing while the train passes by on the Week 3 Erect stage no longer crashes.
- [DESKTOP] Getting a Bad/Shit rating on Blazin' no longer breaks animations.
- The scroll sound no longer plays once after entering Freeplay.
- The Freeplay song preview and album cover now update properly when switching variations.
- The Freeplay clear percent counter now consistently displays the correct value on unranked songs.
- The Freeplay difficulty star flames no longer become offset from the stars.
- The Freeplay difficulty star flames no longer appear during a new rank animation.
- The Freeplay menu now correctly assigns the `currentCharacterId`. (Thanks TechnikTil!)
- Boyfriend's Perfect (Gold) Results animation now loops properly.
- [DESKTOP] The Input Offsets menu no longer activates the debug cursor.
- The Input Offsets Test menu no longer generates stacked notes.
- The Input Offsets Test menu drums no longer desync from the rest of the track.
- The Input Offsets Test menu no longer breaks when a keyboard or controller is connected.
- [MOBILE] Sustain trails now display properly with upscroll enabled.
- [MOBILE] Added a Back button to the keyboard/gamepad Controls menu.
- [iOS] Fixed app name spacing on the Home Screen.
- [iOS] Adjusted the preloader to accommodate for different screen sizes.
- [iOS] The Upgrade button no longer appears if you have already purchased it.
- [ANDROID] Fixed some issues with scrolling.
- [ANDROID] Toasts with blank messages no longer appear.
- Fixed a critical security vulnerability that could be exploited in mods.
- A few more bugfixes and optimizations here and there.
## New Contributors for 0.7.2
* @Smokey555 made their first contribution in [#3318](https://github.com/FunkinCrew/Funkin/pull/3318)
* @CCobaltDev made their first contribution in [#3318](https://github.com/FunkinCrew/Funkin/pull/3318)
## [0.7.1] - 2025-07-15
### Fixed
- Properly implemented ad playback on iOS devices.
## [0.7.0] - 2025-07-15
### Added
- Friday Night Funkin' now has OFFICIAL mobile versions for Android and iOS, available on the Google Play Store and Apple App Store!
- This version contains 100% of the songs from the desktop version of the game.
- [MOBILE] New touch input compatibility for all menus.
- [MOBILE] Added banner and interstitial advertisements to the game. You can upgrade to the full version through an in-app purchase to permanently disable advertisements.
- [MOBILE] Graphics are compressed using the ASTC algorithm, decreasing memory usage in exchange for a slightly larger file size.
- [MOBILE] Added haptic feedback to several areas of the game.
- Added a visual indicator that shows available difficulties for the currently selected song in Freeplay.
- Overhauled the input offsets system, including:
- One unified "offset" value.
- An "Offset Calibration" screen where the game determines your ideal offset.
- A "Test" screen where you can play a short note pattern to try out your offset.
- A brand new offset testing theme: Syncobation by Kawai Sprite!
- The ability to change your offsets in the Pause Menu, mid-song!
- The Input Offsets menu isn't yet available on HTML5, but offsets are still configurable through the Pause Menu.
- Added null-safety to a bunch of classes in the source code.
- Added the Changelog back to the game files, written by Hundrec and AbnormalPoof!
- Added a few sandboxed classes to give mods limited access to the Discord and Newgrounds APIs. ([50d9584](https://github.com/FunkinCrew/Funkin/commit/50d9584a388bd891aa2f8b68a5cde894a6e1ede6)) - by @KoloInDaCrib in [#5040](https://github.com/FunkinCrew/Funkin/pull/5040)
- Added script support for Freeplay Backing Cards. ([0001017](https://github.com/FunkinCrew/Funkin/commit/0001017c003be653236c6cc56487c7d0ee33633e)) - by @KoloInDaCrib in [#5233](https://github.com/FunkinCrew/Funkin/pull/5233)
- Sparrow results screen animations can now be scriptable. ([7bb2336](https://github.com/FunkinCrew/Funkin/commit/7bb23369727ca4955aa1fbe25e5798809e8169bd)) - by @KoloInDaCrib in [#5168](https://github.com/FunkinCrew/Funkin/pull/5168)
- Added a blank `Object` class for scripts to extend, and made `FlxObject` and `FlxBasic` scriptable. ([eb6becc](https://github.com/FunkinCrew/Funkin/commit/eb6becc03fff76117ee3fcbeb32fe254236ca232)) - by @cyn0x8 in [#3119](https://github.com/FunkinCrew/Funkin/pull/3119)
- Added default gamepad controls for two recently added Freeplay controls. ([a0d3f8e](https://github.com/FunkinCrew/Funkin/commit/a0d3f8ec553e06b625b463c7989658edbebbbdf5)) - by @MrMadera in [#4559](https://github.com/FunkinCrew/Funkin/pull/4559)
- Added the ability to press the Chart Editor keybind in Freeplay with a song capsule selected. ([2221594](https://github.com/FunkinCrew/Funkin/commit/2221594883afa7cd0e518fca7ea975d05626692a)) - by @Lasercar in [#4114](https://github.com/FunkinCrew/Funkin/pull/4114)
- The Chart Editor now highlights and deletes stacked notes using a customizable threshold. ([8cae34e](https://github.com/FunkinCrew/Funkin/commit/8cae34eed711bff70e5348ffc6178a0fd69b5846)) - by @NotHyper-474 in [#3574](https://github.com/FunkinCrew/Funkin/pull/3574)
- Added a variation indicator next to the Chart Editor playbar difficulty. ([ccd0148](https://github.com/FunkinCrew/Funkin/commit/ccd0148e9b46d512a22b4958d3f289cfc7854965)) - by @KoloInDaCrib in [#5236](https://github.com/FunkinCrew/Funkin/pull/5236)
- Added more tween types to certain Chart Editor events. ([5177e12](https://github.com/FunkinCrew/Funkin/commit/5177e1275eb2fb2b016224c139e84debb421b895)) - by @Lasercar in [#4249](https://github.com/FunkinCrew/Funkin/pull/4249)
- Pressing Ctrl + N now creates a new stage in the Stage Editor. ([576f8e5](https://github.com/FunkinCrew/Funkin/commit/576f8e54ff8ca8e205241fafa33d0256b62d11d5)) - by @Lasercar in [#5175](https://github.com/FunkinCrew/Funkin/pull/5175)
- Added "Flip character horizontally" to the list of shortcuts in the Animation Editor. ([c464cae](https://github.com/FunkinCrew/funkin.assets/commit/c464caec921dcefef7b0b74b2abf95e76ce64491)) - by @AbnormalPoof in [funkin.assets#60](https://github.com/FunkinCrew/funkin.assets/pull/60)
- Added Perfect (Gold) to the list of available ranks in Results Debug menu. ([c5308cc](https://github.com/FunkinCrew/Funkin/commit/c5308ccbb9d2b98c62fa4974b8ad7ac1e1ec7d19)) - by @AbnormalPoof in [#4642](https://github.com/FunkinCrew/Funkin/pull/4642)
- [MOBILE] Implemented Kevin and Michael.
### Changed
- The mod API version now supports v0.7.0, along with v0.6.3. Be sure to check that your mods still work!
- Updated the app icon for Desktop platforms.
- [MOBILE] Modified several parts of the game to look better on phone screens with wider aspect ratios, up to 20:9.
- [DESKTOP] The game now tries to match the window's aspect ratio when changing states, extending as wide as 20:9.
- [DESKTOP] Included Mobile stage expansions on Desktop as well. Now you'll have more room for camera events!
- Playable Pico and Weekend 1 songs are now always unlocked in Freeplay, even on new saves.
- The Freeplay difficulty graphic now scrolls smoothly when changing difficulties.
- The "Pause on Unfocus" preference now opens the Pause Menu when unfocusing during a song.
- Scripts can now make hold note trails semi-transparent.
- Completely reformatted every script file within the game's assets for better readability.
- Completely reformatted and optimized every single chart file in the game.
- Recharted pico-speaker's chart in Stress
- Tweaked charts for the following songs:
- Bopeebo [all difficulties] - Removed an extra hey animation event
- Bopeebo (Pico Mix) [Hard] - Added a missing note in Section 24
- Fresh Erect [Nightmare] - Added a missing grace note for BF in Section 24
- South Erect [Nightmare] - Added missing grace notes for BF in Sections 13, 17, and 53
- Philly Nice [Hard] - Added missing grace notes for Pico in Sections 30 and 62
- Philly Nice [all difficulties] - Added hey animations throughout the song
- Philly Nice Erect [Erect] - Added a grace note for BF in Section 33, removed a stacked note for opponent in Section 12
- Philly Nice (Pico Mix) [Normal] - Adjusted a left note by 1/96 in Section 60
- Blammed (Pico Mix) [Hard] - Added a missing jack in Section 46
- Satin Panties [Hard] - Added grace notes in Sections 7-10
- Satin Panties [Normal/Hard] - Made Mom sing a sustain rather than two notes in Section 30
- High Erect [Erect/Nightmare] - Added a missing note in Section 16
- Cocoa [Easy] - Added some notes to reduce sparseness, fixed Mom singing Dad's notes
- Cocoa Erect [Erect/Nightmare] - Reimplemented BF's censored notes for Nightmare, adjusted one note by 1/48 in Section 63
- Eggnog Erect [Erect/Nightmare] Added two grace notes in Sections 10 and 14 and a missing note for Dad in Section 44
- Eggnog (Pico Mix) [Hard] - Added a missing grace note for Pico that was present on Normal in Section 20
- Roses [Normal/Hard] - Made Senpai sing a sustain rather than two notes (sneaky)
- Roses Erect [Erect/Nightmare] - Mirrored the changes from normal Roses
- Guns [all difficulties] - Added a missing note in Sections 28 and 32 and adjusted a hold note's length in Section 73
- Stress [Hard] - Split whole notes in halves in Sections 57-60
- Darnell [Hard] - Added one missing note for Pico in Section 35
- Darnell [all difficulties] - Adjusted camera event timings for consistency
- Darnell (BF Mix) [all difficulties] - Removed 3 extra notes and fixed Darnell's pattern being offset
- Lit Up [all difficulties] - Added 4 sustains for Darnell throughout the song
- Lit Up (BF Mix) [all difficulties] - Added 4 sustains for Darnell throughout the song
- 2hot [Easy/Hard] - Fixed remaining offset rhythms (for real this time)
- Notes now scroll more smoothly by rendering based on delta timing. ([6ad9ffc](https://github.com/FunkinCrew/Funkin/commit/6ad9ffc7f9d66bbaf6ba343663de4c7268f4be3b)) - by @KutikiPlayz in [#3544](https://github.com/FunkinCrew/Funkin/pull/3544)
- The Freeplay character select hint now always displays if you have more than one character unlocked. ([7ccf75c](https://github.com/FunkinCrew/Funkin/commit/7ccf75cd869ba4b6f18a5adc01e65e52ae7bb809)) - by @Hundrec in [#5023](https://github.com/FunkinCrew/Funkin/pull/5023)
- Favorite songs in Freeplay are now sorted by Week order instead of alphabetically. ([da0964a](https://github.com/FunkinCrew/Funkin/commit/da0964a7b7bbe4ece1bdbd19233eb6dba0de3ac5)) - by @Hundrec in [#3609](https://github.com/FunkinCrew/Funkin/pull/3609)
- Shifted Mommy Mearest's pixel icon to the left in Freeplay. ([d861eba](https://github.com/FunkinCrew/funkin.assets/commit/d861ebac027dd07d0254c79d7c89b59ee04b38f1)) - by @KoloInDaCrib in [funkin.assets#197](https://github.com/FunkinCrew/funkin.assets/pull/197)
- The Character Select screen now opens on the currently selected character. ([4819a74](https://github.com/FunkinCrew/Funkin/commit/4819a74c2959cc9b32dfe2cb76c3a4c00e7c7f9a)) - by @Lasercar in [#4072](https://github.com/FunkinCrew/Funkin/pull/4072)
- Visualizers now zero out when the game audio is muted. ([6dcec59](https://github.com/FunkinCrew/Funkin/commit/6dcec592f467a0daeb8ff1e0ce122916e36ca869)) - by @Lasercar in [#5266](https://github.com/FunkinCrew/Funkin/pull/5266)
- The Options Menu can now scroll to display more menu items. ([70f0a54](https://github.com/FunkinCrew/Funkin/commit/70f0a54191597bd72a6d30d4d12ef5ece6ba078c)) - by @AbnormalPoof in [#4706](https://github.com/FunkinCrew/Funkin/pull/4706)
- Raised the FPS cap preference from 300 to 500. ([be73134](https://github.com/FunkinCrew/Funkin/commit/be7313453f70983fff55e69a8b52d741f0cc53b4)) - by @Hundrec in [#5044](https://github.com/FunkinCrew/Funkin/pull/5044)
- The Credits menu now uses less memory, especially with many entries. ([1b68c3a](https://github.com/FunkinCrew/Funkin/commit/1b68c3a8d6f66905a9a508a1cb692fe3beb7b4a2)) - by @lemz1 in [#2655](https://github.com/FunkinCrew/Funkin/pull/2655)
- Added a timer sequence class to queue up multiple timers in scripts with ease. ([9e182f7](https://github.com/FunkinCrew/Funkin/commit/9e182f70d2bcc92eb68d730d74af143c45f7dcf8)) - by @cyn0x8 in [#2391](https://github.com/FunkinCrew/Funkin/pull/2391)
- Replaced smoothLerp and coolLerp with smoothLerpPrecision to fix a few lerp-related bugs. ([94eae11](https://github.com/FunkinCrew/Funkin/commit/94eae116c7a5e6039683d6391208b169378b5ff1)) - by @cyn0x8 in [#3617](https://github.com/FunkinCrew/Funkin/pull/3617)
- Fixed empty text strings softlocking the dialogue box. ([88d0e8c](https://github.com/FunkinCrew/Funkin/commit/88d0e8c3b0529654fb7eee8aebb099f7fb346f66)) - by @xenkap in [#4671](https://github.com/FunkinCrew/Funkin/pull/4671)
- Adjusted the size of the Beat/Step display in the Chart Editor. ([905181c](https://github.com/FunkinCrew/Funkin/commit/905181c9af29bb11280bda33ef9343069678a762)) - by @NotHyper-474 in [#4994](https://github.com/FunkinCrew/Funkin/pull/4994)
- The Chart Editor will now only fall back to the first available difficulty if the selected difficulty cannot be found. ([1c25713](https://github.com/FunkinCrew/Funkin/commit/1c257134648ebd89acf6c9d07f5a0c088fb915c6)) - by @Lasercar in [#4949](https://github.com/FunkinCrew/Funkin/pull/4949)
- The undo/redo history is now cleared when loading another song in the Chart Editor. ([426a9c0](https://github.com/FunkinCrew/Funkin/commit/426a9c0c108ac65a042295194679d46444ec1ea5)) - by @Lasercar in [#4308](https://github.com/FunkinCrew/Funkin/pull/4308)
- Blacklisted more classes for security reasons. ([cadfa3b](https://github.com/FunkinCrew/Funkin/commit/cadfa3b7ceae2ecabe2d544ddc4c9f453b0dfd56)) - by @NotHyper-474 in [#5185](https://github.com/FunkinCrew/Funkin/pull/5185)
### Fixed
- Fixed a ton of performance issues to help the game run better on mobile devices.
- Exiting the Freeplay Menu no longer freezes the game for a really long time (thanks NotHyper-474!)
- Notestyle graphics are now preloaded before the song starts, fixing the stutter at the beginning of the song.
- Hitting many hold note trails in one song no longer leads to a lag spike.
- The first lightning strike in Week 2 Erect no longer creates a lag spike.
- [DESKTOP] The conductor and music no longer gradually drift out of sync to eventually trigger a resync.
- Pixel notestyle strumlines are now properly positioned when Downscroll is enabled.
- Added the missing graffiti to the wall in the Weekend 1 Blazin' stage.
- Accept keybinds now properly scroll faster through the Credits.
- Typing in most text fields in debug editors no longer triggers keyboard shortcuts.
- The Chart Editor playback speed feature now works properly.
- The Chart Editor metronome and hitsounds now play at exactly the right time.
- The Chart Editor notification box no longer covers playbar info.
- Selecting a Recent File too quickly in the Stage Editor no longer crashes the game.
- Blacklisted a few classes for security.
- Opening the logs or backups folder before it's created no longer crashes the game. ([d3490f8](https://github.com/FunkinCrew/Funkin/commit/d3490f8c9929eefb9879ad65ce43038c193642d6)) - by @NotHyper-474 in [#4940](https://github.com/FunkinCrew/Funkin/pull/4940)
- Fixed a crash when mashing D or I during startup. ([b52c73f](https://github.com/FunkinCrew/Funkin/commit/b52c73f2b0fa32fbc349804621cf947dff2d364e)) - by @CrusherNotDrip in [#5160](https://github.com/FunkinCrew/Funkin/pull/5160)
- Hot-reloading with F5 during gameplay no longer crashes the game. ([d2acb5d](https://github.com/FunkinCrew/Funkin/commit/d2acb5d167afd42299d7200ab8c67972044a09c6)) - by @AbnormalPoof in [#5065](https://github.com/FunkinCrew/Funkin/pull/5065)
- Hot-reloading with F5 in the Input Offsets menu no longer crashes the game. ([58257f6](https://github.com/FunkinCrew/Funkin/commit/58257f6ac187925f3b23d3f1eef2c812ae569a6b)) - by @NotHyper-474 in [#5085](https://github.com/FunkinCrew/Funkin/pull/5085)
- Songs no longer skip forward at the beginning with high offsets. ([1f75a64](https://github.com/FunkinCrew/Funkin/commit/1f75a641e0c80d15f1af10bae7ee71a6ffecf219)) - by @xenkap in [#3732](https://github.com/FunkinCrew/Funkin/pull/3732)
- The song countdown no longer stacks when restarting or continues behind the Pause Menu.
([63eca96](https://github.com/FunkinCrew/Funkin/commit/63eca96c98a87e7155df8b2a1735f269ea83e1b5)) - by @KoloInDaCrib and @NotHyper-474 in [#4875](https://github.com/FunkinCrew/Funkin/pull/4875)
- Fixed incorrect highlighting and squashed text on Freeplay song capsules. ([0c62428](https://github.com/FunkinCrew/Funkin/commit/0c62428fc883c0fa6d09cd403efb287ff3af8c53)) - by @VioletSnowLeopard in [#5036](https://github.com/FunkinCrew/Funkin/pull/5036)
- The Freeplay song preview no longer plays twice after returning from Character
Select. ([3d3e2bd](https://github.com/FunkinCrew/Funkin/commit/3d3e2bd3786b858143d214caf55be2ee3e9483fc)) - by @Lasercar in [#5248](https://github.com/FunkinCrew/Funkin/pull/5248)
- Freeplay song ranks no longer disappear after changing variations. ([7cc9464](https://github.com/FunkinCrew/Funkin/commit/7cc9464573d07996e4bd0d557f82847809d3a786)) - by @VioletSnowLeopard in [#4583](https://github.com/FunkinCrew/Funkin/pull/4583)
- Freeplay song capsules now cycle through long names consistently. ([e193f73](https://github.com/FunkinCrew/Funkin/commit/e193f7392a83a04e4aac85fba4f441a78f7b6668)) - by @VioletSnowLeopard in [#4677](https://github.com/FunkinCrew/Funkin/pull/4677)
- Fixed a few visual issues with Freeplay's rank slam animation. ([ab817bb](https://github.com/FunkinCrew/Funkin/commit/ab817bb1eab74ae71c1b1fd74d7512a11e6d4339)) - by @Lasercar in [#4986](https://github.com/FunkinCrew/Funkin/pull/4986)
- Fixed visual errors in Freeplay after exiting Character Select. ([56a18e1](https://github.com/FunkinCrew/Funkin/commit/56a18e1cf6a15971feebcc828be8818037948cef)) - by @KoloInDaCrib in [#5245](https://github.com/FunkinCrew/Funkin/pull/5245)
- Freeplay styles are now reloaded when hot-reloading with F5. ([f54e140](https://github.com/FunkinCrew/Funkin/commit/f54e140b65e36fcf810c52ce464799dbc0c73c6d)) - by @Keoiki in [#5286](https://github.com/FunkinCrew/Funkin/pull/5286)
- Adjusted offsets for Freeplay DJ Pico's fistPump animation. ([382e286](https://github.com/FunkinCrew/funkin.assets/commit/382e286a2478939d3d6aca1c7c90719f33815014)) - by @AbnormalPoof in [funkin.assets#91](https://github.com/FunkinCrew/funkin.assets/pull/91)
- The "New Highscore" text no longer appears more than once in the Results screen. ([4e31003](https://github.com/FunkinCrew/Funkin/commit/4e31003a0f60cd394edc2bd4586f9f385b3d07bc)) - by @Lasercar in [#4319](https://github.com/FunkinCrew/Funkin/pull/4319)
- The Results Debug menu now shows the correct rank after recent scoring changes. ([11d9998](https://github.com/FunkinCrew/Funkin/commit/11d9998e5c73a3839ea39e06b7f217cbaab69c6d)) - by @NotHyper-474 in [#4905](https://github.com/FunkinCrew/Funkin/pull/4905)
- The Input Offsets menu now exits to the Options menu instead of the Main menu. ([5361df2](https://github.com/FunkinCrew/Funkin/commit/5361df254470e68d7571b4534cf456f08d5ffd60)) - by @JackXson-Real in [#5076](https://github.com/FunkinCrew/Funkin/pull/5076)
- The Debug Menu can no longer be opened after selecting an item in the Main Menu.
([5695bc2](https://github.com/FunkinCrew/Funkin/commit/5695bc20e721f0afd5b97a36167f13e550c12b16)) - by @Lasercar in [#4211](https://github.com/FunkinCrew/Funkin/pull/4211)
- The debug cursor is now always hidden when the game starts. ([6222c38](https://github.com/FunkinCrew/Funkin/commit/6222c389e301fa2bb4939697376c4e51e29a9977)) - by @Hundrec in [#4520](https://github.com/FunkinCrew/Funkin/pull/4520)
- The Story Mode Weekend 1 level title no longer clips into other level titles below it. ([19d1a8c](https://github.com/FunkinCrew/Funkin/commit/19d1a8c59380009f0d0814c94fd0b4eccb0c80cd)) - by @KoloInDaCrib in [#4348](https://github.com/FunkinCrew/Funkin/pull/4348)
- Hold note covers now display properly if a hold note was previously dropped. ([96d1324](https://github.com/FunkinCrew/Funkin/commit/96d1324af140858cb93edd07dc36a969c8ae84c0)) - by @T5mpler in [#5275](https://github.com/FunkinCrew/Funkin/pull/5275)
- Girlfriend's and Nene's combo drop animations now play consistently. ([34d5ed1](https://github.com/FunkinCrew/Funkin/commit/34d5ed11695cef7348c13505f13fb1da38b7988c)) - by @VioletSnowLeopard in [#4968](https://github.com/FunkinCrew/Funkin/pull/4968)
- Girlfriend (Tankman Stickup) now plays her combo drop animation. ([e329601](https://github.com/FunkinCrew/funkin.assets/commit/e329601834f270910ce80ea5539e4487b9895a8a)) - by @qt2k4 in [funkin.assets#149](https://github.com/FunkinCrew/funkin.assets/pull/149)
- Darnell's idle animation now loops consistently. ([df64586](https://github.com/FunkinCrew/funkin.assets/commit/df64586771ea41c544913e049fd0f32bdc655417)) - by @qt2k4 in [funkin.assets#159](https://github.com/FunkinCrew/funkin.assets/pull/159)
- Darnell's kneeCan animation now plays properly in 2hot. ([a2e9931](https://github.com/FunkinCrew/funkin.assets/commit/a2e993167aaa2ff6bff8806940f912e444608645)) - by @biomseed in [funkin.assets#78](https://github.com/FunkinCrew/funkin.assets/pull/78)
- Otis and Pico (Speaker) no longer spaz out when playtesting Stress. ([3f6d75f](https://github.com/FunkinCrew/funkin.assets/commit/3f6d75f3b6f6c8deb660323e3fb9bf1974c06520)) - by @Lasercar in [funkin.assets#124](https://github.com/FunkinCrew/funkin.assets/pull/124)
- The gasp sound now only plays once in the Week 3 Pico Mix doppelganger cutscene. ([ab4598b](https://github.com/FunkinCrew/funkin.assets/commit/ab4598baf3c6790d30cfb727d04c8b57fa18dd0d)) - by @KoloInDaCrib in [funkin.assets#126](https://github.com/FunkinCrew/funkin.assets/pull/126)
- Fixed a few issues with the train in Week 3. ([8db2426](https://github.com/FunkinCrew/funkin.assets/commit/8db2426991caebde44d19c81b198e8e2ad86f700)) - by @ShadzXD in [funkin.assets#180](https://github.com/FunkinCrew/funkin.assets/pull/180)
- The cars in Week 4 and Weekend 1 no longer get stuck when the song is restarted. ([9c511e3](https://github.com/FunkinCrew/funkin.assets/commit/9c511e371fd08a43ddf834766a6d35667bdef4f7)) - by @MetaBreeze in [funkin.assets#186](https://github.com/FunkinCrew/funkin.assets/pull/186)
- A-Bot's visualizer no longer jumps to a random volume when the song ends. ([51cc118](https://github.com/FunkinCrew/funkin.assets/commit/51cc1186bc77a2ee45a47fdbde2d75d9ec69de3a)) - by @VioletSnowLeopard in [funkin.assets#183](https://github.com/FunkinCrew/funkin.assets/pull/183)
- Pico's burpShit animation now re-enables volume for player vocals. ([cefda0e](https://github.com/FunkinCrew/funkin.assets/commit/cefda0e52fabbbe04afe60b7aed560267e2cb01e)) - by @Hundrec in [funkin.assets#71](https://github.com/FunkinCrew/funkin.assets/pull/71)
- Removed vocals from Monster's instrumental on web builds. ([1c9473f](https://github.com/FunkinCrew/funkin.assets/commit/1c9473f3dfdfb97d97f6c8457001055322abf5ab)) - by @JVNpixels in [funkin.assets#182](https://github.com/FunkinCrew/funkin.assets/pull/182)
- Fixed the retry sound not playing after a Tankman death quote finishes. ([e7c4b1b](https://github.com/FunkinCrew/Funkin/commit/e7c4b1ba38ba0739cfe347f6c4763f9811fb95b0)) - by @VioletSnowLeopard in [#4726](https://github.com/FunkinCrew/Funkin/pull/4726)
- Darnell (BF Mix)'s alternate instrumental is now properly accessible. ([5abdabf](https://github.com/FunkinCrew/funkin.assets/commit/5abdabf69b39ca4eebd36ae6bbd77fab736d0b86)) - by @Hundrec in [funkin.assets#168](https://github.com/FunkinCrew/funkin.assets/pull/168)
- Fixed Newgrounds score submissions for Lit Up and Lit Up (BF Mix). ([183cec6](https://github.com/FunkinCrew/Funkin/commit/183cec62dc1fd3c7f3f634dd3e2400e6ee77b476)) - by @Raltyro in [#4577](https://github.com/FunkinCrew/Funkin/pull/4577)
- Inputs are now disabled before Senpai's dialogue appears. ([c43d906](https://github.com/FunkinCrew/funkin.assets/commit/c43d906d19d91d71b9096e65d5e0d3543af8cd31)) - by @anysad in [funkin.assets#165](https://github.com/FunkinCrew/funkin.assets/pull/165)
- An easter egg now restarts the song using the correct instrumental. ([e657bc9](https://github.com/FunkinCrew/Funkin/commit/e657bc900bc62cc220276dc171dd47f0a176ac66)) - by @KoloInDaCrib in [#4956](https://github.com/FunkinCrew/Funkin/pull/4956)
- Encountering an easter egg during a Chart Editor playtest no longer crashes the game. ([b53b5bd](https://github.com/FunkinCrew/funkin.assets/commit/b53b5bdaecf975555538725a4cdfe71d38565b08)) - by @NotHyper-474 in [funkin.assets#133](https://github.com/FunkinCrew/funkin.assets/pull/133)
- Nonexistent characters no longer crash the Chart Editor. ([3bbb4b0](https://github.com/FunkinCrew/Funkin/commit/3bbb4b06c8c1a1885a18d4354fcfa4363a0c6c75)) - by @Lasercar in [#5008](https://github.com/FunkinCrew/Funkin/pull/5008)
- Holding Ctrl and clicking on a hold note trail no longer crashes the Chart Editor. ([dc56cca](https://github.com/FunkinCrew/Funkin/commit/dc56ccada50e671996caf0557de1977b7ff8d236)) - by @Lasercar in [#4203](https://github.com/FunkinCrew/Funkin/pull/4203)
- Tweens and timers are now canceled when returning to the Chart Editor. ([7e76cf6](https://github.com/FunkinCrew/Funkin/commit/7e76cf66340c00ef6ec84358e6304d62815173b6)) - by @KoloInDaCrib in [#5278](https://github.com/FunkinCrew/Funkin/pull/5278)
- Reduced the severity of a memory leak in the Chart Editor. ([cce8c18](https://github.com/FunkinCrew/Funkin/commit/cce8c18822e083910200597f5db4d87b6e3b521f)) - by @NotHyper-474 in [#5247](https://github.com/FunkinCrew/Funkin/pull/5247)
- Pressing the Chart Editor keybind during a song now opens to the variation and difficulty you were playing. ([e3fca16](https://github.com/FunkinCrew/Funkin/commit/e3fca167938642bea85398fe57347c10439c1892)) - by @Lasercar in [#4116](https://github.com/FunkinCrew/Funkin/pull/4116)
- The Chart Editor now properly saves audio levels when exiting. ([f78ab4d](https://github.com/FunkinCrew/Funkin/commit/f78ab4da1db4f9527a2e1715d5cfb37670e11a74)) - by @Lasercar in [#4149](https://github.com/FunkinCrew/Funkin/pull/4149)
- The Chart Editor "Load Metadata File" and "Load Chart File" buttons now function properly. ([9df5395](https://github.com/FunkinCrew/Funkin/commit/9df5395ff888cb6740e21204c8e19116e0472db4)) - by @Lasercar in [#4278](https://github.com/FunkinCrew/Funkin/pull/4278)
- FNF Legacy files can now be opened in the Chart Editor on MacOS. ([d98628c](https://github.com/FunkinCrew/Funkin/commit/d98628ca0f9f60357715bd7f95fc686a83201209)) - by @AbnormalPoof in [#4580](https://github.com/FunkinCrew/Funkin/pull/4580)
- The Chart Editor now consistently displays the correct waveform for vocal tracks. ([c0e0523](https://github.com/FunkinCrew/Funkin/commit/c0e0523651e8aaaae2a0eed6d5fef6c5ef1b7315)) - by @NotHyper-474 in [#5231](https://github.com/FunkinCrew/Funkin/pull/5231)
- Fixed selection boxes duplicating in the Chart Editor. ([65ed583](https://github.com/FunkinCrew/Funkin/commit/65ed58350b798bca0044603510540cfe81b48611)) - by @NotHyper-474 in [#5073](https://github.com/FunkinCrew/Funkin/pull/5073)
- Fixed the Chart Editor timer occasionally displaying incorrect millisecond values. ([26dc895](https://github.com/FunkinCrew/Funkin/commit/26dc895a27e0d7e49469251cd68b83be66384e15)) - by @Hundrec in [#4257](https://github.com/FunkinCrew/Funkin/pull/4257)
- The Chart Editor playhead can no longer be scrolled to before the beginning of the song. ([7c7dc11](https://github.com/FunkinCrew/Funkin/commit/7c7dc11f18644882444df97ac927e11adaa4ce50)) - by @Hundrec in [#5024](https://github.com/FunkinCrew/Funkin/pull/5024)
- The Chart Editor playbar no longer extends past the right of the grid. ([c7abb19](https://github.com/FunkinCrew/Funkin/commit/c7abb196989476cfa4db6354cc6fac5bacb2e56a)) - by @anysad in [#5090](https://github.com/FunkinCrew/Funkin/pull/5090)
- Dragging a hold note in the Chart Editor now drags its trail along with its head. ([d3d8aaa](https://github.com/FunkinCrew/Funkin/commit/d3d8aaae7bfbfa8975a9573807b9a3ca68a1ff55)) - by @KoloInDaCrib in [#4127](https://github.com/FunkinCrew/Funkin/pull/4127)
- Hold note trails will no longer disappear when dragged too far in the Chart Editor. ([37dc66b](https://github.com/FunkinCrew/Funkin/commit/37dc66bc189bc1941cf60587e1c068770aeec872)) - by @NotHyper-474 in
[#5261](https://github.com/FunkinCrew/Funkin/pull/5261)
- Undoing and redoing hold note length changes now visually updates the trail in the Chart Editor. ([06a440f](https://github.com/FunkinCrew/Funkin/commit/06a440f21c285666ce2d2bdf17a91ee82ab01061)) - by @NotHyper-474 in [#5265](https://github.com/FunkinCrew/Funkin/pull/5265)
- The Chart Editor hold note context menu now displays the correct options. ([4801316](https://github.com/FunkinCrew/Funkin/commit/48013168ef09ddc09549268a2e5309520d3fcc18)) - by @Lasercar in [#4231](https://github.com/FunkinCrew/Funkin/pull/4231)
- The buttons in the Chart Editor context menu for selections now do the right thing. ([62d24fc](https://github.com/FunkinCrew/Funkin/commit/62d24fcf4cbe7be328a995bad04f3eeb265262c5)) - by @Lasercar in [#4233](https://github.com/FunkinCrew/Funkin/pull/4233)
- The charter field in the song metadata now properly displays the charter in the Chart Editor. ([894d8cb](https://github.com/FunkinCrew/Funkin/commit/894d8cb4637fd0a64359a5edc805a23403f3045c)) - by @Lasercar in [#4879](https://github.com/FunkinCrew/Funkin/pull/4879)
- Chart Editor difficulties are now sorted in a consistent order. ([7aa77a1](https://github.com/FunkinCrew/Funkin/commit/7aa77a11cf7508fc05758045a13b2220aca96dd5)) - by @Lasercar in [#4528](https://github.com/FunkinCrew/Funkin/pull/4528)
- Chart Editor and Stage Editor windows now consistently show a close button. ([b23b7b8](https://github.com/FunkinCrew/funkin.assets/commit/b23b7b81d843c8fa2334fbdbe1ef979633956bb9)) - by @Lasercar in [funkin.assets#121](https://github.com/FunkinCrew/funkin.assets/pull/121)
- The Chart Editor playbar's font size no longer becomes too small. ([f9c1f7a](https://github.com/FunkinCrew/Funkin/commit/f9c1f7a5f7d3906155c2004ad2ec1d02556b9730)) - by @KoloInDaCrib in [#5253](https://github.com/FunkinCrew/Funkin/pull/5253)
- The Chart Editor copy notification no longer chases the mouse cursor. ([0ea42e1](https://github.com/FunkinCrew/Funkin/commit/0ea42e18e93b0b57f1ae5499d70c4681f191dacb)) - by @KoloInDaCrib in [#4029](https://github.com/FunkinCrew/Funkin/pull/4029)
- Changed "Tankman Battlefield (Erect)" to "Tankman Battlefield [Erect]" in the Chart Editor for consistency. ([52852a0](https://github.com/FunkinCrew/funkin.assets/commit/52852a02f60df81c281bfd0e49fd8fa09e118409)) - by @JVNpixels in [funkin.assets#155](https://github.com/FunkinCrew/funkin.assets/pull/155)
- Fixed Pico (Pixel) having the incorrect name in the Chart Editor. ([3ff0e9c](https://github.com/FunkinCrew/funkin.assets/commit/3ff0e9ca4f8cdc5734c335f2d7d72fa310686d46)) - by @ExtraCode75 in [funkin.assets#158](https://github.com/FunkinCrew/funkin.assets/pull/158)
- Fixed various issues and added missing functionalities to the Stage Editor. ([a776ce1](https://github.com/FunkinCrew/Funkin/commit/a776ce1a81a539f75f8bd2220a9768c03d347058)) - by @KoloInDaCrib in [#3974](https://github.com/FunkinCrew/Funkin/pull/3974)
- Stage Editor windows are now able to be closed. ([65461d8](https://github.com/FunkinCrew/Funkin/commit/65461d839b3764659aab33f1a35edf64ee514952)) - by @Lasercar in [#5238](https://github.com/FunkinCrew/Funkin/pull/5238)
- Fixed duplicate exit prompts appearing in the Stage Editor. ([136a5df](https://github.com/FunkinCrew/Funkin/commit/136a5dfad430b461a909be3a7e89f46c8be1d3b3)) - by @Lasercar in [#5239](https://github.com/FunkinCrew/Funkin/pull/5239)
- The help guide in the Stage Editor can no longer be opened multiple times. ([564d679](https://github.com/FunkinCrew/Funkin/commit/564d679f969c500834426ce3cf50507091d69697)) - by @Lasercar in [#4128](https://github.com/FunkinCrew/Funkin/pull/4128)
- Removed a spammy console trace from Spooky Kids (Dark). ([5935a61](https://github.com/FunkinCrew/funkin.assets/commit/5935a61dd71f51e6264dcd039f1164cd1ff295ef)) - by @NotHyper-474 in [funkin.assets#187](https://github.com/FunkinCrew/funkin.assets/pull/187)
- Removed spammy console traces from `DiscordClient`. ([e89f9f5](https://github.com/FunkinCrew/Funkin/commit/e89f9f50dc6085e3550736459ce9e4fd02c1fc5b)) - by @AbnormalPoof in [#4207](https://github.com/FunkinCrew/Funkin/pull/4207)
- Removed a spammy console trace from some Chart Editor events. ([b883ad3](https://github.com/FunkinCrew/Funkin/commit/b883ad3d50b990e605d7b79d042292c7371db5f0)) - by @anysad in [#5097](https://github.com/FunkinCrew/Funkin/pull/5097)
- ANSI colors now display in the console on more computers. ([3747b94](https://github.com/FunkinCrew/Funkin/commit/3747b942461c3644fe31f25d2ce847fd74d1b1e0)) - by @AbnormalPoof in [#4676](https://github.com/FunkinCrew/Funkin/pull/4676)
- Properly blacklist a certain class from scripts. ([3dc7699](https://github.com/FunkinCrew/Funkin/commit/3dc7699aac737998b637ff9a9f16986a434424be)) - by @charlesisfeline in [#4773](https://github.com/FunkinCrew/Funkin/pull/4773)
### Removed
- Removed the VSync preference from web builds, where it's non-functional. ([0b7a94b](https://github.com/FunkinCrew/Funkin/commit/0b7a94b1cc5c5d0dbac5a4c3d595349c4e6eb6e4)) - by @NotHyper-474 in [#5062](https://github.com/FunkinCrew/Funkin/pull/5062)
- Removed a few non-functional screenshot preferences. ([93e4f79](https://github.com/FunkinCrew/Funkin/commit/93e4f799f4f0ea435b3d77ca8ef2ab6beeb0a955)) - by @Lasercar in [#4895](https://github.com/FunkinCrew/Funkin/pull/4895)
## New Contributors for 0.7.0
* @KutikiPlayz made their first contribution in [#3544](https://github.com/FunkinCrew/Funkin/pull/3544)
* @xenkap made their first contribution in [#3732](https://github.com/FunkinCrew/Funkin/pull/3732)
* @Raltyro made their first contribution in [#4577](https://github.com/FunkinCrew/Funkin/pull/4577)
* @charlesisfeline made their first contribution in [#4773](https://github.com/FunkinCrew/Funkin/pull/4773)
* @T5mpler made their first contribution in [#5275](https://github.com/FunkinCrew/Funkin/pull/5275)
* @biomseed made their first contribution in [funkin.assets#78](https://github.com/FunkinCrew/funkin.assets/pull/78)
* @qt2k4 made their first contribution in [funkin.assets#149](https://github.com/FunkinCrew/funkin.assets/pull/149)
* @ExtraCode75 made their first contribution in [funkin.assets#158](https://github.com/FunkinCrew/funkin.assets/pull/158)
* @MetaBreeze made their first contribution in [funkin.assets#186](https://github.com/FunkinCrew/funkin.assets/pull/186)
## [0.6.4] - 2025-05-02
@ -745,7 +1042,7 @@ The Weekend 1 update!
- Improvements to video cutscenes and dialogue, allowing them to be easily skipped or restarted.
- Updated Polymod by several major versions, allowing for fully dynamic asset replacement and support for scripted classes.
- Completely refactored almost every part of the game's code for performance, stability, and extensibility.
- This is not the Ludum Dare game held together with sticks and glue you played three years ago.
- This is not the Ludem Dare game held together with sticks and glue you played three years ago.
- Characters, stages, songs, story levels, and dialogue are now built from JSON data registries rather than being hardcoded.
- All of these also support attaching scripts for custom behavior, more documentation on this soon.
- You can forcibly reload the game's JSON data and scripts by pressing F5.

28
LaunchScreen.storyboard Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<simulatedScreenMetrics key="simulatedMetrics" type="freeform" size="375x667"/>
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0" green="0" blue="0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

103
README.md
View file

@ -1,48 +1,55 @@
# Friday Night Funkin'
Friday Night Funkin' is a rhythm game. Built using HaxeFlixel for Ludum Dare 47.
This game was made with love to Newgrounds and its community. Extra love to Tom Fulp.
- [Playable web demo on Newgrounds!](https://www.newgrounds.com/portal/view/770371)
- [Demo download builds for Windows, Mac, and Linux from Itch.io!](https://ninja-muffin24.itch.io/funkin)
# Getting Started
**PLEASE USE THE LINKS ABOVE IF YOU JUST WANT TO PLAY THE GAME**
To learn how to install the necessary dependencies and compile the game from source, please follow our [Compiling Guide](/docs/COMPILING.md).
# Contributing
Check out our [Contributing Guide](/docs/CONTRIBUTING.md) to learn how you can actively contribute to the development of Friday Night Funkin'!
# Modding
Feel free to start learning to mod the game by reading our [documentation](https://funkincrew.github.io/funkin-modding-docs/) and guide to modding.
# Credits and Special Thanks
Full credits can be found in-game, or in the `credits.json` file which is located [here](https://github.com/FunkinCrew/funkin.assets/blob/main/exclude/data/credits.json).
## Programming
- [ninjamuffin99](https://twitter.com/ninja_muffin99) - Lead Programmer
- [EliteMasterEric](https://twitter.com/EliteMasterEric) - Programmer
- [MtH](https://twitter.com/emmnyaa) - Charting and Additional Programming
- [GeoKureli](https://twitter.com/Geokureli/) - Additional Programming
- Our contributors on GitHub
## Art / Animation / UI
- [PhantomArcade3K](https://twitter.com/phantomarcade3k) - Artist and Animator
- [Evilsk8r](https://twitter.com/evilsk8r) - Art
- [Moawling](https://twitter.com/moawko) - Week 6 Pixel Art
- [IvanAlmighty](https://twitter.com/IvanA1mighty) - Misc UI Design
## Music
- [Kawaisprite](https://twitter.com/kawaisprite) - Musician
- [BassetFilms](https://twitter.com/Bassetfilms) - Music for "Monster", Additional Character Design
## Special Thanks
- [Tom Fulp](https://twitter.com/tomfulp) - For being a great guy and for Newgrounds
- [JohnnyUtah](https://twitter.com/JohnnyUtahNG/) - Voice of Tankman
- [L0Litsmonica](https://twitter.com/L0Litsmonica) - Voice of Mommy Mearest
# Friday Night Funkin'
Friday Night Funkin' is a rhythm game. Built using HaxeFlixel for Ludum Dare 47.
This game was made with love to Newgrounds and its community. Extra love to Tom Fulp.
- [Playable web demo on Newgrounds!](https://www.newgrounds.com/portal/view/770371)
- [Demo download builds for Windows, Mac, and Linux from Itch.io!](https://ninja-muffin24.itch.io/funkin)
- [Download Android builds from Google Play!](https://play.google.com/store/apps/details?id=me.funkin.fnf)
- [Download iOS builds from the App Store!](https://apps.apple.com/app/id6740428530)
# Getting Started
**PLEASE USE THE LINKS ABOVE IF YOU JUST WANT TO PLAY THE GAME**
To learn how to install the necessary dependencies and compile the game from source, please follow our [Compiling Guide](/docs/COMPILING.md).
# Contributing
Check out our [Contributing Guide](/docs/CONTRIBUTING.md) to learn how you can actively contribute to the development of Friday Night Funkin'!
# Modding
Feel free to start learning to mod the game by reading our [documentation](https://funkincrew.github.io/funkin-modding-docs/) and guide to modding.
# Credits and Special Thanks
Full credits can be found in-game, or in the `credits.json` file which is located [here](https://github.com/FunkinCrew/funkin.assets/blob/main/exclude/data/credits.json).
## Programming
- [ninjamuffin99](https://twitter.com/ninja_muffin99) - Lead Programmer
- [EliteMasterEric](https://twitter.com/EliteMasterEric) - Programmer
- [MtH](https://twitter.com/emmnyaa) - Charting and Additional Programming
- [GeoKureli](https://twitter.com/Geokureli/) - Additional Programming
- [ZackDroid](https://x.com/ZackDroidCoder) - Lead Mobile Programmer
- [MAJigsaw77](https://github.com/MAJigsaw77) - Mobile Programmer
- [Karim-Akra](https://x.com/KarimAkra_0) - Mobile Programmer
- [Sector_5](https://github.com/sector-a) - Mobile Programmer
- [Luckydog7](https://github.com/luckydog7) - Mobile Programmer
- Our contributors on GitHub
## Art / Animation / UI
- [PhantomArcade3K](https://twitter.com/phantomarcade3k) - Artist and Animator
- [Evilsk8r](https://twitter.com/evilsk8r) - Art
- [Moawling](https://twitter.com/moawko) - Week 6 Pixel Art
- [IvanAlmighty](https://twitter.com/IvanA1mighty) - Misc UI Design
## Music
- [Kawaisprite](https://twitter.com/kawaisprite) - Musician
- [BassetFilms](https://twitter.com/Bassetfilms) - Music for "Monster", Additional Character Design
## Special Thanks
- [Tom Fulp](https://twitter.com/tomfulp) - For being a great guy and for Newgrounds
- [JohnnyUtah](https://twitter.com/JohnnyUtahNG/) - Voice of Tankman
- [L0Litsmonica](https://twitter.com/L0Litsmonica) - Voice of Mommy Mearest

2
art

@ -1 +1 @@
Subproject commit 8402339e2e63ae99c441941a46d54bf3f0c0d5fa
Subproject commit 490e97f4c6e673a52ee4f9af98325b1aa2d0c3fe

2
assets

@ -1 +1 @@
Subproject commit c108a7ff0d11bf328e7b232160b8f68c71e21bca
Subproject commit a8d15febf5e37a4fc7ffeb0d3eff9c4d36457a37

View file

@ -70,9 +70,10 @@
},
{
"props": {
"severity": "IGNORE",
"policy": "aligned",
"allowSingleline": true,
"severity": "INFO"
"allowSingleline": true
},
"type": "ConditionalCompilation"
},

View file

@ -87,4 +87,3 @@ filter_commits = false
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "newest"

21
compression-excludes.txt Normal file
View file

@ -0,0 +1,21 @@
assets/preload/images/cursor/*
assets/preload/images/freeplay/*
assets/preload/images/icons/*
assets/preload/images/titleEnter.png
assets/preload/images/titleEnter_mobile.png
assets/preload/images/soundtray/*
assets/preload/images/stageBuild/*
assets/preload/images/ui/popup/pixel/
assets/shared/images/characters/abotPixel/
assets/shared/images/characters/bfPixel.png
assets/shared/images/characters/bfPixelsDEAD.png
assets/shared/images/characters/gfPixel.png
assets/shared/images/characters/nenePixel/
assets/shared/images/characters/picoPixel/
assets/shared/images/characters/senpai.png
assets/shared/images/characters/spirit.png
assets/shared/images/resultScreen/*
assets/shared/images/ui/chart-editor/*
assets/shared/images/ui/countdown/pixel/
assets/week1/
assets/week6/*

View file

@ -40,8 +40,8 @@ There are several useful build flags you can add to a build to affect how it wor
- This feature causes the game to load exported assets from the project's assets folder rather than the exported one. Great for fast iteration, but the game will break if you try to zip it up and send it to someone, so it's disabled for release builds.
- `-DFEATURE_DISCORD_RPC` or `-DNO_FEATURE_DISCORD_RPC` to forcibly enable or disable support for Discord Rich Presence.
- `-DFEATURE_VIDEO_PLAYBACK` or `-DNO_FEATURE_VIDEO_PLAYBACK` to forcibly enable or disable video cutscene support.
- `-DFEATURE_CHART_EDITOR` or `-DNO_FEATURE_CHART_EDITOR` to forcibly enable or disable the chart editor in the Debug menu.
- `-DFEATURE_SCREENSHOTS` or `-DNO_FEATURE_SCREENSHOTS` to forcibly enable or disable the screenshots feature.
- `-DFEATURE_CHART_EDITOR` or `-DNO_FEATURE_CHART_EDITOR` to forcibly enable or disable the chart editor in the Debug menu.
- `-DFEATURE_STAGE_EDITOR` to forcibly enable the experimental stage editor.
- `-DFEATURE_GHOST_TAPPING` to forcibly enable an experimental gameplay change to the anti-mash system.

98
docs/COMPILING_MOBILE.md Normal file
View file

@ -0,0 +1,98 @@
# Compiling Friday Night Funkin' for Mobile Devices
Before starting, **make sure your game builds on desktop.**
Check [COMPILING.md](./COMPILING.md) if you havent done that yet.
## Android
0. **Create a new folder** this will store Android tools (remember where you put it!).
1. **Open a terminal as Administrator.**
2. Run this in the terminal (replace the path with your actual folder):
```bash
setx ANDROID_HOME "C:\path\to\your\folder" /M
```
3. Download [Android Studio Command-line Tools](https://developer.android.com/studio#command-line-tools-only).
4. Extract the ZIP into your folder from step 1.
5. (Optional) Close and reopen the terminal if needed.
6. Run:
```bash
sdkmanager --install "build-tools;35.0.0" "ndk;29.0.13113456" "platforms;android-29" "platforms;android-35"
```
- The latest NDK is not compatible with Lime you have to use the old one.
7. Download and install [JDK 17 (MSI)](https://adoptium.net/temurin/releases/?version=17&os=windows).
8. Run:
```bash
lime setup android
```
Use these when asked:
- **Android SDK:** `C:\path\to\your\folder`
- **Android NDK:** `C:\path\to\your\folder\ndk\29.0.13113456`
- **JDK:** `C:\Program Files\Java\jdk-17`
9. Now build your game:
```bash
lime test android
```
### macOS
0. **Create a new folder** this will store Android tools (remember where you put it!).
1. Open **Terminal** (Command ⌘ + Space → type “terminal” → Enter).
2. In Terminal:
```bash
cd /path/to/your/folder
export ANDROID_HOME=/path/to/your/folder
export PATH=$PATH:$ANDROID_HOME/cmdline-tools:$ANDROID_HOME/cmdline-tools/bin:$ANDROID_HOME/platform-tools
```
3. Download [Android Studio Command-line Tools](https://developer.android.com/studio#command-line-tools-only).
4. Extract the ZIP into your folder from step 1.
5. (Optional) Restart Terminal if needed.
6. Run:
```bash
sdkmanager --install "build-tools;35.0.0" "ndk;29.0.13113456" "platforms;android-29" "platforms;android-35"
```
7. Download and install [JDK 17 for macOS](https://adoptium.net/temurin/releases/?os=mac&version=17).
8. Run:
```bash
lime setup android
```
Use these when asked:
- **Android SDK:** `/path/to/your/folder`
- **Android NDK:** `/path/to/your/folder/ndk/28.0.13004108`
- **JDK:** `/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home`
_(If not asked for JDK, dont worry — just skip it.)_
9. Build your game:
```bash
lime test android
```
## iOS
Note that you can only build the game for iOS on a computer running MacOS.
0. Build the game for desktop to make sure everything works. Check [COMPILING.md](./COMPILING.md).
1. Get Xcode from the app store on your MacOS Machine.
2. Download the iPhone SDK (First thing that pops up in Xcode)
3. Open up a terminal tab and run `lime test ios -xcode`
4. You will need to sign your own copy in order to run the game with a real iOS device! That requires an Apple Developer account, sorry!
- To run with an iOS simulator instead of `-xcode` use `-simulator`
### iOS Troubleshooting
- **A required plugin failed to load. Please ensure system content is up-to-date — try running 'xcodebuild -runFirstLaunch'.**
Make sure you have the iOS SDK isntalled, see Step 2.
- **error: No Accounts: Add a new account in Accounts settings. (in target 'Funkin' from project 'Funkin')**
Open XCode, press CMD+, to open Settings, select Accounts, add an Apple ID.
- error: No Account for Team "Z7G7AVNGSH". Add a new account in Accounts settings or verify that your accounts have valid credentials.
Open `project.hxp` and change `IOS_TEAM_ID` to your personal team's ID.
- error: Failed Registering Bundle Identifier: The app identifier "me.funkin.fnf" cannot be registered to your development team because it is not available.
The Funkin' Crew are the only ones that can build an iOS app with the identifier `me.funkin.fnf`. Open `project.hxp` and change `PACKAGE_NAME` to a unique value.
- error: No profiles for 'me.funkin.fnf' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'me.funkin.fnf'

32
docs/INSTALLING_MODS.md Normal file
View file

@ -0,0 +1,32 @@
# HTML5/Web
1. Nope
# Windows
1. Start the game at least once. This will create a `mods` folder if it doesn't already exist, alongside the executable.
2. Extract the mod you downloaded from its ZIP file, and place the mod folder into the game's `mods` folder.
3. Restart the game. The game should detect the mod and start with it.
# Linux
1. Start the game at least once. This will create a `mods` folder if it doesn't already exist, alongside the executable.
2. Extract the mod you downloaded from its ZIP file, and place the mod folder into the game's `mods` folder.
3. Restart the game. The game should detect the mod and start with it.
# MacOS
1. Start the game at least once. This will create a `mods` folder if it doesn't already exist in the game's system files.
2. Right click `Funkin.app` and select `Show Package Contents`.
3. Navigate to `Contents/Resources/mods`.
4. Extract the mod you downloaded from its ZIP file, and place the mod folder into the game's `mods` folder.
5. Restart the game. The game should detect the mod and start with it.
# Android
1. Start the game at least once. This will create a `mods` folder deep in your system files.
2. Get an Android file browser that lets you view the app data files, or use Android Studio and open up the Device Explorer.
3. Locate the `/sdcard/Android/obb/me.funkin.fnf/mods` folder.
4. Extract the mod you downloaded from its ZIP file, and place the mod folder into the game's `mods` folder.
5. Restart the game (you may have to [force close](https://support.google.com/android/answer/9079646?hl=en) the app first). The game should detect the mod and start with it.
# iOS
1. Start the game at least once. This will create a `mods` folder in your system files.
2. Open the Files app, and navigate to `On My iPhone` -> `Friday Night Funkin` -> `mods`.
3. Extract the mod you downloaded from its ZIP file, and place the mod folder into the game's `mods` folder.
4. Restart the game (you may have to [force close](https://support.apple.com/en-us/109359) the app first). The game should detect the mod and start with it.

View file

@ -0,0 +1,66 @@
@echo off
set ZIP_FILE="./temp/_temp_jdk.zip"
set OUTPUT_DIR="./temp/"
set SIX_LINK="https://drive.usercontent.google.com/download?id=1GqFpIk_bkxFb0tNN3x9LxnN-Zh_oDUX5&export=download&authuser=0&confirm=t&uuid=43108c0a-bd53-4465-86f3-80aaceaa7a38&at=APZUnTVNS_BV9cNyC_iicDInosmz%3A1718921284514"
set EIGHT_LINK="https://drive.usercontent.google.com/download?id=1X8jjtYYos8aDfZKwehGS9B3zFQa-sCb-&export=download&authuser=0&confirm=t&uuid=07b24a6c-5352-4ba5-9fb8-cff151a6d91e&at=APZUnTUfw26NBAl0nCMn6HBKgHwK%3A1718922303598"
echo MAKING TEMP
mkdir %OUTPUT_DIR%
echo MADE TEMP
echo INSTALLING ANDROID BUILD TOOLS
call .\asclt\bin\sdkmanager "build-tools;32.0.0" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
call .\asclt\bin\sdkmanager "build-tools;32.1.0-rc1" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo INSTALLED ANDROID BUILD TOOLS
echo INSTALLING ANDROID SDK
REM First install the sdks
call .\asclt\bin\sdkmanager "platforms;android-29" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo ANDROID SDK INSTALLED
echo INSTALLING ANDROID NDK
REM then the ndks
call ./asclt/bin/sdkmanager "ndk;21.4.7075529" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo ANDROID NDK INSTALLED
echo DOWNLOADING JDK
call curl -o %ZIP_FILE% %SIX_LINK%
echo DOWNLOADED JDK
echo UNZIPPING JDK
call powershell -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUTPUT_DIR%' -Force"
echo UNZIPPED JDK
echo MAKING JDK PATH
mkdir "%LOCALAPPDATA%/Android/jdk"
echo MADE JDK PATH
echo MOVING JDK TO PROPER PATH
call move "%OUTPUT_DIR%/jdk-17.0.11+9" "%LOCALAPPDATA%/Android/jdk/"
echo MOVED JDK
echo LIME SETTING UP
haxelib run lime config ANDROID_SDK %LOCALAPPDATA%\Android\Sdk
haxelib run lime config ANDROID_NDK_ROOT %LOCALAPPDATA%\Android\Sdk\ndk\21.4.7075529
haxelib run lime config JAVA_HOME %LOCALAPPDATA%\Android\Sdk\jdk\jdk-17.0.11+9
haxelib run lime config ANDROID_SETUP true
echo DONE
pause

View file

@ -0,0 +1,66 @@
@echo off
set ZIP_FILE="./temp/_temp_jdk.zip"
set OUTPUT_DIR="./temp/"
set SIX_LINK="https://drive.usercontent.google.com/download?id=1GqFpIk_bkxFb0tNN3x9LxnN-Zh_oDUX5&export=download&authuser=0&confirm=t&uuid=43108c0a-bd53-4465-86f3-80aaceaa7a38&at=APZUnTVNS_BV9cNyC_iicDInosmz%3A1718921284514"
set EIGHT_LINK="https://drive.usercontent.google.com/download?id=1X8jjtYYos8aDfZKwehGS9B3zFQa-sCb-&export=download&authuser=0&confirm=t&uuid=07b24a6c-5352-4ba5-9fb8-cff151a6d91e&at=APZUnTUfw26NBAl0nCMn6HBKgHwK%3A1718922303598"
echo MAKING TEMP
mkdir %OUTPUT_DIR%
echo MADE TEMP
echo INSTALLING ANDROID BUILD TOOLS
call .\asclt\bin\sdkmanager "build-tools;32.0.0" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
call .\asclt\bin\sdkmanager "build-tools;32.1.0-rc1" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo INSTALLED ANDROID BUILD TOOLS
echo INSTALLING ANDROID SDK
REM First install the sdks
call .\asclt\bin\sdkmanager "platforms;android-29" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo ANDROID SDK INSTALLED
echo INSTALLING ANDROID NDK
REM then the ndks
call ./asclt/bin/sdkmanager "ndk;21.4.7075529" --sdk_root="%LOCALAPPDATA%/Android/Sdk/"
echo ANDROID NDK INSTALLED
echo DOWNLOADING JDK
call curl -o %ZIP_FILE% %EIGHT_LINK%
echo DOWNLOADED JDK
echo UNZIPPING JDK
call powershell -Command "Expand-Archive -Path '%ZIP_FILE%' -DestinationPath '%OUTPUT_DIR%' -Force"
echo UNZIPPED JDK
echo MAKING JDK PATH
mkdir "%LOCALAPPDATA%/Android/jdk"
echo MADE JDK PATH
echo MOVING JDK TO PROPER PATH
call move "%OUTPUT_DIR%/jdk-17.0.11+9" "%LOCALAPPDATA%/Android/jdk/"
echo MOVED JDK
echo LIME SETTING UP
haxelib run lime config ANDROID_SDK %LOCALAPPDATA%\Android\Sdk
haxelib run lime config ANDROID_NDK_ROOT %LOCALAPPDATA%\Android\Sdk\ndk\21.4.7075529
haxelib run lime config JAVA_HOME %LOCALAPPDATA%\Android\Sdk\jdk\jdk-17.0.11+9
haxelib run lime config ANDROID_SETUP true
echo DONE
pause

View file

@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.5.0",
"api_version": "0.7.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}

View file

@ -6,7 +6,7 @@
"name": "EliteMasterEric"
}
],
"api_version": "0.5.0",
"api_version": "0.7.0",
"mod_version": "1.0.0",
"license": "Apache-2.0"
}

View file

@ -4,14 +4,48 @@
"name": "FlxPartialSound",
"type": "git",
"dir": null,
"ref": "41f35ddb1eb9d10bc742e6f8b5bcc62f9ef8ad84",
"url": "https://github.com/FunkinCrew/FlxPartialSound.git"
"ref": "3c9f63e3501c20c0b60442089dc05306f5a87968",
"url": "https://github.com/FunkinDroidTeam/FlxPartialSound.git"
},
{
"name": "astc-compressor",
"type": "git",
"dir": null,
"ref": "8c9f56927c523df7b849352c6951f04112fe15cc",
"url": "https://github.com/KarimAkra/astc-compressor"
},
{
"name": "extension-admob",
"type": "git",
"dir": null,
"ref": "02334589ff9603a5f483077a44395009644f6274",
"url": "https://github.com/FunkinCrew/extension-admob"
},
{
"name": "extension-androidtools",
"type": "haxelib",
"version": "2.2.2"
},
{
"name": "extension-haptics",
"type": "haxelib",
"version": "1.0.4"
},
{
"name": "extension-iapcore",
"type": "haxelib",
"version": "1.0.4"
},
{
"name": "extension-iarcore",
"type": "haxelib",
"version": "1.0.3"
},
{
"name": "flixel",
"type": "git",
"dir": null,
"ref": "fffb1a74cf08f63dacc2ab09976340563f5b6e6d",
"ref": "08fc955ca87f192a971719a675f1d3b21709725d",
"url": "https://github.com/FunkinCrew/flixel"
},
{
@ -21,18 +55,11 @@
"ref": "b9118f47f43a66bc0e5fbfcfd9903f0425e918ee",
"url": "https://github.com/FunkinCrew/flixel-addons"
},
{
"name": "flixel-text-input",
"type": "git",
"dir": null,
"ref": "951a0103a17bfa55eed86703ce50b4fb0d7590bc",
"url": "https://github.com/FunkinCrew/flixel-text-input"
},
{
"name": "flxanimate",
"type": "git",
"dir": null,
"ref": "f8842cea9883d6112a2c854cf93fa72856171428",
"ref": "b1faf19885dad06c899cb71ffe07b4e40b8c6d0c",
"url": "https://github.com/FunkinCrew/flxanimate"
},
{
@ -51,8 +78,8 @@
"name": "grig.audio",
"type": "git",
"dir": "src",
"ref": "57f5d47f2533fd0c3dcd025a86cb86c0dfa0b6d2",
"url": "https://gitlab.com/haxe-grig/grig.audio.git"
"ref": "8567c4dad34cfeaf2ff23fe12c3796f5db80685e",
"url": "https://github.com/FunkinCrew/grig.audio"
},
{
"name": "hamcrest",
@ -63,29 +90,29 @@
"name": "haxeui-core",
"type": "git",
"dir": null,
"ref": "07fc7aa8098deaea633b0726d01f83eb4ef8a832",
"ref": "47ee9f5fa02d422e186e844f87e68220cabfcc5b",
"url": "https://github.com/haxeui/haxeui-core"
},
{
"name": "haxeui-flixel",
"type": "git",
"dir": null,
"ref": "b899a4c7d7318c5ff2b1bb645fbc73728fad1ac9",
"ref": "100f2c96beab619cfe72c567a058c41c71e3e998",
"url": "https://github.com/haxeui/haxeui-flixel"
},
{
"name": "hscript",
"type": "git",
"dir": null,
"ref": "27c86f9a761c1d16d4433c4cf252eccb7b2e18de",
"ref": "d60bb2947fa609fdc875ccfae89666a6984eeaf2",
"url": "https://github.com/FunkinCrew/hscript"
},
{
"name": "hxcpp",
"type": "git",
"dir": null,
"ref": "v4.3.75",
"url": "https://github.com/HaxeFoundation/hxcpp"
"ref": "5a0dc3f644dc676a4a092b7e6c8edc8be941f024",
"url": "https://github.com/FunkinCrew/hxcpp"
},
{
"name": "hxcpp-debug-server",
@ -116,7 +143,7 @@
{
"name": "hxvlc",
"type": "haxelib",
"version": "2.1.2"
"version": "2.2.2"
},
{
"name": "json2object",
@ -143,7 +170,7 @@
"name": "lime",
"type": "git",
"dir": null,
"ref": "be81ad7e4e1a92c3482bcc009648a4ac892cfa35",
"ref": "e5f8c27124598505917a001588b560244731adfb",
"url": "https://github.com/FunkinCrew/lime"
},
{
@ -185,14 +212,14 @@
"name": "openfl",
"type": "git",
"dir": null,
"ref": "d061c936b462f040304ec2bd42d9f59d2e59e285",
"ref": "a0df7c3afe360c9af59a76e45007dbf4e53b5131",
"url": "https://github.com/FunkinCrew/openfl"
},
{
"name": "polymod",
"type": "git",
"dir": null,
"ref": "0fbdf27fe124549730accd540cec8a183f8652c0",
"ref": "d4142dd15a3b57ed4eb149f9f6a2c3ad9935bf7b",
"url": "https://github.com/larsiusprime/polymod"
},
{

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,17 @@
package;
import flixel.FlxG;
import flixel.FlxGame;
import flixel.FlxState;
import funkin.ui.FullScreenScaleMode;
import funkin.Preferences;
import funkin.util.logging.CrashHandler;
import funkin.ui.debug.MemoryCounter;
import funkin.save.Save;
import haxe.ui.Toolkit;
#if hxvlc
import hxvlc.util.Handle;
#end
import openfl.display.FPS;
import openfl.display.Sprite;
import openfl.events.Event;
@ -31,6 +36,15 @@ class Main extends Sprite
public static function main():Void
{
// Set the current working directory for Android and iOS devices
#if android
// On Android use External Files Dir.
Sys.setCwd(haxe.io.Path.addTrailingSlash(extension.androidtools.content.Context.getExternalFilesDir()));
#elseif ios
// On iOS use Documents Dir.
Sys.setCwd(haxe.io.Path.addTrailingSlash(lime.system.System.documentsDirectory));
#end
// We need to make the crash handler LITERALLY FIRST so nothing EVER gets past it.
CrashHandler.initialize();
CrashHandler.queryStatus();
@ -97,9 +111,19 @@ class Main extends Sprite
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
#end
#if mobile
// Add this signal so we can reposition and resize the memory and fps counter.
FlxG.signals.preUpdate.add(repositionCounters.bind(true));
#end
// George recommends binding the save before FlxGame is created.
Save.load();
#if hxvlc
// Initialize hxvlc's Handle here so the videos are loading faster.
Handle.init();
#end
// Don't call anything from the preferences until the save is loaded!
#if web
// set this variable (which is a function) from the lime version at lime/_internal/backend/html5/HTML5Application.hx
@ -109,7 +133,6 @@ class Main extends Sprite
WindowUtil.setVSyncMode(funkin.Preferences.vsyncMode);
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash, startFullscreen);
// FlxG.game._customSoundTray wants just the class, it calls new from
@ -124,6 +147,15 @@ class Main extends Sprite
game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil());
#end
#if !html5
FlxG.scaleMode = new FullScreenScaleMode();
#end
#if mobile
// Reposition and resize the memory and fps counter without lerping.
repositionCounters(false);
#end
#if hxcpp_debug_server
trace('hxcpp_debug_server is enabled! You can now connect to the game with a debugger.');
#else
@ -145,4 +177,56 @@ class Main extends Sprite
funkin.input.Cursor.registerHaxeUICursors();
haxe.ui.tooltips.ToolTipManager.defaultDelay = 200;
}
#if mobile
function repositionCounters(lerp:Bool):Void
{
// Calling this so it gets scaled based on the resolution of the game and device's resolution.
var scale:Float = Math.min(FlxG.stage.stageWidth / FlxG.width, FlxG.stage.stageHeight / FlxG.height);
#if android
scale = Math.max(scale, 1);
#else
scale = Math.min(scale, 1);
#end
final thypos:Float = Math.max(FullScreenScaleMode.notchSize.x, 10);
if (fpsCounter != null)
{
fpsCounter.scaleX = fpsCounter.scaleY = scale;
if (FlxG.game != null)
{
if (lerp)
{
fpsCounter.x = flixel.math.FlxMath.lerp(fpsCounter.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
}
else
{
fpsCounter.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
}
fpsCounter.y = FlxG.game.y + (3 * scale);
}
}
if (memoryCounter != null)
{
memoryCounter.scaleX = memoryCounter.scaleY = scale;
if (FlxG.game != null)
{
if (lerp)
{
memoryCounter.x = flixel.math.FlxMath.lerp(memoryCounter.x, FlxG.game.x + thypos, FlxG.elapsed * 3);
}
else
{
memoryCounter.x = FlxG.game.x + FullScreenScaleMode.notchSize.x + 10;
}
memoryCounter.y = FlxG.game.y + (13 * scale);
}
}
}
#end
}

View file

@ -29,7 +29,7 @@ class Postbuild
var buildTime:Float = roundToTwoDecimals(end - start);
trace('Build took: ${buildTime} seconds');
Sys.println('[INFO] Build took: ${buildTime} seconds');
}
}

View file

@ -9,48 +9,24 @@ class Prebuild
{
static inline final BUILD_TIME_FILE:String = '.build_time';
static final NG_CREDS_PATH:String = './source/funkin/api/newgrounds/NewgroundsCredentials.hx';
static final NG_CREDS_TEMPLATE:String = "package funkin.api.newgrounds;
class NewgroundsCredentials
{
public static final APP_ID:String = #if API_NG_APP_ID haxe.macro.Compiler.getDefine(\"API_NG_APP_ID\") #else 'INSERT APP ID HERE' #end;
public static final ENCRYPTION_KEY:String = #if API_NG_ENC_KEY haxe.macro.Compiler.getDefine(\"API_NG_ENC_KEY\") #else 'INSERT ENCRYPTION KEY HERE' #end;
}";
static function main():Void
{
trace('Building...');
var start:Float = Sys.time();
Sys.println('[INFO] Performing pre-build tasks...');
saveBuildTime();
buildCredsFile();
var end:Float = Sys.time();
var duration:Float = end - start;
Sys.println('[INFO] Finished pre-build tasks in $duration seconds.');
}
static function saveBuildTime():Void
{
// PostBuild.hx reads this file and computes the total build duration.
var fo:sys.io.FileOutput = File.write(BUILD_TIME_FILE);
var now:Float = Sys.time();
fo.writeDouble(now);
fo.close();
}
static function buildCredsFile():Void
{
#if sys
if (sys.FileSystem.exists(NG_CREDS_PATH))
{
trace('NewgroundsCredentials.hx already exists, skipping.');
}
else
{
trace('Creating NewgroundsCredentials.hx...');
var fileContents:String = NG_CREDS_TEMPLATE;
sys.io.File.saveContent(NG_CREDS_PATH, fileContents);
}
#end
}
}

View file

@ -24,6 +24,27 @@ extern class Native_TracyProfiler
@:native('::__hxcpp_tracy_framemark')
public static function frameMark():Void;
/**
Mark a named frame. Allows creating multiple frame sets for different timing categories.
Each unique name creates a separate frame set in the Tracy timeline.
**/
@:native('::__hxcpp_tracy_framemark_named')
public static function frameMarkNamed(_name:String):Void;
/**
Mark the start of a discontinuous frame. Use for periodic work with gaps.
Must be paired with frameMarkEnd() using the same name.
**/
@:native('::__hxcpp_tracy_framemark_start')
public static function frameMarkStart(_name:String):Void;
/**
Mark the end of a discontinuous frame. Use for periodic work with gaps.
Must be paired with frameMarkStart() using the same name.
**/
@:native('::__hxcpp_tracy_framemark_end')
public static function frameMarkEnd(_name:String):Void;
/**
Print a message into Tracy's log.
**/
@ -71,6 +92,18 @@ class Cppia_TracyProfiler
public static function frameMark()
Native_TracyProfiler.frameMark();
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkNamed)
public static function frameMarkNamed(_name:String)
Native_TracyProfiler.frameMarkNamed(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkStart)
public static function frameMarkStart(_name:String)
Native_TracyProfiler.frameMarkStart(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.frameMarkEnd)
public static function frameMarkEnd(_name:String)
Native_TracyProfiler.frameMarkEnd(_name);
@:inheritDoc(cpp.vm.tracy.Native_TracyProfiler.message)
public static function message(_msg:String, ?_color:Int = 0x000000)
Native_TracyProfiler.message(_msg, _color);

View file

@ -9,6 +9,11 @@ import openfl.utils.Future;
@:nullSafety
class Assets
{
/**
* The assets cache.
*/
public static var cache:openfl.utils.IAssetCache = openfl.utils.Assets.cache;
/**
* Get the file system path for an asset
* @param path The asset path to load from, relative to the assets folder

View file

@ -6,6 +6,7 @@ import flixel.math.FlxMath;
import funkin.data.song.SongData.SongTimeChange;
import funkin.data.song.SongDataUtils;
import funkin.save.Save;
import funkin.util.TimerUtil.SongSequence;
import haxe.Timer;
import flixel.sound.FlxSound;
@ -92,6 +93,12 @@ class Conductor
*/
public var songPosition(default, null):Float = 0;
/**
* The offset between frame time and music time.
* Used in `getTimeWithDelta()` to get a more accurate music time when on higher framerates.
*/
var songPositionDelta(default, null):Float = 0;
var prevTimestamp:Float = 0;
var prevTime:Float = 0;
@ -242,25 +249,18 @@ class Conductor
* No matter if you're using a local conductor or not, this always loads
* to/from the save file
*/
public var inputOffset(get, set):Int;
public var globalOffset(get, never):Int;
/**
* An offset set by the user to compensate for audio/visual lag
* No matter if you're using a local conductor or not, this always loads
* to/from the save file
*/
public var audioVisualOffset(get, set):Int;
public var audioVisualOffset(get, never):Int;
function get_inputOffset():Int
function get_globalOffset():Int
{
return Save?.instance?.options?.inputOffset ?? 0;
}
function set_inputOffset(value:Int):Int
{
Save.instance.options.inputOffset = value;
Save.instance.flush();
return Save.instance.options.inputOffset;
return Preferences.globalOffset;
}
function get_audioVisualOffset():Int
@ -268,18 +268,11 @@ class Conductor
return Save?.instance?.options?.audioVisualOffset ?? 0;
}
function set_audioVisualOffset(value:Int):Int
{
Save.instance.options.audioVisualOffset = value;
Save.instance.flush();
return Save.instance.options.audioVisualOffset;
}
public var combinedOffset(get, never):Float;
function get_combinedOffset():Float
{
return instrumentalOffset + audioVisualOffset + inputOffset;
return instrumentalOffset + formatOffset + globalOffset;
}
/**
@ -401,8 +394,10 @@ class Conductor
* @param songPosition The current position in the song in milliseconds.
* Leave blank to use the FlxG.sound.music position.
* @param applyOffsets If it should apply the instrumentalOffset + formatOffset + audioVisualOffset
* @param forceDispatch If it should force the dispatch of onStepHit, onBeatHit, and onMeasureHit
* even if the current step, beat, or measure hasn't changed.
*/
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false)
public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false):Void
{
var currentTime:Float = (FlxG.sound.music != null) ? FlxG.sound.music.time : 0.0;
var currentLength:Float = (FlxG.sound.music != null) ? FlxG.sound.music.length : 0.0;
@ -422,7 +417,8 @@ class Conductor
// If the song is playing, limit the song position to the length of the song or beginning of the song.
if (FlxG.sound.music != null && FlxG.sound.music.playing)
{
this.songPosition = Math.min(currentLength, Math.max(0, songPos));
this.songPosition = FlxMath.bound(Math.min(this.combinedOffset, 0), songPos, currentLength);
this.songPositionDelta += FlxG.elapsed * 1000 * FlxG.sound.music.pitch;
}
else
{
@ -488,10 +484,23 @@ class Conductor
// which it doesn't do every frame!
if (prevTime != this.songPosition)
{
this.songPositionDelta = 0;
// Update the timestamp for use in-between frames
prevTime = this.songPosition;
prevTimestamp = Std.int(Timer.stamp() * 1000);
}
if (this == Conductor.instance) @:privateAccess SongSequence.update.dispatch();
}
/**
* Returns a more accurate music time for higher framerates.
* @return Float
*/
public function getTimeWithDelta():Float
{
return this.songPosition + this.songPositionDelta;
}
/**

View file

@ -0,0 +1,428 @@
package funkin;
import flixel.graphics.FlxGraphic;
import flixel.FlxG;
import funkin.play.notes.notestyle.NoteStyle;
import openfl.utils.AssetType;
import openfl.Assets;
import openfl.system.System;
import openfl.media.Sound;
import lime.app.Future;
import lime.app.Promise;
/**
* Handles caching of textures and sounds for the game.
* TODO: Remove this once Eric finishes the memory system.
*/
@:nullSafety
class FunkinMemory
{
static var permanentCachedTextures:Map<String, FlxGraphic> = [];
static var currentCachedTextures:Map<String, FlxGraphic> = [];
static var previousCachedTextures:Map<String, FlxGraphic> = [];
// waow
static var permanentCachedSounds:Map<String, Sound> = [];
static var currentCachedSounds:Map<String, Sound> = [];
static var previousCachedSounds:Map<String, Sound> = [];
static var purgeFilter:Array<String> = ["/week", "/characters", "/charSelect", "/results"];
/**
* Caches textures that are always required.
*/
public static inline function initialCache():Void
{
var allImages:Array<String> = Assets.list();
for (file in allImages)
{
if (!(file.endsWith(".png") #if FEATURE_COMPRESSED_TEXTURES || file.endsWith(".astc") #end)
|| file.contains("chart-editor")
|| !file.contains("ui/"))
{
continue;
}
file = file.replace(" ", ""); // Handle stray spaces.
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.IMAGE))
{
file = 'shared:$file';
}
permanentCacheTexture(file);
}
permanentCacheTexture(Paths.image("healthBar"));
permanentCacheTexture(Paths.image("menuDesat"));
permanentCacheTexture(Paths.image("notes", "shared"));
permanentCacheTexture(Paths.image("noteSplashes", "shared"));
permanentCacheTexture(Paths.image("noteStrumline", "shared"));
permanentCacheTexture(Paths.image("NOTE_hold_assets"));
// dude
permanentCacheTexture(Paths.image("fonts/bold", null));
permanentCacheTexture(Paths.image("fonts/default", null));
permanentCacheTexture(Paths.image("fonts/freeplay-clear", null));
var allSounds:Array<String> = Assets.list(AssetType.SOUND);
for (file in allSounds)
{
if (!file.endsWith(".ogg") || !file.contains("countdown/")) continue;
file = file.replace(" ", "");
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.SOUND))
{
file = 'shared:$file';
}
permanentCacheSound(file);
}
permanentCacheSound(Paths.sound("cancelMenu"));
permanentCacheSound(Paths.sound("confirmMenu"));
permanentCacheSound(Paths.sound("screenshot"));
permanentCacheSound(Paths.sound("scrollMenu"));
permanentCacheSound(Paths.sound("soundtray/Voldown"));
permanentCacheSound(Paths.sound("soundtray/VolMAX"));
permanentCacheSound(Paths.sound("soundtray/Volup"));
permanentCacheSound(Paths.music("freakyMenu/freakyMenu"));
permanentCacheSound(Paths.music("offsetsLoop/offsetsLoop"));
permanentCacheSound(Paths.music("offsetsLoop/drumsLoop"));
permanentCacheSound(Paths.sound("missnote1", "shared"));
permanentCacheSound(Paths.sound("missnote2", "shared"));
permanentCacheSound(Paths.sound("missnote3", "shared"));
}
/**
* Clears the current texture and sound caches.
*/
public static inline function purgeCache(callGarbageCollector:Bool = false):Void
{
preparePurgeTextureCache();
purgeTextureCache();
preparePurgeSoundCache();
purgeSoundCache();
#if (cpp || neko || hl)
if (callGarbageCollector) funkin.util.MemoryUtil.collect(true);
#end
}
///// TEXTURES /////
/**
* Ensures a texture with the given key is cached.
* @param key The key of the texture to cache.
*/
public static function cacheTexture(key:String):Void
{
if (currentCachedTextures.exists(key))
{
return; // Already cached.
}
if (previousCachedTextures.exists(key))
{
// Move the texture from the previous cache to the current cache.
var graphic:Null<FlxGraphic> = previousCachedTextures.get(key);
previousCachedTextures.remove(key);
if (graphic != null) currentCachedTextures.set(key, graphic);
return;
}
var graphic:Null<FlxGraphic> = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
currentCachedTextures.set(key, graphic);
}
}
/**
* Permanently caches a texture with the given key.
* @param key The key of the texture to cache.
*/
static function permanentCacheTexture(key:String):Void
{
if (permanentCachedTextures.exists(key))
{
return; // Already cached.
}
var graphic:Null<FlxGraphic> = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
permanentCachedTextures.set(key, graphic);
}
currentCachedTextures = permanentCachedTextures;
}
/**
* Prepares the cache for purging unused textures.
*/
public inline static function preparePurgeTextureCache():Void
{
previousCachedTextures = currentCachedTextures;
for (graphicKey in previousCachedTextures.keys())
{
if (permanentCachedTextures.exists(graphicKey))
{
previousCachedTextures.remove(graphicKey);
}
}
currentCachedTextures = permanentCachedTextures;
}
/**
* Purges unused textures from the cache.
*/
public static function purgeTextureCache():Void
{
for (graphicKey in previousCachedTextures.keys())
{
if (permanentCachedTextures.exists(graphicKey))
{
previousCachedTextures.remove(graphicKey);
continue;
}
if (graphicKey.contains("fonts")) continue;
var graphic:Null<FlxGraphic> = previousCachedTextures.get(graphicKey);
if (graphic != null)
{
FlxG.bitmap.remove(graphic);
graphic.destroy();
previousCachedTextures.remove(graphicKey);
Assets.cache.clear(graphicKey);
}
}
@:privateAccess
if (FlxG.bitmap._cache == null)
{
@:privateAccess
FlxG.bitmap._cache = new Map();
}
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj == null || obj.persist || permanentCachedTextures.exists(key) || key.contains("fonts"))
{
continue;
}
if (obj.useCount > 0)
{
for (purgeEntry in purgeFilter)
{
if (key.contains(purgeEntry))
{
FlxG.bitmap.removeKey(key);
obj.destroy();
}
}
}
}
}
///// NOTE STYLE //////
public static function cacheNoteStyle(style:NoteStyle):Void
{
// TODO: Texture paths should fall back to the default values.
cacheTexture(Paths.image(style.getNoteAssetPath() ?? "note"));
cacheTexture(style.getHoldNoteAssetPath() ?? "noteHold");
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? "strumline"));
cacheTexture(Paths.image(style.getSplashAssetPath() ?? "noteSplash"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(LEFT) ?? "LEFT"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(RIGHT) ?? "RIGHT"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(UP) ?? "UP"));
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(DOWN) ?? "DOWN"));
// cacheTexture(Paths.image(style.buildCountdownSpritePath(THREE) ?? "THREE"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(TWO) ?? "TWO"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(ONE) ?? "ONE"));
cacheTexture(Paths.image(style.buildCountdownSpritePath(GO) ?? "GO"));
cacheSound(style.getCountdownSoundPath(THREE) ?? "THREE");
cacheSound(style.getCountdownSoundPath(TWO) ?? "TWO");
cacheSound(style.getCountdownSoundPath(ONE) ?? "ONE");
cacheSound(style.getCountdownSoundPath(GO) ?? "GO");
cacheTexture(Paths.image(style.buildJudgementSpritePath("sick") ?? 'sick'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("good") ?? 'good'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("bad") ?? 'bad'));
cacheTexture(Paths.image(style.buildJudgementSpritePath("shit") ?? 'shit'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(0) ?? '0'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(1) ?? '1'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(2) ?? '2'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(3) ?? '3'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(4) ?? '4'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(5) ?? '5'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(6) ?? '6'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(7) ?? '7'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(8) ?? '8'));
cacheTexture(Paths.image(style.buildComboNumSpritePath(9) ?? '9'));
}
///// SOUND //////
public static function cacheSound(key:String):Void
{
if (currentCachedSounds.exists(key)) return;
if (previousCachedSounds.exists(key))
{
// Move the texture from the previous cache to the current cache.
var sound:Null<Sound> = previousCachedSounds.get(key);
previousCachedSounds.remove(key);
if (sound != null) currentCachedSounds.set(key, sound);
return;
}
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
else
currentCachedSounds.set(key, sound);
}
public static function permanentCacheSound(key:String):Void
{
if (permanentCachedSounds.exists(key)) return;
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound == null) return;
else
permanentCachedSounds.set(key, sound);
if (sound != null) currentCachedSounds.set(key, sound);
}
public static function preparePurgeSoundCache():Void
{
previousCachedSounds = currentCachedSounds;
for (key in previousCachedSounds.keys())
{
if (permanentCachedSounds.exists(key))
{
previousCachedSounds.remove(key);
}
}
currentCachedSounds = permanentCachedSounds;
}
/**
* Purges unused sounds from the cache.
*/
public static inline function purgeSoundCache():Void
{
for (key in previousCachedSounds.keys())
{
if (permanentCachedSounds.exists(key))
{
previousCachedSounds.remove(key);
continue;
}
var sound:Null<Sound> = previousCachedSounds.get(key);
if (sound != null)
{
Assets.cache.removeSound(key);
previousCachedSounds.remove(key);
}
}
Assets.cache.clear("songs");
Assets.cache.clear("music");
// Felt lazy.
var key = Paths.music("freakyMenu/freakyMenu");
var sound:Null<Sound> = Assets.getSound(key, true);
if (sound != null)
{
permanentCachedSounds.set(key, sound);
currentCachedSounds.set(key, sound);
}
}
///// MISC /////
public static inline function clearFreeplay():Void
{
var keysToRemove:Array<String> = [];
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
if (!key.contains("freeplay")) continue;
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
keysToRemove.push(key);
}
@:privateAccess
for (key in keysToRemove)
{
trace('Cleaning up $key');
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj != null)
{
obj.destroy();
}
FlxG.bitmap.removeKey(key);
if (currentCachedTextures.exists(key)) currentCachedTextures.remove(key);
Assets.cache.clear(key);
}
preparePurgeSoundCache();
purgeSoundCache();
}
public static inline function clearStickers():Void
{
var keysToRemove:Array<String> = [];
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
if (!key.contains("stickers")) continue;
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
keysToRemove.push(key);
}
@:privateAccess
for (key in keysToRemove)
{
trace('Cleaning up $key');
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj != null)
{
obj.destroy();
}
FlxG.bitmap.removeKey(key);
if (currentCachedTextures.exists(key)) currentCachedTextures.remove(key);
Assets.cache.clear(key);
}
}
}

View file

@ -3,6 +3,7 @@ package funkin;
/**
* A core class which handles tracking score and combo for the current song.
*/
@:nullSafety
class Highscore
{
/**

View file

@ -10,6 +10,7 @@ import flixel.math.FlxPoint;
import flixel.math.FlxRect;
import flixel.system.debug.log.LogStyle;
import flixel.util.FlxColor;
import funkin.graphics.FunkinSprite;
import funkin.data.dialogue.conversation.ConversationRegistry;
import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry;
import funkin.data.dialogue.speaker.SpeakerRegistry;
@ -27,12 +28,12 @@ import funkin.play.character.CharacterData.CharacterDataParser;
import funkin.play.notes.notekind.NoteKindManager;
import funkin.play.PlayStatePlaylist;
import funkin.ui.debug.charting.ChartEditorState;
import funkin.ui.debug.stageeditor.StageEditorState;
import funkin.ui.title.TitleState;
import funkin.ui.transition.LoadingState;
import funkin.util.CLIUtil;
import funkin.util.CLIUtil.CLIParams;
import funkin.util.macro.MacroUtil;
import funkin.util.TimerUtil;
import funkin.util.TrackerUtil;
import funkin.util.WindowUtil;
import openfl.display.BitmapData;
@ -51,6 +52,7 @@ import funkin.api.newgrounds.NewgroundsClient;
*
* It should not contain any sprites or rendering.
*/
@:nullSafety
class InitState extends FlxState
{
/**
@ -90,6 +92,31 @@ class InitState extends FlxState
funkin.util.WindowUtil.initTracy();
#end
#if FEATURE_HAPTICS
// Setup Haptic feedback
extension.haptics.Haptic.initialize();
#end
#if FEATURE_MOBILE_ADVERTISEMENTS
// Setup Admob
funkin.mobile.util.AdMobUtil.init();
#end
#if FEATURE_MOBILE_IAP
// Setup In-App purchases
funkin.mobile.util.InAppPurchasesUtil.init();
#end
#if FEATURE_MOBILE_IAR
// Setup In-App purchases
funkin.mobile.util.InAppReviewUtil.init();
#end
#if ios
// Setup Audio session
funkin.external.ios.AudioSession.initialize();
#end
// This ain't a pixel art game! (most of the time)
FlxSprite.defaultAntialiasing = true;
@ -102,13 +129,15 @@ class InitState extends FlxState
// but that makes our soundtray not show up on init if we have the game muted.
// We set it to active so it at least calls it's update function once (see FlxGame.onEnterFrame(), it's called there)
// and also see FunkinSoundTray.update() to see what we do and how we check if we are muted or not
#if !mobile
FlxG.game.soundTray.active = true;
#end
// Set the game to a lower frame rate while it is in the background.
FlxG.game.focusLostFramerate = 30;
// Makes Flixel use frame times instead of locked movements per frame for things like tweens
FlxG.fixedTimestep = false;
FlxG.fixedTimestep = false;
setupFlixelDebug();
@ -131,6 +160,25 @@ class InitState extends FlxState
// Don't play transition in when entering the title state.
FlxTransitionableState.skipNextTransIn = true;
FlxG.signals.gameResized.add(function(width:Int, height:Int) {
FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), tileData,
new FlxRect(-200, -200, FlxG.width * 1.4, FlxG.height * 1.4));
});
// SDL for some reason enables VSync on focus lost/gained in Android
// Since we don't really need VSync on Android we're gonna forcefully disable it on these signals for now
// This is fixed on SDL3 from what I've heared but that doodoo isn't working poperly for Android
#if android
FlxG.signals.focusLost.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
FlxG.signals.focusGained.add(function() {
WindowUtil.setVSyncMode(lime.ui.WindowVSyncMode.OFF);
});
#end
//
// NEWGROUNDS API SETUP
//
@ -154,6 +202,7 @@ class InitState extends FlxState
//
#if android
FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK];
funkin.external.android.CallbackUtil.init();
#end
//
@ -168,12 +217,20 @@ class InitState extends FlxState
#if FEATURE_SCREENSHOTS
funkin.util.plugins.ScreenshotPlugin.initialize();
#end
#if FEATURE_NEWGROUNDS
funkin.util.plugins.NewgroundsMedalPlugin.initialize();
#end
funkin.util.plugins.EvacuateDebugPlugin.initialize();
funkin.util.plugins.ForceCrashPlugin.initialize();
funkin.util.plugins.ReloadAssetsDebugPlugin.initialize();
#if !mobile
funkin.util.plugins.VolumePlugin.initialize();
#end
funkin.util.plugins.WatchPlugin.initialize();
#if mobile
funkin.util.plugins.TouchPointerPlugin.initialize();
funkin.mobile.input.ControlsHandler.initInputTrackers();
#end
//
// GAME DATA PARSING
@ -182,7 +239,6 @@ class InitState extends FlxState
// NOTE: Registries must be imported and not referenced with fully qualified names,
// to ensure build macros work properly.
trace('Parsing game data...');
var perfStart:Float = TimerUtil.start();
SongEventRegistry.loadEventCache(); // SongEventRegistry is structured differently so it's not a BaseRegistry.
SongRegistry.instance.loadEntries();
LevelRegistry.instance.loadEntries();
@ -208,7 +264,10 @@ class InitState extends FlxState
funkin.input.Cursor.hide();
trace('Parsing game data took: ${TimerUtil.ms(perfStart)}');
#if !html5
// This fucking breaks on HTML5 builds because the "shared" library isn't loaded yet.
funkin.FunkinMemory.initialCache();
#end
}
/**
@ -241,6 +300,9 @@ class InitState extends FlxState
#elseif CHARTING
// -DCHARTING
FlxG.switchState(() -> new funkin.ui.debug.charting.ChartEditorState());
#elseif STAGING
// -DSTAGING
FlxG.switchState(() -> new funkin.ui.debug.stageeditor.StageEditorState());
#elseif STAGEBUILD
// -DSTAGEBUILD
FlxG.switchState(() -> new funkin.ui.debug.stage.StageBuilderState());
@ -303,9 +365,16 @@ class InitState extends FlxState
fnfcTargetPath: params.chart.chartPath,
}));
}
else if (params.stage.shouldLoadStage)
{
FlxG.switchState(() -> new StageEditorState(
{
fnfsTargetPath: params.stage.stagePath,
}));
}
else
{
FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu'));
// FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu'));
FlxG.switchState(() -> new TitleState());
}
}
@ -317,7 +386,7 @@ class InitState extends FlxState
*/
function startSong(songId:String, difficultyId:String = 'normal'):Void
{
var songData:funkin.play.song.Song = funkin.data.song.SongRegistry.instance.fetchEntry(songId);
var songData:Null<funkin.play.song.Song> = funkin.data.song.SongRegistry.instance.fetchEntry(songId);
if (songData == null)
{
@ -354,6 +423,7 @@ class InitState extends FlxState
PlayStatePlaylist.campaignId = 'weekend1';
}
@:nullSafety(Off) // Cannot unify?
LoadingState.loadPlayState(
{
targetSong: songData,
@ -368,7 +438,7 @@ class InitState extends FlxState
*/
function startLevel(levelId:String, difficultyId:String = 'normal'):Void
{
var currentLevel:funkin.ui.story.Level = funkin.data.story.level.LevelRegistry.instance.fetchEntry(levelId);
var currentLevel:Null<funkin.ui.story.Level> = funkin.data.story.level.LevelRegistry.instance.fetchEntry(levelId);
if (currentLevel == null)
{
@ -384,10 +454,19 @@ class InitState extends FlxState
PlayStatePlaylist.isStoryMode = true;
PlayStatePlaylist.campaignScore = 0;
var targetSongId:String = PlayStatePlaylist.playlistSongIds.shift();
var targetSongId:Null<String> = PlayStatePlaylist.playlistSongIds.shift();
var targetSong:funkin.play.song.Song = SongRegistry.instance.fetchEntry(targetSongId);
var targetSong:Null<funkin.play.song.Song> = null;
if (targetSongId != null) targetSong = SongRegistry.instance.fetchEntry(targetSongId);
if (targetSongId == null)
{
startGameNormally();
return;
}
@:nullSafety(Off)
LoadingState.loadPlayState(
{
targetSong: targetSong,
@ -395,6 +474,7 @@ class InitState extends FlxState
});
}
@:nullSafety(Off) // Meh, remove when flixel.system.debug.log.LogStyle is null safe
function setupFlixelDebug():Void
{
//
@ -474,17 +554,17 @@ class InitState extends FlxState
#end
}
function defineSong():String
function defineSong():Null<String>
{
return MacroUtil.getDefine('SONG');
}
function defineLevel():String
function defineLevel():Null<String>
{
return MacroUtil.getDefine('LEVEL');
}
function defineDifficulty():String
function defineDifficulty():Null<String>
{
return MacroUtil.getDefine('DIFFICULTY');
}

View file

@ -6,6 +6,7 @@ import openfl.utils.AssetType;
/**
* A core class which handles determining asset paths.
*/
@:nullSafety
class Paths
{
static var currentLevel:Null<String> = null;
@ -136,7 +137,7 @@ class Paths
* @param withExtension if it should return with the audio file extension `.mp3` or `.ogg`.
* @return String
*/
public static function inst(song:String, ?suffix:String = '', ?withExtension:Bool = true):String
public static function inst(song:String, ?suffix:String = '', withExtension:Bool = true):String
{
var ext:String = withExtension ? '.${Constants.EXT_SOUND}' : '';
return 'songs:assets/songs/${song.toLowerCase()}/Inst$suffix$ext';

View file

@ -9,12 +9,17 @@ import flixel.util.FlxSignal.FlxTypedSignal;
/**
* A core class which represents the current player(s) and their controls and other configuration.
*/
@:nullSafety
class PlayerSettings
{
// TODO: Finish implementation of second player.
public static var numPlayers(default, null) = 0;
public static var numAvatars(default, null) = 0;
// TODO: Making both of these null makes a lot of errors with the controls.
// That'd explain why unplugging input devices can cause the game to crash?
@:nullSafety(Off)
public static var player1(default, null):PlayerSettings;
@:nullSafety(Off)
public static var player2(default, null):PlayerSettings;
public static var onAvatarAdd(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
@ -70,6 +75,7 @@ class PlayerSettings
/**
* Forcibly destroy the PlayerSettings singletons for each player.
*/
@:nullSafety(Off)
public static function reset():Void
{
player1 = null;

View file

@ -1,15 +1,22 @@
package funkin;
#if mobile
import funkin.mobile.ui.FunkinHitbox;
import funkin.mobile.util.InAppPurchasesUtil;
#end
import funkin.save.Save;
import funkin.util.WindowUtil;
import funkin.util.HapticUtil.HapticsMode;
/**
* A core class which provides a store of user-configurable, globally relevant values.
*/
@:nullSafety
class Preferences
{
/**
* FPS
* Always the refresh rate of the display on mobile, or 60 on web.
* @default `60`
*/
public static var framerate(get, set):Int;
@ -18,6 +25,12 @@ class Preferences
{
#if web
return 60;
#elseif mobile
var refreshRate:Int = FlxG.stage.window.displayMode.refreshRate;
if (refreshRate < 60) refreshRate = 60;
return refreshRate;
#else
return Save?.instance?.options?.framerate ?? 60;
#end
@ -45,11 +58,19 @@ class Preferences
static function get_naughtyness():Bool
{
return Save?.instance?.options?.naughtyness;
#if NO_FEATURE_NAUGHTYNESS
return false;
#else
return Save?.instance?.options?.naughtyness ?? true;
#end
}
static function set_naughtyness(value:Bool):Bool
{
#if NO_FEATURE_NAUGHTYNESS
value = false;
#end
var save:Save = Save.instance;
save.options.naughtyness = value;
save.flush();
@ -64,7 +85,7 @@ class Preferences
static function get_downscroll():Bool
{
return Save?.instance?.options?.downscroll;
return Save?.instance?.options?.downscroll #if mobile ?? true #else ?? false #end;
}
static function set_downscroll(value:Bool):Bool
@ -102,7 +123,7 @@ class Preferences
static function get_zoomCamera():Bool
{
return Save?.instance?.options?.zoomCamera;
return Save?.instance?.options?.zoomCamera ?? true;
}
static function set_zoomCamera(value:Bool):Bool
@ -115,13 +136,17 @@ class Preferences
/**
* If enabled, an FPS and memory counter will be displayed even if this is not a debug build.
* Always disabled on mobile.
* @default `false`
*/
public static var debugDisplay(get, set):Bool;
static function get_debugDisplay():Bool
{
return Save?.instance?.options?.debugDisplay;
#if mobile
return false;
#end
return Save?.instance?.options?.debugDisplay ?? false;
}
static function set_debugDisplay(value:Bool):Bool
@ -137,14 +162,78 @@ class Preferences
return value;
}
/**
* If enabled, haptic feedback will be enabled.
* @default `All`
*/
public static var hapticsMode(get, set):HapticsMode;
static function get_hapticsMode():HapticsMode
{
var value = Save?.instance?.options?.hapticsMode ?? "All";
return switch (value)
{
case "None":
HapticsMode.NONE;
case "Notes Only":
HapticsMode.NOTES_ONLY;
default:
HapticsMode.ALL;
};
}
static function set_hapticsMode(value:HapticsMode):HapticsMode
{
var string;
switch (value)
{
case HapticsMode.NONE:
string = "None";
case HapticsMode.NOTES_ONLY:
string = "Notes Only";
default:
string = "All";
};
var save:Save = Save.instance;
save.options.hapticsMode = string;
save.flush();
return value;
}
/**
* Multiplier of intensity for all the haptic feedback effects.
* @default `2.5`
*/
public static var hapticsIntensityMultiplier(get, set):Float;
static function get_hapticsIntensityMultiplier():Float
{
return Save?.instance?.options?.hapticsIntensityMultiplier ?? 1;
}
static function set_hapticsIntensityMultiplier(value:Float):Float
{
var save:Save = Save.instance;
save.options.hapticsIntensityMultiplier = value;
save.flush();
return value;
}
/**
* If enabled, the game will automatically pause when tabbing out.
* Always enabled on mobile.
* @default `true`
*/
public static var autoPause(get, set):Bool;
static function get_autoPause():Bool
{
#if mobile
return true;
#end
return Save?.instance?.options?.autoPause ?? true;
}
@ -177,6 +266,26 @@ class Preferences
return value;
}
/**
* A global audio offset in milliseconds.
* This is used to sync the audio.
* @default `0`
*/
public static var globalOffset(get, set):Int;
static function get_globalOffset():Int
{
return Save?.instance?.options?.globalOffset ?? 0;
}
static function set_globalOffset(value:Int):Int
{
var save:Save = Save.instance;
save.options.globalOffset = value;
save.flush();
return value;
}
/**
* If enabled, the game will utilize VSync (or adaptive VSync) on startup.
* @default `OFF`
@ -228,7 +337,7 @@ class Preferences
static function get_unlockedFramerate():Bool
{
return Save?.instance?.options?.unlockedFramerate;
return Save?.instance?.options?.unlockedFramerate ?? false;
}
static function set_unlockedFramerate(value:Bool):Bool
@ -343,44 +452,6 @@ class Preferences
return value;
}
/**
* The game will save any screenshots taken to this format.
* @default `PNG`
*/
public static var saveFormat(get, set):Any;
static function get_saveFormat():Any
{
return Save?.instance?.options?.screenshot?.saveFormat ?? 'PNG';
}
static function set_saveFormat(value):Any
{
var save:Save = Save.instance;
save.options.screenshot.saveFormat = value;
save.flush();
return value;
}
/**
* The game will save JPEG screenshots with this quality percentage.
* @default `80`
*/
public static var jpegQuality(get, set):Int;
static function get_jpegQuality():Int
{
return Save?.instance?.options?.screenshot?.jpegQuality ?? 80;
}
static function set_jpegQuality(value:Int):Int
{
var save:Save = Save.instance;
save.options.screenshot.jpegQuality = value;
save.flush();
return value;
}
/**
* Loads the user's preferences from the save data and apply them.
*/
@ -394,8 +465,16 @@ class Preferences
#if web
toggleFramerateCap(Preferences.unlockedFramerate);
#end
#if desktop
// Apply the autoFullscreen setting (launches the game in fullscreen automatically)
FlxG.fullscreen = Preferences.autoFullscreen;
#end
#if mobile
// Apply the allowScreenTimeout setting.
lime.system.System.allowScreenTimeout = Preferences.screenTimeout;
#end
}
static function toggleFramerateCap(unlocked:Bool):Void
@ -411,18 +490,88 @@ class Preferences
if (show)
{
// Enable the debug display.
FlxG.stage.addChild(Main.fpsCounter);
FlxG.game.parent.addChild(Main.fpsCounter);
#if !html5
FlxG.stage.addChild(Main.memoryCounter);
FlxG.game.parent.addChild(Main.memoryCounter);
#end
}
else
{
// Disable the debug display.
FlxG.stage.removeChild(Main.fpsCounter);
FlxG.game.parent.removeChild(Main.fpsCounter);
#if !html5
FlxG.stage.removeChild(Main.memoryCounter);
FlxG.game.parent.removeChild(Main.memoryCounter);
#end
}
}
#if mobile
/**
* If enabled, device will be able to sleep on its own.
* @default `false`
*/
public static var screenTimeout(get, set):Bool;
static function get_screenTimeout():Bool
{
return Save?.instance?.mobileOptions?.screenTimeout ?? false;
}
static function set_screenTimeout(value:Bool):Bool
{
if (value != Save.instance.mobileOptions.screenTimeout) lime.system.System.allowScreenTimeout = value;
var save:Save = Save.instance;
save.mobileOptions.screenTimeout = value;
save.flush();
return value;
}
/**
* Controls Scheme for the hitbox.
* @default `4 Lanes`
*/
public static var controlsScheme(get, set):String;
static function get_controlsScheme():String
{
return Save?.instance?.mobileOptions?.controlsScheme ?? FunkinHitboxControlSchemes.Arrows;
}
static function set_controlsScheme(value:String):String
{
var save:Save = Save.instance;
save.mobileOptions.controlsScheme = value;
save.flush();
return value;
}
#if FEATURE_MOBILE_IAP
/**
* If bought, the game will not show any ads.
* @default `false`
*/
@:unreflective
public static var noAds(get, set):Bool;
@:unreflective
static function get_noAds():Bool
{
if (InAppPurchasesUtil.hasInitialized) noAds = InAppPurchasesUtil.isPurchased(InAppPurchasesUtil.UPGRADE_PRODUCT_ID);
var returnedValue = Save?.instance?.mobileOptions?.noAds ?? false;
return returnedValue;
}
@:unreflective
static function set_noAds(value:Bool):Bool
{
var save:Save = Save.instance;
save.mobileOptions.noAds = value;
save.flush();
return value;
}
#end
#end
}

View file

@ -1,5 +1,6 @@
package funkin.api.discord;
import funkin.util.macro.EnvironmentConfigMacro;
#if FEATURE_DISCORD_RPC
import hxdiscord_rpc.Discord;
import hxdiscord_rpc.Types.DiscordButton;
@ -8,9 +9,10 @@ import hxdiscord_rpc.Types.DiscordRichPresence;
import hxdiscord_rpc.Types.DiscordUser;
import sys.thread.Thread;
@:nullSafety
class DiscordClient
{
static final CLIENT_ID:String = "816168432860790794";
static final CLIENT_ID:Null<String> = EnvironmentConfigMacro.environmentConfig?.get("DESKTOP_DISCORD_CLIENT_ID");
public static var instance(get, never):DiscordClient;
static var _instance:Null<DiscordClient> = null;
@ -39,13 +41,29 @@ class DiscordClient
{
trace('[DISCORD] Initializing connection...');
// Discord.initialize(CLIENT_ID, handlers, true, null);
Discord.Initialize(CLIENT_ID, cpp.RawPointer.addressOf(handlers), 1, null);
if (!hasValidCredentials())
{
FlxG.log.warn("Tried to initialize Discord connection, but credentials are invalid!");
return;
}
@:nullSafety(Off)
{
Discord.Initialize(CLIENT_ID, cpp.RawPointer.addressOf(handlers), 1, "");
}
createDaemon();
}
var daemon:Thread = null;
/**
* @returns `false` if the client ID is invalid.
*/
static function hasValidCredentials():Bool
{
return !(CLIENT_ID == null || CLIENT_ID == "" || (CLIENT_ID != null && CLIENT_ID.contains(" ")));
}
var daemon:Null<Thread> = null;
function createDaemon():Void
{
@ -56,8 +74,6 @@ class DiscordClient
{
while (true)
{
trace('[DISCORD] Performing client update...');
#if DISCORD_DISABLE_IO_THREAD
Discord.updateConnection();
#end
@ -76,8 +92,6 @@ class DiscordClient
public function setPresence(params:DiscordClientPresenceParams):Void
{
trace('[DISCORD] Updating presence... (${params})');
Discord.updatePresence(buildPresence(params));
}
@ -92,17 +106,15 @@ class DiscordClient
presence.largeImageText = "Friday Night Funkin'";
// State should be generally what the person is doing, like "In the Menus" or "Pico (Pico Mix) [Freeplay Hard]"
presence.state = cast(params.state, Null<String>);
presence.state = cast(params.state, Null<String>) ?? "";
// Details should be what the person is specifically doing, including stuff like timestamps (maybe something like "03:24 elapsed").
presence.details = cast(params.details, Null<String>);
presence.details = cast(params.details, Null<String>) ?? "";
// The large image displaying what the user is doing.
// This should probably be album art.
// IMPORTANT NOTE: This can be an asset key uploaded to Discord's developer panel OR any URL you like.
presence.largeImageKey = cast(params.largeImageKey, Null<String>) ?? "album-volume1";
trace('[DISCORD] largeImageKey: ${presence.largeImageKey}');
// TODO: Make this use the song's album art.
// presence.largeImageKey = "icon";
// presence.largeImageKey = "https://f4.bcbits.com/img/a0746694746_16.jpg";
@ -110,7 +122,7 @@ class DiscordClient
// The small inset image for what the user is doing.
// This can be the opponent's health icon?
// NOTE: Like largeImageKey, this can be a URL, or an asset key.
presence.smallImageKey = cast(params.smallImageKey, Null<String>);
presence.smallImageKey = cast(params.smallImageKey, Null<String>) ?? "";
// NOTE: In previous versions, this showed as "Elapsed", but now shows as playtime and doesn't look good
// presence.startTimestamp = time - 10;
@ -136,9 +148,9 @@ class DiscordClient
final username:String = request[0].username;
final globalName:String = request[0].username;
final discriminator:Int = Std.parseInt(request[0].discriminator);
final discriminator:Null<Int> = Std.parseInt(request[0].discriminator);
if (discriminator != 0)
if (discriminator != null && discriminator != 0)
{
trace('[DISCORD] User: ${username}#${discriminator} (${globalName})');
}
@ -204,4 +216,30 @@ typedef DiscordClientPresenceParams =
*/
var ?smallImageKey:String;
}
class DiscordClientSandboxed
{
public static function setPresence(params:DiscordClientPresenceParams):Void
{
DiscordClient.instance.setPresence(params);
}
public static function shutdown():Void
{
DiscordClient.instance.shutdown();
}
}
#else
class DiscordClientSandboxed
{
public static function setPresence(params:Dynamic):Void
{
// Do nothing.
}
public static function shutdown():Void
{
// Do nothing.
}
}
#end

View file

@ -1,9 +1,11 @@
package funkin.api.newgrounds;
#if FEATURE_NEWGROUNDS_EVENTS
import io.newgrounds.Call.CallOutcome;
import io.newgrounds.NG;
import io.newgrounds.objects.events.Outcome;
import io.newgrounds.objects.events.Result;
#end
/**
* Use Newgrounds to perform basic telemetry. Ignore if not logged in to Newgrounds.
@ -31,6 +33,7 @@ class Events
#end
}
#if FEATURE_NEWGROUNDS_EVENTS
static function onEventLogged(eventName:String, outcome:CallOutcome<LogEventData>)
{
switch (outcome)
@ -55,6 +58,7 @@ class Events
}
}
}
#end
public static inline function logStartGame():Void
{

View file

@ -2,10 +2,14 @@ package funkin.api.newgrounds;
#if FEATURE_NEWGROUNDS
import io.newgrounds.Call.CallError;
import io.newgrounds.components.ScoreBoardComponent;
import io.newgrounds.objects.Score;
import io.newgrounds.objects.ScoreBoard as LeaderboardData;
import io.newgrounds.objects.User;
import io.newgrounds.objects.events.Outcome;
import io.newgrounds.utils.ScoreBoardList;
@:nullSafety
class Leaderboards
{
public static function listLeaderboardData():Map<Leaderboard, LeaderboardData>
@ -16,21 +20,8 @@ class Leaderboards
trace('[NEWGROUNDS] Not logged in, cannot fetch medal data!');
return [];
}
else
{
var result:Map<Leaderboard, LeaderboardData> = [];
for (leaderboardId in leaderboardList.keys())
{
var leaderboardData = leaderboardList.get(leaderboardId);
if (leaderboardData == null) continue;
// A little hacky, but it works.
result.set(cast leaderboardId, leaderboardData);
}
return result;
}
return @:privateAccess leaderboardList._map?.copy() ?? [];
}
/**
@ -66,6 +57,41 @@ class Leaderboards
}
}
/**
* Request to receive scores from Newgrounds.
* @param leaderboard The leaderboard to fetch scores from.
* @param params Additional parameters for fetching the score.
*/
public static function requestScores(leaderboard:Leaderboard, ?params:RequestScoresParams)
{
// Silently reject retrieving scores from unknown leaderboards.
if (leaderboard == Leaderboard.Unknown) return;
var leaderboardList = NewgroundsClient.instance.leaderboards;
if (leaderboardList == null) return;
var leaderboardData:Null<LeaderboardData> = leaderboardList.get(leaderboard.getId());
if (leaderboardData == null) return;
var user:Null<User> = null;
if ((params?.useCurrentUser ?? false) && NewgroundsClient.instance.isLoggedIn()) user = NewgroundsClient.instance.user;
leaderboardData.requestScores(params?.limit ?? 10, params?.skip ?? 0, params?.period ?? ALL, params?.social ?? false, params?.tag, user,
function(outcome:Outcome<CallError>):Void {
switch (outcome)
{
case SUCCESS:
trace('[NEWGROUNDS] Fetched scores!');
if (params != null && params.onComplete != null) params.onComplete(leaderboardData.scores);
case FAIL(error):
trace('[NEWGROUNDS] Failed to fetch scores!');
trace(error);
if (params != null && params.onFail != null) params.onFail();
}
});
}
/**
* Submit a score for a Story Level to Newgrounds.
*/
@ -84,9 +110,77 @@ class Leaderboards
Leaderboards.submitScore(Leaderboard.getLeaderboardBySong(songId, difficultyId), score, tag);
}
}
/**
* Wrapper for `Leaderboards` that prevents submitting scores.
*/
@:nullSafety
class LeaderboardsSandboxed
{
public static function getLeaderboardBySong(songId:String, difficultyId:String)
{
return Leaderboard.getLeaderboardBySong(songId, difficultyId);
}
public static function getLeaderboardByLevel(levelId:String)
{
return Leaderboard.getLeaderboardByLevel(levelId);
}
public function requestScores(leaderboard:Leaderboard, params:RequestScoresParams)
{
Leaderboards.requestScores(leaderboard, params);
}
}
/**
* Additional parameters for `Leaderboards.requestScores()`
*/
typedef RequestScoresParams =
{
/**
* How many scores to include in a list.
* @default `10`
*/
var ?limit:Int;
/**
* How many scores to skip before starting the list.
* @default `0`
*/
var ?skip:Int;
/**
* The time-frame to pull the scores from.
* @default `Period.ALL`
*/
var ?period:Period;
/**
* If true, only scores by the user and their friends will be loaded. Ignored if no user is set.
* @default `false`
*/
var ?social:Bool;
/**
* An optional tag to filter the results by.
* @default `null`
*/
var ?tag:String;
/**
* If true, only the scores from the currently logged in user will be loaded.
* Additionally, if `social` is set to true, the scores of the user's friend will be loaded.
* @default `false`
*/
var ?useCurrentUser:Bool;
var ?onComplete:Array<Score>->Void;
var ?onFail:Void->Void;
}
#end
enum abstract Leaderboard(Int)
enum abstract Leaderboard(Int) from Int to Int
{
/**
* Represents an undefined or invalid leaderboard.
@ -285,7 +379,7 @@ enum abstract Leaderboard(Int)
{
case "darnell":
return DarnellBFMix;
case "litup":
case "lit-up":
return LitUpBFMix;
default:
return Unknown;
@ -379,7 +473,7 @@ enum abstract Leaderboard(Int)
return Stress;
case "darnell":
return Darnell;
case "litup":
case "lit-up":
return LitUp;
case "2hot":
return TwoHot;

View file

@ -8,6 +8,7 @@ import openfl.display.BitmapData;
import io.newgrounds.utils.MedalList;
import haxe.Json;
@:nullSafety
class Medals
{
public static var medalJSON:Array<MedalJSON> = [];
@ -21,22 +22,8 @@ class Medals
trace('[NEWGROUNDS] Not logged in, cannot fetch medal data!');
return [];
}
else
{
// TODO: Why do I have to do this, @:nullSafety is fucked up
var result:Map<Medal, MedalData> = [];
for (medalId in medalList.keys())
{
var medalData = medalList.get(medalId);
if (medalData == null) continue;
// A little hacky, but it works.
result.set(cast medalId, medalData);
}
return result;
}
return @:privateAccess medalList._map?.copy() ?? [];
}
public static function award(medal:Medal):Void
@ -131,32 +118,78 @@ class Medals
}
}
public static function awardStoryLevel(id:String):Void
public static function fetchMedalData(medal:Medal):Null<FetchedMedalData>
{
switch (id)
var medalList = NewgroundsClient.instance.medals;
@:privateAccess
if (medalList == null || medalList._map == null) return null;
var medalData:Null<MedalData> = medalList.get(medal.getId());
@:privateAccess
if (medalData == null || medalData._data == null)
{
case 'tutorial':
Medals.award(Medal.StoryTutorial);
case 'week1':
Medals.award(Medal.StoryWeek1);
case 'week2':
Medals.award(Medal.StoryWeek2);
case 'week3':
Medals.award(Medal.StoryWeek3);
case 'week4':
Medals.award(Medal.StoryWeek4);
case 'week5':
Medals.award(Medal.StoryWeek5);
case 'week6':
Medals.award(Medal.StoryWeek6);
case 'week7':
Medals.award(Medal.StoryWeek7);
case 'weekend1':
Medals.award(Medal.StoryWeekend1);
default:
trace('[NEWGROUNDS] Story level does not have a medal! (${id}).');
trace('[NEWGROUNDS] Could not retrieve data for medal: ${medal}');
return null;
}
return {
id: medalData.id,
name: medalData.name,
description: medalData.description,
icon: medalData.icon,
value: medalData.value,
difficulty: medalData.difficulty,
secret: medalData.secret,
unlocked: medalData.unlocked
}
}
public static function awardStoryLevel(id:String):Void
{
var medal:Medal = Medal.getMedalByStoryLevel(id);
if (medal == Medal.Unknown)
{
trace('[NEWGROUNDS] Story level does not have a medal! (${id}).');
return;
}
Medals.award(medal);
}
}
/**
* Wrapper for `Medals` that prevents awarding medals.
*/
class MedalsSandboxed
{
public static function fetchMedalData(medal:Medal):Null<FetchedMedalData>
{
return Medals.fetchMedalData(medal);
}
public static function getMedalByStoryLevel(id:String):Medal
{
return Medal.getMedalByStoryLevel(id);
}
public static function getAllMedals():Array<Medal>
{
return Medal.getAllMedals();
}
}
/**
* Contains data for a Medal, but excludes functions like `sendUnlock()`.
*/
typedef FetchedMedalData =
{
var id:Int;
var name:String;
var description:String;
var icon:String;
var value:Int;
var difficulty:Int;
var secret:Bool;
var unlocked:Bool;
}
#end
@ -324,6 +357,8 @@ enum abstract Medal(Int) from Int to Int
{
switch (levelId)
{
case "tutorial":
return StoryTutorial;
case "week1":
return StoryWeek1;
case "week2":
@ -344,4 +379,33 @@ enum abstract Medal(Int) from Int to Int
return Unknown;
}
}
/**
* Lists all medals aside from the `Unknown` one.
*/
public static function getAllMedals()
{
return [
StartGame,
StoryTutorial,
StoryWeek1,
StoryWeek2,
StoryWeek3,
StoryWeek4,
StoryWeek5,
StoryWeek6,
StoryWeek7,
StoryWeekend1,
CharSelect,
FreeplayPicoMix,
FreeplayStressPico,
LossRating,
PerfectRatingHard,
GoldPerfectRatingHard,
ErectDifficulty,
GoldPerfectRatingNightmare,
FridayNight,
Nice
];
}
}

View file

@ -0,0 +1,156 @@
package funkin.api.newgrounds;
#if FEATURE_NEWGROUNDS
import io.newgrounds.utils.SaveSlotList;
import io.newgrounds.objects.SaveSlot;
import io.newgrounds.Call.CallError;
import io.newgrounds.objects.events.Outcome;
import funkin.save.Save;
@:nullSafety
@:access(funkin.save.Save)
class NGSaveSlot
{
public static var instance(get, never):NGSaveSlot;
static var _instance:Null<NGSaveSlot> = null;
static function get_instance():NGSaveSlot
{
if (_instance == null)
{
return loadInstance();
}
return _instance;
}
public static function loadInstance():NGSaveSlot
{
var loadedSave:NGSaveSlot = loadSlot(Save.BASE_SAVE_SLOT);
if (_instance == null) _instance = loadedSave;
return loadedSave;
}
static function loadSlot(slot:Int):NGSaveSlot
{
trace('[NEWGROUNDS] Getting save slot from ID $slot');
var saveSlot:Null<SaveSlot> = NewgroundsClient.instance.saveSlots?.getById(slot);
var saveSlotObj:NGSaveSlot = new NGSaveSlot(saveSlot);
return saveSlotObj;
}
public var ngSaveSlot:Null<SaveSlot> = null;
public function new(?ngSaveSlot:Null<SaveSlot>)
{
this.ngSaveSlot = ngSaveSlot;
#if FLX_DEBUG
FlxG.console.registerClass(NGSaveSlot);
FlxG.console.registerClass(Save);
#end
}
/**
* Saves `data` to the newgrounds save slot.
* @param data The raw save data.
*/
public function save(data:RawSaveData):Void
{
var encodedData:String = haxe.Serializer.run(data);
try
{
ngSaveSlot?.save(encodedData, function(outcome:Outcome<CallError>) {
switch (outcome)
{
case SUCCESS:
trace('[NEWGROUNDS] Successfully saved save data to save slot!');
case FAIL(error):
trace('[NEWGROUNDS] Failed to save data to save slot!');
trace(error);
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to save data to save slot!');
trace(error);
}
}
public function load(?onComplete:Null<Dynamic->Void>, ?onError:Null<CallError->Void>):Void
{
try
{
ngSaveSlot?.load(function(outcome:SaveSlotOutcome):Void {
switch (outcome)
{
case SUCCESS(value):
trace('[NEWGROUNDS] Loaded save slot with the ID of ${ngSaveSlot?.id}!');
#if FEATURE_DEBUG_FUNCTIONS
trace('Save Slot Data:');
trace(value);
#end
if (onComplete != null && value != null)
{
var decodedData:Dynamic = haxe.Unserializer.run(value);
onComplete(decodedData);
}
case FAIL(error):
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
trace(error);
if (onError != null)
{
onError(error);
}
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
trace(error);
if (onError != null)
{
onError(RESPONSE({message: error, code: 500}));
}
}
}
public function clear():Void
{
try
{
ngSaveSlot?.clear(function(outcome:Outcome<CallError>) {
switch (outcome)
{
case SUCCESS:
trace('[NEWGROUNDS] Successfully cleared save slot!');
case FAIL(error):
trace('[NEWGROUNDS] Failed to clear save slot!');
trace(error);
}
});
}
catch (error:String)
{
trace('[NEWGROUNDS] Failed to clear save slot!');
trace(error);
}
}
public function checkSlot():Void
{
trace('[NEWGROUNDS] Checking save slot with the ID of ${ngSaveSlot?.id}...');
trace(' Is null? ${ngSaveSlot == null}');
trace(' Is empty? ${ngSaveSlot?.isEmpty() ?? false}');
}
}
#end

View file

@ -1,5 +1,6 @@
package funkin.api.newgrounds;
import funkin.util.macro.EnvironmentConfigMacro;
import funkin.save.Save;
import funkin.api.newgrounds.Medals.Medal;
#if FEATURE_NEWGROUNDS
@ -10,13 +11,18 @@ import io.newgrounds.NGLite.LoginOutcome;
import io.newgrounds.NGLite.LoginFail;
import io.newgrounds.objects.events.Outcome;
import io.newgrounds.utils.MedalList;
import io.newgrounds.utils.SaveSlotList;
import io.newgrounds.utils.ScoreBoardList;
import io.newgrounds.objects.User;
@:nullSafety
class NewgroundsClient
{
static final APP_ID:Null<String> = EnvironmentConfigMacro.environmentConfig?.get("API_NG_APP_ID");
static final ENCRYPTION_KEY:Null<String> = EnvironmentConfigMacro.environmentConfig?.get("API_NG_ENC_KEY");
public static var instance(get, never):NewgroundsClient;
static var _instance:Null<NewgroundsClient> = null;
static function get_instance():NewgroundsClient
@ -29,14 +35,15 @@ class NewgroundsClient
public var user(get, never):Null<User>;
public var medals(get, never):Null<MedalList>;
public var leaderboards(get, never):Null<ScoreBoardList>;
public var saveSlots(get, never):Null<SaveSlotList>;
private function new()
{
trace('[NEWGROUNDS] Initializing client...');
#if FEATURE_NEWGROUNDS_DEBUG
trace('[NEWGROUNDS] App ID: ${NewgroundsCredentials.APP_ID}');
trace('[NEWGROUNDS] Encryption Key: ${NewgroundsCredentials.ENCRYPTION_KEY}');
trace('[NEWGROUNDS] App ID: ${APP_ID}');
trace('[NEWGROUNDS] Encryption Key: ${ENCRYPTION_KEY}');
#end
if (!hasValidCredentials())
@ -45,9 +52,12 @@ class NewgroundsClient
return;
}
var debug = #if FEATURE_NEWGROUNDS_DEBUG true #else false #end;
NG.create(NewgroundsCredentials.APP_ID, getSessionId(), debug, onLoginResolved);
NG.core.setupEncryption(NewgroundsCredentials.ENCRYPTION_KEY);
@:nullSafety(Off)
{
NG.create(APP_ID, getSessionId(), #if FEATURE_NEWGROUNDS_DEBUG true #else false #end, onLoginResolved);
NG.core.setupEncryption(ENCRYPTION_KEY);
}
}
public function init()
@ -166,12 +176,12 @@ class NewgroundsClient
*/
static function hasValidCredentials():Bool
{
return !(NewgroundsCredentials.APP_ID == null
|| NewgroundsCredentials.APP_ID == ""
|| NewgroundsCredentials.APP_ID.contains(" ")
|| NewgroundsCredentials.ENCRYPTION_KEY == null
|| NewgroundsCredentials.ENCRYPTION_KEY == ""
|| NewgroundsCredentials.ENCRYPTION_KEY.contains(" "));
return !(APP_ID == null
|| APP_ID == ""
|| (APP_ID != null && APP_ID.contains(" "))
|| ENCRYPTION_KEY == null
|| ENCRYPTION_KEY == ""
|| (ENCRYPTION_KEY != null && ENCRYPTION_KEY.contains(" ")));
}
function onLoginResolved(outcome:LoginOutcome):Void
@ -236,6 +246,8 @@ class NewgroundsClient
trace('[NEWGROUNDS] Submitting leaderboard request...');
NG.core.scoreBoards.loadList(onFetchedLeaderboards);
trace('[NEWGROUNDS] Submitting save slot request...');
NG.core.saveSlots.loadList(onFetchedSaveSlots);
}
function onLoginFailed(result:LoginFail):Void
@ -301,6 +313,13 @@ class NewgroundsClient
// trace(funkin.api.newgrounds.Leaderboards.listLeaderboardData());
}
function onFetchedSaveSlots(outcome:Outcome<CallError>):Void
{
trace('[NEWGROUNDS] Fetched save slots!');
NGSaveSlot.instance.checkSlot();
}
function get_user():Null<User>
{
if (NG.core == null || !this.isLoggedIn()) return null;
@ -319,6 +338,12 @@ class NewgroundsClient
return NG.core.scoreBoards;
}
function get_saveSlots():Null<SaveSlotList>
{
if (NG.core == null || !this.isLoggedIn()) return null;
return NG.core.saveSlots;
}
static function getSessionId():Null<String>
{
#if js
@ -331,4 +356,22 @@ class NewgroundsClient
return Save.instance.ngSessionId;
}
}
/**
* Wrapper for `NewgroundsClient` that prevents submitting cheated data.
*/
class NewgroundsClientSandboxed
{
public static var user(get, never):Null<User>;
static function get_user()
{
return NewgroundsClient.instance.user;
}
public static function isLoggedIn()
{
return NewgroundsClient.instance.isLoggedIn();
}
}
#end

View file

@ -11,6 +11,7 @@ import openfl.utils.AssetType;
/**
* a FlxSound that just overrides loadEmbedded to allow for "streamed" sounds to load with better performance!
*/
@:nullSafety
class FlxStreamSound extends FlxSound
{
public function new()
@ -18,7 +19,7 @@ class FlxStreamSound extends FlxSound
super();
}
override public function loadEmbedded(EmbeddedSound:FlxSoundAsset, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound
override public function loadEmbedded(EmbeddedSound:Null<FlxSoundAsset>, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound
{
if (EmbeddedSound == null) return this;

View file

@ -20,9 +20,6 @@ import openfl.media.Sound;
import openfl.media.SoundChannel;
import openfl.media.SoundMixer;
#if (openfl >= "8.0.0")
#end
/**
* A FlxSound which adds additional functionality:
* - Delayed playback via negative song position.
@ -45,9 +42,9 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
if (_onVolumeChanged == null)
{
_onVolumeChanged = new FlxTypedSignal<Float->Void>();
FlxG.sound.volumeHandler = function(volume:Float) {
FlxG.sound.onVolumeChange.add(function(volume:Float) {
_onVolumeChanged.dispatch(volume);
}
});
}
return _onVolumeChanged;
}
@ -478,7 +475,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
if (autoPlay) sound.play();
sound.volume = volume;
sound.group = FlxG.sound.defaultSoundGroup;
FlxG.sound.defaultSoundGroup.add(sound);
sound.persist = persist;
sound.important = important;
@ -551,6 +548,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
}
FlxTween.cancelTweensOf(this);
this._label = 'unknown';
this._waveformData = null;
}
@:access(openfl.media.Sound)

View file

@ -7,6 +7,7 @@ import flixel.tweens.FlxTween;
* A group of FunkinSounds that are all synced together.
* Unlike FlxSoundGroup, you can also control their time and pitch.
*/
@:nullSafety
class SoundGroup extends FlxTypedGroup<FunkinSound>
{
public var time(get, set):Float;
@ -36,6 +37,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
return result;
}
@:nullSafety(Off)
for (sndFile in files)
{
var snd:FunkinSound = FunkinSound.load(Paths.voices(song, '$sndFile'));
@ -70,7 +72,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
/**
* Add a sound to the group.
*/
public override function add(sound:FunkinSound):FunkinSound
public override function add(sound:FunkinSound):Null<FunkinSound>
{
var result:FunkinSound = super.add(sound);
@ -134,6 +136,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
/**
* Fade in all the sounds in the group.
*/
@:nullSafety(Off)
public function fadeIn(duration:Float, ?from:Float = 0.0, ?to:Float = 1.0, ?onComplete:FlxTween->Void):Void
{
forEachAlive(function(sound:FunkinSound) {
@ -144,6 +147,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
/**
* Fade out all the sounds in the group.
*/
@:nullSafety(Off)
public function fadeOut(duration:Float, ?to:Float = 0.0, ?onComplete:FlxTween->Void):Void
{
forEachAlive(function(sound:FunkinSound) {
@ -238,7 +242,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
function get_muted():Bool
{
if (getFirstAlive() != null) return getFirstAlive().muted;
if (getFirstAlive() != null) return getFirstAlive()?.muted ?? false;
else
return false;
}

View file

@ -3,10 +3,11 @@ package funkin.audio;
import flixel.group.FlxGroup.FlxTypedGroup;
import funkin.audio.waveform.WaveformData;
@:nullSafety
class VoicesGroup extends SoundGroup
{
var playerVoices:FlxTypedGroup<FunkinSound>;
var opponentVoices:FlxTypedGroup<FunkinSound>;
var playerVoices:Null<FlxTypedGroup<FunkinSound>>;
var opponentVoices:Null<FlxTypedGroup<FunkinSound>>;
/**
* Control the volume of only the sounds in the player group.
@ -41,12 +42,12 @@ class VoicesGroup extends SoundGroup
public function addPlayerVoice(sound:FunkinSound):Void
{
super.add(sound);
playerVoices.add(sound);
playerVoices?.add(sound);
}
function set_playerVolume(volume:Float):Float
{
playerVoices.forEachAlive(function(voice:FunkinSound) {
playerVoices?.forEachAlive(function(voice:FunkinSound) {
voice.volume = volume;
});
return playerVolume = volume;
@ -59,10 +60,10 @@ class VoicesGroup extends SoundGroup
snd.time = time;
});
playerVoices.forEachAlive(function(voice:FunkinSound) {
playerVoices?.forEachAlive(function(voice:FunkinSound) {
voice.time -= playerVoicesOffset;
});
opponentVoices.forEachAlive(function(voice:FunkinSound) {
opponentVoices?.forEachAlive(function(voice:FunkinSound) {
voice.time -= opponentVoicesOffset;
});
@ -71,7 +72,7 @@ class VoicesGroup extends SoundGroup
function set_playerVoicesOffset(offset:Float):Float
{
playerVoices.forEachAlive(function(voice:FunkinSound) {
playerVoices?.forEachAlive(function(voice:FunkinSound) {
voice.time += playerVoicesOffset;
voice.time -= offset;
});
@ -80,7 +81,7 @@ class VoicesGroup extends SoundGroup
function set_opponentVoicesOffset(offset:Float):Float
{
opponentVoices.forEachAlive(function(voice:FunkinSound) {
opponentVoices?.forEachAlive(function(voice:FunkinSound) {
voice.time += opponentVoicesOffset;
voice.time -= offset;
});
@ -93,12 +94,12 @@ class VoicesGroup extends SoundGroup
public function addOpponentVoice(sound:FunkinSound):Void
{
super.add(sound);
opponentVoices.add(sound);
opponentVoices?.add(sound);
}
function set_opponentVolume(volume:Float):Float
{
opponentVoices.forEachAlive(function(voice:FunkinSound) {
opponentVoices?.forEachAlive(function(voice:FunkinSound) {
voice.volume = volume;
});
return opponentVolume = volume;
@ -106,26 +107,26 @@ class VoicesGroup extends SoundGroup
public function getPlayerVoice(index:Int = 0):Null<FunkinSound>
{
return playerVoices.members[index];
return playerVoices?.members[index];
}
public function getOpponentVoice(index:Int = 0):Null<FunkinSound>
{
return opponentVoices.members[index];
return opponentVoices?.members[index];
}
public function getPlayerVoiceWaveform():Null<WaveformData>
{
if (playerVoices.members.length == 0) return null;
if (playerVoices?.members.length == 0) return null;
return playerVoices.members[0].waveformData;
return playerVoices?.members[0].waveformData;
}
public function getOpponentVoiceWaveform():Null<WaveformData>
{
if (opponentVoices.members.length == 0) return null;
if (opponentVoices?.members.length == 0) return null;
return opponentVoices.members[0].waveformData;
return opponentVoices?.members[0].waveformData;
}
/**
@ -133,9 +134,9 @@ class VoicesGroup extends SoundGroup
*/
public function getPlayerVoiceLength():Float
{
if (playerVoices.members.length == 0) return 0.0;
if (playerVoices?.members.length == 0) return 0.0;
return playerVoices.members[0].length;
return playerVoices?.members[0]?.length ?? 0.0;
}
/**
@ -143,15 +144,15 @@ class VoicesGroup extends SoundGroup
*/
public function getOpponentVoiceLength():Float
{
if (opponentVoices.members.length == 0) return 0.0;
if (opponentVoices?.members.length == 0) return 0.0;
return opponentVoices.members[0].length;
return opponentVoices?.members[0]?.length ?? 0.0;
}
public override function clear():Void
{
playerVoices.clear();
opponentVoices.clear();
playerVoices?.clear();
opponentVoices?.clear();
super.clear();
}
@ -159,13 +160,13 @@ class VoicesGroup extends SoundGroup
{
if (playerVoices != null)
{
playerVoices.destroy();
playerVoices?.destroy();
playerVoices = null;
}
if (opponentVoices != null)
{
opponentVoices.destroy();
opponentVoices?.destroy();
opponentVoices = null;
}

View file

@ -3,6 +3,7 @@ package funkin.audio.visualize;
import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
@:nullSafety
class ABot extends FlxTypedSpriteGroup<FlxSprite>
{
public function new()

View file

@ -72,8 +72,8 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
// we use a very low minFreq since some songs use low low subbass like a boss
analyzer.minFreq = 10;
#if desktop
// On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5
#if sys
// On native it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5
// So we want to manually change it!
analyzer.fftN = 256;
#end
@ -116,7 +116,7 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
for (i in 0...min(group.members.length, levels.length))
{
var animFrame:Int = Math.round(levels[i].value * 6);
var animFrame:Int = (FlxG.sound.volume == 0 || FlxG.sound.muted) ? 0 : Math.round(levels[i].value * 6);
// don't display if we're at 0 volume from the level
group.members[i].visible = animFrame > 0;

View file

@ -3,11 +3,12 @@ package funkin.audio.visualize;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.sound.FlxSound;
@:nullSafety
class PolygonVisGroup extends FlxTypedGroup<PolygonSpectogram>
{
public var playerVis:PolygonSpectogram;
public var opponentVis:PolygonSpectogram;
public var instVis:PolygonSpectogram;
public var playerVis:Null<PolygonSpectogram>;
public var opponentVis:Null<PolygonSpectogram>;
public var instVis:Null<PolygonSpectogram>;
public function new()
{
@ -99,8 +100,14 @@ class PolygonVisGroup extends FlxTypedGroup<PolygonSpectogram>
public override function destroy():Void
{
playerVis.destroy();
opponentVis.destroy();
if (playerVis != null)
{
playerVis.destroy();
}
if (opponentVis != null)
{
opponentVis.destroy();
}
super.destroy();
}
}

View file

@ -4,6 +4,7 @@ package funkin.audio.visualize.dsp;
Complex number representation.
**/
@:forward(real, imag) @:notNull @:pure
@:nullSafety
abstract Complex({
final real:Float;
final imag:Float;

View file

@ -8,6 +8,7 @@ using funkin.audio.visualize.dsp.Signal;
/**
Fast/Finite Fourier Transforms.
**/
@:nullSafety
class FFT
{
/**

View file

@ -6,6 +6,7 @@ package funkin.audio.visualize.dsp;
Usages include 1-indexed sequences or zero-centered buffers with negative indexing.
**/
@:forward(array, offset)
@:nullSafety
abstract OffsetArray<T>({
final array:Array<T>;
final offset:Int;

View file

@ -5,12 +5,13 @@ using Lambda;
/**
Signal processing miscellaneous utilities.
**/
@:nullSafety
class Signal
{
/**
Returns a smoothed version of the input array using a moving average.
**/
public static function smooth(y:Array<Float>, n:Int):Array<Float>
public static function smooth(y:Array<Float>, n:Int):Null<Array<Float>>
{
if (n <= 0)
{

View file

@ -243,9 +243,10 @@ class WaveformDataChannel
}
/**
* Retrieve a given minimum point at an index.
* @param i Index
* @return minimum point at an index.
*/
public function minSample(i:Int)
public function minSample(i:Int):Int
{
var offset = (i * parent.channels + this.channelId) * 2;
return inline parent.get(offset);

View file

@ -1,7 +1,6 @@
package funkin.audio.waveform;
import funkin.util.TimerUtil;
@:nullSafety
class WaveformDataParser
{
static final INT16_MAX:Int = 32767;
@ -10,7 +9,7 @@ class WaveformDataParser
static final INT8_MAX:Int = 127;
static final INT8_MIN:Int = -128;
public static function interpretFlxSound(sound:flixel.sound.FlxSound):Null<WaveformData>
public static function interpretFlxSound(sound:Null<flixel.sound.FlxSound>):Null<WaveformData>
{
if (sound == null) return null;
@ -44,73 +43,58 @@ class WaveformDataParser
public static function interpretAudioBuffer(soundBuffer:lime.media.AudioBuffer):Null<WaveformData>
{
var sampleRate = soundBuffer.sampleRate;
var channels = soundBuffer.channels;
var bitsPerSample = soundBuffer.bitsPerSample;
var samplesPerPoint:Int = 256; // I don't think we need to configure this.
var pointsPerSecond:Float = sampleRate / samplesPerPoint; // 172 samples per second for most songs is plenty precise while still being performant..
// TODO: Make this work better on HTML5.
var soundData:lime.utils.Int16Array = cast soundBuffer.data;
var soundDataRawLength:Int = soundData.length;
var soundDataSampleCount:Int = Std.int(Math.ceil(soundDataRawLength / channels / (bitsPerSample == 16 ? 2 : 1)));
var soundDataSampleCount:Int = Std.int(Math.ceil(soundData.length / channels / (bitsPerSample == 16 ? 2 : 1)));
var outputPointCount:Int = Std.int(Math.ceil(soundDataSampleCount / samplesPerPoint));
// trace('Interpreting audio buffer:');
// trace(' sampleRate: ${sampleRate}');
// trace(' channels: ${channels}');
// trace(' bitsPerSample: ${bitsPerSample}');
// trace(' samplesPerPoint: ${samplesPerPoint}');
// trace(' pointsPerSecond: ${pointsPerSecond}');
// trace(' soundDataRawLength: ${soundDataRawLength}');
// trace(' soundDataSampleCount: ${soundDataSampleCount}');
// trace(' soundDataRawLength/4: ${soundDataRawLength / 4}');
// trace(' outputPointCount: ${outputPointCount}');
// Pre-allocate Vector with exact final size for better performance and memory efficiency
var outputDataLength:Int = outputPointCount * channels * 2;
var outputData = new haxe.ds.Vector<Int>(outputDataLength);
var minSampleValue:Int = bitsPerSample == 16 ? INT16_MIN : INT8_MIN;
var maxSampleValue:Int = bitsPerSample == 16 ? INT16_MAX : INT8_MAX;
var outputData:Array<Int> = [];
var perfStart:Float = TimerUtil.start();
// Reusable min/max tracking arrays to avoid allocation in the loop
var minValues = new haxe.ds.Vector<Int>(channels);
var maxValues = new haxe.ds.Vector<Int>(channels);
for (pointIndex in 0...outputPointCount)
{
// minChannel1, maxChannel1, minChannel2, maxChannel2, ...
var values:Array<Int> = [];
var rangeStart:Int = pointIndex * samplesPerPoint;
var rangeEnd:Int = Std.int(Math.min(rangeStart + samplesPerPoint, soundDataSampleCount));
// Reset min/max values for this range
for (i in 0...channels)
{
values.push(bitsPerSample == 16 ? INT16_MAX : INT8_MAX);
values.push(bitsPerSample == 16 ? INT16_MIN : INT8_MIN);
minValues[i] = bitsPerSample == 16 ? INT16_MAX : INT8_MAX;
maxValues[i] = bitsPerSample == 16 ? INT16_MIN : INT8_MIN;
}
var rangeStart = pointIndex * samplesPerPoint;
var rangeEnd = rangeStart + samplesPerPoint;
if (rangeEnd > soundDataSampleCount) rangeEnd = soundDataSampleCount;
// Process all samples in this range
for (sampleIndex in rangeStart...rangeEnd)
{
for (channelIndex in 0...channels)
{
var sampleIndex:Int = sampleIndex * channels + channelIndex;
var sampleValue = soundData[sampleIndex];
var sampleValue:Int = soundData[sampleIndex * channels + channelIndex];
if (sampleValue < values[channelIndex * 2]) values[(channelIndex * 2)] = sampleValue;
if (sampleValue > values[channelIndex * 2 + 1]) values[(channelIndex * 2) + 1] = sampleValue;
if (sampleValue < minValues[channelIndex]) minValues[channelIndex] = sampleValue;
if (sampleValue > maxValues[channelIndex]) maxValues[channelIndex] = sampleValue;
}
}
// We now have the min and max values for the range.
for (value in values)
outputData.push(value);
// Write directly to final positions in output Vector
var baseIndex:Int = pointIndex * channels * 2;
for (channelIndex in 0...channels)
{
outputData[baseIndex + channelIndex * 2] = minValues[channelIndex];
outputData[baseIndex + channelIndex * 2 + 1] = maxValues[channelIndex];
}
}
var outputDataLength:Int = Std.int(outputData.length / channels / 2);
var result = new WaveformData(null, channels, sampleRate, samplesPerPoint, bitsPerSample, outputPointCount, outputData);
trace('[WAVEFORM] Interpreted audio buffer in ${TimerUtil.seconds(perfStart)}.');
var result = new WaveformData(null, channels, soundBuffer.sampleRate, samplesPerPoint, bitsPerSample, outputPointCount, outputData.toArray());
return result;
}

View file

@ -15,6 +15,7 @@ typedef EntryConstructorFunction = String->Void;
* @param T The type to construct. Must implement `IRegistryEntry`.
* @param J The type of the JSON data used when constructing.
*/
@:nullSafety
@:generic
@:autoBuild(funkin.util.macro.DataRegistryMacro.buildRegistry())
abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructorFunction>), J>
@ -115,7 +116,7 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
{
try
{
var entry:T = createEntry(entryId);
var entry:Null<T> = createEntry(entryId);
if (entry != null)
{
trace(' Loaded entry data: ${entry}');
@ -165,7 +166,7 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
* @param id The ID of the entry.
* @return The class name, or `null` if it does not exist.
*/
public function getScriptedEntryClassName(id:String):String
public function getScriptedEntryClassName(id:String):Null<String>
{
return scriptedEntryIds.get(id);
}
@ -216,7 +217,7 @@ abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructo
public function fetchEntryVersion(id:String):Null<thx.semver.Version>
{
var entryStr:String = loadEntryFile(id).contents;
var entryVersion:thx.semver.Version = VersionUtil.getVersionFromJSON(entryStr);
var entryVersion:Null<thx.semver.Version> = VersionUtil.getVersionFromJSON(entryStr);
return entryVersion;
}

View file

@ -4,6 +4,7 @@ import json2object.Position;
import json2object.Position.Line;
import json2object.Error;
@:nullSafety
class DataError
{
public static function printError(error:Error):Void

View file

@ -19,6 +19,7 @@ import thx.semver.VersionRule;
*
* Functions must be of the signature `(hxjsonast.Json, String) -> T`, where the String is the property name and `T` is the type of the property.
*/
@:nullSafety
class DataParse
{
/**
@ -146,7 +147,6 @@ class DataParse
throw 'Expected Backdrop property $name to be specify a valid "type", but it was "${backdropType}".';
}
return null;
default:
throw 'Expected property $name to be an object, but it was ${json.value}.';
}
@ -310,6 +310,7 @@ class DataParse
var length:Null<Float> = values[2] == null ? null : Tools.getValue(values[2]);
var alt:Null<Bool> = values[3] == null ? null : Tools.getValue(values[3]);
if (time == null || data == null) throw 'Property $name note is missing time and/or data values.';
return new LegacyNote(time, data, length, alt);
// return null;
default:

View file

@ -12,6 +12,7 @@ import haxe.ds.Either;
*
* NOTE: Result must include quotation marks if the value is a string! json2object will not add them for you!
*/
@:nullSafety
class DataWrite
{
/**

View file

@ -1,8 +1,9 @@
package funkin.data.animation;
@:nullSafety
class AnimationDataUtil
{
public static function toNamed(data:UnnamedAnimationData, ?name:String = ""):AnimationData
public static function toNamed(data:UnnamedAnimationData, name:String = ""):AnimationData
{
return {
name: name,
@ -22,7 +23,7 @@ class AnimationDataUtil
* @param name (adds index to name)
* @return Array<AnimationData>
*/
public static function toNamedArray(data:Array<UnnamedAnimationData>, ?name:String = ""):Array<AnimationData>
public static function toNamedArray(data:Array<UnnamedAnimationData>, name:String = ""):Array<AnimationData>
{
return data.mapi(function(animItem, ind) return toNamed(animItem, '$name$ind'));
}

View file

@ -5,6 +5,7 @@ import funkin.play.cutscene.dialogue.ScriptedConversation;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class ConversationRegistry extends BaseRegistry<Conversation, ConversationData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -6,6 +6,7 @@ import funkin.play.cutscene.dialogue.ScriptedDialogueBox;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class DialogueBoxRegistry extends BaseRegistry<DialogueBox, DialogueBoxData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -5,6 +5,7 @@ import funkin.play.cutscene.dialogue.ScriptedSpeaker;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class SpeakerRegistry extends BaseRegistry<Speaker, SpeakerData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -8,6 +8,7 @@ import funkin.play.event.ScriptedSongEvent;
/**
* This class statically handles the parsing of internal and scripted song event handlers.
*/
@:nullSafety
class SongEventRegistry
{
/**
@ -87,14 +88,14 @@ class SongEventRegistry
return eventCache.values();
}
public static function getEvent(id:String):SongEvent
public static function getEvent(id:String):Null<SongEvent>
{
return eventCache.get(id);
}
public static function getEventSchema(id:String):SongEventSchema
public static function getEventSchema(id:String):Null<SongEventSchema>
{
var event:SongEvent = getEvent(id);
var event:Null<SongEvent> = getEvent(id);
if (event == null) return null;
return event.getEventSchema();
@ -108,7 +109,7 @@ class SongEventRegistry
public static function handleEvent(data:SongEventData):Void
{
var eventKind:String = data.eventKind;
var eventHandler:SongEvent = eventCache.get(eventKind);
var eventHandler:Null<SongEvent> = eventCache.get(eventKind);
if (eventHandler != null)
{

View file

@ -6,6 +6,7 @@ import funkin.ui.freeplay.ScriptedAlbum;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class AlbumRegistry extends BaseRegistry<Album, AlbumData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -7,6 +7,7 @@ import funkin.save.Save;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> implements ISingleton implements DefaultRegistryImpl
{
/**
@ -56,7 +57,11 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
var player = fetchEntry(charId);
if (player == null) continue;
#if UNLOCK_EVERYTHING
count++;
#else
if (player.isUnlocked()) count++;
#end
}
return count;
@ -64,6 +69,7 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
public function hasNewCharacter():Bool
{
#if (!UNLOCK_EVERYTHING)
var charactersSeen = Save.instance.charactersSeen.clone();
for (charId in listEntryIds())
@ -77,6 +83,7 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
// This character is unlocked but we haven't seen them in Freeplay yet.
return true;
}
#end
// Fallthrough case.
return false;
@ -84,9 +91,10 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
public function listNewCharacters():Array<String>
{
var charactersSeen = Save.instance.charactersSeen.clone();
var result = [];
#if (!UNLOCK_EVERYTHING)
var charactersSeen = Save.instance.charactersSeen.clone();
for (charId in listEntryIds())
{
var player = fetchEntry(charId);
@ -98,6 +106,7 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
// This character is unlocked but we haven't seen them in Freeplay yet.
result.push(charId);
}
#end
return result;
}
@ -116,6 +125,7 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
/**
* Return true if the given stage character is associated with a specific playable character.
* If so, the level should only appear if that character is selected in Freeplay.
* NOTE: This is NOT THE SAME as `player.isUnlocked()`!
* @param characterId The stage character ID.
* @return Whether the character is owned by any one character.
*/
@ -123,4 +133,17 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> impleme
{
return ownedCharacterIds.exists(characterId);
}
/**
* @param characterId The character ID to check.
* @return Whether the player saw the character unlock animation in Character Select.
*/
public function isCharacterSeen(characterId:String):Bool
{
#if UNLOCK_EVERYTHING
return true;
#else
return Save.instance.charactersSeen.contains(characterId);
#end
}
}

View file

@ -6,6 +6,7 @@ import funkin.ui.freeplay.ScriptedFreeplayStyle;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class FreeplayStyleRegistry extends BaseRegistry<FreeplayStyle, FreeplayStyleData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -6,6 +6,7 @@ import funkin.data.notestyle.NoteStyleData;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> implements ISingleton implements DefaultRegistryImpl
{
/**
@ -24,6 +25,8 @@ class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> implement
public function fetchDefault():NoteStyle
{
return fetchEntry(Constants.DEFAULT_NOTE_STYLE);
var notestyle:Null<NoteStyle> = fetchEntry(Constants.DEFAULT_NOTE_STYLE);
if (notestyle == null) throw 'Default notestyle was null! This should not happen!';
return notestyle;
}
}

View file

@ -68,11 +68,12 @@ class SongMetadata implements ICloneable<SongMetadata>
@:jignored
public var variation:String;
public function new(songName:String, artist:String, ?variation:String)
public function new(songName:String, artist:String, ?charter:String, ?variation:String)
{
this.version = SongRegistry.SONG_METADATA_VERSION;
this.songName = songName;
this.artist = artist;
this.charter = (charter == null) ? null : charter;
this.timeFormat = 'ms';
this.divisions = null;
this.offsets = new SongOffsets();
@ -96,7 +97,7 @@ class SongMetadata implements ICloneable<SongMetadata>
*/
public function clone():SongMetadata
{
var result:SongMetadata = new SongMetadata(this.songName, this.artist, this.variation);
var result:SongMetadata = new SongMetadata(this.songName, this.artist, this.charter, this.variation);
result.version = this.version;
result.timeFormat = this.timeFormat;
result.divisions = this.divisions;
@ -139,7 +140,7 @@ class SongMetadata implements ICloneable<SongMetadata>
*/
public function toString():String
{
return 'SongMetadata(${this.songName} by ${this.artist}, variation ${this.variation})';
return 'SongMetadata(${this.songName} by ${this.artist}, charted by ${this.charter}, variation ${this.variation})';
}
}
@ -1116,6 +1117,23 @@ class SongNoteDataRaw implements ICloneable<SongNoteDataRaw>
return 'SongNoteData(${this.time}ms, ' + (this.length > 0 ? '[${this.length}ms hold]' : '') + ' ${this.data}'
+ (this.kind != '' ? ' [kind: ${this.kind}])' : ')');
}
public function buildTooltip():String
{
if ((this.kind?.length ?? 0) == 0) return "";
var result:String = 'Kind: ${this.kind}';
if (this.params.length == 0) return result;
result += "\nParams:";
for (param in params)
{
result += '\n- ${param.name}: ${param.value}';
}
return result;
}
}
/**

View file

@ -5,13 +5,13 @@ import funkin.data.song.SongData.SongEventData;
import funkin.data.song.SongData.SongNoteData;
import funkin.data.song.SongData.SongTimeChange;
import funkin.util.ClipboardUtil;
import funkin.util.SerializerUtil;
using Lambda;
/**
* Utility functions for working with song data, including note data, event data, metadata, etc.
*/
@:nullSafety
class SongDataUtils
{
/**
@ -28,7 +28,7 @@ class SongDataUtils
var time:Float = note.time + offset;
var data:Int = note.data;
var length:Float = note.length;
var kind:String = note.kind;
var kind:Null<String> = note.kind;
return new SongNoteData(time, data, length, kind);
};
@ -132,7 +132,7 @@ class SongDataUtils
* Create an array of notes whose note data is flipped (player becomes opponent and vice versa)
* Does not mutate the original array.
*/
public static function flipNotes(notes:Array<SongNoteData>, ?strumlineSize:Int = 4):Array<SongNoteData>
public static function flipNotes(notes:Array<SongNoteData>, strumlineSize:Int = 4):Array<SongNoteData>
{
return notes.map(function(note:SongNoteData):SongNoteData {
var newData = note.data;
@ -150,7 +150,7 @@ class SongDataUtils
*
* Offset the provided array of notes such that the first note is at 0 milliseconds.
*/
public static function buildNoteClipboard(notes:Array<SongNoteData>, ?timeOffset:Int = null):Array<SongNoteData>
public static function buildNoteClipboard(notes:Array<SongNoteData>, ?timeOffset:Int):Array<SongNoteData>
{
if (notes.length == 0) return notes;
if (timeOffset == null) timeOffset = Std.int(notes[0].time);
@ -162,7 +162,7 @@ class SongDataUtils
*
* Offset the provided array of events such that the first event is at 0 milliseconds.
*/
public static function buildEventClipboard(events:Array<SongEventData>, ?timeOffset:Int = null):Array<SongEventData>
public static function buildEventClipboard(events:Array<SongEventData>, ?timeOffset:Int):Array<SongEventData>
{
if (events.length == 0) return events;
if (timeOffset == null) timeOffset = Std.int(events[0].time);

View file

@ -0,0 +1,138 @@
package funkin.data.song;
using SongData.SongNoteData;
/**
* Utility class for extra handling of song notes
*/
@:nullSafety
class SongNoteDataUtils
{
static final CHUNK_INTERVAL_MS:Float = 2500;
/**
* Retrieves all stacked notes. It does this by cycling through "chunks" of notes within a certain interval.
*
* @param notes Sorted notes by time.
* @param threshold The note stack threshold. Refer to `doNotesStack` for more details.
* @param includeOverlapped (Optional) If overlapped notes should be included.
* @param overlapped (Optional) An array that gets populated with overlapped notes.
* Note that it's only guaranteed to work properly if the provided notes are sorted.
* @return Stacked notes.
*/
public static function listStackedNotes(notes:Array<SongNoteData>, threshold:Float, includeOverlapped:Bool = true,
?overlapped:Array<SongNoteData>):Array<SongNoteData>
{
var stackedNotes:Array<SongNoteData> = [];
var chunkTime:Float = 0;
var chunks:Array<Array<SongNoteData>> = [[]];
for (note in notes)
{
if (note == null)
{
continue;
}
while (note.time >= chunkTime + CHUNK_INTERVAL_MS)
{
chunkTime += CHUNK_INTERVAL_MS;
chunks.push([]);
}
chunks[chunks.length - 1].push(note);
}
for (chunk in chunks)
{
for (i in 0...(chunk.length - 1))
{
for (j in (i + 1)...chunk.length)
{
var noteI:SongNoteData = chunk[i];
var noteJ:SongNoteData = chunk[j];
if (doNotesStack(noteI, noteJ, threshold))
{
if (!stackedNotes.fastContains(noteI))
{
if (includeOverlapped) stackedNotes.push(noteI);
if (overlapped != null && !overlapped.contains(noteI)) overlapped.push(noteI);
}
if (!stackedNotes.fastContains(noteJ))
{
stackedNotes.push(noteJ);
}
}
}
}
}
return stackedNotes;
}
/**
* Concatenates two arrays of notes but overwrites notes in `lhs` that are overlapped by notes in `rhs`.
* Hold notes are only overwritten by longer hold notes.
* This operation only modifies the second array and `overwrittenNotes`.
*
* @param lhs An array of notes
* @param rhs An array of notes to concatenate into `lhs`
* @param overwrittenNotes An optional array that is modified in-place with the notes in `lhs` that were overwritten.
* @param threshold The note stack threshold. Refer to `doNotesStack` for more details.
* @return The unsorted resulting array.
*/
public static function concatOverwrite(lhs:Array<SongNoteData>, rhs:Array<SongNoteData>, ?overwrittenNotes:Array<SongNoteData>,
threshold:Float = 0):Array<SongNoteData>
{
if (lhs == null || rhs == null || rhs.length == 0) return lhs;
if (lhs.length == 0) return rhs;
var result = lhs.copy();
for (i in 0...rhs.length)
{
var noteB:SongNoteData = rhs[i];
var hasOverlap:Bool = false;
for (j in 0...lhs.length)
{
var noteA:SongNoteData = lhs[j];
if (doNotesStack(noteA, noteB, threshold))
{
// Long hold notes should have priority over shorter hold notes
if (noteA.length <= noteB.length)
{
overwrittenNotes?.push(result[j].clone());
result[j] = noteB;
}
hasOverlap = true;
break;
}
}
if (!hasOverlap) result.push(noteB);
}
return result;
}
/**
* @param noteA First note.
* @param noteB Second note.
* @param threshold The note stack threshold, in steps.
* @return Returns `true` if both notes are on the same strumline, have the same direction
* and their time difference in steps is less than the step-based threshold.
* A threshold of 0 will return `true` if notes are nearly perfectly aligned.
*/
public static function doNotesStack(noteA:SongNoteData, noteB:SongNoteData, threshold:Float = 0):Bool
{
if (noteA.data != noteB.data) return false;
else if (threshold == 0) return Math.ffloor(Math.abs(noteA.time - noteB.time)) < 1;
final stepDiff:Float = Math.abs(noteA.getStepTime() - noteB.getStepTime());
return stepDiff <= threshold + 0.001;
}
}

View file

@ -324,7 +324,7 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
}
else
{
throw '[${registryId}] Chart entry ${id}:${variation} does not support migration to version ${SONG_CHART_DATA_VERSION_RULE}.';
throw '[${registryId}] Chart entry ${id}:${variation} does not support migration to version ${SONG_MUSIC_DATA_VERSION_RULE}.';
}
}
@ -337,7 +337,7 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> implements ISingleto
}
else
{
throw '[${registryId}] Chart entry "$fileName" does not support migration to version ${SONG_CHART_DATA_VERSION_RULE}.';
throw '[${registryId}] Chart entry "$fileName" does not support migration to version ${SONG_MUSIC_DATA_VERSION_RULE}.';
}
}

View file

@ -9,9 +9,10 @@ import funkin.data.song.SongData.SongTimeChange;
import funkin.data.song.importer.FNFLegacyData;
import funkin.data.song.importer.FNFLegacyData.LegacyNoteSection;
@:nullSafety
class FNFLegacyImporter
{
public static function parseLegacyDataRaw(input:String, fileName:String = 'raw'):FNFLegacyData
public static function parseLegacyDataRaw(input:String, fileName:String = 'raw'):Null<FNFLegacyData>
{
var parser = new json2object.JsonParser<FNFLegacyData>();
parser.ignoreUnknownVariables = true; // Set to true to ignore extra variables that might be included in the JSON.
@ -36,18 +37,16 @@ class FNFLegacyImporter
{
trace('Migrating song metadata from FNF Legacy.');
var songMetadata:SongMetadata = new SongMetadata('Import', Constants.DEFAULT_ARTIST, 'default');
var hadError:Bool = false;
var songMetadata:SongMetadata = new SongMetadata('Import', Constants.DEFAULT_ARTIST, Constants.DEFAULT_CHARTER, Constants.DEFAULT_VARIATION);
// Set generatedBy string for debugging.
songMetadata.generatedBy = 'Chart Editor Import (FNF Legacy)';
songMetadata.playData.stage = songData?.song?.stageDefault ?? 'mainStage';
songMetadata.songName = songData?.song?.song ?? 'Import';
songMetadata.playData.stage = songData.song?.stageDefault ?? 'mainStage';
songMetadata.songName = songData.song?.song ?? 'Import';
songMetadata.playData.difficulties = [];
if (songData?.song?.notes != null)
if (songData.song?.notes != null)
{
switch (songData.song.notes)
{
@ -65,7 +64,7 @@ class FNFLegacyImporter
songMetadata.timeChanges = rebuildTimeChanges(songData);
songMetadata.playData.characters = new SongCharacterData(songData?.song?.player1 ?? 'bf', 'gf', songData?.song?.player2 ?? 'dad');
songMetadata.playData.characters = new SongCharacterData(songData.song?.player1 ?? 'bf', 'gf', songData.song?.player2 ?? 'dad');
return songMetadata;
}
@ -76,7 +75,7 @@ class FNFLegacyImporter
var songChartData:SongChartData = new SongChartData([difficulty => 1.0], [], [difficulty => []]);
if (songData?.song?.notes != null)
if (songData.song?.notes != null)
{
switch (songData.song.notes)
{
@ -84,7 +83,6 @@ class FNFLegacyImporter
// One difficulty of notes.
songChartData.notes.set(difficulty, migrateNoteSections(notes));
case Right(difficulties):
var baseDifficulty = null;
if (difficulties.easy != null) songChartData.notes.set('easy', migrateNoteSections(difficulties.easy));
if (difficulties.normal != null) songChartData.notes.set('normal', migrateNoteSections(difficulties.normal));
if (difficulties.hard != null) songChartData.notes.set('hard', migrateNoteSections(difficulties.hard));
@ -124,8 +122,8 @@ class FNFLegacyImporter
noteSections = notes;
case Right(difficulties):
if (difficulties.normal != null) noteSections = difficulties.normal;
if (difficulties.hard != null) noteSections = difficulties.normal;
if (difficulties.easy != null) noteSections = difficulties.normal;
if (difficulties.hard != null) noteSections = difficulties.hard;
if (difficulties.easy != null) noteSections = difficulties.easy;
}
if (noteSections == null || noteSections.length == 0) return result;
@ -158,7 +156,7 @@ class FNFLegacyImporter
{
var result:Array<SongTimeChange> = [];
result.push(new SongTimeChange(0, songData?.song?.bpm ?? Constants.DEFAULT_BPM));
result.push(new SongTimeChange(0, songData.song?.bpm ?? Constants.DEFAULT_BPM));
var noteSections = [];
switch (songData.song.notes)
@ -168,8 +166,8 @@ class FNFLegacyImporter
noteSections = notes;
case Right(difficulties):
if (difficulties.normal != null) noteSections = difficulties.normal;
if (difficulties.hard != null) noteSections = difficulties.normal;
if (difficulties.easy != null) noteSections = difficulties.normal;
if (difficulties.hard != null) noteSections = difficulties.hard;
if (difficulties.easy != null) noteSections = difficulties.easy;
}
if (noteSections == null || noteSections.length == 0) return result;
@ -179,7 +177,7 @@ class FNFLegacyImporter
if (noteSection.changeBPM ?? false)
{
var firstNote:LegacyNote = noteSection.sectionNotes[0];
if (firstNote != null) result.push(new SongTimeChange(firstNote.time, noteSection.bpm));
if (firstNote != null) result.push(new SongTimeChange(firstNote.time, noteSection.bpm ?? Constants.DEFAULT_BPM));
}
}

View file

@ -24,7 +24,7 @@ class SongDataMigrator
public static function migrate_SongMetadata_v2_1_0(input:SongData_v2_1_0.SongMetadata_v2_1_0):SongMetadata
{
var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation);
var result:SongMetadata = new SongMetadata(input.songName, input.artist, Constants.DEFAULT_CHARTER, input.variation);
result.version = SongRegistry.SONG_METADATA_VERSION;
result.timeFormat = input.timeFormat;
result.divisions = input.divisions;
@ -66,7 +66,7 @@ class SongDataMigrator
public static function migrate_SongMetadata_v2_0_0(input:SongData_v2_0_0.SongMetadata_v2_0_0):SongMetadata
{
var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation);
var result:SongMetadata = new SongMetadata(input.songName, input.artist, Constants.DEFAULT_CHARTER, input.variation);
result.version = SongRegistry.SONG_METADATA_VERSION;
result.timeFormat = input.timeFormat;
result.divisions = input.divisions;

View file

@ -205,7 +205,7 @@ typedef StageDataProp =
/**
* The angle of the prop, as a float.
* @default 1.0
* @default 0.0
*/
@:optional
@:default(0.0)
@ -284,7 +284,7 @@ typedef StageDataCharacter =
/**
* The angle of the character, as a float.
* @default 1.0
* @default 0.0
*/
@:optional
@:default(0.0)

View file

@ -5,6 +5,7 @@ import funkin.play.stage.ScriptedStage;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class StageRegistry extends BaseRegistry<Stage, StageData> implements ISingleton implements DefaultRegistryImpl
{
/**
@ -12,7 +13,7 @@ class StageRegistry extends BaseRegistry<Stage, StageData> implements ISingleton
* Handle breaking changes by incrementing this value
* and adding migration to the `migrateStageData()` function.
*/
public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.3";
public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.2";
public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = ">=1.0.0 <1.1.0";

View file

@ -4,6 +4,7 @@ import funkin.data.stickers.StickerData;
import funkin.ui.transition.stickers.StickerPack;
import funkin.ui.transition.stickers.ScriptedStickerPack;
@:nullSafety
class StickerRegistry extends BaseRegistry<StickerPack, StickerData>
{
/**
@ -24,7 +25,9 @@ class StickerRegistry extends BaseRegistry<StickerPack, StickerData>
public function fetchDefault():StickerPack
{
return fetchEntry(Constants.DEFAULT_STICKER_PACK);
var stickerPack:Null<StickerPack> = fetchEntry(Constants.DEFAULT_STICKER_PACK);
if (stickerPack == null) throw 'Default sticker pack was null! This should not happen!';
return stickerPack;
}
/**

View file

@ -6,6 +6,7 @@ import funkin.ui.story.ScriptedLevel;
import funkin.util.tools.ISingleton;
import funkin.data.DefaultRegistryImpl;
@:nullSafety
class LevelRegistry extends BaseRegistry<Level, LevelData> implements ISingleton implements DefaultRegistryImpl
{
/**

View file

@ -0,0 +1,70 @@
package funkin.external.android;
#if android
import lime.system.JNI;
import flixel.util.FlxSignal;
/**
* A Utility class to handle Android API level callbacks and events.
*/
@:unreflective
class CallbackUtil
{
/**
* The result code for `DATA_FOLDER_CLOSED` activity.
*/
public static var DATA_FOLDER_CLOSED(get, never):Int;
@:noCompletion
static function get_DATA_FOLDER_CLOSED():Int
{
final field:Null<Dynamic> = JNIUtil.createStaticField('funkin/extensions/CallbackUtil', 'DATA_FOLDER_CLOSED', 'I');
return field != null ? field.get() : 0;
}
/**
* Signal triggered when an activity result is received.
*
* First argument is the request code, second is the result code.
*/
public static var onActivityResult:FlxTypedSignal<Int->Int->Void> = new FlxTypedSignal<Int->Int->Void>();
/**
* Initializes the callback utility.
*/
public static function init():Void
{
final initCallBackJNI:Null<Dynamic> = JNIUtil.createStaticMethod('funkin/extensions/CallbackUtil', 'initCallBack', '(Lorg/haxe/lime/HaxeObject;)V');
if (initCallBackJNI != null)
{
initCallBackJNI(new CallbackHandler());
}
}
}
/**
* Internal class to handle native callback events.
*/
class CallbackHandler #if (lime >= "8.0.0") implements JNISafety #end
{
@:allow(funkin.external.android.CallbackUtil)
function new():Void {}
/**
* Handles the activity result callback from native code.
*
* @param requestCode The request code of the acitivty.
* @param resultCode The result code of the acitivty.
*/
@:keep
#if (lime >= "8.0.0")
@:runOnMainThread
#end
public function onActivityResult(requestCode:Int, resultCode:Int):Void
{
if (CallbackUtil.onActivityResult != null) CallbackUtil.onActivityResult.dispatch(requestCode, resultCode);
}
}
#end

View file

@ -0,0 +1,23 @@
package funkin.external.android;
#if android
/**
* A Utility class to manage the Application's Data folder on Android.
*/
@:unreflective
class DataFolderUtil
{
/**
* Opens the data folder on an Android device using JNI.
*/
public static function openDataFolder():Void
{
final openDataFolderJNI:Null<Dynamic> = JNIUtil.createStaticMethod('funkin/util/DataFolderUtil', 'openDataFolder', '(I)V');
if (openDataFolderJNI != null)
{
openDataFolderJNI(CallbackUtil.DATA_FOLDER_CLOSED);
}
}
}
#end

View file

@ -0,0 +1,111 @@
package funkin.external.android;
#if android
import lime.system.JNI;
/**
* A utility class for caching JNI method and field references.
*/
class JNIUtil
{
@:noCompletion
private static var staticMethodCache:Map<String, Dynamic> = [];
@:noCompletion
private static var memberMethodCache:Map<String, Dynamic> = [];
@:noCompletion
private static var staticFieldCache:Map<String, JNIStaticField> = [];
@:noCompletion
private static var memberFieldCache:Map<String, JNIMemberField> = [];
/**
* Retrieves or creates a cached static method reference.
*
* @param className The name of the Java class containing the method.
* @param methodName The name of the method.
* @param signature The method signature in JNI format.
* @param cache Whether to cache the result (default true).
* @return A dynamic reference to the static method.
*/
public static function createStaticMethod(className:String, methodName:String, signature:String, cache:Bool = true):Null<Dynamic>
{
@:privateAccess
className = JNI.transformClassName(className);
final key:String = '$className::$methodName::$signature';
if (cache && !staticMethodCache.exists(key)) staticMethodCache.set(key, JNI.createStaticMethod(className, methodName, signature));
else if (!cache) return JNI.createStaticMethod(className, methodName, signature);
return staticMethodCache.get(key);
}
/**
* Retrieves or creates a cached member method reference.
*
* @param className The name of the Java class containing the method.
* @param methodName The name of the method.
* @param signature The method signature in JNI format.
* @param cache Whether to cache the result (default true).
* @return A dynamic reference to the member method.
*/
public static function createMemberMethod(className:String, methodName:String, signature:String, cache:Bool = true):Null<Dynamic>
{
@:privateAccess
className = JNI.transformClassName(className);
final key:String = '$className::$methodName::$signature';
if (cache && !memberMethodCache.exists(key)) memberMethodCache.set(key, JNI.createMemberMethod(className, methodName, signature));
else if (!cache) return JNI.createMemberMethod(className, methodName, signature);
return memberMethodCache.get(key);
}
/**
* Retrieves or creates a cached static field reference.
*
* @param className The name of the Java class containing the field.
* @param fieldName The name of the field.
* @param signature The field signature in JNI format.
* @param cache Whether to cache the result (default true).
* @return A reference to the static field.
*/
public static function createStaticField(className:String, fieldName:String, signature:String, cache:Bool = true):Null<JNIStaticField>
{
@:privateAccess
className = JNI.transformClassName(className);
final key:String = '$className::$fieldName::$signature';
if (cache && !staticFieldCache.exists(key)) staticFieldCache.set(key, JNI.createStaticField(className, fieldName, signature));
else if (!cache) return JNI.createStaticField(className, fieldName, signature);
return staticFieldCache.get(key);
}
/**
* Retrieves or creates a cached member field reference.
*
* @param className The name of the Java class containing the field.
* @param fieldName The name of the field.
* @param signature The field signature in JNI format.
* @param cache Whether to cache the result (default true).
* @return A reference to the member field.
*/
public static function createMemberField(className:String, fieldName:String, signature:String, cache:Bool = true):Null<JNIMemberField>
{
@:privateAccess
className = JNI.transformClassName(className);
final key:String = '$className::$fieldName::$signature';
if (cache && !memberFieldCache.exists(key)) memberFieldCache.set(key, JNI.createMemberField(className, fieldName, signature));
else if (!cache) return JNI.createMemberField(className, fieldName, signature);
return memberFieldCache.get(key);
}
}
#end

View file

@ -0,0 +1,52 @@
package funkin.external.android;
#if android
import lime.math.Rectangle;
import lime.system.JNI;
/**
* A Utility class to get Android screen related informations.
*/
@:unreflective
class ScreenUtil
{
/**
* Retrieves the dimensions of display cutouts (such as notches) on Android devices.
*
* @return An array of `Rectangle` objects, each representing a display cutout's position and size.
*/
public static function getCutoutDimensions():Array<Rectangle>
{
final getCutoutDimensionsJNI:Null<Dynamic> = JNIUtil.createStaticMethod('funkin/util/ScreenUtil', 'getCutoutDimensions', '()[Landroid/graphics/Rect;');
if (getCutoutDimensionsJNI != null)
{
final rectangles:Array<Rectangle> = [];
for (rectangle in cast(getCutoutDimensionsJNI(), Array<Dynamic>))
{
if (rectangle == null) continue;
final topJNI:Null<JNIMemberField> = JNIUtil.createMemberField('android/graphics/Rect', 'top', 'I');
final leftJNI:Null<JNIMemberField> = JNIUtil.createMemberField('android/graphics/Rect', 'left', 'I');
final rightJNI:Null<JNIMemberField> = JNIUtil.createMemberField('android/graphics/Rect', 'right', 'I');
final bottomJNI:Null<JNIMemberField> = JNIUtil.createMemberField('android/graphics/Rect', 'bottom', 'I');
if (topJNI != null && leftJNI != null && rightJNI != null && bottomJNI != null)
{
final top:Int = topJNI.get(rectangle);
final left:Int = leftJNI.get(rectangle);
final right:Int = rightJNI.get(rectangle);
final bottom:Int = bottomJNI.get(rectangle);
rectangles.push(new Rectangle(left, top, right - left, bottom - top));
}
}
return rectangles;
}
return [];
}
}
#end

View file

@ -0,0 +1,36 @@
package funkin.extensions;
import android.content.Intent;
import org.haxe.extension.Extension;
import org.haxe.lime.HaxeObject;
public class CallbackUtil extends Extension
{
/**
* Constant representing the event when the data folder is closed.
*/
public static int DATA_FOLDER_CLOSED = 0x01;
private static HaxeObject haxeObject;
/**
* Initializes the callback object for handling Haxe callbacks.
*
* @param haxeObject The HaxeObject instance to handle callbacks.
*/
public static void initCallBack(final HaxeObject haxeObject)
{
CallbackUtil.haxeObject = haxeObject;
}
@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data)
{
if (haxeObject != null)
haxeObject.call2("onActivityResult", requestCode, resultCode);
return true;
}
}

View file

@ -0,0 +1,346 @@
package funkin.provider;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Point;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
import android.webkit.MimeTypeMap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
/**
* @see https://github.com/termux/termux-app/blob/7bceab88e2272f961d1b94ef736f1a9e20173247/app/src/main/java/com/termux/filepicker/TermuxDocumentsProvider.java
*/
public class DataFolderProvider extends DocumentsProvider
{
private static File BASE_DIR;
private static String BASE_DIR_PATH;
private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
Root.COLUMN_ROOT_ID,
Root.COLUMN_MIME_TYPES,
Root.COLUMN_FLAGS,
Root.COLUMN_ICON,
Root.COLUMN_TITLE,
Root.COLUMN_SUMMARY,
Root.COLUMN_DOCUMENT_ID,
Root.COLUMN_AVAILABLE_BYTES
};
private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
Document.COLUMN_DOCUMENT_ID,
Document.COLUMN_MIME_TYPE,
Document.COLUMN_DISPLAY_NAME,
Document.COLUMN_LAST_MODIFIED,
Document.COLUMN_FLAGS,
Document.COLUMN_SIZE
};
@Override
public Cursor queryRoots(String[] projection)
{
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION);
if (BASE_DIR == null)
return result;
final MatrixCursor.RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, getDocIdForFile(BASE_DIR));
row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(BASE_DIR));
row.add(Root.COLUMN_SUMMARY, "Data Folder");
row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD);
row.add(Root.COLUMN_TITLE, "::APP_TITLE::");
row.add(Root.COLUMN_MIME_TYPES, "*/*");
row.add(Root.COLUMN_AVAILABLE_BYTES, BASE_DIR.getFreeSpace());
::if (APP_PACKAGE != "")::
row.add(Root.COLUMN_ICON, ::APP_PACKAGE::.R.mipmap.ic_launcher);
::end::
return result;
}
@Override
public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException
{
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
includeFile(result, documentId, null);
return result;
}
@Override
public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException
{
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
File parent = getFileForDocId(parentDocumentId);
if (parent != null)
{
File[] children = null;
try {
children = parent.listFiles();
} catch (SecurityException e) {
children = new File[0];
}
if (children != null)
{
for (File file : children)
includeFile(result, null, file);
}
}
return result;
}
@Override
public ParcelFileDescriptor openDocument(String documentId, String mode, CancellationSignal signal) throws FileNotFoundException
{
return ParcelFileDescriptor.open(getFileForDocId(documentId), ParcelFileDescriptor.parseMode(mode));
}
@Override
public AssetFileDescriptor openDocumentThumbnail(String documentId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException
{
final File file = getFileForDocId(documentId);
final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return new AssetFileDescriptor(pfd, 0, file.length());
}
@Override
public boolean onCreate()
{
BASE_DIR = getContext().getExternalFilesDir(null);
if (BASE_DIR == null)
return false;
try
{
BASE_DIR_PATH = BASE_DIR.getCanonicalPath();
}
catch (IOException e)
{
BASE_DIR_PATH = BASE_DIR.getAbsolutePath();
}
return true;
}
@Override
public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException
{
File parentFile = getFileForDocId(parentDocumentId);
File newFile = new File(parentFile, displayName);
int noConflictId = 2;
while (newFile.exists())
{
newFile = new File(parentFile, displayName + " (" + noConflictId++ + ")");
}
try
{
boolean succeeded;
if (Document.MIME_TYPE_DIR.equals(mimeType))
succeeded = newFile.mkdir();
else
succeeded = newFile.createNewFile();
if (!succeeded)
throw new FileNotFoundException("Failed to create document with id " + newFile.getPath());
}
catch (IOException e)
{
throw new FileNotFoundException("Failed to create document with id " + newFile.getPath());
}
return newFile.getPath();
}
@Override
public void deleteDocument(String documentId) throws FileNotFoundException
{
if (!deleteRecursive(getFileForDocId(documentId)))
throw new FileNotFoundException("Failed to delete document with id " + documentId);
}
@Override
public String getDocumentType(String documentId) throws FileNotFoundException
{
return getMimeType(getFileForDocId(documentId));
}
@Override
public Cursor querySearchDocuments(String rootId, String query, String[] projection) throws FileNotFoundException
{
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
final LinkedList<File> pending = new LinkedList<>();
pending.add(getFileForDocId(rootId));
final int MAX_SEARCH_RESULTS = 50;
while (!pending.isEmpty() && result.getCount() < MAX_SEARCH_RESULTS)
{
final File file = pending.removeFirst();
boolean isInsideHome;
try
{
isInsideHome = file.getCanonicalPath().startsWith(BASE_DIR_PATH);
}
catch (IOException e)
{
isInsideHome = true;
}
if (isInsideHome)
{
if (file.isDirectory())
{
try {
Collections.addAll(pending, file.listFiles());
} catch (SecurityException e) {
// ignore
}
}
else if (file.getName().toLowerCase().contains(query))
{
includeFile(result, null, file);
}
}
}
return result;
}
@Override
public boolean isChildDocument(String parentDocumentId, String documentId)
{
try
{
File parent = getFileForDocId(parentDocumentId).getCanonicalFile();
File child = getFileForDocId(documentId).getCanonicalFile();
return child.getPath().startsWith(parent.getPath() + "/");
}
catch (IOException e)
{
return false;
}
}
private boolean deleteRecursive(File file)
{
if (file.isDirectory())
{
File[] children = file.listFiles();
if (children != null)
{
for (File child : children)
{
if (!deleteRecursive(child))
return false;
}
}
}
return file.delete();
}
private static String getDocIdForFile(File file)
{
return file.getAbsolutePath();
}
private static File getFileForDocId(String docId) throws FileNotFoundException
{
if (BASE_DIR == null)
throw new FileNotFoundException("Base directory not available");
final File f = (docId == null || docId.isEmpty()) ? BASE_DIR : new File(docId);
if (!f.exists())
throw new FileNotFoundException(f.getAbsolutePath() + " not found");
return f;
}
private static String getMimeType(File file)
{
if (file == null || file.isDirectory())
return Document.MIME_TYPE_DIR;
String name = file.getName();
int lastDot = name.lastIndexOf('.');
if (lastDot >= 0)
{
String extension = name.substring(lastDot + 1).toLowerCase();
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mime != null)
return mime;
}
return "application/octet-stream";
}
private void includeFile(MatrixCursor result, String docId, File file) throws FileNotFoundException
{
if (docId == null)
docId = getDocIdForFile(file);
else
file = getFileForDocId(docId);
int flags = 0;
if (file.isDirectory())
{
if (file.canWrite())
flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
}
else if (file.canWrite())
{
flags |= Document.FLAG_SUPPORTS_WRITE;
}
if (file.getParentFile() != null && file.getParentFile().canWrite())
flags |= Document.FLAG_SUPPORTS_DELETE;
final String mimeType = getMimeType(file);
if (mimeType.startsWith("image/"))
flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
final MatrixCursor.RowBuilder row = result.newRow();
row.add(Document.COLUMN_DOCUMENT_ID, docId);
row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
row.add(Document.COLUMN_SIZE, file.length());
row.add(Document.COLUMN_MIME_TYPE, mimeType);
row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
row.add(Document.COLUMN_FLAGS, flags);
::if (APP_PACKAGE != "")::
row.add(Document.COLUMN_ICON, ::APP_PACKAGE::.R.mipmap.ic_launcher);
::end::
}
}

View file

@ -0,0 +1,34 @@
package funkin.util;
import android.content.Intent;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.content.pm.PackageInfo;
import java.util.List;
import org.haxe.extension.Extension;
public class DataFolderUtil
{
/**
* A method that opens the Application's data folder for browsing through the Storage Access Framework.
* It's highly based on some code borrowed from Mterial Files
* https://github.com/zhanghai/MaterialFiles
*/
public static void openDataFolder(int requestCode)
{
::if (APP_PACKAGE != "")::
if (Extension.mainActivity != null)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(DocumentsContract.buildRootUri("::APP_PACKAGE::.docprovider", ""), "vnd.android.document/directory");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Extension.mainActivity.startActivityForResult(intent, requestCode);
}
::end::
}
}

View file

@ -0,0 +1,39 @@
package funkin.util;
import android.graphics.Rect;
import android.os.Build;
import android.view.DisplayCutout;
import android.view.WindowInsets;
import java.util.List;
import org.haxe.extension.Extension;
public class ScreenUtil
{
public static Rect[] getCutoutDimensions()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
{
if (Extension.mainActivity != null)
{
WindowInsets insets = Extension.mainActivity.getWindow().getDecorView().getRootWindowInsets();
if (insets != null)
{
DisplayCutout cutout = insets.getDisplayCutout();
if (cutout != null)
{
List<Rect> boundingRects = cutout.getBoundingRects();
if (boundingRects != null && !boundingRects.isEmpty())
return boundingRects.toArray(new Rect[0]);
}
}
}
}
return new Rect[0];
}
}

View file

@ -0,0 +1,17 @@
package funkin.external.ios;
#if ios
/**
* A Utility class to manage iOS audio.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('AudioSession.hpp')
@:unreflective
extern class AudioSession
{
@:native('initialize')
static function initialize():Void;
@:native('setActive')
static function setActive(active:Bool):Void;
}
#end

View file

@ -0,0 +1,18 @@
package funkin.external.ios;
#if ios
/**
* A Utility class to get iOS screen related informations.
*/
@:build(funkin.util.macro.LinkerMacro.xml('project/Build.xml'))
@:include('ScreenUtil.hpp')
@:unreflective
extern class ScreenUtil
{
@:native('getSafeAreaInsets')
static function getSafeAreaInsets(top:cpp.RawPointer<Float>, bottom:cpp.RawPointer<Float>, left:cpp.RawPointer<Float>, right:cpp.RawPointer<Float>):Void;
@:native('getScreenSize')
static function getScreenSize(width:cpp.RawPointer<Float>, height:cpp.RawPointer<Float>):Void;
}
#end

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<pragma once="true" />
<files id="haxe">
<compilerflag value="-I${this_dir}/ios/include" if="iphoneos || iphonesim" />
</files>
<files id="__main__">
<compilerflag value="-I${this_dir}/ios/include" if="iphoneos || iphonesim" />
</files>
<files id="external-ios" dir="${this_dir}/ios" if="iphoneos || iphonesim">
<compilerflag value="-I${this_dir}/ios/include" />
<file name="src/ScreenUtil.mm" />
<file name="src/AudioSession.mm" />
</files>
<target id="haxe">
<section if="iphoneos || iphonesim">
<vflag name="-framework" value="UIKit" />
<vflag name="-framework" value="Foundation" />
<vflag name="-framework" value="AVFAudio" />
</section>
<files id="external-ios" if="iphoneos || iphonesim" />
</target>
</xml>

View file

@ -0,0 +1,4 @@
#pragma once
void initialize();
void setActive(bool active);

View file

@ -0,0 +1,4 @@
#pragma once
void getSafeAreaInsets(double* top, double* bottom, double* left, double* right);
void getScreenSize(double* width, double* height);

View file

@ -0,0 +1,41 @@
#import <Foundation/Foundation.h>
#import <AVFAudio/AVFAudio.h>
void initialize()
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayback
mode:AVAudioSessionModeDefault
options:AVAudioSessionCategoryOptionAllowBluetoothA2DP|AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
error:&error];
if (@available(iOS 17.0, *))
{
[session setPrefersInterruptionOnRouteDisconnect:false error:nil];
}
if (@available(iOS 14.5, *))
{
[session setPrefersNoInterruptionsFromSystemAlerts:true error:nil];
}
if (error)
{
NSLog(@"Unable to set category of audio session: %@", error);
}
}
void setActive(bool active)
{
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setActive:YES error:&error];
if (error)
{
NSLog(@"Unable to set active of audio session: %@", error);
}
}

View file

@ -0,0 +1,36 @@
#import "ScreenUtil.hpp"
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
void getSafeAreaInsets(double* top, double* bottom, double* left, double* right)
{
if (@available(iOS 11, *))
{
UIWindow* window = [UIApplication sharedApplication].windows[0];
UIEdgeInsets safeAreaInsets = window.safeAreaInsets;
float scale = [UIScreen mainScreen].scale;
(*top) = safeAreaInsets.top * scale;
(*bottom) = safeAreaInsets.bottom * scale;
(*left) = safeAreaInsets.left * scale;
(*right) = safeAreaInsets.right * scale;
return;
}
(*top) = 0.0;
(*bottom) = 0.0;
(*left) = 0.0;
(*right) = 0.0;
}
void getScreenSize(double* width, double* height)
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
float scale = [UIScreen mainScreen].scale;
(*width) = (double)screenRect.size.width * scale;
(*height) = (double)screenRect.size.height * scale;
}

View file

@ -32,6 +32,7 @@ import openfl.display._internal.CairoGraphics as GfxRenderer;
* A modified `FlxSprite` that supports filters.
* The name's pretty much self-explanatory.
*/
@:nullSafety
@:access(openfl.geom.Rectangle)
@:access(openfl.filters.BitmapFilter)
@:access(flixel.graphics.frames.FlxFrame)
@ -39,12 +40,12 @@ class FlxFilteredSprite extends FlxSprite
{
@:noCompletion var _renderer:FlxAnimateFilterRenderer = new FlxAnimateFilterRenderer();
@:noCompletion var _filterMatrix:FlxMatrix;
@:noCompletion var _filterMatrix:FlxMatrix = new FlxMatrix();
/**
* An `Array` of shader filters (aka `BitmapFilter`).
*/
public var filters(default, set):Array<BitmapFilter>;
public var filters(default, set):Null<Array<BitmapFilter>>;
/**
* a flag to update the image with the filters.
@ -52,11 +53,15 @@ class FlxFilteredSprite extends FlxSprite
*/
public var filterDirty:Bool = false;
@:noCompletion var filtered:Bool;
@:noCompletion var filtered:Bool = false;
// These appear to be a little troublesome to null safe.
@:nullSafety(Off)
@:noCompletion var _blankFrame:FlxFrame;
@:nullSafety(Off)
var _filterBmp1:BitmapData;
@:nullSafety(Off)
var _filterBmp2:BitmapData;
override public function update(elapsed:Float)
@ -162,6 +167,7 @@ class FlxFilteredSprite extends FlxSprite
}
_flashRect.width += frameWidth;
_flashRect.height += frameHeight;
@:nullSafety(Off)
if (_blankFrame == null) _blankFrame = new FlxFrame(null);
if (_blankFrame.parent == null || _flashRect.width > _blankFrame.parent.width || _flashRect.height > _blankFrame.parent.height)
@ -178,6 +184,7 @@ class FlxFilteredSprite extends FlxSprite
_filterBmp2 = new BitmapData(_blankFrame.parent.width, _blankFrame.parent.height, 0);
}
_blankFrame.offset.copyFrom(_frame.offset);
@:nullSafety(Off)
_blankFrame.parent.bitmap = _renderer.applyFilter(_blankFrame.parent.bitmap, _filterBmp1, _filterBmp2, frame.parent.bitmap, filters, _flashRect,
frame.frame.copyToFlash());
_blankFrame.frame = FlxRect.get(0, 0, _blankFrame.parent.bitmap.width, _blankFrame.parent.bitmap.height);
@ -193,7 +200,7 @@ class FlxFilteredSprite extends FlxSprite
}
@:noCompletion
function set_filters(value:Array<BitmapFilter>)
function set_filters(value:Null<Array<BitmapFilter>>)
{
if (filters != value) filterDirty = true;

View file

@ -24,6 +24,7 @@ import openfl.filters.ShaderFilter;
* - NOTE: Several other blend modes work without FunkinCamera. Some still do not work.
* - NOTE: Framerate-independent camera tweening is fixed in Flixel 6.x. Rest in peace, SwagCamera.
*/
@:nullSafety
@:access(openfl.display.DisplayObject)
@:access(openfl.display.BitmapData)
@:access(openfl.display3D.Context3D)
@ -50,11 +51,12 @@ class FunkinCamera extends FlxCamera
// Used to identify the camera during debugging.
final id:String = 'unknown';
@:nullSafety(Off)
public function new(id:String = 'unknown', x:Int = 0, y:Int = 0, width:Int = 0, height:Int = 0, zoom:Float = 0)
{
super(x, y, width, height, zoom);
this.id = id;
bgTexture = pickTexture(width, height);
bgTexture = @:nullSafety(Off) pickTexture(width, height);
bgBitmap = FixedBitmapData.fromTexture(bgTexture);
bgFrame = new FlxFrame(new FlxGraphic('', null));
bgFrame.parent.bitmap = bgBitmap;
@ -74,12 +76,15 @@ class FunkinCamera extends FlxCamera
* and the grabbed bitmap will not include any previously rendered sprites
* @return the grabbed bitmap data
*/
public function grabScreen(applyFilters:Bool, isolate:Bool = false):BitmapData
public function grabScreen(applyFilters:Bool, isolate:Bool = false):Null<BitmapData>
{
final texture = pickTexture(width, height);
final bitmap = FixedBitmapData.fromTexture(texture);
squashTo(bitmap, applyFilters, isolate);
grabbed.push(bitmap);
if (bitmap != null)
{
squashTo(bitmap, applyFilters, isolate);
grabbed.push(bitmap);
}
return bitmap;
}
@ -126,12 +131,14 @@ class FunkinCamera extends FlxCamera
if (applyFilters)
{
bitmap.draw(flashSprite, matrix);
@:nullSafety(Off) // TODO: Remove this once openfl.display.Sprite has been null safed.
flashSprite.filters = null;
filtersApplied = true;
}
else
{
final tmp = flashSprite.filters;
@:nullSafety(Off)
flashSprite.filters = null;
bitmap.draw(flashSprite, matrix);
flashSprite.filters = tmp;
@ -197,6 +204,7 @@ class FunkinCamera extends FlxCamera
final isolated = grabScreen(false, true);
// apply fullscreen blend
customBlendShader.blendSwag = blend;
@:nullSafety(Off) // I hope this doesn't cause issues
customBlendShader.sourceSwag = isolated;
customBlendShader.updateViewInfo(FlxG.width, FlxG.height, this);
applyFilter(customBlendFilter);
@ -228,7 +236,7 @@ class FunkinCamera extends FlxCamera
bgItemCount = 0;
}
function pickTexture(width:Int, height:Int):TextureBase
function pickTexture(width:Int, height:Int):Null<TextureBase>
{
// zero-sized textures will be problematic
width = width < 1 ? 1 : width;
@ -236,7 +244,9 @@ class FunkinCamera extends FlxCamera
if (texturePool.length > 0)
{
final res = texturePool.pop();
BitmapDataUtil.resizeTexture(res, width, height);
if (res != null) BitmapDataUtil.resizeTexture(res, width, height);
else
trace('huh? why is this null? $texturePool');
return res;
}
return Lib.current.stage.context3D.createTexture(width, height, BGRA, true);

View file

@ -11,12 +11,16 @@ import flixel.math.FlxRect;
import flixel.math.FlxPoint;
import flixel.graphics.frames.FlxFrame.FlxFrameAngle;
import flixel.FlxCamera;
import openfl.system.System;
using StringTools;
/**
* An FlxSprite with additional functionality.
* - A more efficient method for creating solid color sprites.
* - TODO: Better cache handling for textures.
*/
@:nullSafety
class FunkinSprite extends FlxSprite
{
/**
@ -31,6 +35,8 @@ class FunkinSprite extends FlxSprite
*/
static var previousCachedTextures:Map<String, FlxGraphic> = [];
static var permanentCachedTextures:Map<String, FlxGraphic> = [];
/**
* @param x Starting X position
* @param y Starting Y position
@ -158,9 +164,14 @@ class FunkinSprite extends FlxSprite
* @param input The OpenFL `TextureBase` to apply
* @return This sprite, for chaining
*/
public function loadTextureBase(input:TextureBase):FunkinSprite
public function loadTextureBase(input:TextureBase):Null<FunkinSprite>
{
var inputBitmap:FixedBitmapData = FixedBitmapData.fromTexture(input);
var inputBitmap:Null<FixedBitmapData> = FixedBitmapData.fromTexture(input);
if (inputBitmap == null)
{
FlxG.log.warn('loadTextureBase - input resulted in null bitmap! $input');
return null;
}
return loadBitmapData(inputBitmap);
}
@ -219,7 +230,7 @@ class FunkinSprite extends FlxSprite
// Move the graphic from the previous cache to the current cache.
var graphic = previousCachedTextures.get(key);
previousCachedTextures.remove(key);
currentCachedTextures.set(key, graphic);
if (graphic != null) currentCachedTextures.set(key, graphic);
return;
}
@ -237,6 +248,27 @@ class FunkinSprite extends FlxSprite
}
}
public static function permanentCacheTexture(key:String):Void
{
// We don't want to cache the same texture twice.
if (permanentCachedTextures.exists(key)) return;
// Else, texture is currently uncached.
var graphic:FlxGraphic = FlxGraphic.fromAssetKey(key, false, null, true);
if (graphic == null)
{
FlxG.log.warn('Failed to cache graphic: $key');
}
else
{
trace('Successfully cached graphic: $key');
graphic.persist = true;
permanentCachedTextures.set(key, graphic);
}
currentCachedTextures = permanentCachedTextures;
}
public static function cacheSparrow(key:String):Void
{
cacheTexture(Paths.image(key));
@ -253,7 +285,14 @@ class FunkinSprite extends FlxSprite
public static function preparePurgeCache():Void
{
previousCachedTextures = currentCachedTextures;
currentCachedTextures = [];
for (graphicKey in previousCachedTextures.keys())
{
if (!permanentCachedTextures.exists(graphicKey)) continue;
previousCachedTextures.remove(graphicKey);
}
currentCachedTextures = permanentCachedTextures;
}
public static function purgeCache():Void
@ -267,12 +306,39 @@ class FunkinSprite extends FlxSprite
graphic.destroy();
previousCachedTextures.remove(graphicKey);
}
@:privateAccess
if (FlxG.bitmap._cache == null)
{
@:privateAccess
FlxG.bitmap._cache = new Map();
System.gc();
return;
}
@:privateAccess
for (key in FlxG.bitmap._cache.keys())
{
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
if (obj == null) continue;
if (obj.persist) continue;
if (permanentCachedTextures.exists(key)) continue;
if (!(obj.useCount <= 0 || key.contains("characters") || key.contains("charSelect") || key.contains("results"))) continue;
FlxG.bitmap.removeKey(key);
obj.destroy();
}
openfl.Assets.cache.clear("songs");
openfl.Assets.cache.clear("sounds");
openfl.Assets.cache.clear("music");
System.gc();
}
static function isGraphicCached(graphic:FlxGraphic):Bool
{
var result = null;
if (graphic == null) return false;
var result = FlxG.bitmap.get(graphic.key);
result = FlxG.bitmap.get(graphic.key);
if (result == null) return false;
if (result != graphic)
{
@ -288,8 +354,9 @@ class FunkinSprite extends FlxSprite
*/
public function isAnimationDynamic(id:String):Bool
{
var animData = null;
if (this.animation == null) return false;
var animData = this.animation.getByName(id);
animData = this.animation.getByName(id);
if (animData == null) return false;
return animData.numFrames > 1;
}
@ -428,6 +495,7 @@ class FunkinSprite extends FlxSprite
public override function destroy():Void
{
@:nullSafety(Off) // TODO: Remove when flixel.FlxSprite is null safed.
frames = null;
// Cancel all tweens so they don't continue to run on a destroyed sprite.
// This prevents crashes.

View file

@ -1,8 +1,8 @@
package funkin.modding.base;
package funkin.graphics;
/**
* A script that can be tied to a FunkinSprite.
* Create a scripted class that extends FunkinSprite to use this.
*/
@:hscriptClass
class ScriptedFunkinSprite extends funkin.graphics.FunkinSprite implements HScriptedClass {}
class ScriptedFunkinSprite extends funkin.graphics.FunkinSprite implements polymod.hscript.HScriptedClass {}

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