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);
}