diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 8b2732a9a..dbfeb8621 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -284,7 +284,7 @@ class Conductor * @param songPosition The current position in the song in milliseconds. * Leave blank to use the FlxG.sound.music position. */ - public function update(?songPos:Float) + public function update(?songPos:Float, applyOffsets:Bool = true) { if (songPos == null) { @@ -292,7 +292,7 @@ class Conductor songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; } else - songPos += instrumentalOffset + formatOffset; + songPos += applyOffsets ? instrumentalOffset + formatOffset : 0; var oldMeasure = this.currentMeasure; var oldBeat = this.currentBeat; diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 057f05acb..4538696dc 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -41,6 +41,12 @@ class Strumline extends FlxSpriteGroup public var isPlayer:Bool; + /** + * Usually you want to keep this as is, but if you are using a Strumline and + * playing a sound that has it's own conductor, set this (LatencyState for example) + */ + public var conductorInUse:Conductor = Conductor.instance; + /** * The notes currently being rendered on the strumline. * This group iterates over this every frame to update note positions. @@ -158,7 +164,7 @@ class Strumline extends FlxSpriteGroup var hitWindowCenter = note.strumTime; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - if (Conductor.instance.songPosition > hitWindowEnd) + if (conductorInUse.songPosition > hitWindowEnd) { if (!isPlayer && note.hasMissed) continue; @@ -168,7 +174,7 @@ class Strumline extends FlxSpriteGroup if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; } - else if (Conductor.instance.songPosition > hitWindowCenter) + else if (conductorInUse.songPosition > hitWindowCenter) { // only run this on opponent strumlines! if (!isPlayer) continue; @@ -191,7 +197,7 @@ class Strumline extends FlxSpriteGroup playNoteHoldCover(note.holdNoteSprite); } } - else if (Conductor.instance.songPosition > hitWindowStart) + else if (conductorInUse.songPosition > hitWindowStart) { if (!isPlayer && (note.hasBeenHit || note.hasMissed)) continue; @@ -352,7 +358,7 @@ class Strumline extends FlxSpriteGroup * @param strumTime * @return Float */ - static function calculateNoteYPos(strumTime:Float, vwoosh:Bool = true):Float + public function calculateNoteYPos(strumTime:Float, vwoosh:Bool = true):Float { // Make the note move faster visually as it moves offscreen. // var vwoosh:Float = (strumTime < Conductor.songPosition) && vwoosh ? 2.0 : 1.0; @@ -360,7 +366,7 @@ class Strumline extends FlxSpriteGroup var vwoosh:Float = 1.0; var scrollSpeed:Float = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; - return Constants.PIXELS_PER_MS * (Conductor.instance.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); + return Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); } function updateNotes():Void @@ -368,8 +374,8 @@ class Strumline extends FlxSpriteGroup if (noteData.length == 0) return; var songStart:Float = PlayState.instance?.startTimestamp ?? 0.0; - var hitWindowStart:Float = Conductor.instance.songPosition - Constants.HIT_WINDOW_MS; - var renderWindowStart:Float = Conductor.instance.songPosition + RENDER_DISTANCE_MS; + var hitWindowStart:Float = conductorInUse.songPosition - Constants.HIT_WINDOW_MS; + var renderWindowStart:Float = conductorInUse.songPosition + RENDER_DISTANCE_MS; for (noteIndex in nextNoteIndex...noteData.length) { @@ -416,7 +422,7 @@ class Strumline extends FlxSpriteGroup { if (holdNote == null || !holdNote.alive) continue; - if (Conductor.instance.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) + if (conductorInUse.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) { if (isPlayer && !isKeyHeld(holdNote.noteDirection)) { @@ -430,7 +436,7 @@ class Strumline extends FlxSpriteGroup var renderWindowEnd = holdNote.strumTime + holdNote.fullSustainLength + Constants.HIT_WINDOW_MS + RENDER_DISTANCE_MS / 8; - if (holdNote.missedNote && Conductor.instance.songPosition >= renderWindowEnd) + if (holdNote.missedNote && conductorInUse.songPosition >= renderWindowEnd) { // Hold note is offscreen, kill it. holdNote.visible = false; @@ -476,13 +482,13 @@ class Strumline extends FlxSpriteGroup holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; } } - else if (Conductor.instance.songPosition > holdNote.strumTime && holdNote.hitNote) + else if (conductorInUse.songPosition > holdNote.strumTime && holdNote.hitNote) { // Hold note is currently being hit, clip it off. holdConfirm(holdNote.noteDirection); holdNote.visible = true; - holdNote.sustainLength = (holdNote.strumTime + holdNote.fullSustainLength) - Conductor.instance.songPosition; + holdNote.sustainLength = (holdNote.strumTime + holdNote.fullSustainLength) - conductorInUse.songPosition; if (holdNote.sustainLength <= 10) { diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 33333565f..4013258af 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -27,6 +27,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; + public var conductorInUse:Conductor = Conductor.instance; public function new() { @@ -125,7 +126,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function stepHit():Bool { - var event = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event = new SongTimeScriptEvent(SONG_STEP_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); @@ -136,7 +137,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function beatHit():Bool { - var event = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event = new SongTimeScriptEvent(SONG_BEAT_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 0fa55c234..dc2958b91 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -20,6 +20,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl { public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; + public var conductorInUse:Conductor = Conductor.instance; public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) { @@ -95,7 +96,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function stepHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); @@ -111,7 +112,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function beatHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index aa186d6b3..0f396c972 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -45,10 +45,18 @@ class LatencyState extends MusicBeatSubState var stateCamera:FlxCamera; + /** + * A local conductor instance for this testing class, in-case we are in a PlayState + * because I'm too lazy to set the old variables for conductor stuff ! + */ + var localConductor:Conductor; + override function create() { super.create(); + localConductor = new Conductor(); + stateCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height); stateCamera.bgColor = FlxColor.BLACK; FlxG.cameras.add(stateCamera); @@ -68,26 +76,27 @@ class LatencyState extends MusicBeatSubState swagSong.loadEmbedded(Paths.sound('soundTest'), true); swagSong.looped = true; swagSong.play(); + FlxG.sound.list.add(swagSong); PreciseInputManager.instance.onInputPressed.add(preciseInputPressed); PreciseInputManager.instance.onInputReleased.add(preciseInputReleased); - Conductor.instance.forceBPM(60); + localConductor.forceBPM(60); noteGrp = []; diffGrp = new FlxTypedGroup(); add(diffGrp); - for (beat in 0...Math.floor(swagSong.length / (Conductor.instance.stepLengthMs * 2))) + for (beat in 0...Math.floor(swagSong.length / (localConductor.stepLengthMs * 2))) { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 15); + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 15); beatTick.makeGraphic(2, 15); beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -121,6 +130,7 @@ class LatencyState extends MusicBeatSubState add(strumlineBG); strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true); + strumLine.conductorInUse = localConductor; strumLine.screenCenter(); add(strumLine); @@ -173,6 +183,7 @@ class LatencyState extends MusicBeatSubState FlxG.sound.music.volume = previousVolume; swagSong.stop(); + FlxG.sound.list.remove(swagSong); FlxG.cameras.remove(stateCamera); @@ -183,7 +194,7 @@ class LatencyState extends MusicBeatSubState { for (i in 0...32) { - var note:SongNoteData = new SongNoteData((Conductor.instance.stepLengthMs * 2) * i, 1); + var note:SongNoteData = new SongNoteData((localConductor.stepLengthMs * 2) * i, 1); noteGrp.push(note); } @@ -192,9 +203,9 @@ class LatencyState extends MusicBeatSubState override function stepHit():Bool { - if (Conductor.instance.currentStep % 4 == 2) + if (localConductor.currentStep % 4 == 2) { - blocks.members[((Conductor.instance.currentBeat % 8) + 1) % 8].alpha = 0.5; + blocks.members[((localConductor.currentBeat % 8) + 1) % 8].alpha = 0.5; } return super.stepHit(); @@ -202,11 +213,11 @@ class LatencyState extends MusicBeatSubState override function beatHit():Bool { - if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> { + if (localConductor.currentBeat % 8 == 0) blocks.forEach(blok -> { blok.alpha = 0.1; }); - blocks.members[Conductor.instance.currentBeat % 8].alpha = 1; + blocks.members[localConductor.currentBeat % 8].alpha = 1; // block.visible = !block.visible; return super.beatHit(); @@ -219,18 +230,18 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - Conductor.instance.update(swagSong.time); + localConductor.update(swagSong.time, false); - // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; + // localConductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; - songPosVis.x = songPosToX(Conductor.instance.songPosition); - songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset); - songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset); + songPosVis.x = songPosToX(localConductor.songPosition); + songVisFollowAudio.x = songPosToX(localConductor.songPosition - localConductor.instrumentalOffset); + songVisFollowVideo.x = songPosToX(localConductor.songPosition - localConductor.inputOffset); - visualOffsetText.text = "Visual Offset: " + Conductor.instance.instrumentalOffset + "ms"; + visualOffsetText.text = "Visual Offset: " + localConductor.instrumentalOffset + "ms"; visualOffsetText.text += "\nYou can press SPACE+Left/Right to change this value."; - offsetText.text = "INPUT Offset (Left/Right to change): " + Conductor.instance.inputOffset + "ms"; + offsetText.text = "INPUT Offset (Left/Right to change): " + localConductor.inputOffset + "ms"; var avgOffsetInput:Float = 0; @@ -249,24 +260,24 @@ class LatencyState extends MusicBeatSubState { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.instrumentalOffset += 1 * multiply; + localConductor.instrumentalOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.instrumentalOffset -= 1 * multiply; + localConductor.instrumentalOffset -= 1 * multiply; } } else { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.inputOffset += 1 * multiply; + localConductor.inputOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.inputOffset -= 1 * multiply; + localConductor.inputOffset -= 1 * multiply; } } @@ -280,21 +291,21 @@ class LatencyState extends MusicBeatSubState function generateBeatStuff(event:PreciseInputEvent) { - // Conductor.instance.update(swagSong.getTimeWithDiff()); + // localConductor.update(swagSong.getTimeWithDiff()); var inputLatencyMs:Float = haxe.Int64.toInt(PreciseInputManager.getCurrentTimestamp() - event.timestamp) / 1000.0 / 1000.0; trace("input latency: " + inputLatencyMs + "ms"); trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); trace("event timestamp: " + event.timestamp + "ns"); - trace("songtime: " + Conductor.instance.getTimeWithDiff(swagSong) + "ms"); + trace("songtime: " + localConductor.getTimeWithDiff(swagSong) + "ms"); - var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff(swagSong) / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; - var getDiff:Float = Conductor.instance.getTimeWithDiff(swagSong) - (closestBeat * (Conductor.instance.stepLengthMs * 2)); - // getDiff -= Conductor.instance.inputOffset; + var closestBeat:Int = Math.round(localConductor.getTimeWithDiff(swagSong) / (localConductor.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = localConductor.getTimeWithDiff(swagSong) - (closestBeat * (localConductor.stepLengthMs * 2)); + // getDiff -= localConductor.inputOffset; getDiff -= inputLatencyMs; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= swagSong.length; + if (closestBeat == 0 && getDiff >= localConductor.stepLengthMs * 2) getDiff -= swagSong.length; beatTrail.x = songPosVis.x;