From eb40d3bda5cb0853ef94250cccf277d6bef843e4 Mon Sep 17 00:00:00 2001 From: Keoiki <55053690+Keoiki@users.noreply.github.com> Date: Tue, 22 Apr 2025 06:09:13 +0300 Subject: [PATCH] Fix measure number values and positions (and remove 2 comments I forgot to remove last time) --- source/funkin/Conductor.hx | 57 +++++++++++++++++-- .../components/ChartEditorMeasureTicks.hx | 19 +++---- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index b4c712742..e90406f95 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -469,7 +469,7 @@ class Conductor this.currentStepTime = FlxMath.roundDecimal((currentTimeChange.beatTime * Constants.STEPS_PER_BEAT) + (this.songPosition - currentTimeChange.timeStamp) / stepLengthMs, 6); this.currentBeatTime = currentStepTime / Constants.STEPS_PER_BEAT; - this.currentMeasureTime = getMeasureTime(songPos); + this.currentMeasureTime = getTimeInMeasures(songPos); this.currentStep = Math.floor(currentStepTime); this.currentBeat = Math.floor(currentBeatTime); this.currentMeasure = Math.floor(currentMeasureTime); @@ -594,11 +594,11 @@ class Conductor } /** - * Calculates the measure time for a given time in milliseconds. + * Given a time in milliseconds, return a time in measures. * @param ms The time in milliseconds. * @return The time in measures. */ - public function getMeasureTime(ms:Float):Float + public function getTimeInMeasures(ms:Float):Float { if (timeChanges.length == 0) { @@ -639,6 +639,53 @@ class Conductor } } + /** + * Given a time in measures and fractional measures, return a time in milliseconds. + * @param measureTime The time in measures. + * @return The time in milliseconds. + */ + public function getMeasureTimeInMs(measureTime:Float):Float + { + if (timeChanges.length == 0) + { + // Assume a constant BPM equal to the forced value. + return measureTime * stepLengthMs * stepsPerMeasure; + } + else + { + var resultMs:Float = 0; + + var lastTimeChange:SongTimeChange = timeChanges[0]; + var i:Int = -1; + for (timeChange in timeChanges) + { + var currentTimeChangeMeasureTime:Float = getTimeInMeasures(timeChange.timeStamp); + if (measureTime >= currentTimeChangeMeasureTime) + { + // We do NOT want to add the current time change's MEASURE LENGTH to the result, same for if we're inside the song's last time change. + if (measureTime < currentTimeChangeMeasureTime || i == timeChanges.length - 1) + { + // However, we still want this for the ending calculation. + lastTimeChange = timeChange; + break; + } + var currentStepLengthMs:Float = (((Constants.SECS_PER_MIN / lastTimeChange.bpm) * Constants.MS_PER_SEC) * (4 / lastTimeChange.timeSignatureDen)) / Constants.STEPS_PER_BEAT; + var currentStepsPerMeasure:Int = lastTimeChange.timeSignatureNum * Constants.STEPS_PER_BEAT; + resultMs += (currentTimeChangeMeasureTime - getTimeInMeasures(lastTimeChange.timeStamp)) * currentStepLengthMs * currentStepsPerMeasure; + lastTimeChange = timeChange; + } + i++; + } + + var remainingStepLengthMs:Float = (((Constants.SECS_PER_MIN / lastTimeChange.bpm) * Constants.MS_PER_SEC) * (4 / lastTimeChange.timeSignatureDen)) / Constants.STEPS_PER_BEAT; + var remainingStepsPerMeasure:Int = lastTimeChange.timeSignatureNum * Constants.STEPS_PER_BEAT; + var remainingFractionalMeasure:Float = (measureTime - getTimeInMeasures(lastTimeChange.timeStamp)) * remainingStepLengthMs * remainingStepsPerMeasure; + resultMs += remainingFractionalMeasure; + + return resultMs; + } + } + /** * Given a time in milliseconds, return a time in steps. * @param ms The time in milliseconds. @@ -678,7 +725,7 @@ class Conductor var resultFractionalStep:Float = (ms - lastTimeChange.timeStamp) / lastStepLengthMs; resultStep += resultFractionalStep; - return resultStep; // FIX THIS SHIT + return resultStep; } } @@ -720,7 +767,7 @@ class Conductor var lastStepLengthMs:Float = (((Constants.SECS_PER_MIN / lastTimeChange.bpm) * Constants.MS_PER_SEC) * (4 / lastTimeChange.timeSignatureDen)) / Constants.STEPS_PER_BEAT; resultMs += (stepTime - lastTimeChange.beatTime * Constants.STEPS_PER_BEAT) * lastStepLengthMs; - return resultMs; // FIX THIS SHIT + return resultMs; } } diff --git a/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx b/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx index 255c6d9ed..e61329ba3 100644 --- a/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx +++ b/source/funkin/ui/debug/charting/components/ChartEditorMeasureTicks.hx @@ -49,33 +49,32 @@ class ChartEditorMeasureTicks extends FlxTypedSpriteGroup } /** - * At time of writing, we only have to manipulate one measure number because we can only see one measure at a time. + * Update all 5 measure numbers, since that's the most we can really see at a time, even if barely. + * Please excuse the horror you're about to witness. */ function updateMeasureNumber() { - var viewTopPosition = 0 - this.y; - var viewHeight = FlxG.height - ChartEditorState.MENU_BAR_HEIGHT - ChartEditorState.PLAYBAR_HEIGHT; - var viewBottomPosition = viewTopPosition + viewHeight; + var currentPixelScrollPositionInMs = Conductor.instance?.getStepTimeInMs((this.chartEditorState?.scrollPositionInPixels + 1) / ChartEditorState.GRID_SIZE); + var measureNumberInViewport = Math.floor(Conductor.instance?.getTimeInMeasures(currentPixelScrollPositionInMs)); for (i in 0...measureNumbers.length) { var measureNumber:FlxText = measureNumbers[i]; if (measureNumber == null) continue; - var measureNumberInViewport = Math.floor(viewTopPosition / ChartEditorState.GRID_SIZE / Conductor.instance.stepsPerMeasure) + 1 + i; - var measureNumberPosition = measureNumberInViewport * ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure; + var measureNumberPosition = Math.floor(Conductor.instance?.getTimeInSteps(Conductor.instance?.getMeasureTimeInMs(measureNumberInViewport + + i)) * ChartEditorState.GRID_SIZE); measureNumber.y = measureNumberPosition + this.y; // Show the measure number only if it isn't beneath the end of the note grid. // Using measureNumber + 1 because the cut-off bar at the bottom is technically a bar, but it looks bad if a measure number shows up there. - if ((measureNumberInViewport + 1) < chartEditorState.songLengthInSteps / Conductor.instance.stepsPerMeasure) - measureNumber.text = '${measureNumberInViewport + 1}'; + var fixedMeasureNumberValue = measureNumberInViewport + i + 1; + if (fixedMeasureNumberValue < Math.ceil(Conductor.instance?.getTimeInMeasures(chartEditorState.songLengthInMs))) + measureNumber.text = '${fixedMeasureNumberValue}'; else measureNumber.text = ''; } - - // trace(measureNumber.text + ' at ' + measureNumber.y); } public function setHeight(songLengthInPixels:Float):Void