diff --git a/buildnumber.txt b/buildnumber.txt index 20d91f52..25c83294 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -963 \ No newline at end of file +968 \ No newline at end of file diff --git a/source/funkin/editors/ChartingState.hx b/source/funkin/editors/ChartingState.hx index f74aca22..678b716e 100644 --- a/source/funkin/editors/ChartingState.hx +++ b/source/funkin/editors/ChartingState.hx @@ -480,8 +480,6 @@ class ChartingState extends MusicBeatState override function update(elapsed:Float) { - curStep = recalculateSteps(); - Conductor.songPosition = FlxG.sound.music.time; _song.song = typingShit.text; @@ -695,25 +693,6 @@ class ChartingState extends MusicBeatState updateGrid(); } - function recalculateSteps():Int - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (FlxG.sound.music.time > Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } - - curStep = lastChange.stepTime + Math.floor((FlxG.sound.music.time - lastChange.songTime) / Conductor.stepCrochet); - updateBeat(); - - return curStep; - } - function resetSection(songBeginning:Bool = false):Void { updateGrid(); @@ -731,7 +710,6 @@ class ChartingState extends MusicBeatState } vocals.time = FlxG.sound.music.time; - updateCurStep(); updateGrid(); updateSectionUI(); @@ -762,7 +740,6 @@ class ChartingState extends MusicBeatState FlxG.sound.music.time = sectionStartTime(); vocals.time = FlxG.sound.music.time; - updateCurStep(); } updateGrid(); diff --git a/source/funkin/game/GameOverSubstate.hx b/source/funkin/game/GameOverSubstate.hx index 4af8e8d1..93cef62b 100644 --- a/source/funkin/game/GameOverSubstate.hx +++ b/source/funkin/game/GameOverSubstate.hx @@ -43,8 +43,6 @@ class GameOverSubstate extends MusicBeatSubstate daBf = 'bf'; } - Conductor.songPosition = 0; - bf = new Character(x, y, daBf, true); add(bf); @@ -90,18 +88,11 @@ class GameOverSubstate extends MusicBeatSubstate { FlxG.sound.playMusic(Paths.music('gameOver' + stageSuffix)); } - - if (FlxG.sound.music.playing) - { - Conductor.songPosition = FlxG.sound.music.time; - } } - override function beatHit() + override function beatHit(curBeat:Int) { - super.beatHit(); - - FlxG.log.add('beat'); + super.beatHit(curBeat); } var isEnding:Bool = false; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index e5fae60d..d907abfa 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -723,6 +723,8 @@ class PlayState extends MusicBeatState #end scripts.call("onDiscordPresenceUpdate"); } + + var __vocalOffsetViolation:Float = 0; override public function update(elapsed:Float) { #if !debug @@ -785,21 +787,12 @@ class PlayState extends MusicBeatState if (Conductor.songPosition >= 0) startSong(); } - } - else - { - Conductor.songPosition += FlxG.elapsed * 1000; - - if (!paused) - { - songTime += FlxG.game.ticks - previousFrameTime; - previousFrameTime = FlxG.game.ticks; - - if (Math.abs(FlxG.sound.music.time - Conductor.songPosition) > 25) - resyncVocals(); + } else { + __vocalOffsetViolation = Math.max(0, __vocalOffsetViolation + (FlxG.sound.music.time != vocals.time ? elapsed * 2 : -elapsed)); + if (__vocalOffsetViolation > 25) { + resyncVocals(); + __vocalOffsetViolation = 0; } - - // Conductor.lastSongPos = FlxG.sound.music.time; } if (generatedMusic && PlayState.SONG.notes[Std.int(curStep / 16)] != null) @@ -1354,15 +1347,15 @@ class PlayState extends MusicBeatState } } - override function stepHit() + override function stepHit(curStep:Int) { - super.stepHit(); + super.stepHit(curStep); scripts.call("stepHit", [curStep]); } - override function beatHit() + override function beatHit(curBeat:Int) { - super.beatHit(); + super.beatHit(curBeat); scripts.call("beatHit", [curBeat]); if (SONG.notes[Math.floor(curStep / 16)] != null && SONG.notes[Math.floor(curStep / 16)].changeBPM) diff --git a/source/funkin/menus/TitleState.hx b/source/funkin/menus/TitleState.hx index 4814e1d3..90e9e25b 100644 --- a/source/funkin/menus/TitleState.hx +++ b/source/funkin/menus/TitleState.hx @@ -138,8 +138,6 @@ class TitleState extends MusicBeatState override function update(elapsed:Float) { - if (FlxG.sound.music != null) Conductor.songPosition = FlxG.sound.music.time; - if (FlxG.keys.justPressed.F) FlxG.fullscreen = !FlxG.fullscreen; var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; @@ -172,7 +170,7 @@ class TitleState extends MusicBeatState titleText.animation.play('press'); FlxG.camera.flash(FlxColor.WHITE, 1); - FlxG.sound.play(Paths.sound('confirmMenu'), 0.7); + CoolUtil.playMenuSFX(1, 0.7); transitioning = true; // FlxG.sound.music.stop(); @@ -212,9 +210,9 @@ class TitleState extends MusicBeatState while (textGroup.members.length > 0) textGroup.remove(textGroup.members[0], true); } - override function beatHit() + override function beatHit(curBeat:Int) { - super.beatHit(); + super.beatHit(curBeat); logoBl.animation.play('bump'); danceLeft = !danceLeft; diff --git a/source/funkin/system/Conductor.hx b/source/funkin/system/Conductor.hx index cfc27f19..83e1def1 100644 --- a/source/funkin/system/Conductor.hx +++ b/source/funkin/system/Conductor.hx @@ -1,5 +1,7 @@ package funkin.system; +import funkin.interfaces.IBeatReceiver; +import flixel.FlxG; import funkin.system.Song.SwagSong; /** @@ -36,6 +38,29 @@ class Conductor * Current position of the song, in milliseconds. */ public static var songPosition:Float; + + + /** + * Current step + */ + public static var curStep:Int = 0; + + /** + * Current beat + */ + public static var curBeat:Int = 0; + + + /** + * Current step, as a `Float` (ex: 4.94, instead of 4) + */ + public static var curStepFloat:Float = 0; + + /** + * Current beat, as a `Float` (ex: 1.24, instead of 1) + */ + public static var curBeatFloat:Float = 0; + @:dox(hide) public static var lastSongPos:Float; @:dox(hide) public static var offset:Float = 0; @@ -52,7 +77,7 @@ class Conductor public static function reset() { songPosition = lastSongPos = 0; bpmChangeMap = []; - changeBPM(100); + changeBPM(0); } /** * Maps BPM changes from a song. @@ -85,6 +110,59 @@ class Conductor trace("new BPM map BUDDY " + bpmChangeMap); } + public static function init() { + FlxG.signals.preUpdate.add(update); + reset(); + } + + private static function update() { + var elapsed = FlxG.elapsed; + + if (FlxG.sound.music == null || !FlxG.sound.music.playing) return; + if (FlxG.state != null && FlxG.state is MusicBeatState && cast(FlxG.state, MusicBeatState).cancelConductorUpdate) return; + if (lastSongPos != (lastSongPos = FlxG.sound.music.time)) { + // update conductor + songPosition = FlxG.sound.music.time; + } else { + songPosition += elapsed * 1000; + } + + if (bpm > 0) { + // updates curbeat and stuff + var lastChange:BPMChangeEvent = { + stepTime: 0, + songTime: 0, + bpm: 0 + } + for (change in Conductor.bpmChangeMap) + { + if (Conductor.songPosition >= change.songTime) + lastChange = change; + } + + curStepFloat = lastChange.stepTime + ((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet); + curBeatFloat = curStepFloat / 4; + + if (curStep != (curStep = Std.int(curStepFloat))) { + // updates step + var updateBeat = curBeat != (curBeat = Std.int(curBeatFloat)); + + if (FlxG.state is IBeatReceiver) { + var state = FlxG.state; + while(state != null) { + if (FlxG.state is IBeatReceiver) { + var st = cast(FlxG.state, IBeatReceiver); + st.stepHit(curStep); + if (updateBeat) + st.beatHit(curBeat); + } + state = state.subState; + } + } + } + } + } + public static function changeBPM(newBpm:Float) { bpm = newBpm; diff --git a/source/funkin/system/FramerateField.hx b/source/funkin/system/FramerateField.hx index f7128c0d..a731c333 100644 --- a/source/funkin/system/FramerateField.hx +++ b/source/funkin/system/FramerateField.hx @@ -71,6 +71,10 @@ class FramerateField extends TextField { text.push('CODENAME ENGINE ALPHA - BUILD ${funkin.macros.BuildCounterMacro.getBuildNumber()}'); #end if (debugMode) { + text.push('======'); + text.push('Current Song Position: ${Conductor.songPosition} (${Conductor.curBeat} beats - ${Conductor.curStep} steps)'); + text.push('Current BPM: ${Conductor.bpm}'); + text.push('======'); text.push('System: ${lime.system.System.platformLabel} ${lime.system.System.platformVersion}'); text.push('Objs in state: ${FlxG.state.members.length}'); text.push('Nb cameras: ${FlxG.cameras.list.length}'); diff --git a/source/funkin/system/Main.hx b/source/funkin/system/Main.hx index 86d9be46..841dcc31 100644 --- a/source/funkin/system/Main.hx +++ b/source/funkin/system/Main.hx @@ -133,6 +133,7 @@ class Main extends Sprite Options.load(); + Conductor.init(); AudioSwitchFix.init(); WindowsAPI.setDarkMode(true); diff --git a/source/funkin/system/MusicBeatState.hx b/source/funkin/system/MusicBeatState.hx index 1ad2574c..28d13c36 100644 --- a/source/funkin/system/MusicBeatState.hx +++ b/source/funkin/system/MusicBeatState.hx @@ -11,7 +11,7 @@ import flixel.math.FlxMath; import flixel.util.FlxTimer; import funkin.options.PlayerSettings; -class MusicBeatState extends FlxUIState +class MusicBeatState extends FlxUIState implements IBeatReceiver { private var lastBeat:Float = 0; private var lastStep:Float = 0; @@ -42,6 +42,11 @@ class MusicBeatState extends FlxUIState */ public var controls(get, never):Controls; + /** + * Whenever the Conductor auto update should be enabled or not. + */ + public var cancelConductorUpdate:Bool = false; + inline function get_controls():Controls return PlayerSettings.player1.controls; @@ -55,45 +60,16 @@ class MusicBeatState extends FlxUIState //everyStep(); var oldStep:Int = curStep; - updateCurStep(); - updateBeat(); - - if (oldStep != curStep && curStep > 0) - stepHit(); super.update(elapsed); } - private function updateBeat():Void - { - curBeat = Math.floor(curBeatFloat = (curStepFloat / 4)); - } - - private function updateCurStep():Void - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (Conductor.songPosition >= Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } - - curStep = Math.floor(curStepFloat = lastChange.stepTime + ((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet)); - } - - @:dox(hide) public function stepHit():Void + @:dox(hide) public function stepHit(curStep:Int):Void { for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).stepHit(curStep); - - if (curStep % 4 == 0) - beatHit(); } - @:dox(hide) public function beatHit():Void + @:dox(hide) public function beatHit(curBeat:Int):Void { for(e in members) if (e is IBeatReceiver) cast(e, IBeatReceiver).beatHit(curBeat); } diff --git a/source/funkin/system/MusicBeatSubstate.hx b/source/funkin/system/MusicBeatSubstate.hx index 098e1777..a26d11f0 100644 --- a/source/funkin/system/MusicBeatSubstate.hx +++ b/source/funkin/system/MusicBeatSubstate.hx @@ -1,5 +1,6 @@ package funkin.system; +import funkin.interfaces.IBeatReceiver; import funkin.system.Conductor.BPMChangeEvent; import funkin.system.Conductor; import funkin.options.PlayerSettings; @@ -7,7 +8,7 @@ import flixel.FlxG; import flixel.FlxSubState; import flixel.math.FlxMath; -class MusicBeatSubstate extends FlxSubState +class MusicBeatSubstate extends FlxSubState implements IBeatReceiver { public function new() { @@ -43,42 +44,16 @@ class MusicBeatSubstate extends FlxSubState override function update(elapsed:Float) { - //everyStep(); - var oldStep:Int = curStep; - - updateCurStep(); - curBeat = Math.floor(curStep / 4); - - if (oldStep != curStep && curStep > 0) - stepHit(); - - super.update(elapsed); } - private function updateCurStep():Void - { - var lastChange:BPMChangeEvent = { - stepTime: 0, - songTime: 0, - bpm: 0 - } - for (i in 0...Conductor.bpmChangeMap.length) - { - if (Conductor.songPosition > Conductor.bpmChangeMap[i].songTime) - lastChange = Conductor.bpmChangeMap[i]; - } - curStep = lastChange.stepTime + Math.floor((Conductor.songPosition - lastChange.songTime) / Conductor.stepCrochet); + @:dox(hide) public function stepHit(curStep:Int):Void + { + //do literally nothing neither dumbass } - @:dox(hide) public function stepHit():Void - { - if (curStep % 4 == 0) - beatHit(); - } - - @:dox(hide) public function beatHit():Void + @:dox(hide) public function beatHit(curBeat:Int):Void { //do literally nothing dumbass }