コード例 #1
0
    void UpdateBeatLines4()
    {
        int measurePoolPos = 0, beatPoolPos = 0, quarterPoolPos = 0;

        Song song           = editor.currentSong;
        uint startRange     = song.WorldPositionToSnappedTick(editor.camYMin.position.y, 8);
        uint endRange       = editor.maxPos;
        var  timeSignatures = editor.currentSong.timeSignatures;
        int  startIndex     = SongObjectHelper.FindClosestPositionRoundedDown(startRange, timeSignatures);

        for (int tsIndex = startIndex; tsIndex < timeSignatures.Count && timeSignatures[tsIndex].tick <= endRange; ++tsIndex)
        {
            TimeSignature ts = timeSignatures[tsIndex];

            uint nextTSTick = tsIndex + 1 < timeSignatures.Count ? timeSignatures[tsIndex + 1].tick : endRange;

            TimeSignature.MeasureInfo measureInfo = ts.GetMeasureInfo();

            measurePoolPos += RenderBeatLines(ts, measureInfo.measureLine, measureLinePool, measurePoolPos, startRange, endRange, nextTSTick);
            beatPoolPos    += RenderBeatLines(ts, measureInfo.beatLine, beatLinePool, beatPoolPos, startRange, endRange, nextTSTick);
            quarterPoolPos += RenderBeatLines(ts, measureInfo.quarterBeatLine, quarterBeatLinePool, quarterPoolPos, startRange, endRange, nextTSTick);
        }

        DisableBeatLines(measurePoolPos, measureLinePool);
        DisableBeatLines(beatPoolPos, beatLinePool);
        DisableBeatLines(quarterPoolPos, quarterBeatLinePool);
    }
コード例 #2
0
    public static uint TickToSnappedTick(uint tick, int step, Song song)
    {
        float resolution = song.resolution;

        var           timeSignatures = song.timeSignatures;
        int           tsIndex        = SongObjectHelper.FindClosestPositionRoundedDown(tick, timeSignatures);
        TimeSignature ts             = timeSignatures[tsIndex];
        uint?         endRange       = tsIndex < (timeSignatures.Count - 1) ? (uint?)timeSignatures[tsIndex + 1].tick : null;

        TimeSignature.MeasureInfo measureInfo     = ts.GetMeasureInfo();
        TimeSignature.BeatInfo    measureLineInfo = measureInfo.measureLine;
        TimeSignature.BeatInfo    beatLineInfo    = measureInfo.beatLine;

        uint tickOffsetFromTs     = tick - ts.tick;
        int  measuresFromTsToSnap = (int)((float)tickOffsetFromTs / measureLineInfo.tickGap);
        uint lastMeasureTick      = ts.tick + (uint)(measuresFromTsToSnap * measureLineInfo.tickGap);

        float realBeatStep = step / 4.0f;
        float tickGap      = beatLineInfo.tickGap / realBeatStep * ts.denominator / 4.0f;
        uint  tickOffsetFromLastMeasure  = tick - lastMeasureTick;
        int   beatsFromLastMeasureToSnap = Mathf.RoundToInt((float)tickOffsetFromLastMeasure / tickGap);

        uint snappedTick = lastMeasureTick + (uint)(beatsFromLastMeasureToSnap * tickGap);

        if (endRange.HasValue)
        {
            return(snappedTick < endRange.Value ? snappedTick : endRange.Value);
        }
        else
        {
            return(snappedTick);
        }

        // Old algorithm
        // Snap position based on step
        //float factor = Song.FULL_STEP / (float)step * resolution / Song.STANDARD_BEAT_RESOLUTION;
        //float divisor = tick / factor;
        //float lowerBound = (int)divisor * factor;
        //float remainder = divisor - (int)divisor;
        //
        //if (remainder > 0.5f)
        //    tick = (uint)Mathf.Round(lowerBound + factor);
        //else
        //    tick = (uint)Mathf.Round(lowerBound);
        //
        //return tick;
    }
コード例 #3
0
    static string CheckForErrorsCloneHero(Song song, ref bool hasErrors)
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendLine("Clone Hero validation report: ");

        bool hasErrorsLocal = false;

        // Check that time signature positions line up on the measure from the previous time signature
        {
            var timeSignatures = song.timeSignatures;
            for (int tsIndex = 1; tsIndex < timeSignatures.Count; ++tsIndex)
            {
                TimeSignature             previousTs  = timeSignatures[tsIndex - 1];
                TimeSignature.MeasureInfo measureInfo = previousTs.GetMeasureInfo();

                TimeSignature tsToTest  = timeSignatures[tsIndex];
                uint          deltaTick = tsToTest.tick - previousTs.tick;

                var measureLine = measureInfo.measureLine;
                if (((float)deltaTick % measureLine.tickGap) != 0)      // Doesn't line up on a measure
                {
                    hasErrorsLocal |= true;
                    sb.AppendFormat("\tFound misaligned Time Signature at position {0}. Time signatures must be aligned to the measure set by the previous time signature.\n", tsToTest.tick);
                }
            }
        }

        if (!hasErrorsLocal)
        {
            sb.AppendLine("\tNo errors detected");
        }

        hasErrors |= hasErrorsLocal;

        return(sb.ToString());
    }
コード例 #4
0
    static string CheckForErrorsCloneHero(Song song, ValidationParameters validationParams, ref bool hasErrors)
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendLine("Clone Hero validation report: ");

        bool hasErrorsLocal = false;

        // Check that time signature positions line up on the measure from the previous time signature
        {
            var timeSignatures = song.timeSignatures;
            for (int tsIndex = 1; tsIndex < timeSignatures.Count; ++tsIndex)
            {
                TimeSignature             previousTs  = timeSignatures[tsIndex - 1];
                TimeSignature.MeasureInfo measureInfo = previousTs.GetMeasureInfo();

                TimeSignature tsToTest  = timeSignatures[tsIndex];
                uint          deltaTick = tsToTest.tick - previousTs.tick;

                var measureLine = measureInfo.measureLine;
                if (((float)deltaTick % measureLine.tickGap) != 0)      // Doesn't line up on a measure
                {
                    hasErrorsLocal |= true;
                    sb.AppendFormat("\tFound misaligned Time Signature at position {0}. Time signatures must be aligned to the measure set by the previous time signature.\n", tsToTest.tick);
                }
            }
        }

        // If we have no starpower but more than 1 solo section then CH will interpret this as an RB1 style midi, and misinterpret the solo markers as starpower
        if (validationParams.checkMidiIssues)
        {
            foreach (Song.Instrument instrument in EnumX <Song.Instrument> .Values)
            {
                if (instrument == Song.Instrument.Unrecognised)
                {
                    continue;
                }

                foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values)
                {
                    Chart chart = song.GetChart(instrument, difficulty);

                    if (chart.starPower.Count <= 0)
                    {
                        // Check for solo markers
                        int soloMarkerCount = 0;
                        foreach (ChartEvent ce in chart.events)
                        {
                            if (ce.eventName == MoonscraperChartEditor.Song.IO.MidIOHelper.SoloEventText)
                            {
                                ++soloMarkerCount;

                                if (soloMarkerCount > 1)
                                {
                                    hasErrorsLocal |= true;
                                    sb.AppendFormat("\tTrack {0} has no starpower and more than 1 solo section. If exported to the midi format, Clone Hero will interpret this chart as an older style midi, and will misinterpret solo markers as starpower.\n", instrument);

                                    goto NewInstrument;
                                }
                            }
                        }
                    }
                }

                NewInstrument :;
            }
        }

        if (!hasErrorsLocal)
        {
            sb.AppendLine("\tNo errors detected");
        }

        hasErrors |= hasErrorsLocal;

        return(sb.ToString());
    }