void FGAFLoader::ProcessLoad(FGAFData* input, UGAFAsset* asset)
{
    Stream = new FGAFStream(input);

    FGAFHeader& header = Stream->GetInput()->GetHeader();

    FGAFTimelinePtr timeline;
    if (header.GetMajorVersion() >= 4)
    {
        ReadHeaderEndV4(header);
        RegisterTagLoadersV4();
    }
    else
    {
        ReadHeaderEnd(header);
        RegisterTagLoadersV3();

        timeline = MakeShareable(new FGAFTimeline(nullptr, 0, header.FrameSize, header.Pivot, header.FramesCount));
        asset->PushTimeline(0, timeline);
        asset->SetRootTimeline((uint32_t)0);
    }

    RegisterTagLoadersCommon();

    asset->SetHeader(header);

    LoadTags(Stream, asset, timeline);

    delete Stream;
}
void FormTagManager::DelTags(void)
{
	::PrintLog(L"FormTagManager.DelTags.");

	wchar_t selectedTags[MAXCOUNT_TAG][MAXLENGTH_EACHTAG] = {0};

	int count = 0;
	int searchFrom = -1;
	int selectedIdx = -1;

	// find first
	selectedIdx = ListView_GetNextItem(_hListTags,searchFrom,LVIS_SELECTED);
	while (selectedIdx > -1){
		ListView_GetItemText(_hListTags,selectedIdx,0,selectedTags[count],MAXLENGTH_EACHTAG);

		searchFrom = selectedIdx;
		count++;

		// find next
		selectedIdx = ListView_GetNextItem(_hListTags,searchFrom,LVIS_SELECTED);
	}

	if ( NULL != selectedTags && count > 0)
	{
		wchar_t msg[LOADSTRING_BUFFERSIZE];
		const int maxShown = 20;
		const UINT len = (MAXLENGTH_EACHTAG + 3) * MAXCOUNT_TAG;	// 3 for \0\r\n.
		wchar_t tmp[len] = {0};
		for (int i = 0; i < count && i < maxShown; i++)
		{
			StrCat(tmp,selectedTags[i]);
			if(i < count -1 )
				StrCat(tmp,L"\r\n");
		}

		if( maxShown < count ){
			wsprintf(msg,::MyLoadString(IDS_MSG_MORE_N_HIDDEN),count-maxShown);
			StrCat(tmp,L"\r\n");
			StrCat(tmp,msg);
		}

		wsprintf(msg,::MyLoadString(IDS_MSG_CONFRIM_DEL_TAG),tmp);
		int result = MessageBox(_hwnd,msg,::MyLoadString(IDS_MSGBOX_CAPTION_WARNING),MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON1);
		if( IDYES == result )
		{
			this->_handler->pTagHelper->DeleteTags(selectedTags,count);
			LoadTags();
		}
		else
		{
			MessageBox(_hwnd,L"CANCEL",L"Warning",MB_OK);
		}
	}
	else
	{
		// should not be occured.
		::PrintLog(L"Selected none while deleting. Should not be occured here.");
	}
}
Beispiel #3
0
XConsoleMain::XConsoleMain()
{
	CONSOLE_MAIN = this;
	Init();
#ifdef _SERVER
	LoadTags();		// 일단은 서버에서만 사용하는걸로.
	LoadidAcc();
#endif // _SERVER
#if defined(_SERVER) || defined(_XBOT)
	ID idThread = ::GetCurrentThreadId();
	m_idThreadMain = idThread;
	XDetectDeadLock::sGet()->OnCreate();
	XDetectDeadLock::sGet()->AddThread( idThread, nullptr, _T( "main" ) );
#endif // _SERVER
}
void FormTagManager::InitTagList()
{
	_ASSERT_EXPR(NULL!=_hListTags,"_hListTags could not be NULL.");

	ListView_SetImageList(_hListTags,_sysImgList,LVSIL_SMALL);

	UINT cIdx = 0;
	LVCOLUMN c = {0};
	c.pszText = ::MyLoadString(IDS_DLG_TAGMANAGER_LV_TAGS_HEADER_TAGNAME);
	c.mask = LVCF_TEXT | LVCF_MINWIDTH | LVCF_WIDTH;
	c.cxMin = 80;
	c.cx = 105;
	ListView_InsertColumn(_hListTags,cIdx++,&c);

	c.pszText = ::MyLoadString(IDS_DLG_TAGMANAGER_LV_TAGS_HEADER_USECOUNT);
	c.mask = LVCF_TEXT | LVCF_MINWIDTH | LVCF_WIDTH | LVCF_FMT;
	c.cxMin = 40;
	c.cx = 50;
	c.fmt = LVCFMT_RIGHT;
	ListView_InsertColumn(_hListTags,cIdx++,&c);

	LoadTags();
}
bool KSFLoader::LoadGlobalData( const CString &sPath, Song &out )
{
    MsdFile msd;
    if( !msd.ReadFile( sPath ) )
        RageException::Throw( "Error opening file \"%s\": %s", sPath.c_str(), msd.GetError().c_str() );

    float BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1;;

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

        // handle the data
        if( 0==stricmp(sValueName,"TITLE") )
            LoadTags(sParams[1], out);
        else if( 0==stricmp(sValueName,"BPM") )
            out.AddBPMSegment( BPMSegment(0, strtof(sParams[1], NULL)) );
        else if( 0==stricmp(sValueName,"BPM2") )
            BPM2 = strtof( sParams[1], NULL );
        else if( 0==stricmp(sValueName,"BPM3") )
            BPM3 = strtof( sParams[1], NULL );
        else if( 0==stricmp(sValueName,"BUNKI") )
            BPMPos2 = strtof( sParams[1], NULL ) / 100.0f;
        else if( 0==stricmp(sValueName,"BUNKI2") )
            BPMPos3 = strtof( sParams[1], NULL ) / 100.0f;
        else if( 0==stricmp(sValueName,"STARTTIME") )
            out.m_Timing.m_fBeat0OffsetInSeconds = -strtof( sParams[1], NULL )/100;
        else if( 0==stricmp(sValueName,"TICKCOUNT") ||
                 0==stricmp(sValueName,"STEP") ||
                 0==stricmp(sValueName,"DIFFICULTY"))
            ; /* Handled in LoadFromKSFFile; don't warn. */
        else
            LOG->Trace( "Unexpected value named '%s'", sValueName.c_str() );
    }

    /* This doesn't work yet: we also need to move the data around, I think, and
     * we should handle more than one BPM change. */
    if( BPM2 > 0 && BPMPos2 > 0 )
    {
        const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f;
        const float beat = BPMPos2 * BeatsPerSecond;
        LOG->Trace("BPM %f, BPS %f, BPMPos2 %f, beat %f",
                   out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos2, beat);
        out.AddBPMSegment( BPMSegment(beat, BPM2) );
    }

    if( BPM3 > 0 && BPMPos3 > 0 )
    {
        const float BeatsPerSecond = out.GetBPMAtBeat(0) / 60.0f;
        const float beat = BPMPos3 * BeatsPerSecond;
        LOG->Trace("BPM %f, BPS %f, BPMPos3 %f, beat %f",
                   out.GetBPMAtBeat(0), BeatsPerSecond, BPMPos3, beat);
        out.AddBPMSegment( BPMSegment(beat, BPM3) );
    }

    /* Try to fill in missing bits of information from the pathname. */
    {
        CStringArray asBits;
        split( sPath, "/", asBits, true);

        ASSERT(asBits.size() > 1);
        LoadTags(asBits[asBits.size()-2], out);
    }

    // search for music with song in the file name
    CStringArray arrayPossibleMusic;
    GetDirListing( out.GetSongDir() + CString("song.mp3"), arrayPossibleMusic );
    GetDirListing( out.GetSongDir() + CString("song.ogg"), arrayPossibleMusic );
    GetDirListing( out.GetSongDir() + CString("song.wav"), arrayPossibleMusic );

    if( !arrayPossibleMusic.empty() )		// we found a match
        out.m_sMusicFile = arrayPossibleMusic[0];

    return true;
}
Beispiel #6
0
static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant )
{
	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;
	}

	// changed up there in case of something is found inside the SONGFILE tag in the head ksf -DaisuMaster
	// search for music with song in the file name
	vector<RString> arrayPossibleMusic;
	GetDirListing( out.GetSongDir() + RString("song.mp3"), arrayPossibleMusic );
	GetDirListing( out.GetSongDir() + RString("song.oga"), arrayPossibleMusic );
	GetDirListing( out.GetSongDir() + RString("song.ogg"), arrayPossibleMusic );
	GetDirListing( out.GetSongDir() + RString("song.wav"), arrayPossibleMusic );

	if( !arrayPossibleMusic.empty() )		// we found a match
		out.m_sMusicFile = arrayPossibleMusic[0];
	// ^this was below, at the end

	float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1;
	int iTickCount = -1;
	bKIUCompliant = false;
	vector<RString> vNoteRows;

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

		// handle the data
		if( sValueName=="TITLE" )
			LoadTags(sParams[1], out);
		else if( sValueName=="BPM" )
		{
			BPM1 = StringToFloat(sParams[1]);
			out.m_SongTiming.AddSegment( BPMSegment(0, BPM1) );
		}
		else if( sValueName=="BPM2" )
		{
			bKIUCompliant = true;
			BPM2 = StringToFloat( sParams[1] );
		}
		else if( sValueName=="BPM3" )
		{
			bKIUCompliant = true;
			BPM3 = StringToFloat( sParams[1] );
		}
		else if( sValueName=="BUNKI" )
		{
			bKIUCompliant = true;
			BPMPos2 = StringToFloat( sParams[1] ) / 100.0f;
		}
		else if( sValueName=="BUNKI2" )
		{
			bKIUCompliant = true;
			BPMPos3 = StringToFloat( sParams[1] ) / 100.0f;
		}
		else if( sValueName=="STARTTIME" )
		{
			SMGap1 = -StringToFloat( sParams[1] )/100;
			out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1;
		}
		// This is currently required for more accurate KIU BPM changes.
		else if( sValueName=="STARTTIME2" )
		{
			bKIUCompliant = true;
			SMGap2 = -StringToFloat( sParams[1] )/100;
		}
		else if ( sValueName=="STARTTIME3" )
		{
			// STARTTIME3 only ensures this is a KIU compliant simfile.
			//bKIUCompliant = true;
		}
		else if ( sValueName=="TICKCOUNT" )
		{
			ProcessTickcounts(sParams[1], iTickCount, out.m_SongTiming);
		}
		else if ( sValueName=="STEP" )
		{
			/* STEP will always be the last header in a KSF file by design. Due to
			 * the Direct Move syntax, it is best to get the rows of notes here. */
			RString theSteps = sParams[1];
			TrimLeft( theSteps );
			split( theSteps, "\n", vNoteRows, true );
		}
		else if( sValueName=="DIFFICULTY" || sValueName=="PLAYER" )
		{
			/* DIFFICULTY and PLAYER are handled only in LoadFromKSFFile.
			Ignore those here. */
			continue;
		}
		// New cases noted in Aldo_MX's code:
		else if( sValueName=="MUSICINTRO" || sValueName=="INTRO" )
		{
			out.m_fMusicSampleStartSeconds = HHMMSSToSeconds( sParams[1] );
		}
		else if( sValueName=="TITLEFILE" )
		{
			out.m_sBackgroundFile = sParams[1];
		}
		else if( sValueName=="DISCFILE" )
		{
			out.m_sBannerFile = sParams[1];
		}
		else if( sValueName=="SONGFILE" )
		{
			out.m_sMusicFile = sParams[1];
		}
		//else if( sValueName=="INTROFILE" )
		//{
		//	nothing to add...
		//}
		// end new cases
		else
		{
			LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".",
				      sValueName.c_str() );
		}
	}

	//intro length in piu mixes is generally 7 seconds
	out.m_fMusicSampleLengthSeconds = 7.0f;

	/* BPM Change checks are done here.  If bKIUCompliant, it's short and sweet.
	 * Otherwise, the whole file has to be processed.  Right now, this is only 
	 * called once, for the initial file (often the Crazy steps).  Hopefully that
	 * will end up changing soon. */
	if( bKIUCompliant )
	{
		if( BPM2 > 0 && BPMPos2 > 0 )
		{
			HandleBunki( out.m_SongTiming, BPM1, BPM2, SMGap1, BPMPos2 );
		}

		if( BPM3 > 0 && BPMPos3 > 0 )
		{
			HandleBunki( out.m_SongTiming, BPM2, BPM3, SMGap2, BPMPos3 );
		}
	}
	else
	{
		float fCurBeat = 0.0f;
		bool bDMRequired = false;

		for( unsigned i=0; i < vNoteRows.size(); ++i )
		{
			RString& NoteRowString = vNoteRows[i];
			StripCrnl( NoteRowString );

			if( NoteRowString == "" )
				continue; // ignore empty rows.

			if( NoteRowString == "2222222222222" ) // Row of 2s = end. Confirm KIUCompliency here.
			{
				if (!bDMRequired)
					bKIUCompliant = true;
				break;
			}

			// This is where the DMRequired test will take place.
			if ( BeginsWith( NoteRowString, "|" ) )
			{
				// have a static timing for everything
				bDMRequired = true;
				continue;
			}
			else
			{
				// ignore whatever else...
				//continue;
			}
			
			fCurBeat += 1.0f / iTickCount;
		}
	}

	// Try to fill in missing bits of information from the pathname.
	{
		vector<RString> asBits;
		split( sPath, "/", asBits, true);

		ASSERT( asBits.size() > 1 );
		LoadTags( asBits[asBits.size()-2], out );
	}

	return true;
}