From d62042a99a66731d80e6a043bf85e66ae6198407 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 11 Dec 2023 17:38:16 -0500 Subject: [PATCH 01/60] skip transition into debug substate --- source/funkin/ui/debug/DebugMenuSubState.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 404bf6f67..87977c85b 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -21,7 +21,9 @@ class DebugMenuSubState extends MusicBeatSubState override function create():Void { + FlxTransitionableState.skipNextTransIn = true; super.create(); + bgColor = 0x00000000; // Create an object for the camera to track. From 7058d9baa76c2b9a10dedb11a0c9ce419b976601 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 12 Dec 2023 23:28:16 -0500 Subject: [PATCH 02/60] stuf in progres --- source/funkin/ui/debug/DebugMenuSubState.hx | 7 ++++ .../funkin/ui/debug/latency/LatencyState.hx | 42 ++++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 87977c85b..11c2e3625 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -51,6 +51,7 @@ class DebugMenuSubState extends MusicBeatSubState // Create each menu item. // Call onMenuChange when the first item is created to move the camera . onMenuChange(createItem("CHART EDITOR", openChartEditor)); + createItem("Input Offset Testing", openInputOffsetTesting); createItem("ANIMATION EDITOR", openAnimationEditor); createItem("STAGE EDITOR", openStageEditor); createItem("TEST STICKERS", testStickers); @@ -92,6 +93,12 @@ class DebugMenuSubState extends MusicBeatSubState FlxG.switchState(new ChartEditorState()); } + function openInputOffsetTesting() + { + FlxG.switchState(new funkin.ui.debug.latency.LatencyState()); + trace('Input Offset Testing'); + } + function openAnimationEditor() { FlxG.switchState(new funkin.ui.debug.anim.DebugBoundingState()); diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 70ef97fd0..429884bb0 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -41,6 +41,10 @@ class LatencyState extends MusicBeatSubState override function create() { + super.create(); + + if (FlxG.sound.music != null) FlxG.sound.music.stop(); + swagSong = new HomemadeMusic(); swagSong.loadEmbedded(Paths.sound('soundTest'), true); @@ -66,8 +70,8 @@ class LatencyState extends MusicBeatSubState trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff()); // trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp()); - @:privateAccess - trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); + // @:privateAccess + // trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); // trace("EVENT LISTENER: " + key); }); @@ -91,14 +95,14 @@ class LatencyState extends MusicBeatSubState // // musSpec.visType = FREQUENCIES; // add(musSpec); - for (beat in 0...Math.floor(FlxG.sound.music.length / Conductor.instance.beatLengthMs)) + for (beat in 0...Math.floor(FlxG.sound.music.length / (Conductor.stepLengthMs * 2))) { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 15); + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.stepLengthMs * 2)), FlxG.height - 15); beatTick.makeGraphic(2, 15); beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * Conductor.instance.beatLengthMs), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * (Conductor.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -130,7 +134,7 @@ class LatencyState extends MusicBeatSubState for (i in 0...32) { - var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), Conductor.instance.beatLengthMs * i); + var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), (Conductor.stepLengthMs * 2) * i); noteGrp.add(note); } @@ -140,8 +144,6 @@ class LatencyState extends MusicBeatSubState strumLine = new FlxSprite(FlxG.width / 2, 100).makeGraphic(FlxG.width, 5); add(strumLine); - - super.create(); } override function stepHit():Bool @@ -183,12 +185,12 @@ class LatencyState extends MusicBeatSubState trace("\tUPDATE PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); } - if (FlxG.keys.justPressed.SPACE) - { - if (FlxG.sound.music.playing) FlxG.sound.music.pause(); - else - FlxG.sound.music.resume(); - } + // if (FlxG.keys.justPressed.SPACE) + // { + // if (FlxG.sound.music.playing) FlxG.sound.music.pause(); + // else + // FlxG.sound.music.resume(); + // } if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed; @@ -217,7 +219,7 @@ class LatencyState extends MusicBeatSubState if (FlxG.keys.pressed.SHIFT) multiply = 1; - if (FlxG.keys.pressed.CONTROL) + if (FlxG.keys.pressed.CONTROL || FlxG.keys.pressed.SPACE) { if (FlxG.keys.justPressed.RIGHT) { @@ -250,7 +252,7 @@ class LatencyState extends MusicBeatSubState }*/ noteGrp.forEach(function(daNote:NoteSprite) { - daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.noteData.time) * 0.45); + daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.instrumentalOffset) - daNote.strumTime) * 0.45); daNote.x = strumLine.x + 30; if (daNote.y < strumLine.y) daNote.alpha = 0.5; @@ -269,12 +271,12 @@ class LatencyState extends MusicBeatSubState { Conductor.instance.update(swagSong.getTimeWithDiff()); - 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; + var closestBeat:Int = Math.round(Conductor.songPosition / (Conductor.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = Conductor.songPosition - (closestBeat * (Conductor.stepLengthMs * 2)); + getDiff -= Conductor.inputOffset; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.instance.beatLengthMs * 2) getDiff -= FlxG.sound.music.length; + if (closestBeat == 0 && getDiff >= Conductor.stepLengthMs * 2) getDiff -= FlxG.sound.music.length; trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); trace("\tCLOSEST BEAT: " + closestBeat); From e323f46569798bac31d9973648208265aa99aa7e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 8 Jan 2024 15:46:16 -0500 Subject: [PATCH 03/60] conductor.instance fixes --- source/funkin/ui/debug/latency/LatencyState.hx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 429884bb0..c1321f19c 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -95,14 +95,14 @@ class LatencyState extends MusicBeatSubState // // musSpec.visType = FREQUENCIES; // add(musSpec); - for (beat in 0...Math.floor(FlxG.sound.music.length / (Conductor.stepLengthMs * 2))) + for (beat in 0...Math.floor(FlxG.sound.music.length / (Conductor.instance.stepLengthMs * 2))) { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.stepLengthMs * 2)), FlxG.height - 15); + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 15); beatTick.makeGraphic(2, 15); beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * (Conductor.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -134,7 +134,7 @@ class LatencyState extends MusicBeatSubState for (i in 0...32) { - var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), (Conductor.stepLengthMs * 2) * i); + var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), (Conductor.instance.stepLengthMs * 2) * i); noteGrp.add(note); } @@ -252,7 +252,7 @@ class LatencyState extends MusicBeatSubState }*/ noteGrp.forEach(function(daNote:NoteSprite) { - daNote.y = (strumLine.y - ((Conductor.songPosition - Conductor.instrumentalOffset) - daNote.strumTime) * 0.45); + daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.strumTime) * 0.45); daNote.x = strumLine.x + 30; if (daNote.y < strumLine.y) daNote.alpha = 0.5; @@ -271,12 +271,12 @@ class LatencyState extends MusicBeatSubState { Conductor.instance.update(swagSong.getTimeWithDiff()); - var closestBeat:Int = Math.round(Conductor.songPosition / (Conductor.stepLengthMs * 2)) % diffGrp.members.length; - var getDiff:Float = Conductor.songPosition - (closestBeat * (Conductor.stepLengthMs * 2)); - getDiff -= Conductor.inputOffset; + var closestBeat:Int = Math.round(Conductor.instance.songPosition / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = Conductor.instance.songPosition - (closestBeat * (Conductor.instance.stepLengthMs * 2)); + getDiff -= Conductor.instance.inputOffset; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.stepLengthMs * 2) getDiff -= FlxG.sound.music.length; + if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= FlxG.sound.music.length; trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); trace("\tCLOSEST BEAT: " + closestBeat); From 5d0c1521d58c4819b14847d620feb1064e556014 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 9 Jan 2024 13:16:00 -0500 Subject: [PATCH 04/60] strumline refactor stuffy --- source/funkin/play/PlayState.hx | 110 +----------------- source/funkin/play/notes/Strumline.hx | 81 +++++++++++++ source/funkin/ui/debug/DebugMenuSubState.hx | 4 +- .../funkin/ui/debug/latency/CoolStatsGraph.hx | 33 ++++-- .../funkin/ui/debug/latency/LatencyState.hx | 76 +++++------- 5 files changed, 142 insertions(+), 162 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 995797dd1..1eaad0b06 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1791,63 +1791,7 @@ class PlayState extends MusicBeatSubState { if (playerStrumline?.notes?.members == null || opponentStrumline?.notes?.members == null) return; - // Process notes on the opponent's side. - for (note in opponentStrumline.notes.members) - { - if (note == null) continue; - - var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; - var hitWindowCenter = note.strumTime; - var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - - if (Conductor.instance.songPosition > hitWindowEnd) - { - if (note.hasMissed) continue; - - note.tooEarly = false; - note.mayHit = false; - note.hasMissed = true; - - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; - } - else if (Conductor.instance.songPosition > hitWindowCenter) - { - if (note.hasBeenHit) continue; - - // Call an event to allow canceling the note hit. - // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new NoteScriptEvent(NOTE_HIT, note, 0, true); - dispatchEvent(event); - - // Calling event.cancelEvent() skips all the other logic! Neat! - if (event.eventCanceled) continue; - - // Command the opponent to hit the note on time. - // NOTE: This is what handles the strumline and cleaning up the note itself! - opponentStrumline.hitNote(note); - - if (note.holdNoteSprite != null) - { - opponentStrumline.playNoteHoldCover(note.holdNoteSprite); - } - } - else if (Conductor.instance.songPosition > hitWindowStart) - { - if (note.hasBeenHit || note.hasMissed) continue; - - note.tooEarly = false; - note.mayHit = true; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - else - { - note.tooEarly = true; - note.mayHit = false; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - } + opponentStrumline.processNotes(null, dispatchEvent); // Process hold notes on the opponent's side. for (holdNote in opponentStrumline.holdNotes.members) @@ -1868,57 +1812,7 @@ class PlayState extends MusicBeatSubState // if (holdNote.missedNote && !holdNote.handledMiss) { holdNote.handledMiss = true; } } - // Process notes on the player's side. - for (note in playerStrumline.notes.members) - { - if (note == null || note.hasBeenHit) continue; - - var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; - var hitWindowCenter = note.strumTime; - var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - - 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.instance.songPosition > hitWindowStart) - { - note.tooEarly = false; - note.mayHit = true; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - else - { - note.tooEarly = true; - note.mayHit = false; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - - // This becomes true when the note leaves the hit window. - // It might still be on screen. - if (note.hasMissed && !note.handledMiss) - { - // Call an event to allow canceling the note miss. - // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new NoteScriptEvent(NOTE_MISS, note, 0, true); - dispatchEvent(event); - - // Calling event.cancelEvent() skips all the other logic! Neat! - if (event.eventCanceled) continue; - - // Judge the miss. - // NOTE: This is what handles the scoring. - trace('Missed note! ${note.noteData}'); - onNoteMiss(note); - - note.handledMiss = true; - } - } + playerStrumline.processNotes(onNoteMiss, dispatchEvent); // Process hold notes on the player's side. // This handles scoring so we don't need it on the opponent's side. diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index b312494cf..b0ab1ba1c 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -14,6 +14,7 @@ import funkin.play.notes.SustainTrail; import funkin.data.song.SongData.SongNoteData; import funkin.ui.options.PreferencesMenu; import funkin.util.SortUtil; +import funkin.modding.events.ScriptEvent; /** * A group of sprites which handles the receptor, the note splashes, and the notes (with sustains) for a given player. @@ -142,6 +143,86 @@ class Strumline extends FlxSpriteGroup updateNotes(); } + /** + * Process the notes in this strumline. + * @param onNoteMiss + * @param dispatchEvent TODO: better way to do this? Maybe passing in current dispatchEvent function from current state? + */ + public function processNotes(?onNoteMiss:NoteSprite->Void, ?dispatchEvent:ScriptEvent->Void) + { + for (note in notes.members) + { + if (note == null || (isPlayer && note.hasBeenHit)) continue; + + var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; + var hitWindowCenter = note.strumTime; + var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; + + if (Conductor.instance.songPosition > hitWindowEnd) + { + if (!isPlayer && note.hasMissed) continue; + + note.tooEarly = false; + note.mayHit = false; + note.hasMissed = true; + + if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; + } + else if (Conductor.instance.songPosition > hitWindowCenter) + { + // only run this on opponent strumlines! + if (!isPlayer) continue; + + // Call an event to allow canceling the note hit. + // NOTE: This is what handles the character animations! + var event:NoteScriptEvent = new NoteScriptEvent(NOTE_HIT, note, 0, true); + if (dispatchEvent != null) dispatchEvent(event); + + // Calling event.cancelEvent() skips all other logic! Neat! + if (event.eventCanceled) continue; + + // Command the opponent to hit the note on time. + // NOTE: This is what handles the strumline and cleaning up the note itself! + + hitNote(note); + + if (note.holdNoteSprite != null) + { + playNoteHoldCover(note.holdNoteSprite); + } + } + else if (Conductor.instance.songPosition > hitWindowStart) + { + if (!isPlayer && (note.hasBeenHit || note.hasMissed)) continue; + + note.tooEarly = false; + note.mayHit = true; + note.hasMissed = false; + if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; + } + else + { + note.tooEarly = true; + note.mayHit = false; + note.hasMissed = false; + if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; + } + + if (note.hasMissed && !note.handledMiss) + { + var event:NoteScriptEvent = new NoteScriptEvent(NOTE_MISS, note, 0, true); + + if (dispatchEvent != null) dispatchEvent(event); + + if (event.eventCanceled) continue; + + if (onNoteMiss != null) onNoteMiss(note); + + note.handledMiss = true; + } + } + } + var frameMax:Int; var animFinishedEver:Bool; diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 11c2e3625..f797dfbad 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -48,6 +48,8 @@ class DebugMenuSubState extends MusicBeatSubState items.onChange.add(onMenuChange); add(items); + FlxTransitionableState.skipNextTransIn = true; + // Create each menu item. // Call onMenuChange when the first item is created to move the camera . onMenuChange(createItem("CHART EDITOR", openChartEditor)); @@ -88,8 +90,6 @@ class DebugMenuSubState extends MusicBeatSubState function openChartEditor() { - FlxTransitionableState.skipNextTransIn = true; - FlxG.switchState(new ChartEditorState()); } diff --git a/source/funkin/ui/debug/latency/CoolStatsGraph.hx b/source/funkin/ui/debug/latency/CoolStatsGraph.hx index 01689f494..fc733ec28 100644 --- a/source/funkin/ui/debug/latency/CoolStatsGraph.hx +++ b/source/funkin/ui/debug/latency/CoolStatsGraph.hx @@ -7,7 +7,6 @@ import flash.text.TextField; import flash.text.TextFormatAlign; import flixel.math.FlxMath; import flixel.system.debug.DebuggerUtil; -import flixel.system.debug.stats.Stats; import flixel.util.FlxColor; import flixel.util.FlxDestroyUtil; @@ -16,13 +15,31 @@ import flixel.util.FlxDestroyUtil; * SHAMELESSLY STOLEN FROM FLIXEL * https://github.com/HaxeFlixel/flixel/blob/master/flixel/system/debug/stats/StatsGraph.hx */ -#if FLX_DEBUG class CoolStatsGraph extends Sprite { static inline var AXIS_COLOR:FlxColor = 0xffffff; static inline var AXIS_ALPHA:Float = 0.5; static inline var HISTORY_MAX:Int = 500; + /** + * How often to update the stats, in ms. The lower, the more performance-intense! + */ + static inline var UPDATE_DELAY:Int = 250; + + /** + * The initial width of the stats window. + */ + static inline var INITIAL_WIDTH:Int = 160; + + static inline var FPS_COLOR:FlxColor = 0xff96ff00; + static inline var MEMORY_COLOR:FlxColor = 0xff009cff; + static inline var DRAW_TIME_COLOR:FlxColor = 0xffA60004; + static inline var UPDATE_TIME_COLOR:FlxColor = 0xffdcd400; + + public static inline var LABEL_COLOR:FlxColor = 0xaaffffff; + public static inline var TEXT_SIZE:Int = 11; + public static inline var DECIMALS:Int = 1; + public var minLabel:TextField; public var curLabel:TextField; public var maxLabel:TextField; @@ -45,6 +62,7 @@ class CoolStatsGraph extends Sprite public function new(X:Int, Y:Int, Width:Int, Height:Int, GraphColor:FlxColor, Unit:String, LabelWidth:Int = 45, ?Label:String) { super(); + x = X; y = Y; _width = Width - LabelWidth; @@ -57,11 +75,11 @@ class CoolStatsGraph extends Sprite _axis = new Shape(); _axis.x = _labelWidth + 10; - maxLabel = DebuggerUtil.createTextField(0, 0, Stats.LABEL_COLOR, Stats.TEXT_SIZE); - curLabel = DebuggerUtil.createTextField(0, (_height / 2) - (Stats.TEXT_SIZE / 2), graphColor, Stats.TEXT_SIZE); - minLabel = DebuggerUtil.createTextField(0, _height - Stats.TEXT_SIZE, Stats.LABEL_COLOR, Stats.TEXT_SIZE); + maxLabel = DebuggerUtil.createTextField(0, 0, LABEL_COLOR, TEXT_SIZE); + curLabel = DebuggerUtil.createTextField(0, (_height / 2) - (TEXT_SIZE / 2), graphColor, TEXT_SIZE); + minLabel = DebuggerUtil.createTextField(0, _height - TEXT_SIZE, LABEL_COLOR, TEXT_SIZE); - avgLabel = DebuggerUtil.createTextField(_labelWidth + 20, (_height / 2) - (Stats.TEXT_SIZE / 2) - 10, Stats.LABEL_COLOR, Stats.TEXT_SIZE); + avgLabel = DebuggerUtil.createTextField(_labelWidth + 20, (_height / 2) - (TEXT_SIZE / 2) - 10, LABEL_COLOR, TEXT_SIZE); avgLabel.width = _width; avgLabel.defaultTextFormat.align = TextFormatAlign.CENTER; avgLabel.alpha = 0.5; @@ -136,7 +154,7 @@ class CoolStatsGraph extends Sprite function formatValue(value:Float):String { - return FlxMath.roundDecimal(value, Stats.DECIMALS) + " " + _unit; + return FlxMath.roundDecimal(value, DECIMALS) + " " + _unit; } public function average():Float @@ -157,4 +175,3 @@ class CoolStatsGraph extends Sprite history = null; } } -#end diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index c1321f19c..ae922612b 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -8,7 +8,6 @@ import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; import funkin.ui.MusicBeatSubState; import flixel.sound.FlxSound; -import flixel.system.debug.stats.StatsGraph; import flixel.text.FlxText; import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram; @@ -16,12 +15,17 @@ import funkin.play.notes.NoteSprite; import funkin.ui.debug.latency.CoolStatsGraph; import haxe.Timer; import openfl.events.KeyboardEvent; +import funkin.input.PreciseInputManager; +import funkin.play.notes.Strumline; +import funkin.play.notes.notestyle.NoteStyle; +import funkin.data.notestyle.NoteStyleData; +import funkin.data.notestyle.NoteStyleRegistry; class LatencyState extends MusicBeatSubState { var offsetText:FlxText; var noteGrp:FlxTypedGroup; - var strumLine:FlxSprite; + var strumLine:Strumline; var blocks:FlxTypedGroup; @@ -34,10 +38,8 @@ class LatencyState extends MusicBeatSubState var offsetsPerBeat:Array = []; var swagSong:HomemadeMusic; - #if FLX_DEBUG var funnyStatsGraph:CoolStatsGraph; var realStats:CoolStatsGraph; - #end override function create() { @@ -51,33 +53,24 @@ class LatencyState extends MusicBeatSubState FlxG.sound.music = swagSong; FlxG.sound.music.play(); - #if FLX_DEBUG - funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.PINK, "time"); + funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 3), Std.int(FlxG.width / 2), Std.int(FlxG.height / 3), FlxColor.PINK, "time"); + funnyStatsGraph.curLabel.y += 32; FlxG.addChildBelowMouse(funnyStatsGraph); - realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 2), FlxG.width, Std.int(FlxG.height / 2), FlxColor.YELLOW, "REAL"); + realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 3), Std.int(FlxG.width / 2), Std.int(FlxG.height / 3), FlxColor.YELLOW, "REAL"); + realStats.curLabel.y -= 32; FlxG.addChildBelowMouse(realStats); - #end - FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> { - trace(key.charCode); - - if (key.charCode == 120) generateBeatStuff(); - - trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); - // trace(FlxG.sound.music.prevTimestamp); - trace(FlxG.sound.music.time); - trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff()); - - // trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp()); - // @:privateAccess - // trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); - // trace("EVENT LISTENER: " + key); + PreciseInputManager.instance.onInputPressed.add(function(event:PreciseInputEvent) { + strumLine.pressKey(event.noteDirection); + strumLine.playPress(event.noteDirection); + generateBeatStuff(event); }); - // FlxG.sound.playMusic(Paths.sound('soundTest')); - - // funnyStatsGraph.hi + PreciseInputManager.instance.onInputReleased.add(function(event:PreciseInputEvent) { + strumLine.playStatic(event.noteDirection); + strumLine.releaseKey(event.noteDirection); + }); Conductor.instance.forceBPM(60); @@ -139,10 +132,11 @@ class LatencyState extends MusicBeatSubState } offsetText = new FlxText(); + offsetText.size = 20; offsetText.screenCenter(); add(offsetText); - strumLine = new FlxSprite(FlxG.width / 2, 100).makeGraphic(FlxG.width, 5); + strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true); add(strumLine); } @@ -175,15 +169,8 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - #if FLX_DEBUG - funnyStatsGraph.update(FlxG.sound.music.time % 500); + funnyStatsGraph.update(Conductor.instance.songPosition % 500); realStats.update(swagSong.getTimeWithDiff() % 500); - #end - - if (FlxG.keys.justPressed.S) - { - trace("\tUPDATE PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); - } // if (FlxG.keys.justPressed.SPACE) // { @@ -192,17 +179,15 @@ class LatencyState extends MusicBeatSubState // FlxG.sound.music.resume(); // } - if (FlxG.keys.pressed.D) FlxG.sound.music.time += 1000 * FlxG.elapsed; - - Conductor.instance.update(swagSong.getTimeWithDiff() - Conductor.instance.inputOffset); + Conductor.instance.update(); // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; songPosVis.x = songPosToX(Conductor.instance.songPosition); songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset); songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset); - offsetText.text = "INST Offset: " + Conductor.instance.instrumentalOffset + "ms"; - offsetText.text += "\nINPUT Offset: " + Conductor.instance.inputOffset + "ms"; + offsetText.text = "INST Offset (CTRL+Left/Right to change): " + Conductor.instance.instrumentalOffset + "ms"; + offsetText.text += "\nINPUT Offset (Left/Right to change): " + Conductor.instance.inputOffset + "ms"; offsetText.text += "\ncurrentStep: " + Conductor.instance.currentStep; offsetText.text += "\ncurrentBeat: " + Conductor.instance.currentBeat; @@ -267,19 +252,23 @@ class LatencyState extends MusicBeatSubState super.update(elapsed); } - function generateBeatStuff() + function generateBeatStuff(event:PreciseInputEvent) { - Conductor.instance.update(swagSong.getTimeWithDiff()); + // Conductor.instance.update(swagSong.getTimeWithDiff()); + + var inputLatencyMs:Float = haxe.Int64.toInt(PreciseInputManager.getCurrentTimestamp() - event.timestamp) / 1000.0 / 1000.0; + trace("input latency: " + inputLatencyMs + "ms"); + trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); + trace("event timestamp: " + event.timestamp + "ns"); var closestBeat:Int = Math.round(Conductor.instance.songPosition / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; var getDiff:Float = Conductor.instance.songPosition - (closestBeat * (Conductor.instance.stepLengthMs * 2)); getDiff -= Conductor.instance.inputOffset; + getDiff -= inputLatencyMs; // lil fix for end of song if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= FlxG.sound.music.length; - trace("\tDISTANCE TO CLOSEST BEAT: " + getDiff + "ms"); - trace("\tCLOSEST BEAT: " + closestBeat); beatTrail.x = songPosVis.x; diffGrp.members[closestBeat].text = getDiff + "ms"; @@ -295,7 +284,6 @@ class LatencyState extends MusicBeatSubState class HomemadeMusic extends FlxSound { public var prevTimestamp:Int = 0; - public var timeWithDiff:Float = 0; public function new() { From d9a6bead77d467a236913496ac244d8c091bf5b6 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 9 Jan 2024 19:41:25 -0500 Subject: [PATCH 05/60] inputOffset + audioVisualOffset in Save class --- Project.xml | 2 +- source/funkin/save/Save.hx | 16 +++++++++++++++- source/funkin/save/changelog.md | 12 ++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 source/funkin/save/changelog.md diff --git a/Project.xml b/Project.xml index e0677b026..fc6ebf085 100644 --- a/Project.xml +++ b/Project.xml @@ -127,7 +127,7 @@ - + diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 810d0fd93..6753419b7 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -15,7 +15,7 @@ import thx.semver.Version; abstract Save(RawSaveData) { // Version 2.0.1 adds attributes to `optionsChartEditor`, that should return default values if they are null. - public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.1"; + public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.2"; public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x"; // We load this version's saves from a new save path, to maintain SOME level of backwards compatibility. @@ -72,6 +72,8 @@ abstract Save(RawSaveData) zoomCamera: true, debugDisplay: false, autoPause: true, + inputOffset: 0, + audioVisualOffset: 0, controls: { @@ -828,6 +830,18 @@ typedef SaveDataOptions = */ var autoPause:Bool; + /** + * Offset the users inputs by this many ms. + * @default `0` + */ + var inputOffset:Int; + + /** + * Affects the delay between the audio and the visuals during gameplay + * @default `0` + */ + var audioVisualOffset:Int; + var controls: { var p1: diff --git a/source/funkin/save/changelog.md b/source/funkin/save/changelog.md new file mode 100644 index 000000000..3fa9839d1 --- /dev/null +++ b/source/funkin/save/changelog.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [2.0.3] - 2024-01-09 +### Added +- `inputOffset:Float` to `SongDataOptions` +- `audioVisualOffset:Float` to `SongDataOptions` From 3544f2a804866ea248dceb95f3e13a30d1a84852 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 9 Jan 2024 19:48:01 -0500 Subject: [PATCH 06/60] input offset get/set functions in conductor --- source/funkin/Conductor.hx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 05c23108f..6113baf23 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -209,7 +209,17 @@ class Conductor /** * An offset set by the user to compensate for input lag. */ - public var inputOffset:Float = 0; + public var inputOffset(get, set):Float; + + function get_inputOffset():Float + { + return Save.get().options.inputOffset; + } + + function set_inputOffset(value:Float):Float + { + return Save.get().options.inputOffset = value; + } /** * The number of beats in a measure. May be fractional depending on the time signature. From b11bf096870cc1d4b54c7278f01f6c6b437d5d14 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 9 Jan 2024 19:57:33 -0500 Subject: [PATCH 07/60] save/load for inputOffsets --- source/funkin/Conductor.hx | 11 +++++++---- source/funkin/ui/debug/latency/LatencyState.hx | 10 +++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 6113baf23..2ca144a2d 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -6,6 +6,7 @@ import flixel.math.FlxMath; import funkin.play.song.Song.SongDifficulty; import funkin.data.song.SongData.SongTimeChange; import funkin.data.song.SongDataUtils; +import funkin.save.Save; /** * A core class which handles musical timing throughout the game, @@ -209,16 +210,18 @@ class Conductor /** * An offset set by the user to compensate for input lag. */ - public var inputOffset(get, set):Float; + public var inputOffset(get, set):Int; - function get_inputOffset():Float + function get_inputOffset():Int { return Save.get().options.inputOffset; } - function set_inputOffset(value:Float):Float + function set_inputOffset(value:Int):Int { - return Save.get().options.inputOffset = value; + Save.get().options.inputOffset = value; + Save.get().flush(); + return Save.get().options.inputOffset; } /** diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index ae922612b..84425d4a0 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -200,7 +200,7 @@ class LatencyState extends MusicBeatSubState offsetText.text += "\naverage input offset needed: " + avgOffsetInput; - var multiply:Float = 10; + var multiply:Int = 10; if (FlxG.keys.pressed.SHIFT) multiply = 1; @@ -208,24 +208,24 @@ class LatencyState extends MusicBeatSubState { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.instrumentalOffset += 1.0 * multiply; + Conductor.instance.instrumentalOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.instrumentalOffset -= 1.0 * multiply; + Conductor.instance.instrumentalOffset -= 1 * multiply; } } else { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.inputOffset += 1.0 * multiply; + Conductor.instance.inputOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.inputOffset -= 1.0 * multiply; + Conductor.instance.inputOffset -= 1 * multiply; } } From 53d3db200751dbad221771307268d8d6b06676c9 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 16 Jan 2024 04:06:56 -0500 Subject: [PATCH 08/60] assets subjod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index b282f3431..d094640f7 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b282f3431c15b719222196813da98ab70839d3e5 +Subproject commit d094640f727a670a348b3579d11af5ff6a2ada3a From 1dcd0debc728a6ab18c3a688a0336dcca37cfb0e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 16 Jan 2024 05:37:06 -0500 Subject: [PATCH 09/60] conductor stuff --- source/funkin/Conductor.hx | 25 +++++++ .../funkin/ui/debug/latency/LatencyState.hx | 72 +++++++++---------- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 2ca144a2d..7a4f76924 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -7,6 +7,7 @@ import funkin.play.song.Song.SongDifficulty; import funkin.data.song.SongData.SongTimeChange; import funkin.data.song.SongDataUtils; import funkin.save.Save; +import haxe.Timer; /** * A core class which handles musical timing throughout the game, @@ -71,6 +72,9 @@ class Conductor */ public var songPosition(default, null):Float = 0; + var prevTimestamp:Float = 0; + var prevTime:Float = 0; + /** * Beats per minute of the current song at the current time. */ @@ -349,6 +353,27 @@ class Conductor Conductor.measureHit.dispatch(); } } + + // only update the timestamp if songPosition actually changed + // which it doesn't do every frame! + if (prevTime != this.songPosition) + { + // Update the timestamp for use in-between frames + prevTime = this.songPosition; + prevTimestamp = Std.int(Timer.stamp() * 1000); + } + } + + /** + * Can be called in-between frames, usually for input related things + * that can potentially get processed on exact milliseconds/timestmaps. + * If you need song position, use `Conductor.instance.songPosition` instead + * for use in update() related functions. + * @return Float + */ + public function getTimeWithDiff():Float + { + return this.songPosition + (Std.int(Timer.stamp() * 1000) - prevTimestamp); } public function mapTimeChanges(songTimeChanges:Array) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 84425d4a0..d3f7bb7b6 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -13,18 +13,19 @@ import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram; import funkin.play.notes.NoteSprite; import funkin.ui.debug.latency.CoolStatsGraph; -import haxe.Timer; import openfl.events.KeyboardEvent; import funkin.input.PreciseInputManager; import funkin.play.notes.Strumline; import funkin.play.notes.notestyle.NoteStyle; import funkin.data.notestyle.NoteStyleData; import funkin.data.notestyle.NoteStyleRegistry; +import funkin.data.song.SongData.SongNoteData; +import haxe.Timer; class LatencyState extends MusicBeatSubState { var offsetText:FlxText; - var noteGrp:FlxTypedGroup; + var noteGrp:Array; var strumLine:Strumline; var blocks:FlxTypedGroup; @@ -74,8 +75,7 @@ class LatencyState extends MusicBeatSubState Conductor.instance.forceBPM(60); - noteGrp = new FlxTypedGroup(); - add(noteGrp); + noteGrp = []; diffGrp = new FlxTypedGroup(); add(diffGrp); @@ -125,12 +125,6 @@ class LatencyState extends MusicBeatSubState blocks.add(block); } - for (i in 0...32) - { - var note:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault(), (Conductor.instance.stepLengthMs * 2) * i); - noteGrp.add(note); - } - offsetText = new FlxText(); offsetText.size = 20; offsetText.screenCenter(); @@ -138,6 +132,19 @@ class LatencyState extends MusicBeatSubState strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true); add(strumLine); + + regenNoteData(); + } + + function regenNoteData() + { + for (i in 0...32) + { + var note:SongNoteData = new SongNoteData((Conductor.instance.stepLengthMs * 2) * i, 1); + noteGrp.push(note); + } + + strumLine.applyNoteData(noteGrp); } override function stepHit():Bool @@ -169,17 +176,11 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - funnyStatsGraph.update(Conductor.instance.songPosition % 500); - realStats.update(swagSong.getTimeWithDiff() % 500); - - // if (FlxG.keys.justPressed.SPACE) - // { - // if (FlxG.sound.music.playing) FlxG.sound.music.pause(); - // else - // FlxG.sound.music.resume(); - // } - Conductor.instance.update(); + + funnyStatsGraph.update(Conductor.instance.songPosition % 500); + realStats.update(Conductor.instance.getTimeWithDiff() % 500); + // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; songPosVis.x = songPosToX(Conductor.instance.songPosition); @@ -229,25 +230,18 @@ class LatencyState extends MusicBeatSubState } } - /* if (FlxG.keys.justPressed.SPACE) - { - FlxG.sound.music.stop(); + // noteGrp.forEach(function(daNote:NoteSprite) { + // daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.strumTime) * 0.45); + // daNote.x = strumLine.x + 30; - FlxG.resetState(); - }*/ + // if (daNote.y < strumLine.y) daNote.alpha = 0.5; - noteGrp.forEach(function(daNote:NoteSprite) { - daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.strumTime) * 0.45); - daNote.x = strumLine.x + 30; - - if (daNote.y < strumLine.y) daNote.alpha = 0.5; - - if (daNote.y < 0 - daNote.height) - { - daNote.alpha = 1; - // daNote.data.strumTime += Conductor.instance.beatLengthMs * 8; - } - }); + // if (daNote.y < 0 - daNote.height) + // { + // daNote.alpha = 1; + // // daNote.data.strumTime += Conductor.instance.beatLengthMs * 8; + // } + // }); super.update(elapsed); } @@ -261,8 +255,8 @@ class LatencyState extends MusicBeatSubState trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); trace("event timestamp: " + event.timestamp + "ns"); - var closestBeat:Int = Math.round(Conductor.instance.songPosition / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; - var getDiff:Float = Conductor.instance.songPosition - (closestBeat * (Conductor.instance.stepLengthMs * 2)); + var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff() / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = Conductor.instance.getTimeWithDiff() - (closestBeat * (Conductor.instance.stepLengthMs * 2)); getDiff -= Conductor.instance.inputOffset; getDiff -= inputLatencyMs; From df2c01b2ff8dc4b7b28c7b70d897cd078b5df7e1 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 27 Jan 2024 06:16:39 -0500 Subject: [PATCH 10/60] crackhead activity in progress --- .vscode/tasks.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 16a77646f..be4414ea0 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,13 +1,13 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "lime", - "command": "test", - "group": { - "kind": "build", - "isDefault": true - } - } - ] + "version": "2.0.0", + "tasks": [ + { + "type": "lime", + "command": "test", + "group": { + "kind": "build", + "isDefault": true + } + } + ] } From c44e33c5568fd27ebe633695f4879f4ab74f61d9 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 27 Jan 2024 06:16:46 -0500 Subject: [PATCH 11/60] derp --- .vscode/launch.json | 6 ++++++ assets | 2 +- source/funkin/Conductor.hx | 8 +++++++- source/funkin/ui/debug/latency/LatencyState.hx | 14 +++----------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 74f72b826..afc0ab8db 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,6 +7,12 @@ "type": "lime", "request": "launch" }, + { + "name": "Debug", + "type": "lime", + "request": "launch", + "preLaunchTask": null + }, { // Launch in browser "name": "HTML5 Debug", diff --git a/assets b/assets index d094640f7..b2f8b6a78 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d094640f727a670a348b3579d11af5ff6a2ada3a +Subproject commit b2f8b6a780316959d0a79adc6dbf61f9e4ca675f diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 7a4f76924..75031f6dd 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -373,7 +373,13 @@ class Conductor */ public function getTimeWithDiff():Float { - return this.songPosition + (Std.int(Timer.stamp() * 1000) - prevTimestamp); + // trace(this.songPosition); + + @:privateAccess + this.songPosition = FlxG.sound.music._channel.position; + // return this.songPosition + (Std.int(Timer.stamp() * 1000) - prevTimestamp); + // trace("\t--> " + this.songPosition); + return this.songPosition; } public function mapTimeChanges(songTimeChanges:Array) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index d3f7bb7b6..f75ac16bc 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -63,9 +63,9 @@ class LatencyState extends MusicBeatSubState FlxG.addChildBelowMouse(realStats); PreciseInputManager.instance.onInputPressed.add(function(event:PreciseInputEvent) { + generateBeatStuff(event); strumLine.pressKey(event.noteDirection); strumLine.playPress(event.noteDirection); - generateBeatStuff(event); }); PreciseInputManager.instance.onInputReleased.add(function(event:PreciseInputEvent) { @@ -80,14 +80,6 @@ class LatencyState extends MusicBeatSubState diffGrp = new FlxTypedGroup(); add(diffGrp); - // var musSpec:PolygonSpectogram = new PolygonSpectogram(FlxG.sound.music, FlxColor.RED, FlxG.height, Math.floor(FlxG.height / 2)); - // musSpec.x += 170; - // musSpec.scrollFactor.set(); - // musSpec.waveAmplitude = 100; - // musSpec.realtimeVisLenght = 0.45; - // // musSpec.visType = FREQUENCIES; - // add(musSpec); - for (beat in 0...Math.floor(FlxG.sound.music.length / (Conductor.instance.stepLengthMs * 2))) { var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 15); @@ -178,7 +170,7 @@ class LatencyState extends MusicBeatSubState Conductor.instance.update(); - funnyStatsGraph.update(Conductor.instance.songPosition % 500); + funnyStatsGraph.update(swagSong.getTimeWithDiff() % 500); realStats.update(Conductor.instance.getTimeWithDiff() % 500); // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; @@ -266,7 +258,7 @@ class LatencyState extends MusicBeatSubState beatTrail.x = songPosVis.x; diffGrp.members[closestBeat].text = getDiff + "ms"; - offsetsPerBeat[closestBeat] = Std.int(getDiff); + offsetsPerBeat[closestBeat] = Math.round(getDiff); } function songPosToX(pos:Float):Float From cdb73f94ca6f93b96c988cb48f09def5196bf3dd Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 31 Jan 2024 01:10:57 -0500 Subject: [PATCH 12/60] lime fixy --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 4b2885a87..54ddabb09 100644 --- a/hmm.json +++ b/hmm.json @@ -107,7 +107,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "fff39ba6fc64969cd51987ef7491d9345043dc5d", + "ref": "6bedb913b1429e81ac68996467e867501221e6c2", "url": "https://github.com/FunkinCrew/lime" }, { From 3621f17bd05d2170109fc3475d946395d90a4ceb Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 31 Jan 2024 03:24:00 -0500 Subject: [PATCH 13/60] maybe acurate? --- assets | 2 +- hmm.json | 2 +- source/funkin/input/PreciseInputManager.hx | 5 +++-- source/funkin/ui/debug/latency/LatencyState.hx | 3 ++- source/funkin/util/Constants.hx | 2 ++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/assets b/assets index b2f8b6a78..30ad76c15 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b2f8b6a780316959d0a79adc6dbf61f9e4ca675f +Subproject commit 30ad76c15d88bdff2b41ec017e3f3089ede52411 diff --git a/hmm.json b/hmm.json index 54ddabb09..80ae1023b 100644 --- a/hmm.json +++ b/hmm.json @@ -54,7 +54,7 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "5b2d5b8e7e470cf637953e1369c80a1f42016a75", + "ref": "a551159", "url": "https://github.com/haxeui/haxeui-core" }, { diff --git a/source/funkin/input/PreciseInputManager.hx b/source/funkin/input/PreciseInputManager.hx index 59e6610a5..1dfa7ac95 100644 --- a/source/funkin/input/PreciseInputManager.hx +++ b/source/funkin/input/PreciseInputManager.hx @@ -293,8 +293,9 @@ class PreciseInputManager extends FlxKeyManager // TODO: Remove this line with SDL3 when timestamps change meaning. // This is because SDL3's timestamps are measured in nanoseconds, not milliseconds. - timestamp *= Constants.NS_PER_MS; - + timestamp *= Constants.NS_PER_MS; // 18126000000 38367000000 + timestamp -= Conductor.instance.inputOffset * Constants.NS_PER_MS; + // trace(timestamp); updateKeyStates(key, true); if (getInputByKey(key)?.justPressed ?? false) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index f75ac16bc..1a59167ef 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -246,10 +246,11 @@ class LatencyState extends MusicBeatSubState trace("input latency: " + inputLatencyMs + "ms"); trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); trace("event timestamp: " + event.timestamp + "ns"); + trace("songtime: " + Conductor.instance.getTimeWithDiff() + "ms"); var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff() / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; var getDiff:Float = Conductor.instance.getTimeWithDiff() - (closestBeat * (Conductor.instance.stepLengthMs * 2)); - getDiff -= Conductor.instance.inputOffset; + // getDiff -= Conductor.instance.inputOffset; getDiff -= inputLatencyMs; // lil fix for end of song diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 1005b312e..d18956a8a 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -224,6 +224,8 @@ class Constants /** * Constant for the number of seconds in a minute. + * + * sex per min */ public static final SECS_PER_MIN:Int = 60; From cd28f81c8c42925a963cc55a824d588e6102e478 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 9 Feb 2024 01:31:34 -0500 Subject: [PATCH 14/60] hmm commit update --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index 80ae1023b..3845003c4 100644 --- a/hmm.json +++ b/hmm.json @@ -107,7 +107,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "6bedb913b1429e81ac68996467e867501221e6c2", + "ref": "develop2", "url": "https://github.com/FunkinCrew/lime" }, { @@ -163,4 +163,4 @@ "version": "0.11.0" } ] -} +} \ No newline at end of file From aeddcee9838b28695b57cc16558106b28f253581 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 10 Feb 2024 15:42:29 -0500 Subject: [PATCH 15/60] tweaks in progress --- hmm.json | 4 +- .../funkin/ui/debug/latency/LatencyState.hx | 69 ++++++++----------- 2 files changed, 32 insertions(+), 41 deletions(-) diff --git a/hmm.json b/hmm.json index 3845003c4..542feaf01 100644 --- a/hmm.json +++ b/hmm.json @@ -107,7 +107,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "develop2", + "ref": "6c92c7e", "url": "https://github.com/FunkinCrew/lime" }, { @@ -163,4 +163,4 @@ "version": "0.11.0" } ] -} \ No newline at end of file +} diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 1a59167ef..137ab77ee 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -24,6 +24,7 @@ import haxe.Timer; class LatencyState extends MusicBeatSubState { + var visualOffsetText:FlxText; var offsetText:FlxText; var noteGrp:Array; var strumLine:Strumline; @@ -39,9 +40,6 @@ class LatencyState extends MusicBeatSubState var offsetsPerBeat:Array = []; var swagSong:HomemadeMusic; - var funnyStatsGraph:CoolStatsGraph; - var realStats:CoolStatsGraph; - override function create() { super.create(); @@ -54,14 +52,6 @@ class LatencyState extends MusicBeatSubState FlxG.sound.music = swagSong; FlxG.sound.music.play(); - funnyStatsGraph = new CoolStatsGraph(0, Std.int(FlxG.height / 3), Std.int(FlxG.width / 2), Std.int(FlxG.height / 3), FlxColor.PINK, "time"); - funnyStatsGraph.curLabel.y += 32; - FlxG.addChildBelowMouse(funnyStatsGraph); - - realStats = new CoolStatsGraph(0, Std.int(FlxG.height / 3), Std.int(FlxG.width / 2), Std.int(FlxG.height / 3), FlxColor.YELLOW, "REAL"); - realStats.curLabel.y -= 32; - FlxG.addChildBelowMouse(realStats); - PreciseInputManager.instance.onInputPressed.add(function(event:PreciseInputEvent) { generateBeatStuff(event); strumLine.pressKey(event.noteDirection); @@ -112,19 +102,36 @@ class LatencyState extends MusicBeatSubState for (i in 0...8) { - var block = new FlxSprite(2, 50 * i).makeGraphic(48, 48); - block.alpha = 0; + var block = new FlxSprite(2, ((FlxG.height / 8) + 2) * i).makeGraphic(Std.int(FlxG.height / 8), Std.int((FlxG.height / 8) - 4)); + block.alpha = 0.1; blocks.add(block); } - offsetText = new FlxText(); - offsetText.size = 20; - offsetText.screenCenter(); - add(offsetText); + var strumlineBG:FlxSprite = new FlxSprite(); + add(strumlineBG); strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true); + strumLine.screenCenter(); add(strumLine); + strumlineBG.x = strumLine.x; + strumlineBG.makeGraphic(Std.int(strumLine.width), FlxG.height, 0xFFFFFFFF); + strumlineBG.alpha = 0.1; + + visualOffsetText = new FlxText(); + visualOffsetText.setFormat(Paths.font("vcr.ttf"), 20); + visualOffsetText.x = (FlxG.height / 8) + 10; + visualOffsetText.y = 10; + visualOffsetText.fieldWidth = strumLine.x - visualOffsetText.x - 10; + add(visualOffsetText); + + offsetText = new FlxText(); + offsetText.setFormat(Paths.font("vcr.ttf"), 20); + offsetText.x = strumLine.x + strumLine.width + 10; + offsetText.y = 10; + offsetText.fieldWidth = FlxG.width - offsetText.x - 10; + add(offsetText); + regenNoteData(); } @@ -152,7 +159,7 @@ class LatencyState extends MusicBeatSubState override function beatHit():Bool { if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> { - blok.alpha = 0; + blok.alpha = 0.1; }); blocks.members[Conductor.instance.currentBeat % 8].alpha = 1; @@ -170,19 +177,16 @@ class LatencyState extends MusicBeatSubState Conductor.instance.update(); - funnyStatsGraph.update(swagSong.getTimeWithDiff() % 500); - realStats.update(Conductor.instance.getTimeWithDiff() % 500); - // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; songPosVis.x = songPosToX(Conductor.instance.songPosition); songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset); songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset); - offsetText.text = "INST Offset (CTRL+Left/Right to change): " + Conductor.instance.instrumentalOffset + "ms"; - offsetText.text += "\nINPUT Offset (Left/Right to change): " + Conductor.instance.inputOffset + "ms"; - offsetText.text += "\ncurrentStep: " + Conductor.instance.currentStep; - offsetText.text += "\ncurrentBeat: " + Conductor.instance.currentBeat; + visualOffsetText.text = "Visual Offset: " + Conductor.instance.instrumentalOffset + "ms"; + visualOffsetText.text += "\nYou can press SPACE+Left/Right to change this value."; + + offsetText.text = "INPUT Offset (Left/Right to change): " + Conductor.instance.inputOffset + "ms"; var avgOffsetInput:Float = 0; @@ -191,7 +195,7 @@ class LatencyState extends MusicBeatSubState avgOffsetInput /= offsetsPerBeat.length; - offsetText.text += "\naverage input offset needed: " + avgOffsetInput; + offsetText.text += "\nEstimated average input offset needed: " + avgOffsetInput; var multiply:Int = 10; @@ -222,19 +226,6 @@ class LatencyState extends MusicBeatSubState } } - // noteGrp.forEach(function(daNote:NoteSprite) { - // daNote.y = (strumLine.y - ((Conductor.instance.songPosition - Conductor.instance.instrumentalOffset) - daNote.strumTime) * 0.45); - // daNote.x = strumLine.x + 30; - - // if (daNote.y < strumLine.y) daNote.alpha = 0.5; - - // if (daNote.y < 0 - daNote.height) - // { - // daNote.alpha = 1; - // // daNote.data.strumTime += Conductor.instance.beatLengthMs * 8; - // } - // }); - super.update(elapsed); } From 0145d7ed2d236dc759ba6ed7f214d7cbe6964766 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 12 Feb 2024 20:06:43 -0500 Subject: [PATCH 16/60] input offset edits in progress --- source/funkin/Conductor.hx | 9 +- source/funkin/play/PauseSubState.hx | 8 +- source/funkin/ui/debug/DebugMenuSubState.hx | 2 +- .../funkin/ui/debug/latency/LatencyState.hx | 93 ++++++++++++++----- 4 files changed, 85 insertions(+), 27 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 75031f6dd..8b2732a9a 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -8,6 +8,7 @@ import funkin.data.song.SongData.SongTimeChange; import funkin.data.song.SongDataUtils; import funkin.save.Save; import haxe.Timer; +import flixel.sound.FlxSound; /** * A core class which handles musical timing throughout the game, @@ -290,6 +291,8 @@ class Conductor // Take into account instrumental and file format song offsets. songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; } + else + songPos += instrumentalOffset + formatOffset; var oldMeasure = this.currentMeasure; var oldBeat = this.currentBeat; @@ -369,14 +372,16 @@ class Conductor * that can potentially get processed on exact milliseconds/timestmaps. * If you need song position, use `Conductor.instance.songPosition` instead * for use in update() related functions. + * @param soundToCheck Which FlxSound object to check, defaults to FlxG.sound.music if no input * @return Float */ - public function getTimeWithDiff():Float + public function getTimeWithDiff(?soundToCheck:FlxSound):Float { + if (soundToCheck == null) soundToCheck = FlxG.sound.music; // trace(this.songPosition); @:privateAccess - this.songPosition = FlxG.sound.music._channel.position; + this.songPosition = soundToCheck._channel.position; // return this.songPosition + (Std.int(Timer.stamp() * 1000) - prevTimestamp); // trace("\t--> " + this.songPosition); return this.songPosition; diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx index c9039ce40..62a4e3f4d 100644 --- a/source/funkin/play/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -5,6 +5,7 @@ import flixel.FlxSprite; import flixel.addons.transition.FlxTransitionableState; import flixel.group.FlxGroup.FlxTypedGroup; import funkin.ui.MusicBeatSubState; +import funkin.ui.debug.latency.LatencyState; import flixel.sound.FlxSound; import flixel.text.FlxText; import flixel.tweens.FlxEase; @@ -18,14 +19,16 @@ class PauseSubState extends MusicBeatSubState { var grpMenuShit:FlxTypedGroup; + // todo: maybe make these enums or somethin? final pauseOptionsBase:Array = [ 'Resume', 'Restart Song', 'Change Difficulty', 'Toggle Practice Mode', + 'Adjust Input Offsets', 'Exit to Menu' ]; - final pauseOptionsCharting:Array = ['Resume', 'Restart Song', 'Exit to Chart Editor']; + final pauseOptionsCharting:Array = ['Resume', 'Restart Song', 'Adjust Input Offsets', 'Exit to Chart Editor']; final pauseOptionsDifficultyBase:Array = ['BACK']; @@ -240,7 +243,8 @@ class PauseSubState extends MusicBeatSubState { openSubState(new funkin.ui.transition.StickerSubState(null, FREEPLAY)); } - + case 'Adjust Input Offsets': + openSubState(new LatencyState()); case 'Exit to Chart Editor': this.close(); if (FlxG.sound.music != null) FlxG.sound.music.pause(); // Don't reset song position! diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index f797dfbad..7e03b2d7a 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -95,7 +95,7 @@ class DebugMenuSubState extends MusicBeatSubState function openInputOffsetTesting() { - FlxG.switchState(new funkin.ui.debug.latency.LatencyState()); + openSubState(new funkin.ui.debug.latency.LatencyState()); trace('Input Offset Testing'); } diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 137ab77ee..6bba9200c 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -21,6 +21,7 @@ import funkin.data.notestyle.NoteStyleData; import funkin.data.notestyle.NoteStyleRegistry; import funkin.data.song.SongData.SongNoteData; import haxe.Timer; +import flixel.FlxCamera; class LatencyState extends MusicBeatSubState { @@ -38,30 +39,39 @@ class LatencyState extends MusicBeatSubState var beatTrail:FlxSprite; var diffGrp:FlxTypedGroup; var offsetsPerBeat:Array = []; - var swagSong:HomemadeMusic; + var swagSong:FlxSound; + + var previousVolume:Float; + + var stateCamera:FlxCamera; override function create() { super.create(); - if (FlxG.sound.music != null) FlxG.sound.music.stop(); + stateCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height); + stateCamera.bgColor = FlxColor.BLACK; + FlxG.cameras.add(stateCamera); - swagSong = new HomemadeMusic(); + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); + add(bg); + + if (FlxG.sound.music != null) + { + previousVolume = FlxG.sound.music.volume; + FlxG.sound.music.volume = 0; // only want to mute the volume, incase we are coming from pause menu + } + else + previousVolume = 1; // defaults to 1 if no music is playing 🤔 also fuck it, emoji in code comment + + swagSong = new FlxSound(); swagSong.loadEmbedded(Paths.sound('soundTest'), true); + swagSong.looped = true; + swagSong.play(); - FlxG.sound.music = swagSong; - FlxG.sound.music.play(); + PreciseInputManager.instance.onInputPressed.add(preciseInputPressed); - PreciseInputManager.instance.onInputPressed.add(function(event:PreciseInputEvent) { - generateBeatStuff(event); - strumLine.pressKey(event.noteDirection); - strumLine.playPress(event.noteDirection); - }); - - PreciseInputManager.instance.onInputReleased.add(function(event:PreciseInputEvent) { - strumLine.playStatic(event.noteDirection); - strumLine.releaseKey(event.noteDirection); - }); + PreciseInputManager.instance.onInputReleased.add(preciseInputReleased); Conductor.instance.forceBPM(60); @@ -70,7 +80,7 @@ class LatencyState extends MusicBeatSubState diffGrp = new FlxTypedGroup(); add(diffGrp); - for (beat in 0...Math.floor(FlxG.sound.music.length / (Conductor.instance.stepLengthMs * 2))) + for (beat in 0...Math.floor(swagSong.length / (Conductor.instance.stepLengthMs * 2))) { var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 15); beatTick.makeGraphic(2, 15); @@ -132,9 +142,43 @@ class LatencyState extends MusicBeatSubState offsetText.fieldWidth = FlxG.width - offsetText.x - 10; add(offsetText); + var helpText:FlxText = new FlxText(); + helpText.setFormat(Paths.font("vcr.ttf"), 20); + helpText.text = "Press ESC to return to main menu"; + helpText.x = FlxG.width - helpText.width; + helpText.y = FlxG.height - helpText.height - 2; + add(helpText); + regenNoteData(); } + function preciseInputPressed(event:PreciseInputEvent) + { + generateBeatStuff(event); + strumLine.pressKey(event.noteDirection); + strumLine.playPress(event.noteDirection); + } + + function preciseInputReleased(event:PreciseInputEvent) + { + strumLine.playStatic(event.noteDirection); + strumLine.releaseKey(event.noteDirection); + } + + override public function close():Void + { + PreciseInputManager.instance.onInputPressed.remove(preciseInputPressed); + + PreciseInputManager.instance.onInputReleased.remove(preciseInputReleased); + + FlxG.sound.music.volume = previousVolume; + swagSong.stop(); + + FlxG.cameras.remove(stateCamera); + + super.close(); + } + function regenNoteData() { for (i in 0...32) @@ -175,7 +219,7 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - Conductor.instance.update(); + Conductor.instance.update(swagSong.position); // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; @@ -226,6 +270,11 @@ class LatencyState extends MusicBeatSubState } } + if (FlxG.keys.justPressed.ESCAPE) + { + close(); + } + super.update(elapsed); } @@ -237,15 +286,15 @@ class LatencyState extends MusicBeatSubState trace("input latency: " + inputLatencyMs + "ms"); trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); trace("event timestamp: " + event.timestamp + "ns"); - trace("songtime: " + Conductor.instance.getTimeWithDiff() + "ms"); + trace("songtime: " + Conductor.instance.getTimeWithDiff(swagSong) + "ms"); - var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff() / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; - var getDiff:Float = Conductor.instance.getTimeWithDiff() - (closestBeat * (Conductor.instance.stepLengthMs * 2)); + var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff(swagSong) / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = Conductor.instance.getTimeWithDiff(swagSong) - (closestBeat * (Conductor.instance.stepLengthMs * 2)); // getDiff -= Conductor.instance.inputOffset; getDiff -= inputLatencyMs; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= FlxG.sound.music.length; + if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= swagSong.length; beatTrail.x = songPosVis.x; @@ -255,7 +304,7 @@ class LatencyState extends MusicBeatSubState function songPosToX(pos:Float):Float { - return FlxMath.remapToRange(pos, 0, FlxG.sound.music.length, 0, FlxG.width); + return FlxMath.remapToRange(pos, 0, swagSong.length, 0, FlxG.width); } } From 43ec35f5fd1c576226b965c99f5a3d00919408a3 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 12 Feb 2024 21:00:40 -0500 Subject: [PATCH 17/60] derp .position -> .time fix --- source/funkin/ui/debug/latency/LatencyState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 6bba9200c..aa186d6b3 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -219,7 +219,7 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - Conductor.instance.update(swagSong.position); + Conductor.instance.update(swagSong.time); // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; From 25766dbde9f939f2f6b2e5f5407ea019d6c5ccd7 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 12 Feb 2024 21:41:16 -0500 Subject: [PATCH 18/60] decoupling some stuff from Conductor.instance --- source/funkin/Conductor.hx | 4 +- source/funkin/play/notes/Strumline.hx | 28 +++++---- source/funkin/ui/MusicBeatState.hx | 5 +- source/funkin/ui/MusicBeatSubState.hx | 5 +- .../funkin/ui/debug/latency/LatencyState.hx | 63 +++++++++++-------- 5 files changed, 62 insertions(+), 43 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 8b2732a9a..dbfeb8621 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -284,7 +284,7 @@ class Conductor * @param songPosition The current position in the song in milliseconds. * Leave blank to use the FlxG.sound.music position. */ - public function update(?songPos:Float) + public function update(?songPos:Float, applyOffsets:Bool = true) { if (songPos == null) { @@ -292,7 +292,7 @@ class Conductor songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; } else - songPos += instrumentalOffset + formatOffset; + songPos += applyOffsets ? instrumentalOffset + formatOffset : 0; var oldMeasure = this.currentMeasure; var oldBeat = this.currentBeat; diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 057f05acb..4538696dc 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -41,6 +41,12 @@ class Strumline extends FlxSpriteGroup public var isPlayer:Bool; + /** + * Usually you want to keep this as is, but if you are using a Strumline and + * playing a sound that has it's own conductor, set this (LatencyState for example) + */ + public var conductorInUse:Conductor = Conductor.instance; + /** * The notes currently being rendered on the strumline. * This group iterates over this every frame to update note positions. @@ -158,7 +164,7 @@ class Strumline extends FlxSpriteGroup var hitWindowCenter = note.strumTime; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - if (Conductor.instance.songPosition > hitWindowEnd) + if (conductorInUse.songPosition > hitWindowEnd) { if (!isPlayer && note.hasMissed) continue; @@ -168,7 +174,7 @@ class Strumline extends FlxSpriteGroup if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; } - else if (Conductor.instance.songPosition > hitWindowCenter) + else if (conductorInUse.songPosition > hitWindowCenter) { // only run this on opponent strumlines! if (!isPlayer) continue; @@ -191,7 +197,7 @@ class Strumline extends FlxSpriteGroup playNoteHoldCover(note.holdNoteSprite); } } - else if (Conductor.instance.songPosition > hitWindowStart) + else if (conductorInUse.songPosition > hitWindowStart) { if (!isPlayer && (note.hasBeenHit || note.hasMissed)) continue; @@ -352,7 +358,7 @@ class Strumline extends FlxSpriteGroup * @param strumTime * @return Float */ - static function calculateNoteYPos(strumTime:Float, vwoosh:Bool = true):Float + public function calculateNoteYPos(strumTime:Float, vwoosh:Bool = true):Float { // Make the note move faster visually as it moves offscreen. // var vwoosh:Float = (strumTime < Conductor.songPosition) && vwoosh ? 2.0 : 1.0; @@ -360,7 +366,7 @@ class Strumline extends FlxSpriteGroup var vwoosh:Float = 1.0; var scrollSpeed:Float = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; - return Constants.PIXELS_PER_MS * (Conductor.instance.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); + return Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); } function updateNotes():Void @@ -368,8 +374,8 @@ class Strumline extends FlxSpriteGroup if (noteData.length == 0) return; var songStart:Float = PlayState.instance?.startTimestamp ?? 0.0; - var hitWindowStart:Float = Conductor.instance.songPosition - Constants.HIT_WINDOW_MS; - var renderWindowStart:Float = Conductor.instance.songPosition + RENDER_DISTANCE_MS; + var hitWindowStart:Float = conductorInUse.songPosition - Constants.HIT_WINDOW_MS; + var renderWindowStart:Float = conductorInUse.songPosition + RENDER_DISTANCE_MS; for (noteIndex in nextNoteIndex...noteData.length) { @@ -416,7 +422,7 @@ class Strumline extends FlxSpriteGroup { if (holdNote == null || !holdNote.alive) continue; - if (Conductor.instance.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) + if (conductorInUse.songPosition > holdNote.strumTime && holdNote.hitNote && !holdNote.missedNote) { if (isPlayer && !isKeyHeld(holdNote.noteDirection)) { @@ -430,7 +436,7 @@ class Strumline extends FlxSpriteGroup var renderWindowEnd = holdNote.strumTime + holdNote.fullSustainLength + Constants.HIT_WINDOW_MS + RENDER_DISTANCE_MS / 8; - if (holdNote.missedNote && Conductor.instance.songPosition >= renderWindowEnd) + if (holdNote.missedNote && conductorInUse.songPosition >= renderWindowEnd) { // Hold note is offscreen, kill it. holdNote.visible = false; @@ -476,13 +482,13 @@ class Strumline extends FlxSpriteGroup holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) + yOffset + STRUMLINE_SIZE / 2; } } - else if (Conductor.instance.songPosition > holdNote.strumTime && holdNote.hitNote) + else if (conductorInUse.songPosition > holdNote.strumTime && holdNote.hitNote) { // Hold note is currently being hit, clip it off. holdConfirm(holdNote.noteDirection); holdNote.visible = true; - holdNote.sustainLength = (holdNote.strumTime + holdNote.fullSustainLength) - Conductor.instance.songPosition; + holdNote.sustainLength = (holdNote.strumTime + holdNote.fullSustainLength) - conductorInUse.songPosition; if (holdNote.sustainLength <= 10) { diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 33333565f..4013258af 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -27,6 +27,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; + public var conductorInUse:Conductor = Conductor.instance; public function new() { @@ -125,7 +126,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function stepHit():Bool { - var event = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event = new SongTimeScriptEvent(SONG_STEP_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); @@ -136,7 +137,7 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public function beatHit():Bool { - var event = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event = new SongTimeScriptEvent(SONG_BEAT_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 0fa55c234..dc2958b91 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -20,6 +20,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl { public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; + public var conductorInUse:Conductor = Conductor.instance; public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) { @@ -95,7 +96,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function stepHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_STEP_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); @@ -111,7 +112,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl */ public function beatHit():Bool { - var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, Conductor.instance.currentBeat, Conductor.instance.currentStep); + var event:ScriptEvent = new SongTimeScriptEvent(SONG_BEAT_HIT, conductorInUse.currentBeat, conductorInUse.currentStep); dispatchEvent(event); diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index aa186d6b3..0f396c972 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -45,10 +45,18 @@ class LatencyState extends MusicBeatSubState var stateCamera:FlxCamera; + /** + * A local conductor instance for this testing class, in-case we are in a PlayState + * because I'm too lazy to set the old variables for conductor stuff ! + */ + var localConductor:Conductor; + override function create() { super.create(); + localConductor = new Conductor(); + stateCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height); stateCamera.bgColor = FlxColor.BLACK; FlxG.cameras.add(stateCamera); @@ -68,26 +76,27 @@ class LatencyState extends MusicBeatSubState swagSong.loadEmbedded(Paths.sound('soundTest'), true); swagSong.looped = true; swagSong.play(); + FlxG.sound.list.add(swagSong); PreciseInputManager.instance.onInputPressed.add(preciseInputPressed); PreciseInputManager.instance.onInputReleased.add(preciseInputReleased); - Conductor.instance.forceBPM(60); + localConductor.forceBPM(60); noteGrp = []; diffGrp = new FlxTypedGroup(); add(diffGrp); - for (beat in 0...Math.floor(swagSong.length / (Conductor.instance.stepLengthMs * 2))) + for (beat in 0...Math.floor(swagSong.length / (localConductor.stepLengthMs * 2))) { - var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 15); + var beatTick:FlxSprite = new FlxSprite(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 15); beatTick.makeGraphic(2, 15); beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * (Conductor.instance.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -121,6 +130,7 @@ class LatencyState extends MusicBeatSubState add(strumlineBG); strumLine = new Strumline(NoteStyleRegistry.instance.fetchDefault(), true); + strumLine.conductorInUse = localConductor; strumLine.screenCenter(); add(strumLine); @@ -173,6 +183,7 @@ class LatencyState extends MusicBeatSubState FlxG.sound.music.volume = previousVolume; swagSong.stop(); + FlxG.sound.list.remove(swagSong); FlxG.cameras.remove(stateCamera); @@ -183,7 +194,7 @@ class LatencyState extends MusicBeatSubState { for (i in 0...32) { - var note:SongNoteData = new SongNoteData((Conductor.instance.stepLengthMs * 2) * i, 1); + var note:SongNoteData = new SongNoteData((localConductor.stepLengthMs * 2) * i, 1); noteGrp.push(note); } @@ -192,9 +203,9 @@ class LatencyState extends MusicBeatSubState override function stepHit():Bool { - if (Conductor.instance.currentStep % 4 == 2) + if (localConductor.currentStep % 4 == 2) { - blocks.members[((Conductor.instance.currentBeat % 8) + 1) % 8].alpha = 0.5; + blocks.members[((localConductor.currentBeat % 8) + 1) % 8].alpha = 0.5; } return super.stepHit(); @@ -202,11 +213,11 @@ class LatencyState extends MusicBeatSubState override function beatHit():Bool { - if (Conductor.instance.currentBeat % 8 == 0) blocks.forEach(blok -> { + if (localConductor.currentBeat % 8 == 0) blocks.forEach(blok -> { blok.alpha = 0.1; }); - blocks.members[Conductor.instance.currentBeat % 8].alpha = 1; + blocks.members[localConductor.currentBeat % 8].alpha = 1; // block.visible = !block.visible; return super.beatHit(); @@ -219,18 +230,18 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - Conductor.instance.update(swagSong.time); + localConductor.update(swagSong.time, false); - // Conductor.instance.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; + // localConductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; - songPosVis.x = songPosToX(Conductor.instance.songPosition); - songVisFollowAudio.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.instrumentalOffset); - songVisFollowVideo.x = songPosToX(Conductor.instance.songPosition - Conductor.instance.inputOffset); + songPosVis.x = songPosToX(localConductor.songPosition); + songVisFollowAudio.x = songPosToX(localConductor.songPosition - localConductor.instrumentalOffset); + songVisFollowVideo.x = songPosToX(localConductor.songPosition - localConductor.inputOffset); - visualOffsetText.text = "Visual Offset: " + Conductor.instance.instrumentalOffset + "ms"; + visualOffsetText.text = "Visual Offset: " + localConductor.instrumentalOffset + "ms"; visualOffsetText.text += "\nYou can press SPACE+Left/Right to change this value."; - offsetText.text = "INPUT Offset (Left/Right to change): " + Conductor.instance.inputOffset + "ms"; + offsetText.text = "INPUT Offset (Left/Right to change): " + localConductor.inputOffset + "ms"; var avgOffsetInput:Float = 0; @@ -249,24 +260,24 @@ class LatencyState extends MusicBeatSubState { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.instrumentalOffset += 1 * multiply; + localConductor.instrumentalOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.instrumentalOffset -= 1 * multiply; + localConductor.instrumentalOffset -= 1 * multiply; } } else { if (FlxG.keys.justPressed.RIGHT) { - Conductor.instance.inputOffset += 1 * multiply; + localConductor.inputOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - Conductor.instance.inputOffset -= 1 * multiply; + localConductor.inputOffset -= 1 * multiply; } } @@ -280,21 +291,21 @@ class LatencyState extends MusicBeatSubState function generateBeatStuff(event:PreciseInputEvent) { - // Conductor.instance.update(swagSong.getTimeWithDiff()); + // localConductor.update(swagSong.getTimeWithDiff()); var inputLatencyMs:Float = haxe.Int64.toInt(PreciseInputManager.getCurrentTimestamp() - event.timestamp) / 1000.0 / 1000.0; trace("input latency: " + inputLatencyMs + "ms"); trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); trace("event timestamp: " + event.timestamp + "ns"); - trace("songtime: " + Conductor.instance.getTimeWithDiff(swagSong) + "ms"); + trace("songtime: " + localConductor.getTimeWithDiff(swagSong) + "ms"); - var closestBeat:Int = Math.round(Conductor.instance.getTimeWithDiff(swagSong) / (Conductor.instance.stepLengthMs * 2)) % diffGrp.members.length; - var getDiff:Float = Conductor.instance.getTimeWithDiff(swagSong) - (closestBeat * (Conductor.instance.stepLengthMs * 2)); - // getDiff -= Conductor.instance.inputOffset; + var closestBeat:Int = Math.round(localConductor.getTimeWithDiff(swagSong) / (localConductor.stepLengthMs * 2)) % diffGrp.members.length; + var getDiff:Float = localConductor.getTimeWithDiff(swagSong) - (closestBeat * (localConductor.stepLengthMs * 2)); + // getDiff -= localConductor.inputOffset; getDiff -= inputLatencyMs; // lil fix for end of song - if (closestBeat == 0 && getDiff >= Conductor.instance.stepLengthMs * 2) getDiff -= swagSong.length; + if (closestBeat == 0 && getDiff >= localConductor.stepLengthMs * 2) getDiff -= swagSong.length; beatTrail.x = songPosVis.x; From e759f901478c982c6a90e7c5cceb10265e5546dd Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 12 Feb 2024 22:14:35 -0500 Subject: [PATCH 19/60] audioVisualOffset numbers --- source/funkin/Conductor.hx | 45 ++++++++++++++----- .../funkin/ui/debug/latency/LatencyState.hx | 18 ++++---- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index dbfeb8621..b30d405fa 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -217,6 +217,11 @@ class Conductor */ public var inputOffset(get, set):Int; + /** + * An offset set by the user to compensate for audio/visual lag + */ + public var audioVisualOffset(get, set):Int; + function get_inputOffset():Int { return Save.get().options.inputOffset; @@ -229,6 +234,18 @@ class Conductor return Save.get().options.inputOffset; } + function get_audioVisualOffset():Int + { + return Save.get().options.audioVisualOffset; + } + + function set_audioVisualOffset(value:Int):Int + { + Save.get().options.audioVisualOffset = value; + Save.get().flush(); + return Save.get().options.audioVisualOffset; + } + /** * The number of beats in a measure. May be fractional depending on the time signature. */ @@ -283,16 +300,17 @@ class Conductor * * @param songPosition The current position in the song in milliseconds. * Leave blank to use the FlxG.sound.music position. + * @param applyOffsets If it should apply the instrumentalOffset + formatOffset + audioVisualOffset */ - public function update(?songPos:Float, applyOffsets:Bool = true) + public function update(?songPos:Float, applyOffsets:Bool = true, forceDispatch:Bool = false) { if (songPos == null) { // Take into account instrumental and file format song offsets. - songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset) : 0.0; + songPos = (FlxG.sound.music != null) ? (FlxG.sound.music.time + instrumentalOffset + formatOffset + audioVisualOffset) : 0.0; } else - songPos += applyOffsets ? instrumentalOffset + formatOffset : 0; + songPos += applyOffsets ? instrumentalOffset + formatOffset + audioVisualOffset : 0; var oldMeasure = this.currentMeasure; var oldBeat = this.currentBeat; @@ -338,7 +356,7 @@ class Conductor } // Only fire the signal if we are THE Conductor. - if (this == Conductor.instance) + if (this == Conductor.instance || forceDispatch) { // FlxSignals are really cool. if (currentStep != oldStep) @@ -428,7 +446,7 @@ class Conductor } // Update currentStepTime - this.update(Conductor.instance.songPosition); + this.update(this.songPosition, false); } /** @@ -540,13 +558,18 @@ class Conductor } } - public static function watchQuick():Void + /** + * @param conductorToUse defaults to Conductor.instance if null + */ + public static function watchQuick(?conductorToUse:Conductor):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); + if (conductorToUse == null) conductorToUse = Conductor.instance; + + FlxG.watch.addQuick("songPosition", conductorToUse.songPosition); + FlxG.watch.addQuick("bpm", conductorToUse.bpm); + FlxG.watch.addQuick("currentMeasureTime", conductorToUse.currentMeasureTime); + FlxG.watch.addQuick("currentBeatTime", conductorToUse.currentBeatTime); + FlxG.watch.addQuick("currentStepTime", conductorToUse.currentStepTime); } /** diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 0f396c972..4e9b83f2e 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -230,15 +230,15 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - localConductor.update(swagSong.time, false); + localConductor.update(swagSong.time, false, true); // localConductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; songPosVis.x = songPosToX(localConductor.songPosition); - songVisFollowAudio.x = songPosToX(localConductor.songPosition - localConductor.instrumentalOffset); + songVisFollowAudio.x = songPosToX(localConductor.songPosition - localConductor.audioVisualOffset); songVisFollowVideo.x = songPosToX(localConductor.songPosition - localConductor.inputOffset); - visualOffsetText.text = "Visual Offset: " + localConductor.instrumentalOffset + "ms"; + visualOffsetText.text = "Visual Offset: " + localConductor.audioVisualOffset + "ms"; visualOffsetText.text += "\nYou can press SPACE+Left/Right to change this value."; offsetText.text = "INPUT Offset (Left/Right to change): " + localConductor.inputOffset + "ms"; @@ -260,12 +260,12 @@ class LatencyState extends MusicBeatSubState { if (FlxG.keys.justPressed.RIGHT) { - localConductor.instrumentalOffset += 1 * multiply; + localConductor.audioVisualOffset += 1 * multiply; } if (FlxG.keys.justPressed.LEFT) { - localConductor.instrumentalOffset -= 1 * multiply; + localConductor.audioVisualOffset -= 1 * multiply; } } else @@ -294,10 +294,10 @@ class LatencyState extends MusicBeatSubState // localConductor.update(swagSong.getTimeWithDiff()); var inputLatencyMs:Float = haxe.Int64.toInt(PreciseInputManager.getCurrentTimestamp() - event.timestamp) / 1000.0 / 1000.0; - trace("input latency: " + inputLatencyMs + "ms"); - trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); - trace("event timestamp: " + event.timestamp + "ns"); - trace("songtime: " + localConductor.getTimeWithDiff(swagSong) + "ms"); + // trace("input latency: " + inputLatencyMs + "ms"); + // trace("cur timestamp: " + PreciseInputManager.getCurrentTimestamp() + "ns"); + // trace("event timestamp: " + event.timestamp + "ns"); + // trace("songtime: " + localConductor.getTimeWithDiff(swagSong) + "ms"); var closestBeat:Int = Math.round(localConductor.getTimeWithDiff(swagSong) / (localConductor.stepLengthMs * 2)) % diffGrp.members.length; var getDiff:Float = localConductor.getTimeWithDiff(swagSong) - (closestBeat * (localConductor.stepLengthMs * 2)); From 58077b4505cae8b4575635d390f28b731f4b52eb Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 12 Feb 2024 22:44:59 -0500 Subject: [PATCH 20/60] more working audio offset in progress --- source/funkin/Conductor.hx | 4 ++++ source/funkin/ui/MusicBeatSubState.hx | 2 +- source/funkin/ui/debug/latency/LatencyState.hx | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index b30d405fa..4b1b89dfa 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -214,11 +214,15 @@ class Conductor /** * An offset set by the user to compensate for input lag. + * No matter if you're using a local conductor or not, this always loads + * to/from the save file */ public var inputOffset(get, set):Int; /** * An offset set by the user to compensate for audio/visual lag + * No matter if you're using a local conductor or not, this always loads + * to/from the save file */ public var audioVisualOffset(get, set):Int; diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index dc2958b91..f93fbce0a 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -67,7 +67,7 @@ class MusicBeatSubState extends FlxTransitionableSubState implements IEventHandl // Display Conductor info in the watch window. FlxG.watch.addQuick("musicTime", FlxG.sound.music?.time ?? 0.0); - Conductor.watchQuick(); + Conductor.watchQuick(conductorInUse); dispatchEvent(new UpdateScriptEvent(elapsed)); } diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 4e9b83f2e..9cce4ca23 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -56,6 +56,7 @@ class LatencyState extends MusicBeatSubState super.create(); localConductor = new Conductor(); + conductorInUse = localConductor; stateCamera = new FlxCamera(0, 0, FlxG.width, FlxG.height); stateCamera.bgColor = FlxColor.BLACK; @@ -239,9 +240,11 @@ class LatencyState extends MusicBeatSubState songVisFollowVideo.x = songPosToX(localConductor.songPosition - localConductor.inputOffset); visualOffsetText.text = "Visual Offset: " + localConductor.audioVisualOffset + "ms"; - visualOffsetText.text += "\nYou can press SPACE+Left/Right to change this value."; + visualOffsetText.text += "\n\nYou can press SPACE+Left/Right to change this value."; + visualOffsetText.text += "\n\nYou can hold SHIFT to step 1ms at a time"; offsetText.text = "INPUT Offset (Left/Right to change): " + localConductor.inputOffset + "ms"; + offsetText.text += "\n\nYou can hold SHIFT to step 1ms at a time"; var avgOffsetInput:Float = 0; @@ -250,7 +253,7 @@ class LatencyState extends MusicBeatSubState avgOffsetInput /= offsetsPerBeat.length; - offsetText.text += "\nEstimated average input offset needed: " + avgOffsetInput; + offsetText.text += "\n\nEstimated average input offset needed: " + avgOffsetInput; var multiply:Int = 10; @@ -303,6 +306,7 @@ class LatencyState extends MusicBeatSubState var getDiff:Float = localConductor.getTimeWithDiff(swagSong) - (closestBeat * (localConductor.stepLengthMs * 2)); // getDiff -= localConductor.inputOffset; getDiff -= inputLatencyMs; + getDiff -= localConductor.audioVisualOffset; // lil fix for end of song if (closestBeat == 0 && getDiff >= localConductor.stepLengthMs * 2) getDiff -= swagSong.length; From 96d27c271ae2646bf1089beda4e7f9814b157000 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 14 Feb 2024 08:29:38 -0500 Subject: [PATCH 21/60] avg offset better calc --- source/funkin/ui/debug/latency/LatencyState.hx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 9cce4ca23..0d486fca1 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -38,7 +38,7 @@ class LatencyState extends MusicBeatSubState var beatTrail:FlxSprite; var diffGrp:FlxTypedGroup; - var offsetsPerBeat:Array = []; + var offsetsPerBeat:Array> = []; var swagSong:FlxSound; var previousVolume:Float; @@ -101,7 +101,7 @@ class LatencyState extends MusicBeatSubState offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); - offsetsPerBeat.push(0); + offsetsPerBeat.push(null); } songVisFollowAudio = new FlxSprite(0, FlxG.height - 20).makeGraphic(2, 20, FlxColor.YELLOW); @@ -248,10 +248,15 @@ class LatencyState extends MusicBeatSubState var avgOffsetInput:Float = 0; + var loopInd:Int = 0; for (offsetThing in offsetsPerBeat) + { + if (offsetThing == null) continue; avgOffsetInput += offsetThing; + loopInd++; + } - avgOffsetInput /= offsetsPerBeat.length; + avgOffsetInput /= loopInd; offsetText.text += "\n\nEstimated average input offset needed: " + avgOffsetInput; From 638c1666633cddd73398efbb2ccc6cb0bf59aa3d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 15 Feb 2024 04:10:48 -0500 Subject: [PATCH 22/60] optimization when opening from pause menu --- source/funkin/ui/debug/latency/LatencyState.hx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 0d486fca1..282f05651 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -51,10 +51,21 @@ class LatencyState extends MusicBeatSubState */ var localConductor:Conductor; + // stores values of what the previous persistent draw/update stuff was, example if opened + // from pause menu, we want to NOT draw persistently, but then resume drawing once closed + var prevPersistentDraw:Bool; + var prevPersistentUpdate:Bool; + override function create() { super.create(); + prevPersistentDraw = FlxG.state.persistentDraw; + prevPersistentUpdate = FlxG.state.persistentUpdate; + + FlxG.state.persistentDraw = false; + FlxG.state.persistentUpdate = false; + localConductor = new Conductor(); conductorInUse = localConductor; @@ -179,7 +190,6 @@ class LatencyState extends MusicBeatSubState override public function close():Void { PreciseInputManager.instance.onInputPressed.remove(preciseInputPressed); - PreciseInputManager.instance.onInputReleased.remove(preciseInputReleased); FlxG.sound.music.volume = previousVolume; @@ -188,6 +198,8 @@ class LatencyState extends MusicBeatSubState FlxG.cameras.remove(stateCamera); + FlxG.state.persistentDraw = prevPersistentDraw; + FlxG.state.persistentUpdate = prevPersistentUpdate; super.close(); } From 94732c1190c634a65ef7425669ad8f62f74a4e72 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 19 Feb 2024 20:33:48 -0500 Subject: [PATCH 23/60] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 75ac8ec25..e76470d66 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 75ac8ec2564c9a56e8282b0853091ecd8b4f2dfd +Subproject commit e76470d66794bf3796f7ace84f2121b698e37a30 From 63a49010ba0d88d591b37b9513737b6b2f590056 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 19 Feb 2024 20:56:57 -0500 Subject: [PATCH 24/60] positioning and average reset --- .../funkin/ui/debug/latency/LatencyState.hx | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 282f05651..480338e46 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -108,7 +108,7 @@ class LatencyState extends MusicBeatSubState beatTick.alpha = 0.3; add(beatTick); - var offsetTxt:FlxText = new FlxText(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 26, 0, "swag"); + var offsetTxt:FlxText = new FlxText(songPosToX(beat * (localConductor.stepLengthMs * 2)), FlxG.height - 26, 0, ""); offsetTxt.alpha = 0.5; diffGrp.add(offsetTxt); @@ -168,7 +168,7 @@ class LatencyState extends MusicBeatSubState helpText.setFormat(Paths.font("vcr.ttf"), 20); helpText.text = "Press ESC to return to main menu"; helpText.x = FlxG.width - helpText.width; - helpText.y = FlxG.height - helpText.height - 2; + helpText.y = FlxG.height - (helpText.height * 2) - 2; add(helpText); regenNoteData(); @@ -290,14 +290,22 @@ class LatencyState extends MusicBeatSubState } else { - if (FlxG.keys.justPressed.RIGHT) + if (FlxG.keys.anyJustPressed([LEFT, RIGHT])) { - localConductor.inputOffset += 1 * multiply; - } + if (FlxG.keys.justPressed.RIGHT) + { + localConductor.inputOffset += 1 * multiply; + } - if (FlxG.keys.justPressed.LEFT) - { - localConductor.inputOffset -= 1 * multiply; + if (FlxG.keys.justPressed.LEFT) + { + localConductor.inputOffset -= 1 * multiply; + } + + // reset the average, so you don't need to wait a full loop to start getting averages + // also reset each text member + offsetsPerBeat = []; + diffGrp.forEach(memb -> memb.text = ""); } } From e87a31368ac19c8cc1f1622b65266b6c19cf98c7 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 19 Feb 2024 21:03:50 -0500 Subject: [PATCH 25/60] update lime to version with ndll files --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index f45340855..dbb9d646e 100644 --- a/hmm.json +++ b/hmm.json @@ -104,7 +104,7 @@ "name": "lime", "type": "git", "dir": null, - "ref": "6c92c7e", + "ref": "90e6727a8127e016f1071ace045b5c6542ded099", "url": "https://github.com/FunkinCrew/lime" }, { From dc638a130371206407f7e4e0db4a69f599bb6ec3 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sat, 23 Mar 2024 15:34:37 -0400 Subject: [PATCH 26/60] Fix a bunch of merge bugs. --- source/funkin/Conductor.hx | 16 +-- source/funkin/InitState.hx | 12 +- source/funkin/data/DataParse.hx | 4 +- source/funkin/data/conversation/TODO.md | 0 source/funkin/data/dialogue/TODO.md | 0 .../data/dialogue/conversation/CHANGELOG.md | 9 ++ .../{ => conversation}/ConversationData.hx | 2 +- .../ConversationRegistry.hx | 4 +- .../data/dialogue/dialoguebox/CHANGELOG.md | 13 ++ .../{ => dialoguebox}/DialogueBoxData.hx | 2 +- .../{ => dialoguebox}/DialogueBoxRegistry.hx | 4 +- .../funkin/data/dialogue/speaker/CHANGELOG.md | 9 ++ .../dialogue/{ => speaker}/SpeakerData.hx | 2 +- .../dialogue/{ => speaker}/SpeakerRegistry.hx | 4 +- .../data/freeplay/{ => album}/AlbumData.hx | 2 +- .../freeplay/{ => album}/AlbumRegistry.hx | 4 +- .../funkin/data/freeplay/album/CHANGELOG.md | 9 ++ source/funkin/data/song/CHANGELOG.md | 36 +++++ source/funkin/data/speaker/TODO.md | 0 source/funkin/data/stage/CHANGELOG.md | 14 ++ source/funkin/data/stage/StageRegistry.hx | 2 +- source/funkin/data/story/level/CHANGELOG.md | 9 ++ .../data/{ => story}/level/LevelData.hx | 4 +- .../data/{ => story}/level/LevelRegistry.hx | 4 +- source/funkin/modding/PolymodHandler.hx | 10 +- source/funkin/play/PlayState.hx | 10 +- .../play/cutscene/dialogue/Conversation.hx | 14 +- .../play/cutscene/dialogue/DialogueBox.hx | 4 +- .../funkin/play/cutscene/dialogue/Speaker.hx | 4 +- source/funkin/play/notes/Strumline.hx | 133 +++--------------- source/funkin/ui/MusicBeatState.hx | 16 ++- source/funkin/ui/MusicBeatSubState.hx | 7 +- .../debug/dialogue/ConversationDebugState.hx | 14 +- source/funkin/ui/freeplay/Album.hx | 4 +- source/funkin/ui/freeplay/AlbumRoll.hx | 2 +- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- source/funkin/ui/options/OptionsState.hx | 4 + source/funkin/ui/story/Level.hx | 4 +- source/funkin/ui/story/LevelProp.hx | 2 +- source/funkin/ui/story/StoryMenuState.hx | 2 +- 40 files changed, 216 insertions(+), 181 deletions(-) delete mode 100644 source/funkin/data/conversation/TODO.md delete mode 100644 source/funkin/data/dialogue/TODO.md create mode 100644 source/funkin/data/dialogue/conversation/CHANGELOG.md rename source/funkin/data/dialogue/{ => conversation}/ConversationData.hx (98%) rename source/funkin/data/dialogue/{ => conversation}/ConversationRegistry.hx (95%) create mode 100644 source/funkin/data/dialogue/dialoguebox/CHANGELOG.md rename source/funkin/data/dialogue/{ => dialoguebox}/DialogueBoxData.hx (98%) rename source/funkin/data/dialogue/{ => dialoguebox}/DialogueBoxRegistry.hx (95%) create mode 100644 source/funkin/data/dialogue/speaker/CHANGELOG.md rename source/funkin/data/dialogue/{ => speaker}/SpeakerData.hx (97%) rename source/funkin/data/dialogue/{ => speaker}/SpeakerRegistry.hx (96%) rename source/funkin/data/freeplay/{ => album}/AlbumData.hx (95%) rename source/funkin/data/freeplay/{ => album}/AlbumRegistry.hx (96%) create mode 100644 source/funkin/data/freeplay/album/CHANGELOG.md create mode 100644 source/funkin/data/song/CHANGELOG.md delete mode 100644 source/funkin/data/speaker/TODO.md create mode 100644 source/funkin/data/stage/CHANGELOG.md create mode 100644 source/funkin/data/story/level/CHANGELOG.md rename source/funkin/data/{ => story}/level/LevelData.hx (95%) rename source/funkin/data/{ => story}/level/LevelRegistry.hx (97%) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index aba154814..5b207c045 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -233,26 +233,26 @@ class Conductor function get_inputOffset():Int { - return Save.get().options.inputOffset; + return Save.instance.options.inputOffset; } function set_inputOffset(value:Int):Int { - Save.get().options.inputOffset = value; - Save.get().flush(); - return Save.get().options.inputOffset; + Save.instance.options.inputOffset = value; + Save.instance.flush(); + return Save.instance.options.inputOffset; } function get_audioVisualOffset():Int { - return Save.get().options.audioVisualOffset; + return Save.instance.options.audioVisualOffset; } function set_audioVisualOffset(value:Int):Int { - Save.get().options.audioVisualOffset = value; - Save.get().flush(); - return Save.get().options.audioVisualOffset; + Save.instance.options.audioVisualOffset = value; + Save.instance.flush(); + return Save.instance.options.audioVisualOffset; } /** diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 6ea77ec18..59c19d6ce 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -16,14 +16,14 @@ import funkin.util.macro.MacroUtil; import funkin.util.WindowUtil; import funkin.play.PlayStatePlaylist; import openfl.display.BitmapData; -import funkin.data.level.LevelRegistry; +import funkin.data.story.level.LevelRegistry; import funkin.data.notestyle.NoteStyleRegistry; import funkin.data.event.SongEventRegistry; import funkin.data.stage.StageRegistry; -import funkin.data.dialogue.ConversationRegistry; -import funkin.data.dialogue.DialogueBoxRegistry; -import funkin.data.dialogue.SpeakerRegistry; -import funkin.data.freeplay.AlbumRegistry; +import funkin.data.dialogue.conversation.ConversationRegistry; +import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry; +import funkin.data.dialogue.speaker.SpeakerRegistry; +import funkin.data.freeplay.album.AlbumRegistry; import funkin.data.song.SongRegistry; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.modding.module.ModuleHandler; @@ -275,7 +275,7 @@ class InitState extends FlxState */ function startLevel(levelId:String, difficultyId:String = 'normal'):Void { - var currentLevel:funkin.ui.story.Level = funkin.data.level.LevelRegistry.instance.fetchEntry(levelId); + var currentLevel:funkin.ui.story.Level = funkin.data.story.level.LevelRegistry.instance.fetchEntry(levelId); if (currentLevel == null) { diff --git a/source/funkin/data/DataParse.hx b/source/funkin/data/DataParse.hx index 244d41132..472ffd6e7 100644 --- a/source/funkin/data/DataParse.hx +++ b/source/funkin/data/DataParse.hx @@ -120,7 +120,7 @@ class DataParse } } - public static function backdropData(json:Json, name:String):funkin.data.dialogue.ConversationData.BackdropData + public static function backdropData(json:Json, name:String):funkin.data.dialogue.conversation.ConversationData.BackdropData { switch (json.value) { @@ -152,7 +152,7 @@ class DataParse } } - public static function outroData(json:Json, name:String):Null + public static function outroData(json:Json, name:String):Null { switch (json.value) { diff --git a/source/funkin/data/conversation/TODO.md b/source/funkin/data/conversation/TODO.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/funkin/data/dialogue/TODO.md b/source/funkin/data/dialogue/TODO.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/funkin/data/dialogue/conversation/CHANGELOG.md b/source/funkin/data/dialogue/conversation/CHANGELOG.md new file mode 100644 index 000000000..f9ab99fab --- /dev/null +++ b/source/funkin/data/dialogue/conversation/CHANGELOG.md @@ -0,0 +1,9 @@ +# Dialogue Conversation Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/dialogue/ConversationData.hx b/source/funkin/data/dialogue/conversation/ConversationData.hx similarity index 98% rename from source/funkin/data/dialogue/ConversationData.hx rename to source/funkin/data/dialogue/conversation/ConversationData.hx index 795ddae9a..30e3f451b 100644 --- a/source/funkin/data/dialogue/ConversationData.hx +++ b/source/funkin/data/dialogue/conversation/ConversationData.hx @@ -1,4 +1,4 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.conversation; import funkin.data.animation.AnimationData; diff --git a/source/funkin/data/dialogue/ConversationRegistry.hx b/source/funkin/data/dialogue/conversation/ConversationRegistry.hx similarity index 95% rename from source/funkin/data/dialogue/ConversationRegistry.hx rename to source/funkin/data/dialogue/conversation/ConversationRegistry.hx index 9186ef786..e64d62831 100644 --- a/source/funkin/data/dialogue/ConversationRegistry.hx +++ b/source/funkin/data/dialogue/conversation/ConversationRegistry.hx @@ -1,7 +1,7 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.conversation; import funkin.play.cutscene.dialogue.Conversation; -import funkin.data.dialogue.ConversationData; +import funkin.data.dialogue.conversation.ConversationData; import funkin.play.cutscene.dialogue.ScriptedConversation; class ConversationRegistry extends BaseRegistry diff --git a/source/funkin/data/dialogue/dialoguebox/CHANGELOG.md b/source/funkin/data/dialogue/dialoguebox/CHANGELOG.md new file mode 100644 index 000000000..06604734a --- /dev/null +++ b/source/funkin/data/dialogue/dialoguebox/CHANGELOG.md @@ -0,0 +1,13 @@ +# Dialogue Box Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.0] +### Added +- Added an option to specify the font used by the dialogue box. Defaults to `Arial` if unspecified. + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/dialogue/DialogueBoxData.hx b/source/funkin/data/dialogue/dialoguebox/DialogueBoxData.hx similarity index 98% rename from source/funkin/data/dialogue/DialogueBoxData.hx rename to source/funkin/data/dialogue/dialoguebox/DialogueBoxData.hx index a75a5595a..228d391c8 100644 --- a/source/funkin/data/dialogue/DialogueBoxData.hx +++ b/source/funkin/data/dialogue/dialoguebox/DialogueBoxData.hx @@ -1,4 +1,4 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.dialoguebox; import funkin.data.animation.AnimationData; diff --git a/source/funkin/data/dialogue/DialogueBoxRegistry.hx b/source/funkin/data/dialogue/dialoguebox/DialogueBoxRegistry.hx similarity index 95% rename from source/funkin/data/dialogue/DialogueBoxRegistry.hx rename to source/funkin/data/dialogue/dialoguebox/DialogueBoxRegistry.hx index 87205d96c..ec0feeaae 100644 --- a/source/funkin/data/dialogue/DialogueBoxRegistry.hx +++ b/source/funkin/data/dialogue/dialoguebox/DialogueBoxRegistry.hx @@ -1,7 +1,7 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.dialoguebox; import funkin.play.cutscene.dialogue.DialogueBox; -import funkin.data.dialogue.DialogueBoxData; +import funkin.data.dialogue.dialoguebox.DialogueBoxData; import funkin.play.cutscene.dialogue.ScriptedDialogueBox; class DialogueBoxRegistry extends BaseRegistry diff --git a/source/funkin/data/dialogue/speaker/CHANGELOG.md b/source/funkin/data/dialogue/speaker/CHANGELOG.md new file mode 100644 index 000000000..284e690e1 --- /dev/null +++ b/source/funkin/data/dialogue/speaker/CHANGELOG.md @@ -0,0 +1,9 @@ +# Dialogue Speaker Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/dialogue/SpeakerData.hx b/source/funkin/data/dialogue/speaker/SpeakerData.hx similarity index 97% rename from source/funkin/data/dialogue/SpeakerData.hx rename to source/funkin/data/dialogue/speaker/SpeakerData.hx index e8a2eacf0..458f91cab 100644 --- a/source/funkin/data/dialogue/SpeakerData.hx +++ b/source/funkin/data/dialogue/speaker/SpeakerData.hx @@ -1,4 +1,4 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.speaker; import funkin.data.animation.AnimationData; diff --git a/source/funkin/data/dialogue/SpeakerRegistry.hx b/source/funkin/data/dialogue/speaker/SpeakerRegistry.hx similarity index 96% rename from source/funkin/data/dialogue/SpeakerRegistry.hx rename to source/funkin/data/dialogue/speaker/SpeakerRegistry.hx index 6bd301dd7..7db501d41 100644 --- a/source/funkin/data/dialogue/SpeakerRegistry.hx +++ b/source/funkin/data/dialogue/speaker/SpeakerRegistry.hx @@ -1,7 +1,7 @@ -package funkin.data.dialogue; +package funkin.data.dialogue.speaker; import funkin.play.cutscene.dialogue.Speaker; -import funkin.data.dialogue.SpeakerData; +import funkin.data.dialogue.speaker.SpeakerData; import funkin.play.cutscene.dialogue.ScriptedSpeaker; class SpeakerRegistry extends BaseRegistry diff --git a/source/funkin/data/freeplay/AlbumData.hx b/source/funkin/data/freeplay/album/AlbumData.hx similarity index 95% rename from source/funkin/data/freeplay/AlbumData.hx rename to source/funkin/data/freeplay/album/AlbumData.hx index 265a01fce..bb6ca4f00 100644 --- a/source/funkin/data/freeplay/AlbumData.hx +++ b/source/funkin/data/freeplay/album/AlbumData.hx @@ -1,4 +1,4 @@ -package funkin.data.freeplay; +package funkin.data.freeplay.album; /** * A type definition for the data for an album of songs. diff --git a/source/funkin/data/freeplay/AlbumRegistry.hx b/source/funkin/data/freeplay/album/AlbumRegistry.hx similarity index 96% rename from source/funkin/data/freeplay/AlbumRegistry.hx rename to source/funkin/data/freeplay/album/AlbumRegistry.hx index 78fba451b..c04464fd2 100644 --- a/source/funkin/data/freeplay/AlbumRegistry.hx +++ b/source/funkin/data/freeplay/album/AlbumRegistry.hx @@ -1,7 +1,7 @@ -package funkin.data.freeplay; +package funkin.data.freeplay.album; import funkin.ui.freeplay.Album; -import funkin.data.freeplay.AlbumData; +import funkin.data.freeplay.album.AlbumData; import funkin.ui.freeplay.ScriptedAlbum; class AlbumRegistry extends BaseRegistry diff --git a/source/funkin/data/freeplay/album/CHANGELOG.md b/source/funkin/data/freeplay/album/CHANGELOG.md new file mode 100644 index 000000000..ae307465e --- /dev/null +++ b/source/funkin/data/freeplay/album/CHANGELOG.md @@ -0,0 +1,9 @@ +# Freeplay Album Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/song/CHANGELOG.md b/source/funkin/data/song/CHANGELOG.md new file mode 100644 index 000000000..3cd3af070 --- /dev/null +++ b/source/funkin/data/song/CHANGELOG.md @@ -0,0 +1,36 @@ +# Song Chart Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [2.2.2] +### Added +- Added `playData.previewStart` and `playData.previewEnd` fields to specify when in the song should the song's audio should be played as a preview in Freeplay. + +## [2.2.1] +### Added +- Added `playData.offsets` field to specify instrumental and vocal offsets. + +## [2.2.0] +### Added +- Added `playData.album` to specify the album art to display in Freeplay. +- Added `playData.ratings` for difficulty ratings displayed in Freeplay. +### Changed +- Renamed `playData.noteSkin` to `playData.noteStyle`. + +## [2.1.0] +### Changed +- Rearranged the `playData` field. + - Refactored the `playableChars` +### Removed +- Removed the `variation` field. + +## [2.0.0] +Full refactor of the chart format for improved structure. +### Added +- Added a semantic version field for migration tracking. + +## [1.0.0] +Initial version from 2020. diff --git a/source/funkin/data/speaker/TODO.md b/source/funkin/data/speaker/TODO.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/funkin/data/stage/CHANGELOG.md b/source/funkin/data/stage/CHANGELOG.md new file mode 100644 index 000000000..879139db5 --- /dev/null +++ b/source/funkin/data/stage/CHANGELOG.md @@ -0,0 +1,14 @@ +# Story Mode Level Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.1] +### Added +- Added the ability to specify a hexadecimal color in the `assetPath` field instead of a texture key. + - In this case, the `scale` property will be used to determine the size of the rectangle in pixels. + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/stage/StageRegistry.hx b/source/funkin/data/stage/StageRegistry.hx index b78292e5b..f18a643d2 100644 --- a/source/funkin/data/stage/StageRegistry.hx +++ b/source/funkin/data/stage/StageRegistry.hx @@ -11,7 +11,7 @@ class StageRegistry extends BaseRegistry * Handle breaking changes by incrementing this value * and adding migration to the `migrateStageData()` function. */ - public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.1"; + public static final STAGE_DATA_VERSION:thx.semver.Version = "1.0.0"; public static final STAGE_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x"; diff --git a/source/funkin/data/story/level/CHANGELOG.md b/source/funkin/data/story/level/CHANGELOG.md new file mode 100644 index 000000000..75d1fe4c0 --- /dev/null +++ b/source/funkin/data/story/level/CHANGELOG.md @@ -0,0 +1,9 @@ +# Story Mode Level Data Schema Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] +Initial release. diff --git a/source/funkin/data/level/LevelData.hx b/source/funkin/data/story/level/LevelData.hx similarity index 95% rename from source/funkin/data/level/LevelData.hx rename to source/funkin/data/story/level/LevelData.hx index f5e58ae16..957a9f66f 100644 --- a/source/funkin/data/level/LevelData.hx +++ b/source/funkin/data/story/level/LevelData.hx @@ -1,4 +1,4 @@ -package funkin.data.level; +package funkin.data.story.level; import funkin.data.animation.AnimationData; @@ -13,7 +13,7 @@ typedef LevelData = * When making changes to the level data format, this should be incremented, * and a migration function should be added to LevelDataParser to handle old versions. */ - @:default(funkin.data.level.LevelRegistry.LEVEL_DATA_VERSION) + @:default(funkin.data.story.level.LevelRegistry.LEVEL_DATA_VERSION) var version:String; /** diff --git a/source/funkin/data/level/LevelRegistry.hx b/source/funkin/data/story/level/LevelRegistry.hx similarity index 97% rename from source/funkin/data/level/LevelRegistry.hx rename to source/funkin/data/story/level/LevelRegistry.hx index 96712cba5..4f33207c8 100644 --- a/source/funkin/data/level/LevelRegistry.hx +++ b/source/funkin/data/story/level/LevelRegistry.hx @@ -1,7 +1,7 @@ -package funkin.data.level; +package funkin.data.story.level; import funkin.ui.story.Level; -import funkin.data.level.LevelData; +import funkin.data.story.level.LevelData; import funkin.ui.story.ScriptedLevel; class LevelRegistry extends BaseRegistry diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx index a88476d4d..c53374454 100644 --- a/source/funkin/modding/PolymodHandler.hx +++ b/source/funkin/modding/PolymodHandler.hx @@ -1,14 +1,14 @@ package funkin.modding; -import funkin.data.dialogue.ConversationRegistry; -import funkin.data.dialogue.DialogueBoxRegistry; -import funkin.data.dialogue.SpeakerRegistry; +import funkin.data.dialogue.conversation.ConversationRegistry; +import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry; +import funkin.data.dialogue.speaker.SpeakerRegistry; import funkin.data.event.SongEventRegistry; -import funkin.data.level.LevelRegistry; +import funkin.data.story.level.LevelRegistry; import funkin.data.notestyle.NoteStyleRegistry; import funkin.data.song.SongRegistry; import funkin.data.stage.StageRegistry; -import funkin.data.freeplay.AlbumRegistry; +import funkin.data.freeplay.album.AlbumRegistry; import funkin.modding.module.ModuleHandler; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.save.Save; diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 12b290afd..a4f665329 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -24,7 +24,7 @@ import flixel.util.FlxTimer; import funkin.api.newgrounds.NGio; import funkin.audio.VoicesGroup; import funkin.audio.VoicesGroup; -import funkin.data.dialogue.ConversationRegistry; +import funkin.data.dialogue.conversation.ConversationRegistry; import funkin.data.event.SongEventRegistry; import funkin.data.notestyle.NoteStyleData; import funkin.data.notestyle.NoteStyleRegistry; @@ -2011,10 +2011,10 @@ class PlayState extends MusicBeatSubState { if (note == null) continue; - // TODO: Does this properly account for offsets? - var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; - var hitWindowCenter = note.strumTime; - var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; + // TODO: Are offsets being accounted for in the correct direction? + var hitWindowStart = note.strumTime + Conductor.instance.inputOffset - Constants.HIT_WINDOW_MS; + var hitWindowCenter = note.strumTime + Conductor.instance.inputOffset; + var hitWindowEnd = note.strumTime + Conductor.instance.inputOffset + Constants.HIT_WINDOW_MS; if (Conductor.instance.songPosition > hitWindowEnd) { diff --git a/source/funkin/play/cutscene/dialogue/Conversation.hx b/source/funkin/play/cutscene/dialogue/Conversation.hx index f865f3b7b..1b899acf5 100644 --- a/source/funkin/play/cutscene/dialogue/Conversation.hx +++ b/source/funkin/play/cutscene/dialogue/Conversation.hx @@ -16,13 +16,13 @@ import funkin.play.cutscene.dialogue.DialogueBox; import funkin.modding.IScriptedClass.IDialogueScriptedClass; import funkin.modding.events.ScriptEventDispatcher; import flixel.addons.display.FlxPieDial; -import funkin.data.dialogue.ConversationData; -import funkin.data.dialogue.ConversationData.DialogueEntryData; -import funkin.data.dialogue.ConversationRegistry; -import funkin.data.dialogue.SpeakerData; -import funkin.data.dialogue.SpeakerRegistry; -import funkin.data.dialogue.DialogueBoxData; -import funkin.data.dialogue.DialogueBoxRegistry; +import funkin.data.dialogue.conversation.ConversationData; +import funkin.data.dialogue.conversation.ConversationData.DialogueEntryData; +import funkin.data.dialogue.conversation.ConversationRegistry; +import funkin.data.dialogue.speaker.SpeakerData; +import funkin.data.dialogue.speaker.SpeakerRegistry; +import funkin.data.dialogue.dialoguebox.DialogueBoxData; +import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry; /** * A high-level handler for dialogue. diff --git a/source/funkin/play/cutscene/dialogue/DialogueBox.hx b/source/funkin/play/cutscene/dialogue/DialogueBox.hx index fe4f13be0..6d3c0b8bc 100644 --- a/source/funkin/play/cutscene/dialogue/DialogueBox.hx +++ b/source/funkin/play/cutscene/dialogue/DialogueBox.hx @@ -11,8 +11,8 @@ import funkin.modding.events.ScriptEvent; import funkin.audio.FunkinSound; import funkin.modding.IScriptedClass.IDialogueScriptedClass; import flixel.util.FlxColor; -import funkin.data.dialogue.DialogueBoxData; -import funkin.data.dialogue.DialogueBoxRegistry; +import funkin.data.dialogue.dialoguebox.DialogueBoxData; +import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry; class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass implements IRegistryEntry { diff --git a/source/funkin/play/cutscene/dialogue/Speaker.hx b/source/funkin/play/cutscene/dialogue/Speaker.hx index 0d29481c4..7203ddb28 100644 --- a/source/funkin/play/cutscene/dialogue/Speaker.hx +++ b/source/funkin/play/cutscene/dialogue/Speaker.hx @@ -6,8 +6,8 @@ import funkin.modding.events.ScriptEvent; import flixel.graphics.frames.FlxFramesCollection; import funkin.util.assets.FlxAnimationUtil; import funkin.modding.IScriptedClass.IDialogueScriptedClass; -import funkin.data.dialogue.SpeakerData; -import funkin.data.dialogue.SpeakerRegistry; +import funkin.data.dialogue.speaker.SpeakerData; +import funkin.data.dialogue.speaker.SpeakerRegistry; /** * The character sprite which displays during dialogue. diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index aa87fa2e4..f2db41428 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -50,7 +50,20 @@ class Strumline extends FlxSpriteGroup * Usually you want to keep this as is, but if you are using a Strumline and * playing a sound that has it's own conductor, set this (LatencyState for example) */ - public var conductorInUse:Conductor = Conductor.instance; + public var conductorInUse(get, set):Conductor; + + var _conductorInUse:Null; + + function get_conductorInUse():Conductor + { + if (_conductorInUse == null) return Conductor.instance; + return _conductorInUse; + } + + function set_conductorInUse(value:Conductor):Conductor + { + return _conductorInUse = value; + } /** * The notes currently being rendered on the strumline. @@ -159,103 +172,9 @@ class Strumline extends FlxSpriteGroup } /** - * Process the notes in this strumline. - * @param onNoteMiss - * @param dispatchEvent TODO: better way to do this? Maybe passing in current dispatchEvent function from current state? + * Return notes that are within `Constants.HIT_WINDOW` ms of the strumline. + * @return An array of `NoteSprite` objects. */ - public function processNotes(?onNoteMiss:NoteSprite->Void, ?dispatchEvent:ScriptEvent->Void) - { - for (note in notes.members) - { - if (note == null || (isPlayer && note.hasBeenHit)) continue; - - var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; - var hitWindowCenter = note.strumTime; - var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; - - if (conductorInUse.songPosition > hitWindowEnd) - { - if (!isPlayer && note.hasMissed) continue; - - note.tooEarly = false; - note.mayHit = false; - note.hasMissed = true; - - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true; - } - else if (conductorInUse.songPosition > hitWindowCenter) - { - // only run this on opponent strumlines! - if (!isPlayer) continue; - - // Call an event to allow canceling the note hit. - // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new NoteScriptEvent(NOTE_HIT, note, 0, true); - if (dispatchEvent != null) dispatchEvent(event); - - // Calling event.cancelEvent() skips all other logic! Neat! - if (event.eventCanceled) continue; - - // Command the opponent to hit the note on time. - // NOTE: This is what handles the strumline and cleaning up the note itself! - - hitNote(note); - - if (note.holdNoteSprite != null) - { - playNoteHoldCover(note.holdNoteSprite); - } - } - else if (conductorInUse.songPosition > hitWindowStart) - { - if (!isPlayer && (note.hasBeenHit || note.hasMissed)) continue; - - note.tooEarly = false; - note.mayHit = true; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - else - { - note.tooEarly = true; - note.mayHit = false; - note.hasMissed = false; - if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false; - } - - if (note.hasMissed && !note.handledMiss) - { - var event:NoteScriptEvent = new NoteScriptEvent(NOTE_MISS, note, 0, true); - - if (dispatchEvent != null) dispatchEvent(event); - - if (event.eventCanceled) continue; - - if (onNoteMiss != null) onNoteMiss(note); - - note.handledMiss = true; - } - } - } - - var frameMax:Int; - var animFinishedEver:Bool; - - /** - * Get a list of notes within + or - the given strumtime. - * @param strumTime The current time. - * @param hitWindow The hit window to check. - */ - public function getNotesInRange(strumTime:Float, hitWindow:Float):Array - { - var hitWindowStart:Float = strumTime - hitWindow; - var hitWindowEnd:Float = strumTime + hitWindow; - - return notes.members.filter(function(note:NoteSprite) { - return note != null && note.alive && !note.hasBeenHit && note.strumTime >= hitWindowStart && note.strumTime <= hitWindowEnd; - }); - } - public function getNotesMayHit():Array { return notes.members.filter(function(note:NoteSprite) { @@ -263,6 +182,10 @@ class Strumline extends FlxSpriteGroup }); } + /** + * Return hold notes that are within `Constants.HIT_WINDOW` ms of the strumline. + * @return An array of `SustainTrail` objects. + */ public function getHoldNotesHitOrMissed():Array { return holdNotes.members.filter(function(holdNote:SustainTrail) { @@ -270,19 +193,6 @@ class Strumline extends FlxSpriteGroup }); } - public function getHoldNotesInRange(strumTime:Float, hitWindow:Float):Array - { - var hitWindowStart:Float = strumTime - hitWindow; - var hitWindowEnd:Float = strumTime + hitWindow; - - return holdNotes.members.filter(function(note:SustainTrail) { - return note != null - && note.alive - && note.strumTime >= hitWindowStart - && (note.strumTime + note.fullSustainLength) <= hitWindowEnd; - }); - } - public function getNoteSprite(noteData:SongNoteData):NoteSprite { if (noteData == null) return null; @@ -382,6 +292,9 @@ class Strumline extends FlxSpriteGroup { if (noteData.length == 0) return; + // Ensure note data gets reset if the song happens to loop. + if (conductorInUse.currentStep == 0) nextNoteIndex = 0; + var songStart:Float = PlayState.instance?.startTimestamp ?? 0.0; var hitWindowStart:Float = conductorInUse.songPosition - Constants.HIT_WINDOW_MS; var renderWindowStart:Float = conductorInUse.songPosition + RENDER_DISTANCE_MS; diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index d54fd5b8f..e76bf31a7 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -27,7 +27,21 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; - public var conductorInUse:Conductor = Conductor.instance; + + public var conductorInUse(get, set):Conductor; + + var _conductorInUse:Null; + + function get_conductorInUse():Conductor + { + if (_conductorInUse == null) return Conductor.instance; + return _conductorInUse; + } + + function set_conductorInUse(value:Conductor):Conductor + { + return _conductorInUse = value; + } public function new() { diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index ab62a082d..15c564db0 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -21,7 +21,7 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler public var leftWatermarkText:FlxText = null; public var rightWatermarkText:FlxText = null; - public var conductorInUse(get, default):Conductor; + public var conductorInUse(get, set):Conductor; var _conductorInUse:Null; @@ -31,6 +31,11 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler return _conductorInUse; } + function set_conductorInUse(value:Conductor):Conductor + { + return _conductorInUse = value; + } + public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) { super(); diff --git a/source/funkin/ui/debug/dialogue/ConversationDebugState.hx b/source/funkin/ui/debug/dialogue/ConversationDebugState.hx index c2edcca5a..db7b35d3e 100644 --- a/source/funkin/ui/debug/dialogue/ConversationDebugState.hx +++ b/source/funkin/ui/debug/dialogue/ConversationDebugState.hx @@ -5,13 +5,13 @@ import funkin.modding.events.ScriptEventDispatcher; import funkin.modding.events.ScriptEvent; import flixel.util.FlxColor; import funkin.ui.MusicBeatState; -import funkin.data.dialogue.ConversationData; -import funkin.data.dialogue.ConversationRegistry; -import funkin.data.dialogue.DialogueBoxData; -import funkin.data.dialogue.DialogueBoxRegistry; -import funkin.data.dialogue.SpeakerData; -import funkin.data.dialogue.SpeakerRegistry; -import funkin.data.freeplay.AlbumRegistry; +import funkin.data.dialogue.conversation.ConversationData; +import funkin.data.dialogue.conversation.ConversationRegistry; +import funkin.data.dialogue.dialoguebox.DialogueBoxData; +import funkin.data.dialogue.dialoguebox.DialogueBoxRegistry; +import funkin.data.dialogue.speaker.SpeakerData; +import funkin.data.dialogue.speaker.SpeakerRegistry; +import funkin.data.freeplay.album.AlbumRegistry; import funkin.play.cutscene.dialogue.Conversation; import funkin.play.cutscene.dialogue.DialogueBox; import funkin.play.cutscene.dialogue.Speaker; diff --git a/source/funkin/ui/freeplay/Album.hx b/source/funkin/ui/freeplay/Album.hx index 7291c7357..a686bff51 100644 --- a/source/funkin/ui/freeplay/Album.hx +++ b/source/funkin/ui/freeplay/Album.hx @@ -1,7 +1,7 @@ package funkin.ui.freeplay; -import funkin.data.freeplay.AlbumData; -import funkin.data.freeplay.AlbumRegistry; +import funkin.data.freeplay.album.AlbumData; +import funkin.data.freeplay.album.AlbumRegistry; import funkin.data.IRegistryEntry; import flixel.graphics.FlxGraphic; diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index a1e63c9a1..6e8ef8fe2 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -6,7 +6,7 @@ import flixel.util.FlxSort; import flixel.tweens.FlxTween; import flixel.util.FlxTimer; import flixel.tweens.FlxEase; -import funkin.data.freeplay.AlbumRegistry; +import funkin.data.freeplay.album.AlbumRegistry; import funkin.graphics.FunkinSprite; import funkin.util.SortUtil; import openfl.utils.Assets; diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index fc11eec28..858ff922f 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -18,7 +18,7 @@ import flixel.util.FlxColor; import flixel.util.FlxSpriteUtil; import flixel.util.FlxTimer; import funkin.audio.FunkinSound; -import funkin.data.level.LevelRegistry; +import funkin.data.story.level.LevelRegistry; import funkin.data.song.SongRegistry; import funkin.graphics.FunkinCamera; import funkin.graphics.FunkinSprite; diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index 7b233f03d..152d9b817 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -1,5 +1,6 @@ package funkin.ui.options; +import funkin.ui.debug.latency.LatencyState; import flixel.FlxSprite; import flixel.FlxSubState; import flixel.addons.transition.FlxTransitionableState; @@ -182,6 +183,9 @@ class OptionsMenu extends Page add(items = new TextMenuList()); createItem("PREFERENCES", function() switchPage(Preferences)); createItem("CONTROLS", function() switchPage(Controls)); + createItem("INPUT OFFSETS", function() { + FlxG.state.openSubState(new LatencyState()); + }); #if newgrounds if (NGio.isLoggedIn) createItem("LOGOUT", selectLogout); diff --git a/source/funkin/ui/story/Level.hx b/source/funkin/ui/story/Level.hx index 626fb8e52..22f10f096 100644 --- a/source/funkin/ui/story/Level.hx +++ b/source/funkin/ui/story/Level.hx @@ -6,8 +6,8 @@ import flixel.util.FlxColor; import funkin.play.song.Song; import funkin.data.IRegistryEntry; import funkin.data.song.SongRegistry; -import funkin.data.level.LevelRegistry; -import funkin.data.level.LevelData; +import funkin.data.story.level.LevelRegistry; +import funkin.data.story.level.LevelData; /** * An object used to retrieve data about a story mode level (also known as "weeks"). diff --git a/source/funkin/ui/story/LevelProp.hx b/source/funkin/ui/story/LevelProp.hx index d8eae9c77..ffc756e1c 100644 --- a/source/funkin/ui/story/LevelProp.hx +++ b/source/funkin/ui/story/LevelProp.hx @@ -2,7 +2,7 @@ package funkin.ui.story; import funkin.play.stage.Bopper; import funkin.util.assets.FlxAnimationUtil; -import funkin.data.level.LevelData; +import funkin.data.story.level.LevelData; class LevelProp extends Bopper { diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 9ce110c73..3719704c8 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -9,7 +9,7 @@ import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxTimer; import funkin.audio.FunkinSound; -import funkin.data.level.LevelRegistry; +import funkin.data.story.level.LevelRegistry; import funkin.data.song.SongRegistry; import funkin.graphics.FunkinSprite; import funkin.modding.events.ScriptEvent; From 680ed3c2f3f85229326ff442eee833df7ee7b59a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sat, 23 Mar 2024 15:34:48 -0400 Subject: [PATCH 27/60] Fix a syntax error. --- tests/unit/source/funkin/data/level/LevelRegistryTest.hx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/source/funkin/data/level/LevelRegistryTest.hx b/tests/unit/source/funkin/data/level/LevelRegistryTest.hx index 691d8bedc..44cfb909c 100644 --- a/tests/unit/source/funkin/data/level/LevelRegistryTest.hx +++ b/tests/unit/source/funkin/data/level/LevelRegistryTest.hx @@ -1,6 +1,6 @@ -package funkin.data.level; +package funkin.data.story.level; -import funkin.data.level.LevelRegistry; +import funkin.data.story.level.LevelRegistry; import funkin.ui.story.Level; import massive.munit.Assert; import massive.munit.async.AsyncFactory; @@ -8,7 +8,7 @@ import massive.munit.util.Timer; @:nullSafety @:access(funkin.ui.story.Level) -@:access(funkin.data.level.LevelRegistry) +@:access(funkin.data.story.level.LevelRegistry) class LevelRegistryTest extends FunkinTest { public function new() From 9a874d5293a17a93b7779c930a7b5d1583131f3c Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 4 Apr 2024 19:45:57 -0400 Subject: [PATCH 28/60] Fix for weird HSV colors --- assets | 2 +- source/funkin/graphics/shaders/HSVShader.hx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets b/assets index 5027bc656..ad6ed62bd 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 5027bc656c9df5ec208ab256f9494bd7da425111 +Subproject commit ad6ed62bd254456b9584b02ed0a5402118b033a8 diff --git a/source/funkin/graphics/shaders/HSVShader.hx b/source/funkin/graphics/shaders/HSVShader.hx index 733bbca7f..9b6ae4cdd 100644 --- a/source/funkin/graphics/shaders/HSVShader.hx +++ b/source/funkin/graphics/shaders/HSVShader.hx @@ -20,7 +20,7 @@ class HSVShader extends FlxRuntimeShader function set_hue(value:Float):Float { - this.setFloat('hue', value); + this.setFloat('_hue', value); this.hue = value; return this.hue; @@ -28,7 +28,7 @@ class HSVShader extends FlxRuntimeShader function set_saturation(value:Float):Float { - this.setFloat('sat', value); + this.setFloat('_sat', value); this.saturation = value; return this.saturation; @@ -36,7 +36,7 @@ class HSVShader extends FlxRuntimeShader function set_value(value:Float):Float { - this.setFloat('val', value); + this.setFloat('_val', value); this.value = value; return this.value; From 72a3742890c472cc40650a24b307ffacc1e4c19e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 4 Apr 2024 19:46:08 -0400 Subject: [PATCH 29/60] Fixes and improvements to LatencyState --- .../funkin/ui/debug/latency/LatencyState.hx | 25 ++++--------------- source/funkin/ui/freeplay/SongMenuItem.hx | 2 +- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 91cf2013b..9d1bcde71 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -27,7 +27,7 @@ class LatencyState extends MusicBeatSubState { var visualOffsetText:FlxText; var offsetText:FlxText; - var noteGrp:Array; + var noteGrp:Array = []; var strumLine:Strumline; var blocks:FlxTypedGroup; @@ -39,7 +39,7 @@ class LatencyState extends MusicBeatSubState var beatTrail:FlxSprite; var diffGrp:FlxTypedGroup; var offsetsPerBeat:Array> = []; - var swagSong:FlxSound; + var swagSong:HomemadeMusic; var previousVolume:Float; @@ -84,7 +84,7 @@ class LatencyState extends MusicBeatSubState else previousVolume = 1; // defaults to 1 if no music is playing 🤔 also fuck it, emoji in code comment - swagSong = new FlxSound(); + swagSong = new HomemadeMusic(); swagSong.loadEmbedded(Paths.sound('soundTest'), true); swagSong.looped = true; swagSong.play(); @@ -99,7 +99,7 @@ class LatencyState extends MusicBeatSubState FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> { trace(key.charCode); - if (key.charCode == 120) generateBeatStuff(); + // if (key.charCode == 120) generateBeatStuff(); trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); // trace(FlxG.sound.music.prevTimestamp); @@ -116,9 +116,6 @@ class LatencyState extends MusicBeatSubState Conductor.instance.forceBPM(60); - noteGrp = new FlxTypedGroup(); - add(noteGrp); - diffGrp = new FlxTypedGroup(); add(diffGrp); @@ -264,7 +261,7 @@ class LatencyState extends MusicBeatSubState trace(FlxG.sound.music._channel.position); */ - localConductor.update(swagSong.time, false, true); + localConductor.update(swagSong.time, false); // localConductor.songPosition += (Timer.stamp() * 1000) - FlxG.sound.music.prevTimestamp; @@ -334,18 +331,6 @@ class LatencyState extends MusicBeatSubState { close(); } - noteGrp.forEach(function(daNote:NoteSprite) { - 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; - - if (daNote.y < 0 - daNote.height) - { - daNote.alpha = 1; - // daNote.data.strumTime += Conductor.instance.beatLengthMs * 8; - } - }); super.update(elapsed); } diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index f8b3d7ac3..bfb40c9ac 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -82,7 +82,7 @@ class SongMenuItem extends FlxSpriteGroup grayscaleShader = new Grayscale(1); diffRatingSprite = new FlxSprite(145, 90).loadGraphic(Paths.image('freeplay/diffRatings/diff00')); - diffRatingSprite.shader = grayscaleShader; + // diffRatingSprite.shader = grayscaleShader; diffRatingSprite.origin.set(capsule.origin.x - diffRatingSprite.x, capsule.origin.y - diffRatingSprite.y); // TODO: Readd once ratings are fully implemented // add(diffRatingSprite); From 17a15a3947cc03e6c4c2424a8a584bbd2bc33c56 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 10 Apr 2024 21:31:22 -0400 Subject: [PATCH 30/60] Reposition notes based on the configured input offset (so you still hit them when centered) --- source/funkin/play/notes/Strumline.hx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 73c2a6fab..6a18f17d5 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -285,7 +285,8 @@ class Strumline extends FlxSpriteGroup var vwoosh:Float = 1.0; var scrollSpeed:Float = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; - return Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); + return + Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime - Conductor.instance.inputOffset) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); } function updateNotes():Void From e0721b901ec7be33d55fa9293c745156da19503a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 10 Apr 2024 21:31:49 -0400 Subject: [PATCH 31/60] Fix a bug where negative visual offsets would break the countdown. --- source/funkin/play/PlayState.hx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 787349952..8787f8175 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -890,7 +890,8 @@ class PlayState extends MusicBeatSubState { if (isInCountdown) { - Conductor.instance.update(Conductor.instance.songPosition + elapsed * 1000); + // Do NOT apply offsets at this point, because they already got applied the previous frame! + Conductor.instance.update(Conductor.instance.songPosition + elapsed * 1000, false); if (Conductor.instance.songPosition >= (startTimestamp)) startSong(); } } From c3ba4081f1b7231a8dda92da78390db95ad72705 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 10 Apr 2024 21:32:08 -0400 Subject: [PATCH 32/60] Fix a crash issue caused when pressing a key after leaving the input offsets state. --- source/funkin/ui/debug/latency/LatencyState.hx | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 9d1bcde71..94f179629 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -96,24 +96,6 @@ class LatencyState extends MusicBeatSubState localConductor.forceBPM(60); - FlxG.stage.addEventListener(KeyboardEvent.KEY_DOWN, key -> { - trace(key.charCode); - - // if (key.charCode == 120) generateBeatStuff(); - - trace("\tEVENT PRESS: \t" + FlxG.sound.music.time + " " + Timer.stamp()); - // trace(FlxG.sound.music.prevTimestamp); - trace(FlxG.sound.music.time); - trace("\tFR FR PRESS: \t" + swagSong.getTimeWithDiff()); - - // trace("\tREDDIT: \t" + swagSong.frfrTime + " " + Timer.stamp()); - @:privateAccess - trace("\tREDDIT: \t" + FlxG.sound.music._channel.position + " " + Timer.stamp()); - // trace("EVENT LISTENER: " + key); - }); - - // funnyStatsGraph.hi - Conductor.instance.forceBPM(60); diffGrp = new FlxTypedGroup(); From 85e06ef18fa2584fb1038e34c12fd696e3e2c264 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 24 Apr 2024 22:08:20 -0400 Subject: [PATCH 33/60] Make it possible to escape the input offsets menu on controller. --- source/funkin/ui/debug/latency/LatencyState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/debug/latency/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx index 94f179629..962438154 100644 --- a/source/funkin/ui/debug/latency/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -166,7 +166,7 @@ class LatencyState extends MusicBeatSubState var helpText:FlxText = new FlxText(); helpText.setFormat(Paths.font("vcr.ttf"), 20); - helpText.text = "Press ESC to return to main menu"; + helpText.text = "Press BACK to return to main menu"; helpText.x = FlxG.width - helpText.width; helpText.y = FlxG.height - (helpText.height * 2) - 2; add(helpText); @@ -309,7 +309,7 @@ class LatencyState extends MusicBeatSubState } } - if (FlxG.keys.justPressed.ESCAPE) + if (controls.BACK) { close(); } From 3083305f51038051944db788e1b5ca0c49999617 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Mon, 29 Apr 2024 02:21:44 +0100 Subject: [PATCH 34/60] fix pixel combo numbers being huge --- source/funkin/play/components/PopUpStuff.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/components/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx index b062b22cf..b7e206e97 100644 --- a/source/funkin/play/components/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -42,7 +42,7 @@ class PopUpStuff extends FlxTypedGroup if (PlayState.instance.currentStageId.startsWith('school')) { - rating.setGraphicSize(Std.int(rating.width * Constants.PIXEL_ART_SCALE * 0.65)); + rating.setGraphicSize(Std.int(rating.width * Constants.PIXEL_ART_SCALE * 0.7)); rating.antialiasing = false; } else @@ -133,7 +133,7 @@ class PopUpStuff extends FlxTypedGroup if (PlayState.instance.currentStageId.startsWith('school')) { - numScore.setGraphicSize(Std.int(numScore.width * Constants.PIXEL_ART_SCALE)); + numScore.setGraphicSize(Std.int(numScore.width * Constants.PIXEL_ART_SCALE * 0.7)); numScore.antialiasing = false; } else From b35822f9a4935362655bc36f9d698366fc7f1f13 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Mon, 29 Apr 2024 02:22:11 +0100 Subject: [PATCH 35/60] soundtray fade --- source/funkin/ui/options/FunkinSoundTray.hx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/options/FunkinSoundTray.hx b/source/funkin/ui/options/FunkinSoundTray.hx index 4af94569b..b8c408508 100644 --- a/source/funkin/ui/options/FunkinSoundTray.hx +++ b/source/funkin/ui/options/FunkinSoundTray.hx @@ -20,6 +20,7 @@ class FunkinSoundTray extends FlxSoundTray { var graphicScale:Float = 0.30; var lerpYPos:Float = 0; + var alphaTarget:Float = 0; var volumeMaxSound:String; @@ -40,7 +41,7 @@ class FunkinSoundTray extends FlxSoundTray // makes an alpha'd version of all the bars (bar_10.png) var backingBar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_10"))); - backingBar.x = 10; + backingBar.x = 9; backingBar.y = 5; backingBar.scaleX = graphicScale; backingBar.scaleY = graphicScale; @@ -56,7 +57,7 @@ class FunkinSoundTray extends FlxSoundTray for (i in 1...11) { var bar:Bitmap = new Bitmap(Assets.getBitmapData(Paths.image("soundtray/bars_" + i))); - bar.x = 10; + bar.x = 9; bar.y = 5; bar.scaleX = graphicScale; bar.scaleY = graphicScale; @@ -77,15 +78,18 @@ class FunkinSoundTray extends FlxSoundTray override public function update(MS:Float):Void { y = MathUtil.coolLerp(y, lerpYPos, 0.1); + alpha = MathUtil.coolLerp(alpha, alphaTarget, 0.25); // Animate sound tray thing if (_timer > 0) { _timer -= (MS / 1000); + alphaTarget = 1; } else if (y > -height) { lerpYPos = -height - 10; + alphaTarget = 0; if (y <= -height) { From c609e3591bd8653194686457a09983aa85786fbb Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Mon, 29 Apr 2024 02:22:33 +0100 Subject: [PATCH 36/60] fixed classic camera reset --- source/funkin/play/event/FocusCameraSongEvent.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/event/FocusCameraSongEvent.hx b/source/funkin/play/event/FocusCameraSongEvent.hx index 569dcb87a..074fafccf 100644 --- a/source/funkin/play/event/FocusCameraSongEvent.hx +++ b/source/funkin/play/event/FocusCameraSongEvent.hx @@ -127,7 +127,7 @@ class FocusCameraSongEvent extends SongEvent switch (ease) { case 'CLASSIC': // Old-school. No ease. Just set follow point. - PlayState.instance.resetCamera(); + PlayState.instance.resetCamera(false, true); PlayState.instance.cameraFollowPoint.setPosition(targetX, targetY); case 'INSTANT': // Instant ease. Duration is automatically 0. PlayState.instance.tweenCameraToPosition(targetX, targetY, 0); From 333b177ffb1f90ab8c515b9abc2d8b1d55c4497b Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Mon, 29 Apr 2024 02:22:49 +0100 Subject: [PATCH 37/60] update assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index ac8bf6e12..61eabfd45 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ac8bf6e129113551e1c7971327b31096d703e433 +Subproject commit 61eabfd454436c18470af769610fe23b0af9a8e7 From 21ab198c58b77db400412ebb4c70fa169792b582 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 01:19:58 -0400 Subject: [PATCH 38/60] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 2e59d1bf5..ad2264080 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 2e59d1bf5b9b7d3e5d83f9b949464bd27544ce14 +Subproject commit ad22640805196fe606417dcf12d8e679ee61c543 From 450a232eb8f10fbeea213415abe451b6aa65ae71 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 01:39:19 -0400 Subject: [PATCH 39/60] hxcodec version commit bump --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index c53a1143b..300f0287f 100644 --- a/hmm.json +++ b/hmm.json @@ -80,7 +80,7 @@ "name": "hxCodec", "type": "git", "dir": null, - "ref": "387e1665d6feb5762358134f168e6ebfe46acec8", + "ref": "c0c7f2680cc190c932a549c2e2fdd9b0ba2bd10e", "url": "https://github.com/FunkinCrew/hxCodec" }, { @@ -171,4 +171,4 @@ "url": "https://github.com/FunkinCrew/thx.semver" } ] -} \ No newline at end of file +} From 64b416e956db55a6c334e6a59a6d259821096736 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 02:31:40 -0400 Subject: [PATCH 40/60] async the LoadingState asset preloads --- source/funkin/ui/transition/LoadingState.hx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/source/funkin/ui/transition/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx index 3b53e1b4a..28533e35b 100644 --- a/source/funkin/ui/transition/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -326,15 +326,20 @@ class LoadingState extends MusicBeatSubState // I will fix this properly later I swear -eric if (!path.endsWith('.png')) continue; - FunkinSprite.cacheTexture(path); + new Future(function() { + FunkinSprite.cacheTexture(path); + // Another dumb hack: FlxAnimate fetches from OpenFL's BitmapData cache directly and skips the FlxGraphic cache. + // Since FlxGraphic tells OpenFL to not cache it, we have to do it manually. + if (path.endsWith('spritemap1.png')) + { + trace('Preloading FlxAnimate asset: ${path}'); + openfl.Assets.getBitmapData(path, true); + } + return 'Done precaching ${path}'; + }, true); - // Another dumb hack: FlxAnimate fetches from OpenFL's BitmapData cache directly and skips the FlxGraphic cache. - // Since FlxGraphic tells OpenFL to not cache it, we have to do it manually. - if (path.endsWith('spritemap1.png')) - { - trace('Preloading FlxAnimate asset: ${path}'); - openfl.Assets.getBitmapData(path, true); - } + trace("Queued ${path} for precaching"); + // FunkinSprite.cacheTexture(path); } // FunkinSprite.cacheAllNoteStyleTextures(noteStyle) // This will replace the stuff above! From 81f8338c99bc082dc9f1d7ebff99affc44151a9b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 03:49:28 -0400 Subject: [PATCH 41/60] sets the selected track as first one in group when swapping sorts on freeplay --- source/funkin/ui/freeplay/FreeplayState.hx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index b16cbe63a..bd558f747 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -456,6 +456,14 @@ class FreeplayState extends MusicBeatSubState default: generateSongList({filterType: REGEXP, filterData: str}, true); } + + // We want to land on the first song of the group, rather than random song when changing letter sorts + // that is, only if there's more than one song in the group! + if (grpCapsules.members.length > 0) + { + curSelected = 1; + changeSelection(); + } }; exitMovers.set([fp, txtCompletion, fnfHighscoreSpr], From 3a7efeeca36d99639c8295c882c0d1319fb85b9d Mon Sep 17 00:00:00 2001 From: Hazel Date: Mon, 29 Apr 2024 20:04:01 +0100 Subject: [PATCH 42/60] fix(ci): linux private repo issues (#524) --- .github/hooks/post-checkout | 0 .github/hooks/post-merge | 0 .github/hooks/pre-push | 0 Project.xml | 2 +- hmm.json | 6 +++--- source/funkin/audio/visualize/ABotVis.hx | 6 +++--- 6 files changed, 7 insertions(+), 7 deletions(-) mode change 100644 => 100755 .github/hooks/post-checkout mode change 100644 => 100755 .github/hooks/post-merge mode change 100644 => 100755 .github/hooks/pre-push diff --git a/.github/hooks/post-checkout b/.github/hooks/post-checkout old mode 100644 new mode 100755 diff --git a/.github/hooks/post-merge b/.github/hooks/post-merge old mode 100644 new mode 100755 diff --git a/.github/hooks/pre-push b/.github/hooks/pre-push old mode 100644 new mode 100755 diff --git a/Project.xml b/Project.xml index 0a44a268c..2e056426c 100644 --- a/Project.xml +++ b/Project.xml @@ -124,7 +124,7 @@ - + diff --git a/hmm.json b/hmm.json index c53a1143b..0417b583a 100644 --- a/hmm.json +++ b/hmm.json @@ -46,10 +46,10 @@ "version": "3.5.0" }, { - "name": "funkVis", + "name": "funkin.vis", "type": "git", "dir": null, - "ref": "7fc9901553fbe9b8fcf6e2e84bc86eabeaf29701", + "ref": "98c9db09f0bbfedfe67a84538a5814aaef80bdea", "url": "https://github.com/FunkinCrew/funkVis" }, { @@ -171,4 +171,4 @@ "url": "https://github.com/FunkinCrew/thx.semver" } ] -} \ No newline at end of file +} diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index 0295e35ff..ca77dd58a 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -8,8 +8,8 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.math.FlxMath; import flixel.sound.FlxSound; import funkin.util.MathUtil; -import funkVis.dsp.SpectralAnalyzer; -import funkVis.audioclip.frontends.LimeAudioClip; +import funkin.vis.dsp.SpectralAnalyzer; +import funkin.vis.audioclip.frontends.LimeAudioClip; using Lambda; @@ -90,7 +90,7 @@ class ABotVis extends FlxTypedSpriteGroup } /** - * TJW funkVis based visualizer! updateFFT() is the old nasty shit that dont worky! + * TJW funkin.vis based visualizer! updateFFT() is the old nasty shit that dont worky! */ function drawFFT():Void { From e4ae935ae5fdaa87e8110cc5ac12f21fa5284fcd Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 17:50:58 -0400 Subject: [PATCH 43/60] Update hxCodec to latest. --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index c53a1143b..300f0287f 100644 --- a/hmm.json +++ b/hmm.json @@ -80,7 +80,7 @@ "name": "hxCodec", "type": "git", "dir": null, - "ref": "387e1665d6feb5762358134f168e6ebfe46acec8", + "ref": "c0c7f2680cc190c932a549c2e2fdd9b0ba2bd10e", "url": "https://github.com/FunkinCrew/hxCodec" }, { @@ -171,4 +171,4 @@ "url": "https://github.com/FunkinCrew/thx.semver" } ] -} \ No newline at end of file +} From c9f023be1f8abecd93f097ee2706ea769c71ecdb Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 17:51:12 -0400 Subject: [PATCH 44/60] Some doc cleanup. --- .vscode/launch.json | 6 -- docs/COMPILING.md | 4 +- docs/FNFC-SPEC.md | 186 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 docs/FNFC-SPEC.md diff --git a/.vscode/launch.json b/.vscode/launch.json index afc0ab8db..74f72b826 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,12 +7,6 @@ "type": "lime", "request": "launch" }, - { - "name": "Debug", - "type": "lime", - "request": "launch", - "preLaunchTask": null - }, { // Launch in browser "name": "HTML5 Debug", diff --git a/docs/COMPILING.md b/docs/COMPILING.md index 6d5b5b365..442142e9b 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -16,5 +16,5 @@ - Mac: [`lime setup mac` Documentation](https://lime.openfl.org/docs/advanced-setup/macos/) - Linux: [`lime setup linux` Documentation](https://lime.openfl.org/docs/advanced-setup/linux/) - HTML5: Compiles without any extra setup -6. If you are targeting for native, you likely need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -7. `lime test PLATFORM` ! +6. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +7. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). diff --git a/docs/FNFC-SPEC.md b/docs/FNFC-SPEC.md new file mode 100644 index 000000000..3a444843a --- /dev/null +++ b/docs/FNFC-SPEC.md @@ -0,0 +1,186 @@ +# .fnfc File Specification + +*Updated 2024-04-29* + +- Manifest version: `1.0.0` +- Metadata version: `2.2.2` +- Chart data version: `2.0.0` + +## Introduction + +This document describes the structure of the FNFC file format used for saving and loading charts in the Chart Editor for Friday Night Funkin'. It is designed to refactor how the game stores levels, as the original format was clunky and poorly extensible. + +FNFC files are a store of all the required files for crediting and editing charts. This includes any relevant audio files, which is perfect for collaboration between charters. + +## Overview + +Friday Night Funkin' charts utilize a concept called "variations"; these are groups of difficulties which share gameplay data. This is done to prevent significant redundancy; if each chart + +If a difficulty for a song should have the same events as another difficulty, those difficulties should be in the same variation (for example, Normal and Hard). If a particular difficulty for a song should have different song events, characters, stages, or music (including instruments or vocals) from the base variation, they should use a different variation. Difficulties for a song start in the `default` variation. + +An example of this is the Erect and Nightmare difficulties. These are defined in an alternative variation, which allows for those difficulties to utilize different events and music from the base variation. + +The Chart Editor is made aware of which variations are available in the current chart file by querying the `playData.songVariations` key in the `default` variation's metadata file. + +The chart data itself is split into two files. The `-metadata.json` file should contain all the information the game needs to display a song in menus such as Freeplay, including but not limited to the song name, artist, and BPM. The `-chart.json` should only contain the note data for each difficulty of that variation, and the song event data for the variation. This allows the game to, when it first loads, parse and cache the metadata for all available songs for use in menus, while keeping the bulky chart file data unloaded until that chart specifically is played. + +Note that the game itself does not store its songs as FNFC files; rather, it stores the `metadata.json`, `chart.json`, and `.ogg` files separately. + +Note also that the files may include some values whose functionality are not yet fully implemented into the game itself. + +## File Contents + +FNFC files are standard ZIP files containing the following: + +- `manifest.json`: This file contains minimal information to minimize work in the parsing of chart files. +- `Inst.ogg`: Song instrumental for the default variation. +- `Inst-.ogg`: *(optional)* An alternative instrumental which can be used. +- `Voices-.ogg`: *(optional)* Song vocals for a specific character, for the default variation. +- `Voices--.ogg`: *(optional)* Song vocals for a specific character, for an alternate variation. +- `-metadata.json`: Song metadata for the `default` variation. +- `-metadata-.json`: *(optional)* Song metadata for alternate variations. +- `-chart.json`: Song chart data for the `default` variation. +- `-chart-.json`: *(optional)* Song chart data for alternate variations. + +## Files + +Note that each component file contains its own separate [Semantic Version](https://semver.org/) number which the game adheres to when parsing. New functionality (with backwards compatibility) should be represented by a `1.x.0` change and breaking changes should be kept to a minimum, and represented by a `x.0.0` change. + +### manifest.json + +`manifest.json` is a JSON-formatted text file, containing a single object with the following keys: + +- `version`: The Semantic Version string for the manifest file. +- `songId`: The song ID associated with this chart. Used to allow the Chart Editor to easily determine the proper filenames for the `metadata` and `chart` files. + +#### manifest.json Example + +```jsonc +{ + "version": "1.0.0", // The Semantic Version string. + "songId": "dadbattle" // The song ID. +} +``` + +### Inst.ogg + +This is an audio file in the OGG container format with the Vorbis audio codec. + +This file is mandatory. A chart file without an instrumental track is considered invalid. + +This file is used as the default backing track for the song. + +### Inst-.ogg + +This is an audio file in the OGG container format with the Vorbis audio codec. + +This file is optional if no alternative instrumental is specified in any variation. + +This file is used as an alternate backing track for the song. It is specified using the `playData.characters.instrumental` key in the current variation's metadata file. + +### Voices-.ogg + +This is an audio file in the OGG container format with the Vorbis audio codec. + +This file is optional. The game will look for the specified file but will ignore if it is missing. + +This file is used for the character vocal track for the song. The game will look for and play the vocal track for the player (using the ID specified by the `playData.characters.player` key in the current variation's metadata file), and the opponent (using the ID specified by the `playData.characters.opponent` key in the current variation's metadata file). + +### Voices--.ogg + +This is an audio file in the OGG container format with the Vorbis audio codec. + +This file is optional. The game will look for the specified file but will ignore if it is missing. + +This file is used for the character vocal track for the song, for the given variation. The game will look for and play the vocal track for the player and the opponent using the same JSON keys as the `Voices-.ogg` files for the default variation, while also applying the current variation ID. + +### -metadata.json + +`-metadata.json` is a JSON-formatted text file, specifying metadata about the default variation for this song. It has the following keys: + +- `version`: The Semantic Version string for the metadata file. +- `songName`: The human readable name for the song, as a string. +- `artist`: The human readable artist(s) for the song, as a string. +- `timeFormat`: The time format. In the future, this will allow chart files to define the timestamps for BPM changes, note data, or event data, in fractional beats and steps, but for now the only supported value is the string `"ms"`. +- `timeChanges`: An array of Song Time Change objects. Note that at least one Song Time Change object must be specified, with a timestamp of `0`. +- `playData`: A Song Play Data object. +- `offsets`: A Song Offset Data object. +- `generatedBy`: A string specified when creating a chart. Should only be used for debugging purposes, and not read or used by the game. Custom engines should modify `Constants.hx` to ensure unique values in case of issues with the metadata or chart data. + +The Song Time Change objects have the following keys: +- `t`: The timestamp for the BPM change, in milliseconds, as a float. +- `bpm`: The new song timing, in beats per minute, as a float. +- `n`: *optional* Time signature numerator, as an integer. Defaults to 4. (int). Optional, defaults to `4`. +- `d`: *optional* Time signature denominator, as an integer. Should only ever be a power of two. Defaults to `4`. +- `bt`: *optional* Beat tuplets. This defines how many steps each beat is divided into. Defaults to `[4, 4, 4, 4]` + +The Song Play Data objects have the following keys: +- `album`: The album ID to display in the Freeplay menu, as a string ID. +- `previewStart`: The timestamp to begin the audio preview for this track in the Freeplay Menu, in milliseconds, as a float. +- `previewEnd`: The timestamp to end the audio preview for this track in the Freeplay Menu, in milliseconds, as a float. +- `ratings`: An map object; each key is a difficulty ID and each value is an integer difficulty rating value for display in Freeplay. +- `songVariations`: An array of string variation IDs this song has. The game will attempt to read `-metadata-.json` and `-chart-.json` files for each variation ID included in this list. +- `difficulties`: An array of string difficulties this song has available to play. Any difficulties in this list will be made available to players in-game, and any difficulties not in this list will be ignored. +- `characters`: A Song Character Data object. +- `stage`: The stage to use for this chart, as a string ID. +- `noteStyle`: The note style to use for this chart, as a string ID. + +The Song Character Data objects have the following keys: +- `player`: The player character to use, as a string ID. +- `girlfriend`: The girlfriend character to use, as a string ID. +- `opponent`: The opponent character to use, as a string ID. +- `instrumental`: The instrumental ID to use. Defaults to a blank string to use `Inst.ogg` +- `altInstrumentals`: + +The Song Offset Data objects have the following keys: + +#### -metadata.json Example + +```jsonc +{ + "version": "2.2.2", // Semantic Version string + "songName": "DadBattle", // Readable song name + "artist": "Kawai Sprite", // Song artist(s) + "timeFormat": "ms", // Time format to use + "timeChanges": [{ // List of BPM changes. Must have at least one. + "t": 0, // BPM change timestamp in milliseconds. + "bpm": 180 // The target BPM. + }], + "playData": { + "album": "volume1", // The album to display in Freeplay. + "previewStart": 0, // Time (ms) to start preview at + "previewEnd": 15000, // Time (ms) to end preview at + "ratings": { // Rating data for each difficulty + "easy": 1, // Rating for Easy difficulty + "normal": 3, // Rating for Normal difficulty + "hard": 5 // Rating for Hard difficulty + }, + "songVariations": [ // Available variation files. + "erect" // This says dadbattle-metadata-erect.json exists. + ], + "difficulties": [ // Available difficulties. + "easy", + "normal", + "hard" + ], + "characters": { // Characters to use for this variation. + "player": "bf", // Boyfriend + "girlfriend": "gf", // Girlfriend + "opponent": "dad" // Daddy Dearest + }, + "stage": "mainStage", // Week 1 stage. + "noteStyle": "funkin" // Default note style. + }, + "generatedBy": "EliteMasterEric (by hand)" // Unique string. +} + +``` + +### -chart.json +Song chart data for the `default` variation. + +### -metadata-.json +*(optional)* Song metadata for alternate variations. + +### -chart-.json +*(optional)* Song chart data for alternate variations. From ea61c19aa5beb25f9334c46aa8d9a17c063811b4 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 17:51:36 -0400 Subject: [PATCH 45/60] Replace cutscenes. --- assets | 2 +- source/funkin/ui/title/AttractState.hx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets b/assets index ac8bf6e12..3a35ba2bc 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ac8bf6e129113551e1c7971327b31096d703e433 +Subproject commit 3a35ba2bcc3d7544374bca6d673391908e55adbd diff --git a/source/funkin/ui/title/AttractState.hx b/source/funkin/ui/title/AttractState.hx index a42a6c3d9..f674f9837 100644 --- a/source/funkin/ui/title/AttractState.hx +++ b/source/funkin/ui/title/AttractState.hx @@ -12,12 +12,12 @@ import funkin.ui.MusicBeatState; * After about 2 minutes of inactivity on the title screen, * the game will enter the Attract state, as a reference to physical arcade machines. * - * In the current version, this just plays the Kickstarter trailer, but this can be changed to + * In the current version, this just plays the ~~Kickstarter trailer~~ Erect teaser, but this can be changed to * gameplay footage, a generic game trailer, or something more elaborate. */ class AttractState extends MusicBeatState { - static final ATTRACT_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('kickstarterTrailer', 'shared')); + static final ATTRACT_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('erectTeaser', 'shared')); public override function create():Void { From 3786b0a23a955946851f7ed2dbe481b33662e872 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 18:31:20 -0400 Subject: [PATCH 46/60] Fix build issue on release builds. --- source/Main.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/Main.hx b/source/Main.hx index cbfc3ac63..add5bbc67 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -113,7 +113,9 @@ class Main extends Sprite addChild(game); + #if debug game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil()); + #end addChild(fpsCounter); From 3b1f84b4bd033d0c0ac2a44ebc39d543b7aa3fff Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 18:31:27 -0400 Subject: [PATCH 47/60] Fixes to attract state. --- assets | 2 +- source/funkin/ui/title/AttractState.hx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets b/assets index 3a35ba2bc..4b7dd53fe 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3a35ba2bcc3d7544374bca6d673391908e55adbd +Subproject commit 4b7dd53fe3e24c4a80649b63f95ab49628776d70 diff --git a/source/funkin/ui/title/AttractState.hx b/source/funkin/ui/title/AttractState.hx index f674f9837..11954aef2 100644 --- a/source/funkin/ui/title/AttractState.hx +++ b/source/funkin/ui/title/AttractState.hx @@ -17,7 +17,7 @@ import funkin.ui.MusicBeatState; */ class AttractState extends MusicBeatState { - static final ATTRACT_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('erectTeaser', 'shared')); + static final ATTRACT_VIDEO_PATH:String = Paths.stripLibrary(Paths.videos('erectTeaser')); public override function create():Void { From dbae4aff8fde2621c370388c72e003f3fd4e7027 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 29 Apr 2024 19:28:47 -0400 Subject: [PATCH 48/60] Fix crash when initializing screenshots when there is no save data --- source/funkin/Preferences.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index d8066c581..c4bda2b9a 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -53,7 +53,7 @@ class Preferences static function get_flashingLights():Bool { - return Save.instance.options.flashingLights; + return Save?.instance?.options?.flashingLights ?? true; } static function set_flashingLights(value:Bool):Bool From e1327f1b2c05d71950a308c0cd13694654adafa8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 23:00:39 -0400 Subject: [PATCH 49/60] remove filter from touch here to play, and make it more responsive to input --- art | 2 +- .../ui/transition/preload/FunkinPreloader.hx | 68 ++++++++++++++----- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/art b/art index 00463685f..f72947b65 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 00463685fa570f0c853d08e250b46ef80f30bc48 +Subproject commit f72947b65fe0555821f827dccd562f01d308486d diff --git a/source/funkin/ui/transition/preload/FunkinPreloader.hx b/source/funkin/ui/transition/preload/FunkinPreloader.hx index 9f509df9c..1bcfc5d5c 100644 --- a/source/funkin/ui/transition/preload/FunkinPreloader.hx +++ b/source/funkin/ui/transition/preload/FunkinPreloader.hx @@ -112,6 +112,7 @@ class FunkinPreloader extends FlxBasePreloader var logo:Bitmap; #if TOUCH_HERE_TO_PLAY var touchHereToPlay:Bitmap; + var touchHereSprite:Sprite; #end var progressBarPieces:Array; var progressBar:Bitmap; @@ -123,6 +124,7 @@ class FunkinPreloader extends FlxBasePreloader var stereoText:TextField; var vfdShader:VFDOverlay; + var vfdBitmap:Bitmap; var box:Sprite; var progressLines:Sprite; @@ -162,18 +164,6 @@ class FunkinPreloader extends FlxBasePreloader }); // addChild(logo); - #if TOUCH_HERE_TO_PLAY - touchHereToPlay = createBitmap(TouchHereToPlayImage, function(bmp:Bitmap) { - // Scale and center the touch to start image. - // We have to do this inside the async call, after the image size is known. - bmp.scaleX = bmp.scaleY = ratio; - bmp.x = (this._width - bmp.width) / 2; - bmp.y = (this._height - bmp.height) / 2; - }); - touchHereToPlay.alpha = 0.0; - addChild(touchHereToPlay); - #end - var amountOfPieces:Int = 16; progressBarPieces = []; var maxBarWidth = this._width - BAR_PADDING * 2; @@ -289,11 +279,27 @@ class FunkinPreloader extends FlxBasePreloader // gradient.graphics.endFill(); // addChild(gradient); - var vfdBitmap:Bitmap = new Bitmap(new BitmapData(this._width, this._height, true, 0xFFFFFFFF)); + vfdBitmap = new Bitmap(new BitmapData(this._width, this._height, true, 0xFFFFFFFF)); addChild(vfdBitmap); vfdShader = new VFDOverlay(); vfdBitmap.shader = vfdShader; + + #if TOUCH_HERE_TO_PLAY + touchHereToPlay = createBitmap(TouchHereToPlayImage, function(bmp:Bitmap) { + // Scale and center the touch to start image. + // We have to do this inside the async call, after the image size is known. + bmp.scaleX = bmp.scaleY = ratio; + bmp.x = (this._width - bmp.width) / 2; + bmp.y = (this._height - bmp.height) / 2; + }); + touchHereToPlay.alpha = 0.0; + + touchHereSprite = new Sprite(); + touchHereSprite.buttonMode = false; + touchHereSprite.addChild(touchHereToPlay); + addChild(touchHereSprite); + #end } var lastElapsed:Float = 0.0; @@ -802,9 +808,14 @@ class FunkinPreloader extends FlxBasePreloader if (touchHereToPlay.alpha < 1.0) { + touchHereSprite.buttonMode = true; touchHereToPlay.alpha = 1.0; + removeChild(vfdBitmap); addEventListener(MouseEvent.CLICK, onTouchHereToPlay); + touchHereSprite.addEventListener(MouseEvent.MOUSE_OVER, overTouchHereToPlay); + touchHereSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownTouchHereToPlay); + touchHereSprite.addEventListener(MouseEvent.MOUSE_OUT, outTouchHereToPlay); } return 1.0; @@ -818,9 +829,34 @@ class FunkinPreloader extends FlxBasePreloader } #if TOUCH_HERE_TO_PLAY + function overTouchHereToPlay(e:MouseEvent):Void + { + touchHereToPlay.scaleX = touchHereToPlay.scaleY = ratio * 1.1; + touchHereToPlay.x = (this._width - touchHereToPlay.width) / 2; + touchHereToPlay.y = (this._height - touchHereToPlay.height) / 2; + } + + function outTouchHereToPlay(e:MouseEvent):Void + { + touchHereToPlay.scaleX = touchHereToPlay.scaleY = ratio * 1; + touchHereToPlay.x = (this._width - touchHereToPlay.width) / 2; + touchHereToPlay.y = (this._height - touchHereToPlay.height) / 2; + } + + function mouseDownTouchHereToPlay(e:MouseEvent):Void + { + touchHereToPlay.y += 10; + } + function onTouchHereToPlay(e:MouseEvent):Void { + touchHereToPlay.x = (this._width - touchHereToPlay.width) / 2; + touchHereToPlay.y = (this._height - touchHereToPlay.height) / 2; + removeEventListener(MouseEvent.CLICK, onTouchHereToPlay); + touchHereSprite.removeEventListener(MouseEvent.MOUSE_OVER, overTouchHereToPlay); + touchHereSprite.removeEventListener(MouseEvent.MOUSE_OUT, outTouchHereToPlay); + touchHereSprite.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownTouchHereToPlay); // This is the actual thing that makes the game load. immediatelyStartGame(); @@ -999,9 +1035,9 @@ class FunkinPreloader extends FlxBasePreloader */ override function createSiteLockFailureScreen():Void { - addChild(createSiteLockFailureBackground(Constants.COLOR_PRELOADER_LOCK_BG, Constants.COLOR_PRELOADER_LOCK_BG)); - addChild(createSiteLockFailureIcon(Constants.COLOR_PRELOADER_LOCK_FG, 0.9)); - addChild(createSiteLockFailureText(30)); + // addChild(createSiteLockFailureBackground(Constants.COLOR_PRELOADER_LOCK_BG, Constants.COLOR_PRELOADER_LOCK_BG)); + // addChild(createSiteLockFailureIcon(Constants.COLOR_PRELOADER_LOCK_FG, 0.9)); + // addChild(createSiteLockFailureText(30)); } /** From 9f95c86850c2efc3250ee1ea3d3fada32d29b338 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Tue, 30 Apr 2024 04:03:42 +0100 Subject: [PATCH 50/60] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 4b7dd53fe..bb7e07cc0 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4b7dd53fe3e24c4a80649b63f95ab49628776d70 +Subproject commit bb7e07cc0e5567e2968ccc0c2bf95e64a6f8cabd From bd551092dc70d8eceb4dade74f25af0e681f61b2 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 29 Apr 2024 23:31:55 -0400 Subject: [PATCH 51/60] persistentUpdate true main menu --- source/funkin/ui/mainmenu/MainMenuState.hx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index b4631d74d..11c7c6ebf 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -54,7 +54,7 @@ class MainMenuState extends MusicBeatState playMenuMusic(); - persistentUpdate = false; + persistentUpdate = true; persistentDraw = true; var bg:FlxSprite = new FlxSprite(Paths.image('menuBG')); @@ -103,6 +103,7 @@ class MainMenuState extends MusicBeatState // Freeplay has its own custom transition FlxTransitionableState.skipNextTransIn = true; FlxTransitionableState.skipNextTransOut = true; + openSubState(new FreeplayState()); }); @@ -274,6 +275,8 @@ class MainMenuState extends MusicBeatState public function openPrompt(prompt:Prompt, onClose:Void->Void):Void { menuItems.enabled = false; + persistentUpdate = false; + prompt.closeCallback = function() { menuItems.enabled = true; if (onClose != null) onClose(); @@ -326,6 +329,8 @@ class MainMenuState extends MusicBeatState #if CHART_EDITOR_SUPPORTED if (controls.DEBUG_MENU) { + persistentUpdate = false; + FlxG.state.openSubState(new DebugMenuSubState()); } #end From ce24ad1a8a9b034dd2d7cb047ab4c3f557289216 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 00:40:42 -0400 Subject: [PATCH 52/60] add fullscreen rebindable keybind across whole game --- source/funkin/InitState.hx | 1 + source/funkin/input/Controls.hx | 20 ++++++++++++++++++++ source/funkin/ui/title/TitleState.hx | 3 +-- source/funkin/util/WindowUtil.hx | 10 ++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 2377343c3..00d34fadb 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -74,6 +74,7 @@ class InitState extends FlxState // // Setup window events (like callbacks for onWindowClose) + // and fullscreen keybind setup WindowUtil.initWindowEvents(); // Disable the thing on Windows where it tries to send a bug report to Microsoft because why do they care? WindowUtil.disableCrashHandler(); diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index 14b226d88..1983d413b 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -66,6 +66,7 @@ class Controls extends FlxActionSet var _volume_up = new FunkinAction(Action.VOLUME_UP); var _volume_down = new FunkinAction(Action.VOLUME_DOWN); var _volume_mute = new FunkinAction(Action.VOLUME_MUTE); + var _fullscreen = new FunkinAction(Action.FULLSCREEN); var byName:Map = new Map(); @@ -272,6 +273,11 @@ class Controls extends FlxActionSet inline function get_VOLUME_MUTE() return _volume_mute.check(); + public var FULLSCREEN(get, never):Bool; + + inline function get_FULLSCREEN() + return _fullscreen.check(); + public function new(name, scheme:KeyboardScheme = null) { super(name); @@ -296,6 +302,7 @@ class Controls extends FlxActionSet add(_volume_up); add(_volume_down); add(_volume_mute); + add(_fullscreen); for (action in digitalActions) { if (Std.isOfType(action, FunkinAction)) { @@ -399,6 +406,7 @@ class Controls extends FlxActionSet case VOLUME_UP: _volume_up; case VOLUME_DOWN: _volume_down; case VOLUME_MUTE: _volume_mute; + case FULLSCREEN: _fullscreen; } } @@ -474,6 +482,8 @@ class Controls extends FlxActionSet func(_volume_down, JUST_PRESSED); case VOLUME_MUTE: func(_volume_mute, JUST_PRESSED); + case FULLSCREEN: + func(_fullscreen, JUST_PRESSED); } } @@ -668,6 +678,7 @@ class Controls extends FlxActionSet bindKeys(Control.VOLUME_UP, getDefaultKeybinds(scheme, Control.VOLUME_UP)); bindKeys(Control.VOLUME_DOWN, getDefaultKeybinds(scheme, Control.VOLUME_DOWN)); bindKeys(Control.VOLUME_MUTE, getDefaultKeybinds(scheme, Control.VOLUME_MUTE)); + bindKeys(Control.FULLSCREEN, getDefaultKeybinds(scheme, Control.FULLSCREEN)); bindMobileLol(); } @@ -696,6 +707,8 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS, NUMPADPLUS]; case Control.VOLUME_DOWN: return [MINUS, NUMPADMINUS]; case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO]; + case Control.FULLSCREEN: return [FlxKey.F]; + } case Duo(true): switch (control) { @@ -719,6 +732,8 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS]; case Control.VOLUME_DOWN: return [MINUS]; case Control.VOLUME_MUTE: return [ZERO]; + case Control.FULLSCREEN: return [FlxKey.F]; + } case Duo(false): switch (control) { @@ -742,6 +757,8 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [NUMPADPLUS]; case Control.VOLUME_DOWN: return [NUMPADMINUS]; case Control.VOLUME_MUTE: return [NUMPADZERO]; + case Control.FULLSCREEN: return []; + } default: // Fallthrough. @@ -876,6 +893,7 @@ class Controls extends FlxActionSet case Control.CUTSCENE_ADVANCE: return [A]; case Control.DEBUG_MENU: return []; case Control.DEBUG_CHART: return []; + case Control.FULLSCREEN: return []; default: // Fallthrough. } @@ -1398,6 +1416,7 @@ enum Control ACCEPT; BACK; PAUSE; + FULLSCREEN; // CUTSCENE CUTSCENE_ADVANCE; // SCREENSHOT @@ -1443,6 +1462,7 @@ enum abstract Action(String) to String from String var BACK = "back"; var PAUSE = "pause"; var RESET = "reset"; + var FULLSCREEN = "fullscreen"; // SCREENSHOT var SCREENSHOT = "screenshot"; // CUTSCENE diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index d122bf7c1..012e3669a 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -251,7 +251,7 @@ class TitleState extends MusicBeatState var transitioning:Bool = false; - override function update(elapsed:Float) + override function update(elapsed:Float):Void { FlxG.bitmapLog.add(FlxG.camera.buffer); @@ -286,7 +286,6 @@ class TitleState extends MusicBeatState } 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? var pressedEnter:Bool = FlxG.keys.justPressed.ENTER; diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index f73fe11ce..763d84853 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -90,6 +90,16 @@ class WindowUtil openfl.Lib.current.stage.application.onExit.add(function(exitCode:Int) { windowExit.dispatch(exitCode); }); + + openfl.Lib.current.stage.addEventListener(openfl.events.KeyboardEvent.KEY_DOWN, (e:openfl.events.KeyboardEvent) -> { + for (key in PlayerSettings.player1.controls.getKeysForAction(FULLSCREEN)) + { + if (e.keyCode == key) + { + openfl.Lib.application.window.fullscreen = !openfl.Lib.application.window.fullscreen; + } + } + }); } /** From 0c72f0f5a2e1a2ef2047e7a89b0d72af0f104f48 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 01:09:40 -0400 Subject: [PATCH 53/60] fix spacing on the fnf text on the preloader --- .../ui/transition/preload/FunkinPreloader.hx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/transition/preload/FunkinPreloader.hx b/source/funkin/ui/transition/preload/FunkinPreloader.hx index 1bcfc5d5c..29300aed0 100644 --- a/source/funkin/ui/transition/preload/FunkinPreloader.hx +++ b/source/funkin/ui/transition/preload/FunkinPreloader.hx @@ -120,6 +120,7 @@ class FunkinPreloader extends FlxBasePreloader var progressRightText:TextField; var dspText:TextField; + var fnfText:TextField; var enhancedText:TextField; var stereoText:TextField; @@ -202,6 +203,7 @@ class FunkinPreloader extends FlxBasePreloader // Create the progress message. progressLeftText = new TextField(); dspText = new TextField(); + fnfText = new TextField(); enhancedText = new TextField(); stereoText = new TextField(); @@ -252,6 +254,15 @@ class FunkinPreloader extends FlxBasePreloader dspText.y = -5; box.addChild(dspText); + fnfText.selectable = false; + fnfText.textColor = 0x000000; + fnfText.width = this._width; + fnfText.height = 20; + fnfText.x = 75; + fnfText.y = -5; + fnfText.text = 'FNF'; + box.addChild(fnfText); + enhancedText.selectable = false; enhancedText.textColor = Constants.COLOR_PRELOADER_BAR; enhancedText.width = this._width; @@ -967,9 +978,13 @@ class FunkinPreloader extends FlxBasePreloader progressLeftText.text = text; dspText.defaultTextFormat = new TextFormat("Quantico", 20, 0x000000, false); - dspText.text = 'DSP\t\t\t\t\tFNF'; // fukin dum.... + dspText.text = 'DSP'; // fukin dum.... dspText.textColor = 0x000000; + fnfText.defaultTextFormat = new TextFormat("Quantico", 20, 0x000000, false); + fnfText.text = 'FNF'; + fnfText.textColor = 0x000000; + enhancedText.defaultTextFormat = new TextFormat("Inconsolata Black", 16, Constants.COLOR_PRELOADER_BAR, false); enhancedText.text = 'ENHANCED'; enhancedText.textColor = Constants.COLOR_PRELOADER_BAR; @@ -1007,6 +1022,7 @@ class FunkinPreloader extends FlxBasePreloader progressRightText.alpha = logo.alpha; box.alpha = logo.alpha; dspText.alpha = logo.alpha; + fnfText.alpha = logo.alpha; enhancedText.alpha = logo.alpha; stereoText.alpha = logo.alpha; progressLines.alpha = logo.alpha; From b12d86c959bacb2af6392c134dcae215c01ca20d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 01:33:29 -0400 Subject: [PATCH 54/60] completion number and box fadeout --- source/funkin/ui/freeplay/FreeplayState.hx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index bd558f747..660c794ec 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -430,6 +430,7 @@ class FreeplayState extends MusicBeatSubState add(fp); var clearBoxSprite:FlxSprite = new FlxSprite(1165, 65).loadGraphic(Paths.image('freeplay/clearBox')); + clearBoxSprite.visible = false; add(clearBoxSprite); txtCompletion = new AtlasText(1185, 87, '69', AtlasFont.FREEPLAY_CLEAR); @@ -466,7 +467,7 @@ class FreeplayState extends MusicBeatSubState } }; - exitMovers.set([fp, txtCompletion, fnfHighscoreSpr], + exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, txtCompletion, clearBoxSprite], { x: FlxG.width, speed: 0.3 @@ -509,6 +510,7 @@ class FreeplayState extends MusicBeatSubState fp.visible = true; fp.updateScore(0); + clearBoxSprite.visible = true; txtCompletion.visible = true; intendedCompletion = 0; @@ -752,13 +754,13 @@ class FreeplayState extends MusicBeatSubState switch (txtCompletion.text.length) { case 3: - txtCompletion.x = 1185 - 10; + txtCompletion.offset.x = 10; case 2: - txtCompletion.x = 1185; + txtCompletion.offset.x = 0; case 1: - txtCompletion.x = 1185 + 24; + txtCompletion.offset.x = -24; default: - txtCompletion.x = 1185; + txtCompletion.offset.x = 0; } handleInputs(elapsed); From 84668432ba4f675fbe0cc0aa8a21e49571715aec Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 01:38:00 -0400 Subject: [PATCH 55/60] better tween in for bg dad art --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 660c794ec..95e2c0342 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -342,7 +342,7 @@ class FreeplayState extends MusicBeatSubState }); add(bgDad); - FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.75}, 1, {ease: FlxEase.quintOut}); + FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.75}, 0.7, {ease: FlxEase.quintOut}); blackOverlayBullshitLOLXD.shader = bgDad.shader; From 61012fab68330fc2edade83dbeede06c62549e3e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 03:22:30 -0400 Subject: [PATCH 56/60] dad art tween and shader on ost text --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 95e2c0342..860b8f235 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -336,7 +336,6 @@ class FreeplayState extends MusicBeatSubState exitMovers.set([blackOverlayBullshitLOLXD, bgDad], { x: FlxG.width * 1.5, - y: bgDad.height, speed: 0.4, wait: 0 }); @@ -409,6 +408,7 @@ class FreeplayState extends MusicBeatSubState var sillyStroke:StrokeShader = new StrokeShader(0xFFFFFFFF, 2, 2); fnfFreeplay.shader = sillyStroke; + ostName.shader = sillyStroke; add(fnfFreeplay); add(ostName); From ce93a82b5355bca4d567cb490178649564b06bb4 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 07:14:21 -0400 Subject: [PATCH 57/60] pixel death sound fix --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index bb7e07cc0..47bbe52ec 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit bb7e07cc0e5567e2968ccc0c2bf95e64a6f8cabd +Subproject commit 47bbe52ecb823e4fe1d2fd20914c28b509277073 From 23dd9937ecca2ede2ff3a617120eb333dead992d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 07:21:45 -0400 Subject: [PATCH 58/60] black camera bg --- source/funkin/play/PlayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 775f3c25b..978bacab8 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -568,7 +568,7 @@ class PlayState extends MusicBeatSubState var generatedMusic:Bool = false; var perfectMode:Bool = false; - static final BACKGROUND_COLOR:FlxColor = FlxColor.MAGENTA; + static final BACKGROUND_COLOR:FlxColor = FlxColor.BLACK; /** * Instantiate a new PlayState. From aff9ee5312e799229a7453181365a361b3c07851 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 07:54:42 -0400 Subject: [PATCH 59/60] volume preference fix --- source/funkin/ui/options/FunkinSoundTray.hx | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/funkin/ui/options/FunkinSoundTray.hx b/source/funkin/ui/options/FunkinSoundTray.hx index b8c408508..792e38fc4 100644 --- a/source/funkin/ui/options/FunkinSoundTray.hx +++ b/source/funkin/ui/options/FunkinSoundTray.hx @@ -86,26 +86,26 @@ class FunkinSoundTray extends FlxSoundTray _timer -= (MS / 1000); alphaTarget = 1; } - else if (y > -height) + else if (y >= -height) { lerpYPos = -height - 10; alphaTarget = 0; + } - if (y <= -height) + if (y <= -height) + { + visible = false; + active = false; + + #if FLX_SAVE + // Save sound preferences + if (FlxG.save.isBound) { - visible = false; - active = false; - - #if FLX_SAVE - // Save sound preferences - if (FlxG.save.isBound) - { - FlxG.save.data.mute = FlxG.sound.muted; - FlxG.save.data.volume = FlxG.sound.volume; - FlxG.save.flush(); - } - #end + FlxG.save.data.mute = FlxG.sound.muted; + FlxG.save.data.volume = FlxG.sound.volume; + FlxG.save.flush(); } + #end } } From 80a881a5ce96806b59c5603a5cc28f5cae430df2 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 30 Apr 2024 08:13:39 -0400 Subject: [PATCH 60/60] autoPause save fix --- source/funkin/Preferences.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index c4bda2b9a..6d11514aa 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -115,7 +115,7 @@ class Preferences static function get_autoPause():Bool { - return Save.instance.options.autoPause; + return Save?.instance?.options?.autoPause ?? true; } static function set_autoPause(value:Bool):Bool