Skip to content

Commit 8553392

Browse files
committed
Seamless Fading Loop in Freeplay Previews
1 parent 36c8890 commit 8553392

File tree

3 files changed

+348
-29
lines changed

3 files changed

+348
-29
lines changed

source/funkin/play/song/Song.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
329329
difficulty.difficultyRating = metadata.playData.ratings.get(diffId) ?? 0;
330330
difficulty.album = metadata.playData.album;
331331
difficulty.stickerPack = metadata.playData.stickerPack;
332+
difficulty.previewStart = metadata.playData.previewStart;
333+
difficulty.previewEnd = metadata.playData.previewEnd;
332334

333335
difficulty.stage = metadata.playData.stage;
334336
difficulty.noteStyle = metadata.playData.noteStyle;
@@ -793,6 +795,8 @@ class SongDifficulty
793795
public var difficultyRating:Int = 0;
794796
public var album:Null<String> = null;
795797
public var stickerPack:Null<String> = null;
798+
public var previewStart:Int = 0;
799+
public var previewEnd:Int = 15000;
796800

797801
public function new(song:Song, diffId:String, variation:String)
798802
{

source/funkin/ui/freeplay/FreeplayState.hx

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import funkin.ui.AtlasText;
4444
import funkin.ui.FullScreenScaleMode;
4545
import funkin.ui.MusicBeatSubState;
4646
import funkin.ui.freeplay.backcards.*;
47-
import funkin.ui.freeplay.components.DifficultySprite;
47+
import funkin.ui.freeplay.components.*;
4848
import funkin.ui.freeplay.charselect.PlayableCharacter;
4949
import funkin.ui.mainmenu.MainMenuState;
5050
import funkin.ui.story.Level;
@@ -272,6 +272,8 @@ class FreeplayState extends MusicBeatSubState
272272

273273
public var freeplayArrow:Null<FlxText>;
274274

275+
var previewMusicData:Null<PreviewMusicData> = null;
276+
275277
public function new(?params:FreeplayStateParams, ?stickers:StickerSubState)
276278
{
277279
var fetchPlayableCharacter = function():PlayableCharacter
@@ -2190,6 +2192,8 @@ class FreeplayState extends MusicBeatSubState
21902192
FlxG.cameras.remove(funnyCam);
21912193
// Cancel all song preview timers just in case a preview loads after we exit.
21922194
clearPreviews();
2195+
// Destroy the preview music data.
2196+
previewMusicData?.destroy();
21932197
}
21942198

21952199
function goBack():Void
@@ -2951,6 +2955,9 @@ class FreeplayState extends MusicBeatSubState
29512955
{
29522956
if (daSongCapsule == null) daSongCapsule = currentCapsule;
29532957

2958+
// Make sure the player is still hovering over the song we want to load preview for
2959+
if (!daSongCapsule.selected) return;
2960+
29542961
var previewVolume:Float = 0.7;
29552962
if (dj != null) previewVolume *= dj.getMusicPreviewMult();
29562963

@@ -2969,8 +2976,6 @@ class FreeplayState extends MusicBeatSubState
29692976
}
29702977
else
29712978
{
2972-
// Make sure the player is still hovering over the song we want to load preview for
2973-
if (!daSongCapsule.selected) return;
29742979
var previewSong:Null<Song> = daSongCapsule?.freeplayData?.data;
29752980
if (previewSong == null) return;
29762981

@@ -2990,35 +2995,26 @@ class FreeplayState extends MusicBeatSubState
29902995
instSuffix = (instSuffix != '') ? '-$instSuffix' : '';
29912996
// trace('Attempting to play partial preview: ${previewSong.id}:${instSuffix}');
29922997

2993-
FunkinSound.playMusic(previewSong.id, {
2994-
startingVolume: 0.0,
2995-
overrideExisting: true,
2996-
restartTrack: false,
2997-
mapTimeChanges: false, // The music metadata is not alongside the audio file so this won't work.
2998-
pathsFunction: INST,
2999-
suffix: instSuffix,
3000-
partialParams: {
3001-
loadPartial: true,
3002-
start: 0,
3003-
end: 0.2
3004-
},
3005-
onLoad: function()
3006-
{
3007-
FlxG.sound.music.fadeIn(2, 0, previewVolume);
3008-
3009-
var fadeStart:Float = (FlxG.sound.music.length / 1000) - 2;
2998+
if (FlxG.sound.music == null)
2999+
{
3000+
FunkinSound.setMusic(FunkinSound.load(null));
3001+
}
30103002

3011-
previewTimers.push(new FlxTimer().start(fadeStart, function(_)
3012-
{
3013-
FlxG.sound.music.fadeOut(2, 0);
3014-
}));
3003+
if (previewMusicData == null) previewMusicData = new PreviewMusicData();
3004+
previewMusicData.setAssetPath(Paths.inst(previewSong.id, instSuffix), songDifficulty?.previewStart, songDifficulty?.previewEnd, true,
3005+
function(musicData:PreviewMusicData)
3006+
{
3007+
// Check again if it's still selected.
3008+
if (!daSongCapsule.selected) return;
30153009

3016-
previewTimers.push(new FlxTimer().start(FlxG.sound.music.length / 1000, function(_)
3017-
{
3018-
playCurSongPreview();
3019-
}));
3020-
},
3010+
FlxG.sound.music.fadeTween?.cancel();
3011+
FlxG.sound.music.unload();
3012+
FlxG.sound.music.loadEmbedded(musicData);
3013+
FlxG.sound.music.volume = previewVolume;
3014+
FlxG.sound.music.looped = true;
3015+
FlxG.sound.music.play(true, 0);
30213016
});
3017+
30223018
if (songDifficulty != null)
30233019
{
30243020
Conductor.instance.mapTimeChanges(songDifficulty.timeChanges);

0 commit comments

Comments
 (0)