Beispiel #1
0
    public static float LiveTickToTime(uint position, float resolution, BPM initialBpm, IList <SyncTrack> synctrack)
    {
        double time    = 0;
        BPM    prevBPM = initialBpm;

        foreach (SyncTrack syncTrack in synctrack)
        {
            BPM bpmInfo = syncTrack as BPM;

            if (bpmInfo == null)
            {
                continue;
            }

            if (bpmInfo.tick > position)
            {
                break;
            }
            else
            {
                time   += TickFunctions.DisToTime(prevBPM.tick, bpmInfo.tick, resolution, prevBPM.value / 1000.0f);
                prevBPM = bpmInfo;
            }
        }

        time += TickFunctions.DisToTime(prevBPM.tick, position, resolution, prevBPM.value / 1000.0f);

        return((float)time);
    }
Beispiel #2
0
    /// <summary>
    /// Converts a tick position into the time it will appear in the song.
    /// </summary>
    /// <param name="position">Tick position.</param>
    /// <param name="resolution">Ticks per beat, usually provided from the resolution song of a Song class.</param>
    /// <returns>Returns the time in seconds.</returns>
    public float TickToTime(uint position, float resolution)
    {
        int previousBPMPos = SongObjectHelper.FindClosestPosition(position, bpms);

        if (bpms[previousBPMPos].tick > position)
        {
            --previousBPMPos;
        }

        BPM   prevBPM = bpms[previousBPMPos];
        float time    = prevBPM.assignedTime;

        time += (float)TickFunctions.DisToTime(prevBPM.tick, position, resolution, prevBPM.value / 1000.0f);

        return(time);
    }
Beispiel #3
0
    bool AdjustForAnchors(uint newBpmValue)
    {
        ChartEditor.GetInstance().songObjectPoolManager.SetAllPoolsDirty();

        int pos = SongObjectHelper.FindObjectPosition(currentBPM, currentBPM.song.bpms);

        if (pos != SongObjectHelper.NOTFOUND)
        {
            BPM anchor      = null;
            BPM bpmToAdjust = null;

            int anchorPos = 0;

            // Get the next anchor
            for (int i = pos + 1; i < currentBPM.song.bpms.Count; ++i)
            {
                if (currentBPM.song.bpms[i].anchor != null)
                {
                    anchor    = currentBPM.song.bpms[i];
                    anchorPos = i;
                    // Get the bpm before that anchor
                    bpmToAdjust = currentBPM.song.bpms[i - 1];

                    break;
                }
            }

            if (anchor == null || bpmToAdjust == currentBPM)
            {
                if (currentBPM.value != newBpmValue)
                {
                    ChartEditor.isDirty = true;
                }

                currentBPM.value = newBpmValue;
                return(true);
            }

            // Calculate the minimum the bpm can adjust to
            const float MIN_DT = 0.01f;

            float bpmTime    = (float)anchor.anchor - MIN_DT;
            float resolution = currentBPM.song.resolution;
            // Calculate the time of the 2nd bpm pretending that the adjustable one is super close to the anchor
            for (int i = anchorPos - 1; i > pos + 1; --i)
            {
                // Calculate up until 2 bpms before the anchor
                // Re-hash of the actual time calculation equation in Song.cs
                bpmTime -= (float)TickFunctions.DisToTime(currentBPM.song.bpms[i - 1].tick, currentBPM.song.bpms[i].tick, resolution, currentBPM.song.bpms[i - 1].value / 1000.0f);
            }

            float timeBetweenFirstAndSecond = bpmTime - currentBPM.time;
            // What bpm will result in this exact time difference?
            uint minVal = (uint)(Mathf.Ceil((float)TickFunctions.DisToBpm(currentBPM.song.bpms[pos].tick, currentBPM.song.bpms[pos + 1].tick, timeBetweenFirstAndSecond, currentBPM.song.resolution)) * 1000);

            if (newBpmValue < minVal)
            {
                newBpmValue = minVal;
            }

            if (anchorAdjustment == null)
            {
                anchorAdjustment = bpmToAdjust;
                anchorAdjustmentOriginalValue = new BPM(bpmToAdjust);
            }

            BPM  anchorBPM = anchor;
            uint oldValue  = currentBPM.value;
            currentBPM.value = newBpmValue;

            double deltaTime = (double)anchorBPM.anchor - editor.currentSong.LiveTickToTime(bpmToAdjust.tick, editor.currentSong.resolution);
            uint   newValue  = (uint)Mathf.Round((float)(TickFunctions.DisToBpm(bpmToAdjust.tick, anchorBPM.tick, deltaTime, editor.currentSong.resolution) * 1000.0d));
            currentBPM.value = oldValue;
            if (deltaTime > 0 && newValue > 0)
            {
                if (newValue != 0)
                {
                    bpmToAdjust.value = newValue;
                }
                currentBPM.value = newBpmValue;

                ChartEditor.isDirty = true;
            }
        }
        else
        {
            if (currentBPM.value != newBpmValue)
            {
                ChartEditor.isDirty = true;
            }

            currentBPM.value = newBpmValue;
        }

        return(true);
    }
    static MoonscraperEngine.ICommand GenerateCommandsAdjustedForAnchors(BPM currentBPM, uint desiredBpmValue)
    {
        List <SongEditCommand> commands = new List <SongEditCommand>();

        int pos = SongObjectHelper.FindObjectPosition(currentBPM, currentBPM.song.bpms);

        if (pos != SongObjectHelper.NOTFOUND)
        {
            BPM anchor      = null;
            BPM bpmToAdjust = null;

            int anchorPos = 0;

            // Get the next anchor
            for (int i = pos + 1; i < currentBPM.song.bpms.Count; ++i)
            {
                if (currentBPM.song.bpms[i].anchor != null)
                {
                    anchor    = currentBPM.song.bpms[i];
                    anchorPos = i;
                    // Get the bpm before that anchor
                    bpmToAdjust = currentBPM.song.bpms[i - 1];

                    break;
                }
            }

            if (anchor == null || bpmToAdjust == currentBPM)
            {
                commands.Add(new SongEditModify <BPM>(currentBPM, new BPM(currentBPM.tick, desiredBpmValue, currentBPM.anchor)));
                return(new BatchedSongEditCommand(commands));
            }

            // Calculate the minimum the bpm can adjust to
            const float MIN_DT = 0.01f;

            float bpmTime    = (float)anchor.anchor - MIN_DT;
            float resolution = currentBPM.song.resolution;
            // Calculate the time of the 2nd bpm pretending that the adjustable one is super close to the anchor
            for (int i = anchorPos - 1; i > pos + 1; --i)
            {
                // Calculate up until 2 bpms before the anchor
                // Re-hash of the actual time calculation equation in Song.cs
                bpmTime -= (float)TickFunctions.DisToTime(currentBPM.song.bpms[i - 1].tick, currentBPM.song.bpms[i].tick, resolution, currentBPM.song.bpms[i - 1].value / 1000.0f);
            }

            float timeBetweenFirstAndSecond = bpmTime - currentBPM.time;
            // What bpm will result in this exact time difference?
            uint minVal = (uint)(Mathf.Ceil((float)TickFunctions.DisToBpm(currentBPM.song.bpms[pos].tick, currentBPM.song.bpms[pos + 1].tick, timeBetweenFirstAndSecond, currentBPM.song.resolution)) * 1000);

            if (desiredBpmValue < minVal)
            {
                desiredBpmValue = minVal;
            }

            BPM  anchorBPM = anchor;
            uint oldValue  = currentBPM.value;

            ChartEditor editor = ChartEditor.Instance;
            currentBPM.value = desiredBpmValue; // Very much cheating, better to not do this
            double deltaTime = (double)anchorBPM.anchor - editor.currentSong.LiveTickToTime(bpmToAdjust.tick, editor.currentSong.resolution);
            uint   newValue  = (uint)Mathf.Round((float)(TickFunctions.DisToBpm(bpmToAdjust.tick, anchorBPM.tick, deltaTime, editor.currentSong.resolution) * 1000.0d));
            currentBPM.value = oldValue;

            uint finalValue = oldValue;
            if (deltaTime > 0 && newValue > 0)
            {
                if (newValue != 0)
                {
                    commands.Add(new SongEditModify <BPM>(bpmToAdjust, new BPM(bpmToAdjust.tick, newValue, bpmToAdjust.anchor)));
                }

                finalValue = desiredBpmValue;
            }

            desiredBpmValue = finalValue;
        }

        if (desiredBpmValue == currentBPM.value)
        {
            return(null);
        }

        commands.Add(new SongEditModify <BPM>(currentBPM, new BPM(currentBPM.tick, desiredBpmValue, currentBPM.anchor)));
        return(new BatchedSongEditCommand(commands));
    }