You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

323 lines
8.1 KiB

//
// Copyright (c) 2010-2011 Matthew Jack and Doug Binks
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#include "ISplashScreen.h"
#include "../../RuntimeObjectSystem/ObjectInterfacePerModule.h"
#include "../../RuntimeCompiler/IFileChangeNotifier.h"
#include "../../Systems/SystemTable.h"
#include "../../Systems/IEntitySystem.h"
#include "../../Systems/IAssetSystem.h"
#include "../../Systems/ILogSystem.h"
#include "../../RuntimeObjectSystem/ISimpleSerializer.h"
#include "../../Systems/IGUISystem.h"
#include "../../Systems/IGame.h"
#include "../../Systems/IAssetSystem.h"
#include <assert.h>
#include <stdio.h>
#include <algorithm>
class SplashScreen: public ISplashScreen, public IFileChangeListener, public IGUIEventListener
{
public:
SplashScreen()
: m_pSplashElement(0)
, m_pDocument(0)
, m_fMinViewTime(0.0f)
, m_fFadeInTime(0.0f)
, m_fFadeOutTime(0.0f)
, m_fTimeDisplayed(0.0f)
, m_fFadeOutStartTime(0.0f)
, m_bAutoClose(false)
, m_bCloseRequested(false)
, m_bReadyToClose(false)
{
}
virtual ~SplashScreen()
{
if( m_pEntity )
{
m_pEntity->SetUpdateable(NULL);
}
if ( m_pSplashElement )
{
m_pSplashElement->RemoveEventListener( "click", this );
m_pSplashElement->RemoveReference();
}
if ( m_pDocument )
{
if (!IsRuntimeDelete())
{
m_pDocument->Hide();
}
m_pDocument->RemoveReference();
}
}
// IEntityObject
virtual void Serialize(ISimpleSerializer *pSerializer)
{
AU_ASSERT(pSerializer);
IEntityObject::Serialize(pSerializer);
SERIALIZE(m_ImageFile);
SERIALIZE(m_fMinViewTime);
SERIALIZE(m_fFadeInTime);
SERIALIZE(m_fFadeOutTime);
SERIALIZE(m_fTimeDisplayed);
SERIALIZE(m_fFadeOutStartTime);
SERIALIZE(m_bAutoClose);
SERIALIZE(m_bCloseRequested);
SERIALIZE(m_bReadyToClose);
}
virtual void Init( bool isFirstInit )
{
m_pEntity->SetUpdateable( this );
InitWatch();
InitDocument(false);
if (!m_ImageFile.empty())
{
SetImage(m_ImageFile.c_str());
}
}
// ~IEntityObject
// IAUUpdateable
virtual void Update( float deltaTime )
{
if( !m_pSplashElement || !m_pDocument )
{
return;
}
if (!m_bReadyToClose)
{
m_pDocument->Show(); // HACK - recompiling with visible splashscreen seems to make it vanish for some reason
char buff[32];
// Check if window has re-szie and move splash screen
float currWindowSize[2];
PerModuleInterface::g_pSystemTable->pGame->GetWindowSize( currWindowSize[0], currWindowSize[1] );
if( currWindowSize[0] != m_WindowSize[0] || currWindowSize[1] != m_WindowSize[1] )
{
m_WindowSize[0] = currWindowSize[0];
m_WindowSize[1] = currWindowSize[1];
int left;
left = (int)( (m_WindowSize[0] - m_pSplashElement->GetClientWidth()) * 0.5f );
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d",left);
m_pSplashElement->SetProperty("left", buff);
int top;
top = (int)( (m_WindowSize[1] - m_pSplashElement->GetClientHeight()) * 0.5f );
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d",top);
m_pSplashElement->SetProperty("top", buff);
}
m_fTimeDisplayed += deltaTime;
if (m_fTimeDisplayed < m_fFadeInTime)
{
// Fade In
float t = m_fTimeDisplayed / m_fFadeInTime;
_snprintf_s( buff, sizeof(buff), _TRUNCATE, "rgba(255,255,255,%d)", (int)(255 * t) );
m_pSplashElement->SetProperty( "color", buff );
}
else if (m_fTimeDisplayed < (m_fFadeInTime + m_fMinViewTime) ||
(!m_bAutoClose && !m_bCloseRequested))
{
// Regular View
m_fFadeOutStartTime = m_fTimeDisplayed;
m_pSplashElement->SetProperty( "color", "rgba(255,255,255,255)" );
}
else if (m_fTimeDisplayed < (m_fFadeOutStartTime + m_fFadeOutTime))
{
// Fade Out
float t = (m_fFadeOutStartTime + m_fFadeOutTime - m_fTimeDisplayed) / m_fFadeOutTime;
_snprintf_s( buff, sizeof(buff),_TRUNCATE , "rgba(255,255,255,%d)", (int)(255 * t) );
m_pSplashElement->SetProperty( "color", buff );
}
else
{
m_bReadyToClose = true;
}
}
}
// ~IAUUpdateable
// IFileChangeListener
virtual void OnFileChange(const IAUDynArray<const char*>& filelist)
{
// Reload RML document and clear RCSS cache
InitDocument(true);
}
// ~IFileChangeListener
// IGUIEventListener
virtual void OnEvent( const IGUIEvent& event_info )
{
m_bCloseRequested = true;
}
// ~IGUIEventListener
// ISplashScreen
virtual void SetImage( const char* imageFile )
{
AU_ASSERT(imageFile);
m_ImageFile = imageFile;
if (m_pSplashElement)
{
m_pSplashElement->SetAttribute("src", imageFile);
// Position element correctly so that it is centered
PerModuleInterface::g_pSystemTable->pGame->GetWindowSize( m_WindowSize[0], m_WindowSize[1] );
char buff[16];
int left;
left = (int)( (m_WindowSize[0] - m_pSplashElement->GetClientWidth()) * 0.5f );
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d",left);
m_pSplashElement->SetProperty("left", buff);
int top;
top = (int)( (m_WindowSize[1] - m_pSplashElement->GetClientHeight()) * 0.5f );
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%d",top);
m_pSplashElement->SetProperty("top", buff);
}
}
virtual void SetMinViewTime( float fSeconds )
{
m_fMinViewTime = std::max(0.0f, fSeconds);
}
virtual void SetFadeInTime( float fSeconds )
{
m_fFadeInTime = std::max(0.0f, fSeconds);
}
virtual void SetFadeOutTime( float fSeconds )
{
m_fFadeOutTime = std::max(0.0f, fSeconds);
}
virtual void SetAutoClose( bool bAutoClose )
{
m_bAutoClose = bAutoClose;
}
virtual bool ReadyToClose() const
{
return m_bReadyToClose;
}
// ~ISplashScreen
private:
void InitWatch()
{
IFileChangeNotifier* pFileChangeNotifier = PerModuleInterface::g_pSystemTable->pFileChangeNotifier;
// Set watches on the data files we rely on for drawing GUI
std::string path = PerModuleInterface::g_pSystemTable->pAssetSystem->GetAssetDirectory();
path += "/GUI/splashscreen.rml";
pFileChangeNotifier->Watch(path.c_str(), this);
path = PerModuleInterface::g_pSystemTable->pAssetSystem->GetAssetDirectory();
path += "/GUI/splashscreen.rcss";
pFileChangeNotifier->Watch(path.c_str(), this);
}
void InitDocument(bool forceLoad)
{
// may be serializing an already initialized object, ensure we handle reference
// counting correctly.
if (m_pSplashElement)
{
m_pSplashElement->RemoveEventListener( "click", this );
m_pSplashElement->RemoveReference();
m_pSplashElement = 0;
}
if (m_pDocument)
{
m_pDocument->RemoveReference();
m_pDocument = 0;
}
// Load and show the splashscreen
IGUISystem* pGUI = PerModuleInterface::g_pSystemTable->pGUISystem;
if (forceLoad)
{
// Clear style sheet cache so any changes to RCSS files will be applied
pGUI->ClearStyleSheetCache();
}
//Always load document in order to reset its state correctly
m_pDocument = pGUI->LoadDocument("/GUI/splashscreen.rml", "Splashscreen");
if (m_pDocument != NULL)
{
m_pDocument->Show();
m_pSplashElement = m_pDocument->Element()->GetElementById("splash");
m_pSplashElement->AddEventListener( "click", this );
}
}
// Private Members
IGUIElement* m_pSplashElement;
IGUIDocument* m_pDocument;
std::string m_ImageFile;
float m_fMinViewTime;
float m_fFadeInTime;
float m_fFadeOutTime;
float m_fTimeDisplayed;
float m_fFadeOutStartTime;
bool m_bAutoClose;
bool m_bCloseRequested;
bool m_bReadyToClose;
float m_WindowSize[2];
};
REGISTERCLASS(SplashScreen);