当前位置: 首页>>代码示例>>C++>>正文


C++ TimingData类代码示例

本文整理汇总了C++中TimingData的典型用法代码示例。如果您正苦于以下问题:C++ TimingData类的具体用法?C++ TimingData怎么用?C++ TimingData使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了TimingData类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: UpdateSongPosition

void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp )
{

	if( !timestamp.IsZero() )
		m_LastBeatUpdate = timestamp;
	else
		m_LastBeatUpdate.Touch();

	TimingData::GetBeatArgs beat_info;
	beat_info.elapsed_time= fPositionSeconds;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeat= beat_info.beat;
	m_fCurBPS= beat_info.bps_out;
	m_bFreeze= beat_info.freeze_out;
	m_bDelay= beat_info.delay_out;
	m_iWarpBeginRow= beat_info.warp_begin_out;
	m_fWarpDestination= beat_info.warp_dest_out;
	
	// "Crash reason : -243478.890625 -48695.773438"
	// The question is why is -2000 used as the limit? -aj
	ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds is less than -2000!", m_fSongBeat, fPositionSeconds) );

	m_fMusicSeconds = fPositionSeconds;

	m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );

	m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
	
	m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get();
	beat_info.elapsed_time= m_fMusicSecondsVisible;
	timing.GetBeatAndBPSFromElapsedTime(beat_info);
	m_fSongBeatVisible= beat_info.beat;
}
开发者ID:Highlogic,项目名称:stepmania-event,代码行数:33,代码来源:SongPosition.cpp

示例2: BPStoSPB

void BPStoSPB(TimingData &BPS)
{
    auto BPSCopy = BPS;
    for (auto i = BPS.begin(); i != BPS.end(); ++i)
    {
        double valueBPS = i->Value;
        i->Value = 1 / valueBPS;
        i->Time = IntegrateToTime(BPSCopy, i->Time); // Find time in beats based off beats in time
    }
}
开发者ID:dtinth,项目名称:raindrop,代码行数:10,代码来源:Song7K.cpp

示例3: ProcessStops

void SSCLoader::ProcessStops( TimingData &out, const RString sParam )
{
	vector<RString> arrayStopExpressions;
	split( sParam, ",", arrayStopExpressions );
	
	for( unsigned b=0; b<arrayStopExpressions.size(); b++ )
	{
		vector<RString> arrayStopValues;
		split( arrayStopExpressions[b], "=", arrayStopValues );
		if( arrayStopValues.size() != 2 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.",
				     arrayStopExpressions[b].c_str() );
			continue;
		}
		
		const float fBeat = StringToFloat( arrayStopValues[0] );
		const float fNewStop = StringToFloat( arrayStopValues[1] );
		if( fBeat >= 0 && fNewStop > 0 )
			out.AddSegment( StopSegment(BeatToNoteRow(fBeat), fNewStop) );
		else
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid Stop at beat %f, length %f.",
				     fBeat, fNewStop );
		}
	}
}
开发者ID:Ancaro,项目名称:stepmania,代码行数:31,代码来源:NotesLoaderSSC.cpp

示例4: ProcessLabels

void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
{
	vector<RString> arrayLabelExpressions;
	split( sParam, ",", arrayLabelExpressions );
	
	for( unsigned b=0; b<arrayLabelExpressions.size(); b++ )
	{
		vector<RString> arrayLabelValues;
		split( arrayLabelExpressions[b], "=", arrayLabelValues );
		if( arrayLabelValues.size() != 2 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid #LABELS value \"%s\" (must have exactly one '='), ignored.",
				     arrayLabelExpressions[b].c_str() );
			continue;
		}
		
		const float fBeat = StringToFloat( arrayLabelValues[0] );
		RString sLabel = arrayLabelValues[1];
		TrimRight(sLabel);
		if( fBeat >= 0.0f )
			out.AddSegment( LabelSegment(BeatToNoteRow(fBeat), sLabel) );
		else 
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid Label at beat %f called %s.",
				     fBeat, sLabel.c_str() );
		}
		
	}
}
开发者ID:Ancaro,项目名称:stepmania,代码行数:33,代码来源:NotesLoaderSSC.cpp

示例5: ProcessScrolls

void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
{
	vector<RString> vs1;
	split( sParam, ",", vs1 );
	
	FOREACH_CONST( RString, vs1, s1 )
	{
		vector<RString> vs2;
		split( *s1, "=", vs2 );
		
		if( vs2.size() < 2 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an scroll change with %i values.",
				     static_cast<int>(vs2.size()) );
			continue;
		}

		const float fBeat = StringToFloat( vs2[0] );
		const float fRatio = StringToFloat( vs2[1] );

		if( fBeat < 0 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an scroll change with beat %f.",
				     fBeat );
			continue;
		}

		out.AddSegment( ScrollSegment(BeatToNoteRow(fBeat), fRatio) );
	}
开发者ID:Ancaro,项目名称:stepmania,代码行数:33,代码来源:NotesLoaderSSC.cpp

示例6: HandleBunki

static void HandleBunki( TimingData &timing, const float fEarlyBPM,
			const float fCurBPM, const float fGap,
			const float fPos )
{
	const float BeatsPerSecond = fEarlyBPM / 60.0f;
	const float beat = (fPos + fGap) * BeatsPerSecond;
	LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f",
		   fEarlyBPM, BeatsPerSecond, fPos, beat );
	timing.AddSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) );
}
开发者ID:jberney,项目名称:stepmania,代码行数:10,代码来源:NotesLoaderKSF.cpp

示例7: ProcessTickcounts

static void ProcessTickcounts( const std::string & value, int & ticks, TimingData & timing )
{
	/* TICKCOUNT will be used below if there are DM compliant BPM changes
	 * and stops. It will be called again in LoadFromKSFFile for the
	 * actual steps. */
	ticks = StringToInt( value );
	ticks = Rage::clamp( ticks, 0, ROWS_PER_BEAT );

	if( ticks == 0 )
		ticks = TickcountSegment::DEFAULT_TICK_COUNT;

	timing.AddSegment( TickcountSegment(0, ticks) );
}
开发者ID:jberney,项目名称:stepmania,代码行数:13,代码来源:NotesLoaderKSF.cpp

示例8: ProcessVSpeeds

void Difficulty::ProcessVSpeeds(TimingData& BPS, TimingData& VerticalSpeeds, double SpeedConstant)
{
    VerticalSpeeds.clear();

    if (SpeedConstant) // We're using a CMod, so further processing is pointless
    {
        TimingSegment VSpeed;
        VSpeed.Time = 0;
        VSpeed.Value = SpeedConstant;
        VerticalSpeeds.push_back(VSpeed);
        return;
    }

    // Calculate velocity at time based on BPM at time
    for (auto Time = BPS.begin();
    Time != BPS.end();
        ++Time)
    {
        float VerticalSpeed;
        TimingSegment VSpeed;

        if (Time->Value)
        {
            float spb = 1 / Time->Value;
            VerticalSpeed = MeasureBaseSpacing / (spb * 4);
        }
        else
            VerticalSpeed = 0;

        VSpeed.Value = VerticalSpeed;
        VSpeed.Time = Time->Time; // We blindly take the BPS time that had offset and drift applied.

        VerticalSpeeds.push_back(VSpeed);
    }

    // Let first speed be not-null.
    if (VerticalSpeeds.size() && VerticalSpeeds[0].Value == 0)
    {
        for (auto i = VerticalSpeeds.begin();
        i != VerticalSpeeds.end();
            ++i)
        {
            if (i->Value != 0)
                VerticalSpeeds[0].Value = i->Value;
        }
    }
}
开发者ID:dtinth,项目名称:raindrop,代码行数:47,代码来源:Song7K.cpp

示例9: ProcessWarps

void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float fVersion )
{
	vector<RString> arrayWarpExpressions;
	split( sParam, ",", arrayWarpExpressions );
	
	for( unsigned b=0; b<arrayWarpExpressions.size(); b++ )
	{
		vector<RString> arrayWarpValues;
		split( arrayWarpExpressions[b], "=", arrayWarpValues );
		if( arrayWarpValues.size() != 2 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid #WARPS value \"%s\" (must have exactly one '='), ignored.",
				     arrayWarpExpressions[b].c_str() );
			continue;
		}
		
		const float fBeat = StringToFloat( arrayWarpValues[0] );
		const float fNewBeat = StringToFloat( arrayWarpValues[1] );
		// Early versions were absolute in beats. They should be relative.
		if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) )
		{
			out.AddSegment( WarpSegment(BeatToNoteRow(fBeat), fNewBeat - fBeat) );
		}
		else if( fNewBeat > 0 )
			out.AddSegment( WarpSegment(BeatToNoteRow(fBeat), fNewBeat) );
		else
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid Warp at beat %f, BPM %f.",
				     fBeat, fNewBeat );
		}
	}
}
开发者ID:Ancaro,项目名称:stepmania,代码行数:36,代码来源:NotesLoaderSSC.cpp

示例10: ProcessCombos

void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int rowsPerBeat )
{
	vector<RString> arrayComboExpressions;
	split( line, ",", arrayComboExpressions );
	
	for( unsigned f=0; f<arrayComboExpressions.size(); f++ )
	{
		vector<RString> arrayComboValues;
		split( arrayComboExpressions[f], "=", arrayComboValues );
		unsigned size = arrayComboValues.size();
		if( size < 2 )
		{
			LOG->UserLog("Song file",
				     this->GetSongTitle(),
				     "has an invalid #COMBOS value \"%s\" (must have at least one '='), ignored.",
				     arrayComboExpressions[f].c_str() );
			continue;
		}
		const float fComboBeat = StringToFloat( arrayComboValues[0] );
		const int iCombos = StringToInt( arrayComboValues[1] );
		const int iMisses = (size == 2 ? iCombos : StringToInt(arrayComboValues[2]));
		out.AddSegment( ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ) );
	}
}
开发者ID:Ancaro,项目名称:stepmania,代码行数:24,代码来源:NotesLoaderSSC.cpp

示例11: run

void run()
{
#define CHECK(call, exp) \
{ \
	float ret = call; \
	if( call != exp ) { \
		LOG->Warn( "Line %i: Got %f, expected %f", __LINE__, ret, exp); \
		return; \
	} \
}

	TimingData test;
	test.AddBPMSegment( BPMSegment(0, 60) );
	
	/* First, trivial sanity checks. */
	CHECK( test.GetBeatFromElapsedTime(60), 60.0f );
	CHECK( test.GetElapsedTimeFromBeat(60), 60.0f );

	/* The first BPM segment extends backwards in time. */
	CHECK( test.GetBeatFromElapsedTime(-60), -60.0f );
	CHECK( test.GetElapsedTimeFromBeat(-60), -60.0f );
	
	CHECK( test.GetBeatFromElapsedTime(100000), 100000.0f );
	CHECK( test.GetElapsedTimeFromBeat(100000), 100000.0f );
	CHECK( test.GetBeatFromElapsedTime(-100000), -100000.0f );
	CHECK( test.GetElapsedTimeFromBeat(-100000), -100000.0f );
	
	CHECK( test.GetBPMAtBeat(0), 60.0f );
	CHECK( test.GetBPMAtBeat(100000), 60.0f );
	CHECK( test.GetBPMAtBeat(-100000), 60.0f );

	/* 120BPM at beat 10: */
	test.AddBPMSegment( BPMSegment(10, 120) );
	CHECK( test.GetBPMAtBeat(9.99), 60.0f );
	CHECK( test.GetBPMAtBeat(10), 120.0f );

	CHECK( test.GetBeatFromElapsedTime(9), 9.0f );
	CHECK( test.GetBeatFromElapsedTime(10), 10.0f );
	CHECK( test.GetBeatFromElapsedTime(10.5), 11.0f );

	CHECK( test.GetElapsedTimeFromBeat(9), 9.0f );
	CHECK( test.GetElapsedTimeFromBeat(10), 10.0f );
	CHECK( test.GetElapsedTimeFromBeat(11), 10.5f );

	/* Add a 5-second stop at beat 10. */
	test.AddStopSegment( StopSegment(10, 5) );

	/* The stop shouldn't affect GetBPMAtBeat at all. */
	CHECK( test.GetBPMAtBeat(9.99), 60.0f );
	CHECK( test.GetBPMAtBeat(10), 120.0f );

	CHECK( test.GetBeatFromElapsedTime(9), 9.0f );
	CHECK( test.GetBeatFromElapsedTime(10), 10.0f );
	CHECK( test.GetBeatFromElapsedTime(12), 10.0f );
	CHECK( test.GetBeatFromElapsedTime(14), 10.0f );
	CHECK( test.GetBeatFromElapsedTime(15), 10.0f );
	CHECK( test.GetBeatFromElapsedTime(15.5), 11.0f );
	
	CHECK( test.GetElapsedTimeFromBeat(9), 9.0f );
	CHECK( test.GetElapsedTimeFromBeat(10), 10.0f );
	CHECK( test.GetElapsedTimeFromBeat(11), 15.5f );

	/* Add a 2-second stop at beat 5 and a 5-second stop at beat 15. */
	test.m_StopSegments.clear();
	test.AddStopSegment( StopSegment(5, 2) );
	test.AddStopSegment( StopSegment(15, 5) );
	CHECK( test.GetBPMAtBeat(9.99), 60.0f );
	CHECK( test.GetBPMAtBeat(10), 120.0f );

	CHECK( test.GetBeatFromElapsedTime(1), 1.0f );
	CHECK( test.GetBeatFromElapsedTime(2), 2.0f );
	CHECK( test.GetBeatFromElapsedTime(5), 5.0f ); // stopped
	CHECK( test.GetBeatFromElapsedTime(6), 5.0f ); // stopped
	CHECK( test.GetBeatFromElapsedTime(7), 5.0f ); // stop finished
	CHECK( test.GetBeatFromElapsedTime(8), 6.0f );
	CHECK( test.GetBeatFromElapsedTime(12), 10.0f ); // bpm changes to 120
	CHECK( test.GetBeatFromElapsedTime(13), 12.0f );
	CHECK( test.GetBeatFromElapsedTime(14), 14.0f );
	CHECK( test.GetBeatFromElapsedTime(14.5f), 15.0f ); // stopped
	CHECK( test.GetBeatFromElapsedTime(15), 15.0f ); // stopped
	CHECK( test.GetBeatFromElapsedTime(17), 15.0f ); // stopped
	CHECK( test.GetBeatFromElapsedTime(19.5f), 15.0f ); // stop finished
	CHECK( test.GetBeatFromElapsedTime(20), 16.0f );

	CHECK( test.GetElapsedTimeFromBeat(1), 1.0f );
	CHECK( test.GetElapsedTimeFromBeat(2), 2.0f );
	CHECK( test.GetElapsedTimeFromBeat(5), 5.0f ); // stopped
	CHECK( test.GetElapsedTimeFromBeat(6), 8.0f );
	CHECK( test.GetElapsedTimeFromBeat(10), 12.0f ); // bpm changes to 120
	CHECK( test.GetElapsedTimeFromBeat(12), 13.0f );
	CHECK( test.GetElapsedTimeFromBeat(14), 14.0f );
	CHECK( test.GetElapsedTimeFromBeat(15.0f), 14.5f ); // stopped
	CHECK( test.GetElapsedTimeFromBeat(16), 20.0f );

RageTimer foobar;
	/* We can look up the time of any given beat, then look up the beat of that
	 * time and get the original value.  (We can't do this in reverse; the beat
	 * doesn't move during stop segments.) */
int q = 0;
	for( float f = -10; f < 250; f += 0.002 )
//.........这里部分代码省略.........
开发者ID:BitMax,项目名称:openitg,代码行数:101,代码来源:test_timing_data.cpp

示例12: Serialize

static void Serialize(const TimingData &td, Json::Value &root)
{
	JsonUtil::SerializeVectorPointers( td.GetTimingSegments(SEGMENT_BPM), Serialize, root["BpmSegments"] );
	JsonUtil::SerializeVectorPointers( td.GetTimingSegments(SEGMENT_STOP), Serialize, root["StopSegments"] );
}
开发者ID:AratnitY,项目名称:stepmania,代码行数:5,代码来源:NotesWriterJson.cpp

示例13: GetPlayableData

void Difficulty::GetPlayableData(VectorTN NotesOut,
    TimingData& BPS,
    TimingData& VerticalSpeeds,
    TimingData& Warps,
    float Drift, double SpeedConstant)
{
    /*
        We'd like to build the notes' position from 0 to infinity,
        however the real "zero" position would be the judgment line
        in other words since "up" is negative relative to 0
        and 0 is the judgment line
        position would actually be
        judgeline - positiveposition
        and positiveposition would just be
        measure * measuresize + fraction * fractionsize

        In practice, since we use a ms-based model rather than a beat one,
        we just do regular integration of
        position = sum(speed_i * duration_i) + speed_current * (time_current - speed_start_time)
    */

    assert(Data != nullptr);

    ProcessBPS(BPS, Drift);
    ProcessVSpeeds(BPS, VerticalSpeeds, SpeedConstant);

    if (!SpeedConstant) // If there is a speed constant having speed changes is not what we want
        ProcessSpeedVariations(BPS, VerticalSpeeds, Drift);

    if (SpeedConstant) Warps.clear();
    else Warps = Data->Warps;

    // From here on, we'll just copy the notes out. Otherwise, just leave the processed data.
    if (!NotesOut)
        return;

    for (int KeyIndex = 0; KeyIndex < Channels; KeyIndex++)
        NotesOut[KeyIndex].clear();

    /* For all channels of this difficulty */
    for (int KeyIndex = 0; KeyIndex < Channels; KeyIndex++)
    {
        int MIdx = 0;

        /* For each measure of this channel */
        for (auto Msr = Data->Measures.begin();
        Msr != Data->Measures.end();
            ++Msr)
        {
            /* For each note in the measure... */
            ptrdiff_t total_notes = Msr->Notes[KeyIndex].size();

            for (auto Note = 0; Note < total_notes; Note++)
            {
                /*
                    Calculate position. (Change this to TrackNote instead of processing?)
                    issue is not having the speed change data there.
                */
                NoteData &CurrentNote = (*Msr).Notes[KeyIndex][Note];
                TrackNote NewNote;

                NewNote.AssignNotedata(CurrentNote);

                NewNote.AddTime(Drift);

                float VerticalPosition = IntegrateToTime(VerticalSpeeds, NewNote.GetStartTime());
                float HoldEndPosition = IntegrateToTime(VerticalSpeeds, NewNote.GetTimeFinal());

                // if upscroll change minus for plus as well as matrix at screengameplay7k
                if (!CurrentNote.EndTime)
                    NewNote.AssignPosition(VerticalPosition);
                else
                    NewNote.AssignPosition(VerticalPosition, HoldEndPosition);

                // Okay, now we want to know what fraction of a beat we're dealing with
                // this way we can display colored (a la Stepmania) notes.
                // We should do this before changing time by drift.
                double cBeat = IntegrateToTime(BPS, NewNote.GetStartTime());
                double iBeat = floor(cBeat);
                double dBeat = (cBeat - iBeat);

                NewNote.AssignFraction(dBeat);

                double Wamt = -GetWarpAmountAtTime(CurrentNote.StartTime);
                NewNote.AddTime(Wamt);

                if (!SpeedConstant || (NewNote.IsJudgable() && !IsWarpingAt(CurrentNote.StartTime)))
                    NotesOut[KeyIndex].push_back(NewNote);
            }

            MIdx++;
        }

        // done with the channel - sort it
        std::stable_sort(NotesOut[KeyIndex].begin(), NotesOut[KeyIndex].end(),
            [](const TrackNote &A, const TrackNote &B) -> bool
        {
            return A.GetVertical() < B.GetVertical();
        });
    }
//.........这里部分代码省略.........
开发者ID:dtinth,项目名称:raindrop,代码行数:101,代码来源:Song7K.cpp

示例14: assert

void Difficulty::ProcessSpeedVariations(TimingData& BPS, TimingData& VerticalSpeeds, double Drift)
{
    assert(Data != NULL);

    TimingData tVSpeeds = VerticalSpeeds; // We need this to store what values to change
    TimingData &Scrolls = Data->Scrolls;

    std::sort(Scrolls.begin(), Scrolls.end());

    for (TimingData::const_iterator Change = Scrolls.begin();
    Change != Scrolls.end();
        ++Change)
    {
        TimingData::const_iterator NextChange = (Change + 1);
        double ChangeTime = Change->Time + Drift + Offset;

        /*
            Find all VSpeeds
            if there exists a speed change which is virtually happening at the same time as this VSpeed
            modify it to be this value * factor
        */

        bool MoveOn = false;
        for (auto Time = VerticalSpeeds.begin();
        Time != VerticalSpeeds.end();
            ++Time)
        {
            if (abs(ChangeTime - Time->Time) < 0.00001)
            {
                Time->Value *= Change->Value;
                MoveOn = true;
            }
        }

        if (MoveOn) continue;

        /*
            There are no collisions- insert a new speed at this time
        */

        if (ChangeTime < 0)
            continue;

        float SpeedValue;
        SpeedValue = SectionValue(tVSpeeds, ChangeTime) * Change->Value;

        TimingSegment VSpeed;

        VSpeed.Time = ChangeTime;
        VSpeed.Value = SpeedValue;

        VerticalSpeeds.push_back(VSpeed);

        /*
            Theorically, if there were a VSpeed change after this one (such as a BPM change) we've got to modify them
            if they're between this and the next speed change.

            Apparently, this behaviour is a "bug" since osu!mania resets SV changes
            after a BPM change.
        */

        if (BPMType == VSRG::Difficulty::BT_BEATSPACE) // Okay, we're an osu!mania chart, leave the resetting.
            continue;

        // We're not an osu!mania chart, so it's time to do what should be done.
        for (auto Time = VerticalSpeeds.begin();
        Time != VerticalSpeeds.end();
            ++Time)
        {
            if (Time->Time > ChangeTime)
            {
                // Two options, between two speed changes, or the last one. Second case, NextChange == Scrolls.end().
                // Otherwise, just move on
                // Last speed change
                if (NextChange == Scrolls.end())
                {
                    Time->Value = Change->Value * SectionValue(tVSpeeds, Time->Time);
                }
                else
                {
                    if (Time->Time < NextChange->Time) // Between speed changes
                        Time->Value = Change->Value * SectionValue(tVSpeeds, Time->Time);
                }
            }
        }
    }

    std::sort(VerticalSpeeds.begin(), VerticalSpeeds.end());
}
开发者ID:dtinth,项目名称:raindrop,代码行数:89,代码来源:Song7K.cpp

示例15: LoadFromKSFFile

static bool LoadFromKSFFile( const std::string &sPath, Steps &out, Song &song, bool bKIUCompliant )
{
	using std::max;
	LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() );

	MsdFile msd;
	if( !msd.ReadFile( sPath, false ) )  // don't unescape
	{
		LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() );
		return false;
	}

	// this is the value we read for TICKCOUNT
	int iTickCount = -1;
	// used to adapt weird tickcounts
	//float fScrollRatio = 1.0f; -- uncomment when ready to use.
	vector<std::string> vNoteRows;

	// According to Aldo_MX, there is a default BPM and it's 60. -aj
	bool bDoublesChart = false;

	TimingData stepsTiming;
	float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1;

	for( unsigned i=0; i<msd.GetNumValues(); i++ )
	{
		const MsdFile::value_t &sParams = msd.GetValue( i );
		std::string sValueName = Rage::make_upper(sParams[0]);

		/* handle the data...well, not this data: not related to steps.
		 * Skips INTRO, MUSICINTRO, TITLEFILE, DISCFILE, SONGFILE. */
		if (sValueName=="TITLE" || Rage::ends_with(sValueName, "INTRO")
			|| Rage::ends_with(sValueName, "FILE") )
		{

		}
		else if( sValueName=="BPM" )
		{
			BPM1 = StringToFloat(sParams[1]);
			stepsTiming.AddSegment( BPMSegment(0, BPM1) );
		}
		else if( sValueName=="BPM2" )
		{
			if (bKIUCompliant)
			{
				BPM2 = StringToFloat( sParams[1] );
			}
			else
			{
				// LOG an error.
			}
		}
		else if( sValueName=="BPM3" )
		{
			if (bKIUCompliant)
			{
				BPM3 = StringToFloat( sParams[1] );
			}
			else
			{
				// LOG an error.
			}
		}
		else if( sValueName=="BUNKI" )
		{
			if (bKIUCompliant)
			{
				BPMPos2 = StringToFloat( sParams[1] ) / 100.0f;
			}
			else
			{
				// LOG an error.
			}
		}
		else if( sValueName=="BUNKI2" )
		{
			if (bKIUCompliant)
			{
				BPMPos3 = StringToFloat( sParams[1] ) / 100.0f;
			}
			else
			{
				// LOG an error.
			}
		}
		else if( sValueName=="STARTTIME" )
		{
			SMGap1 = -StringToFloat( sParams[1] )/100;
			stepsTiming.set_offset(SMGap1);
		}
		// This is currently required for more accurate KIU BPM changes.
		else if( sValueName=="STARTTIME2" )
		{
			if (bKIUCompliant)
			{
				SMGap2 = -StringToFloat( sParams[1] )/100;
			}
			else
			{
				// LOG an error.
//.........这里部分代码省略.........
开发者ID:jberney,项目名称:stepmania,代码行数:101,代码来源:NotesLoaderKSF.cpp


注:本文中的TimingData类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。