From a523b824397aa80240fc4be706542496e73af02f Mon Sep 17 00:00:00 2001 From: Mike Welsh <mwelsh@gmail.com> Date: Fri, 16 Feb 2024 20:48:43 -0800 Subject: [PATCH] Fix songs failing to load on HTML5 target Do a small refactor of `LoadingState` to fix loading songs on the when `NO_PRELOAD_ALL` is defined. This allows the HTML5 target to progress into song gameplay again. --- source/funkin/InitState.hx | 12 ++-- source/funkin/play/PlayState.hx | 49 +++++++--------- source/funkin/ui/freeplay/FreeplayState.hx | 8 +-- source/funkin/ui/story/StoryMenuState.hx | 11 +--- source/funkin/ui/transition/LoadingState.hx | 62 ++++++++++++++------- 5 files changed, 70 insertions(+), 72 deletions(-) diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 399f52498..8072a847a 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -302,15 +302,11 @@ class InitState extends FlxState return; } - // Load and cache the song's charts. - // TODO: Do this in the loading state. - songData.cacheCharts(true); - - LoadingState.loadAndSwitchState(() -> new funkin.play.PlayState( + LoadingState.loadPlayState( { targetSong: songData, targetDifficulty: difficultyId, - })); + }); } /** @@ -336,11 +332,11 @@ class InitState extends FlxState var targetSong:funkin.play.song.Song = SongRegistry.instance.fetchEntry(targetSongId); - LoadingState.loadAndSwitchState(() -> new funkin.play.PlayState( + LoadingState.loadPlayState( { targetSong: targetSong, targetDifficulty: difficultyId, - })); + }); } function defineSong():String diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 66e8e0dcc..862e1ee43 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -123,6 +123,11 @@ typedef PlayStateParams = * and must be loaded externally. */ ?overrideMusic:Bool, + /** + * The initial camera follow point. + * Used to persist the position of the `cameraFollowPosition` between levels. + */ + ?cameraFollowPoint:FlxPoint, } /** @@ -216,7 +221,7 @@ class PlayState extends MusicBeatSubState * The camera follow point from the last stage. * Used to persist the position of the `cameraFollowPosition` between levels. */ - public var previousCameraFollowPoint:FlxSprite = null; + public var previousCameraFollowPoint:FlxPoint = null; /** * The current camera zoom level. @@ -544,6 +549,7 @@ class PlayState extends MusicBeatSubState isMinimalMode = params.minimalMode ?? false; startTimestamp = params.startTimestamp ?? 0.0; overrideMusic = params.overrideMusic ?? false; + previousCameraFollowPoint = params.cameraFollowPoint; // Don't do anything else here! Wait until create() when we attach to the camera. } @@ -2621,38 +2627,25 @@ class PlayState extends MusicBeatSubState FlxG.sound.play(Paths.sound('Lights_Shut_off'), function() { // no camFollow so it centers on horror tree var targetSong:Song = SongRegistry.instance.fetchEntry(targetSongId); - // Load and cache the song's charts. - // TODO: Do this in the loading state. - targetSong.cacheCharts(true); - - LoadingState.loadAndSwitchState(() -> { - var nextPlayState:PlayState = new PlayState( - { - targetSong: targetSong, - targetDifficulty: PlayStatePlaylist.campaignDifficulty, - targetVariation: currentVariation, - }); - nextPlayState.previousCameraFollowPoint = new FlxSprite(cameraFollowPoint.x, cameraFollowPoint.y); - return nextPlayState; - }); + LoadingState.loadPlayState( + { + targetSong: targetSong, + targetDifficulty: PlayStatePlaylist.campaignDifficulty, + targetVariation: currentVariation, + cameraFollowPoint: cameraFollowPoint.getPosition(), + }); }); } else { var targetSong:Song = SongRegistry.instance.fetchEntry(targetSongId); - // Load and cache the song's charts. - // TODO: Do this in the loading state. - targetSong.cacheCharts(true); - LoadingState.loadAndSwitchState(() -> { - var nextPlayState:PlayState = new PlayState( - { - targetSong: targetSong, - targetDifficulty: PlayStatePlaylist.campaignDifficulty, - targetVariation: currentVariation, - }); - nextPlayState.previousCameraFollowPoint = new FlxSprite(cameraFollowPoint.x, cameraFollowPoint.y); - return nextPlayState; - }); + LoadingState.loadPlayState( + { + targetSong: targetSong, + targetDifficulty: PlayStatePlaylist.campaignDifficulty, + targetVariation: currentVariation, + cameraFollowPoint: cameraFollowPoint.getPosition(), + }); } } } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index e7c615313..39cab8759 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1135,18 +1135,14 @@ class FreeplayState extends MusicBeatSubState FlxG.sound.play(Paths.sound('confirmMenu')); dj.confirm(); - // Load and cache the song's charts. - // TODO: Do this in the loading state. - targetSong.cacheCharts(true); - new FlxTimer().start(1, function(tmr:FlxTimer) { Paths.setCurrentLevel(cap.songData.levelId); - LoadingState.loadAndSwitchState(() -> new PlayState( + LoadingState.loadPlayState( { targetSong: targetSong, targetDifficulty: targetDifficulty, targetVariation: targetVariation, - }), true); + }, true); }); } diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 1905a7c57..54e16e917 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -554,22 +554,15 @@ class StoryMenuState extends MusicBeatState PlayStatePlaylist.campaignTitle = currentLevel.getTitle(); PlayStatePlaylist.campaignDifficulty = currentDifficultyId; - if (targetSong != null) - { - // Load and cache the song's charts. - // TODO: Do this in the loading state. - targetSong.cacheCharts(true); - } - new FlxTimer().start(1, function(tmr:FlxTimer) { FlxTransitionableState.skipNextTransIn = false; FlxTransitionableState.skipNextTransOut = false; - LoadingState.loadAndSwitchState(() -> new PlayState( + LoadingState.loadPlayState( { targetSong: targetSong, targetDifficulty: PlayStatePlaylist.campaignDifficulty, - }), true); + }, true); }); } diff --git a/source/funkin/ui/transition/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx index 63dcb8f68..86f443d1d 100644 --- a/source/funkin/ui/transition/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -9,7 +9,6 @@ import funkin.graphics.shaders.ScreenWipeShader; import funkin.play.PlayState; import funkin.play.PlayStatePlaylist; import funkin.play.song.Song.SongDifficulty; -import funkin.ui.mainmenu.MainMenuState; import funkin.ui.MusicBeatState; import haxe.io.Path; import funkin.graphics.FunkinSprite; @@ -27,17 +26,19 @@ class LoadingState extends MusicBeatState inline static var MIN_TIME = 1.0; var target:NextState; - var stopMusic = false; + var playParams:Null<PlayStateParams>; + var stopMusic:Bool = false; var callbacks:MultiCallback; - var danceLeft = false; + var danceLeft:Bool = false; var loadBar:FlxSprite; var funkay:FlxSprite; - function new(target:NextState, stopMusic:Bool) + function new(target:NextState, stopMusic:Bool, playParams:Null<PlayStateParams> = null) { super(); this.target = target; + this.playParams = playParams; this.stopMusic = stopMusic; } @@ -62,10 +63,18 @@ class LoadingState extends MusicBeatState callbacks = new MultiCallback(onLoad); var introComplete = callbacks.add('introComplete'); - if (Std.isOfType(target, PlayState)) + if (playParams != null) { - var targetPlayState:PlayState = cast target; - var targetChart:SongDifficulty = targetPlayState.currentChart; + // Load and cache the song's charts. + if (playParams.targetSong != null) + { + playParams.targetSong.cacheCharts(true); + } + + // Preload the song for the play state. + var difficulty:String = playParams.targetDifficulty ?? Constants.DEFAULT_DIFFICULTY; + var variation:String = playParams.targetVariation ?? Constants.DEFAULT_VARIATION; + var targetChart:SongDifficulty = playParams.targetSong?.getDifficulty(difficulty, variation); var instPath:String = Paths.inst(targetChart.song.id); var voicesPaths:Array<String> = targetChart.buildVoiceList(); @@ -172,25 +181,36 @@ class LoadingState extends MusicBeatState return Paths.inst(PlayState.instance.currentSong.id); } - inline static public function loadAndSwitchState(nextState:NextState, shouldStopMusic = false):Void - { - FlxG.switchState(getNextState(nextState, shouldStopMusic)); - } - - static function getNextState(nextState:NextState, shouldStopMusic = false):NextState + /** + * Starts the transition to a new `PlayState` to start a new song. + * First switches to the `LoadingState` if assets need to be loaded. + * @param params The parameters for the next `PlayState`. + * @param shouldStopMusic Whether to stop the current music while loading. + */ + public static function loadPlayState(params:PlayStateParams, shouldStopMusic = false):Void { Paths.setCurrentLevel(PlayStatePlaylist.campaignId); + var playStateCtor:NextState = () -> new PlayState(params); #if NO_PRELOAD_ALL - // var loaded = isSoundLoaded(getSongPath()) - // && (!PlayState.currentSong.needsVoices || isSoundLoaded(getVocalPath())) - // && isLibraryLoaded('shared'); - // - if (true) return () -> new LoadingState(nextState, shouldStopMusic); - #end - if (shouldStopMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); + // Switch to loading state while we load assets (default on HTML5 target). + var loadStateCtor:NextState = () -> new LoadingState(playStateCtor, shouldStopMusic, params); + FlxG.switchState(loadStateCtor); + #else + // All assets preloaded, switch directly to play state (defualt on other targets). + if (shouldStopMusic && FlxG.sound.music != null) + { + FlxG.sound.music.stop(); + } - return nextState; + // Load and cache the song's charts. + if (params?.targetSong != null) + { + params.targetSong.cacheCharts(true); + } + + FlxG.switchState(playStateCtor); + #end } #if NO_PRELOAD_ALL