static void SearchForDifficulty( RString sTag, Steps *pOut ) { sTag.MakeLower(); // Only match "Light" in parentheses. if( sTag.find( "(light" ) != sTag.npos ) { pOut->SetDifficulty( Difficulty_Easy ); } else if( sTag.find( "another" ) != sTag.npos ) { pOut->SetDifficulty( Difficulty_Hard ); } else if( sTag.find( "(solo)" ) != sTag.npos ) { pOut->SetDescription( "Solo" ); pOut->SetDifficulty( Difficulty_Edit ); } LOG->Trace( "Tag \"%s\" is %s", sTag.c_str(), DifficultyToString(pOut->GetDifficulty()).c_str() ); }
void Steps::Decompress() { if( m_bNoteDataIsFilled ) return; // already decompressed if( parent ) { // get autogen m_pNoteData NoteData notedata; parent->GetNoteData( notedata ); m_bNoteDataIsFilled = true; int iNewTracks = GAMEMAN->GetStepsTypeInfo(m_StepsType).iNumTracks; if( this->m_StepsType == StepsType_lights_cabinet ) { NoteDataUtil::LoadTransformedLights( notedata, *m_pNoteData, iNewTracks ); } else { // Special case so that kickbox can have autogen steps that are playable. // Hopefully I'll replace this with a good generalized autogen system // later. -Kyz if(stepstype_is_kickbox(this->m_StepsType)) { // Number of notes seems like a useful "random" input so that charts // from different sources come out different, but autogen always // makes the same thing from one source. -Kyz NoteDataUtil::AutogenKickbox(notedata, *m_pNoteData, *GetTimingData(), this->m_StepsType, static_cast<int>(GetRadarValues(PLAYER_1)[RadarCategory_TapsAndHolds])); } else { NoteDataUtil::LoadTransformedSlidingWindow( notedata, *m_pNoteData, iNewTracks ); NoteDataUtil::RemoveStretch( *m_pNoteData, m_StepsType ); } } return; } if( !m_sFilename.empty() && m_sNoteDataCompressed.empty() ) { // We have NoteData on disk and not in memory. Load it. if (!this->GetNoteDataFromSimfile()) { LOG->Warn("Couldn't load the %s chart's NoteData from \"%s\"", DifficultyToString(m_Difficulty).c_str(), m_sFilename.c_str()); return; } this->GetSMNoteData( m_sNoteDataCompressed ); } if( m_sNoteDataCompressed.empty() ) { /* there is no data, do nothing */ } else { // load from compressed bool bComposite = GAMEMAN->GetStepsTypeInfo(m_StepsType).m_StepsTypeCategory == StepsTypeCategory_Routine; m_bNoteDataIsFilled = true; m_pNoteData->SetNumTracks( GAMEMAN->GetStepsTypeInfo(m_StepsType).iNumTracks ); NoteDataUtil::LoadFromSMNoteDataString( *m_pNoteData, m_sNoteDataCompressed, bComposite ); } }
ScreenRanking::ScreenRanking( CString sClassName ) : ScreenAttract( sClassName ) { // init Actors for category and course { m_Banner.SetName( "Banner" ); m_Banner.SetHidden( true ); this->AddChild( &m_Banner ); m_sprBannerFrame.SetName( "BannerFrame" ); m_sprBannerFrame.SetHidden( true ); this->AddChild( &m_sprBannerFrame ); m_textCategory.SetName( "Category" ); m_textCategory.LoadFromFont( THEME->GetPathToF("ScreenRanking category") ); m_textCategory.SetShadowLength( 0 ); m_textCategory.SetHidden( true ); this->AddChild( &m_textCategory ); m_textCourseTitle.SetName( "CourseTitle" ); m_textCourseTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking course title") ); m_textCourseTitle.SetShadowLength( 0 ); m_textCourseTitle.SetHidden( true ); this->AddChild( &m_textCourseTitle ); m_textStepsType.SetName( "StepsType" ); m_textStepsType.LoadFromFont( THEME->GetPathToF("ScreenRanking steps type") ); m_textStepsType.SetShadowLength( 0 ); m_textStepsType.SetHidden( true ); this->AddChild( &m_textStepsType ); for( int l=0; l<NUM_RANKING_LINES; l++ ) { m_sprBullets[l].SetName( ssprintf("Bullet%d",l+1) ); m_sprBullets[l].Load( THEME->GetPathToG( ssprintf("ScreenRanking bullets 1x%d",NUM_RANKING_LINES) ) ); m_sprBullets[l].SetState( l ); m_sprBullets[l].StopAnimating(); m_sprBullets[l].SetHidden( true ); this->AddChild( &m_sprBullets[l] ); m_textNames[l].SetName( ssprintf("Name%d",l+1) ); m_textNames[l].LoadFromFont( THEME->GetPathToF("ScreenRanking name") ); m_textNames[l].SetHidden( true ); this->AddChild( &m_textNames[l] ); m_textScores[l].SetName( ssprintf("Score%d",l+1) ); m_textScores[l].LoadFromFont( THEME->GetPathToF("ScreenRanking score") ); m_textScores[l].SetHidden( true ); this->AddChild( &m_textScores[l] ); m_textPoints[l].SetName( ssprintf("Points%d",l+1) ); m_textPoints[l].LoadFromFont( THEME->GetPathToF("ScreenRanking points") ); m_textPoints[l].SetHidden( true ); this->AddChild( &m_textPoints[l] ); m_textTime[l].SetName( ssprintf("Time%d",l+1) ); m_textTime[l].LoadFromFont( THEME->GetPathToF("ScreenRanking time") ); m_textTime[l].SetHidden( true ); this->AddChild( &m_textTime[l] ); // TODO: Think of a better way to handle this if( PREFSMAN->m_sCoursesToShowRanking == "" ) PREFSMAN->m_sCoursesToShowRanking = THEME->GetMetric("ScreenRanking","CoursesToShow"); } } // make the list of difficulties to show { vector<CString> sShowDiffs; split( DIFFICULTIES_TO_SHOW, ",", sShowDiffs, true ); for( vector<CString>::const_iterator iter = sShowDiffs.begin(); iter != sShowDiffs.end(); iter++ ) { m_vDiffsToShow.push_back( StringToDifficulty( *iter ) ); } } // init Actors for all_steps { FOREACH_Difficulty( d ) { bool bShowThis = find(m_vDiffsToShow.begin(), m_vDiffsToShow.end(), d) != m_vDiffsToShow.end(); if( !bShowThis ) continue; // skip m_sprDifficulty[d].Load( THEME->GetPathG(m_sName,"difficulty "+DifficultyToString(d)) ); m_sprDifficulty[d]->SetName( ssprintf("Difficulty%d",d) ); m_sprDifficulty[d]->SetHidden( true ); this->AddChild( m_sprDifficulty[d] ); } const unsigned num_songs = SONGMAN->GetAllSongs().size(); for( unsigned s=0; s<num_songs; s++ ) { Song *pSong = SONGMAN->GetAllSongs()[s]; if( UNLOCKMAN->SongIsLocked(pSong) ) continue; if( !pSong->ShowInDemonstrationAndRanking() ) continue; StepsScoreRowItem* pStepsScoreRowItem = new StepsScoreRowItem; pStepsScoreRowItem ->m_pSong = pSong; pStepsScoreRowItem->m_sprSongFrame.SetName( "SongFrame" ); pStepsScoreRowItem->m_sprSongFrame.SetHidden( true ); pStepsScoreRowItem->m_sprSongFrame.Load( THEME->GetPathToG("ScreenRanking song frame") ); pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_sprSongFrame ); pStepsScoreRowItem->m_textSongTitle.SetName( "SongTitle" ); pStepsScoreRowItem->m_textSongTitle.SetHidden( true ); pStepsScoreRowItem->m_textSongTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking song title") ); pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_textSongTitle ); for( int d=0; d<NUM_DIFFICULTIES; d++ ) { pStepsScoreRowItem->m_textStepsScore[d].SetName( "StepsScore" ); pStepsScoreRowItem->m_textStepsScore[d].LoadFromFont( THEME->GetPathToF("ScreenRanking steps score") ); pStepsScoreRowItem->m_textStepsScore[d].SetHidden( true ); pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_textStepsScore[d] ); } m_vpStepsScoreRowItem.push_back( pStepsScoreRowItem ); } m_ListScoreRowItems.SetName( "ListScoreRowItems" ); this->AddChild( &m_ListScoreRowItems ); m_ListScoreRowItems.SetXY( CENTER_X, CENTER_Y ); } { // for all_courses: FOREACH_ShownCourseDifficulty(d) { CString cd = CourseDifficultyToString(d); m_sprCourseDifficulty[d].Load( THEME->GetPathG(m_sName,"CourseDifficulty "+cd) ); m_sprCourseDifficulty[d]->SetName( ssprintf("CourseDifficulty%s",cd.c_str()) ); m_sprCourseDifficulty[d]->SetHidden( true ); this->AddChild( m_sprCourseDifficulty[d] ); } vector<Course*> courses; SONGMAN->GetAllCourses( courses, false ); LOG->Trace("rankings: adding %u courses", unsigned(courses.size())); for( unsigned s=0; s<courses.size(); s++ ) { if( UNLOCKMAN->CourseIsLocked(courses[s]) ) continue; CourseScoreRowItem* pCourseScoreRowItem = new CourseScoreRowItem; pCourseScoreRowItem->m_pCourse = courses[s]; pCourseScoreRowItem->m_sprSongFrame.SetName( "CourseListFrame" ); pCourseScoreRowItem->m_sprSongFrame.SetHidden( true ); pCourseScoreRowItem->m_sprSongFrame.Load( THEME->GetPathToG("ScreenRanking course frame") ); pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_sprSongFrame ); pCourseScoreRowItem->m_textSongTitle.SetName( "CourseListTitle" ); pCourseScoreRowItem->m_textSongTitle.SetHidden( true ); pCourseScoreRowItem->m_textSongTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking course list title") ); pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_textSongTitle ); FOREACH_ShownCourseDifficulty(d) { pCourseScoreRowItem->m_textStepsScore[d].SetName( "CourseListScore" ); pCourseScoreRowItem->m_textStepsScore[d].LoadFromFont( THEME->GetPathToF("ScreenRanking course list score") ); pCourseScoreRowItem->m_textStepsScore[d].SetHidden( true ); pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_textStepsScore[d] ); } m_vpCourseScoreRowItem.push_back( pCourseScoreRowItem ); } m_ListCourseRowItems.SetName( "ListCourseRowItems" ); this->AddChild( &m_ListCourseRowItems ); m_ListCourseRowItems.SetXY( CENTER_X, CENTER_Y ); } // calculate which StepsTypes to show vector<StepsType> aStepsTypesToShow; { GAMEMAN->GetStepsTypesForGame( GAMESTATE->m_pCurGame, aStepsTypesToShow ); // subtract hidden StepsTypes { vector<CString> asStepsTypesToHide; split( STEPS_TYPES_TO_HIDE, ",", asStepsTypesToHide, true ); for( unsigned i=0; i<asStepsTypesToHide.size(); i++ ) { StepsType st = GameManager::StringToStepsType(asStepsTypesToHide[i]); if( st != STEPS_TYPE_INVALID ) { const vector<StepsType>::iterator iter = find( aStepsTypesToShow.begin(), aStepsTypesToShow.end(), st ); if( iter != aStepsTypesToShow.end() ) aStepsTypesToShow.erase( iter ); } } } } // // fill m_vPagesToShow // if( SHOW_CATEGORIES ) { for( unsigned i=0; i<aStepsTypesToShow.size(); i++ ) { for( int c=0; c<NUM_RANKING_CATEGORIES; c++ ) { PageToShow pts; pts.type = PAGE_TYPE_CATEGORY; pts.colorIndex = i; pts.category = (RankingCategory)c; pts.nt = aStepsTypesToShow[i]; m_vPagesToShow.push_back( pts ); } } } { vector<CString> asCoursePaths; split( COURSES_TO_SHOW, ",", asCoursePaths, true ); for( unsigned i=0; i<aStepsTypesToShow.size(); i++ ) { for( unsigned c=0; c<asCoursePaths.size(); c++ ) { PageToShow pts; pts.type = PAGE_TYPE_TRAIL; pts.colorIndex = i; pts.nt = aStepsTypesToShow[i]; pts.pCourse = SONGMAN->GetCourseFromPath( asCoursePaths[c] ); if( pts.pCourse == NULL ) continue; pts.pTrail = pts.pCourse->GetTrail( pts.nt ); if( pts.pTrail == NULL ) continue; m_vPagesToShow.push_back( pts ); } } } if( SHOW_ALL_STEPS_SCORES ) { vector<Song*> vpSongs = SONGMAN->GetAllSongs(); if( !vpSongs.empty() ) { for( unsigned i=0; i<aStepsTypesToShow.size(); i++ ) { PageToShow pts; pts.type = PAGE_TYPE_ALL_STEPS; pts.colorIndex = i; pts.nt = aStepsTypesToShow[i]; m_vPagesToShow.push_back( pts ); } } } if( SHOW_ALL_COURSE_SCORES ) { vector<Course*> courses; SONGMAN->GetAllCourses( courses, false ); if( !courses.empty() ) { for( unsigned i=0; i<aStepsTypesToShow.size(); i++ ) { PageToShow pts; pts.type = PAGE_TYPE_ALL_COURSES; pts.colorIndex = i; pts.nt = aStepsTypesToShow[i]; m_vPagesToShow.push_back( pts ); } } } this->ClearMessageQueue( SM_BeginFadingOut ); // ignore ScreenAttract's SecsToShow this->PostScreenMessage( SM_ShowNextPage, 0.5f ); }
bool CourseWriterCRS::Write( const Course &course, RageFileBasic &f, bool bSavingCache ) { ASSERT( !course.m_bIsAutogen ); f.PutLine( ssprintf("#COURSE:%s;", course.m_sMainTitle.c_str()) ); if( course.m_sMainTitleTranslit != "" ) f.PutLine( ssprintf("#COURSETRANSLIT:%s;", course.m_sMainTitleTranslit.c_str()) ); if( course.m_sScripter != "" ) f.PutLine( ssprintf("#SCRIPTER:%s;", course.m_sScripter.c_str()) ); if( course.m_bRepeat ) f.PutLine( "#REPEAT:YES;" ); if( course.m_iLives != -1 ) f.PutLine( ssprintf("#LIVES:%i;", course.m_iLives) ); if( !course.m_sBannerPath.empty() ) f.PutLine( ssprintf("#BANNER:%s;", course.m_sBannerPath.c_str()) ); if( !course.m_setStyles.empty() ) { vector<RString> asStyles; asStyles.insert( asStyles.begin(), course.m_setStyles.begin(), course.m_setStyles.end() ); f.PutLine( ssprintf("#STYLE:%s;", join( ",", asStyles ).c_str()) ); } FOREACH_ENUM( CourseDifficulty,cd ) { if( course.m_iCustomMeter[cd] == -1 ) continue; f.PutLine( ssprintf("#METER:%s:%i;", DifficultyToCRSString(cd).c_str(), course.m_iCustomMeter[cd]) ); } if( bSavingCache ) { f.PutLine( "// cache tags:" ); Course::RadarCache_t::const_iterator it; for( it = course.m_RadarCache.begin(); it != course.m_RadarCache.end(); ++it ) { // #RADAR:type:difficulty:value,value,value...; const Course::CacheEntry &entry = it->first; StepsType st = entry.first; CourseDifficulty cd = entry.second; vector<RString> asRadarValues; const RadarValues &rv = it->second; for( int r=0; r < NUM_RadarCategory; r++ ) asRadarValues.push_back( ssprintf("%.3f", rv[r]) ); RString sLine = ssprintf( "#RADAR:%i:%i:", st, cd ); sLine += join( ",", asRadarValues ) + ";"; f.PutLine( sLine ); } f.PutLine( "// end cache tags" ); } for( unsigned i=0; i<course.m_vEntries.size(); i++ ) { const CourseEntry& entry = course.m_vEntries[i]; for( unsigned j = 0; j < entry.attacks.size(); ++j ) { if( j == 0 ) f.PutLine( "#MODS:" ); const Attack &a = entry.attacks[j]; f.Write( ssprintf( " TIME=%.2f:LEN=%.2f:MODS=%s", a.fStartSecond, a.fSecsRemaining, a.sModifiers.c_str() ) ); if( j+1 < entry.attacks.size() ) f.Write( ":" ); else f.Write( ";" ); f.PutLine( "" ); } if( entry.fGainSeconds > 0 ) f.PutLine( ssprintf("#GAINSECONDS:%f;", entry.fGainSeconds) ); if( entry.songSort == SongSort_MostPlays && entry.iChooseIndex != -1 ) { f.Write( ssprintf( "#SONG:BEST%d", entry.iChooseIndex+1 ) ); } else if( entry.songSort == SongSort_FewestPlays && entry.iChooseIndex != -1 ) { f.Write( ssprintf( "#SONG:WORST%d", entry.iChooseIndex+1 ) ); } else if( entry.songID.ToSong() ) { Song *pSong = entry.songID.ToSong(); const RString &sSong = Basename( pSong->GetSongDir() ); f.Write( "#SONG:" ); if( !entry.songCriteria.m_sGroupName.empty() ) f.Write( entry.songCriteria.m_sGroupName + '/' ); f.Write( sSong ); } else if( !entry.songCriteria.m_sGroupName.empty() ) { f.Write( ssprintf( "#SONG:%s/*", entry.songCriteria.m_sGroupName.c_str() ) ); } else { f.Write( "#SONG:*" ); } f.Write( ":" ); if( entry.stepsCriteria.m_difficulty != Difficulty_Invalid ) f.Write( DifficultyToString(entry.stepsCriteria.m_difficulty) ); else if( entry.stepsCriteria.m_iLowMeter != -1 && entry.stepsCriteria.m_iHighMeter != -1 ) f.Write( ssprintf( "%d..%d", entry.stepsCriteria.m_iLowMeter, entry.stepsCriteria.m_iHighMeter ) ); f.Write( ":" ); RString sModifiers = entry.sModifiers; if( entry.bSecret ) { if( sModifiers != "" ) sModifiers += ","; sModifiers += entry.bSecret? "noshowcourse":"showcourse"; } if( entry.bNoDifficult ) { if( sModifiers != "" ) sModifiers += ","; sModifiers += "nodifficult"; } if( entry.iGainLives > -1 ) { if( !sModifiers.empty() ) sModifiers += ','; sModifiers += ssprintf( "award%d", entry.iGainLives ); } f.Write( sModifiers ); f.PutLine( ";" ); } return true; }
void EditCoursesSongMenu::OnRowValueChanged( Row row ) { LOG->Trace( "EditCoursesSongMenu::OnRowValueChanged(%i)", row ); m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[0].EnableAnimation( CanGoLeft() ); m_sprArrows[1].EnableAnimation( CanGoRight() ); CString sGroup = GetSelectedGroup(); Song *pSong = GetSelectedSong(); switch( row ) { case ROW_GROUP: { CHECKPOINT; m_textValue[ROW_GROUP].SetText( sGroup ); UpdateSongList(); pSong = GetSelectedSong(); } // fall through case ROW_SONG: CHECKPOINT; m_textValue[ROW_SONG].SetText( pSong? pSong->GetTranslitMainTitle():CString("") ); // fall through case ROW_TYPE: CHECKPOINT; m_textValue[ROW_TYPE].SetText( CourseEntryTypeToString(GetSelectedType()) ); for( int i = 0; i < NUM_ROWS; ++i ) m_textValue[i].SetDiffuse( g_bRowEnabledForType[GetSelectedType()][i]? RageColor(1,1,1,1):RageColor(0.4f,0.4f,0.4f,1) ); // fall through case ROW_DIFFICULTY: { CHECKPOINT; Difficulty dc = GetSelectedDifficulty(); if( dc == DIFFICULTY_INVALID ) m_textValue[ROW_DIFFICULTY].SetText( "(any)" ); else m_textValue[ROW_DIFFICULTY].SetText( DifficultyToString(dc) ); // fall through } case ROW_LOW_METER: CHECKPOINT; if( GetLowMeter() == -1 ) m_textValue[ROW_LOW_METER].SetText( "(any)" ); else m_textValue[ROW_LOW_METER].SetText( ssprintf("%d",GetLowMeter()) ); // fall through case ROW_HIGH_METER: CHECKPOINT; if( GetHighMeter() == -1 ) m_textValue[ROW_HIGH_METER].SetText( "(any)" ); else m_textValue[ROW_HIGH_METER].SetText( ssprintf("%d",GetHighMeter()) ); // fall through case ROW_BEST_WORST_VALUE: CHECKPOINT; m_textValue[ROW_BEST_WORST_VALUE].SetText( ssprintf("%d",GetBestWorst()+1) ); break; default: ASSERT(0); // invalid row } }
RString TrailID::ToString() const { RString s = GAMEMAN->GetStepsTypeInfo(st).szName; s += " " + DifficultyToString( cd ); return s; }
void EditCoursesMenu::OnRowValueChanged( Row row ) { LOG->Trace( "EditCoursesMenu::OnRowValueChanged(%i)", row ); const bool bCanGoLeft = CanGoLeft(), bCanGoRight = CanGoRight(); m_sprArrows[0].SetDiffuse( bCanGoLeft?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[1].SetDiffuse( bCanGoRight?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[0].EnableAnimation( bCanGoLeft ); m_sprArrows[1].EnableAnimation( bCanGoRight ); Course* pCourse = GetSelectedCourse(); CourseEntry* pEntry = GetSelectedEntry(); switch( row ) { case ROW_COURSE: CHECKPOINT; m_textValue[ROW_COURSE].SetText( pCourse->GetFullDisplayTitle() ); m_CourseBanner.LoadFromCourse( pCourse ); m_CourseBanner.ScaleToClipped( COURSE_BANNER_WIDTH, COURSE_BANNER_HEIGHT ); m_iSelection[ROW_ENTRY] = 0; pEntry = GetSelectedEntry(); if( pEntry == NULL ) { CourseEntry ce; const vector<Song*> &apSongs = SONGMAN->GetAllSongs(); ASSERT( !apSongs.empty() ); ce.pSong = apSongs[0]; pCourse->m_entries.push_back( ce ); pEntry = GetSelectedEntry(); } // fall through case ROW_COURSE_OPTIONS: CHECKPOINT; m_textValue[ROW_COURSE_OPTIONS].SetText( ssprintf( "(START) %s, %s, ", pCourse->m_bRepeat ? "repeat" : "no repeat", pCourse->m_bRandomize ? "randomize" : "no randomize" ) + ssprintf( (pCourse->m_iLives==-1) ? "use bar life" : "%d lives", pCourse->m_iLives ) ); // fall through case ROW_ACTION: CHECKPOINT; m_textValue[ROW_ACTION].SetText( "(START) " + ActionToString(GetSelectedAction()) ); // fall through case ROW_ENTRY: CHECKPOINT; m_textValue[ROW_ENTRY].SetText( ssprintf("%d of %d",m_iSelection[ROW_ENTRY]+1, (int)GetSelectedCourse()->m_entries.size()) ); m_iSelection[ROW_ENTRY_TYPE] = pEntry->type; // fall through case ROW_ENTRY_TYPE: CHECKPOINT; m_textValue[ROW_ENTRY_TYPE].SetText( pEntry ? CourseEntryTypeToString(pEntry->type) : CString("(none)") ); // fall through case ROW_ENTRY_OPTIONS: CHECKPOINT; { CStringArray as; const bool *bShow = g_bRowEnabledForType[GetSelectedEntry()->type]; if( bShow[song] ) as.push_back( pEntry->pSong ? pEntry->pSong->GetFullTranslitTitle() : CString("(missing song)") ); if( bShow[group] ) as.push_back( pEntry->group_name.empty() ? CString("(no group)") : pEntry->group_name ); if( bShow[difficulty] ) if( pEntry->difficulty != DIFFICULTY_INVALID ) as.push_back( DifficultyToString(pEntry->difficulty) ); if( bShow[low_meter] ) if( pEntry->low_meter > 0 ) as.push_back( ssprintf("low meter %d", pEntry->low_meter) ); if( bShow[high_meter] ) if( pEntry->high_meter > 0 ) as.push_back( ssprintf("high meter %d", pEntry->high_meter) ); if( bShow[best_worst_value] ) if( pEntry->players_index != -1 ) as.push_back( ssprintf("rank %d", pEntry->players_index+1) ); m_textValue[ROW_ENTRY_OPTIONS].SetText( "(START) " + join(", ",as) ); } // fall through case ROW_ENTRY_PLAYER_OPTIONS: CHECKPOINT; { CString s = "(START) "; PlayerOptions po; po.FromString( pEntry->modifiers ); if( po.GetString().empty() ) s += "(none)"; else s += po.GetString(); m_textValue[ROW_ENTRY_PLAYER_OPTIONS].SetText( s ); } // fall through case ROW_ENTRY_SONG_OPTIONS: CHECKPOINT; { CString s = "(START) "; SongOptions so; so.FromString( pEntry->modifiers ); if( so.GetString().empty() ) s += "(none)"; else s += so.GetString(); m_textValue[ROW_ENTRY_SONG_OPTIONS].SetText( s ); } break; default: ASSERT(0); // invalid row } }
XNode* Profile::SaveGeneralDataCreateNode() const { XNode* pGeneralDataNode = new XNode; pGeneralDataNode->name = "GeneralData"; // TRICKY: These are write-only elements that are never read again. This // data is required by other apps (like internet ranking), but is // redundant to the game app. pGeneralDataNode->AppendChild( "DisplayName", GetDisplayName() ); pGeneralDataNode->AppendChild( "IsMachine", IsMachine() ); pGeneralDataNode->AppendChild( "Guid", m_sGuid ); pGeneralDataNode->AppendChild( "UsingProfileDefaultModifiers", m_bUsingProfileDefaultModifiers ); pGeneralDataNode->AppendChild( "DefaultModifiers", m_sDefaultModifiers ); pGeneralDataNode->AppendChild( "SortOrder", SortOrderToString(m_SortOrder) ); pGeneralDataNode->AppendChild( "LastDifficulty", DifficultyToString(m_LastDifficulty) ); pGeneralDataNode->AppendChild( "LastCourseDifficulty", CourseDifficultyToString(m_LastCourseDifficulty) ); pGeneralDataNode->AppendChild( m_lastSong.CreateNode() ); pGeneralDataNode->AppendChild( m_lastCourse.CreateNode() ); pGeneralDataNode->AppendChild( "TotalPlays", m_iTotalPlays ); pGeneralDataNode->AppendChild( "TotalPlaySeconds", m_iTotalPlaySeconds ); pGeneralDataNode->AppendChild( "TotalGameplaySeconds", m_iTotalGameplaySeconds ); pGeneralDataNode->AppendChild( "CurrentCombo", m_iCurrentCombo ); pGeneralDataNode->AppendChild( "TotalCaloriesBurned", m_fTotalCaloriesBurned ); pGeneralDataNode->AppendChild( "LastPlayedMachineGuid", m_sLastPlayedMachineGuid ); pGeneralDataNode->AppendChild( "LastPlayedDate", m_LastPlayedDate ); pGeneralDataNode->AppendChild( "TotalDancePoints", m_iTotalDancePoints ); pGeneralDataNode->AppendChild( "NumExtraStagesPassed", m_iNumExtraStagesPassed ); pGeneralDataNode->AppendChild( "NumExtraStagesFailed", m_iNumExtraStagesFailed ); pGeneralDataNode->AppendChild( "NumToasties", m_iNumToasties ); pGeneralDataNode->AppendChild( "TotalTapsAndHolds", m_iTotalTapsAndHolds ); pGeneralDataNode->AppendChild( "TotalJumps", m_iTotalJumps ); pGeneralDataNode->AppendChild( "TotalHolds", m_iTotalHolds ); pGeneralDataNode->AppendChild( "TotalMines", m_iTotalMines ); pGeneralDataNode->AppendChild( "TotalHands", m_iTotalHands ); // Keep declared variables in a very local scope so they aren't // accidentally used where they're not intended. There's a lot of // copying and pasting in this code. { XNode* pUnlockedSongs = pGeneralDataNode->AppendChild("UnlockedSongs"); for( set<int>::const_iterator it = m_UnlockedSongs.begin(); it != m_UnlockedSongs.end(); ++it ) pUnlockedSongs->AppendChild( ssprintf("Unlock%i", *it) ); } { XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode"); FOREACH_PlayMode( pm ) { /* Don't save unplayed PlayModes. */ if( !m_iNumSongsPlayedByPlayMode[pm] ) continue; pNumSongsPlayedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPlayedByPlayMode[pm] ); } } { XNode* pNumSongsPlayedByStyle = pGeneralDataNode->AppendChild("NumSongsPlayedByStyle"); for( map<StyleID,int>::const_iterator iter = m_iNumSongsPlayedByStyle.begin(); iter != m_iNumSongsPlayedByStyle.end(); iter++ ) { const StyleID &s = iter->first; int iNumPlays = iter->second; XNode *pStyleNode = s.CreateNode(); pStyleNode->SetValue( iNumPlays ); pNumSongsPlayedByStyle->AppendChild( pStyleNode ); } } { XNode* pNumSongsPlayedByDifficulty = pGeneralDataNode->AppendChild("NumSongsPlayedByDifficulty"); FOREACH_Difficulty( dc ) { if( !m_iNumSongsPlayedByDifficulty[dc] ) continue; pNumSongsPlayedByDifficulty->AppendChild( DifficultyToString(dc), m_iNumSongsPlayedByDifficulty[dc] ); } } { XNode* pNumSongsPlayedByMeter = pGeneralDataNode->AppendChild("NumSongsPlayedByMeter"); for( int i=0; i<MAX_METER+1; i++ ) { if( !m_iNumSongsPlayedByMeter[i] ) continue; pNumSongsPlayedByMeter->AppendChild( ssprintf("Meter%d",i), m_iNumSongsPlayedByMeter[i] ); } } { XNode* pNumStagesPassedByGrade = pGeneralDataNode->AppendChild("NumStagesPassedByGrade"); FOREACH_Grade( g ) { if( !m_iNumStagesPassedByGrade[g] ) continue; pNumStagesPassedByGrade->AppendChild( GradeToString(g), m_iNumStagesPassedByGrade[g] ); } } { XNode* pNumStagesPassedByPlayMode = pGeneralDataNode->AppendChild("NumStagesPassedByPlayMode"); FOREACH_PlayMode( pm ) { /* Don't save unplayed PlayModes. */ if( !m_iNumStagesPassedByPlayMode[pm] ) continue; pNumStagesPassedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumStagesPassedByPlayMode[pm] ); } } return pGeneralDataNode; }
static NoteData ParseNoteData(RString &step1, RString &step2, Steps &out, const RString &path) { g_mapDanceNoteToNoteDataColumn.clear(); switch( out.m_StepsType ) { case StepsType_dance_single: g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; break; case StepsType_dance_double: case StepsType_dance_couple: g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7; break; case StepsType_dance_solo: g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4; g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5; break; DEFAULT_FAIL( out.m_StepsType ); } NoteData newNoteData; newNoteData.SetNumTracks( g_mapDanceNoteToNoteDataColumn.size() ); for( int pad=0; pad<2; pad++ ) // foreach pad { RString sStepData; switch( pad ) { case 0: sStepData = step1; break; case 1: if( step2 == "" ) // no data continue; // skip sStepData = step2; break; DEFAULT_FAIL( pad ); } sStepData.Replace("\n", ""); sStepData.Replace("\r", ""); sStepData.Replace("\t", ""); sStepData.Replace(" ", ""); double fCurrentBeat = 0; double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE; for( size_t i=0; i<sStepData.size(); ) { char c = sStepData[i++]; switch( c ) { // begins a series case '(': fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE; break; case '[': fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE; break; case '{': fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE; break; case '`': fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE; break; // ends a series case ')': case ']': case '}': case '\'': case '>': fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE; break; default: // this is a note character { if( c == '!' ) { LOG->UserLog( "Song file", path, "has an unexpected character: '!'." ); continue; } bool jump = false; if( c == '<' ) { /* Arr. Is this a jump or a 1/192 marker? */ if( Is192( sStepData, i ) ) { fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE; break; } /* It's a jump. * We need to keep reading notes until we hit a >. */ jump = true; i++; } const int iIndex = BeatToNoteRow( (float)fCurrentBeat ); i--; do { c = sStepData[i++]; if( jump && c == '>' ) break; int iCol1, iCol2; DWIcharToNoteCol( c, (GameController)pad, iCol1, iCol2, path ); if( iCol1 != -1 ) newNoteData.SetTapNote(iCol1, iIndex, TAP_ORIGINAL_TAP); if( iCol2 != -1 ) newNoteData.SetTapNote(iCol2, iIndex, TAP_ORIGINAL_TAP); if(i>=sStepData.length()) { break; //we ran out of data //while looking for the ending > mark } if( sStepData[i] == '!' ) { i++; const char holdChar = sStepData[i++]; DWIcharToNoteCol(holdChar, (GameController)pad, iCol1, iCol2, path ); if( iCol1 != -1 ) newNoteData.SetTapNote(iCol1, iIndex, TAP_ORIGINAL_HOLD_HEAD); if( iCol2 != -1 ) newNoteData.SetTapNote(iCol2, iIndex, TAP_ORIGINAL_HOLD_HEAD); } } while( jump ); fCurrentBeat += fCurrentIncrementer; } break; } } } /* Fill in iDuration. */ for( int t=0; t<newNoteData.GetNumTracks(); ++t ) { FOREACH_NONEMPTY_ROW_IN_TRACK( newNoteData, t, iHeadRow ) { TapNote tn = newNoteData.GetTapNote( t, iHeadRow ); if( tn.type != TapNote::hold_head ) continue; int iTailRow = iHeadRow; bool bFound = false; while( !bFound && newNoteData.GetNextTapNoteRowForTrack(t, iTailRow) ) { const TapNote &TailTap = newNoteData.GetTapNote( t, iTailRow ); if( TailTap.type == TapNote::empty ) continue; newNoteData.SetTapNote( t, iTailRow, TAP_EMPTY ); tn.iDuration = iTailRow - iHeadRow; newNoteData.SetTapNote( t, iHeadRow, tn ); bFound = true; } if( !bFound ) { /* The hold was never closed. */ LOG->UserLog("Song file", path, "failed to close a hold note in \"%s\" on track %i", DifficultyToString(out.GetDifficulty()).c_str(), t); newNoteData.SetTapNote( t, iHeadRow, TAP_EMPTY ); } } }
void EditMenu::OnRowValueChanged( Row row ) { m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); m_sprArrows[0].EnableAnimation( CanGoLeft() ); m_sprArrows[1].EnableAnimation( CanGoRight() ); switch( row ) { case ROW_GROUP: m_textValue[ROW_GROUP].SetText( SONGMAN->ShortenGroupName(GetSelectedGroup()) ); m_GroupBanner.LoadFromGroup( GetSelectedGroup() ); m_GroupBanner.ScaleToClipped( GROUP_BANNER_WIDTH, GROUP_BANNER_HEIGHT ); m_pSongs.clear(); SONGMAN->GetSongs( m_pSongs, GetSelectedGroup() ); m_iSelection[ROW_SONG] = 0; // fall through case ROW_SONG: m_textValue[ROW_SONG].SetText( "" ); m_SongBanner.LoadFromSong( GetSelectedSong() ); m_SongBanner.ScaleToClipped( SONG_BANNER_WIDTH, SONG_BANNER_HEIGHT ); m_SongTextBanner.LoadFromSong( GetSelectedSong() ); // fall through case ROW_STEPS_TYPE: m_textValue[ROW_STEPS_TYPE].SetText( GAMEMAN->StepsTypeToString(GetSelectedStepsType()) ); // fall through case ROW_DIFFICULTY: m_textValue[ROW_DIFFICULTY].SetText( DifficultyToString(GetSelectedDifficulty()) ); m_Meter.SetFromSteps( GetSelectedNotes() ); // fall through case ROW_SOURCE_STEPS_TYPE: m_textLabel[ROW_SOURCE_STEPS_TYPE].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) ); m_textValue[ROW_SOURCE_STEPS_TYPE].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) ); m_textValue[ROW_SOURCE_STEPS_TYPE].SetText( GAMEMAN->StepsTypeToString(GetSelectedSourceStepsType()) ); // fall through case ROW_SOURCE_DIFFICULTY: m_textLabel[ROW_SOURCE_DIFFICULTY].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) ); m_textValue[ROW_SOURCE_DIFFICULTY].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) ); m_textValue[ROW_SOURCE_DIFFICULTY].SetText( DifficultyToString(GetSelectedSourceDifficulty()) ); m_SourceMeter.SetFromSteps( GetSelectedSourceNotes() ); m_SourceMeter.SetZoomY( GetSelectedNotes()?0.f:1.f ); m_Actions.clear(); if( GetSelectedNotes() ) { m_Actions.push_back( ACTION_EDIT ); m_Actions.push_back( ACTION_DELETE ); } else if( GetSelectedSourceNotes() ) { m_Actions.push_back( ACTION_COPY ); m_Actions.push_back( ACTION_AUTOGEN ); m_Actions.push_back( ACTION_BLANK ); } else { m_Actions.push_back( ACTION_BLANK ); } m_iSelection[ROW_ACTION] = 0; // fall through case ROW_ACTION: m_textValue[ROW_ACTION].SetText( ActionToString(GetSelectedAction()) ); break; default: ASSERT(0); // invalid row } }
static CString GetDifficultyCommandName( Difficulty d ) { return "Set"+DifficultyToString(d); }