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:
@@ -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]
|
||||
|
||||
|
||||
@@ -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'/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] );
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -568,6 +568,7 @@ public:
|
||||
artist,
|
||||
genre,
|
||||
credit,
|
||||
preview,
|
||||
main_title_transliteration,
|
||||
sub_title_transliteration,
|
||||
artist_transliteration,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user