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
----------
* [SelectMusic] Select Music now plays preview.ogg for a simfile if it exists
instead of using the song file for the sample music. The sample length
from the simfile is used and the sample start is treated as 0. [kyzentun]
* [SelectMusic] Select Music now plays music file named by #PREVIEW tag if
it's not blank, instead of using the song file for the sample music. The
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
number and string keys. Number keys are iterated over first. [kyzentun]
+1
View File
@@ -1542,6 +1542,7 @@
<Function name='GetMusicPath'/>
<Function name='GetOneSteps'/>
<Function name='GetOrigin'/>
<Function name='GetPreviewMusicPath'/>
<Function name='GetPreviewVidPath'/>
<Function name='GetSampleLength'/>
<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=''>
Gets the Song's origin.
</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=''>
Returns the path to the Song's preview video, if it exists. (Returns <code>nil</code> otherwise.)
</Function>
+3
View File
@@ -1142,6 +1142,7 @@ Predicted Meter=Predicted Meter
Preferences=Preferences
PreloadSounds=Preload Sounds
Premium=Premium
Preview=Preview
Preview Length=Preview Length
Preview Start=Preview Start
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 genre.=Enter a new genre.
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 chart name.=Enter the name/title of this chart.
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 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 preview file '%s' does not exist.=The preview file '%s' does not exist.
[SongSort]
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];
}
else if(sValueName == "PREVIEW")
{
out.m_PreviewFile= sParams[1];
}
else if( sValueName=="INSTRUMENTTRACK" )
{
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( "#CDTITLE:%s;", SmEscape(out.m_sCDTitleFile).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();
+16 -2
View File
@@ -952,6 +952,9 @@ static MenuDef g_SongInformation(
MenuRowDef(ScreenEdit::credit,
"Credit",
true, EditMode_Practice, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::preview,
"Preview",
true, EditMode_Full, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::main_title_transliteration,
"Main title transliteration",
true, EditMode_Practice, true, true, 0, NULL ),
@@ -1477,10 +1480,10 @@ void ScreenEdit::PlayPreviewMusic()
{
SOUND->StopMusic();
SOUND->PlayMusic(
m_pSong->GetMusicPath(),
m_pSong->GetPreviewMusicPath(),
NULL,
false,
m_pSong->m_fMusicSampleStartSeconds,
m_pSong->GetPreviewStartSeconds(),
m_pSong->m_fMusicSampleLengthSeconds,
FADE_IN_PREVIEW,
FADE_OUT_PREVIEW );
@@ -4318,6 +4321,12 @@ static void ChangeCredit( const RString &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 )
{
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[genre].SetOneUnthemedChoice( pSong->m_sGenre );
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[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit );
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_GENRE ("ScreenEdit","Enter a new genre.");
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_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title 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:
ScreenTextEntry::TextEntry( SM_None, ENTER_CREDIT, pSong->m_sCredit, 100, NULL, ChangeCredit, NULL );
break;
case preview:
ScreenTextEntry::TextEntry(SM_None, ENTER_PREVIEW, pSong->m_PreviewFile, 100, SongUtil::ValidateCurrentSongPreview, ChangePreview, NULL);
break;
case main_title_transliteration:
ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE_TRANSLIT, pSong->m_sMainTitleTranslit, 100, NULL, ChangeMainTitleTranslit, NULL );
break;
+1
View File
@@ -568,6 +568,7 @@ public:
artist,
genre,
credit,
preview,
main_title_transliteration,
sub_title_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
// check inside PrepareScreen; that may be called from a thread for concurrent
// 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 );
ASSERT( bLoaded );
+2 -2
View File
@@ -548,10 +548,10 @@ void ScreenNetSelectMusic::MusicChanged()
{
SOUND->StopMusic();
SOUND->PlayMusic(
GAMESTATE->m_pCurSong->GetMusicPath(),
GAMESTATE->m_pCurSong->GetPreviewMusicPath(),
NULL,
true,
GAMESTATE->m_pCurSong->m_fMusicSampleStartSeconds,
GAMESTATE->m_pCurSong->GetPreviewStartSeconds(),
GAMESTATE->m_pCurSong->m_fMusicSampleLengthSeconds );
}
}
+6 -11
View File
@@ -79,17 +79,14 @@ void ScreenWithMenuElements::Init()
// decorations
{
AutoActor decorations;
decorations.LoadB( m_sName, "decorations" );
decorations->SetName("Decorations");
decorations->SetDrawOrder( DRAW_ORDER_DECORATIONS );
ActorFrame *pFrame = dynamic_cast<ActorFrame*>(static_cast<Actor*>(decorations));
m_Decorations.LoadB( m_sName, "decorations" );
m_Decorations->SetName("Decorations");
m_Decorations->SetDrawOrder( DRAW_ORDER_DECORATIONS );
ActorFrame *pFrame = dynamic_cast<ActorFrame*>(static_cast<Actor*>(m_Decorations));
if( pFrame )
{
m_vDecorations = pFrame->GetChildren();
FOREACH( Actor*, m_vDecorations, child )
this->AddChild( *child );
pFrame->RemoveAllChildren();
this->AddChild(m_Decorations);
LOAD_ALL_COMMANDS(m_Decorations);
}
}
@@ -167,8 +164,6 @@ ScreenWithMenuElements::~ScreenWithMenuElements()
if( m_MemoryCardDisplay[p] != NULL )
SAFE_DELETE( m_MemoryCardDisplay[p] );
}
FOREACH( Actor*, m_vDecorations, actor )
delete *actor;
}
void ScreenWithMenuElements::SetHelpText( RString s )
+1 -1
View File
@@ -45,7 +45,7 @@ protected:
MemoryCardDisplay *m_MemoryCardDisplay[NUM_PLAYERS];
MenuTimer *m_MenuTimer;
AutoActor m_sprOverlay;
vector<Actor*> m_vDecorations;
AutoActor m_Decorations;
Transition m_In;
Transition m_Out;
+15 -10
View File
@@ -43,7 +43,7 @@
* @brief The internal version of the cache for StepMania.
*
* 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? */
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
@@ -1479,22 +1479,20 @@ RString Song::GetPreviewVidPath() const
RString Song::GetPreviewMusicPath() const
{
RString preview= GetSongDir() + "preview.ogg";
if(FILEMAN->DoesFileExist(preview))
if(m_PreviewFile.empty())
{
return preview;
return GetMusicPath();
}
return GetMusicPath();
return GetSongAssetPath(m_PreviewFile, m_sSongDir);
}
float Song::GetPreviewStartSeconds() const
{
RString preview= GetSongDir() + "preview.ogg";
if(FILEMAN->DoesFileExist(preview))
if(m_PreviewFile.empty())
{
return 0.0f;
return m_fMusicSampleStartSeconds;
}
return m_fMusicSampleStartSeconds;
return 0.0f;
}
RString Song::GetDisplayMainTitle() const
@@ -1814,6 +1812,12 @@ public:
lua_pushnil(L);
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 )
{
RString s = p->GetJacketPath();
@@ -1886,7 +1890,7 @@ public:
}
static int GetSampleStart( T* p, lua_State *L )
{
lua_pushnumber(L, p->m_fMusicSampleStartSeconds);
lua_pushnumber(L, p->GetPreviewStartSeconds());
return 1;
}
static int GetSampleLength( T* p, lua_State *L )
@@ -2128,6 +2132,7 @@ public:
ADD_METHOD( ShowInDemonstrationAndRanking );
ADD_METHOD( HasPreviewVid );
ADD_METHOD( GetPreviewVidPath );
ADD_METHOD(GetPreviewMusicPath);
}
};
+1
View File
@@ -224,6 +224,7 @@ public:
RString m_sOrigin; // song origin (for .ssc format)
RString m_sMusicFile;
RString m_PreviewFile;
RString m_sInstrumentTrackFile[NUM_InstrumentTrack];
/** @brief The length of the music file. */
+18
View File
@@ -899,6 +899,24 @@ bool SongUtil::ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErr
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 )
{
set<RString> genres;
+1
View File
@@ -165,6 +165,7 @@ namespace SongUtil
bool ValidateCurrentStepsDescription( const RString &sAnswer, RString &sErrorOut );
bool ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErrorOut );
bool ValidateCurrentStepsChartName(const RString &answer, RString &error);
bool ValidateCurrentSongPreview(const RString& answer, RString& error);
void GetAllSongGenres( vector<RString> &vsOut );
/**