Implement preview music properly as a new optional tag in the ssc file. Changed ScreenManager to emit an error instead of asserting if a screen attempts to use SetNewScreen inside an InitCommand. Changed decorations layer to be a proper child instead of stripping away the ActorFrame.

This commit is contained in:
Kyzentun
2015-03-04 01:31:02 -07:00
parent 519ad8d243
commit 0318f07d2d
16 changed files with 88 additions and 30 deletions
+5 -3
View File
@@ -6,9 +6,11 @@ ________________________________________________________________________________
2015/03/01 2015/03/01
---------- ----------
* [SelectMusic] Select Music now plays preview.ogg for a simfile if it exists * [SelectMusic] Select Music now plays music file named by #PREVIEW tag if
instead of using the song file for the sample music. The sample length it's not blank, instead of using the song file for the sample music. The
from the simfile is used and the sample start is treated as 0. [kyzentun] sample length from the simfile is used and the sample start is treated as
0. [kyzentun]
* [Song] GetPreviewMusicPath added. [kyzentun]
* [foreach] foreach_ordered lua function now works on tables that have both * [foreach] foreach_ordered lua function now works on tables that have both
number and string keys. Number keys are iterated over first. [kyzentun] number and string keys. Number keys are iterated over first. [kyzentun]
+1
View File
@@ -1542,6 +1542,7 @@
<Function name='GetMusicPath'/> <Function name='GetMusicPath'/>
<Function name='GetOneSteps'/> <Function name='GetOneSteps'/>
<Function name='GetOrigin'/> <Function name='GetOrigin'/>
<Function name='GetPreviewMusicPath'/>
<Function name='GetPreviewVidPath'/> <Function name='GetPreviewVidPath'/>
<Function name='GetSampleLength'/> <Function name='GetSampleLength'/>
<Function name='GetSampleStart'/> <Function name='GetSampleStart'/>
+3
View File
@@ -4464,6 +4464,9 @@ save yourself some time, copy this for undocumented things:
<Function name='GetOrigin' return='string' arguments=''> <Function name='GetOrigin' return='string' arguments=''>
Gets the Song's origin. Gets the Song's origin.
</Function> </Function>
<Function name='GetPreviewMusicPath' return='string' arguments=''>
Returns the path to the Song's preview music. This handles the #PREVIEW tag internally, so it works with songs that use it and songs that don't.
</Function>
<Function name='GetPreviewVidPath' return='string' arguments=''> <Function name='GetPreviewVidPath' return='string' arguments=''>
Returns the path to the Song's preview video, if it exists. (Returns <code>nil</code> otherwise.) Returns the path to the Song's preview video, if it exists. (Returns <code>nil</code> otherwise.)
</Function> </Function>
+3
View File
@@ -1142,6 +1142,7 @@ Predicted Meter=Predicted Meter
Preferences=Preferences Preferences=Preferences
PreloadSounds=Preload Sounds PreloadSounds=Preload Sounds
Premium=Premium Premium=Premium
Preview=Preview
Preview Length=Preview Length Preview Length=Preview Length
Preview Start=Preview Start Preview Start=Preview Start
Export Packages=Export Packages Export Packages=Export Packages
@@ -1497,6 +1498,7 @@ Enter a new artist transliteration.=Enter a new artist transliteration.
Enter a new artist.=Enter a new artist. Enter a new artist.=Enter a new artist.
Enter a new genre.=Enter a new genre. Enter a new genre.=Enter a new genre.
Enter a new credit.=Enter a new credit. Enter a new credit.=Enter a new credit.
Enter a preview file.=Enter a preview file.
Enter a new description.=Enter a new description. Enter a new description.=Enter a new description.
Enter a new chart name.=Enter the name/title of this chart. Enter a new chart name.=Enter the name/title of this chart.
Enter a new chart style.=Enter a new chart style (e.g. "Pad", "Keyboard"). Enter a new chart style.=Enter a new chart style (e.g. "Pad", "Keyboard").
@@ -1997,6 +1999,7 @@ The name you chose conflicts with another edit. Please use a different name.=The
The chart name cannot contain any of the following characters: %s=The chart name cannot contain any of the following characters: %s The chart name cannot contain any of the following characters: %s=The chart name cannot contain any of the following characters: %s
The edit name cannot contain any of the following characters: %s=The edit name can not contain any of the following characters: %s The edit name cannot contain any of the following characters: %s=The edit name can not contain any of the following characters: %s
The step author's name cannot contain any of the following characters: %s=The step author's name cannot contain any of the following characters: %s The step author's name cannot contain any of the following characters: %s=The step author's name cannot contain any of the following characters: %s
The preview file '%s' does not exist.=The preview file '%s' does not exist.
[SongSort] [SongSort]
FewestPlays=Fewest Plays FewestPlays=Fewest Plays
+5
View File
@@ -426,6 +426,11 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
out.m_sMusicFile = sParams[1]; out.m_sMusicFile = sParams[1];
} }
else if(sValueName == "PREVIEW")
{
out.m_PreviewFile= sParams[1];
}
else if( sValueName=="INSTRUMENTTRACK" ) else if( sValueName=="INSTRUMENTTRACK" )
{ {
SMLoader::ProcessInstrumentTracks( out, sParams[1] ); SMLoader::ProcessInstrumentTracks( out, sParams[1] );
+4
View File
@@ -230,6 +230,10 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.PutLine( ssprintf( "#LYRICSPATH:%s;", SmEscape(out.m_sLyricsFile).c_str() ) ); f.PutLine( ssprintf( "#LYRICSPATH:%s;", SmEscape(out.m_sLyricsFile).c_str() ) );
f.PutLine( ssprintf( "#CDTITLE:%s;", SmEscape(out.m_sCDTitleFile).c_str() ) ); f.PutLine( ssprintf( "#CDTITLE:%s;", SmEscape(out.m_sCDTitleFile).c_str() ) );
f.PutLine( ssprintf( "#MUSIC:%s;", SmEscape(out.m_sMusicFile).c_str() ) ); f.PutLine( ssprintf( "#MUSIC:%s;", SmEscape(out.m_sMusicFile).c_str() ) );
if(!out.m_PreviewFile.empty())
{
f.PutLine(ssprintf("#PREVIEW:%s;", SmEscape(out.m_PreviewFile).c_str()));
}
{ {
vector<RString> vs = out.GetInstrumentTracksToVectorString(); vector<RString> vs = out.GetInstrumentTracksToVectorString();
+16 -2
View File
@@ -952,6 +952,9 @@ static MenuDef g_SongInformation(
MenuRowDef(ScreenEdit::credit, MenuRowDef(ScreenEdit::credit,
"Credit", "Credit",
true, EditMode_Practice, true, true, 0, NULL ), true, EditMode_Practice, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::preview,
"Preview",
true, EditMode_Full, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::main_title_transliteration, MenuRowDef(ScreenEdit::main_title_transliteration,
"Main title transliteration", "Main title transliteration",
true, EditMode_Practice, true, true, 0, NULL ), true, EditMode_Practice, true, true, 0, NULL ),
@@ -1477,10 +1480,10 @@ void ScreenEdit::PlayPreviewMusic()
{ {
SOUND->StopMusic(); SOUND->StopMusic();
SOUND->PlayMusic( SOUND->PlayMusic(
m_pSong->GetMusicPath(), m_pSong->GetPreviewMusicPath(),
NULL, NULL,
false, false,
m_pSong->m_fMusicSampleStartSeconds, m_pSong->GetPreviewStartSeconds(),
m_pSong->m_fMusicSampleLengthSeconds, m_pSong->m_fMusicSampleLengthSeconds,
FADE_IN_PREVIEW, FADE_IN_PREVIEW,
FADE_OUT_PREVIEW ); FADE_OUT_PREVIEW );
@@ -4318,6 +4321,12 @@ static void ChangeCredit( const RString &sNew )
pSong->m_sCredit = sNew; pSong->m_sCredit = sNew;
} }
static void ChangePreview(const RString& sNew)
{
Song* pSong = GAMESTATE->m_pCurSong;
pSong->m_PreviewFile= sNew;
}
static void ChangeMainTitleTranslit( const RString &sNew ) static void ChangeMainTitleTranslit( const RString &sNew )
{ {
Song* pSong = GAMESTATE->m_pCurSong; Song* pSong = GAMESTATE->m_pCurSong;
@@ -4707,6 +4716,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
g_SongInformation.rows[artist].SetOneUnthemedChoice( pSong->m_sArtist ); g_SongInformation.rows[artist].SetOneUnthemedChoice( pSong->m_sArtist );
g_SongInformation.rows[genre].SetOneUnthemedChoice( pSong->m_sGenre ); g_SongInformation.rows[genre].SetOneUnthemedChoice( pSong->m_sGenre );
g_SongInformation.rows[credit].SetOneUnthemedChoice( pSong->m_sCredit ); g_SongInformation.rows[credit].SetOneUnthemedChoice( pSong->m_sCredit );
g_SongInformation.rows[preview].SetOneUnthemedChoice(pSong->m_PreviewFile);
g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit ); g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit );
g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit ); g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit );
g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit ); g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit );
@@ -5419,6 +5429,7 @@ static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title.")
static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist."); static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist.");
static LocalizedString ENTER_GENRE ("ScreenEdit","Enter a new genre."); static LocalizedString ENTER_GENRE ("ScreenEdit","Enter a new genre.");
static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit."); static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit.");
static LocalizedString ENTER_PREVIEW ("ScreenEdit", "Enter a preview file.");
static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ("ScreenEdit","Enter a new main title transliteration."); static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ("ScreenEdit","Enter a new main title transliteration.");
static LocalizedString ENTER_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration."); static LocalizedString ENTER_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration.");
static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration."); static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration.");
@@ -5447,6 +5458,9 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec
case credit: case credit:
ScreenTextEntry::TextEntry( SM_None, ENTER_CREDIT, pSong->m_sCredit, 100, NULL, ChangeCredit, NULL ); ScreenTextEntry::TextEntry( SM_None, ENTER_CREDIT, pSong->m_sCredit, 100, NULL, ChangeCredit, NULL );
break; break;
case preview:
ScreenTextEntry::TextEntry(SM_None, ENTER_PREVIEW, pSong->m_PreviewFile, 100, SongUtil::ValidateCurrentSongPreview, ChangePreview, NULL);
break;
case main_title_transliteration: case main_title_transliteration:
ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE_TRANSLIT, pSong->m_sMainTitleTranslit, 100, NULL, ChangeMainTitleTranslit, NULL ); ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE_TRANSLIT, pSong->m_sMainTitleTranslit, 100, NULL, ChangeMainTitleTranslit, NULL );
break; break;
+1
View File
@@ -568,6 +568,7 @@ public:
artist, artist,
genre, genre,
credit, credit,
preview,
main_title_transliteration, main_title_transliteration,
sub_title_transliteration, sub_title_transliteration,
artist_transliteration, artist_transliteration,
+6 -1
View File
@@ -742,7 +742,12 @@ void ScreenManager::LoadDelayedScreen()
// Screens may not call SetNewScreen from the ctor or Init(). (We don't do this // Screens may not call SetNewScreen from the ctor or Init(). (We don't do this
// check inside PrepareScreen; that may be called from a thread for concurrent // check inside PrepareScreen; that may be called from a thread for concurrent
// loading, and the main thread may call SetNewScreen during that time.) // loading, and the main thread may call SetNewScreen during that time.)
ASSERT_M( m_sDelayedScreen.empty(), m_sDelayedScreen ); // Emit an error instead of asserting. -Kyz
if(!m_sDelayedScreen.empty())
{
LuaHelpers::ReportScriptError("Setting a new screen during an InitCommand is not allowed.");
m_sDelayedScreen= "";
}
bLoaded = ActivatePreparedScreenAndBackground( sScreenName ); bLoaded = ActivatePreparedScreenAndBackground( sScreenName );
ASSERT( bLoaded ); ASSERT( bLoaded );
+2 -2
View File
@@ -548,10 +548,10 @@ void ScreenNetSelectMusic::MusicChanged()
{ {
SOUND->StopMusic(); SOUND->StopMusic();
SOUND->PlayMusic( SOUND->PlayMusic(
GAMESTATE->m_pCurSong->GetMusicPath(), GAMESTATE->m_pCurSong->GetPreviewMusicPath(),
NULL, NULL,
true, true,
GAMESTATE->m_pCurSong->m_fMusicSampleStartSeconds, GAMESTATE->m_pCurSong->GetPreviewStartSeconds(),
GAMESTATE->m_pCurSong->m_fMusicSampleLengthSeconds ); GAMESTATE->m_pCurSong->m_fMusicSampleLengthSeconds );
} }
} }
+6 -11
View File
@@ -79,17 +79,14 @@ void ScreenWithMenuElements::Init()
// decorations // decorations
{ {
AutoActor decorations; m_Decorations.LoadB( m_sName, "decorations" );
decorations.LoadB( m_sName, "decorations" ); m_Decorations->SetName("Decorations");
decorations->SetName("Decorations"); m_Decorations->SetDrawOrder( DRAW_ORDER_DECORATIONS );
decorations->SetDrawOrder( DRAW_ORDER_DECORATIONS ); ActorFrame *pFrame = dynamic_cast<ActorFrame*>(static_cast<Actor*>(m_Decorations));
ActorFrame *pFrame = dynamic_cast<ActorFrame*>(static_cast<Actor*>(decorations));
if( pFrame ) if( pFrame )
{ {
m_vDecorations = pFrame->GetChildren(); this->AddChild(m_Decorations);
FOREACH( Actor*, m_vDecorations, child ) LOAD_ALL_COMMANDS(m_Decorations);
this->AddChild( *child );
pFrame->RemoveAllChildren();
} }
} }
@@ -167,8 +164,6 @@ ScreenWithMenuElements::~ScreenWithMenuElements()
if( m_MemoryCardDisplay[p] != NULL ) if( m_MemoryCardDisplay[p] != NULL )
SAFE_DELETE( m_MemoryCardDisplay[p] ); SAFE_DELETE( m_MemoryCardDisplay[p] );
} }
FOREACH( Actor*, m_vDecorations, actor )
delete *actor;
} }
void ScreenWithMenuElements::SetHelpText( RString s ) void ScreenWithMenuElements::SetHelpText( RString s )
+1 -1
View File
@@ -45,7 +45,7 @@ protected:
MemoryCardDisplay *m_MemoryCardDisplay[NUM_PLAYERS]; MemoryCardDisplay *m_MemoryCardDisplay[NUM_PLAYERS];
MenuTimer *m_MenuTimer; MenuTimer *m_MenuTimer;
AutoActor m_sprOverlay; AutoActor m_sprOverlay;
vector<Actor*> m_vDecorations; AutoActor m_Decorations;
Transition m_In; Transition m_In;
Transition m_Out; Transition m_Out;
+15 -10
View File
@@ -43,7 +43,7 @@
* @brief The internal version of the cache for StepMania. * @brief The internal version of the cache for StepMania.
* *
* Increment this value to invalidate the current cache. */ * Increment this value to invalidate the current cache. */
const int FILE_CACHE_VERSION = 222; const int FILE_CACHE_VERSION = 223;
/** @brief How long does a song sample last by default? */ /** @brief How long does a song sample last by default? */
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
@@ -1479,22 +1479,20 @@ RString Song::GetPreviewVidPath() const
RString Song::GetPreviewMusicPath() const RString Song::GetPreviewMusicPath() const
{ {
RString preview= GetSongDir() + "preview.ogg"; if(m_PreviewFile.empty())
if(FILEMAN->DoesFileExist(preview))
{ {
return preview; return GetMusicPath();
} }
return GetMusicPath(); return GetSongAssetPath(m_PreviewFile, m_sSongDir);
} }
float Song::GetPreviewStartSeconds() const float Song::GetPreviewStartSeconds() const
{ {
RString preview= GetSongDir() + "preview.ogg"; if(m_PreviewFile.empty())
if(FILEMAN->DoesFileExist(preview))
{ {
return 0.0f; return m_fMusicSampleStartSeconds;
} }
return m_fMusicSampleStartSeconds; return 0.0f;
} }
RString Song::GetDisplayMainTitle() const RString Song::GetDisplayMainTitle() const
@@ -1814,6 +1812,12 @@ public:
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
static int GetPreviewMusicPath(T* p, lua_State* L)
{
RString s= p->GetPreviewMusicPath();
lua_pushstring(L, s);
return 1;
}
static int GetJacketPath( T* p, lua_State *L ) static int GetJacketPath( T* p, lua_State *L )
{ {
RString s = p->GetJacketPath(); RString s = p->GetJacketPath();
@@ -1886,7 +1890,7 @@ public:
} }
static int GetSampleStart( T* p, lua_State *L ) static int GetSampleStart( T* p, lua_State *L )
{ {
lua_pushnumber(L, p->m_fMusicSampleStartSeconds); lua_pushnumber(L, p->GetPreviewStartSeconds());
return 1; return 1;
} }
static int GetSampleLength( T* p, lua_State *L ) static int GetSampleLength( T* p, lua_State *L )
@@ -2128,6 +2132,7 @@ public:
ADD_METHOD( ShowInDemonstrationAndRanking ); ADD_METHOD( ShowInDemonstrationAndRanking );
ADD_METHOD( HasPreviewVid ); ADD_METHOD( HasPreviewVid );
ADD_METHOD( GetPreviewVidPath ); ADD_METHOD( GetPreviewVidPath );
ADD_METHOD(GetPreviewMusicPath);
} }
}; };
+1
View File
@@ -224,6 +224,7 @@ public:
RString m_sOrigin; // song origin (for .ssc format) RString m_sOrigin; // song origin (for .ssc format)
RString m_sMusicFile; RString m_sMusicFile;
RString m_PreviewFile;
RString m_sInstrumentTrackFile[NUM_InstrumentTrack]; RString m_sInstrumentTrackFile[NUM_InstrumentTrack];
/** @brief The length of the music file. */ /** @brief The length of the music file. */
+18
View File
@@ -899,6 +899,24 @@ bool SongUtil::ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErr
return true; return true;
} }
static LocalizedString PREVIEW_DOES_NOT_EXIST("SongUtil", "The preview file '%s' does not exist.");
bool SongUtil::ValidateCurrentSongPreview(const RString& answer, RString& error)
{
if(answer.empty())
{ return true; }
Song* song= GAMESTATE->m_pCurSong;
RString real_file= song->m_PreviewFile;
song->m_PreviewFile= answer;
RString path= song->GetPreviewMusicPath();
bool valid= DoesFileExist(path);
song->m_PreviewFile= real_file;
if(!valid)
{
error= ssprintf(PREVIEW_DOES_NOT_EXIST.GetValue(), answer.c_str());
}
return valid;
}
void SongUtil::GetAllSongGenres( vector<RString> &vsOut ) void SongUtil::GetAllSongGenres( vector<RString> &vsOut )
{ {
set<RString> genres; set<RString> genres;
+1
View File
@@ -165,6 +165,7 @@ namespace SongUtil
bool ValidateCurrentStepsDescription( const RString &sAnswer, RString &sErrorOut ); bool ValidateCurrentStepsDescription( const RString &sAnswer, RString &sErrorOut );
bool ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErrorOut ); bool ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErrorOut );
bool ValidateCurrentStepsChartName(const RString &answer, RString &error); bool ValidateCurrentStepsChartName(const RString &answer, RString &error);
bool ValidateCurrentSongPreview(const RString& answer, RString& error);
void GetAllSongGenres( vector<RString> &vsOut ); void GetAllSongGenres( vector<RString> &vsOut );
/** /**