Fix a crash that occured when changing themes that had differing numbers of song/course group colors.
This commit is contained in:
@@ -9,6 +9,15 @@ Not all changes are documented, for various reasons.
|
|||||||
supported but exist anyways.)
|
supported but exist anyways.)
|
||||||
_____________________________________________________________________________
|
_____________________________________________________________________________
|
||||||
|
|
||||||
|
20100603
|
||||||
|
--------
|
||||||
|
* [MusicWheel] If AutoSetStyle is on and Autogen is off, some songs with valid
|
||||||
|
steps may be missing from the wheel. Re-add them by checking for every
|
||||||
|
playable StepsType when AutoSetStyle is on.
|
||||||
|
Fixes issue 147: http://ssc.ajworld.net/sm-ssc/bugtracker/view.php?id=147
|
||||||
|
* Fix a crash that occured when changing themes that had differing numbers
|
||||||
|
of song/course group colors. (Yes, finally.)
|
||||||
|
|
||||||
20100602
|
20100602
|
||||||
--------
|
--------
|
||||||
* [Actor] add addrotationx, addrotationy, addrotationz bindings/commands
|
* [Actor] add addrotationx, addrotationy, addrotationz bindings/commands
|
||||||
|
|||||||
+28
-33
@@ -81,9 +81,7 @@ static map<RString,CreateScreenFn> *g_pmapRegistrees = NULL;
|
|||||||
|
|
||||||
namespace ScreenManagerUtil
|
namespace ScreenManagerUtil
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// in draw order first to last
|
// in draw order first to last
|
||||||
//
|
|
||||||
struct LoadedScreen
|
struct LoadedScreen
|
||||||
{
|
{
|
||||||
Screen *m_pScreen;
|
Screen *m_pScreen;
|
||||||
@@ -112,7 +110,7 @@ namespace ScreenManagerUtil
|
|||||||
vector<LoadedScreen> g_vPreparedScreens;
|
vector<LoadedScreen> g_vPreparedScreens;
|
||||||
vector<Actor*> g_vPreparedBackgrounds;
|
vector<Actor*> g_vPreparedBackgrounds;
|
||||||
|
|
||||||
/* Add a screen to g_ScreenStack. This is the only function that adds to g_ScreenStack. */
|
// Add a screen to g_ScreenStack. This is the only function that adds to g_ScreenStack.
|
||||||
void PushLoadedScreen( const LoadedScreen &ls )
|
void PushLoadedScreen( const LoadedScreen &ls )
|
||||||
{
|
{
|
||||||
LOG->Trace( "PushScreen: \"%s\"", ls.m_pScreen->GetName().c_str() );
|
LOG->Trace( "PushScreen: \"%s\"", ls.m_pScreen->GetName().c_str() );
|
||||||
@@ -122,14 +120,14 @@ namespace ScreenManagerUtil
|
|||||||
// during BeginScreen.
|
// during BeginScreen.
|
||||||
g_ScreenStack.push_back( ls );
|
g_ScreenStack.push_back( ls );
|
||||||
|
|
||||||
/* Set the name of the loading screen. */
|
// Set the name of the loading screen.
|
||||||
{
|
{
|
||||||
LuaThreadVariable var1( "PreviousScreen", m_sPreviousTopScreen );
|
LuaThreadVariable var1( "PreviousScreen", m_sPreviousTopScreen );
|
||||||
LuaThreadVariable var2( "LoadingScreen", ls.m_pScreen->GetName() );
|
LuaThreadVariable var2( "LoadingScreen", ls.m_pScreen->GetName() );
|
||||||
ls.m_pScreen->BeginScreen();
|
ls.m_pScreen->BeginScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is the new top screen, save the name. */
|
// If this is the new top screen, save the name.
|
||||||
if( g_ScreenStack.size() == 1 )
|
if( g_ScreenStack.size() == 1 )
|
||||||
m_sPreviousTopScreen = ls.m_pScreen->GetName();
|
m_sPreviousTopScreen = ls.m_pScreen->GetName();
|
||||||
|
|
||||||
@@ -166,7 +164,7 @@ namespace ScreenManagerUtil
|
|||||||
|
|
||||||
void BeforeDeleteScreen()
|
void BeforeDeleteScreen()
|
||||||
{
|
{
|
||||||
/* Deleting a screen can take enough time to cause a frame skip. */
|
// Deleting a screen can take enough time to cause a frame skip.
|
||||||
SCREENMAN->ZeroNextUpdate();
|
SCREENMAN->ZeroNextUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,8 +176,8 @@ namespace ScreenManagerUtil
|
|||||||
* cached textures. */
|
* cached textures. */
|
||||||
TEXTUREMAN->DeleteCachedTextures();
|
TEXTUREMAN->DeleteCachedTextures();
|
||||||
|
|
||||||
/* Cleanup song data. This can free up a fair bit of memory, so do it after
|
/* Cleanup song data. This can free up a fair bit of memory, so do it
|
||||||
* deleting screens. */
|
* after deleting screens. */
|
||||||
SONGMAN->Cleanup();
|
SONGMAN->Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +266,7 @@ ScreenManager::~ScreenManager()
|
|||||||
LUA->UnsetGlobal( "SCREENMAN" );
|
LUA->UnsetGlobal( "SCREENMAN" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is called when we start up, and when the theme changes or is reloaded. */
|
// This is called when we start up, and when the theme changes or is reloaded.
|
||||||
void ScreenManager::ThemeChanged()
|
void ScreenManager::ThemeChanged()
|
||||||
{
|
{
|
||||||
LOG->Trace( "ScreenManager::ThemeChanged" );
|
LOG->Trace( "ScreenManager::ThemeChanged" );
|
||||||
@@ -297,6 +295,9 @@ void ScreenManager::ThemeChanged()
|
|||||||
g_OverlayScreens.push_back( pScreen );
|
g_OverlayScreens.push_back( pScreen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reload song manager colors (to avoid crashes) -aj
|
||||||
|
SONGMAN->ResetGroupColors();
|
||||||
|
|
||||||
// force recreate of new BGA
|
// force recreate of new BGA
|
||||||
SAFE_DELETE( g_pSharedBGA );
|
SAFE_DELETE( g_pSharedBGA );
|
||||||
g_pSharedBGA = new Actor;
|
g_pSharedBGA = new Actor;
|
||||||
@@ -331,7 +332,7 @@ bool ScreenManager::AllowOperatorMenuButton() const
|
|||||||
|
|
||||||
bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const
|
bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const
|
||||||
{
|
{
|
||||||
/* True if the screen is in the screen stack, but not the first. */
|
// True if the screen is in the screen stack, but not the first.
|
||||||
for( unsigned i = 1; i < g_ScreenStack.size(); ++i )
|
for( unsigned i = 1; i < g_ScreenStack.size(); ++i )
|
||||||
if( g_ScreenStack[i].m_pScreen == pScreen )
|
if( g_ScreenStack[i].m_pScreen == pScreen )
|
||||||
return true;
|
return true;
|
||||||
@@ -355,7 +356,7 @@ ScreenMessage ScreenManager::PopTopScreenInternal( bool bSendLoseFocus )
|
|||||||
|
|
||||||
if( g_setPersistantScreens.find(ls.m_pScreen->GetName()) != g_setPersistantScreens.end() )
|
if( g_setPersistantScreens.find(ls.m_pScreen->GetName()) != g_setPersistantScreens.end() )
|
||||||
{
|
{
|
||||||
/* Move the screen back to the prepared list. */
|
// Move the screen back to the prepared list.
|
||||||
g_vPreparedScreens.push_back( ls );
|
g_vPreparedScreens.push_back( ls );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -378,9 +379,7 @@ ScreenMessage ScreenManager::PopTopScreenInternal( bool bSendLoseFocus )
|
|||||||
|
|
||||||
void ScreenManager::Update( float fDeltaTime )
|
void ScreenManager::Update( float fDeltaTime )
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// Pop the top screen, if PopTopScreen was called.
|
// Pop the top screen, if PopTopScreen was called.
|
||||||
//
|
|
||||||
if( m_PopTopScreen != SM_Invalid )
|
if( m_PopTopScreen != SM_Invalid )
|
||||||
{
|
{
|
||||||
ScreenMessage SM = m_PopTopScreen;
|
ScreenMessage SM = m_PopTopScreen;
|
||||||
@@ -393,8 +392,7 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
SendMessageToTopScreen( SM2 );
|
SendMessageToTopScreen( SM2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Screens take some time to load. If we don't do this, then screens
|
||||||
* Screens take some time to load. If we don't do this, then screens
|
|
||||||
* receive an initial update that includes all of the time they spent
|
* receive an initial update that includes all of the time they spent
|
||||||
* loading, which will chop off their tweens.
|
* loading, which will chop off their tweens.
|
||||||
*
|
*
|
||||||
@@ -405,8 +403,7 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
* If we cap that large update delta from the screen load, the update
|
* If we cap that large update delta from the screen load, the update
|
||||||
* to load the new screen will come after 4 seconds plus the load time.
|
* to load the new screen will come after 4 seconds plus the load time.
|
||||||
*
|
*
|
||||||
* So, let's just zero the first update for every screen.
|
* So, let's just zero the first update for every screen. */
|
||||||
*/
|
|
||||||
ASSERT( !g_ScreenStack.empty() || m_sDelayedScreen != "" ); // Why play the game if there is nothing showing?
|
ASSERT( !g_ScreenStack.empty() || m_sDelayedScreen != "" ); // Why play the game if there is nothing showing?
|
||||||
|
|
||||||
Screen* pScreen = g_ScreenStack.empty() ? NULL : GetTopScreen();
|
Screen* pScreen = g_ScreenStack.empty() ? NULL : GetTopScreen();
|
||||||
@@ -423,9 +420,7 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
m_bZeroNextUpdate = false;
|
m_bZeroNextUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Update screens.
|
// Update screens.
|
||||||
//
|
|
||||||
{
|
{
|
||||||
for( unsigned i=0; i<g_ScreenStack.size(); i++ )
|
for( unsigned i=0; i<g_ScreenStack.size(); i++ )
|
||||||
g_ScreenStack[i].m_pScreen->Update( fDeltaTime );
|
g_ScreenStack[i].m_pScreen->Update( fDeltaTime );
|
||||||
@@ -506,7 +501,7 @@ void ScreenManager::Input( const InputEventPlus &input )
|
|||||||
g_ScreenStack.back().m_pScreen->Input( input );
|
g_ScreenStack.back().m_pScreen->Input( input );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Just create a new screen; don't do any associated cleanup. */
|
// Just create a new screen; don't do any associated cleanup.
|
||||||
Screen* ScreenManager::MakeNewScreen( const RString &sScreenName )
|
Screen* ScreenManager::MakeNewScreen( const RString &sScreenName )
|
||||||
{
|
{
|
||||||
RageTimer t;
|
RageTimer t;
|
||||||
@@ -590,15 +585,13 @@ void ScreenManager::SetNewScreen( const RString &sScreenName )
|
|||||||
m_sDelayedScreen = sScreenName;
|
m_sDelayedScreen = sScreenName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate the screen and/or its background, if either are loaded. Return true if both were
|
/* Activate the screen and/or its background, if either are loaded.
|
||||||
* activated. */
|
* Return true if both were activated. */
|
||||||
bool ScreenManager::ActivatePreparedScreenAndBackground( const RString &sScreenName )
|
bool ScreenManager::ActivatePreparedScreenAndBackground( const RString &sScreenName )
|
||||||
{
|
{
|
||||||
bool bLoadedBoth = true;
|
bool bLoadedBoth = true;
|
||||||
|
|
||||||
//
|
|
||||||
// Find the prepped screen.
|
// Find the prepped screen.
|
||||||
//
|
|
||||||
if( GetTopScreen() == NULL || GetTopScreen()->GetName() != sScreenName )
|
if( GetTopScreen() == NULL || GetTopScreen()->GetName() != sScreenName )
|
||||||
{
|
{
|
||||||
LoadedScreen ls;
|
LoadedScreen ls;
|
||||||
@@ -663,26 +656,26 @@ void ScreenManager::LoadDelayedScreen()
|
|||||||
// Pop the top screen, if any.
|
// Pop the top screen, if any.
|
||||||
ScreenMessage SM = PopTopScreenInternal();
|
ScreenMessage SM = PopTopScreenInternal();
|
||||||
|
|
||||||
/* If the screen is already prepared, activate it before performing any cleanup, so
|
/* If the screen is already prepared, activate it before performing any
|
||||||
* it doesn't get deleted by cleanup. */
|
* cleanup, so it doesn't get deleted by cleanup. */
|
||||||
bool bLoaded = ActivatePreparedScreenAndBackground( sScreenName );
|
bool bLoaded = ActivatePreparedScreenAndBackground( sScreenName );
|
||||||
|
|
||||||
vector<Actor*> apActorsToDelete;
|
vector<Actor*> apActorsToDelete;
|
||||||
if( g_setGroupedScreens.find(sScreenName) == g_setGroupedScreens.end() )
|
if( g_setGroupedScreens.find(sScreenName) == g_setGroupedScreens.end() )
|
||||||
{
|
{
|
||||||
/* It's time to delete all old prepared screens. Depending on DelayedScreenLoad,
|
/* It's time to delete all old prepared screens. Depending on DelayedScreenLoad,
|
||||||
* we can either delete the screens before or after we load the new screen. Either
|
* we can either delete the screens before or after we load the new screen.
|
||||||
* way, we must remove them from the prepared list before we prepare new screens.
|
* Either way, we must remove them from the prepared list before we prepare
|
||||||
*
|
* new screens.
|
||||||
* If DelayedScreenLoad is true, delete them now; this lowers memory requirements,
|
* If DelayedScreenLoad is true, delete them now; this lowers memory
|
||||||
* but results in redundant loads as we unload common data. */
|
* requirements, but results in redundant loads as we unload common data. */
|
||||||
if( g_bDelayedScreenLoad )
|
if( g_bDelayedScreenLoad )
|
||||||
DeletePreparedScreens();
|
DeletePreparedScreens();
|
||||||
else
|
else
|
||||||
GrabPreparedActors( apActorsToDelete );
|
GrabPreparedActors( apActorsToDelete );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the screen wasn't already prepared, load it. */
|
// If the screen wasn't already prepared, load it.
|
||||||
if( !bLoaded )
|
if( !bLoaded )
|
||||||
{
|
{
|
||||||
PrepareScreen( sScreenName );
|
PrepareScreen( sScreenName );
|
||||||
@@ -738,7 +731,7 @@ void ScreenManager::PopTopScreen( ScreenMessage SM )
|
|||||||
* from inside a screen. */
|
* from inside a screen. */
|
||||||
void ScreenManager::PopAllScreens()
|
void ScreenManager::PopAllScreens()
|
||||||
{
|
{
|
||||||
/* Make sure only the top screen receives LoseFocus. */
|
// Make sure only the top screen receives LoseFocus.
|
||||||
bool bFirst = true;
|
bool bFirst = true;
|
||||||
while( !g_ScreenStack.empty() )
|
while( !g_ScreenStack.empty() )
|
||||||
{
|
{
|
||||||
@@ -867,6 +860,7 @@ public:
|
|||||||
static int SystemMessage( T* p, lua_State *L ) { p->SystemMessage( SArg(1) ); return 0; }
|
static int SystemMessage( T* p, lua_State *L ) { p->SystemMessage( SArg(1) ); return 0; }
|
||||||
static int ScreenIsPrepped( T* p, lua_State *L ) { lua_pushboolean( L, ScreenManagerUtil::ScreenIsPrepped( SArg(1) ) ); return 1; }
|
static int ScreenIsPrepped( T* p, lua_State *L ) { lua_pushboolean( L, ScreenManagerUtil::ScreenIsPrepped( SArg(1) ) ); return 1; }
|
||||||
static int ScreenClassExists( T* p, lua_State *L ) { lua_pushboolean( L, g_pmapRegistrees->find( SArg(1) ) != g_pmapRegistrees->end() ); return 1; }
|
static int ScreenClassExists( T* p, lua_State *L ) { lua_pushboolean( L, g_pmapRegistrees->find( SArg(1) ) != g_pmapRegistrees->end() ); return 1; }
|
||||||
|
//static int GetScreenStackSize( T* p, lua_State *L ) { lua_pushnumber( L, ScreenManagerUtil::g_ScreenStack.size() ); return 1; }
|
||||||
|
|
||||||
LunaScreenManager()
|
LunaScreenManager()
|
||||||
{
|
{
|
||||||
@@ -875,6 +869,7 @@ public:
|
|||||||
ADD_METHOD( SystemMessage );
|
ADD_METHOD( SystemMessage );
|
||||||
ADD_METHOD( ScreenIsPrepped );
|
ADD_METHOD( ScreenIsPrepped );
|
||||||
ADD_METHOD( ScreenClassExists );
|
ADD_METHOD( ScreenClassExists );
|
||||||
|
//ADD_METHOD( GetScreenStackSize );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+13
-7
@@ -126,13 +126,6 @@ void SongManager::Reload( bool bAllowFastLoad, LoadingWindow *ld )
|
|||||||
PREFSMAN->m_bFastLoad.Set( OldVal );
|
PREFSMAN->m_bFastLoad.Set( OldVal );
|
||||||
|
|
||||||
UpdatePreferredSort();
|
UpdatePreferredSort();
|
||||||
|
|
||||||
// Reload song/course group colors to prevent a crash when switching
|
|
||||||
// themes in-game. (apparently not, though.) -aj
|
|
||||||
NUM_SONG_GROUP_COLORS .Load( "SongManager", "NumSongGroupColors" );
|
|
||||||
SONG_GROUP_COLOR .Load( "SongManager", SONG_GROUP_COLOR_NAME, NUM_SONG_GROUP_COLORS );
|
|
||||||
NUM_COURSE_GROUP_COLORS .Load( "SongManager", "NumCourseGroupColors" );
|
|
||||||
COURSE_GROUP_COLOR .Load( "SongManager", COURSE_GROUP_COLOR_NAME, NUM_COURSE_GROUP_COLORS );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SongManager::InitSongsFromDisk( LoadingWindow *ld )
|
void SongManager::InitSongsFromDisk( LoadingWindow *ld )
|
||||||
@@ -576,6 +569,19 @@ RageColor SongManager::GetCourseColor( const Course* pCourse ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SongManager::ResetGroupColors()
|
||||||
|
{
|
||||||
|
// Reload song/course group colors to prevent a crash when switching
|
||||||
|
// themes in-game. (apparently not, though.) -aj
|
||||||
|
SONG_GROUP_COLOR.Clear();
|
||||||
|
COURSE_GROUP_COLOR.Clear();
|
||||||
|
|
||||||
|
NUM_SONG_GROUP_COLORS .Load( "SongManager", "NumSongGroupColors" );
|
||||||
|
SONG_GROUP_COLOR .Load( "SongManager", SONG_GROUP_COLOR_NAME, NUM_SONG_GROUP_COLORS );
|
||||||
|
NUM_COURSE_GROUP_COLORS .Load( "SongManager", "NumCourseGroupColors" );
|
||||||
|
COURSE_GROUP_COLOR .Load( "SongManager", COURSE_GROUP_COLOR_NAME, NUM_COURSE_GROUP_COLORS );
|
||||||
|
}
|
||||||
|
|
||||||
const vector<Song*> &SongManager::GetSongs( const RString &sGroupName ) const
|
const vector<Song*> &SongManager::GetSongs( const RString &sGroupName ) const
|
||||||
{
|
{
|
||||||
static const vector<Song*> vEmpty;
|
static const vector<Song*> vEmpty;
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public:
|
|||||||
RageColor GetCourseGroupColor( const RString &sCourseGroupName ) const;
|
RageColor GetCourseGroupColor( const RString &sCourseGroupName ) const;
|
||||||
RageColor GetCourseColor( const Course* pCourse ) const;
|
RageColor GetCourseColor( const Course* pCourse ) const;
|
||||||
|
|
||||||
|
void ResetGroupColors(); // sm-ssc add
|
||||||
|
|
||||||
static RString ShortenGroupName( RString sLongGroupName );
|
static RString ShortenGroupName( RString sLongGroupName );
|
||||||
|
|
||||||
// Lookup
|
// Lookup
|
||||||
|
|||||||
Reference in New Issue
Block a user