//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "stdafx.h" // NOTE: This must be the last file included!!! #include "tier0/memdbgon.h" using namespace SF::GFx; // Some utility functions to map SFUI enums to SF enums Movie::ScaleModeType ScaleformUIImpl::ScaleModeType_SFUI_to_SDK( IScaleformUI::_ScaleModeType scaleModeType ) { switch ( scaleModeType ) { case IScaleformUI::SM_NoScale: return Movie::SM_NoScale; case IScaleformUI::SM_ShowAll: return Movie::SM_ShowAll; case IScaleformUI::SM_ExactFit: return Movie::SM_ExactFit; case IScaleformUI::SM_NoBorder: return Movie::SM_NoBorder; default: AssertMsg( 0, "Unknown ScaleModeType\n"); return Movie::SM_NoScale; } }; IScaleformUI::_ScaleModeType ScaleformUIImpl::ScaleModeType_SDK_to_SFUI( Movie::ScaleModeType scaleModeType ) { switch ( scaleModeType ) { case Movie::SM_NoScale: return IScaleformUI::SM_NoScale; case Movie::SM_ShowAll: return IScaleformUI::SM_ShowAll; case Movie::SM_ExactFit: return IScaleformUI::SM_ExactFit; case Movie::SM_NoBorder: return IScaleformUI::SM_NoBorder; default: AssertMsg( 0, "Unknown ScaleModeType\n"); return IScaleformUI::SM_NoScale; } }; Value::ValueType ScaleformUIImpl::ValueType_SFUI_to_SDK( IScaleformUI::_ValueType valueType ) { switch ( valueType ) { case IScaleformUI::VT_Undefined : return Value::VT_Undefined ; case IScaleformUI::VT_Null : return Value::VT_Null ; case IScaleformUI::VT_Boolean : return Value::VT_Boolean ; case IScaleformUI::VT_Int : return Value::VT_Int ; case IScaleformUI::VT_UInt : return Value::VT_UInt ; case IScaleformUI::VT_Number : return Value::VT_Number ; case IScaleformUI::VT_String : return Value::VT_String ; case IScaleformUI::VT_StringW : return Value::VT_StringW ; case IScaleformUI::VT_Object : return Value::VT_Object ; case IScaleformUI::VT_Array : return Value::VT_Array ; case IScaleformUI::VT_DisplayObject : return Value::VT_DisplayObject ; case IScaleformUI::VT_Closure : return Value::VT_Closure ; case IScaleformUI::VT_ConvertBoolean : return Value::VT_ConvertBoolean ; case IScaleformUI::VT_ConvertInt : return Value::VT_ConvertInt ; case IScaleformUI::VT_ConvertUInt : return Value::VT_ConvertUInt ; case IScaleformUI::VT_ConvertNumber : return Value::VT_ConvertNumber ; case IScaleformUI::VT_ConvertString : return Value::VT_ConvertString ; case IScaleformUI::VT_ConvertStringW : return Value::VT_ConvertStringW ; default: AssertMsg( 0, "Unknown ValueType\n"); return Value::VT_Undefined; } } IScaleformUI::_ValueType ScaleformUIImpl::ValueType_SDK_to_SFUI( Value::ValueType valueType ) { switch ( valueType ) { case Value::VT_Undefined : return IScaleformUI::VT_Undefined ; case Value::VT_Null : return IScaleformUI::VT_Null ; case Value::VT_Boolean : return IScaleformUI::VT_Boolean ; case Value::VT_Int : return IScaleformUI::VT_Int ; case Value::VT_UInt : return IScaleformUI::VT_UInt ; case Value::VT_Number : return IScaleformUI::VT_Number ; case Value::VT_String : return IScaleformUI::VT_String ; case Value::VT_StringW : return IScaleformUI::VT_StringW ; case Value::VT_Object : return IScaleformUI::VT_Object ; case Value::VT_Array : return IScaleformUI::VT_Array ; case Value::VT_DisplayObject : return IScaleformUI::VT_DisplayObject ; case Value::VT_Closure : return IScaleformUI::VT_Closure ; case Value::VT_ConvertBoolean : return IScaleformUI::VT_ConvertBoolean ; case Value::VT_ConvertInt : return IScaleformUI::VT_ConvertInt ; case Value::VT_ConvertUInt : return IScaleformUI::VT_ConvertUInt ; case Value::VT_ConvertNumber : return IScaleformUI::VT_ConvertNumber ; case Value::VT_ConvertString : return IScaleformUI::VT_ConvertString ; case Value::VT_ConvertStringW : return IScaleformUI::VT_ConvertStringW ; default: AssertMsg( 0, "Unknown ValueType\n"); return IScaleformUI::VT_Undefined; } } Movie::AlignType ScaleformUIImpl::AlignType_SFUI_to_SDK( IScaleformUI::_AlignType alignType ) { switch ( alignType ) { case IScaleformUI::Align_Center: return Movie::Align_Center; case IScaleformUI::Align_TopCenter: return Movie::Align_TopCenter; case IScaleformUI::Align_BottomCenter: return Movie::Align_BottomCenter; case IScaleformUI::Align_CenterLeft: return Movie::Align_CenterLeft; case IScaleformUI::Align_CenterRight: return Movie::Align_CenterRight; case IScaleformUI::Align_TopLeft: return Movie::Align_TopLeft; case IScaleformUI::Align_TopRight: return Movie::Align_TopRight; case IScaleformUI::Align_BottomLeft: return Movie::Align_BottomLeft; case IScaleformUI::Align_BottomRight: return Movie::Align_BottomRight; default: AssertMsg( 0, "Unknown AlignType\n"); return Movie::Align_Center; } } IScaleformUI::_AlignType ScaleformUIImpl::AlignType_SDK_to_SFUI( Movie::AlignType alignType ) { switch ( alignType ) { case Movie::Align_Center: return IScaleformUI::Align_Center; case Movie::Align_TopCenter: return IScaleformUI::Align_TopCenter; case Movie::Align_BottomCenter: return IScaleformUI::Align_BottomCenter; case Movie::Align_CenterLeft: return IScaleformUI::Align_CenterLeft; case Movie::Align_CenterRight: return IScaleformUI::Align_CenterRight; case Movie::Align_TopLeft: return IScaleformUI::Align_TopLeft; case Movie::Align_TopRight: return IScaleformUI::Align_TopRight; case Movie::Align_BottomLeft: return IScaleformUI::Align_BottomLeft; case Movie::Align_BottomRight: return IScaleformUI::Align_BottomRight; default: AssertMsg( 0, "Unknown AlignType\n"); return IScaleformUI::Align_Center; } } Movie::HitTestType ScaleformUIImpl::HitTestType_SFUI_to_SDK( IScaleformUI::_HitTestType hitTestType ) { switch ( hitTestType ) { case IScaleformUI::HitTest_Bounds: return Movie::HitTest_Bounds; case IScaleformUI::HitTest_Shapes: return Movie::HitTest_Shapes; case IScaleformUI::HitTest_ButtonEvents: return Movie::HitTest_ButtonEvents; case IScaleformUI::HitTest_ShapesNoInvisible: return Movie::HitTest_ShapesNoInvisible; default: AssertMsg( 0, "Unknown HitTestType\n"); return Movie::HitTest_Bounds; } } IScaleformUI::_HitTestType ScaleformUIImpl::HitTestType_SDK_to_SFUI( Movie::HitTestType hitTestType ) { switch ( hitTestType ) { case Movie::HitTest_Bounds: return IScaleformUI::HitTest_Bounds; case Movie::HitTest_Shapes: return IScaleformUI::HitTest_Shapes; case Movie::HitTest_ButtonEvents: return IScaleformUI::HitTest_ButtonEvents; case Movie::HitTest_ShapesNoInvisible: return IScaleformUI::HitTest_ShapesNoInvisible; default: AssertMsg( 0, "Unknown HitTestType\n"); return IScaleformUI::HitTest_Bounds; } } class ScaleformMovieDefHolder: public ASUserData { public: // this is a weak pointer MovieDef* m_pMovieDef; inline ScaleformMovieDefHolder( MovieDef *pdef ) : ASUserData(), m_pMovieDef( pdef ) { } virtual void OnDestroy( Movie* pmovie, void* pobject ) { Release(); } }; void ScaleformUIImpl::InitMovieImpl( void ) { } void ScaleformUIImpl::ShutdownMovieImpl( void ) { #if defined( _DEBUG ) if ( m_MovieViews.Count() ) { LogPrintf( "Scaleform: Some movie views were not released\n" ); for ( int i = 0; i < m_MovieViews.Count(); i++ ) { ASUserData* pud = ( ASUserData* )m_MovieViews[i]->GetUserData(); ScaleformMovieDefHolder* pDef = ( ScaleformMovieDefHolder* ) pud; if ( pDef ) { LogPrintf( " %s\n", pDef->m_pMovieDef->GetFileURL() ); } else { LogPrintf( " unknown slot movie\n" ); } if ( pud ) { pud->OnDestroy( m_MovieViews[i],NULL ); } m_MovieViews[i]->SetUserData( NULL ); } } if ( m_MovieDefNameCache.Count() ) { LogPrintf( "Scaleform: Some movie defs were not released\n" ); for ( int i = 0; i < m_MovieDefNameCache.Count(); i++ ) { LogPrintf( " %s\n", m_MovieDefNameCache[i] ); } } #endif } SFMOVIEDEF ScaleformUIImpl::CreateMovieDef( const char* pfilename, unsigned int loadConstants, size_t memoryArena ) { // first see if we've already got the guy loaded MovieDef* presult = NULL; for ( int i = 0; i < m_MovieDefNameCache.Count(); i++ ) { if ( !V_stricmp( m_MovieDefNameCache[i], pfilename ) ) { presult = m_MovieDefCache[i]; presult->AddRef(); break; } } if ( presult == NULL ) { presult = m_pLoader->CreateMovie( pfilename, loadConstants, memoryArena ); m_MovieDefCache.AddToTail( presult ); char* newString = new char[V_strlen( pfilename )+1]; V_strcpy( newString, pfilename ); m_MovieDefNameCache.AddToTail( newString ); } return ToSFMOVIEDEF( presult ); } void ScaleformUIImpl::ReleaseMovieDef( SFMOVIEDEF movieDef ) { MovieDef* pdef = FromSFMOVIEDEF( movieDef ); int refcount = pdef->GetRefCount(); pdef->Release(); // we actually removed this if ( refcount == 1 ) { for ( int i = 0; i < m_MovieDefCache.Count(); i++ ) { if ( m_MovieDefCache[i] == pdef ) { delete[] m_MovieDefNameCache[i]; m_MovieDefCache.FastRemove( i ); m_MovieDefNameCache.FastRemove( i ); break; } } } } SFMOVIE ScaleformUIImpl::MovieDef_CreateInstance( SFMOVIEDEF movieDef, bool initFirstFrame, size_t memoryArena ) { MovieDef* pDef = FromSFMOVIEDEF( movieDef ); Movie* pView = pDef->CreateInstance( initFirstFrame, memoryArena, 0, m_pThreadCommandQueue ); if ( pView ) { #if defined( _DEBUG ) // only need this so we can print the name of the movie if we don't release it ScaleformMovieDefHolder* def = new ScaleformMovieDefHolder( pDef ); pView->SetUserData( def ); #endif // _DEBUG m_MovieViews.AddToTail( pView ); } return ToSFMOVIE( pView ); } void ScaleformUIImpl::ReleaseMovieView( SFMOVIE movieView ) { if ( movieView ) { m_MovieViews.FindAndFastRemove( FromSFMOVIE( movieView ) ); #if defined( _DEBUG ) ScaleformMovieDefHolder* def = ( ScaleformMovieDefHolder* )FromSFMOVIE( movieView )->GetUserData(); if ( def ) { def->OnDestroy( FromSFMOVIE( movieView ), NULL ); } FromSFMOVIE( movieView )->SetUserData( NULL ); #endif // This needs to execute on the render thread via a command queue. It only works here // because typically when we free movies either QMS is off, or the qms is not very active // because we are loading/unloading maps Movie *pMovie = FromSFMOVIE( movieView ); pMovie->ShutdownRendering( false ); while ( !pMovie->IsShutdownRenderingComplete() ) { if ( m_pRenderer2D->GetContextNotify() ) { MovieDisplayHandle hMovieDisplay = pMovie->GetDisplayHandle(); hMovieDisplay.NextCapture( m_pRenderer2D->GetContextNotify() ); m_pRenderer2D->GetContextNotify()->EndFrameContextNotify(); } } pMovie->Release(); } } void ScaleformUIImpl::MovieView_Advance( SFMOVIE movieView, float time, unsigned int frameCatchUpCount ) { FromSFMOVIE( movieView )->Advance( time, frameCatchUpCount ); } void ScaleformUIImpl::MovieView_SetBackgroundAlpha( SFMOVIE movieView, float alpha ) { FromSFMOVIE( movieView )->SetBackgroundAlpha( alpha ); } void ScaleformUIImpl::MovieView_SetViewport( SFMOVIE movieView, int bufw, int bufh, int left, int top, int w, int h, unsigned int flags ) { FromSFMOVIE( movieView )->SetViewport( bufw, bufh, left, top, w, h, flags ); } void ScaleformUIImpl::MovieView_Display( SFMOVIE movieView ) { MovieDisplayHandle hMovieDisplay = FromSFMOVIE( movieView )->GetDisplayHandle(); if ( hMovieDisplay.NextCapture( m_pRenderer2D->GetContextNotify() ) ) { m_pRenderer2D->Display( hMovieDisplay ); } } /*** * view alignment and scaling */ void ScaleformUIImpl::MovieView_SetViewScaleMode( SFMOVIE movieView, IScaleformUI::_ScaleModeType type ) { FromSFMOVIE( movieView )->SetViewScaleMode( ScaleModeType_SFUI_to_SDK( type ) ); } IScaleformUI::_ScaleModeType ScaleformUIImpl::MovieView_GetViewScaleMode( SFMOVIE movieView ) { return ScaleModeType_SDK_to_SFUI( FromSFMOVIE( movieView )->GetViewScaleMode() ); } void ScaleformUIImpl::MovieView_SetViewAlignment( SFMOVIE movieView, IScaleformUI::_AlignType type ) { FromSFMOVIE( movieView )->SetViewAlignment( AlignType_SFUI_to_SDK( type ) ); } IScaleformUI::_AlignType ScaleformUIImpl::MovieView_GetViewAlignment( SFMOVIE movieView ) { return AlignType_SDK_to_SFUI( FromSFMOVIE( movieView )->GetViewAlignment() ); } /*************************** * values */ SFVALUE ScaleformUIImpl::MovieView_CreateString( SFMOVIE movieView, const char *str ) { Value* pResult = FromSFVALUE( CreateGFxValue() ); FromSFMOVIE( movieView )->CreateString( pResult, str ); return ToSFVALUE( pResult ); } SFVALUE ScaleformUIImpl::MovieView_CreateStringW( SFMOVIE movieView, const wchar_t *str ) { Value* pResult = FromSFVALUE( CreateGFxValue() ); FromSFMOVIE( movieView )->CreateStringW( pResult, str ); return ToSFVALUE( pResult ); } SFVALUE ScaleformUIImpl::MovieView_CreateObject( SFMOVIE movieView, const char* className, SFVALUEARRAY args, int numArgs ) { Assert(numArgs == args.Count()); if ( numArgs != args.Count() ) { Warning("MovieView_CreateObject(%s) called with numArgs different than SFVALUEARRAY size\n", className); } Value* pResult = FromSFVALUE( CreateGFxValue() ); FromSFMOVIE( movieView )->CreateObject( pResult, className, FromSFVALUE( args.GetValues() ), args.Count() ); return ToSFVALUE( pResult ); } SFVALUE ScaleformUIImpl::MovieView_CreateArray( SFMOVIE movieView, int size ) { Value* pResult = FromSFVALUE( CreateGFxValue() ); FromSFMOVIE( movieView )->CreateArray( pResult ); if ( size != -1 ) pResult->SetArraySize( size ); return ToSFVALUE( pResult ); } SFVALUE ScaleformUIImpl::MovieView_GetVariable( SFMOVIE movieView, const char* variablePath ) { Value var; Value* pResult = NULL; bool worked = FromSFMOVIE( movieView )->GetVariable( &var, variablePath ); if ( worked ) { pResult = FromSFVALUE( CreateGFxValue( ToSFVALUE( &var ) ) ); } return ToSFVALUE( pResult ); } /*********** * hit testing */ bool ScaleformUIImpl::MovieView_HitTest( SFMOVIE movieView, float x, float y, IScaleformUI::_HitTestType testCond, unsigned int controllerIdx ) { return FromSFMOVIE( movieView )->HitTest( x, y, HitTestType_SFUI_to_SDK(testCond), controllerIdx ); }