bool RemoteControlLinkage::SetData(const std::string &strDataType, const std::string &strValue, bool bThrowError)
{
	std::string strType = Std_CheckString(strDataType);

	if(AnimatBase::SetData(strType, strValue, false))
		return true;

	if(strType == "ENABLED")
	{
		Enabled(Std_ToBool(strValue));
		return true;
	}
	else if(strType == "SOURCEDATATYPEID")
	{
		SourceDataTypeID(strValue);
		return true;
	}
	else if(strType == "TARGETDATATYPEID")
	{
		TargetDataTypeID(strValue);
		return true;
	}
	else if(strType == "SOURCEID")
	{
		SourceID(strValue);
		return true;
	}
	else if(strType == "TARGETID")
	{
		TargetID(strValue);
		return true;
	}
	else if(strType == "PROPERTYNAME")
	{
		PropertyName(strValue);
		return true;
	}
	else if(strType == "PROPERTYID")
	{
		PropertyID(atoi(strValue.c_str()));
		return true;
	}

	//If it was not one of those above then we have a problem.
	if(bThrowError)
		THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType, "Data Type", strDataType);

	return false;
}
void RemoteControlLinkage::Load(CStdXml &oXml)
{
	AnimatBase::Load(oXml);

	oXml.IntoElem();  //Into Link Element

	InLink(oXml.GetChildBool("InLink", true));
	SourceID(oXml.GetChildString("SourceID", ""));
	TargetID(oXml.GetChildString("TargetID", ""));
	SourceDataTypeID(oXml.GetChildString("SourceDataTypeID", ""));
	TargetDataTypeID(oXml.GetChildString("TargetDataTypeID", ""));
	PropertyName(oXml.GetChildString("PropertyName", ""));
	PropertyID(oXml.GetChildInt("PropertyID", -1));

	oXml.OutOfElem(); //OutOf Link Element
}
void MovieTexture_Generic::CreateTexture()
{
	if( m_uTexHandle || m_pRenderTarget != nullptr )
		return;

	CHECKPOINT_M("About to create a generic texture.");

	m_iSourceWidth  = m_pDecoder->GetWidth();
	m_iSourceHeight = m_pDecoder->GetHeight();

	/* Adjust m_iSourceWidth to support different source aspect ratios. */
	float fSourceAspectRatio = m_pDecoder->GetSourceAspectRatio();
	if( fSourceAspectRatio < 1 )
		m_iSourceHeight = std::lrint( m_iSourceHeight / fSourceAspectRatio );
	else if( fSourceAspectRatio > 1 )
		m_iSourceWidth = std::lrint( m_iSourceWidth * fSourceAspectRatio );

	/* HACK: Don't cap movie textures to the max texture size, since we
	 * render them onto the texture at the source dimensions.  If we find a
	 * fast way to resize movies, we can change this back. */
	m_iImageWidth = m_iSourceWidth;
	m_iImageHeight = m_iSourceHeight;

	/* Texture dimensions need to be a power of two; jump to the next. */
	m_iTextureWidth = power_of_two( m_iImageWidth );
	m_iTextureHeight = power_of_two( m_iImageHeight );
	MovieDecoderPixelFormatYCbCr fmt = PixelFormatYCbCr_Invalid;
	if( m_pSurface == nullptr )
	{
		ASSERT( m_pTextureLock == nullptr );
		if( g_bMovieTextureDirectUpdates )
			m_pTextureLock = DISPLAY->CreateTextureLock();

		m_pSurface = m_pDecoder->CreateCompatibleSurface( m_iImageWidth, m_iImageHeight,
			TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32, fmt );
		if( m_pTextureLock != nullptr )
		{
			delete [] m_pSurface->pixels;
			m_pSurface->pixels = nullptr;
		}

	}

	RagePixelFormat pixfmt = DISPLAY->FindPixelFormat( m_pSurface->format->BitsPerPixel,
			m_pSurface->format->Mask[0],
			m_pSurface->format->Mask[1],
			m_pSurface->format->Mask[2],
			m_pSurface->format->Mask[3] );

	if( pixfmt == RagePixelFormat_Invalid )
	{
		/* We weren't given a natively-supported pixel format.  Pick a supported
		 * one.  This is a fallback case, and implies a second conversion. */
		int depth = TEXTUREMAN->GetPrefs().m_iMovieColorDepth;
		switch( depth )
		{
		default:
			FAIL_M(fmt::sprintf("Unsupported movie color depth: %i", depth));
		case 16:
			if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) )
				pixfmt = RagePixelFormat_RGB5;
			else
				pixfmt = RagePixelFormat_RGBA4;

			break;

		case 32:
			if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB8) )
				pixfmt = RagePixelFormat_RGB8;
			else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGBA8) )
				pixfmt = RagePixelFormat_RGBA8;
			else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) )
				pixfmt = RagePixelFormat_RGB5;
			else
				pixfmt = RagePixelFormat_RGBA4;
			break;
		}
	}

	if( fmt != PixelFormatYCbCr_Invalid )
	{
		Rage::safe_delete( m_pTextureIntermediate );
		m_pSprite->UnloadTexture();

		/* Create the render target.  This will receive the final, converted texture. */
		RenderTargetParam param;
		param.iWidth = m_iImageWidth;
		param.iHeight = m_iImageHeight;

		RageTextureID TargetID( GetID() );
		TargetID.filename += " target";
		m_pRenderTarget = new RageTextureRenderTarget( TargetID, param );

		/* Create the intermediate texture.  This receives the YUV image. */
		RageTextureID IntermedID( GetID() );
		IntermedID.filename += " intermediate";

		m_pTextureIntermediate = new RageMovieTexture_Generic_Intermediate( IntermedID,
			m_pDecoder->GetWidth(), m_pDecoder->GetHeight(),
			m_pSurface->w, m_pSurface->h,
			power_of_two(m_pSurface->w), power_of_two(m_pSurface->h),
			*m_pSurface->format, pixfmt );

		/* Configure the sprite.  This blits the intermediate onto the ifnal render target. */
		m_pSprite->SetHorizAlign( align_left );
		m_pSprite->SetVertAlign( align_top );

		/* Hack: Sprite wants to take ownership of the texture, and will decrement the refcount
		 * when it unloads the texture.  Normally we'd make a "copy", but we can't access
		 * RageTextureManager from here.  Just increment the refcount. */
		++m_pTextureIntermediate->m_iRefCount;
		m_pSprite->SetTexture( m_pTextureIntermediate );
		m_pSprite->SetEffectMode( GetEffectMode(fmt) );

		return;
	}

	m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_pSurface, false );
}