diff --git a/art b/art index 1656bea53..03e7c2a23 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 1656bea5370c65879aaeb323e329f403c78071c5 +Subproject commit 03e7c2a2353b184e45955c96d763b7cdf1acbc34 diff --git a/assets b/assets index 9ecc4d26f..f8e22704a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 9ecc4d26fe6b26f31782cccfcd7331bd8a318ce1 +Subproject commit f8e22704a06b9f7763e795db19ba08cc90f66458 diff --git a/hmm.json b/hmm.json index 57fbbb555..d461edd24 100644 --- a/hmm.json +++ b/hmm.json @@ -54,14 +54,14 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "e765a3e0b7a653823e8dec765e04623f27f573f8", + "ref": "5086e59e7551d775ed4d1fb0188e31de22d1312b", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "7a517d561eff49d8123c128bf9f5c1123b84d014", + "ref": "2b9cff727999b53ed292b1675ac1c9089ac77600", "url": "https://github.com/haxeui/haxeui-flixel" }, { diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 7b34bffe2..05c23108f 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -11,6 +11,7 @@ import funkin.data.song.SongDataUtils; * A core class which handles musical timing throughout the game, * both in gameplay and in menus. */ +@:nullSafety class Conductor { // onBeatHit is called every quarter note @@ -28,29 +29,53 @@ class Conductor // 60 BPM = 240 sixteenth notes per minute = 4 onStepHit per second // 7/8 = 3.5 beats per measure = 14 steps per measure + /** + * The current instance of the Conductor. + * If one doesn't currently exist, a new one will be created. + * + * You can also do stuff like store a reference to the Conductor and pass it around or temporarily replace it, + * or have a second Conductor running at the same time, or other weird stuff like that if you need to. + */ + public static var instance:Conductor = new Conductor(); + + /** + * Signal fired when the current Conductor instance advances to a new measure. + */ + public static var measureHit(default, null):FlxSignal = new FlxSignal(); + + /** + * Signal fired when the current Conductor instance advances to a new beat. + */ + public static var beatHit(default, null):FlxSignal = new FlxSignal(); + + /** + * Signal fired when the current Conductor instance advances to a new step. + */ + public static var stepHit(default, null):FlxSignal = new FlxSignal(); + /** * The list of time changes in the song. * There should be at least one time change (at the beginning of the song) to define the BPM. */ - static var timeChanges:Array = []; + var timeChanges:Array = []; /** * The most recent time change for the current song position. */ - public static var currentTimeChange(default, null):Null; + public var currentTimeChange(default, null):Null; /** * The current position in the song in milliseconds. - * Update this every frame based on the audio position using `Conductor.update()`. + * Update this every frame based on the audio position using `Conductor.instance.update()`. */ - public static var songPosition(default, null):Float = 0; + public var songPosition(default, null):Float = 0; /** * Beats per minute of the current song at the current time. */ - public static var bpm(get, never):Float; + public var bpm(get, never):Float; - static function get_bpm():Float + function get_bpm():Float { if (bpmOverride != null) return bpmOverride; @@ -62,9 +87,9 @@ class Conductor /** * Beats per minute of the current song at the start time. */ - public static var startingBPM(get, never):Float; + public var startingBPM(get, never):Float; - static function get_startingBPM():Float + function get_startingBPM():Float { if (bpmOverride != null) return bpmOverride; @@ -78,14 +103,14 @@ class Conductor * The current value set by `forceBPM`. * If false, BPM is determined by time changes. */ - static var bpmOverride:Null = null; + var bpmOverride:Null = null; /** * Duration of a measure in milliseconds. Calculated based on bpm. */ - public static var measureLengthMs(get, never):Float; + public var measureLengthMs(get, never):Float; - static function get_measureLengthMs():Float + function get_measureLengthMs():Float { return beatLengthMs * timeSignatureNumerator; } @@ -93,9 +118,9 @@ class Conductor /** * Duration of a beat (quarter note) in milliseconds. Calculated based on bpm. */ - public static var beatLengthMs(get, never):Float; + public var beatLengthMs(get, never):Float; - static function get_beatLengthMs():Float + function get_beatLengthMs():Float { // Tied directly to BPM. return ((Constants.SECS_PER_MIN / bpm) * Constants.MS_PER_SEC); @@ -104,25 +129,25 @@ class Conductor /** * Duration of a step (sixtennth note) in milliseconds. Calculated based on bpm. */ - public static var stepLengthMs(get, never):Float; + public var stepLengthMs(get, never):Float; - static function get_stepLengthMs():Float + function get_stepLengthMs():Float { return beatLengthMs / timeSignatureNumerator; } - public static var timeSignatureNumerator(get, never):Int; + public var timeSignatureNumerator(get, never):Int; - static function get_timeSignatureNumerator():Int + function get_timeSignatureNumerator():Int { if (currentTimeChange == null) return Constants.DEFAULT_TIME_SIGNATURE_NUM; return currentTimeChange.timeSignatureNum; } - public static var timeSignatureDenominator(get, never):Int; + public var timeSignatureDenominator(get, never):Int; - static function get_timeSignatureDenominator():Int + function get_timeSignatureDenominator():Int { if (currentTimeChange == null) return Constants.DEFAULT_TIME_SIGNATURE_DEN; @@ -132,44 +157,44 @@ class Conductor /** * Current position in the song, in measures. */ - public static var currentMeasure(default, null):Int = 0; + public var currentMeasure(default, null):Int = 0; /** * Current position in the song, in beats. */ - public static var currentBeat(default, null):Int = 0; + public var currentBeat(default, null):Int = 0; /** * Current position in the song, in steps. */ - public static var currentStep(default, null):Int = 0; + public var currentStep(default, null):Int = 0; /** * Current position in the song, in measures and fractions of a measure. */ - public static var currentMeasureTime(default, null):Float = 0; + public var currentMeasureTime(default, null):Float = 0; /** * Current position in the song, in beats and fractions of a measure. */ - public static var currentBeatTime(default, null):Float = 0; + public var currentBeatTime(default, null):Float = 0; /** * Current position in the song, in steps and fractions of a step. */ - public static var currentStepTime(default, null):Float = 0; + public var currentStepTime(default, null):Float = 0; /** * An offset tied to the current chart file to compensate for a delay in the instrumental. */ - public static var instrumentalOffset:Float = 0; + public var instrumentalOffset:Float = 0; /** * The instrumental offset, in terms of steps. */ - public static var instrumentalOffsetSteps(get, never):Float; + public var instrumentalOffsetSteps(get, never):Float; - static function get_instrumentalOffsetSteps():Float + function get_instrumentalOffsetSteps():Float { var startingStepLengthMs:Float = ((Constants.SECS_PER_MIN / startingBPM) * Constants.MS_PER_SEC) / timeSignatureNumerator; @@ -179,19 +204,19 @@ class Conductor /** * An offset tied to the file format of the audio file being played. */ - public static var formatOffset:Float = 0; + public var formatOffset:Float = 0; /** * An offset set by the user to compensate for input lag. */ - public static var inputOffset:Float = 0; + public var inputOffset:Float = 0; /** * The number of beats in a measure. May be fractional depending on the time signature. */ - public static var beatsPerMeasure(get, never):Float; + public var beatsPerMeasure(get, never):Float; - static function get_beatsPerMeasure():Float + function get_beatsPerMeasure():Float { // NOTE: Not always an integer, for example 7/8 is 3.5 beats per measure return stepsPerMeasure / Constants.STEPS_PER_BEAT; @@ -201,30 +226,15 @@ class Conductor * The number of steps in a measure. * TODO: I don't think this can be fractional? */ - public static var stepsPerMeasure(get, never):Int; + public var stepsPerMeasure(get, never):Int; - static function get_stepsPerMeasure():Int + function get_stepsPerMeasure():Int { // TODO: Is this always an integer? return Std.int(timeSignatureNumerator / timeSignatureDenominator * Constants.STEPS_PER_BEAT * Constants.STEPS_PER_BEAT); } - /** - * Signal fired when the Conductor advances to a new measure. - */ - public static var measureHit(default, null):FlxSignal = new FlxSignal(); - - /** - * Signal fired when the Conductor advances to a new beat. - */ - public static var beatHit(default, null):FlxSignal = new FlxSignal(); - - /** - * Signal fired when the Conductor advances to a new step. - */ - public static var stepHit(default, null):FlxSignal = new FlxSignal(); - - function new() {} + public function new() {} /** * Forcibly defines the current BPM of the song. @@ -235,7 +245,7 @@ class Conductor * WARNING: Avoid this for things like setting the BPM of the title screen music, * you should have a metadata file for it instead. */ - public static function forceBPM(?bpm:Float = null) + public function forceBPM(?bpm:Float = null) { if (bpm != null) { @@ -246,7 +256,7 @@ class Conductor // trace('[CONDUCTOR] Resetting BPM to default'); } - Conductor.bpmOverride = bpm; + this.bpmOverride = bpm; } /** @@ -256,29 +266,29 @@ class Conductor * @param songPosition The current position in the song in milliseconds. * Leave blank to use the FlxG.sound.music position. */ - public static function update(?songPosition:Float) + public function update(?songPos:Float) { - if (songPosition == null) + if (songPos == null) { // Take into account instrumental and file format song offsets. - songPosition = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; + songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; } - var oldMeasure = currentMeasure; - var oldBeat = currentBeat; - var oldStep = currentStep; + var oldMeasure = this.currentMeasure; + var oldBeat = this.currentBeat; + var oldStep = this.currentStep; // Set the song position we are at (for purposes of calculating note positions, etc). - Conductor.songPosition = songPosition; + this.songPosition = songPos; currentTimeChange = timeChanges[0]; - if (Conductor.songPosition > 0.0) + if (this.songPosition > 0.0) { for (i in 0...timeChanges.length) { - if (songPosition >= timeChanges[i].timeStamp) currentTimeChange = timeChanges[i]; + if (this.songPosition >= timeChanges[i].timeStamp) currentTimeChange = timeChanges[i]; - if (songPosition < timeChanges[i].timeStamp) break; + if (this.songPosition < timeChanges[i].timeStamp) break; } } @@ -286,45 +296,49 @@ class Conductor { trace('WARNING: Conductor is broken, timeChanges is empty.'); } - else if (currentTimeChange != null && Conductor.songPosition > 0.0) + else if (currentTimeChange != null && this.songPosition > 0.0) { // roundDecimal prevents representing 8 as 7.9999999 - currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * 4) + (songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6); - currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT; - currentMeasureTime = currentStepTime / stepsPerMeasure; - currentStep = Math.floor(currentStepTime); - currentBeat = Math.floor(currentBeatTime); - currentMeasure = Math.floor(currentMeasureTime); + this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * 4) + (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6); + this.currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT; + this.currentMeasureTime = currentStepTime / stepsPerMeasure; + this.currentStep = Math.floor(currentStepTime); + this.currentBeat = Math.floor(currentBeatTime); + this.currentMeasure = Math.floor(currentMeasureTime); } else { // Assume a constant BPM equal to the forced value. - currentStepTime = FlxMath.roundDecimal((songPosition / stepLengthMs), 4); - currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT; - currentMeasureTime = currentStepTime / stepsPerMeasure; - currentStep = Math.floor(currentStepTime); - currentBeat = Math.floor(currentBeatTime); - currentMeasure = Math.floor(currentMeasureTime); + this.currentStepTime = FlxMath.roundDecimal((songPosition / stepLengthMs), 4); + this.currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT; + this.currentMeasureTime = currentStepTime / stepsPerMeasure; + this.currentStep = Math.floor(currentStepTime); + this.currentBeat = Math.floor(currentBeatTime); + this.currentMeasure = Math.floor(currentMeasureTime); } - // FlxSignals are really cool. - if (currentStep != oldStep) + // Only fire the signal if we are THE Conductor. + if (this == Conductor.instance) { - stepHit.dispatch(); - } + // FlxSignals are really cool. + if (currentStep != oldStep) + { + Conductor.stepHit.dispatch(); + } - if (currentBeat != oldBeat) - { - beatHit.dispatch(); - } + if (currentBeat != oldBeat) + { + Conductor.beatHit.dispatch(); + } - if (currentMeasure != oldMeasure) - { - measureHit.dispatch(); + if (currentMeasure != oldMeasure) + { + Conductor.measureHit.dispatch(); + } } } - public static function mapTimeChanges(songTimeChanges:Array) + public function mapTimeChanges(songTimeChanges:Array) { timeChanges = []; @@ -338,24 +352,21 @@ class Conductor // Without any custom handling, `currentStepTime` becomes non-zero at `songPosition = 0`. if (currentTimeChange.timeStamp < 0.0) currentTimeChange.timeStamp = 0.0; - if (currentTimeChange.beatTime == null) + if (currentTimeChange.timeStamp <= 0.0) { - if (currentTimeChange.timeStamp <= 0.0) - { - currentTimeChange.beatTime = 0.0; - } - else - { - // Calculate the beat time of this timestamp. - currentTimeChange.beatTime = 0.0; + currentTimeChange.beatTime = 0.0; + } + else + { + // Calculate the beat time of this timestamp. + currentTimeChange.beatTime = 0.0; - if (currentTimeChange.timeStamp > 0.0 && timeChanges.length > 0) - { - var prevTimeChange:SongTimeChange = timeChanges[timeChanges.length - 1]; - currentTimeChange.beatTime = FlxMath.roundDecimal(prevTimeChange.beatTime - + ((currentTimeChange.timeStamp - prevTimeChange.timeStamp) * prevTimeChange.bpm / Constants.SECS_PER_MIN / Constants.MS_PER_SEC), - 4); - } + if (currentTimeChange.timeStamp > 0.0 && timeChanges.length > 0) + { + var prevTimeChange:SongTimeChange = timeChanges[timeChanges.length - 1]; + currentTimeChange.beatTime = FlxMath.roundDecimal(prevTimeChange.beatTime + + ((currentTimeChange.timeStamp - prevTimeChange.timeStamp) * prevTimeChange.bpm / Constants.SECS_PER_MIN / Constants.MS_PER_SEC), + 4); } } @@ -368,13 +379,13 @@ class Conductor } // Update currentStepTime - Conductor.update(Conductor.songPosition); + this.update(Conductor.instance.songPosition); } /** * Given a time in milliseconds, return a time in steps. */ - public static function getTimeInSteps(ms:Float):Float + public function getTimeInSteps(ms:Float):Float { if (timeChanges.length == 0) { @@ -411,7 +422,7 @@ class Conductor /** * Given a time in steps and fractional steps, return a time in milliseconds. */ - public static function getStepTimeInMs(stepTime:Float):Float + public function getStepTimeInMs(stepTime:Float):Float { if (timeChanges.length == 0) { @@ -447,7 +458,7 @@ class Conductor /** * Given a time in beats and fractional beats, return a time in milliseconds. */ - public static function getBeatTimeInMs(beatTime:Float):Float + public function getBeatTimeInMs(beatTime:Float):Float { if (timeChanges.length == 0) { @@ -480,13 +491,20 @@ class Conductor } } + public static function watchQuick():Void + { + FlxG.watch.addQuick("songPosition", Conductor.instance.songPosition); + FlxG.watch.addQuick("bpm", Conductor.instance.bpm); + FlxG.watch.addQuick("currentMeasureTime", Conductor.instance.currentMeasureTime); + FlxG.watch.addQuick("currentBeatTime", Conductor.instance.currentBeatTime); + FlxG.watch.addQuick("currentStepTime", Conductor.instance.currentStepTime); + } + + /** + * Reset the Conductor, replacing the current instance with a fresh one. + */ public static function reset():Void { - beatHit.removeAll(); - stepHit.removeAll(); - - mapTimeChanges([]); - forceBPM(null); - update(0); + Conductor.instance = new Conductor(); } } diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index 681287808..89b004df4 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -64,7 +64,7 @@ class ABotVis extends FlxTypedSpriteGroup if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, vis.numSamples)); else - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, vis.numSamples)); + remappedShit = Std.int(FlxMath.remapToRange(Conductor.instance.songPosition, 0, vis.snd.length, 0, vis.numSamples)); var fftSamples:Array = []; diff --git a/source/funkin/audio/visualize/SpectogramSprite.hx b/source/funkin/audio/visualize/SpectogramSprite.hx index 63d0fcd2e..b4e024a4c 100644 --- a/source/funkin/audio/visualize/SpectogramSprite.hx +++ b/source/funkin/audio/visualize/SpectogramSprite.hx @@ -164,7 +164,7 @@ class SpectogramSprite extends FlxTypedSpriteGroup if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); else - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); + remappedShit = Std.int(FlxMath.remapToRange(Conductor.instance.songPosition, 0, vis.snd.length, 0, numSamples)); var fftSamples:Array = []; var i = remappedShit; @@ -235,15 +235,15 @@ class SpectogramSprite extends FlxTypedSpriteGroup if (vis.snd.playing) remappedShit = Std.int(FlxMath.remapToRange(vis.snd.time, 0, vis.snd.length, 0, numSamples)); else { - if (curTime == Conductor.songPosition) + if (curTime == Conductor.instance.songPosition) { wavOptimiz = 3; return; // already did shit, so finishes function early } - curTime = Conductor.songPosition; + curTime = Conductor.instance.songPosition; - remappedShit = Std.int(FlxMath.remapToRange(Conductor.songPosition, 0, vis.snd.length, 0, numSamples)); + remappedShit = Std.int(FlxMath.remapToRange(Conductor.instance.songPosition, 0, vis.snd.length, 0, numSamples)); } wavOptimiz = 8; diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 600871e2f..66874e5be 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -149,7 +149,7 @@ class SongTimeChange */ @:optional @:alias("b") - public var beatTime:Null; + public var beatTime:Float; /** * Quarter notes per minute (float). Cannot be empty in the first element of the list, @@ -602,7 +602,7 @@ class SongEventDataRaw { if (_stepTime != null && !force) return _stepTime; - return _stepTime = Conductor.getTimeInSteps(this.time); + return _stepTime = Conductor.instance.getTimeInSteps(this.time); } } @@ -796,7 +796,7 @@ class SongNoteDataRaw { if (_stepTime != null && !force) return _stepTime; - return _stepTime = Conductor.getTimeInSteps(this.time); + return _stepTime = Conductor.instance.getTimeInSteps(this.time); } @:jignored @@ -812,7 +812,7 @@ class SongNoteDataRaw if (_stepLength != null && !force) return _stepLength; - return _stepLength = Conductor.getTimeInSteps(this.time + this.length) - getStepTime(); + return _stepLength = Conductor.instance.getTimeInSteps(this.time + this.length) - getStepTime(); } public function setStepLength(value:Float):Void @@ -823,7 +823,7 @@ class SongNoteDataRaw } else { - var lengthMs:Float = Conductor.getStepTimeInMs(value) - this.time; + var lengthMs:Float = Conductor.instance.getStepTimeInMs(value) - this.time; this.length = lengthMs; } _stepLength = null; diff --git a/source/funkin/play/Countdown.hx b/source/funkin/play/Countdown.hx index d23574ce2..5b7ce9fc2 100644 --- a/source/funkin/play/Countdown.hx +++ b/source/funkin/play/Countdown.hx @@ -40,7 +40,7 @@ class Countdown stopCountdown(); PlayState.instance.isInCountdown = true; - Conductor.update(PlayState.instance.startTimestamp + Conductor.beatLengthMs * -5); + Conductor.instance.update(PlayState.instance.startTimestamp + Conductor.instance.beatLengthMs * -5); // Handle onBeatHit events manually // @:privateAccess // PlayState.instance.dispatchEvent(new SongTimeScriptEvent(SONG_BEAT_HIT, 0, 0)); @@ -48,7 +48,7 @@ class Countdown // The timer function gets called based on the beat of the song. countdownTimer = new FlxTimer(); - countdownTimer.start(Conductor.beatLengthMs / 1000, function(tmr:FlxTimer) { + countdownTimer.start(Conductor.instance.beatLengthMs / 1000, function(tmr:FlxTimer) { if (PlayState.instance == null) { tmr.cancel(); @@ -158,7 +158,7 @@ class Countdown { stopCountdown(); // This will trigger PlayState.startSong() - Conductor.update(0); + Conductor.instance.update(0); // PlayState.isInCountdown = false; } @@ -225,7 +225,7 @@ class Countdown countdownSprite.screenCenter(); // Fade sprite in, then out, then destroy it. - FlxTween.tween(countdownSprite, {y: countdownSprite.y += 100, alpha: 0}, Conductor.beatLengthMs / 1000, + FlxTween.tween(countdownSprite, {y: countdownSprite.y += 100, alpha: 0}, Conductor.instance.beatLengthMs / 1000, { ease: FlxEase.cubeInOut, onComplete: function(twn:FlxTween) { diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index dadd5a3d9..137bf3905 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -129,7 +129,7 @@ class GameOverSubState extends MusicBeatSubState gameOverMusic.stop(); // The conductor now represents the BPM of the game over music. - Conductor.update(0); + Conductor.instance.update(0); } var hasStartedAnimation:Bool = false; @@ -204,7 +204,7 @@ class GameOverSubState extends MusicBeatSubState { // Match the conductor to the music. // This enables the stepHit and beatHit events. - Conductor.update(gameOverMusic.time); + Conductor.instance.update(gameOverMusic.time); } else { diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 3dcabf953..f15529a04 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -561,15 +561,15 @@ class PlayState extends MusicBeatSubState } // Prepare the Conductor. - Conductor.forceBPM(null); + Conductor.instance.forceBPM(null); if (currentChart.offsets != null) { - Conductor.instrumentalOffset = currentChart.offsets.getInstrumentalOffset(); + Conductor.instance.instrumentalOffset = currentChart.offsets.getInstrumentalOffset(); } - Conductor.mapTimeChanges(currentChart.timeChanges); - Conductor.update((Conductor.beatLengthMs * -5) + startTimestamp); + Conductor.instance.mapTimeChanges(currentChart.timeChanges); + Conductor.instance.update((Conductor.instance.beatLengthMs * -5) + startTimestamp); // The song is now loaded. We can continue to initialize the play state. initCameras(); @@ -734,7 +734,7 @@ class PlayState extends MusicBeatSubState // Reset music properly. - FlxG.sound.music.time = Math.max(0, startTimestamp - Conductor.instrumentalOffset); + FlxG.sound.music.time = Math.max(0, startTimestamp - Conductor.instance.instrumentalOffset); FlxG.sound.music.pause(); if (!overrideMusic) @@ -785,22 +785,22 @@ class PlayState extends MusicBeatSubState { if (isInCountdown) { - Conductor.update(Conductor.songPosition + elapsed * 1000); - if (Conductor.songPosition >= (startTimestamp)) startSong(); + Conductor.instance.update(Conductor.instance.songPosition + elapsed * 1000); + if (Conductor.instance.songPosition >= (startTimestamp)) startSong(); } } else { if (Constants.EXT_SOUND == 'mp3') { - Conductor.formatOffset = Constants.MP3_DELAY_MS; + Conductor.instance.formatOffset = Constants.MP3_DELAY_MS; } else { - Conductor.formatOffset = 0.0; + Conductor.instance.formatOffset = 0.0; } - Conductor.update(); // Normal conductor update. + Conductor.instance.update(); // Normal conductor update. } var androidPause:Bool = false; @@ -942,7 +942,7 @@ class PlayState extends MusicBeatSubState // TODO: Check that these work even when songPosition is less than 0. if (songEvents != null && songEvents.length > 0) { - var songEventsToActivate:Array = SongEventParser.queryEvents(songEvents, Conductor.songPosition); + var songEventsToActivate:Array = SongEventParser.queryEvents(songEvents, Conductor.instance.songPosition); if (songEventsToActivate.length > 0) { @@ -950,7 +950,7 @@ class PlayState extends MusicBeatSubState for (event in songEventsToActivate) { // If an event is trying to play, but it's over 5 seconds old, skip it. - if (event.time - Conductor.songPosition < -5000) + if (event.time - Conductor.instance.songPosition < -5000) { event.activated = true; continue; @@ -1052,7 +1052,7 @@ class PlayState extends MusicBeatSubState if (startTimer.finished) { DiscordClient.changePresence(detailsText, '${currentChart.songName} ($storyDifficultyText)', iconRPC, true, - currentSongLengthMs - Conductor.songPosition); + currentSongLengthMs - Conductor.instance.songPosition); } else { @@ -1076,12 +1076,12 @@ class PlayState extends MusicBeatSubState { if (health > Constants.HEALTH_MIN && !paused && FlxG.autoPause) { - if (Conductor.songPosition > 0.0) DiscordClient.changePresence(detailsText, currentSong.song + if (Conductor.instance.songPosition > 0.0) DiscordClient.changePresence(detailsText, currentSong.song + ' (' + storyDifficultyText + ')', iconRPC, true, currentSongLengthMs - - Conductor.songPosition); + - Conductor.instance.songPosition); else DiscordClient.changePresence(detailsText, currentSong.song + ' (' + storyDifficultyText + ')', iconRPC); } @@ -1154,17 +1154,17 @@ class PlayState extends MusicBeatSubState if (!startingSong && FlxG.sound.music != null - && (Math.abs(FlxG.sound.music.time - (Conductor.songPosition + Conductor.instrumentalOffset)) > 200 - || Math.abs(vocals.checkSyncError(Conductor.songPosition + Conductor.instrumentalOffset)) > 200)) + && (Math.abs(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 200 + || Math.abs(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)) > 200)) { trace("VOCALS NEED RESYNC"); - if (vocals != null) trace(vocals.checkSyncError(Conductor.songPosition + Conductor.instrumentalOffset)); - trace(FlxG.sound.music.time - (Conductor.songPosition + Conductor.instrumentalOffset)); + if (vocals != null) trace(vocals.checkSyncError(Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)); + trace(FlxG.sound.music.time - (Conductor.instance.songPosition + Conductor.instance.instrumentalOffset)); resyncVocals(); } - if (iconP1 != null) iconP1.onStepHit(Std.int(Conductor.currentStep)); - if (iconP2 != null) iconP2.onStepHit(Std.int(Conductor.currentStep)); + if (iconP1 != null) iconP1.onStepHit(Std.int(Conductor.instance.currentStep)); + if (iconP2 != null) iconP2.onStepHit(Std.int(Conductor.instance.currentStep)); return true; } @@ -1185,14 +1185,14 @@ class PlayState extends MusicBeatSubState } // Only zoom camera if we are zoomed by less than 35%. - if (FlxG.camera.zoom < (1.35 * defaultCameraZoom) && cameraZoomRate > 0 && Conductor.currentBeat % cameraZoomRate == 0) + if (FlxG.camera.zoom < (1.35 * defaultCameraZoom) && cameraZoomRate > 0 && Conductor.instance.currentBeat % cameraZoomRate == 0) { // Zoom camera in (1.5%) FlxG.camera.zoom += cameraZoomIntensity * defaultCameraZoom; // Hud zooms double (3%) camHUD.zoom += hudCameraZoomIntensity * defaultHUDCameraZoom; } - // trace('Not bopping camera: ${FlxG.camera.zoom} < ${(1.35 * defaultCameraZoom)} && ${cameraZoomRate} > 0 && ${Conductor.currentBeat} % ${cameraZoomRate} == ${Conductor.currentBeat % cameraZoomRate}}'); + // trace('Not bopping camera: ${FlxG.camera.zoom} < ${(1.35 * defaultCameraZoom)} && ${cameraZoomRate} > 0 && ${Conductor.instance.currentBeat} % ${cameraZoomRate} == ${Conductor.instance.currentBeat % cameraZoomRate}}'); // That combo milestones that got spoiled that one time. // Comes with NEAT visual and audio effects. @@ -1205,13 +1205,13 @@ class PlayState extends MusicBeatSubState // TODO: Re-enable combo text (how to do this without sections?). // if (currentSong != null) // { - // shouldShowComboText = (Conductor.currentBeat % 8 == 7); - // var daSection = .getSong()[Std.int(Conductor.currentBeat / 16)]; + // shouldShowComboText = (Conductor.instance.currentBeat % 8 == 7); + // var daSection = .getSong()[Std.int(Conductor.instance.currentBeat / 16)]; // shouldShowComboText = shouldShowComboText && (daSection != null && daSection.mustHitSection); // shouldShowComboText = shouldShowComboText && (Highscore.tallies.combo > 5); // - // var daNextSection = .getSong()[Std.int(Conductor.currentBeat / 16) + 1]; - // var isEndOfSong = .getSong().length < Std.int(Conductor.currentBeat / 16); + // var daNextSection = .getSong()[Std.int(Conductor.instance.currentBeat / 16) + 1]; + // var isEndOfSong = .getSong().length < Std.int(Conductor.instance.currentBeat / 16); // shouldShowComboText = shouldShowComboText && (isEndOfSong || (daNextSection != null && !daNextSection.mustHitSection)); // } @@ -1224,7 +1224,7 @@ class PlayState extends MusicBeatSubState var frameShit:Float = (1 / 24) * 2; // equals 2 frames in the animation - new FlxTimer().start(((Conductor.beatLengthMs / 1000) * 1.25) - frameShit, function(tmr) { + new FlxTimer().start(((Conductor.instance.beatLengthMs / 1000) * 1.25) - frameShit, function(tmr) { animShit.forceFinish(); }); } @@ -1261,10 +1261,10 @@ class PlayState extends MusicBeatSubState if (currentStage == null) return; // TODO: Add HEY! song events to Tutorial. - if (Conductor.currentBeat % 16 == 15 + if (Conductor.instance.currentBeat % 16 == 15 && currentStage.getDad().characterId == 'gf' - && Conductor.currentBeat > 16 - && Conductor.currentBeat < 48) + && Conductor.instance.currentBeat > 16 + && Conductor.instance.currentBeat < 48) { currentStage.getBoyfriend().playAnimation('hey', true); currentStage.getDad().playAnimation('cheer', true); @@ -1575,7 +1575,7 @@ class PlayState extends MusicBeatSubState trace('Song difficulty could not be loaded.'); } - // Conductor.forceBPM(currentChart.getStartingBPM()); + // Conductor.instance.forceBPM(currentChart.getStartingBPM()); if (!overrideMusic) { @@ -1706,7 +1706,7 @@ class PlayState extends MusicBeatSubState FlxG.sound.music.onComplete = endSong; // A negative instrumental offset means the song skips the first few milliseconds of the track. // This just gets added into the startTimestamp behavior so we don't need to do anything extra. - FlxG.sound.music.time = startTimestamp - Conductor.instrumentalOffset; + FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset; trace('Playing vocals...'); add(vocals); @@ -1722,7 +1722,7 @@ class PlayState extends MusicBeatSubState if (startTimestamp > 0) { - // FlxG.sound.music.time = startTimestamp - Conductor.instrumentalOffset; + // FlxG.sound.music.time = startTimestamp - Conductor.instance.instrumentalOffset; handleSkippedNotes(); } } @@ -1800,7 +1800,7 @@ class PlayState extends MusicBeatSubState var hitWindowCenter = note.strumTime; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - if (Conductor.songPosition > hitWindowEnd) + if (Conductor.instance.songPosition > hitWindowEnd) { if (note.hasMissed) continue; @@ -1810,7 +1810,7 @@ class PlayState extends MusicBeatSubState if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; } - else if (Conductor.songPosition > hitWindowCenter) + else if (Conductor.instance.songPosition > hitWindowCenter) { if (note.hasBeenHit) continue; @@ -1831,7 +1831,7 @@ class PlayState extends MusicBeatSubState opponentStrumline.playNoteHoldCover(note.holdNoteSprite); } } - else if (Conductor.songPosition > hitWindowStart) + else if (Conductor.instance.songPosition > hitWindowStart) { if (note.hasBeenHit || note.hasMissed) continue; @@ -1877,14 +1877,14 @@ class PlayState extends MusicBeatSubState var hitWindowCenter = note.strumTime; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - if (Conductor.songPosition > hitWindowEnd) + if (Conductor.instance.songPosition > hitWindowEnd) { note.tooEarly = false; note.mayHit = false; note.hasMissed = true; if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; } - else if (Conductor.songPosition > hitWindowStart) + else if (Conductor.instance.songPosition > hitWindowStart) { note.tooEarly = false; note.mayHit = true; @@ -1951,7 +1951,7 @@ class PlayState extends MusicBeatSubState if (note == null || note.hasBeenHit) continue; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - if (Conductor.songPosition > hitWindowEnd) + if (Conductor.instance.songPosition > hitWindowEnd) { // We have passed this note. // Flag the note for deletion without actually penalizing the player. @@ -2115,7 +2115,7 @@ class PlayState extends MusicBeatSubState { inputSpitter.push( { - t: Std.int(Conductor.songPosition), + t: Std.int(Conductor.instance.songPosition), d: indices[i], l: 20 }); @@ -2125,7 +2125,7 @@ class PlayState extends MusicBeatSubState { inputSpitter.push( { - t: Std.int(Conductor.songPosition), + t: Std.int(Conductor.instance.songPosition), d: -1, l: 20 }); @@ -2186,7 +2186,7 @@ class PlayState extends MusicBeatSubState { inputSpitter.push( { - t: Std.int(Conductor.songPosition), + t: Std.int(Conductor.instance.songPosition), d: indices[i], l: 20 }); @@ -2275,7 +2275,7 @@ class PlayState extends MusicBeatSubState // Get the offset and compensate for input latency. // Round inward (trim remainder) for consistency. - var noteDiff:Int = Std.int(Conductor.songPosition - daNote.noteData.time - inputLatencyMs); + var noteDiff:Int = Std.int(Conductor.instance.songPosition - daNote.noteData.time - inputLatencyMs); var score = Scoring.scoreNote(noteDiff, PBOT1); var daRating = Scoring.judgeNote(noteDiff, PBOT1); @@ -2330,7 +2330,7 @@ class PlayState extends MusicBeatSubState { inputSpitter.push( { - t: Std.int(Conductor.songPosition), + t: Std.int(Conductor.instance.songPosition), d: indices[i], l: 20 }); @@ -2340,7 +2340,7 @@ class PlayState extends MusicBeatSubState { inputSpitter.push( { - t: Std.int(Conductor.songPosition), + t: Std.int(Conductor.instance.songPosition), d: -1, l: 20 }); @@ -2739,15 +2739,15 @@ class PlayState extends MusicBeatSubState { FlxG.sound.music.pause(); - var targetTimeSteps:Float = Conductor.currentStepTime + (Conductor.timeSignatureNumerator * Constants.STEPS_PER_BEAT * sections); - var targetTimeMs:Float = Conductor.getStepTimeInMs(targetTimeSteps); + var targetTimeSteps:Float = Conductor.instance.currentStepTime + (Conductor.instance.timeSignatureNumerator * Constants.STEPS_PER_BEAT * sections); + var targetTimeMs:Float = Conductor.instance.getStepTimeInMs(targetTimeSteps); FlxG.sound.music.time = targetTimeMs; handleSkippedNotes(); // regenNoteData(FlxG.sound.music.time); - Conductor.update(FlxG.sound.music.time); + Conductor.instance.update(FlxG.sound.music.time); resyncVocals(); } diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index 7ad0892f6..390864148 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -367,7 +367,7 @@ class BaseCharacter extends Bopper // This lets you add frames to the end of the sing animation to ease back into the idle! holdTimer += event.elapsed; - var singTimeSec:Float = singTimeSec * (Conductor.beatLengthMs * 0.001); // x beats, to ms. + var singTimeSec:Float = singTimeSec * (Conductor.instance.beatLengthMs * 0.001); // x beats, to ms. if (getCurrentAnimation().endsWith('miss')) singTimeSec *= 2; // makes it feel more awkward when you miss diff --git a/source/funkin/play/components/ComboMilestone.hx b/source/funkin/play/components/ComboMilestone.hx index 54d1438f1..4119e45c2 100644 --- a/source/funkin/play/components/ComboMilestone.hx +++ b/source/funkin/play/components/ComboMilestone.hx @@ -40,7 +40,7 @@ class ComboMilestone extends FlxTypedSpriteGroup { if (onScreenTime < 0.9) { - new FlxTimer().start((Conductor.beatLengthMs / 1000) * 0.25, function(tmr) { + new FlxTimer().start((Conductor.instance.beatLengthMs / 1000) * 0.25, function(tmr) { forceFinish(); }); } diff --git a/source/funkin/play/components/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx index 38a6ec15a..9553856a9 100644 --- a/source/funkin/play/components/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -59,7 +59,7 @@ class PopUpStuff extends FlxTypedGroup remove(rating, true); rating.destroy(); }, - startDelay: Conductor.beatLengthMs * 0.001 + startDelay: Conductor.instance.beatLengthMs * 0.001 }); } @@ -110,7 +110,7 @@ class PopUpStuff extends FlxTypedGroup remove(comboSpr, true); comboSpr.destroy(); }, - startDelay: Conductor.beatLengthMs * 0.001 + startDelay: Conductor.instance.beatLengthMs * 0.001 }); var seperatedScore:Array = []; @@ -157,7 +157,7 @@ class PopUpStuff extends FlxTypedGroup remove(numScore, true); numScore.destroy(); }, - startDelay: Conductor.beatLengthMs * 0.002 + startDelay: Conductor.instance.beatLengthMs * 0.002 }); daLoop++; diff --git a/source/funkin/play/event/ZoomCameraSongEvent.hx b/source/funkin/play/event/ZoomCameraSongEvent.hx index 1ae76039e..4ad2ed390 100644 --- a/source/funkin/play/event/ZoomCameraSongEvent.hx +++ b/source/funkin/play/event/ZoomCameraSongEvent.hx @@ -79,7 +79,8 @@ class ZoomCameraSongEvent extends SongEvent return; } - FlxTween.tween(PlayState.instance, {defaultCameraZoom: zoom * FlxCamera.defaultZoom}, (Conductor.stepLengthMs * duration / 1000), {ease: easeFunction}); + FlxTween.tween(PlayState.instance, {defaultCameraZoom: zoom * FlxCamera.defaultZoom}, (Conductor.instance.stepLengthMs * duration / 1000), + {ease: easeFunction}); } } diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 948e9fa5b..b312494cf 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -279,7 +279,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.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); + return Constants.PIXELS_PER_MS * (Conductor.instance.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); } function updateNotes():Void @@ -287,8 +287,8 @@ class Strumline extends FlxSpriteGroup if (noteData.length == 0) return; var songStart:Float = PlayState.instance?.startTimestamp ?? 0.0; - var hitWindowStart:Float = Conductor.songPosition - Constants.HIT_WINDOW_MS; - var renderWindowStart:Float = Conductor.songPosition + RENDER_DISTANCE_MS; + var hitWindowStart:Float = Conductor.instance.songPosition - Constants.HIT_WINDOW_MS; + var renderWindowStart:Float = Conductor.instance.songPosition + RENDER_DISTANCE_MS; for (noteIndex in nextNoteIndex...noteData.length) { @@ -335,7 +335,7 @@ class Strumline extends FlxSpriteGroup { if (holdNote == null || !holdNote.alive) continue; - if (Conductor.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) + if (Conductor.instance.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) { if (isPlayer && !isKeyHeld(holdNote.noteDirection)) { @@ -349,7 +349,7 @@ class Strumline extends FlxSpriteGroup var renderWindowEnd = holdNote.strumTime + holdNote.fullSustainLength + Constants.HIT_WINDOW_MS + RENDER_DISTANCE_MS / 8; - if (holdNote.missedNote && Conductor.songPosition >= renderWindowEnd) + if (holdNote.missedNote && Conductor.instance.songPosition >= renderWindowEnd) { // Hold note is offscreen, kill it. holdNote.visible = false; @@ -399,13 +399,13 @@ class Strumline extends FlxSpriteGroup holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; } } - else if (Conductor.songPosition > holdNote.strumTime && holdNote.hitNote) + else if (Conductor.instance.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.songPosition; + holdNote.sustainLength = (holdNote.strumTime + holdNote.fullSustainLength) - Conductor.instance.songPosition; if (holdNote.sustainLength <= 10) { diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 077e9e495..848985563 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -83,13 +83,13 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler function handleQuickWatch():Void { // Display Conductor info in the watch window. - FlxG.watch.addQuick("songPosition", Conductor.songPosition); - FlxG.watch.addQuick("songPositionNoOffset", Conductor.songPosition + Conductor.instrumentalOffset); + FlxG.watch.addQuick("songPosition", Conductor.instance.songPosition); + FlxG.watch.addQuick("songPositionNoOffset", Conductor.instance.songPosition + Conductor.instance.instrumentalOffset); FlxG.watch.addQuick("musicTime", FlxG.sound.music?.time ?? 0.0); - FlxG.watch.addQuick("bpm", Conductor.bpm); - FlxG.watch.addQuick("currentMeasureTime", Conductor.currentBeatTime); - FlxG.watch.addQuick("currentBeatTime", Conductor.currentBeatTime); - FlxG.watch.addQuick("currentStepTime", Conductor.currentStepTime); + FlxG.watch.addQuick("bpm", Conductor.instance.bpm); + FlxG.watch.addQuick("currentMeasureTime", Conductor.instance.currentBeatTime); + FlxG.watch.addQuick("currentBeatTime", Conductor.instance.currentBeatTime); + FlxG.watch.addQuick("currentStepTime", Conductor.instance.currentStepTime); } override function update(elapsed:Float) @@ -139,7 +139,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function stepHit():Bool { - var event = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep); + var event = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); dispatchEvent(event); @@ -150,7 +150,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function beatHit():Bool { - var event = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep); + var event = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 9dd755b62..0fa55c234 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -65,12 +65,8 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl if (FlxG.keys.justPressed.F5) debug_refreshModules(); // Display Conductor info in the watch window. - FlxG.watch.addQuick("songPosition", Conductor.songPosition); FlxG.watch.addQuick("musicTime", FlxG.sound.music?.time ?? 0.0); - FlxG.watch.addQuick("bpm", Conductor.bpm); - FlxG.watch.addQuick("currentMeasureTime", Conductor.currentBeatTime); - FlxG.watch.addQuick("currentBeatTime", Conductor.currentBeatTime); - FlxG.watch.addQuick("currentStepTime", Conductor.currentStepTime); + Conductor.watchQuick(); dispatchEvent(new UpdateScriptEvent(elapsed)); } @@ -99,7 +95,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function stepHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.currentBeat, Conductor.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); dispatchEvent(event); @@ -115,7 +111,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function beatHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.currentBeat, Conductor.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 4f96fad69..1c47f81bf 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -21,6 +21,7 @@ import flixel.system.FlxAssets.FlxSoundAsset; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.tweens.misc.VarTween; +import haxe.ui.Toolkit; import flixel.util.FlxColor; import flixel.util.FlxSort; import flixel.util.FlxTimer; @@ -274,13 +275,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function get_songLengthInSteps():Float { - return Conductor.getTimeInSteps(songLengthInMs); + return Conductor.instance.getTimeInSteps(songLengthInMs); } function set_songLengthInSteps(value:Float):Float { - // Getting a reasonable result from setting songLengthInSteps requires that Conductor.mapBPMChanges be called first. - songLengthInMs = Conductor.getStepTimeInMs(value); + // Getting a reasonable result from setting songLengthInSteps requires that Conductor.instance.mapBPMChanges be called first. + songLengthInMs = Conductor.instance.getStepTimeInMs(value); return value; } @@ -394,12 +395,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function get_scrollPositionInMs():Float { - return Conductor.getStepTimeInMs(scrollPositionInSteps); + return Conductor.instance.getStepTimeInMs(scrollPositionInSteps); } function set_scrollPositionInMs(value:Float):Float { - scrollPositionInSteps = Conductor.getTimeInSteps(value); + scrollPositionInSteps = Conductor.instance.getTimeInSteps(value); return value; } @@ -453,13 +454,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function get_playheadPositionInMs():Float { if (audioVisGroup != null && audioVisGroup.playerVis != null) - audioVisGroup.playerVis.realtimeStartOffset = -Conductor.getStepTimeInMs(playheadPositionInSteps); - return Conductor.getStepTimeInMs(playheadPositionInSteps); + audioVisGroup.playerVis.realtimeStartOffset = -Conductor.instance.getStepTimeInMs(playheadPositionInSteps); + return Conductor.instance.getStepTimeInMs(playheadPositionInSteps); } function set_playheadPositionInMs(value:Float):Float { - playheadPositionInSteps = Conductor.getTimeInSteps(value); + playheadPositionInSteps = Conductor.instance.getTimeInSteps(value); if (audioVisGroup != null && audioVisGroup.playerVis != null) audioVisGroup.playerVis.realtimeStartOffset = -value; return value; @@ -2418,13 +2419,13 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } else { - Conductor.currentTimeChange.bpm += 1; + Conductor.instance.currentTimeChange.bpm += 1; this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT); } } playbarBPM.onRightClick = _ -> { - Conductor.currentTimeChange.bpm -= 1; + Conductor.instance.currentTimeChange.bpm -= 1; this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT); } @@ -2489,9 +2490,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState menubarItemPaste.onClick = _ -> { var targetMs:Float = scrollPositionInMs + playheadPositionInMs; - var targetStep:Float = Conductor.getTimeInSteps(targetMs); + var targetStep:Float = Conductor.instance.getTimeInSteps(targetMs); var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio; - var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep); + var targetSnappedMs:Float = Conductor.instance.getStepTimeInMs(targetSnappedStep); performCommand(new PasteItemsCommand(targetSnappedMs)); }; @@ -2685,10 +2686,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState saveDataDirty = false; } + var displayAutosavePopup:Bool = false; + /** * UPDATE FUNCTIONS */ - function autoSave():Void + function autoSave(?beforePlaytest:Bool = false):Void { var needsAutoSave:Bool = saveDataDirty; @@ -2706,13 +2709,21 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (needsAutoSave) { this.exportAllSongData(true, null); - var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]); - this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [ - { - text: "Take Me There", - callback: openBackupsFolder, - } - ]); + if (beforePlaytest) + { + displayAutosavePopup = true; + } + else + { + displayAutosavePopup = false; + var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]); + this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [ + { + text: "Take Me There", + callback: openBackupsFolder, + } + ]); + } } #end } @@ -2828,7 +2839,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (metronomeVolume > 0.0 && this.subState == null && (audioInstTrack != null && audioInstTrack.isPlaying)) { - playMetronomeTick(Conductor.currentBeat % 4 == 0); + playMetronomeTick(Conductor.instance.currentBeat % 4 == 0); } return true; @@ -2844,8 +2855,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (audioInstTrack != null && audioInstTrack.isPlaying) { - if (healthIconDad != null) healthIconDad.onStepHit(Conductor.currentStep); - if (healthIconBF != null) healthIconBF.onStepHit(Conductor.currentStep); + if (healthIconDad != null) healthIconDad.onStepHit(Conductor.instance.currentStep); + if (healthIconBF != null) healthIconBF.onStepHit(Conductor.instance.currentStep); } // Updating these every step keeps it more accurate. @@ -2873,12 +2884,12 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState audioInstTrack.update(elapsed); // If the song starts 50ms in, make sure we start the song there. - if (Conductor.instrumentalOffset < 0) + if (Conductor.instance.instrumentalOffset < 0) { - if (audioInstTrack.time < -Conductor.instrumentalOffset) + if (audioInstTrack.time < -Conductor.instance.instrumentalOffset) { - trace('Resetting instrumental time to ${- Conductor.instrumentalOffset}ms'); - audioInstTrack.time = -Conductor.instrumentalOffset; + trace('Resetting instrumental time to ${- Conductor.instance.instrumentalOffset}ms'); + audioInstTrack.time = -Conductor.instance.instrumentalOffset; } } } @@ -2889,16 +2900,16 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { // If middle mouse panning during song playback, we move ONLY the playhead, without scrolling. Neat! - var oldStepTime:Float = Conductor.currentStepTime; - var oldSongPosition:Float = Conductor.songPosition + Conductor.instrumentalOffset; - Conductor.update(audioInstTrack.time); - handleHitsounds(oldSongPosition, Conductor.songPosition + Conductor.instrumentalOffset); + var oldStepTime:Float = Conductor.instance.currentStepTime; + var oldSongPosition:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset; + Conductor.instance.update(audioInstTrack.time); + handleHitsounds(oldSongPosition, Conductor.instance.songPosition + Conductor.instance.instrumentalOffset); // Resync vocals. if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) { audioVocalTrackGroup.time = audioInstTrack.time; } - var diffStepTime:Float = Conductor.currentStepTime - oldStepTime; + var diffStepTime:Float = Conductor.instance.currentStepTime - oldStepTime; // Move the playhead. playheadPositionInPixels += diffStepTime * GRID_SIZE; @@ -2908,9 +2919,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState else { // Else, move the entire view. - var oldSongPosition:Float = Conductor.songPosition + Conductor.instrumentalOffset; - Conductor.update(audioInstTrack.time); - handleHitsounds(oldSongPosition, Conductor.songPosition + Conductor.instrumentalOffset); + var oldSongPosition:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset; + Conductor.instance.update(audioInstTrack.time); + handleHitsounds(oldSongPosition, Conductor.instance.songPosition + Conductor.instance.instrumentalOffset); // Resync vocals. if (audioVocalTrackGroup != null && Math.abs(audioInstTrack.time - audioVocalTrackGroup.time) > 100) { @@ -2919,7 +2930,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // We need time in fractional steps here to allow the song to actually play. // Also account for a potentially offset playhead. - scrollPositionInPixels = (Conductor.currentStepTime + Conductor.instrumentalOffsetSteps) * GRID_SIZE - playheadPositionInPixels; + scrollPositionInPixels = (Conductor.instance.currentStepTime + Conductor.instance.instrumentalOffsetSteps) * GRID_SIZE - playheadPositionInPixels; // DO NOT move song to scroll position here specifically. @@ -3048,8 +3059,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Let's try testing only notes within a certain range of the view area. // TODO: I don't think this messes up really long sustains, does it? - var viewAreaTopMs:Float = scrollPositionInMs - (Conductor.measureLengthMs * 2); // Is 2 measures enough? - var viewAreaBottomMs:Float = scrollPositionInMs + (Conductor.measureLengthMs * 2); // Is 2 measures enough? + var viewAreaTopMs:Float = scrollPositionInMs - (Conductor.instance.measureLengthMs * 2); // Is 2 measures enough? + var viewAreaBottomMs:Float = scrollPositionInMs + (Conductor.instance.measureLengthMs * 2); // Is 2 measures enough? // Add notes that are now visible. for (noteData in currentSongChartNoteData) @@ -3336,14 +3347,14 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // PAGE UP = Jump up to nearest measure if (pageUpKeyHandler.activated) { - var measureHeight:Float = GRID_SIZE * 4 * Conductor.beatsPerMeasure; + var measureHeight:Float = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure; var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels; var targetScrollPosition:Float = Math.floor(playheadPos / measureHeight) * measureHeight; // If we would move less than one grid, instead move to the top of the previous measure. var targetScrollAmount = Math.abs(targetScrollPosition - playheadPos); if (targetScrollAmount < GRID_SIZE) { - targetScrollPosition -= GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.beatsPerMeasure; + targetScrollPosition -= GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.instance.beatsPerMeasure; } scrollAmount = targetScrollPosition - playheadPos; @@ -3352,21 +3363,21 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (playbarButtonPressed == 'playbarBack') { playbarButtonPressed = ''; - scrollAmount = -GRID_SIZE * 4 * Conductor.beatsPerMeasure; + scrollAmount = -GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure; shouldPause = true; } // PAGE DOWN = Jump down to nearest measure if (pageDownKeyHandler.activated) { - var measureHeight:Float = GRID_SIZE * 4 * Conductor.beatsPerMeasure; + var measureHeight:Float = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure; var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels; var targetScrollPosition:Float = Math.ceil(playheadPos / measureHeight) * measureHeight; // If we would move less than one grid, instead move to the top of the next measure. var targetScrollAmount = Math.abs(targetScrollPosition - playheadPos); if (targetScrollAmount < GRID_SIZE) { - targetScrollPosition += GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.beatsPerMeasure; + targetScrollPosition += GRID_SIZE * Constants.STEPS_PER_BEAT * Conductor.instance.beatsPerMeasure; } scrollAmount = targetScrollPosition - playheadPos; @@ -3375,7 +3386,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (playbarButtonPressed == 'playbarForward') { playbarButtonPressed = ''; - scrollAmount = GRID_SIZE * 4 * Conductor.beatsPerMeasure; + scrollAmount = GRID_SIZE * 4 * Conductor.instance.beatsPerMeasure; shouldPause = true; } @@ -3578,10 +3589,10 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // The song position of the cursor, in steps. var cursorFractionalStep:Float = cursorY / GRID_SIZE; - var cursorMs:Float = Conductor.getStepTimeInMs(cursorFractionalStep); + var cursorMs:Float = Conductor.instance.getStepTimeInMs(cursorFractionalStep); // Round the cursor step to the nearest snap quant. var cursorSnappedStep:Float = Math.floor(cursorFractionalStep / noteSnapRatio) * noteSnapRatio; - var cursorSnappedMs:Float = Conductor.getStepTimeInMs(cursorSnappedStep); + var cursorSnappedMs:Float = Conductor.instance.getStepTimeInMs(cursorSnappedStep); // The direction value for the column at the cursor. var cursorGridPos:Int = Math.floor(cursorX / GRID_SIZE); @@ -3603,7 +3614,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // We released the mouse. Select the notes in the box. var cursorFractionalStepStart:Float = cursorYStart / GRID_SIZE; var cursorStepStart:Int = Math.floor(cursorFractionalStepStart); - var cursorMsStart:Float = Conductor.getStepTimeInMs(cursorStepStart); + var cursorMsStart:Float = Conductor.instance.getStepTimeInMs(cursorStepStart); var cursorColumnBase:Int = Math.floor(cursorX / GRID_SIZE); var cursorColumnBaseStart:Int = Math.floor(cursorXStart / GRID_SIZE); @@ -3839,11 +3850,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var dragDistanceMs:Float = 0; if (dragTargetNote != null && dragTargetNote.noteData != null) { - dragDistanceMs = Conductor.getStepTimeInMs(dragTargetNote.noteData.getStepTime() + dragDistanceSteps) - dragTargetNote.noteData.time; + dragDistanceMs = Conductor.instance.getStepTimeInMs(dragTargetNote.noteData.getStepTime() + dragDistanceSteps) - dragTargetNote.noteData.time; } else if (dragTargetEvent != null && dragTargetEvent.eventData != null) { - dragDistanceMs = Conductor.getStepTimeInMs(dragTargetEvent.eventData.getStepTime() + dragDistanceSteps) - dragTargetEvent.eventData.time; + dragDistanceMs = Conductor.instance.getStepTimeInMs(dragTargetEvent.eventData.getStepTime() + dragDistanceSteps) - dragTargetEvent.eventData.time; } var dragDistanceColumns:Int = dragTargetCurrentColumn; @@ -3903,7 +3914,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { stepTime = dragTargetEvent.eventData.getStepTime(); } - var dragDistanceSteps:Float = Conductor.getTimeInSteps(cursorSnappedMs).clamp(0, songLengthInSteps - (1 * noteSnapRatio)) - stepTime; + var dragDistanceSteps:Float = Conductor.instance.getTimeInSteps(cursorSnappedMs).clamp(0, songLengthInSteps - (1 * noteSnapRatio)) - stepTime; var data:Int = 0; var noteGridPos:Int = 0; if (dragTargetNote != null && dragTargetNote.noteData != null) @@ -3935,8 +3946,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Handle extending the note as you drag. var stepTime:Float = inline currentPlaceNoteData.getStepTime(); - var dragLengthSteps:Float = Conductor.getTimeInSteps(cursorSnappedMs) - stepTime; - var dragLengthMs:Float = dragLengthSteps * Conductor.stepLengthMs; + var dragLengthSteps:Float = Conductor.instance.getTimeInSteps(cursorSnappedMs) - stepTime; + var dragLengthMs:Float = dragLengthSteps * Conductor.instance.stepLengthMs; var dragLengthPixels:Float = dragLengthSteps * GRID_SIZE; if (gridGhostNote != null && gridGhostNote.noteData != null && gridGhostHoldNote != null) @@ -4397,7 +4408,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState if (playbarHeadLayout.playbarHead.value != songPosPercent) playbarHeadLayout.playbarHead.value = songPosPercent; } - var songPos:Float = Conductor.songPosition + Conductor.instrumentalOffset; + var songPos:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset; var songPosSeconds:String = Std.string(Math.floor((Math.abs(songPos) / 1000) % 60)).lpad('0', 2); var songPosMinutes:String = Std.string(Math.floor((Math.abs(songPos) / 1000) / 60)).lpad('0', 2); if (songPos < 0) songPosMinutes = '-' + songPosMinutes; @@ -4453,11 +4464,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var playheadPos:Float = scrollPositionInPixels + playheadPositionInPixels; var playheadPosFractionalStep:Float = playheadPos / GRID_SIZE / noteSnapRatio; var playheadPosStep:Int = Std.int(Math.floor(playheadPosFractionalStep)); - var playheadPosSnappedMs:Float = playheadPosStep * Conductor.stepLengthMs * noteSnapRatio; + var playheadPosSnappedMs:Float = playheadPosStep * Conductor.instance.stepLengthMs * noteSnapRatio; // Look for notes within 1 step of the playhead. var notesAtPos:Array = SongDataUtils.getNotesInTimeRange(currentSongChartNoteData, playheadPosSnappedMs, - playheadPosSnappedMs + Conductor.stepLengthMs * noteSnapRatio); + playheadPosSnappedMs + Conductor.instance.stepLengthMs * noteSnapRatio); notesAtPos = SongDataUtils.getNotesWithData(notesAtPos, [column]); if (notesAtPos.length == 0) @@ -4654,9 +4665,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState else { var targetMs:Float = scrollPositionInMs + playheadPositionInMs; - var targetStep:Float = Conductor.getTimeInSteps(targetMs); + var targetStep:Float = Conductor.instance.getTimeInSteps(targetMs); var targetSnappedStep:Float = Math.floor(targetStep / noteSnapRatio) * noteSnapRatio; - var targetSnappedMs:Float = Conductor.getStepTimeInMs(targetSnappedStep); + var targetSnappedMs:Float = Conductor.instance.getStepTimeInMs(targetSnappedStep); targetSnappedMs; } performCommand(new PasteItemsCommand(targetMs)); @@ -4796,7 +4807,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState */ function testSongInPlayState(minimal:Bool = false):Void { - autoSave(); + autoSave(true); stopWelcomeMusic(); @@ -5000,7 +5011,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Remove any notes past the end of the song. var songCutoffPointSteps:Float = songLengthInSteps - 0.1; - var songCutoffPointMs:Float = Conductor.getStepTimeInMs(songCutoffPointSteps); + var songCutoffPointMs:Float = Conductor.instance.getStepTimeInMs(songCutoffPointSteps); currentSongChartNoteData = SongDataUtils.clampSongNoteData(currentSongChartNoteData, 0.0, songCutoffPointMs); currentSongChartEventData = SongDataUtils.clampSongEventData(currentSongChartEventData, 0.0, songCutoffPointMs); @@ -5102,7 +5113,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var prevDifficulty = availableDifficulties[availableDifficulties.length - 1]; selectedDifficulty = prevDifficulty; - Conductor.mapTimeChanges(this.currentSongMetadata.timeChanges); + Conductor.instance.mapTimeChanges(this.currentSongMetadata.timeChanges); refreshDifficultyTreeSelection(); this.refreshToolbox(CHART_EDITOR_TOOLBOX_METADATA_LAYOUT); @@ -5164,9 +5175,9 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Update the songPosition in the audio tracks. if (audioInstTrack != null) { - audioInstTrack.time = scrollPositionInMs + playheadPositionInMs - Conductor.instrumentalOffset; + audioInstTrack.time = scrollPositionInMs + playheadPositionInMs - Conductor.instance.instrumentalOffset; // Update the songPosition in the Conductor. - Conductor.update(audioInstTrack.time); + Conductor.instance.update(audioInstTrack.time); if (audioVocalTrackGroup != null) audioVocalTrackGroup.time = audioInstTrack.time; } @@ -5226,6 +5237,20 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState this.persistentUpdate = true; this.persistentDraw = true; + if (displayAutosavePopup) + { + displayAutosavePopup = false; + Toolkit.callLater(() -> { + var absoluteBackupsPath:String = Path.join([Sys.getCwd(), ChartEditorImportExportHandler.BACKUPS_PATH]); + this.infoWithActions('Auto-Save', 'Chart auto-saved to ${absoluteBackupsPath}.', [ + { + text: "Take Me There", + callback: openBackupsFolder, + } + ]); + }); + } + moveSongToScrollPosition(); fadeInWelcomeMusic(7, 10); @@ -5485,7 +5510,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState trace('ERROR: Instrumental track is null!'); } - this.songLengthInMs = (audioInstTrack?.length ?? 1000.0) + Conductor.instrumentalOffset; + this.songLengthInMs = (audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset; // Many things get reset when song length changes. healthIconsDirty = true; diff --git a/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx b/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx index 3c45c1168..1ea681cb1 100644 --- a/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx +++ b/source/funkin/ui/debug/charting/commands/ChangeStartingBPMCommand.hx @@ -34,7 +34,7 @@ class ChangeStartingBPMCommand implements ChartEditorCommand state.currentSongMetadata.timeChanges = timeChanges; - Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); } public function undo(state:ChartEditorState):Void @@ -51,7 +51,7 @@ class ChangeStartingBPMCommand implements ChartEditorCommand state.currentSongMetadata.timeChanges = timeChanges; - Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); } public function toString():String diff --git a/source/funkin/ui/debug/charting/commands/MoveEventsCommand.hx b/source/funkin/ui/debug/charting/commands/MoveEventsCommand.hx index efe9c25d5..8331ed397 100644 --- a/source/funkin/ui/debug/charting/commands/MoveEventsCommand.hx +++ b/source/funkin/ui/debug/charting/commands/MoveEventsCommand.hx @@ -33,7 +33,7 @@ class MoveEventsCommand implements ChartEditorCommand { // Clone the notes to prevent editing from affecting the history. var resultEvent = event.clone(); - resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); + resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); movedEvents.push(resultEvent); } diff --git a/source/funkin/ui/debug/charting/commands/MoveItemsCommand.hx b/source/funkin/ui/debug/charting/commands/MoveItemsCommand.hx index 2eedbbf03..087f29e82 100644 --- a/source/funkin/ui/debug/charting/commands/MoveItemsCommand.hx +++ b/source/funkin/ui/debug/charting/commands/MoveItemsCommand.hx @@ -41,7 +41,7 @@ class MoveItemsCommand implements ChartEditorCommand { // Clone the notes to prevent editing from affecting the history. var resultNote = note.clone(); - resultNote.time = (resultNote.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); + resultNote.time = (resultNote.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); resultNote.data = ChartEditorState.gridColumnToNoteData((ChartEditorState.noteDataToGridColumn(resultNote.data) + columns).clamp(0, ChartEditorState.STRUMLINE_SIZE * 2 - 1)); @@ -52,7 +52,7 @@ class MoveItemsCommand implements ChartEditorCommand { // Clone the notes to prevent editing from affecting the history. var resultEvent = event.clone(); - resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); + resultEvent.time = (resultEvent.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); movedEvents.push(resultEvent); } diff --git a/source/funkin/ui/debug/charting/commands/MoveNotesCommand.hx b/source/funkin/ui/debug/charting/commands/MoveNotesCommand.hx index 8bce747a1..0308d8fc8 100644 --- a/source/funkin/ui/debug/charting/commands/MoveNotesCommand.hx +++ b/source/funkin/ui/debug/charting/commands/MoveNotesCommand.hx @@ -34,7 +34,7 @@ class MoveNotesCommand implements ChartEditorCommand { // Clone the notes to prevent editing from affecting the history. var resultNote = note.clone(); - resultNote.time = (resultNote.time + offset).clamp(0, Conductor.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); + resultNote.time = (resultNote.time + offset).clamp(0, Conductor.instance.getStepTimeInMs(state.songLengthInSteps - (1 * state.noteSnapRatio))); resultNote.data = ChartEditorState.gridColumnToNoteData((ChartEditorState.noteDataToGridColumn(resultNote.data) + columns).clamp(0, ChartEditorState.STRUMLINE_SIZE * 2 - 1)); diff --git a/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx b/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx index 75382da41..7e40bc49b 100644 --- a/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx +++ b/source/funkin/ui/debug/charting/commands/PasteItemsCommand.hx @@ -32,9 +32,9 @@ class PasteItemsCommand implements ChartEditorCommand return; } - var stepEndOfSong:Float = Conductor.getTimeInSteps(state.songLengthInMs); + var stepEndOfSong:Float = Conductor.instance.getTimeInSteps(state.songLengthInMs); var stepCutoff:Float = stepEndOfSong - 1.0; - var msCutoff:Float = Conductor.getStepTimeInMs(stepCutoff); + var msCutoff:Float = Conductor.instance.getStepTimeInMs(stepCutoff); addedNotes = SongDataUtils.offsetSongNoteData(currentClipboard.notes, Std.int(targetTimestamp)); addedNotes = SongDataUtils.clampSongNoteData(addedNotes, 0.0, msCutoff); diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx index 990ab41ae..2ef3fd683 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx @@ -185,7 +185,7 @@ class ChartEditorAudioHandler state.audioVocalTrackGroup.addPlayerVoice(vocalTrack); state.audioVisGroup.addPlayerVis(vocalTrack); state.audioVisGroup.playerVis.x = 885; - state.audioVisGroup.playerVis.realtimeVisLenght = Conductor.getStepTimeInMs(16) * 0.00195; + state.audioVisGroup.playerVis.realtimeVisLenght = Conductor.instance.getStepTimeInMs(16) * 0.00195; state.audioVisGroup.playerVis.daHeight = (ChartEditorState.GRID_SIZE) * 16; state.audioVisGroup.playerVis.detail = 1; @@ -196,7 +196,7 @@ class ChartEditorAudioHandler state.audioVisGroup.addOpponentVis(vocalTrack); state.audioVisGroup.opponentVis.x = 435; - state.audioVisGroup.opponentVis.realtimeVisLenght = Conductor.getStepTimeInMs(16) * 0.00195; + state.audioVisGroup.opponentVis.realtimeVisLenght = Conductor.instance.getStepTimeInMs(16) * 0.00195; state.audioVisGroup.opponentVis.daHeight = (ChartEditorState.GRID_SIZE) * 16; state.audioVisGroup.opponentVis.detail = 1; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index 2ede1a39f..1d53dfebd 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -684,8 +684,8 @@ class ChartEditorDialogHandler state.songMetadata.set(targetVariation, newSongMetadata); - Conductor.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. - Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. + Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); state.selectedVariation = Constants.DEFAULT_VARIATION; state.selectedDifficulty = state.availableDifficulties[0]; diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx index 267d2208a..472492abc 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -114,9 +114,9 @@ class ChartEditorImportExportHandler state.songMetadata = newSongMetadata; state.songChartData = newSongChartData; - Conductor.forceBPM(null); // Disable the forced BPM. - Conductor.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. - Conductor.mapTimeChanges(state.currentSongMetadata.timeChanges); + Conductor.instance.forceBPM(null); // Disable the forced BPM. + Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata. + Conductor.instance.mapTimeChanges(state.currentSongMetadata.timeChanges); state.notePreviewDirty = true; state.notePreviewViewportBoundsDirty = true; @@ -415,16 +415,34 @@ class ChartEditorImportExportHandler ]); // We have to force write because the program will die before the save dialog is closed. trace('Force exporting to $targetPath...'); - FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode); - if (onSaveCb != null) onSaveCb(targetPath); + try + { + FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode); + // On success. + if (onSaveCb != null) onSaveCb(targetPath); + } + catch (e) + { + // On failure. + if (onCancelCb != null) onCancelCb(); + } } else { // Force write since we know what file the user wants to overwrite. trace('Force exporting to $targetPath...'); - FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode); - state.saveDataDirty = false; - if (onSaveCb != null) onSaveCb(targetPath); + try + { + // On success. + FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath, targetMode); + state.saveDataDirty = false; + if (onSaveCb != null) onSaveCb(targetPath); + } + catch (e) + { + // On failure. + if (onCancelCb != null) onCancelCb(); + } } } else diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx index 4197ebdd3..1625c53bc 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx @@ -125,7 +125,7 @@ class ChartEditorThemeHandler // 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall. // This gets reused to fill the screen. var gridWidth:Int = Std.int(ChartEditorState.GRID_SIZE * TOTAL_COLUMN_COUNT); - var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.stepsPerMeasure); + var gridHeight:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure); state.gridBitmap = FlxGridOverlay.createGrid(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE, gridWidth, gridHeight, true, gridColor1, gridColor2); // Selection borders @@ -142,7 +142,7 @@ class ChartEditorThemeHandler selectionBorderColor); // Selection borders horizontally along the middle. - for (i in 1...(Conductor.stepsPerMeasure)) + for (i in 1...(Conductor.instance.stepsPerMeasure)) { state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), state.gridBitmap.width, ChartEditorState.GRID_SELECTION_BORDER_WIDTH), @@ -197,9 +197,9 @@ class ChartEditorThemeHandler }; // Selection borders horizontally in the middle. - for (i in 1...(Conductor.stepsPerMeasure)) + for (i in 1...(Conductor.instance.stepsPerMeasure)) { - if ((i % Conductor.beatsPerMeasure) == 0) + if ((i % Conductor.instance.beatsPerMeasure) == 0) { state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (GRID_BEAT_DIVIDER_WIDTH / 2), state.gridBitmap.width, GRID_BEAT_DIVIDER_WIDTH), diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index bc9384cf3..700e5ec6a 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -120,9 +120,9 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox if (event.value == null) return; chartEditorState.currentInstrumentalOffset = event.value; - Conductor.instrumentalOffset = event.value; + Conductor.instance.instrumentalOffset = event.value; // Update song length. - chartEditorState.songLengthInMs = (chartEditorState.audioInstTrack?.length ?? 1000.0) + Conductor.instrumentalOffset; + chartEditorState.songLengthInMs = (chartEditorState.audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset; }; inputOffsetVocal.onChange = function(event:UIEvent) { diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 18b0010b2..70ef97fd0 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -75,7 +75,7 @@ class LatencyState extends MusicBeatSubState // funnyStatsGraph.hi - Conductor.forceBPM(60); + Conductor.instance.forceBPM(60); noteGrp = new FlxTypedGroup(); add(noteGrp); @@ -91,14 +91,14 @@ class LatencyState extends MusicBeatSubState // // musSpec.visType = FREQUENCIES; // add(musSpec); - for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.beatLengthMs)) + for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.instance.beatLengthMs)) { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.beatLengthMs), FlxG.height - 15); + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 15); beatTick.makeGraphic(2, 15); beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.beatLengthMs), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 26, 0, "swag"); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -130,7 +130,7 @@ class LatencyState extends MusicBeatSubState for (i in 0...32) { - var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.beatLengthMs * i); + var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.instance.beatLengthMs * i); noteGrp.add(note); } @@ -146,9 +146,9 @@ class LatencyState extends MusicBeatSubState override function stepHit():Bool { - if (Conductor.currentStep % 4 == 2) + if (Conductor.instance.currentStep % 4 == 2) { - blocks.members[((Conductor.currentBeat % 8) + 1) % 8].alpha = 0.5; + blocks.members[((Conductor.instance.currentBeat % 8) + 1) % 8].alpha = 0.5; } return super.stepHit(); @@ -156,11 +156,11 @@ class LatencyState extends MusicBeatSubState override function beatHit():Bool { - if (Conductor.currentBeat % 8 == 0) blocks.forEach(blok -> { + if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> { blok.alpha = 0; }); - blocks.members[Conductor.currentBeat % 8].alpha = 1; + blocks.members[Conductor.instance.currentBeat % 8].alpha = 1; // block.visible = !block.visible; return super.beatHit(); @@ -192,17 +192,17 @@ class LatencyState extends MusicBeatSubState if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed; - Conductor.update(swagSong.getTimeWithDiff() - Conductor.inputOffset); - // Conductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; + Conductor.instance.update(swagSong.getTimeWithDiff() - Conductor.instance.inputOffset); + // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; - songPosVis.x = songPosToX(Conductor.songPosition); - songVisFollowAudio.x = songPosToX(Conductor.songPosition - Conductor.instrumentalOffset); - songVisFollowVideo.x = songPosToX(Conductor.songPosition - Conductor.inputOffset); + songPosVis.x = songPosToX(Conductor.instance.songPosition); + songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset); + songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset); - offsetText.text = "INST Offset: " + Conductor.instrumentalOffset + "ms"; - offsetText.text += "\nINPUT Offset: " + Conductor.inputOffset + "ms"; - offsetText.text += "\ncurrentStep: " + Conductor.currentStep; - offsetText.text += "\ncurrentBeat: " + Conductor.currentBeat; + offsetText.text = "INST Offset: " + Conductor.instance.instrumentalOffset + "ms"; + offsetText.text += "\nINPUT Offset: " + Conductor.instance.inputOffset + "ms"; + offsetText.text += "\ncurrentStep: " + Conductor.instance.currentStep; + offsetText.text += "\ncurrentBeat: " + Conductor.instance.currentBeat; var avgOffsetInput:Float = 0; @@ -221,24 +221,24 @@ class LatencyState extends MusicBeatSubState { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instrumentalOffset += 1.0 * multiply; + Conductor.instance.instrumentalOffset += 1.0 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instrumentalOffset -= 1.0 * multiply; + Conductor.instance.instrumentalOffset -= 1.0 * multiply; } } else { if (FlxG.keys.justPressed.RIGHT) { - Conductor.inputOffset += 1.0 * multiply; + Conductor.instance.inputOffset += 1.0 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.inputOffset -= 1.0 * multiply; + Conductor.instance.inputOffset -= 1.0 * multiply; } } @@ -250,7 +250,7 @@ class LatencyState extends MusicBeatSubState }*/ noteGrp.forEach(function(daNote:NoteSprite) { - daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.instrumentalOffset) - daNote.noteData.time) * 0.45); + daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45); daNote.x = strumLine.x + 30; if (daNote.y < strumLine.y) daNote.alpha = 0.5; @@ -258,7 +258,7 @@ class LatencyState extends MusicBeatSubState if (daNote.y < 0 - daNote.height) { daNote.alpha = 1; - // daNote.data.strumTime += Conductor.beatLengthMs * 8; + // daNote.data.strumTime += Conductor.instance.beatLengthMs * 8; } }); @@ -267,14 +267,14 @@ class LatencyState extends MusicBeatSubState function generateBeatStuff() { - Conductor.update(swagSong.getTimeWithDiff()); + Conductor.instance.update(swagSong.getTimeWithDiff()); - var closestBeat:Int = Math.round(Conductor.songPosition / Conductor.beatLengthMs) % diffGrp.members.length; - var getDiff:Float = Conductor.songPosition - (closestBeat * Conductor.beatLengthMs); - getDiff -= Conductor.inputOffset; + var closestBeat:Int = Math.round(Conductor.instance.songPosition / Conductor.instance.beatLengthMs) % diffGrp.members.length; + var getDiff:Float = Conductor.instance.songPosition - (closestBeat * Conductor.instance.beatLengthMs); + getDiff -= Conductor.instance.inputOffset; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.beatLengthMs * 2) getDiff -= FlxG.sound.music.length; + if (closestBeat == 0 && getDiff >= Conductor.instance.beatLengthMs * 2) getDiff -= FlxG.sound.music.length; trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); trace("\tCLOSEST BEAT: " + closestBeat); diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 6e4cdacaf..d6dd536f7 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -238,7 +238,7 @@ class StoryMenuState extends MusicBeatState var freakyMenuMetadata:Null = SongRegistry.instance.parseMusicData('freakyMenu'); if (freakyMenuMetadata != null) { - Conductor.mapTimeChanges(freakyMenuMetadata.timeChanges); + Conductor.instance.mapTimeChanges(freakyMenuMetadata.timeChanges); } FlxG.sound.playMusic(Paths.music('freakyMenu/freakyMenu'), 0); @@ -317,7 +317,7 @@ class StoryMenuState extends MusicBeatState override function update(elapsed:Float) { - Conductor.update(); + Conductor.instance.update(); highScoreLerp = Std.int(MathUtil.coolLerp(highScoreLerp, highScore, 0.5)); diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 7671bb336..bc44af073 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -221,7 +221,7 @@ class TitleState extends MusicBeatState var freakyMenuMetadata:Null = SongRegistry.instance.parseMusicData('freakyMenu'); if (freakyMenuMetadata != null) { - Conductor.mapTimeChanges(freakyMenuMetadata.timeChanges); + Conductor.instance.mapTimeChanges(freakyMenuMetadata.timeChanges); } FlxG.sound.playMusic(Paths.music('freakyMenu/freakyMenu'), 0); FlxG.sound.music.fadeIn(4, 0, 0.7); @@ -256,7 +256,7 @@ class TitleState extends MusicBeatState if (FlxG.keys.pressed.DOWN) FlxG.sound.music.pitch -= 0.5 * elapsed; #end - Conductor.update(); + Conductor.instance.update(); /* if (FlxG.onMobile) { @@ -280,7 +280,7 @@ class TitleState extends MusicBeatState FlxTween.tween(FlxG.stage.window, {y: FlxG.stage.window.y + 100}, 0.7, {ease: FlxEase.quadInOut, type: PINGPONG}); } - if (FlxG.sound.music != null) Conductor.update(FlxG.sound.music.time); + if (FlxG.sound.music != null) Conductor.instance.update(FlxG.sound.music.time); if (FlxG.keys.justPressed.F) FlxG.fullscreen = !FlxG.fullscreen; // do controls.PAUSE | controls.ACCEPT instead? @@ -390,7 +390,7 @@ class TitleState extends MusicBeatState var spec:SpectogramSprite = new SpectogramSprite(FlxG.sound.music); add(spec); - Conductor.forceBPM(190); + Conductor.instance.forceBPM(190); FlxG.camera.flash(FlxColor.WHITE, 1); FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); } @@ -442,13 +442,13 @@ class TitleState extends MusicBeatState if (!skippedIntro) { - // FlxG.log.add(Conductor.currentBeat); + // FlxG.log.add(Conductor.instance.currentBeat); // if the user is draggin the window some beats will // be missed so this is just to compensate - if (Conductor.currentBeat > lastBeat) + if (Conductor.instance.currentBeat > lastBeat) { // TODO: Why does it perform ALL the previous steps each beat? - for (i in lastBeat...Conductor.currentBeat) + for (i in lastBeat...Conductor.instance.currentBeat) { switch (i + 1) { @@ -483,11 +483,11 @@ class TitleState extends MusicBeatState } } } - lastBeat = Conductor.currentBeat; + lastBeat = Conductor.instance.currentBeat; } if (skippedIntro) { - if (cheatActive && Conductor.currentBeat % 2 == 0) swagShader.update(0.125); + if (cheatActive && Conductor.instance.currentBeat % 2 == 0) swagShader.update(0.125); if (logoBl != null && logoBl.animation != null) logoBl.animation.play('bump', true); diff --git a/tests/unit/source/funkin/ConductorTest.hx b/tests/unit/source/funkin/ConductorTest.hx index c65f3f297..a0cfedbab 100644 --- a/tests/unit/source/funkin/ConductorTest.hx +++ b/tests/unit/source/funkin/ConductorTest.hx @@ -31,23 +31,23 @@ class ConductorTest extends FunkinTest { // NOTE: Expected value comes first. - Assert.areEqual([], Conductor.timeChanges); - Assert.areEqual(null, Conductor.currentTimeChange); + Assert.areEqual([], Conductor.instance.timeChanges); + Assert.areEqual(null, Conductor.instance.currentTimeChange); - Assert.areEqual(0, Conductor.songPosition); - Assert.areEqual(Constants.DEFAULT_BPM, Conductor.bpm); - Assert.areEqual(null, Conductor.bpmOverride); + Assert.areEqual(0, Conductor.instance.songPosition); + Assert.areEqual(Constants.DEFAULT_BPM, Conductor.instance.bpm); + Assert.areEqual(null, Conductor.instance.bpmOverride); - Assert.areEqual(600, Conductor.beatLengthMs); + Assert.areEqual(600, Conductor.instance.beatLengthMs); - Assert.areEqual(4, Conductor.timeSignatureNumerator); - Assert.areEqual(4, Conductor.timeSignatureDenominator); + Assert.areEqual(4, Conductor.instance.timeSignatureNumerator); + Assert.areEqual(4, Conductor.instance.timeSignatureDenominator); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - Assert.areEqual(0.0, Conductor.currentStepTime); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + Assert.areEqual(0.0, Conductor.instance.currentStepTime); - Assert.areEqual(150, Conductor.stepLengthMs); + Assert.areEqual(150, Conductor.instance.stepLengthMs); } /** @@ -60,23 +60,23 @@ class ConductorTest extends FunkinTest var currentConductorState:Null = conductorState; Assert.isNotNull(currentConductorState); - Assert.areEqual(0, Conductor.songPosition); + Assert.areEqual(0, Conductor.instance.songPosition); step(); // 1 var BPM_100_STEP_TIME = 1 / 9; - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(1 / 9, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(1 / 9, Conductor.instance.currentStepTime); step(7); // 8 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 8, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(8 / 9, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 8, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(8 / 9, Conductor.instance.currentStepTime); Assert.areEqual(0, currentConductorState.beatsHit); Assert.areEqual(0, currentConductorState.stepsHit); @@ -88,10 +88,10 @@ class ConductorTest extends FunkinTest currentConductorState.beatsHit = 0; currentConductorState.stepsHit = 0; - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 9, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(1, Conductor.currentStep); - FunkinAssert.areNear(1.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 9, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(1, Conductor.instance.currentStep); + FunkinAssert.areNear(1.0, Conductor.instance.currentStepTime); step(35 - 9); // 35 @@ -100,10 +100,10 @@ class ConductorTest extends FunkinTest currentConductorState.beatsHit = 0; currentConductorState.stepsHit = 0; - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 35, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(3, Conductor.currentStep); - FunkinAssert.areNear(3.0 + 8 / 9, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 35, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(3, Conductor.instance.currentStep); + FunkinAssert.areNear(3.0 + 8 / 9, Conductor.instance.currentStepTime); step(); // 36 @@ -112,83 +112,83 @@ class ConductorTest extends FunkinTest currentConductorState.beatsHit = 0; currentConductorState.stepsHit = 0; - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 36, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(4, Conductor.currentStep); - FunkinAssert.areNear(4.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 36, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(4, Conductor.instance.currentStep); + FunkinAssert.areNear(4.0, Conductor.instance.currentStepTime); step(50 - 36); // 50 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 50, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(5, Conductor.currentStep); - FunkinAssert.areNear(5.555555, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 50, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(5, Conductor.instance.currentStep); + FunkinAssert.areNear(5.555555, Conductor.instance.currentStepTime); step(49); // 99 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 99, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(11, Conductor.currentStep); - FunkinAssert.areNear(11.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 99, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(11, Conductor.instance.currentStep); + FunkinAssert.areNear(11.0, Conductor.instance.currentStepTime); step(1); // 100 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 100, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(11, Conductor.currentStep); - FunkinAssert.areNear(11.111111, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 100, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(11, Conductor.instance.currentStep); + FunkinAssert.areNear(11.111111, Conductor.instance.currentStepTime); } @Test function testUpdateForcedBPM():Void { - Conductor.forceBPM(60); + Conductor.instance.forceBPM(60); - Assert.areEqual(0, Conductor.songPosition); + Assert.areEqual(0, Conductor.instance.songPosition); // 60 beats per minute = 1 beat per second // 1 beat per second = 1/60 beats per frame = 4/60 steps per frame step(); // Advances time 1/60 of 1 second. - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(4 / 60, Conductor.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(4 / 60, Conductor.instance.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step step(14 - 1); // 14 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 14, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(1.0 - 4 / 60, Conductor.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 14, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(1.0 - 4 / 60, Conductor.instance.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step step(); // 15 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 15, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(1, Conductor.currentStep); - FunkinAssert.areNear(1.0, Conductor.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 15, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(1, Conductor.instance.currentStep); + FunkinAssert.areNear(1.0, Conductor.instance.currentStepTime); // 1/60 of 1 beat = 4/60 of 1 step step(45 - 1); // 59 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(3, Conductor.currentStep); - FunkinAssert.areNear(4.0 - 4 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(3, Conductor.instance.currentStep); + FunkinAssert.areNear(4.0 - 4 / 60, Conductor.instance.currentStepTime); step(); // 60 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(4, Conductor.currentStep); - FunkinAssert.areNear(4.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(4, Conductor.instance.currentStep); + FunkinAssert.areNear(4.0, Conductor.instance.currentStepTime); step(); // 61 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(4, Conductor.currentStep); - FunkinAssert.areNear(4.0 + 4 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(4, Conductor.instance.currentStep); + FunkinAssert.areNear(4.0 + 4 / 60, Conductor.instance.currentStepTime); } @Test @@ -196,50 +196,50 @@ class ConductorTest extends FunkinTest { // Start the song with a BPM of 120. var songTimeChanges:Array = [new SongTimeChange(0, 120)]; - Conductor.mapTimeChanges(songTimeChanges); + Conductor.instance.mapTimeChanges(songTimeChanges); // All should be at 0. - FunkinAssert.areNear(0, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(0.0, Conductor.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step + FunkinAssert.areNear(0, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(0.0, Conductor.instance.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step // 120 beats per minute = 2 beat per second // 2 beat per second = 2/60 beats per frame = 16/120 steps per frame step(); // Advances time 1/60 of 1 second. - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(16 / 120, Conductor.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(16 / 120, Conductor.instance.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step step(15 - 1); // 15 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 15, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(2, Conductor.currentStep); - FunkinAssert.areNear(2.0, Conductor.currentStepTime); // 2/60 of 1 beat = 8/60 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 15, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(2, Conductor.instance.currentStep); + FunkinAssert.areNear(2.0, Conductor.instance.currentStepTime); // 2/60 of 1 beat = 8/60 of 1 step step(45 - 1); // 59 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(7, Conductor.currentStep); - FunkinAssert.areNear(7.0 + 104 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(7, Conductor.instance.currentStep); + FunkinAssert.areNear(7.0 + 104 / 120, Conductor.instance.currentStepTime); step(); // 60 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0, Conductor.instance.currentStepTime); step(); // 61 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0 + 8 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0 + 8 / 60, Conductor.instance.currentStepTime); } @Test @@ -247,57 +247,57 @@ class ConductorTest extends FunkinTest { // Start the song with a BPM of 120. var songTimeChanges:Array = [new SongTimeChange(0, 120), new SongTimeChange(3000, 90)]; - Conductor.mapTimeChanges(songTimeChanges); + Conductor.instance.mapTimeChanges(songTimeChanges); // All should be at 0. - FunkinAssert.areNear(0, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(0.0, Conductor.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step + FunkinAssert.areNear(0, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(0.0, Conductor.instance.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step // 120 beats per minute = 2 beat per second // 2 beat per second = 2/60 beats per frame = 16/120 steps per frame step(); // Advances time 1/60 of 1 second. - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(16 / 120, Conductor.currentStepTime); // 4/120 of 1 beat = 16/120 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(16 / 120, Conductor.instance.currentStepTime); // 4/120 of 1 beat = 16/120 of 1 step step(60 - 1 - 1); // 59 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(7, Conductor.currentStep); - FunkinAssert.areNear(7.0 + 104 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(7, Conductor.instance.currentStep); + FunkinAssert.areNear(7.0 + 104 / 120, Conductor.instance.currentStepTime); step(); // 60 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0, Conductor.instance.currentStepTime); step(); // 61 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0 + 8 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0 + 8 / 60, Conductor.instance.currentStepTime); step(179 - 61); // 179 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 179, Conductor.songPosition); - Assert.areEqual(5, Conductor.currentBeat); - Assert.areEqual(23, Conductor.currentStep); - FunkinAssert.areNear(23.0 + 52 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 179, Conductor.instance.songPosition); + Assert.areEqual(5, Conductor.instance.currentBeat); + Assert.areEqual(23, Conductor.instance.currentStep); + FunkinAssert.areNear(23.0 + 52 / 60, Conductor.instance.currentStepTime); step(); // 180 (3 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 180, Conductor.songPosition); - Assert.areEqual(6, Conductor.currentBeat); - Assert.areEqual(24, Conductor.currentStep); - FunkinAssert.areNear(24.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 180, Conductor.instance.songPosition); + Assert.areEqual(6, Conductor.instance.currentBeat); + Assert.areEqual(24, Conductor.instance.currentStep); + FunkinAssert.areNear(24.0, Conductor.instance.currentStepTime); step(); // 181 (3 + 1/60 seconds) // BPM has switched to 90! @@ -305,24 +305,24 @@ class ConductorTest extends FunkinTest // 1.5 beat per second = 1.5/60 beats per frame = 3/120 beats per frame // = 12/120 steps per frame - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 181, Conductor.songPosition); - Assert.areEqual(6, Conductor.currentBeat); - Assert.areEqual(24, Conductor.currentStep); - FunkinAssert.areNear(24.0 + 12 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 181, Conductor.instance.songPosition); + Assert.areEqual(6, Conductor.instance.currentBeat); + Assert.areEqual(24, Conductor.instance.currentStep); + FunkinAssert.areNear(24.0 + 12 / 120, Conductor.instance.currentStepTime); step(59); // 240 (4 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 240, Conductor.songPosition); - Assert.areEqual(7, Conductor.currentBeat); - Assert.areEqual(30, Conductor.currentStep); - FunkinAssert.areNear(30.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 240, Conductor.instance.songPosition); + Assert.areEqual(7, Conductor.instance.currentBeat); + Assert.areEqual(30, Conductor.instance.currentStep); + FunkinAssert.areNear(30.0, Conductor.instance.currentStepTime); step(); // 241 (4 + 1/60 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 241, Conductor.songPosition); - Assert.areEqual(7, Conductor.currentBeat); - Assert.areEqual(30, Conductor.currentStep); - FunkinAssert.areNear(30.0 + 12 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 241, Conductor.instance.songPosition); + Assert.areEqual(7, Conductor.instance.currentBeat); + Assert.areEqual(30, Conductor.instance.currentStep); + FunkinAssert.areNear(30.0 + 12 / 120, Conductor.instance.currentStepTime); } @Test @@ -334,63 +334,63 @@ class ConductorTest extends FunkinTest new SongTimeChange(3000, 90), new SongTimeChange(6000, 180) ]; - Conductor.mapTimeChanges(songTimeChanges); + Conductor.instance.mapTimeChanges(songTimeChanges); // Verify time changes. - Assert.areEqual(3, Conductor.timeChanges.length); - FunkinAssert.areNear(0, Conductor.timeChanges[0].beatTime); - FunkinAssert.areNear(6, Conductor.timeChanges[1].beatTime); - FunkinAssert.areNear(10.5, Conductor.timeChanges[2].beatTime); + Assert.areEqual(3, Conductor.instance.timeChanges.length); + FunkinAssert.areNear(0, Conductor.instance.timeChanges[0].beatTime); + FunkinAssert.areNear(6, Conductor.instance.timeChanges[1].beatTime); + FunkinAssert.areNear(10.5, Conductor.instance.timeChanges[2].beatTime); // All should be at 0. - FunkinAssert.areNear(0, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(0.0, Conductor.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step + FunkinAssert.areNear(0, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(0.0, Conductor.instance.currentStepTime); // 2/120 of 1 beat = 8/120 of 1 step // 120 beats per minute = 2 beat per second // 2 beat per second = 2/60 beats per frame = 16/120 steps per frame step(); // Advances time 1/60 of 1 second. - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.songPosition); - Assert.areEqual(0, Conductor.currentBeat); - Assert.areEqual(0, Conductor.currentStep); - FunkinAssert.areNear(16 / 120, Conductor.currentStepTime); // 4/120 of 1 beat = 16/120 of 1 step + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 1, Conductor.instance.songPosition); + Assert.areEqual(0, Conductor.instance.currentBeat); + Assert.areEqual(0, Conductor.instance.currentStep); + FunkinAssert.areNear(16 / 120, Conductor.instance.currentStepTime); // 4/120 of 1 beat = 16/120 of 1 step step(60 - 1 - 1); // 59 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.songPosition); - Assert.areEqual(1, Conductor.currentBeat); - Assert.areEqual(7, Conductor.currentStep); - FunkinAssert.areNear(7 + 104 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 59, Conductor.instance.songPosition); + Assert.areEqual(1, Conductor.instance.currentBeat); + Assert.areEqual(7, Conductor.instance.currentStep); + FunkinAssert.areNear(7 + 104 / 120, Conductor.instance.currentStepTime); step(); // 60 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 60, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0, Conductor.instance.currentStepTime); step(); // 61 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.songPosition); - Assert.areEqual(2, Conductor.currentBeat); - Assert.areEqual(8, Conductor.currentStep); - FunkinAssert.areNear(8.0 + 8 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 61, Conductor.instance.songPosition); + Assert.areEqual(2, Conductor.instance.currentBeat); + Assert.areEqual(8, Conductor.instance.currentStep); + FunkinAssert.areNear(8.0 + 8 / 60, Conductor.instance.currentStepTime); step(179 - 61); // 179 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 179, Conductor.songPosition); - Assert.areEqual(5, Conductor.currentBeat); - Assert.areEqual(23, Conductor.currentStep); - FunkinAssert.areNear(23.0 + 52 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 179, Conductor.instance.songPosition); + Assert.areEqual(5, Conductor.instance.currentBeat); + Assert.areEqual(23, Conductor.instance.currentStep); + FunkinAssert.areNear(23.0 + 52 / 60, Conductor.instance.currentStepTime); step(); // 180 (3 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 180, Conductor.songPosition); - Assert.areEqual(6, Conductor.currentBeat); - Assert.areEqual(24, Conductor.currentStep); // 23.999 => 24 - FunkinAssert.areNear(24.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 180, Conductor.instance.songPosition); + Assert.areEqual(6, Conductor.instance.currentBeat); + Assert.areEqual(24, Conductor.instance.currentStep); // 23.999 => 24 + FunkinAssert.areNear(24.0, Conductor.instance.currentStepTime); step(); // 181 (3 + 1/60 seconds) // BPM has switched to 90! @@ -398,45 +398,45 @@ class ConductorTest extends FunkinTest // 1.5 beat per second = 1.5/60 beats per frame = 3/120 beats per frame // = 12/120 steps per frame - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 181, Conductor.songPosition); - Assert.areEqual(6, Conductor.currentBeat); - Assert.areEqual(24, Conductor.currentStep); - FunkinAssert.areNear(24.0 + 12 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 181, Conductor.instance.songPosition); + Assert.areEqual(6, Conductor.instance.currentBeat); + Assert.areEqual(24, Conductor.instance.currentStep); + FunkinAssert.areNear(24.0 + 12 / 120, Conductor.instance.currentStepTime); step(60 - 1 - 1); // 240 (4 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 239, Conductor.songPosition); - Assert.areEqual(7, Conductor.currentBeat); - Assert.areEqual(29, Conductor.currentStep); - FunkinAssert.areNear(29.0 + 108 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 239, Conductor.instance.songPosition); + Assert.areEqual(7, Conductor.instance.currentBeat); + Assert.areEqual(29, Conductor.instance.currentStep); + FunkinAssert.areNear(29.0 + 108 / 120, Conductor.instance.currentStepTime); step(); // 240 (4 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 240, Conductor.songPosition); - Assert.areEqual(7, Conductor.currentBeat); - Assert.areEqual(30, Conductor.currentStep); - FunkinAssert.areNear(30.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 240, Conductor.instance.songPosition); + Assert.areEqual(7, Conductor.instance.currentBeat); + Assert.areEqual(30, Conductor.instance.currentStep); + FunkinAssert.areNear(30.0, Conductor.instance.currentStepTime); step(); // 241 (4 + 1/60 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 241, Conductor.songPosition); - Assert.areEqual(7, Conductor.currentBeat); - Assert.areEqual(30, Conductor.currentStep); - FunkinAssert.areNear(30.0 + 12 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 241, Conductor.instance.songPosition); + Assert.areEqual(7, Conductor.instance.currentBeat); + Assert.areEqual(30, Conductor.instance.currentStep); + FunkinAssert.areNear(30.0 + 12 / 120, Conductor.instance.currentStepTime); step(359 - 241); // 359 (5 + 59/60 seconds) - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 359, Conductor.songPosition); - Assert.areEqual(10, Conductor.currentBeat); - Assert.areEqual(41, Conductor.currentStep); - FunkinAssert.areNear(41 + 108 / 120, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 359, Conductor.instance.songPosition); + Assert.areEqual(10, Conductor.instance.currentBeat); + Assert.areEqual(41, Conductor.instance.currentStep); + FunkinAssert.areNear(41 + 108 / 120, Conductor.instance.currentStepTime); step(); // 360 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 360, Conductor.songPosition); - Assert.areEqual(10, Conductor.currentBeat); - Assert.areEqual(42, Conductor.currentStep); // 41.999 - FunkinAssert.areNear(42.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 360, Conductor.instance.songPosition); + Assert.areEqual(10, Conductor.instance.currentBeat); + Assert.areEqual(42, Conductor.instance.currentStep); // 41.999 + FunkinAssert.areNear(42.0, Conductor.instance.currentStepTime); step(); // 361 // BPM has switched to 180! @@ -444,24 +444,24 @@ class ConductorTest extends FunkinTest // 3 beat per second = 3/60 beats per frame // = 12/60 steps per frame - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 361, Conductor.songPosition); - Assert.areEqual(10, Conductor.currentBeat); - Assert.areEqual(42, Conductor.currentStep); - FunkinAssert.areNear(42.0 + 12 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 361, Conductor.instance.songPosition); + Assert.areEqual(10, Conductor.instance.currentBeat); + Assert.areEqual(42, Conductor.instance.currentStep); + FunkinAssert.areNear(42.0 + 12 / 60, Conductor.instance.currentStepTime); step(); // 362 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 362, Conductor.songPosition); - Assert.areEqual(10, Conductor.currentBeat); - Assert.areEqual(42, Conductor.currentStep); - FunkinAssert.areNear(42.0 + 24 / 60, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 362, Conductor.instance.songPosition); + Assert.areEqual(10, Conductor.instance.currentBeat); + Assert.areEqual(42, Conductor.instance.currentStep); + FunkinAssert.areNear(42.0 + 24 / 60, Conductor.instance.currentStepTime); step(3); // 365 - FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 365, Conductor.songPosition); - Assert.areEqual(10, Conductor.currentBeat); - Assert.areEqual(43, Conductor.currentStep); // 42.999 => 42 - FunkinAssert.areNear(43.0, Conductor.currentStepTime); + FunkinAssert.areNear(FunkinTest.MS_PER_STEP * 365, Conductor.instance.songPosition); + Assert.areEqual(10, Conductor.instance.currentBeat); + Assert.areEqual(43, Conductor.instance.currentStep); // 42.999 => 42 + FunkinAssert.areNear(43.0, Conductor.instance.currentStepTime); } } @@ -504,6 +504,6 @@ class ConductorState extends FlxState super.update(elapsed); // On each step, increment the Conductor as though the song was playing. - Conductor.update(Conductor.songPosition + elapsed * Constants.MS_PER_SEC); + Conductor.instance.update(Conductor.instance.songPosition + elapsed * Constants.MS_PER_SEC); } }