tahoma2d/toonz/sources/common/flash/FAction.cpp

843 lines
19 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
// Copyright © 1999 Middlesoft, Inc. All rights reserved.
// First Created By Lee Thomason.
// First Created On 09/08/1999.
// Last Modified On 11/09/1999.
/****************************************************************************************
File Summary: FAction.cpp
This source file contains the definition for the low-level action-related functions,
grouped by classes, which are all derived from class FAction (except FActionCondition):
Class Member Function
FActionGetURL FActionGetURL(FString*, FString*);
~FActionGetURL();
void WriteToSWFStream(FSWFStream*);
FActionGetURL2 FActionGetURL2(U8);
void WriteToSWFStream(FSWFStream*);
FActionGotoFrame FActionGotoFrame(U16);
void WriteToSWFStream(FSWFStream*);
FActionGotoFrame2 FActionGotoFrame2(U8);
void WriteToSWFStream(FSWFStream*);
FActionGotoLabel FActionGotoLabel(FString*);
~FActionGotoLabel();
void WriteToSWFStream(FSWFStream*);
FActionIf FActionIf(S16);
void WriteToSWFStream(FSWFStream*);
FActionJump FActionJump(S16);
void WriteToSWFStream(FSWFStream*);
FActionPush FActionPush(FString*);
FActionPush(FLOAT);
void WriteToSWFStream(FSWFStream*);
FActionSetTarget FActionSetTarget(FString*);
~FActionSetTarget();
void WriteToSWFStream(FSWFStream*);
FActionWaitForFrame FActionWaitForFrame(U16, U16);
void WriteToSWFStream(FSWFStream*);
FActionWaitForFrame2 FActionWaitForFrame2(U8);
void WriteToSWFStream(FSWFStream*);
FActionCondition FActionCondition();
~FActionCondition();
Clear();
AddActionRecord(FActionRecord*);
AddKeyCode(U32);
AddCondition(U16);
void WriteToSWFStream(FSWFStream*);
void WriteToSWFStream(FSWFStream*, int);
Functions of these classes have not been implemented yet:
class FActionAdd;
class FActionAnd;
class FActionAsciiToChar;
class FActionCall;
class FActionCharToAscii;
class FActionCloneSprite;
class FActionDivide;
class FActionEndDrag;
class FActionEquals;
class FActionGetProperty;
class FActionGetTime;
class FActionGetVariable;
class FActionLess;
class FActionMBAsciiToChar;
class FActionMBCharToAscii;
class FActionMBStringExtract;
class FActionMBStringLength;
class FActionMultiply;
class FActionNextFrame;
class FActionNot;
class FActionOr;
class FActionPlay;
class FActionPop;
class FActionPrevFrame;
class FActionRandomNumber;
class FActionRemoveSprite;
class FActionSetProperty;
class FActionSetTarget2;
class FActionSetVariable;
class FActionStartDrag;
class FActionStop;
class FActionStopSounds;
class FActionStringAdd;
class FActionStringEquals;
class FActionStringExtract;
class FActionStringLength;
class FActionStringLess;
class FActionSubtract;
class FActionToggleQuality;
class FActionToInteger;
class FActionTrace.
****************************************************************************************/
#include "FPrimitive.h"
#include "FAction.h"
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionUnparsed ----------------------------------------------------------
FActionUnparsed::FActionUnparsed(UCHAR _code, USHORT _length, UCHAR *_data) : code(_code)
{
if (code >= 0x80)
length = _length, data = _data;
else
length = 0, data = 0;
}
void FActionUnparsed::WriteToSWFStream(FSWFStream *_SWFStream)
{
_SWFStream->WriteByte(code);
if (code >= 0x80) {
_SWFStream->WriteWord(length);
for (int i = 0; i < length; i++)
_SWFStream->WriteByte(data[i]);
}
}
//////////////////////////////////////////////////////////////////////////////////////
FActionGetURL::FActionGetURL(FString *_url, FString *_window)
{
url = _url;
window = _window;
}
FActionGetURL::~FActionGetURL()
{
delete url;
delete window;
}
void FActionGetURL::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream body;
url->WriteToSWFStream(&body, true);
window->WriteToSWFStream(&body, true);
_SWFStream->WriteByte(sactionGetURL);
_SWFStream->WriteWord(body.Size());
_SWFStream->Append(&body);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionGetURL2 ---------------------------------------------------------
FActionGetURL2::FActionGetURL2(U8 _method)
{
method = _method;
}
void FActionGetURL2::WriteToSWFStream(FSWFStream *_SWFStream)
{
//sactionEquals: enumerated in "Macromedia.h"
_SWFStream->WriteByte(sactionGetURL2);
//write the length since the high bit is set in the action tag
_SWFStream->WriteWord(1);
//write the method
_SWFStream->WriteByte(method);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionGotoFrame -------------------------------------------------------
FActionGotoFrame::FActionGotoFrame(U16 _frameIndex)
{
frameIndex = _frameIndex;
}
void FActionGotoFrame::WriteToSWFStream(FSWFStream *_SWFStream)
{
//enumerated constant (see "Macromedia.h")
_SWFStream->WriteByte(sactionGotoFrame);
_SWFStream->WriteWord(2);
_SWFStream->WriteWord((U32)frameIndex);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionGotoFrame2 ------------------------------------------------------
// Constructor takes in play flag.
FActionGotoFrame2::FActionGotoFrame2(U8 _play)
{
play = _play;
}
void FActionGotoFrame2::WriteToSWFStream(FSWFStream *_SWFStream)
{
//sactionGotoFrame2: enumerated in "Macromedia.h"
_SWFStream->WriteByte(sactionGotoFrame2);
//write the length since the high bit is set in the action tag
_SWFStream->WriteWord(1);
//write the play flag
_SWFStream->WriteByte(play);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionGotoLabel -------------------------------------------------------
FActionGotoLabel::FActionGotoLabel(FString *_label)
{
label = _label;
}
FActionGotoLabel::~FActionGotoLabel()
{
delete label;
}
void FActionGotoLabel::WriteToSWFStream(FSWFStream *_SWFStream)
{
//enumerated type (see "Macromedia.h")
_SWFStream->WriteByte(sactionGotoLabel);
label->WriteToSWFStream(_SWFStream, true);
}
///////////////////////////////////////////////////////////////////////////////
// -------- FActionIf -------------------------------------------------------
// Constructor records the branch offset.
FActionIf::FActionIf(S16 _branchOffset)
{
branchOffset = _branchOffset;
}
void FActionIf::WriteToSWFStream(FSWFStream *_SWFStream)
{
//enumerations in "Macromedia.h"
_SWFStream->WriteByte(sactionIf);
//write the length since the high bit is set in the action tag
_SWFStream->WriteWord(2);
//write the offset
_SWFStream->WriteWord((U32)branchOffset);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionJump -------------------------------------------------------
// Constructor records the branch offset.
FActionJump::FActionJump(S16 _branchOffset)
{
branchOffset = _branchOffset;
}
void FActionJump::WriteToSWFStream(FSWFStream *_SWFStream)
{
//enumerations in "Macromedia.h"
_SWFStream->WriteByte(sactionJump);
//write the length since the high bit is set in the action tag
_SWFStream->WriteWord(2);
//write the offset
_SWFStream->WriteWord((U32)branchOffset);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionPush -------------------------------------------------------
// Constructor for string push.
FActionPush::FActionPush(FString *_string)
{
string = _string;
number = 0;
cValue = 0;
dValue = 0;
type = 0;
}
FActionPush::FActionPush(FLOAT _number)
{
number = _number;
string = 0;
cValue = 0;
dValue = 0;
type = 1;
}
// Constructor for float push.
FActionPush::FActionPush(U8 _type, FLOAT _number)
{
number = _number;
string = 0;
cValue = 0;
dValue = 0;
type = _type;
}
FActionPush::FActionPush(double _number)
{
number = 0;
string = 0;
cValue = 0;
dValue = _number;
type = 6;
}
FActionPush::FActionPush(U8 _type, U8 _value)
{
number = 0;
string = 0;
cValue = _value;
dValue = 0;
type = _type;
}
void FActionPush::WriteToSWFStream(FSWFStream *_SWFStream)
{
//sactionPush: enumerated in "Macromedia.h"
_SWFStream->WriteByte(sactionPush);
U16 size = 0;
FSWFStream temp;
// un byte c'e' sempre per memorizzare il tipo
switch (type) {
case 0:
size = 1 + string->Length() + 1; //bisogna tener conto che la deve essere null terminated
string->WriteToSWFStream(&temp, true);
break;
case 1:
case 7:
size = 5;
temp.WriteDWord((U32)number);
break;
case 4:
case 5:
case 8:
size = 2;
temp.WriteByte(cValue);
break;
case 6: {
size = 9;
U8 *bPtr = (U8 *)&dValue;
#ifndef __LP64__
temp.WriteByte((U32)(bPtr + 4));
temp.WriteByte((U32)(bPtr + 5));
temp.WriteByte((U32)(bPtr + 6));
temp.WriteByte((U32)(bPtr + 7));
temp.WriteByte((U32)bPtr);
temp.WriteByte((U32)(bPtr + 1));
temp.WriteByte((U32)(bPtr + 2));
temp.WriteByte((U32)(bPtr + 3));
#else
typedef unsigned long U64;
temp.WriteByte((U64)(bPtr + 4));
temp.WriteByte((U64)(bPtr + 5));
temp.WriteByte((U64)(bPtr + 6));
temp.WriteByte((U64)(bPtr + 7));
temp.WriteByte((U64)bPtr);
temp.WriteByte((U64)(bPtr + 1));
temp.WriteByte((U64)(bPtr + 2));
temp.WriteByte((U64)(bPtr + 3));
#endif
break;
}
default:
break;
}
_SWFStream->WriteWord(size);
//write the type
_SWFStream->WriteByte((U32)type);
//write the object to be pushed
_SWFStream->Append(&temp);
}
/*//originale
// Writes to the given FSWFStream.
void FActionPush::WriteToSWFStream(FSWFStream *_SWFStream){
//sactionPush: enumerated in "Macromedia.h"
_SWFStream->WriteByte(sactionPush);
// un byte c'e' sempre per memorizzare il tipo
//since tag's high bit is set, must write the length
if ( type == 0 ) {
_SWFStream->WriteWord( 1 + (U32)string->Length() + 1); //bisogna tener conto che la deve essere null terminated
} else {
_SWFStream->WriteWord( 1 + 4 ); //scrive una Dword => 4 bytes
}
//write the type
_SWFStream->WriteByte((U32)type);
//write the object to be pushed
if ( type == 0 ) {
string->WriteToSWFStream(_SWFStream, true);
} else {
_SWFStream->WriteDWord( (U32)number );
}
}
*/
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionSetTarget -------------------------------------------------------
FActionSetTarget::FActionSetTarget(FString *_targetName)
{
targetName = _targetName;
}
FActionSetTarget::~FActionSetTarget()
{
delete targetName;
}
void FActionSetTarget::WriteToSWFStream(FSWFStream *_SWFStream)
{
_SWFStream->WriteByte(sactionSetTarget);
_SWFStream->WriteWord(targetName->Length() + 1);
targetName->WriteToSWFStream(_SWFStream, true);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FActionWaitForFrame ----------------------------------------------------
FActionWaitForFrame::FActionWaitForFrame(U16 index, U16 count)
{
// frameIndex = frameIndex;
// skipCount = skipCount;
frameIndex = index; // fixed from DV
skipCount = count;
}
void FActionWaitForFrame::WriteToSWFStream(FSWFStream *_SWFStream)
{
// enumerations in "Macromedia.h"
_SWFStream->WriteByte(sactionWaitForFrame);
_SWFStream->WriteWord(3);
_SWFStream->WriteWord((U32)frameIndex);
_SWFStream->WriteByte((U32)skipCount);
}
///////////////////////////////////////////////////////////////////////////////////////
// -------- FActionWaitForFrame2 ----------------------------------------------------
FActionWaitForFrame2::FActionWaitForFrame2(U8 _skipCount)
{
skipCount = _skipCount;
}
void FActionWaitForFrame2::WriteToSWFStream(FSWFStream *_SWFStream)
{
// enumerations in "Macromedia.h"
_SWFStream->WriteByte(sactionWaitForFrame2);
//write the length since high bit in tag id is set
_SWFStream->WriteWord(1);
//write the skip count
_SWFStream->WriteByte(skipCount);
}
// Constructor. Initially, there are no actions or conditions so the conditions flag
// equals zero, and the action record list is empty.
FActionCondition::FActionCondition()
{
conditionFlags = 0;
}
// Deletes all of the action records in the action record list.
FActionCondition::~FActionCondition()
{
while (!actionRecordList.empty()) {
delete actionRecordList.front();
actionRecordList.pop_front();
}
}
void FActionCondition::Clear()
{
while (!actionRecordList.empty()) {
delete actionRecordList.front();
actionRecordList.pop_front();
}
}
// Adds an action record to the action record list
void FActionCondition::AddActionRecord(FActionRecord *_ActionRecord)
{
actionRecordList.push_back(_ActionRecord);
}
// Adds the key code information to the action condition (Flash 4).
void FActionCondition::AddKeyCode(U32 keyCode)
{
conditionFlags |= (keyCode << 9);
}
// Adds a condition to the list of conditions for which the actions in the action record list
// will be taken. Sees what condition is passed, and sets the bit which corresponds to the
// condition in the conditionFlags field to 1.
void FActionCondition::AddCondition(U16 _condition)
{
switch (_condition)
{
case OverDownToIdle:
conditionFlags = conditionFlags | 256; //this bitwise OR has the same effect as making the 8th bit a "1"
break;
case IdleToOverDown:
conditionFlags = conditionFlags | 128; //makes 9th bit a "1" ... etc.
break;
case OutDownToIdle:
conditionFlags = conditionFlags | 64;
break;
case OutDownToOverDown:
conditionFlags = conditionFlags | 32;
break;
case OverDownToOutDown:
conditionFlags = conditionFlags | 16;
break;
case OverDownToOverUp:
conditionFlags = conditionFlags | 8;
break;
case OverUpToOverDown:
conditionFlags = conditionFlags | 4;
break;
case OverUpToIdle:
conditionFlags = conditionFlags | 2;
break;
case IdleToOverUp:
conditionFlags = conditionFlags | 1;
}
}
// Writes the action condition to the given FSWFStream. Since the action condition contains
// an offset field to the next action condition, the body of the action condition must first
// be written to a temporary stream so that size can be calculated for the offset.
void FActionCondition::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream temp;
temp.WriteWord((U32)conditionFlags);
int boh = temp.Size();
std::list<FActionRecord *>::iterator cursor;
for (cursor = actionRecordList.begin(); cursor != actionRecordList.end(); cursor++) {
(*cursor)->WriteToSWFStream(&temp);
boh = temp.Size();
}
//add 2 to the size because the offset is actually to the beginning of the
//next action condition's conditionFlags
_SWFStream->WriteWord(2 + temp.Size());
_SWFStream->Append(&temp);
}
// Writes the action condition to the given stream. The lastFlag indicates that this is the
// last action condition so the offset is set to 0 by default.
void FActionCondition::WriteToSWFStream(FSWFStream *_SWFStream, int /*lastFlag*/)
{
_SWFStream->WriteWord(0); //the offset
_SWFStream->WriteWord((U32)conditionFlags);
std::list<FActionRecord *>::iterator cursor;
for (cursor = actionRecordList.begin(); cursor != actionRecordList.end(); cursor++) {
(*cursor)->WriteToSWFStream(_SWFStream);
}
//_SWFStream->FlushBits();
_SWFStream->WriteByte((U32)0);
}
/*
FActionConditionList::FActionConditionList(){
}
FActionConditionList::~FActionConditionList(){
while (!conditionList.empty()){
delete conditionList.front();
conditionList.pop_front();
}
}
void FActionConditionList::AddActionCondition(FActionCondition* _ActionCondition){
conditionList.push_back(_ActionCondition);
}
U32 FActionConditionList::Size(){
return conditionList.size();
}
void FActionConditionList::WriteToSWFStream(FSWFStream* _SWFStream){
std::list<FActionCondition*>::iterator cursor;
std::list<FActionCondition*>::iterator cursor2;
cursor2 = (conditionList.end());
cursor2--;
for (cursor = conditionList.begin(); cursor != cursor2; cursor++) {
(*cursor)->WriteToSWFStream(_SWFStream);
}
(*cursor)->WriteToSWFStream(_SWFStream, 1); //flag indicating it is the last action condition
}
*/
//=============================================================================
// ALCUNE AZIONI FLASH 5
//=============================================================================
FActionConstantPool::FActionConstantPool(FString *string)
{
constantList.push_back(string);
}
FActionConstantPool::~FActionConstantPool()
{
while (!constantList.empty()) {
delete constantList.front();
constantList.pop_front();
}
}
void FActionConstantPool::addConstant(FString *string)
{
constantList.push_back(string);
}
void FActionConstantPool::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream temp;
std::list<FString *>::iterator it = constantList.begin();
while (it != constantList.end()) {
(*it)->WriteToSWFStream(&temp, true);
++it;
}
_SWFStream->WriteByte(sactionConstantPool);
_SWFStream->WriteWord(temp.FullSize() + 2);
_SWFStream->WriteWord(constantList.size());
_SWFStream->Append(&temp);
}
//=============================================================================
// CLIP ACTION / CLIP ACTION RECORD
//=============================================================================
FClipAction::FClipAction()
{
eventFlags = 0;
}
FClipAction::~FClipAction()
{
Clear();
}
void FClipAction::Clear()
{
while (!clipActionRecordList.empty()) {
delete clipActionRecordList.front();
clipActionRecordList.pop_front();
}
}
void FClipAction::AddClipActionRecord(FClipActionRecord *_clipActionRecord)
{
clipActionRecordList.push_back(_clipActionRecord);
}
void FClipAction::AddFlags(U32 _flags)
{
//e' meglio definire i flags come enumerazione che sono gia' i valori da
// mettere in OR per settare l'abilitazione del particolare evento
eventFlags |= _flags;
}
void FClipAction::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream temp;
//Reserved
temp.WriteWord(0);
//allEvent
temp.WriteDWord(eventFlags);
//tutti i clip
std::list<FClipActionRecord *>::iterator it = clipActionRecordList.begin();
int i = 0;
while (it != clipActionRecordList.end()) {
(*it)->WriteToSWFStream(&temp); //, i);//prova zozza
++it;
++i;
}
//end clipAction
temp.WriteDWord(0);
_SWFStream->Append(&temp);
}
//=============================================================================
FClipActionRecord::FClipActionRecord()
{
eventFlags = 0;
keyCode = 0;
}
FClipActionRecord::~FClipActionRecord()
{
Clear();
}
void FClipActionRecord::Clear()
{
while (!actionRecordList.empty()) {
delete actionRecordList.front();
actionRecordList.pop_front();
}
}
void FClipActionRecord::AddActionRecord(FActionRecord *_actionRecord)
{
actionRecordList.push_back(_actionRecord);
}
void FClipActionRecord::AddKeyCode(U8 _keyCode)
{
keyCode |= _keyCode;
}
void FClipActionRecord::AddFlags(U32 _flags)
{
//e' meglio definire i flags come enumerazione che sono gia' i valori da
// mettere in OR per settare l'abilitazione del particolare evento
eventFlags |= _flags;
}
void FClipActionRecord::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream temp;
//metto tutte le azioni su per sapere la size
std::list<FActionRecord *>::iterator it = actionRecordList.begin();
while (it != actionRecordList.end()) {
(*it)->WriteToSWFStream(&temp);
++it;
}
temp.WriteByte(sactionNone);
//e' un offset deve andare a quello dopo
U32 size = temp.FullSize();
FSWFStream temp1;
temp1.WriteDWord(eventFlags);
if ((eventFlags & ClipEventKeyPress) == ClipEventKeyPress) {
temp1.WriteDWord(size + 1);
temp1.WriteByte(keyCode);
} else
temp1.WriteDWord(size);
temp1.Append(&temp);
_SWFStream->Append(&temp1);
}