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


// SWFMovie.cpp: implementation of the CSWFMovie class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "SWFMovie.h" 
 
 
CSWFMovie::CSWFMovie() 
{ 
	// Init .SWF file header struct 
	strcpy((char*)m_SWFHeader.Signature, "FWS"); 
	m_SWFHeader.Version = SWF_FILE_VERSION; 
	m_SWFHeader.FileLength = 0; 
	RECT_F rectangle = {0, 0, SWF_MOVIE_WIDHT, SWF_MOVIE_HEIGHT}; 
	m_SWFMovieRectangle.SetRectangle(rectangle); 
	m_SWFHeader.FrameRate = 0x0C00; 
	m_SWFHeader.FrameCount = 0; 
 
	// Init .SWF file descriptor 
	m_SWFFile = NULL; 
 
	// Init .SWF file stream 
	m_SWFFileStream = NULL; 
	m_SWFFileStreamLength = 0; 
} 
 
CSWFMovie::~CSWFMovie() 
{ 
	if (m_SWFFileStream != NULL) 
	{ 
		free(m_SWFFileStream); 
		m_SWFFileStreamLength = NULL; 
	} 
} 
 
BOOL CSWFMovie::OpenSWFFile(LPTSTR filename, SIZE_F movieSize, int frameRate) 
{ 
	BOOL bResult = TRUE; 
 
	if (m_SWFFile == NULL) 
	{ 
		// Open new .SWF file 
		m_SWFFile = fopen(filename, "wb"); 
		strcpy(m_SWFFileName, filename); 
 
		if (m_SWFFile == NULL) 
			bResult = FALSE; 
		else 
		{ 
			// Set movie info 
			RECT_F rectangle = {0, 0, movieSize.cx, movieSize.cy}; 
			m_SWFMovieRectangle.SetRectangle(rectangle); 
			m_SWFHeader.FrameRate = MAKEWORD(0, frameRate); 
		} 
	} 
	else 
		bResult = FALSE; 
 
	return bResult; 
} 
 
void CSWFMovie::CloseSWFFile() 
{ 
	// Close .SWF file 
	if (m_SWFFile) 
	{ 
		// Go to the beginning of the .SWF file 
		fseek(m_SWFFile, 0, SEEK_SET); 
 
		// Write SWF_FILE_HEADER struct to the file 
		WriteSWFHeaderAndStream(); 
 
		// Go to the end of the .SWF file 
		fseek(m_SWFFile, 0, SEEK_END); 
 
		// Write End tag 
		USHORT endTag = 0x0000; 
		fwrite(&endTag, sizeof(USHORT), 1, m_SWFFile); 
		 
		fclose(m_SWFFile); 
		m_SWFFile = NULL; 
	} 
} 
 
void CSWFMovie::WriteSWFHeaderAndStream() 
{ 
	// Check if file is opened 
	if (m_SWFFile) 
	{ 
		// Check if .SWF file is closing 
		UCHAR* pBuffer = m_SWFMovieRectangle.BuildSWFStream(); 
		int numBytes = m_SWFMovieRectangle.GetSWFStreamLength(); 
			 
		// Calculate total file size 
		m_SWFHeader.FileLength = m_SWFFileStreamLength; 
		m_SWFHeader.FileLength += sizeof(SWF_FILE_HEADER);			// .SWF file header size 
		m_SWFHeader.FileLength += numBytes;							// Additional header size 
		m_SWFHeader.FileLength += sizeof(USHORT);					// .SWF End tag size 
 
		// Write .SWF file header 
		fwrite(m_SWFHeader.Signature, sizeof(UCHAR), 3, m_SWFFile); 
		fwrite(&m_SWFHeader.Version, sizeof(UCHAR), 1, m_SWFFile); 
		fwrite(&m_SWFHeader.FileLength, sizeof(UINT), 1, m_SWFFile); 
		fwrite(pBuffer, sizeof(UCHAR), numBytes, m_SWFFile); 
		fwrite(&m_SWFHeader.FrameRate, sizeof(USHORT), 1, m_SWFFile); 
		fwrite(&m_SWFHeader.FrameCount, sizeof(USHORT), 1, m_SWFFile); 
 
		// Write .SWF file stream 
		fwrite(m_SWFFileStream, sizeof(UCHAR), m_SWFFileStreamLength, m_SWFFile); 
	} 
} 
 
void CSWFMovie::SetBackgroundColor(SWF_RGB bgColor) 
{ 
	// SetBackgroundColor tag 
	SWF_BGCOLOR bgColorTag; 
	bgColorTag.Header.TagCodeAndLength = 9; 
	bgColorTag.Header.TagCodeAndLength = (bgColorTag.Header.TagCodeAndLength << 6) | 3; 
	memcpy(&bgColorTag.BackgroundColor, &bgColor, sizeof(SWF_RGB)); 
 
	// Modify total .SWF file size 
	int newLength = m_SWFFileStreamLength + sizeof(SWF_BGCOLOR); 
 
	// Write SetBackgroundColor tag 
	if (m_SWFFileStreamLength == 0) 
		m_SWFFileStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &bgColorTag, sizeof(SWF_BGCOLOR)); 
	m_SWFFileStreamLength = newLength; 
} 
 
void CSWFMovie::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_SWFFileStreamLength + sizeof(SWF_RECORDHEADER_LONG) + frameLabelLength; 
 
	// Write FrameLabel tag 
	if (m_SWFFileStreamLength == 0) 
		m_SWFFileStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &FrameLabelTag, sizeof(SWF_RECORDHEADER_LONG)); 
	memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG), frameLabel, frameLabelLength); 
	m_SWFFileStreamLength = newLength; 
} 
 
void CSWFMovie::ShowFrame() 
{ 
	// ShowFrame tag 
	USHORT showFrameTage = 0x0040; 
 
	// Modify total .SWF file size 
	int newLength = m_SWFFileStreamLength + sizeof(USHORT); 
 
	// Write ShowFrame tag 
	if (m_SWFFileStreamLength == 0) 
		m_SWFFileStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &showFrameTage, sizeof(USHORT)); 
	m_SWFFileStreamLength = newLength; 
 
	// Increment frame counter 
	m_SWFHeader.FrameCount++; 
} 
 
void CSWFMovie::TriggerAction(CSWFAction* pAction) 
{ 
	// Write DoAction tag to .SWF stream 
	if (pAction != NULL) 
	{ 
		UCHAR* pBuffer = pAction->BuildSWFStream(); 
 
		// Modify total .SWF file size 
		int newLength = m_SWFFileStreamLength + pAction->GetSWFStreamLength(); 
 
		// Write DefineShape tag 
		if (m_SWFFileStreamLength == 0) 
			m_SWFFileStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pBuffer, pAction->GetSWFStreamLength()); 
		m_SWFFileStreamLength = newLength; 
	} 
} 
 
void CSWFMovie::DefineObject(CSWFObject* pObject, int depth, bool bShow) 
{ 
	if (pObject != NULL) 
	{ 
		// Get sprite SWF stream 
		UCHAR* pBuffer = pObject->BuildSWFStream(); 
		int objectLength = pObject->GetSWFStreamLength(); 
 
		int newLength = m_SWFFileStreamLength + objectLength; 
		if (m_SWFFileStreamLength == 0) 
			m_SWFFileStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pBuffer, objectLength); 
		m_SWFFileStreamLength = newLength; 
 
		// Initial display object 
		if ((bShow) && (pObject->m_ObjectType != SWF_OBJECT_TYPE_BITMAP)) 
			DisplayObject(pObject, depth, TRUE, NULL, -1); 
	} 
} 
 
void CSWFMovie::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 CSWFMovie::UpdateObject(CSWFObject* pObject, int depth, SWF_COLOR_TRANSFORM* pColorTransform, int ratio) 
{ 
	if (pObject != NULL) 
	{ 
		// Display object 
		DisplayObject(pObject, depth, FALSE, pColorTransform, ratio); 
	} 
} 
 
void CSWFMovie::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_SWFFileStreamLength + (removeObjectTag.Header.Length-2) + sizeof(SWF_REMOVE_OBJECT2_TAG); 
	if (m_SWFFileStreamLength == 0) 
		m_SWFFileStream = (BYTE*)malloc(newLength); 
	else 
		m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
	memcpy(m_SWFFileStream+m_SWFFileStreamLength, &removeObjectTag, sizeof(SWF_REMOVE_OBJECT2_TAG)); 
	m_SWFFileStreamLength = newLength; 
} 
 
void CSWFMovie::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_SWFFileStreamLength + placeObjectTag.Header.Length + sizeof(SWF_RECORDHEADER_LONG); 
		if (m_SWFFileStreamLength == 0) 
			m_SWFFileStream = (BYTE*)malloc(newLength); 
		else 
			m_SWFFileStream = (BYTE*)realloc(m_SWFFileStream, newLength); 
 
		// Write PlaceObject2 tag 
		newLength = m_SWFFileStreamLength + sizeof(SWF_RECORDHEADER_LONG) + sizeof(UCHAR) + sizeof(USHORT); 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, &placeObjectTag.Header, sizeof(SWF_RECORDHEADER_LONG)); 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG), &placeObjectTag.Flags, sizeof(UCHAR)); 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength+sizeof(SWF_RECORDHEADER_LONG)+sizeof(UCHAR), &placeObjectTag.Depth, sizeof(USHORT)); 
		m_SWFFileStreamLength = newLength; 
 
		// Write CharacterID 
		if (bInitialDisplay) 
		{ 
			newLength = m_SWFFileStreamLength + sizeof(USHORT); 
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, &placeObjectTag.CharacterID, sizeof(USHORT)); 
			m_SWFFileStreamLength = newLength; 
		} 
 
		// Write Matrix 
		newLength = m_SWFFileStreamLength + transformationMatrixLength; 
		memcpy(m_SWFFileStream+m_SWFFileStreamLength, pTransformationMatrix, transformationMatrixLength); 
		m_SWFFileStreamLength = newLength; 
 
		// Write ColorTransform 
		if (pColorTransform != NULL) 
		{ 
			newLength = m_SWFFileStreamLength + colorTransformLength; 
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, pColorTransformBuffer, colorTransformLength); 
			m_SWFFileStreamLength = newLength; 
		} 
 
		// Write Ratio 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_MORPH_SHAPE) 
		{ 
			newLength = m_SWFFileStreamLength + sizeof(USHORT); 
			memcpy(m_SWFFileStream+m_SWFFileStreamLength, &ratio, sizeof(USHORT)); 
			m_SWFFileStreamLength = newLength; 
		} 
 
		// Write Name 
		if (pObject->m_ObjectType == SWF_OBJECT_TYPE_SPRITE) 
		{ 
			if (nameLength != 0) 
			{ 
				newLength = m_SWFFileStreamLength + nameLength; 
				memcpy(m_SWFFileStream+m_SWFFileStreamLength, ((CSWFSprite*)pObject)->m_Name, nameLength); 
				m_SWFFileStreamLength = newLength; 
			} 
		} 
	} 
}