www.pudn.com > C++_Flash.rar > SWFSprite.cpp


// SWFSprite.cpp: implementation of the CSWFSprite class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "SWFSprite.h" 
 
 
CSWFSprite::CSWFSprite(USHORT nID, UCHAR* pName, USHORT depth) 
{ 
	// Init members 
	m_ObjectType = SWF_OBJECT_TYPE_SPRITE; 
	m_SWFStream = NULL; 
	m_SWFStreamLength = 0; 
	m_ID = nID; 
	m_Depth = depth; 
	m_Sprite.Header.TagCodeAndLength = (39 << 6) | 0x003F; 
	m_Sprite.Header.Length = 0; 
	m_Sprite.SpriteID = nID; 
	m_Sprite.FrameCount = 0; 
 
	if (pName != NULL) 
	{ 
		int nameLength = strlen((char*)pName) + 1; 
		m_Name = (UCHAR*)malloc(nameLength*sizeof(UCHAR)); 
		memcpy(m_Name, pName, nameLength-1); 
		m_Name[nameLength-1] = '\0'; 
	} 
	else 
		m_Name = NULL; 
} 
 
CSWFSprite::~CSWFSprite() 
{ 
	if (m_SWFStream != NULL) 
	{ 
		delete m_SWFStream; 
		m_SWFStream = NULL; 
	} 
 
	if (m_Name != NULL) 
	{ 
		free(m_Name); 
		m_Name = NULL; 
	} 
} 
 
void CSWFSprite::SetFrameLabel(UCHAR* frameLabel) 
{ 
	// FrameLabel tag 
	SWF_RECORDHEADER_LONG FrameLabelTag; 
	FrameLabelTag.TagCodeAndLength = (43 << 6) | 0x003F; 
	int frameLabelLength = strlen((char*)frameLabel) + 1; 
	FrameLabelTag.Length = frameLabelLength; 
 
	// Modify total .SWF file size 
	int newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG) + frameLabelLength; 
 
	// Write FrameLabel tag 
	if (m_SWFStreamLength == 0) 
		m_SWFStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
	memcpy(m_SWFStream+m_SWFStreamLength, &FrameLabelTag, sizeof(SWF_RECORDHEADER_LONG)); 
	memcpy(m_SWFStream+m_SWFStreamLength+sizeof(SWF_RECORDHEADER_LONG), frameLabel, frameLabelLength); 
	m_SWFStreamLength = newLength; 
} 
 
void CSWFSprite::ShowFrame() 
{ 
	// ShowFrame tag 
	USHORT showFrameTage = 0x0040; 
 
	// Modify total .SWF file size 
	int newLength = m_SWFStreamLength + sizeof(USHORT); 
 
	// Write ShowFrame tag 
	if (m_SWFStreamLength == 0) 
		m_SWFStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
	memcpy(m_SWFStream+m_SWFStreamLength, &showFrameTage, sizeof(USHORT)); 
	m_SWFStreamLength = newLength; 
 
	// Increment frame counter 
	m_Sprite.FrameCount++; 
} 
 
void CSWFSprite::TriggerAction(CSWFAction* pAction) 
{ 
	// Write DoAction tag to .SWF stream 
	if (pAction != NULL) 
	{ 
		UCHAR* pBuffer = pAction->BuildSWFStream(); 
 
		// Modify total .SWF file size 
		int newLength = m_SWFStreamLength + pAction->GetSWFStreamLength(); 
 
		// Write DefineShape tag 
		if (m_SWFStreamLength == 0) 
			m_SWFStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
		memcpy(m_SWFStream+m_SWFStreamLength, pBuffer, pAction->GetSWFStreamLength()); 
		m_SWFStreamLength = newLength; 
	} 
} 
 
void CSWFSprite::DefineObject(CSWFObject* pObject, int depth, bool bShow) 
{ 
	if ((pObject != NULL) && (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE)) 
	{ 
		// Get sprite SWF stream 
		UCHAR* pBuffer = pObject->BuildSWFStream(); 
		int objectLength = pObject->GetSWFStreamLength(); 
 
		int newLength = m_SWFStreamLength + objectLength; 
		if (m_SWFStreamLength == 0) 
			m_SWFStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
		memcpy(m_SWFStream+m_SWFStreamLength, pBuffer, objectLength); 
		m_SWFStreamLength = newLength; 
 
		// Initial display object 
		if (bShow) 
			DisplayObject(pObject, depth, TRUE, NULL, -1); 
	} 
} 
 
void CSWFSprite::AddObject(CSWFObject* pObject, int depth, SWF_COLOR_TRANSFORM* pColorTransform, int ratio, bool bInitialDisplay) 
{ 
	if (pObject != NULL) 
	{ 
		// Display object 
		DisplayObject(pObject, depth, bInitialDisplay, pColorTransform, ratio); 
	} 
} 
 
void CSWFSprite::UpdateObject(CSWFObject* pObject, int depth, SWF_COLOR_TRANSFORM* pColorTransform, int ratio) 
{ 
	if (pObject != NULL) 
	{ 
		// Display object 
		DisplayObject(pObject, depth, FALSE, pColorTransform, ratio); 
	} 
} 
 
void CSWFSprite::RemoveObject(int depth) 
{ 
	// Format RemoveObject2 tag 
	SWF_REMOVE_OBJECT2_TAG removeObjectTag; 
	memset(&removeObjectTag, 0, sizeof(SWF_REMOVE_OBJECT2_TAG)); 
	removeObjectTag.Header.TagCodeAndLength = (28 << 6) | 0x003F; 
	removeObjectTag.Header.Length = 2; 
	removeObjectTag.Depth = depth; 
 
	// Write RemoveObject2 tag 
	int newLength = m_SWFStreamLength + (removeObjectTag.Header.Length-2) + sizeof(SWF_REMOVE_OBJECT2_TAG); 
	if (m_SWFStreamLength == 0) 
		m_SWFStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
	memcpy(m_SWFStream+m_SWFStreamLength, &removeObjectTag, sizeof(SWF_REMOVE_OBJECT2_TAG)); 
	m_SWFStreamLength = newLength; 
} 
 
void CSWFSprite::DisplayObject(CSWFObject* pObject, int depth, bool bInitialDisplay, SWF_COLOR_TRANSFORM* pColorTransform, int ratio) 
{ 
	if (pObject != NULL) 
	{ 
		// Format PlaceObject2 tag 
		SWF_PLACE_OBJECT_TAG placeObjectTag; 
		memset(&placeObjectTag, 0, sizeof(SWF_PLACE_OBJECT_TAG)); 
		placeObjectTag.Header.TagCodeAndLength = (26 << 6) | 0x003F; 
		placeObjectTag.Header.Length = 0; 
		if (bInitialDisplay) 
			placeObjectTag.CharacterID = pObject->m_ID; 
		placeObjectTag.Depth = depth; 
		if (bInitialDisplay) 
			placeObjectTag.Flags = 0x06; 
		else 
			placeObjectTag.Flags = 0x05; 
		if (pColorTransform != NULL) 
			placeObjectTag.Flags |= 0x08; 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE) 
			placeObjectTag.Flags |= 0x10; 
		int nameLength = 0; 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE) 
		{ 
			if (((CSWFSprite*)pObject)->m_Name != NULL) 
			{ 
				nameLength = strlen((char*)((CSWFSprite*)pObject)->m_Name) + 1; 
				placeObjectTag.Flags |= 0x20; 
			} 
		} 
 
		// Get transformation matrix 
		UCHAR* pTransformationMatrix = NULL; 
		int transformationMatrixLength = 0; 
		switch (pObject->m_ObjectType) 
		{ 
			case SWF_OBJECT_TYPE_SHAPE: 
			{ 
				pTransformationMatrix = ((CSWFShape*)pObject)->m_TransformationMatrix.BuildSWFStream(); 
				transformationMatrixLength = ((CSWFShape*)pObject)->m_TransformationMatrix.GetSWFStreamLength(); 
			} 
			break; 
 
			case SWF_OBJECT_TYPE_MORPH_SHAPE: 
			{ 
				pTransformationMatrix = ((CSWFMorphShape*)pObject)->m_TransformationMatrix.BuildSWFStream(); 
				transformationMatrixLength = ((CSWFMorphShape*)pObject)->m_TransformationMatrix.GetSWFStreamLength(); 
			} 
			break; 
 
			case SWF_OBJECT_TYPE_BUTTON: 
			{ 
				pTransformationMatrix = ((CSWFButton*)pObject)->m_TransformationMatrix.BuildSWFStream(); 
				transformationMatrixLength = ((CSWFButton*)pObject)->m_TransformationMatrix.GetSWFStreamLength(); 
			} 
			break; 
 
			case SWF_OBJECT_TYPE_SPRITE: 
			{ 
				pTransformationMatrix = ((CSWFSprite*)pObject)->m_TransformationMatrix.BuildSWFStream(); 
				transformationMatrixLength = ((CSWFSprite*)pObject)->m_TransformationMatrix.GetSWFStreamLength(); 
			} 
			break; 
		} 
 
		// Get color transformation 
		CSWFColorTransform colorTranform(pColorTransform); 
		UCHAR* pColorTransformBuffer = colorTranform.BuildSWFStream(); 
		int colorTransformLength = colorTranform.GetSWFStreamLength(); 
 
		// Calculate tag length 
		placeObjectTag.Header.Length += sizeof(UCHAR);					// sizeof Flags 
		placeObjectTag.Header.Length += sizeof(USHORT);					// sizeof Depth 
		if (bInitialDisplay) 
			placeObjectTag.Header.Length += sizeof(USHORT);				// sizeof CharacterID 
		placeObjectTag.Header.Length += transformationMatrixLength;		// sizeof TransformationMatrix 
		if (pColorTransform != NULL) 
			placeObjectTag.Header.Length += colorTransformLength;		// sizeof ColorTransformation 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE) 
			placeObjectTag.Header.Length += sizeof(USHORT);				// sizeof Ratio 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE)			// sizeof Name 
		{ 
			if (nameLength != 0) 
				placeObjectTag.Header.Length += strlen((char*)((CSWFSprite*)pObject)->m_Name) + 1; 
		} 
 
		// Write PlaceObject2 tag 
		int newLength = m_SWFStreamLength + placeObjectTag.Header.Length + sizeof(SWF_RECORDHEADER_LONG); 
		if (m_SWFStreamLength == 0) 
			m_SWFStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
 
		// Write PlaceObject2 tag 
		newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG) + sizeof(UCHAR) + sizeof(USHORT); 
		memcpy(m_SWFStream+m_SWFStreamLength, &placeObjectTag.Header, sizeof(SWF_RECORDHEADER_LONG)); 
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(SWF_RECORDHEADER_LONG), &placeObjectTag.Flags, sizeof(UCHAR)); 
		memcpy(m_SWFStream+m_SWFStreamLength+sizeof(SWF_RECORDHEADER_LONG)+sizeof(UCHAR), &placeObjectTag.Depth, sizeof(USHORT)); 
		m_SWFStreamLength = newLength; 
 
		// Write CharacterID 
		if (bInitialDisplay) 
		{ 
			newLength = m_SWFStreamLength + sizeof(USHORT); 
			memcpy(m_SWFStream+m_SWFStreamLength, &placeObjectTag.CharacterID, sizeof(USHORT)); 
			m_SWFStreamLength = newLength; 
		} 
 
		// Write Matrix 
		newLength = m_SWFStreamLength + transformationMatrixLength; 
		memcpy(m_SWFStream+m_SWFStreamLength, pTransformationMatrix, transformationMatrixLength); 
		m_SWFStreamLength = newLength; 
 
		// Write ColorTransform 
		if (pColorTransform != NULL) 
		{ 
			newLength = m_SWFStreamLength + colorTransformLength; 
			memcpy(m_SWFStream+m_SWFStreamLength, pColorTransformBuffer, colorTransformLength); 
			m_SWFStreamLength = newLength; 
		} 
 
		// Write Ratio 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE) 
		{ 
			newLength = m_SWFStreamLength + sizeof(USHORT); 
			memcpy(m_SWFStream+m_SWFStreamLength, &ratio, sizeof(USHORT)); 
			m_SWFStreamLength = newLength; 
		} 
 
		// Write Name 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE) 
		{ 
			if (nameLength != 0) 
			{ 
				newLength = m_SWFStreamLength + nameLength; 
				memcpy(m_SWFStream+m_SWFStreamLength, ((CSWFSprite*)pObject)->m_Name, nameLength); 
				m_SWFStreamLength = newLength; 
			} 
		} 
	} 
} 
 
UCHAR* CSWFSprite::BuildSWFStream() 
{ 
	UCHAR* pTempBuffer = NULL; 
 
	if (m_SWFStreamLength != 0) 
	{ 
		pTempBuffer = new UCHAR[m_SWFStreamLength]; 
		memcpy(pTempBuffer, m_SWFStream, m_SWFStreamLength); 
	} 
 
	// Write DefineSprite tag 
	int newLength = m_SWFStreamLength + sizeof(SWF_DEFINE_SPRITE_TAG) + sizeof(USHORT); 
	if (m_SWFStreamLength == 0) 
		m_SWFStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength); 
 
	m_Sprite.Header.Length = m_SWFStreamLength + 3*sizeof(USHORT); 
 
	memcpy(m_SWFStream, &m_Sprite.Header, sizeof(SWF_RECORDHEADER_LONG)); 
	memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG), &m_Sprite.SpriteID, sizeof(USHORT)); 
	memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG)+sizeof(USHORT), &m_Sprite.FrameCount, sizeof(USHORT)); 
	if (m_SWFStreamLength != 0) 
		memcpy(m_SWFStream+sizeof(SWF_RECORDHEADER_LONG)+2*sizeof(USHORT), pTempBuffer, m_SWFStreamLength); 
	USHORT endTag = 0x0000; 
	memcpy(m_SWFStream+m_SWFStreamLength+sizeof(SWF_RECORDHEADER_LONG)+2*sizeof(USHORT), &endTag, sizeof(USHORT)); 
 
	if (m_SWFStreamLength != 0) 
		delete pTempBuffer; 
 
	m_SWFStreamLength = newLength; 
 
	return m_SWFStream; 
} 
 
int CSWFSprite::GetSWFStreamLength() 
{ 
	return m_SWFStreamLength; 
} 
 
void CSWFSprite::Scale(float scaleX, float scaleY) 
{ 
	MATRIX_F matrix; 
	m_TransformationMatrix.GetMatrix(matrix); 
 
	matrix.scaleX = scaleX; 
	matrix.scaleY = scaleY; 
 
	m_TransformationMatrix.SetMatrix(matrix); 
} 
 
void CSWFSprite::Rotate(float angle) 
{ 
	MATRIX_F matrix; 
	m_TransformationMatrix.GetMatrix(matrix); 
 
	if (((int)angle % 90) == 0) 
		angle += 0.05f; 
 
	double a = PI / 180; 
	matrix.scaleX = (float)cos(angle*a); 
	matrix.scaleY = (float)cos(angle*a); 
	matrix.rotateSkew0 = (float)sin(angle*a); 
	matrix.rotateSkew1 = -(float)sin(angle*a); 
 
	m_TransformationMatrix.SetMatrix(matrix); 
} 
 
void CSWFSprite::Translate(float translateX, float translateY) 
{ 
	MATRIX_F matrix; 
	m_TransformationMatrix.GetMatrix(matrix); 
 
	matrix.translateX = translateX; 
	matrix.translateY = translateY; 
 
	m_TransformationMatrix.SetMatrix(matrix); 
} 
 
void CSWFSprite::Shear(float shearX, float shearY) 
{ 
	MATRIX_F matrix; 
	m_TransformationMatrix.GetMatrix(matrix); 
 
	matrix.rotateSkew0 = shearX; 
	matrix.rotateSkew1 = shearY; 
 
	m_TransformationMatrix.SetMatrix(matrix); 
}