[editorKeysounds -> default] Let's do this.
I expect there to be issues, bugs, etc. I cannot find all of them. Let the people do that.
This commit is contained in:
@@ -13,6 +13,14 @@ StepMania 5.0 alpha 1a | 2012021?
|
|||||||
* [WheelBase, WheelItemBase] Turned WheelItemDataType into a Lua type,
|
* [WheelBase, WheelItemBase] Turned WheelItemDataType into a Lua type,
|
||||||
made WheelBase:GetSelectedType() return the enum instead of a number. [AJ]
|
made WheelBase:GetSelectedType() return the enum instead of a number. [AJ]
|
||||||
|
|
||||||
|
2012/02/08
|
||||||
|
----------
|
||||||
|
* [ScreenEdit] Added support for editing keysounds. Use the Area Menu (Enter)
|
||||||
|
to either modify what sounds play on that row, or even remove a sound from
|
||||||
|
the list. Any sounds assigned to empty notes will automatically become
|
||||||
|
an AutoKeysound, and any AutoKeysounds that have their sound removed will
|
||||||
|
become empty notes. [Wolfman2000]
|
||||||
|
|
||||||
2012/02/08
|
2012/02/08
|
||||||
----------
|
----------
|
||||||
* [ScreenOptionsMaster] Added StepsRowLayoutType metric.
|
* [ScreenOptionsMaster] Added StepsRowLayoutType metric.
|
||||||
|
|||||||
@@ -971,6 +971,7 @@ Min BPM=Min Specified BPM
|
|||||||
Mines=Mines
|
Mines=Mines
|
||||||
Mirror Player 1 to 2=Mirror P1's notes to P2 (routine only)
|
Mirror Player 1 to 2=Mirror P1's notes to P2 (routine only)
|
||||||
Mirror Player 2 to 1=Mirror P2's notes to P1 (routine only)
|
Mirror Player 2 to 1=Mirror P2's notes to P1 (routine only)
|
||||||
|
Modify Keysounds at current beat=Modify keysounds at current beat
|
||||||
MoveRandomToEnd=Random At End
|
MoveRandomToEnd=Random At End
|
||||||
More Options=More Options
|
More Options=More Options
|
||||||
MovieColorDepth=Movie Color
|
MovieColorDepth=Movie Color
|
||||||
@@ -1020,6 +1021,7 @@ RefreshRate=Refresh Rate
|
|||||||
Reload Songs=Reload Songs/Courses
|
Reload Songs=Reload Songs/Courses
|
||||||
Remove=Remove
|
Remove=Remove
|
||||||
Remove Change=Remove Change
|
Remove Change=Remove Change
|
||||||
|
Remove Keysound=Remove Keysound
|
||||||
Rename=Rename
|
Rename=Rename
|
||||||
Reset To Defaults=Reset Options To Default Values
|
Reset To Defaults=Reset Options To Default Values
|
||||||
Revert from disk=Revert from disk
|
Revert from disk=Revert from disk
|
||||||
@@ -1369,6 +1371,11 @@ Help=Help
|
|||||||
Info=Info
|
Info=Info
|
||||||
Routine Player=Player
|
Routine Player=Player
|
||||||
|
|
||||||
|
Track %d=Track %d
|
||||||
|
None=None
|
||||||
|
New Sound=New Sound
|
||||||
|
Enter New Keysound File=Enter the name of the new keysound file.\nPlease make sure it is spelt right.
|
||||||
|
|
||||||
[ScreenEditMenu]
|
[ScreenEditMenu]
|
||||||
HeaderText=Edit Song/Steps
|
HeaderText=Edit Song/Steps
|
||||||
HeaderSubText=Make your songs perfect
|
HeaderSubText=Make your songs perfect
|
||||||
|
|||||||
@@ -3896,6 +3896,10 @@ ColorDisabled=color("1,1,1,1")
|
|||||||
RowInitCommand=halign,0.5;valign,0.5;zoom,0.8;x,75;y,45;shadowlength,1
|
RowInitCommand=halign,0.5;valign,0.5;zoom,0.8;x,75;y,45;shadowlength,1
|
||||||
OptionRowNormalMetricsGroup="OptionRowMiniMenuEditHelp"
|
OptionRowNormalMetricsGroup="OptionRowMiniMenuEditHelp"
|
||||||
|
|
||||||
|
[ScreenMiniMenuKeysoundTrack]
|
||||||
|
Fallback="ScreenMiniMenu"
|
||||||
|
ShowFooter=false
|
||||||
|
|
||||||
[OptionRowMiniMenuEditHelp]
|
[OptionRowMiniMenuEditHelp]
|
||||||
# Help menu ( Keys & Stuff )
|
# Help menu ( Keys & Stuff )
|
||||||
Fallback="OptionRowMiniMenu"
|
Fallback="OptionRowMiniMenu"
|
||||||
|
|||||||
+6
-3
@@ -463,6 +463,7 @@ bool NoteData::IsTap(const TapNote &tn, const int row) const
|
|||||||
{
|
{
|
||||||
return (tn.type != TapNote::empty && tn.type != TapNote::mine
|
return (tn.type != TapNote::empty && tn.type != TapNote::mine
|
||||||
&& tn.type != TapNote::lift && tn.type != TapNote::fake
|
&& tn.type != TapNote::lift && tn.type != TapNote::fake
|
||||||
|
&& tn.type != TapNote::autoKeysound
|
||||||
&& GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(row));
|
&& GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,6 +557,7 @@ bool NoteData::RowNeedsAtLeastSimultaneousPresses( int iMinSimultaneousPresses,
|
|||||||
case TapNote::empty:
|
case TapNote::empty:
|
||||||
case TapNote::fake:
|
case TapNote::fake:
|
||||||
case TapNote::lift: // you don't "press" on a lift.
|
case TapNote::lift: // you don't "press" on a lift.
|
||||||
|
case TapNote::autoKeysound:
|
||||||
continue; // skip these types - they don't count
|
continue; // skip these types - they don't count
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -610,9 +612,10 @@ int NoteData::GetNumRowsWithSimultaneousTaps( int iMinTaps, int iStartIndex, int
|
|||||||
for( int t=0; t<GetNumTracks(); t++ )
|
for( int t=0; t<GetNumTracks(); t++ )
|
||||||
{
|
{
|
||||||
const TapNote &tn = GetTapNote(t, r);
|
const TapNote &tn = GetTapNote(t, r);
|
||||||
if( tn.type != TapNote::mine // mines don't count.
|
if (tn.type != TapNote::mine && // mines don't count.
|
||||||
&& tn.type != TapNote::empty
|
tn.type != TapNote::empty &&
|
||||||
&& tn.type != TapNote::fake)
|
tn.type != TapNote::fake &&
|
||||||
|
tn.type != TapNote::autoKeysound)
|
||||||
iNumNotesThisIndex++;
|
iNumNotesThisIndex++;
|
||||||
}
|
}
|
||||||
if( iNumNotesThisIndex >= iMinTaps )
|
if( iNumNotesThisIndex >= iMinTaps )
|
||||||
|
|||||||
@@ -153,7 +153,10 @@ int LastTapNoteScoreTrack( const NoteData &in, unsigned iRow, PlayerNumber pn )
|
|||||||
{
|
{
|
||||||
/* Skip empty tracks and mines */
|
/* Skip empty tracks and mines */
|
||||||
const TapNote &tn = in.GetTapNote( t, iRow );
|
const TapNote &tn = in.GetTapNote( t, iRow );
|
||||||
if( tn.type == TapNote::empty || tn.type == TapNote::mine || tn.type == TapNote::fake )
|
if (tn.type == TapNote::empty ||
|
||||||
|
tn.type == TapNote::mine ||
|
||||||
|
tn.type == TapNote::fake ||
|
||||||
|
tn.type == TapNote::autoKeysound)
|
||||||
continue;
|
continue;
|
||||||
if( tn.pn != PLAYER_INVALID && tn.pn != pn && pn != PLAYER_INVALID )
|
if( tn.pn != PLAYER_INVALID && tn.pn != pn && pn != PLAYER_INVALID )
|
||||||
continue;
|
continue;
|
||||||
@@ -187,7 +190,10 @@ int MinTapNoteScoreTrack( const NoteData &in, unsigned iRow, PlayerNumber pn )
|
|||||||
{
|
{
|
||||||
// Skip empty tracks and mines
|
// Skip empty tracks and mines
|
||||||
const TapNote &tn = in.GetTapNote( t, iRow );
|
const TapNote &tn = in.GetTapNote( t, iRow );
|
||||||
if( tn.type == TapNote::empty || tn.type == TapNote::mine || tn.type == TapNote::fake )
|
if (tn.type == TapNote::empty ||
|
||||||
|
tn.type == TapNote::mine ||
|
||||||
|
tn.type == TapNote::fake ||
|
||||||
|
tn.type == TapNote::autoKeysound)
|
||||||
continue;
|
continue;
|
||||||
if( tn.pn != PLAYER_INVALID && tn.pn != pn && pn != PLAYER_INVALID )
|
if( tn.pn != PLAYER_INVALID && tn.pn != pn && pn != PLAYER_INVALID )
|
||||||
continue;
|
continue;
|
||||||
@@ -250,7 +256,10 @@ TapNoteScore NoteDataWithScoring::MinTapNoteScore( const NoteData &in, unsigned
|
|||||||
{
|
{
|
||||||
// Ignore mines (and fake arrows), or the score will always be TNS_None.
|
// Ignore mines (and fake arrows), or the score will always be TNS_None.
|
||||||
const TapNote &tn = in.GetTapNote( t, row );
|
const TapNote &tn = in.GetTapNote( t, row );
|
||||||
if( tn.type == TapNote::empty || tn.type == TapNote::mine || tn.type == TapNote::fake )
|
if (tn.type == TapNote::empty ||
|
||||||
|
tn.type == TapNote::mine ||
|
||||||
|
tn.type == TapNote::fake ||
|
||||||
|
tn.type == TapNote::autoKeysound)
|
||||||
continue;
|
continue;
|
||||||
score = min( score, tn.result.tns );
|
score = min( score, tn.result.tns );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -684,6 +684,7 @@ void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeing
|
|||||||
|
|
||||||
void NoteDisplay::DrawActor( const TapNote& tn, Actor* pActor, NotePart part, int iCol, float fYOffset, float fBeat, bool bIsAddition, float fPercentFadeToFail, float fReverseOffsetPixels, float fColorScale, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar )
|
void NoteDisplay::DrawActor( const TapNote& tn, Actor* pActor, NotePart part, int iCol, float fYOffset, float fBeat, bool bIsAddition, float fPercentFadeToFail, float fReverseOffsetPixels, float fColorScale, float fDrawDistanceAfterTargetsPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar )
|
||||||
{
|
{
|
||||||
|
if (tn.type == TapNote::autoKeysound && !GAMESTATE->m_bInStepEditor) return;
|
||||||
if( fYOffset < fDrawDistanceAfterTargetsPixels || fYOffset > fDrawDistanceBeforeTargetsPixels )
|
if( fYOffset < fDrawDistanceAfterTargetsPixels || fYOffset > fDrawDistanceBeforeTargetsPixels )
|
||||||
return;
|
return;
|
||||||
const float fY = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYOffset, fReverseOffsetPixels );
|
const float fY = ArrowEffects::GetYPos( m_pPlayerState, iCol, fYOffset, fReverseOffsetPixels );
|
||||||
|
|||||||
+28
-7
@@ -1653,7 +1653,8 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool
|
|||||||
const TapNote &tn = begin->second;
|
const TapNote &tn = begin->second;
|
||||||
if (!m_Timing->IsJudgableAtRow( begin->first ))
|
if (!m_Timing->IsJudgableAtRow( begin->first ))
|
||||||
break;
|
break;
|
||||||
if( tn.type == TapNote::empty )
|
// unsure if autoKeysounds should be excluded. -Wolfman2000
|
||||||
|
if( tn.type == TapNote::empty || tn.type == TapNote::autoKeysound )
|
||||||
break;
|
break;
|
||||||
if( !bAllowGraded && tn.result.tns != TNS_None )
|
if( !bAllowGraded && tn.result.tns != TNS_None )
|
||||||
break;
|
break;
|
||||||
@@ -2238,9 +2239,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
|||||||
break;
|
break;
|
||||||
case TapNote::attack:
|
case TapNote::attack:
|
||||||
if( !bRelease && fSecondsFromExact <= GetWindowSeconds(TW_Attack) && !pTN->result.bHidden )
|
if( !bRelease && fSecondsFromExact <= GetWindowSeconds(TW_Attack) && !pTN->result.bHidden )
|
||||||
score = TNS_W2; // sentinel
|
score = AllowW1() ? TNS_W1 : TNS_W2; // sentinel
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TapNote::hold_head:
|
case TapNote::hold_head:
|
||||||
// oh wow, this was causing the trigger before the hold heads
|
// oh wow, this was causing the trigger before the hold heads
|
||||||
// bug. (It was fNoteOffset > 0.f before) -DaisuMaster
|
// bug. (It was fNoteOffset > 0.f before) -DaisuMaster
|
||||||
@@ -2791,7 +2791,9 @@ void Player::UpdateJudgedRows()
|
|||||||
for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
|
for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
|
||||||
{
|
{
|
||||||
const TapNote &tn = m_NoteData.GetTapNote( iTrack, iRow );
|
const TapNote &tn = m_NoteData.GetTapNote( iTrack, iRow );
|
||||||
if( tn.type == TapNote::empty || tn.type == TapNote::mine ) continue;
|
if (tn.type == TapNote::empty ||
|
||||||
|
tn.type == TapNote::mine ||
|
||||||
|
tn.type == TapNote::autoKeysound) continue;
|
||||||
SetJudgment( tn.result.tns, iTrack, tn.result.fTapNoteOffset );
|
SetJudgment( tn.result.tns, iTrack, tn.result.fTapNoteOffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2973,8 +2975,11 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
|
|||||||
// check to see if there's a note at the crossed row
|
// check to see if there's a note at the crossed row
|
||||||
if( m_pPlayerState->m_PlayerController != PC_HUMAN )
|
if( m_pPlayerState->m_PlayerController != PC_HUMAN )
|
||||||
{
|
{
|
||||||
if(tn.type != TapNote::empty && tn.type != TapNote::fake && tn.result.tns == TNS_None
|
if (tn.type != TapNote::empty &&
|
||||||
&& this->m_Timing->IsJudgableAtRow(iRow) )
|
tn.type != TapNote::fake &&
|
||||||
|
tn.type != TapNote::autoKeysound &&
|
||||||
|
tn.result.tns == TNS_None &&
|
||||||
|
this->m_Timing->IsJudgableAtRow(iRow) )
|
||||||
{
|
{
|
||||||
Step( iTrack, iRow, now, false, false );
|
Step( iTrack, iRow, now, false, false );
|
||||||
if( m_pPlayerState->m_PlayerController == PC_AUTOPLAY )
|
if( m_pPlayerState->m_PlayerController == PC_AUTOPLAY )
|
||||||
@@ -2984,6 +2989,19 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle autokeysounds here (if not in the editor).
|
||||||
|
if (!GAMESTATE->m_bInStepEditor)
|
||||||
|
{
|
||||||
|
for (int t = 0; t < m_NoteData.GetNumTracks(); ++t)
|
||||||
|
{
|
||||||
|
const TapNote &tap = m_NoteData.GetTapNote(t, iRow);
|
||||||
|
if (tap.type == TapNote::autoKeysound)
|
||||||
|
{
|
||||||
|
PlayKeysound(tap, TNS_None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3141,7 +3159,10 @@ void Player::HandleTapRowScore( unsigned row )
|
|||||||
{
|
{
|
||||||
const TapNote &tn = m_NoteData.GetTapNote( track, row );
|
const TapNote &tn = m_NoteData.GetTapNote( track, row );
|
||||||
// Mines cannot be handled here.
|
// Mines cannot be handled here.
|
||||||
if( tn.type == TapNote::empty || tn.type == TapNote::fake || tn.type == TapNote::mine )
|
if (tn.type == TapNote::empty ||
|
||||||
|
tn.type == TapNote::fake ||
|
||||||
|
tn.type == TapNote::mine ||
|
||||||
|
tn.type == TapNote::autoKeysound)
|
||||||
continue;
|
continue;
|
||||||
if( m_pPrimaryScoreKeeper )
|
if( m_pPrimaryScoreKeeper )
|
||||||
m_pPrimaryScoreKeeper->HandleTapScore( tn );
|
m_pPrimaryScoreKeeper->HandleTapScore( tn );
|
||||||
|
|||||||
+139
-1
@@ -74,6 +74,8 @@ AutoScreenMessage( SM_BackFromInsertStepAttackPlayerOptions );
|
|||||||
AutoScreenMessage( SM_BackFromInsertCourseAttack );
|
AutoScreenMessage( SM_BackFromInsertCourseAttack );
|
||||||
AutoScreenMessage( SM_BackFromInsertCourseAttackPlayerOptions );
|
AutoScreenMessage( SM_BackFromInsertCourseAttackPlayerOptions );
|
||||||
AutoScreenMessage( SM_BackFromCourseModeMenu );
|
AutoScreenMessage( SM_BackFromCourseModeMenu );
|
||||||
|
AutoScreenMessage( SM_BackFromKeysoundTrack );
|
||||||
|
AutoScreenMessage( SM_BackFromNewKeysound );
|
||||||
AutoScreenMessage( SM_DoRevertToLastSave );
|
AutoScreenMessage( SM_DoRevertToLastSave );
|
||||||
AutoScreenMessage( SM_DoRevertFromDisk );
|
AutoScreenMessage( SM_DoRevertFromDisk );
|
||||||
AutoScreenMessage( SM_BackFromTimingDataInformation );
|
AutoScreenMessage( SM_BackFromTimingDataInformation );
|
||||||
@@ -520,6 +522,10 @@ static MenuDef g_EditHelp(
|
|||||||
// fill this in dynamically
|
// fill this in dynamically
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static MenuDef g_KeysoundTrack(
|
||||||
|
"ScreenMiniMenuKeysoundTrack"
|
||||||
|
); // fill this in dynamically
|
||||||
|
|
||||||
static MenuDef g_MainMenu(
|
static MenuDef g_MainMenu(
|
||||||
"ScreenMiniMenuMainMenu",
|
"ScreenMiniMenuMainMenu",
|
||||||
MenuRowDef( ScreenEdit::play_whole_song, "Play whole song", true, EditMode_Practice, true, true, 0, NULL ),
|
MenuRowDef( ScreenEdit::play_whole_song, "Play whole song", true, EditMode_Practice, true, true, 0, NULL ),
|
||||||
@@ -605,7 +611,9 @@ static MenuDef g_AreaMenu(
|
|||||||
MenuRowDef(ScreenEdit::last_second_at_beat, "Designate last second at current beat", true, EditMode_Full, true, true, 0, NULL ),
|
MenuRowDef(ScreenEdit::last_second_at_beat, "Designate last second at current beat", true, EditMode_Full, true, true, 0, NULL ),
|
||||||
MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ),
|
MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ),
|
||||||
MenuRowDef(ScreenEdit::clear_clipboard, "Clear clipboard", true,
|
MenuRowDef(ScreenEdit::clear_clipboard, "Clear clipboard", true,
|
||||||
EditMode_Practice, true, true, 0, NULL )
|
EditMode_Practice, true, true, 0, NULL ),
|
||||||
|
MenuRowDef(ScreenEdit::modify_keysounds_at_row, "Modify Keysounds at current beat",
|
||||||
|
true, EditMode_Full, true, true, 0, NULL)
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2927,6 +2935,8 @@ void ScreenEdit::ScrollTo( float fDestinationBeat )
|
|||||||
m_soundChangeLine.Play();
|
m_soundChangeLine.Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LocalizedString NEW_KEYSOUND_FILE("ScreenEdit", "Enter New Keysound File");
|
||||||
|
|
||||||
void ScreenEdit::HandleMessage( const Message &msg )
|
void ScreenEdit::HandleMessage( const Message &msg )
|
||||||
{
|
{
|
||||||
if( msg == "Judgment" )
|
if( msg == "Judgment" )
|
||||||
@@ -3172,6 +3182,94 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
ASSERT( GAMESTATE->m_pCurCourse );
|
ASSERT( GAMESTATE->m_pCurCourse );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (SM == SM_BackFromKeysoundTrack)
|
||||||
|
{
|
||||||
|
const int track = ScreenMiniMenu::s_iLastRowCode;
|
||||||
|
const int tracks = m_NoteDataEdit.GetNumTracks();
|
||||||
|
const int row = this->GetRow();
|
||||||
|
unsigned int sound = ScreenMiniMenu::s_viLastAnswers[track];
|
||||||
|
vector<RString> &kses = m_pSong->m_vsKeysoundFile;
|
||||||
|
|
||||||
|
if (track < tracks)
|
||||||
|
{
|
||||||
|
if (sound == kses.size())
|
||||||
|
{
|
||||||
|
// create a new sound (filename), point it.
|
||||||
|
// if it's empty, make it an auto keysound.
|
||||||
|
ScreenTextEntry::TextEntry(SM_BackFromNewKeysound, NEW_KEYSOUND_FILE, "", 64);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const TapNote &oldNote = m_NoteDataEdit.GetTapNote(track, row);
|
||||||
|
TapNote newNote = oldNote; // need to lose the const. not feeling like casting.
|
||||||
|
if (sound < kses.size())
|
||||||
|
{
|
||||||
|
// set note at this row to use this keysound file.
|
||||||
|
// if it's empty, make it an auto keysound.
|
||||||
|
newNote.iKeysoundIndex = sound;
|
||||||
|
if (newNote.type == TapNote::empty)
|
||||||
|
{
|
||||||
|
newNote.type = TapNote::autoKeysound; // keysounds need something non empty.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // sound > kses.size()
|
||||||
|
{
|
||||||
|
// remove the sound. if it's an auto keysound, make it empty.
|
||||||
|
newNote.iKeysoundIndex = -1;
|
||||||
|
if (newNote.type == TapNote::autoKeysound)
|
||||||
|
{
|
||||||
|
newNote.type = TapNote::empty; // autoKeysound with no sound is pointless.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_NoteDataEdit.SetTapNote(track, row, newNote);
|
||||||
|
}
|
||||||
|
else if (track == tracks)
|
||||||
|
{
|
||||||
|
kses.erase(kses.begin() + sound);
|
||||||
|
// TODO: Make the following a part of NoteData?
|
||||||
|
for (int t = 0; t < tracks; ++t)
|
||||||
|
{
|
||||||
|
FOREACH_NONEMPTY_ROW_IN_TRACK(m_NoteDataEdit, t, r)
|
||||||
|
{
|
||||||
|
const TapNote &oldNote = m_NoteDataEdit.GetTapNote(t, r);
|
||||||
|
TapNote newNote = oldNote; // need to lose the const. not feeling like casting.
|
||||||
|
if (newNote.iKeysoundIndex == static_cast<int>(sound))
|
||||||
|
{
|
||||||
|
newNote.iKeysoundIndex = -1;
|
||||||
|
if (newNote.type == TapNote::autoKeysound)
|
||||||
|
newNote.type = TapNote::empty;
|
||||||
|
}
|
||||||
|
else if (newNote.iKeysoundIndex > static_cast<int>(sound))
|
||||||
|
newNote.iKeysoundIndex--;
|
||||||
|
|
||||||
|
m_NoteDataEdit.SetTapNote(t, r, newNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetDirty(true);
|
||||||
|
}
|
||||||
|
else if (SM == SM_BackFromNewKeysound && !ScreenTextEntry::s_bCancelledLast)
|
||||||
|
{
|
||||||
|
RString answer = ScreenTextEntry::s_sLastAnswer;
|
||||||
|
const int track = ScreenMiniMenu::s_iLastRowCode; // still keeps the same value.
|
||||||
|
const int row = this->GetRow();
|
||||||
|
const TapNote &oldNote = m_NoteDataEdit.GetTapNote(track, row);
|
||||||
|
TapNote newNote = oldNote; // need to lose the const. not feeling like casting.
|
||||||
|
vector<RString> &kses = m_pSong->m_vsKeysoundFile;
|
||||||
|
unsigned pos = find(kses.begin(), kses.end(), answer) - kses.begin();
|
||||||
|
if (pos == kses.size())
|
||||||
|
{
|
||||||
|
newNote.iKeysoundIndex = kses.size();
|
||||||
|
kses.push_back(answer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newNote.iKeysoundIndex = pos;
|
||||||
|
}
|
||||||
|
if (newNote.type == TapNote::empty)
|
||||||
|
newNote.type = TapNote::autoKeysound; // keysounds need something non empty.
|
||||||
|
m_NoteDataEdit.SetTapNote(track, row, newNote);
|
||||||
|
SetDirty(true);
|
||||||
|
}
|
||||||
else if( SM == SM_BackFromOptions )
|
else if( SM == SM_BackFromOptions )
|
||||||
{
|
{
|
||||||
// The options may have changed the note skin.
|
// The options may have changed the note skin.
|
||||||
@@ -4463,6 +4561,11 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
|||||||
m_Clipboard.ClearAll();
|
m_Clipboard.ClearAll();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case modify_keysounds_at_row:
|
||||||
|
{
|
||||||
|
this->DoKeyboardTrackMenu();
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if( bSaveUndo )
|
if( bSaveUndo )
|
||||||
@@ -5215,6 +5318,41 @@ static RString GetDeviceButtonsLocalized( const vector<EditButton> &veb, const M
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LocalizedString TRACK_NUM("ScreenEdit", "Track %d");
|
||||||
|
static LocalizedString NO_KEYSND("ScreenEdit", "None");
|
||||||
|
static LocalizedString NEWKEYSND("ScreenEdit", "New Sound");
|
||||||
|
|
||||||
|
void ScreenEdit::DoKeyboardTrackMenu()
|
||||||
|
{
|
||||||
|
g_KeysoundTrack.rows.clear();
|
||||||
|
vector<RString> &kses = m_pSong->m_vsKeysoundFile;
|
||||||
|
|
||||||
|
vector<RString> choices;
|
||||||
|
FOREACH(RString, kses, ks)
|
||||||
|
{
|
||||||
|
choices.push_back(*ks);
|
||||||
|
}
|
||||||
|
choices.push_back(NEWKEYSND);
|
||||||
|
choices.push_back(NO_KEYSND);
|
||||||
|
int numKeysounds = kses.size();
|
||||||
|
for (int i = 0; i < m_NoteDataEdit.GetNumTracks(); ++i)
|
||||||
|
{
|
||||||
|
const TapNote &tn = m_NoteDataEdit.GetTapNote(i, this->GetRow());
|
||||||
|
int keyIndex = tn.iKeysoundIndex;
|
||||||
|
if (keyIndex == -1)
|
||||||
|
{
|
||||||
|
keyIndex = numKeysounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_KeysoundTrack.rows.push_back(MenuRowDef(i, ssprintf(TRACK_NUM.GetValue(), i + 1),
|
||||||
|
true, EditMode_Full, false, false, keyIndex, choices));
|
||||||
|
}
|
||||||
|
g_KeysoundTrack.rows.push_back(MenuRowDef(m_NoteDataEdit.GetNumTracks(), "Remove Keysound",
|
||||||
|
true, EditMode_Full, false, false, 0, kses));
|
||||||
|
|
||||||
|
EditMiniMenu(&g_KeysoundTrack, SM_BackFromKeysoundTrack);
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenEdit::DoHelp()
|
void ScreenEdit::DoHelp()
|
||||||
{
|
{
|
||||||
g_EditHelp.rows.clear();
|
g_EditHelp.rows.clear();
|
||||||
|
|||||||
@@ -248,6 +248,9 @@ protected:
|
|||||||
float GetMaximumBeatForNewNote() const; // don't allow Down key to go past this beat.
|
float GetMaximumBeatForNewNote() const; // don't allow Down key to go past this beat.
|
||||||
float GetMaximumBeatForMoving() const; // don't allow Down key to go past this beat.
|
float GetMaximumBeatForMoving() const; // don't allow Down key to go past this beat.
|
||||||
|
|
||||||
|
/** @brief Display the keyboard track menu for the current row. */
|
||||||
|
void DoKeyboardTrackMenu();
|
||||||
|
|
||||||
void DoHelp();
|
void DoHelp();
|
||||||
|
|
||||||
/** @brief Display the TimingData menu for editing song and step timing. */
|
/** @brief Display the TimingData menu for editing song and step timing. */
|
||||||
@@ -435,6 +438,7 @@ public:
|
|||||||
last_second_at_beat,
|
last_second_at_beat,
|
||||||
undo,
|
undo,
|
||||||
clear_clipboard, /**< Clear the clipboards. */
|
clear_clipboard, /**< Clear the clipboards. */
|
||||||
|
modify_keysounds_at_row, /**< Modify the keysounds at this row. */
|
||||||
NUM_AREA_MENU_CHOICES
|
NUM_AREA_MENU_CHOICES
|
||||||
};
|
};
|
||||||
void HandleAlterMenuChoice(AlterMenuChoice c,
|
void HandleAlterMenuChoice(AlterMenuChoice c,
|
||||||
|
|||||||
@@ -50,6 +50,19 @@ struct MenuRowDef
|
|||||||
PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25);
|
PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25);
|
||||||
#undef PUSH
|
#undef PUSH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuRowDef(int r, RString n, bool e, EditMode s,
|
||||||
|
bool bTT, bool bTI, int d, vector<RString> options):
|
||||||
|
iRowCode(r), sName(n), bEnabled(e), pfnEnabled(NULL),
|
||||||
|
emShowIn(s), iDefaultChoice(d), choices(),
|
||||||
|
bThemeTitle(bTT), bThemeItems(bTI)
|
||||||
|
{
|
||||||
|
FOREACH(RString, options, str)
|
||||||
|
{
|
||||||
|
if (*str != "") choices.push_back(*str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI,
|
MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI,
|
||||||
int d, const char *c0=NULL, const char *c1=NULL,
|
int d, const char *c0=NULL, const char *c1=NULL,
|
||||||
const char *c2=NULL, const char *c3=NULL,
|
const char *c2=NULL, const char *c3=NULL,
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld )
|
|||||||
FOREACH_CONST( RString, arrayGroupDirs, s ) // foreach dir in /Songs/
|
FOREACH_CONST( RString, arrayGroupDirs, s ) // foreach dir in /Songs/
|
||||||
{
|
{
|
||||||
RString sGroupDirName = *s;
|
RString sGroupDirName = *s;
|
||||||
|
// TODO: If this check fails, log a warning instead of crashing.
|
||||||
SanityCheckGroupDir(sDir+sGroupDirName);
|
SanityCheckGroupDir(sDir+sGroupDirName);
|
||||||
|
|
||||||
// Find all Song folders in this group directory
|
// Find all Song folders in this group directory
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ void TimingData::Clear()
|
|||||||
vector<TimingSegment*> &vSegs = m_avpTimingSegments[tst];
|
vector<TimingSegment*> &vSegs = m_avpTimingSegments[tst];
|
||||||
for( unsigned i = 0; i < vSegs.size(); ++i )
|
for( unsigned i = 0; i < vSegs.size(); ++i )
|
||||||
{
|
{
|
||||||
#if defined(DEBUG)
|
|
||||||
LOG->Trace( "TimingData::Clear(): deleting %p", vSegs[i] );
|
|
||||||
#endif
|
|
||||||
SAFE_DELETE( vSegs[i] );
|
SAFE_DELETE( vSegs[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user