diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index d6f436c9a3..a0b6007429 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -15,8 +15,14 @@ StepMania 5.0 ????????? | 20110??? number of songs installed. Fixes issue 373. [AJ] * [NotesAllSSC] Add the #CHARTNAME tag to the Steps. #DESCRIPTION is now for more detailed descriptions, or perhaps some short hand lingo. All files - that used #DESCRIPTION will have their values copied to #CHARTNAME on + that used #DESCRIPTION will have their values moved to #CHARTNAME on load. [Wolfman2000] +* [ScreenEdit] Add a Steps Data menu for getting numerical step data on the + chart. This is a read only menu. Edit Steps Information contains writable + information. [Wolfman2000] +* [NotesAllSSC] Add the Steps version of #DISPLAYBPM. The Song version is + still there, so themes should not have to worry about breakage. + [Wolfman2000] 2011/07/06 ---------- diff --git a/Docs/SimfileFormats/ssc_msd5.txt b/Docs/SimfileFormats/ssc_msd5.txt index 9c00273a64..07ae7177ed 100644 --- a/Docs/SimfileFormats/ssc_msd5.txt +++ b/Docs/SimfileFormats/ssc_msd5.txt @@ -42,6 +42,7 @@ // begin #NOTEDATA# // marks a new note data section // information from #NOTES moved here +#CHARTNAME:; #STEPSTYPE:; #DESCRIPTION:; #CHARTSTYLE:; @@ -63,6 +64,7 @@ #FAKES:; #LABELS:; #ATTACKS:; +#DISPLAYBPM:; // actual step data #NOTES:; diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 8cd1019f9d..505e6582ca 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -817,6 +817,7 @@ CoinsPerCredit=Coins Per Credit Connection=Connection Convert pause to beats=Convert stop to beats Convert delay to beats=Convert delay to beats +Convert selection to attack=Convert selection to Attack Convert selection to pause=Convert selection to stop Convert selection to delay=Convert selection to delay Convert selection to warp=Convert selection to Warp Segment @@ -878,6 +879,7 @@ Entry %d=Entry %d EventMode=Event Mode Exit=Exit Fail=Fail +Fakes=Fakes FastLoad=Fast\nLoad File1 Global BGAnimation=File1 Global BGAnimation File1 Global Movie=File1 Global Movie @@ -921,6 +923,7 @@ Key Joy Mappings=Config Key/Joy Mappings Language=Language Last second hint=Last second hint Layer=Layer +Lifts=Lifts LifeDifficulty=Life Difficulty LifeType=Life Type Low Meter=Low Meter @@ -987,6 +990,7 @@ Rename=Rename Reset To Defaults=Reset Options To Default Values Revert from disk=Revert from disk Revert to last save=Revert from cache +Rolls=Rolls Save=Save SaveScores=Save Scores SaveReplays=Save Replays @@ -1051,6 +1055,7 @@ Type=Type Turn=Turn Undo=Undo UseUnlockSystem=Unlock System +View steps data=View Steps Data VisualDelaySeconds=Visual Delay Voltage=Voltage Vsync=Wait For Vsync diff --git a/Themes/_fallback/Scripts/02 Branches.lua b/Themes/_fallback/Scripts/02 Branches.lua index 8463b2283a..3f89ca77da 100644 --- a/Themes/_fallback/Scripts/02 Branches.lua +++ b/Themes/_fallback/Scripts/02 Branches.lua @@ -68,7 +68,7 @@ Branch = { if PROFILEMAN:GetNumLocalProfiles() >= 2 then return "ScreenSelectProfile"; else - return Branch.AfterSelectProfile(); + return "ScreenProfileLoad"; end end, OptionsEdit = function() @@ -79,7 +79,7 @@ Branch = { return "ScreenOptionsEdit"; end, AfterProfileLoad = function() - return "ScreenSelectProfile" + return Branch.AfterSelectProfile() end, AfterSelectProfile = function() if ( THEME:GetMetric("Common","AutoSetStyle") == true ) then diff --git a/Themes/_fallback/Scripts/03 CustomSpeedMods.lua b/Themes/_fallback/Scripts/03 CustomSpeedMods.lua index 093edcd2fb..f84874a591 100644 --- a/Themes/_fallback/Scripts/03 CustomSpeedMods.lua +++ b/Themes/_fallback/Scripts/03 CustomSpeedMods.lua @@ -1,9 +1,12 @@ --[[ -Custom Speed Mods v2.0 (for sm-ssc) +Custom Speed Mods v2.1 (for StepMania 5) by AJ Kelly of KKI Labs ( http://kki.ajworld.net/ ) changelog: +v2.1 (StepMania 5 Preview 2) +* Added support for m-Mods. + v2.0 (for sm-ssc) Giant rewrite of the speed mod parser. This rewrite comes with the following changes/features: @@ -38,9 +41,6 @@ v1.2 v1.1 * Cleaned up code some, I think. -________________________________________________________________________________ -anticipated future changes: -* M-Mod support (when sm-ssc integrates it) ]] -- ProfileDir(slot): gets the profile dir for slot, @@ -150,7 +150,6 @@ local function SpeedModSort(tab) local xMods = {} local mMods = {} local cMods = {} - --local mMods = {} -- convert to numbers so sorting works: for i=1,#tab do @@ -160,7 +159,8 @@ local function SpeedModSort(tab) if string.find(tab[i],"C%d") then typ = cMods val = string.gsub(tab[i], "C", "") - elseif string.find(tab[i],"m%d") then + -- support both cases because I want to hit people -freem + elseif string.find(tab[i],"m%d") or string.find(tab[i],"M%d") then typ = mMods val = string.gsub(tab[i], "m", "") else @@ -187,7 +187,6 @@ local function SpeedModSort(tab) for i=1,#mMods do table.insert(fin, "m"..mMods[i]) end - --for i=1,#mMods do table.insert(fin, "M"..mMods[i]); end; return fin end @@ -298,7 +297,7 @@ function SpeedMods() end --[[ -Copyright © 2008-2009 AJ Kelly/KKI Labs. +Copyright © 2008-2011 AJ Kelly/KKI Labs. Use freely, so long this notice and the above documentation remains. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" diff --git a/Themes/_fallback/Scripts/03 Gameplay.lua b/Themes/_fallback/Scripts/03 Gameplay.lua index f26977c630..90dcc7c88a 100644 --- a/Themes/_fallback/Scripts/03 Gameplay.lua +++ b/Themes/_fallback/Scripts/03 Gameplay.lua @@ -11,7 +11,7 @@ function GetExtraColorThreshold() sGame = GAMESTATE:GetCurrentGame():GetName() local Modes = { dance = 10, - pump = 15, + pump = 21, beat = 12, kb7 = 10, para = 10, diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 5749ed105f..3a9db0d6ab 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -28,7 +28,7 @@ ScreenHeight=480 AutoSetStyle=GetUserPrefB("UserPrefAutoSetStyle") # Default modifiers and noteskin. -DefaultModifiers="1.5x" +DefaultModifiers="" DefaultNoteSkinName="default" # Difficulties to show. Useful for custom games where you want to hide these. @@ -3740,6 +3740,9 @@ Fallback="ScreenMiniMenu" [ScreenMiniMenuStepsInformation] Fallback="ScreenMiniMenu" +[ScreenMiniMenuStepsData] +Fallback="ScreenMiniMenu" + [ScreenMiniMenuSongInformation] Fallback="ScreenMiniMenu" diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index e10f1162a9..0073198195 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -465,8 +465,10 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach { pNewNotes->SetChartName(sParams[1]); } - // TODO: Make this the else clause? - pNewNotes->SetDescription( sParams[1] ); + else + { + pNewNotes->SetDescription(sParams[1]); + } } else if( sValueName=="DIFFICULTY" ) @@ -585,6 +587,23 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach { stepsTiming.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); } + + else if( sValueName=="DISPLAYBPM" ) + { + // #DISPLAYBPM:[xxx][xxx:xxx]|[*]; + if( sParams[1] == "*" ) + pNewNotes->SetDisplayBPM(DISPLAY_BPM_RANDOM); + else + { + pNewNotes->SetDisplayBPM(DISPLAY_BPM_SPECIFIED); + float min = StringToFloat(sParams[1]); + pNewNotes->SetMinBPM(min); + if(sParams[2].empty()) + pNewNotes->SetMaxBPM(min); + else + pNewNotes->SetMaxBPM(StringToFloat(sParams[2])); + } + } break; } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index db5bc40d50..70578ee0dd 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -335,6 +335,26 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa Trim(attacks, ":"); // just in case something screwy happens. lines.push_back( ssprintf( "#ATTACKS:%s;", attacks.c_str())); + switch( in.GetDisplayBPM() ) + { + case DISPLAY_BPM_ACTUAL: + // write nothing + break; + case DISPLAY_BPM_SPECIFIED: + { + float small = in.GetMinBPM(); + float big = in.GetMaxBPM(); + if (small == big) + lines.push_back( ssprintf( "#DISPLAYBPM:%.6f;", small ) ); + else + lines.push_back( ssprintf( "#DISPLAYBPM:%.6f:%.6f;", small, big ) ); + break; + } + case DISPLAY_BPM_RANDOM: + lines.push_back( ssprintf( "#DISPLAYBPM:*;" ) ); + break; + } + RString sNoteData; in.GetSMNoteData( sNoteData ); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 013295415d..c9f872448a 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -63,6 +63,7 @@ AutoScreenMessage( SM_BackFromMainMenu ); AutoScreenMessage( SM_BackFromAreaMenu ); AutoScreenMessage( SM_BackFromAlterMenu ); AutoScreenMessage( SM_BackFromStepsInformation ); +AutoScreenMessage( SM_BackFromStepsData ); AutoScreenMessage( SM_BackFromOptions ); AutoScreenMessage( SM_BackFromSongInformation ); AutoScreenMessage( SM_BackFromBGChange ); @@ -521,12 +522,13 @@ static MenuDef g_MainMenu( MenuRowDef( ScreenEdit::play_selection, "Play selection", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::set_selection_start, "Set selection start", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::set_selection_end, "Set selection end", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::edit_steps_information, "Edit steps information", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::revert_to_last_save, "Revert to last save", true, EditMode_Home, true, true, 0, NULL ), MenuRowDef( ScreenEdit::revert_from_disk, "Revert from disk", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::options, "Editor options", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::edit_song_info, "Edit song info", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::edit_steps_information, "Edit steps information", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::edit_timing_data, "Edit Timing Data", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::view_steps_data, "View steps data", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::play_preview_music, "Play preview music", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::exit, "Exit Edit Mode", true, EditMode_Practice, true, true, 0, NULL ) ); @@ -569,6 +571,8 @@ static MenuDef g_AlterMenu( EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_fake, "Convert selection to fake", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_attack, "Convert selection to attack", true, + EditMode_Full, true, true, 0, NULL), MenuRowDef(ScreenEdit::routine_invert_notes, "Invert notes' player", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::routine_mirror_1_to_2, "Mirror Player 1 to 2", true, @@ -600,22 +604,32 @@ static MenuDef g_StepsInformation( "ScreenMiniMenuStepsInformation", MenuRowDef( ScreenEdit::difficulty, "Difficulty", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::meter, "Meter", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( ScreenEdit::predict_meter, "Predicted Meter", false, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::chartname, "Chart Name", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::description, "Description", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::chartstyle, "Chart Style", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::step_credit, "Step Author", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::predict_meter, "Predicted Meter", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::tap_notes, "Tap Steps", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::jumps, "Jumps", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::hands, "Hands", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::quads, "Quads", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::holds, "Holds", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::mines, "Mines", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::stream, "Stream", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::voltage, "Voltage", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::air, "Air", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::freeze, "Freeze", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::chaos, "Chaos", false, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::step_display_bpm, "Display BPM", true, EditMode_Full, true, true, 0, "Actual", "Specified", "Random" ), + MenuRowDef( ScreenEdit::step_min_bpm, "Min BPM", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::step_max_bpm, "Max BPM", true, EditMode_Full, true, true, 0, NULL ) +); + +static MenuDef g_StepsData( + "ScreenMiniMenuStepsData", + MenuRowDef( ScreenEdit::tap_notes, "Tap Steps", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::jumps, "Jumps", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::hands, "Hands", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::quads, "Quads", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::holds, "Holds", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::mines, "Mines", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::rolls, "Rolls", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::lifts, "Lifts", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::fakes, "Fakes", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::stream, "Stream", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::voltage, "Voltage", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::air, "Air", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::freeze, "Freeze", false, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::chaos, "Chaos", false, EditMode_Full, true, true, 0, NULL ) ); static MenuDef g_SongInformation( @@ -2931,6 +2945,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { HandleStepsInformationChoice( (StepsInformationChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); } + else if (SM == SM_BackFromStepsData) + { + HandleStepsDataChoice((StepsDataChoice)ScreenMiniMenu::s_iLastRowCode, + ScreenMiniMenu::s_viLastAnswers); + } + else if( SM == SM_BackFromSongInformation ) { HandleSongInformationChoice( (SongInformationChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); @@ -3494,11 +3514,23 @@ static void ChangeMinBPM( const RString &sNew ) GAMESTATE->m_pCurSong->m_fSpecifiedBPMMin = StringToFloat( sNew ); } +static void ChangeStepsMinBPM(const RString &sNew) +{ + Steps *step = GAMESTATE->m_pCurSteps[PLAYER_1]; + step->SetMinBPM(StringToFloat(sNew)); +} + static void ChangeMaxBPM( const RString &sNew ) { GAMESTATE->m_pCurSong->m_fSpecifiedBPMMax = StringToFloat( sNew ); } +static void ChangeStepsMaxBPM(const RString &sNew) +{ + Steps *step = GAMESTATE->m_pCurSteps[PLAYER_1]; + step->SetMaxBPM(StringToFloat(sNew)); +} + TimingData & ScreenEdit::GetAppropriateTiming() const { if( GAMESTATE->m_bIsUsingStepTiming ) @@ -3655,7 +3687,6 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns /* XXX: If the difficulty is changed from EDIT, and pSteps->WasLoadedFromProfile() * is true, we should warn that the steps will no longer be saved to the profile. */ Steps* pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - float fMusicSeconds = m_pSoundMusic->GetLengthSeconds(); g_StepsInformation.rows[difficulty].choices.clear(); FOREACH_ENUM( Difficulty, dc ) @@ -3675,20 +3706,32 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns g_StepsInformation.rows[chartstyle].SetOneUnthemedChoice( pSteps->GetChartStyle() ); g_StepsInformation.rows[step_credit].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Full); g_StepsInformation.rows[step_credit].SetOneUnthemedChoice( pSteps->GetCredit() ); - g_StepsInformation.rows[tap_notes].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumTapNotes()) ); - g_StepsInformation.rows[jumps].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumJumps()) ); - g_StepsInformation.rows[hands].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumHands()) ); - g_StepsInformation.rows[quads].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumQuads()) ); - g_StepsInformation.rows[holds].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumHoldNotes()) ); - g_StepsInformation.rows[mines].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumMines()) ); - g_StepsInformation.rows[stream].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetStreamRadarValue(m_NoteDataEdit,fMusicSeconds)) ); - g_StepsInformation.rows[voltage].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetVoltageRadarValue(m_NoteDataEdit,fMusicSeconds)) ); - g_StepsInformation.rows[air].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetAirRadarValue(m_NoteDataEdit,fMusicSeconds)) ); - g_StepsInformation.rows[freeze].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetFreezeRadarValue(m_NoteDataEdit,fMusicSeconds)) ); - g_StepsInformation.rows[chaos].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetChaosRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + g_StepsInformation.rows[step_display_bpm].iDefaultChoice = pSteps->GetDisplayBPM(); + g_StepsInformation.rows[step_min_bpm].SetOneUnthemedChoice( ssprintf("%.6f", pSteps->GetMinBPM())); + g_StepsInformation.rows[step_max_bpm].SetOneUnthemedChoice( ssprintf("%.6f", pSteps->GetMaxBPM())); EditMiniMenu( &g_StepsInformation, SM_BackFromStepsInformation, SM_None ); } break; + case view_steps_data: + { + float fMusicSeconds = m_pSoundMusic->GetLengthSeconds(); + g_StepsData.rows[tap_notes].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumTapNotes()) ); + g_StepsData.rows[jumps].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumJumps()) ); + g_StepsData.rows[hands].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumHands()) ); + g_StepsData.rows[quads].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumQuads()) ); + g_StepsData.rows[holds].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumHoldNotes()) ); + g_StepsData.rows[mines].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumMines()) ); + g_StepsData.rows[rolls].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumRolls()) ); + g_StepsData.rows[lifts].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumLifts()) ); + g_StepsData.rows[fakes].SetOneUnthemedChoice( ssprintf("%d", m_NoteDataEdit.GetNumFakes()) ); + g_StepsData.rows[stream].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetStreamRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + g_StepsData.rows[voltage].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetVoltageRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + g_StepsData.rows[air].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetAirRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + g_StepsData.rows[freeze].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetFreezeRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + g_StepsData.rows[chaos].SetOneUnthemedChoice( ssprintf("%.2f", NoteDataUtil::GetChaosRadarValue(m_NoteDataEdit,fMusicSeconds)) ); + EditMiniMenu( &g_StepsData, SM_BackFromStepsData, SM_None ); + break; + } case save: case save_on_exit: { @@ -4073,6 +4116,29 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn SetDirty(true); break; } + case convert_to_attack: + { + float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker); + float endBeat = NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker); + TimingData &timing = GetAppropriateTiming(); + float &start = g_fLastInsertAttackPositionSeconds; + float &length = g_fLastInsertAttackDurationSeconds; + start = timing.GetElapsedTimeFromBeat(startBeat); + length = timing.GetElapsedTimeFromBeat(endBeat) - start; + + AttackArray &attacks = GAMESTATE->m_bIsUsingStepTiming ? + m_pSteps->m_Attacks : m_pSong->m_Attacks; + int iAttack = FindAttackAtTime(attacks, start); + + PlayerOptions po; + if (iAttack >= 0) + po.FromString(attacks[iAttack].sModifiers); + + GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.Assign( ModsLevel_Preferred, po ); + SCREENMAN->AddNewScreenToTop( "ScreenPlayerOptions", SM_BackFromInsertStepAttackPlayerOptions ); + SetDirty(true); + break; + } case convert_to_fake: { float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker); @@ -4264,16 +4330,24 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns CheckNumberOfNotesAndUndo(); } +void ScreenEdit::HandleStepsDataChoice( StepsDataChoice c, const vector &iAnswers ) +{ + return; // nothing is done with the choices. Yet. +} + static LocalizedString ENTER_NEW_DESCRIPTION( "ScreenEdit", "Enter a new description." ); static LocalizedString ENTER_NEW_CHART_NAME("ScreenEdit", "Enter a new chart name."); static LocalizedString ENTER_NEW_CHART_STYLE( "ScreenEdit", "Enter a new chart style." ); static LocalizedString ENTER_NEW_STEP_AUTHOR( "ScreenEdit", "Enter the author who made this step pattern." ); static LocalizedString ENTER_NEW_METER( "ScreenEdit", "Enter a new meter." ); +static LocalizedString ENTER_MIN_BPM ("ScreenEdit","Enter a new min BPM."); +static LocalizedString ENTER_MAX_BPM ("ScreenEdit","Enter a new max BPM."); void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const vector &iAnswers ) { Steps* pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; Difficulty dc = (Difficulty)iAnswers[difficulty]; pSteps->SetDifficulty( dc ); + pSteps->SetDisplayBPM(static_cast(iAnswers[step_display_bpm])); switch( c ) { @@ -4295,42 +4369,60 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v m_pSteps->GetDescription(), MAX_STEPS_DESCRIPTION_LENGTH, SongUtil::ValidateCurrentStepsDescription, - ChangeDescription,NULL); + ChangeDescription, + NULL); + break; + } + case chartstyle: + { + ScreenTextEntry::TextEntry(SM_None, + ENTER_NEW_CHART_STYLE, + m_pSteps->GetChartStyle(), + 255, + NULL, + ChangeChartStyle, + NULL); + break; + } + case step_credit: + { + ScreenTextEntry::TextEntry(SM_None, + ENTER_NEW_STEP_AUTHOR, + m_pSteps->GetCredit(), + 255, + SongUtil::ValidateCurrentStepsCredit, + ChangeStepCredit, + NULL); + break; + } + case meter: + { + ScreenTextEntry::TextEntry(SM_BackFromDifficultyMeterChange, + ENTER_NEW_METER, + ssprintf("%d", m_pSteps->GetMeter()), + 4); + break; + } + case step_min_bpm: + { + ScreenTextEntry::TextEntry(SM_None, ENTER_MIN_BPM, + ssprintf("%.6f", pSteps->GetMinBPM()), 20, + ScreenTextEntry::FloatValidate, + ChangeStepsMinBPM, NULL); + break; + } + case step_max_bpm: + { + ScreenTextEntry::TextEntry(SM_None, ENTER_MAX_BPM, + ssprintf("%.6f", pSteps->GetMaxBPM()), 20, + ScreenTextEntry::FloatValidate, + ChangeStepsMaxBPM, NULL); break; } - case chartstyle: - ScreenTextEntry::TextEntry( - SM_None, - ENTER_NEW_CHART_STYLE, - m_pSteps->GetChartStyle(), - 255, - NULL, - ChangeChartStyle, - NULL - ); - break; - case step_credit: - ScreenTextEntry::TextEntry( - SM_None, - ENTER_NEW_STEP_AUTHOR, - m_pSteps->GetCredit(), - 255, - SongUtil::ValidateCurrentStepsCredit, - ChangeStepCredit, - NULL - ); - break; - case meter: - ScreenTextEntry::TextEntry( - SM_BackFromDifficultyMeterChange, - ENTER_NEW_METER, - ssprintf("%d", m_pSteps->GetMeter()), - 4 - ); - break; default: break; } + SetDirty(true); } static LocalizedString ENTER_MAIN_TITLE ("ScreenEdit","Enter a new main title."); @@ -4344,8 +4436,6 @@ static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist static LocalizedString ENTER_LAST_SECOND_HINT ("ScreenEdit","Enter a new last second hint."); static LocalizedString ENTER_PREVIEW_START ("ScreenEdit","Enter a new preview start."); static LocalizedString ENTER_PREVIEW_LENGTH ("ScreenEdit","Enter a new preview length."); -static LocalizedString ENTER_MIN_BPM ("ScreenEdit","Enter a new min BPM."); -static LocalizedString ENTER_MAX_BPM ("ScreenEdit","Enter a new max BPM."); void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vector &iAnswers ) { Song* pSong = GAMESTATE->m_pCurSong; @@ -4403,6 +4493,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec ScreenTextEntry::FloatValidate, ChangeMaxBPM, NULL ); break; }; + SetDirty(true); } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 416b71b1f5..5df94954ce 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -380,6 +380,7 @@ public: options, /**< Modify the PlayerOptions and SongOptions. */ edit_song_info, /**< Edit some general information about the song. */ edit_timing_data, /**< Edit the chart's timing data. */ + view_steps_data, /**< View step statistics. */ play_preview_music, /**< Play the song's preview music. */ exit, save_on_exit, @@ -408,6 +409,7 @@ public: convert_to_delay, /**< Convert the range into a DelaySegment. */ convert_to_warp, /**< Convert the range into a WarpSegment. */ convert_to_fake, /**< Convert the range into a FakeSegment. */ + convert_to_attack, /**< Convert the range into an Attack. */ routine_invert_notes, /**< Switch which player hits the note. */ routine_mirror_1_to_2, /**< Mirror Player 1's notes for Player 2. */ routine_mirror_2_to_1, /**< Mirror Player 2's notes for Player 1. */ @@ -510,20 +512,32 @@ public: chartstyle, /**< How is this chart meant to be played? */ step_credit, /**< Who wrote this individual chart? */ predict_meter, /**< What does the game think this chart's rating should be? */ + step_display_bpm, + step_min_bpm, + step_max_bpm, + NUM_STEPS_INFORMATION_CHOICES + }; + void HandleStepsInformationChoice( StepsInformationChoice c, const vector &iAnswers ); + + enum StepsDataChoice + { tap_notes, jumps, hands, quads, holds, mines, + rolls, + lifts, + fakes, stream, voltage, air, freeze, chaos, - NUM_STEPS_INFORMATION_CHOICES + NUM_STEPS_DATA_CHOICES }; - void HandleStepsInformationChoice( StepsInformationChoice c, const vector &iAnswers ); + void HandleStepsDataChoice(StepsDataChoice c, const vector &answers); enum SongInformationChoice { diff --git a/src/Song.cpp b/src/Song.cpp index 4c695b8c42..04e7f1fdff 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -41,7 +41,7 @@ * @brief The internal version of the cache for StepMania. * * Increment this value to invalidate the current cache. */ -const int FILE_CACHE_VERSION = 188; +const int FILE_CACHE_VERSION = 189; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; @@ -202,6 +202,9 @@ void Song::InitSteps(Steps *pSteps) pSteps->m_Timing = this->m_SongTiming; pSteps->m_sAttackString = this->m_sAttackString; pSteps->m_Attacks = this->m_Attacks; + pSteps->SetDisplayBPM(this->m_DisplayBPMType); + pSteps->SetMinBPM(this->m_fSpecifiedBPMMin); + pSteps->SetMaxBPM(this->m_fSpecifiedBPMMax); } void Song::GetDisplayBpms( DisplayBpms &AddTo ) const diff --git a/src/Song.h b/src/Song.h index 2931e6d82e..1a920b1968 100644 --- a/src/Song.h +++ b/src/Song.h @@ -20,7 +20,7 @@ void FixupPath( RString &path, const RString &sSongPath ); RString GetSongAssetPath( RString sPath, const RString &sSongPath ); /** @brief The version of the .ssc file format. */ -const static float STEPFILE_VERSION_NUMBER = 0.74f; +const static float STEPFILE_VERSION_NUMBER = 0.75f; /** @brief How many edits for this song can each profile have? */ const int MAX_EDITS_PER_SONG_PER_PROFILE = 15;