/*
* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Binary output.
*
*/
#include <wchar.h>
#include <sys/time.h>
#include <unistd.h>
#include <cstdlib>
#include <string>
#include "SDCGlobals.h"
#include "SDCBinOutput.h"
#include "aknsconstants.hrh"
#include "SDCException.h"
#include "SDCCompat.h"
// Make std namespace available for compatibility
namespace std {}
using namespace std;
// CLASS DECLARATION
class TPos
{
public:
TPos( CSDCBinOutput* aBinOutput )
{
iPosition = aBinOutput->iOutputPos;
}
void Go( CSDCBinOutput* aBinOutput )
{
iOriginalPosition = aBinOutput->iOutputPos;
aBinOutput->iOutputPos = iPosition;
}
void Back( CSDCBinOutput* aBinOutput )
{
aBinOutput->iOutputPos = iOriginalPosition;
}
int BackwardsDelta()
{
return iOriginalPosition-iPosition;
}
public:
int iPosition;
int iOriginalPosition;
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSDCBinOutput::CSDCBinOutput()
{
iOutputPos = 0;
}
CSDCBinOutput::~CSDCBinOutput()
{
}
//////////////////////////////////////////////////////////////////////
// Other methods
//////////////////////////////////////////////////////////////////////
void CSDCBinOutput::Output( CSDCData* aData, const char* aBaseName, const char* aBinFilename, const bool aStubOnly )
{
iData = aData;
strcpy( iBaseName, aBaseName );
PrepareSkinDescriptor( aStubOnly );
if( iOutputPos != static_cast<int>( iOutputVector.size() ) ) throw CSDCException( ESDCUnknownError, "Internal binary output size does not match" );
FILE* file = fopen( aBinFilename, "wb" );
if( !file ) throw CSDCException( ESDCFileOpenError, "Can not open target binary file for writing" );
unsigned int i;
for( i=0; i<iOutputVector.size(); i++ )
{
fputc( iOutputVector[i], file );
}
fclose( file );
}
void CSDCBinOutput::PrepareSkinDescriptor( const bool aStubOnly )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 0 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 3*4 + 1*2 + 2*4 );
WriteInt( iData->iPid.iPID1 ); // SkinPID1
WriteInt( iData->iPid.iPID2 ); // SkinPID2
WriteInt( 0 ); // SkinCF
WriteUint16( (unsigned short int)iData->iSkinType ); // SkinType
WriteInt( iData->iPalettePid.iPID1 ); // ColorSchemePID1
WriteInt( iData->iPalettePid.iPID2 ); // ColorSchemePID2
AppendBytes( 1*1 ); // Protection
if( iData->iProtection == 1 )
{
WriteByte( 0x01 );
}
else
{
WriteByte( 0x00 );
}
AppendBytes( 1*1 ); // ContentFlags
if( (iData->iAppIconDefVector.size()>0) && (!iData->IsScalable()) )
{
WriteByte( 1 );
}
else
{
WriteByte( 0 );
}
AppendBytes( 1*2 + 1*4 );
WriteUint16( 0 ); // Reserved2
WriteInt( 0 ); // Reserved3
int chunksN = 0;
AppendBytes( 1*4 );
TPos chunksNPos( this );
WriteInt( 0 ); // ChunksN
PrepareInformation();
chunksN++;
unsigned int i;
for( i=0; i<iData->iTargetDeviceVector.size(); i++ )
{
TSDCTargetDeviceEntry* entry = iData->iTargetDeviceVector[i];
PrepareTargetDevice( entry->iDeviceName );
chunksN++;
}
for( i=0; i<iData->iNameVector.size(); i++ )
{
TSDCNameEntry* entry = iData->iNameVector[i];
PrepareName( entry->iLanguageID, entry->iName );
chunksN++;
}
if( (iData->iAHOverridePid.iPID1!=0) && (iData->iAHOverridePid.iPID2!=0) )
{
PrepareLanguageOverride( 0x01, iData->iAHOverridePid );
chunksN++;
}
if( !iData->IsScalable() )
{
for( i=0; i<iData->iBitmapDefVector.size(); i++ )
{
TSDCBitmapDef* entry = iData->iBitmapDefVector[i];
if( (entry->iIID.iMajor == EAknsMajorSkin) &&
(entry->iIID.iMinor == EAknsMinorWallpaper) )
{
PrepareWallpaper( 0x00, entry );
chunksN++;
PrepareWallpaper( 0x01, entry );
chunksN++;
}
if( (entry->iIID.iMajor == EAknsMajorPinboard) &&
(entry->iIID.iMinor == EAknsMinorQsnFrPinbCenterWp) )
{
PrepareWallpaper( 0x02, entry );
chunksN++;
}
}
}
if( !aStubOnly )
{
char buf[512];
strcpy( buf, iBaseName );
strcat( buf, ".mbm" );
PrepareFilename( 0, buf );
chunksN++;
if( iData->IsScalable() )
{
strcpy( buf, iBaseName );
strcat( buf, ".mif" );
PrepareFilename( 1, buf );
chunksN++;
}
PrepareNormalClass( 0 );
chunksN++;
if( !iData->IsScalable() )
{
PrepareAppIconClass();
chunksN++;
}
// Release 2.6 specifics
PrepareEncapsulatedNormalClass( 0x0206 );
chunksN++;
// Release 2.7 specifics
PrepareEncapsulatedNormalClass( 0x0207 );
chunksN++;
// Release 2.8 specifics
PrepareEncapsulatedNormalClass( 0x0208 );
chunksN++;
// Release 3.0 specifics
PrepareEncapsulatedNormalClass( 0x0300 );
chunksN++;
// Non-mirrored
PrepareEncapsulatedNormalClass( 0x00010000 );
chunksN++;
// Mirrored
PrepareEncapsulatedNormalClass( 0x00020000 );
chunksN++;
for (unsigned int count = 0;count < iData->iLanguageVector.size(); count++)
{
// Language
PrepareEncapsulatedNormalClass( iData->iLanguageVector[count] );
chunksN++;
}
}
chunksNPos.Go( this );
WriteInt( chunksN );
chunksNPos.Back( this );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareTargetDevice( const wchar_t* aDeviceName )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 14 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*2 );
WriteUint16( wcslen( aDeviceName ) );
for( unsigned int i=0; i<wcslen( aDeviceName ); i++ )
{
AppendBytes( 2 );
WriteUint16( aDeviceName[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareName( const short int aLanguage, const wchar_t* aName )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 1 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*2 );
WriteInt16( aLanguage );
WriteUint16( wcslen( aName ) );
for( unsigned int i=0; i<wcslen( aName ); i++ )
{
AppendBytes( 2 );
WriteUint16( aName[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareInformation()
{
TPos startPos( this );
unsigned int i;
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 11 ); // Type
WriteUint16( 2 ); // Version
AppendBytes( 2*4 );
struct timeval sysTime;
gettimeofday( &sysTime, NULL);
// 100-nanosecond
unsigned long long currentTime;
// get the 100-nanosecond number at time of UTC
currentTime = ( sysTime.tv_usec + mktime(gmtime(&sysTime.tv_sec)) * SEC_TO_USEC ) * USEC_TO_100NANOSEC;
unsigned int highPart = static_cast<unsigned int>((currentTime >> 32) );
unsigned int lowPart = static_cast<unsigned int>( currentTime );
WriteInt( highPart );
WriteInt( lowPart );
AppendBytes( 2*4 );
WriteInt( (gVersionMajor<<16) | gVersionMinor );
WriteInt( 0 );
AppendBytes( 1*2 );
WriteUint16( wcslen( iData->iAuthor ) );
for( i=0; i<wcslen( iData->iAuthor ); i++ )
{
AppendBytes( 2 );
WriteUint16( iData->iAuthor[i] );
}
AppendBytes( 1*2 );
WriteUint16( wcslen( iData->iCopyright ) );
for( i=0; i<wcslen( iData->iCopyright ); i++ )
{
AppendBytes( 2 );
WriteUint16( iData->iCopyright[i] );
}
AppendBytes( 2*1 );
WriteByte( gPlatformMajor );
WriteByte( gPlatformMinor );
AppendBytes( 1*2 );
WriteUint16( wcslen( iData->iTool ) );
for( i=0; i<wcslen( iData->iTool ); i++ )
{
AppendBytes( 2 );
WriteUint16( iData->iTool[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareLanguageOverride( const unsigned char aOverrideType, const TSDCPID aOverridePid )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 9 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*1 + 2*4 );
WriteByte( aOverrideType );
WriteInt( aOverridePid.iPID1 );
WriteInt( aOverridePid.iPID2 );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareWallpaper( const unsigned char aWpType, const TSDCBitmapDef* aBitmapDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 10 ); // Type
WriteUint16( 1 ); // Version
char buf[512];
strcpy( buf, iBaseName );
strcat( buf, ".mbm" );
AppendBytes( 1*1 + 1*2 );
WriteByte( aWpType );
WriteUint16( strlen( buf ) );
for( unsigned int i=0; i<strlen( buf ); i++ )
{
AppendBytes( 2 );
WriteUint16( (short int)buf[i] );
}
AppendBytes( 1*4 );
WriteInt( aBitmapDef->iMBMIndex );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareFilename( const int aId, const char* aFilename )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 2 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*4 + 1*2 );
WriteInt( aId );
WriteUint16( strlen( aFilename ) );
for( unsigned int i=0; i<strlen( aFilename ); i++ )
{
AppendBytes( 2 );
WriteUint16( (short int)aFilename[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareEncapsulatedNormalClass( const int aRestriction )
{
TPos restStartPos( this );
if( aRestriction )
{
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
if( aRestriction==0x0206 )
{
// 2.6 release restriction
WriteUint16( 13 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*1 );
WriteByte( (aRestriction&0xff00) >> 8 ); // PlatformMajor
WriteByte( aRestriction&0xff ); // PlatformMinor
}
else if( aRestriction<0x0010000 )
{
// Only generic release restriction
WriteUint16( 18 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*1 );
WriteByte( (aRestriction&0xff00) >> 8 ); // PlatformMajor
WriteByte( aRestriction&0xff ); // PlatformMinor
AppendBytes( 2*4 );
WriteInt( 0 ); // Reserved1
WriteInt( 0 ); // Reserved2
}
else if (aRestriction>=0x30000)
{
// language restriction
WriteUint16( 15 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*2 );
WriteUint16( 0 ) ; // GeneralR
WriteUint16( aRestriction&0xffff ); // LanguageR
}
else
{
// Layout restriction
WriteUint16( 15 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*2 );
WriteUint16( (aRestriction&0xffff0000) >> 16 ); // GeneralR
WriteUint16( 0 ); // LanguageR
}
AppendBytes( 1*4 );
WriteInt( 1 ); // ChunksN
}
PrepareNormalClass( aRestriction );
if( aRestriction )
{
AppendBytes( 1*1 );
WriteByte( 0xf5 );
restStartPos.Go( this );
WriteUint( restStartPos.BackwardsDelta() );
restStartPos.Back( this );
}
}
void CSDCBinOutput::PrepareNormalClass( const int aRestriction )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 3 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*1 );
WriteByte( 0 ); // Class
int chunksN = 0;
AppendBytes( 1*4 );
TPos chunksNPos( this );
WriteInt( 0 ); // ChunksN
unsigned int i;
for( i=0; i<iData->iBitmapDefVector.size(); i++ )
{
if( iData->iBitmapDefVector[i]->iRestriction != aRestriction ) continue;
if( (iData->iBitmapDefVector[i]->iAppIconBitmap==false) || iData->IsScalable() )
{
PrepareBitmap( iData->iBitmapDefVector[i] );
chunksN++;
}
}
if( iData->IsScalable() ) for( i=0; i<iData->iAppIconDefVector.size(); i++ )
{
TSDCAppIconDef* entry = iData->iAppIconDefVector[i];
if( entry->iRestriction != aRestriction ) continue;
TSDCImageAttributes attributes;
attributes.iAttributeFlags = ESDCImageAttributeNone;
attributes.iAlignmentFlags = ESDCImageAlignNone;
attributes.iCoordX = 0;
attributes.iCoordY = 0;
attributes.iSizeW = 0;
attributes.iSizeH = 0;
PrepareImageTable( entry->iIID, entry->iIcons, attributes );
chunksN++;
}
for( i=0; i<iData->iFrameDefVector.size(); i++ )
{
TSDCFrameDef* entry = iData->iFrameDefVector[i];
if( entry->iRestriction != aRestriction ) continue;
TSDCImageAttributes attributes;
attributes.iAttributeFlags = ESDCImageAttributeNone;
attributes.iAlignmentFlags = ESDCImageAlignNone;
attributes.iCoordX = 0;
attributes.iCoordY = 0;
attributes.iSizeW = 0;
attributes.iSizeH = 0;
PrepareImageTable( entry->iIID, entry->iElements, attributes );
chunksN++;
}
for( i=0; i<iData->iColorTableDefVector.size(); i++ )
{
if( iData->iColorTableDefVector[i]->iRestriction != aRestriction ) continue;
PrepareColorTable( iData->iColorTableDefVector[i] );
chunksN++;
}
for( i=0; i<iData->iBmpAnimDefVector.size(); i++ )
{
if( iData->iBmpAnimDefVector[i]->iRestriction != aRestriction ) continue;
TSDCImageAttributes attributes;
attributes.iAttributeFlags = ESDCImageAttributeNone;
attributes.iAlignmentFlags = ESDCImageAlignNone;
attributes.iCoordX = 0;
attributes.iCoordY = 0;
attributes.iSizeW = 0;
attributes.iSizeH = 0;
PrepareBmpAnim( iData->iBmpAnimDefVector[i], attributes );
chunksN++;
}
for( i=0; i<iData->iStringDefVector.size(); i++ )
{
if( iData->iStringDefVector[i]->iRestriction != aRestriction ) continue;
PrepareString( iData->iStringDefVector[i] );
chunksN++;
}
if( iData->IsScalable() ) for( i=0; i<iData->iScalableItemDefVector.size(); i++ )
{
if( iData->iScalableItemDefVector[i]->iRestriction != aRestriction ) continue;
PrepareScalableItem( iData->iScalableItemDefVector[i] );
chunksN++;
}
if( iData->IsScalable() ) for( i=0; i<iData->iAnimationDefVector.size(); i++ )
{
if( iData->iAnimationDefVector[i]->iRestriction != aRestriction ) continue;
PrepareAnimation( iData->iAnimationDefVector[i] );
chunksN++;
}
chunksNPos.Go( this );
WriteInt( chunksN );
chunksNPos.Back( this );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareAppIconClass()
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 3 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*1 );
WriteByte( 1 ); // Class
int chunksN = 0;
AppendBytes( 1*4 );
TPos chunksNPos( this );
WriteInt( 0 ); // ChunksN
unsigned int i;
for( i=0; i<iData->iBitmapDefVector.size(); i++ )
{
if( iData->iBitmapDefVector[i]->iAppIconBitmap == true )
{
if( iData->iBitmapDefVector[i]->iRestriction )
throw CSDCException( ESDCContentError, "Application icon bitmap contains restrictions" );
PrepareBitmap( iData->iBitmapDefVector[i] );
chunksN++;
}
}
for( i=0; i<iData->iAppIconDefVector.size(); i++ )
{
TSDCAppIconDef* entry = iData->iAppIconDefVector[i];
if( entry->iRestriction )
throw CSDCException( ESDCContentError, "Application icon contains restrictions" );
TSDCImageAttributes attributes;
attributes.iAttributeFlags = ESDCImageAttributeNone;
attributes.iAlignmentFlags = ESDCImageAlignNone;
attributes.iCoordX = 0;
attributes.iCoordY = 0;
attributes.iSizeW = 0;
attributes.iSizeH = 0;
PrepareImageTable( entry->iIID, entry->iIcons, attributes );
chunksN++;
}
chunksNPos.Go( this );
WriteInt( chunksN );
chunksNPos.Back( this );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareBitmap( const TSDCBitmapDef* aBitmapDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 4 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 5*4 );
WriteInt( aBitmapDef->iIID.iMajor );
WriteInt( aBitmapDef->iIID.iMinor );
if( aBitmapDef->iMBMIndex>=16384 )
{
WriteInt( 1 ); // FilenameID
}
else
{
WriteInt( 0 ); // FilenameID
}
WriteInt( aBitmapDef->iMBMIndex );
WriteInt( aBitmapDef->iMaskMBMIndex );
PrepareAttributes( aBitmapDef->iAttributes );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareColorTable( const TSDCColorTableDef* aColorTableDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 5 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 + 1*1 );
WriteInt( aColorTableDef->iIID.iMajor );
WriteInt( aColorTableDef->iIID.iMinor );
WriteByte( aColorTableDef->iColors.size() );
for( unsigned int i=0; i<aColorTableDef->iColors.size(); i++ )
{
AppendBytes( 1*2 + 1*4 );
WriteInt16( (short int)aColorTableDef->iColors[i].iIndex );
WriteUint( aColorTableDef->iColors[i].iRgb );
}
TSDCImageAttributes attributes;
attributes.iAttributeFlags = ESDCImageAttributeNone;
if( iData->IsScalable() ) {
attributes.iAttributeFlags |= ESDCImageAttributeNBC;
}
attributes.iAlignmentFlags = ESDCImageAlignNone;
attributes.iCoordX = 0;
attributes.iCoordY = 0;
attributes.iSizeW = 0;
attributes.iSizeH = 0;
PrepareAttributes( attributes );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareBmpAnim( const TSDCBmpAnimDef* aBmpAnimDef, const TSDCImageAttributes& aAttributes )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 8 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 + 1*2 + 3*1 );
WriteInt( aBmpAnimDef->iIID.iMajor );
WriteInt( aBmpAnimDef->iIID.iMinor );
WriteInt16( (short int)aBmpAnimDef->iInterval );
WriteByte( (unsigned char)aBmpAnimDef->iPlayMode );
WriteByte( (unsigned char)aBmpAnimDef->iFlash );
WriteByte( (unsigned char)aBmpAnimDef->iFrames.size() );
for( unsigned int i=0; i<aBmpAnimDef->iFrames.size(); i++ )
{
AppendBytes( 2*4 + 3*2 );
WriteInt( aBmpAnimDef->iFrames[i].iIID.iMajor );
WriteInt( aBmpAnimDef->iFrames[i].iIID.iMinor );
WriteInt16( (short int)aBmpAnimDef->iFrames[i].iTime );
WriteInt16( (short int)aBmpAnimDef->iFrames[i].iPosX );
WriteInt16( (short int)aBmpAnimDef->iFrames[i].iPosY );
}
PrepareAttributes( aAttributes );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareString( const TSDCStringDef* aStringDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 12 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 + 1*2 );
WriteInt( aStringDef->iIID.iMajor );
WriteInt( aStringDef->iIID.iMinor );
WriteUint16( wcslen( aStringDef->iString ) );
for( unsigned int i=0; i<wcslen( aStringDef->iString ); i++ )
{
AppendBytes( 2 );
WriteUint16( aStringDef->iString[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareScalableItem( const TSDCScalableItemDef* aItemDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 16 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 );
WriteInt( aItemDef->iIID.iMajor );
WriteInt( aItemDef->iIID.iMinor );
AppendBytes( 2*4 );
WriteInt( aItemDef->iRefIID.iMajor );
WriteInt( aItemDef->iRefIID.iMinor );
AppendBytes( 2*1 );
WriteByte( (aItemDef->iInput&0xff00) >> 8 );
WriteByte( aItemDef->iInput&0xff );
AppendBytes( 2*1 );
WriteByte( (aItemDef->iOutput&0xff00) >> 8 );
WriteByte( aItemDef->iOutput&0xff );
AppendBytes( 1*4 );
WriteUint( 0 ); // Reserved
AppendBytes( 1*2 );
WriteUint16( aItemDef->iCommands.size() );
for( unsigned int i=0; i<aItemDef->iCommands.size(); i++ )
{
PrepareEffectCommand( aItemDef->iCommands[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareAnimation( const TSDCAnimationDef* aItemDef )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 19 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 );
WriteInt( aItemDef->iIID.iMajor );
WriteInt( aItemDef->iIID.iMinor );
AppendBytes( 2*4 );
if( aItemDef->iMorphing )
{
WriteByte( 1 );
}
else
{
WriteByte( 0 );
}
WriteByte( 0 ); // Reserved
WriteUint16( 0 ); // Reserved
WriteInt( 0 ); // Reserved
AppendBytes( 2*1 );
WriteByte( (aItemDef->iInput&0xff00) >> 8 );
WriteByte( aItemDef->iInput&0xff );
AppendBytes( 2*1 );
WriteByte( (aItemDef->iOutput&0xff00) >> 8 );
WriteByte( aItemDef->iOutput&0xff );
AppendBytes( 1*4 );
WriteUint( aItemDef->iMinInterval );
AppendBytes( 1*2 );
WriteUint16( aItemDef->iPreprocessCommands.size() );
unsigned int i;
for( i=0; i<aItemDef->iPreprocessCommands.size(); i++ )
{
PrepareEffectCommand( aItemDef->iPreprocessCommands[i] );
}
AppendBytes( 1*2 );
WriteUint16( aItemDef->iAnimCommands.size() );
for( i=0; i<aItemDef->iAnimCommands.size(); i++ )
{
PrepareEffectCommand( aItemDef->iAnimCommands[i] );
}
AppendBytes( 1*2 );
WriteUint16( aItemDef->iValues.size() );
for( i=0; i<aItemDef->iValues.size(); i++ )
{
PrepareAnimParamGroup( aItemDef->iValues[i] );
}
AppendBytes( 1*2 );
WriteUint16( aItemDef->iTimingModels.size() );
for( i=0; i<aItemDef->iTimingModels.size(); i++ )
{
PrepareAnimParamGroup( aItemDef->iTimingModels[i] );
}
AppendBytes( 1*2 );
WriteUint16( aItemDef->iSizeBoundParams.size() );
for( i=0; i<aItemDef->iSizeBoundParams.size(); i++ )
{
PrepareAnimParamGroup( aItemDef->iSizeBoundParams[i] );
}
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareImageTable( const TSDCIID& aIID, const vector<TSDCIID> aImages, const TSDCImageAttributes& aAttributes )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 6 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 2*4 + 1*1 );
WriteInt( aIID.iMajor );
WriteInt( aIID.iMinor );
WriteByte( (unsigned char)aImages.size() );
for( unsigned int i=0; i<aImages.size(); i++ )
{
AppendBytes( 2*4 );
WriteInt( aImages[i].iMajor );
WriteInt( aImages[i].iMinor );
}
PrepareAttributes( aAttributes );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareAttributes( const TSDCImageAttributes& aAttributes )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 7 ); // Type
WriteUint16( 2 ); // Version
AppendBytes( 2*1 + 4*2 );
WriteByte( (unsigned char)(aAttributes.iAttributeFlags&0xff) );
WriteByte( (unsigned char)(aAttributes.iAlignmentFlags&0xff) );
WriteInt16( (short int)aAttributes.iCoordX );
WriteInt16( (short int)aAttributes.iCoordY );
WriteInt16( (short int)aAttributes.iSizeW );
WriteInt16( (short int)aAttributes.iSizeH );
AppendBytes( 1*2 + 1*4 );
WriteUint16( (unsigned short)((aAttributes.iAttributeFlags&0xffff00)>>8) );
WriteUint( 0 ); // Reserved
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareParamVector( const vector<TSDCEffectParameter>& aParameters )
{
for( unsigned int i=0; i<aParameters.size(); i++ )
{
int type = aParameters[i].iType;
TPos paramPos( this );
AppendBytes( 1*2 + 1*1 );
WriteUint16( 0 ); // ParamLength
WriteByte( 0 ); // Reserved
if( type == 0 || type == 3 )
{
AppendBytes( 1*1 );
WriteByte( type ); // ParamType
}
else if( type == 1 || type == 4 ) // String or raw data
{
AppendBytes( 1*1 );
WriteByte( 1 ); // ParamType
}
else if( type == 2 )
{
AppendBytes( 1*1 );
WriteByte( 2 ); // ParamType
}
else
{
throw CSDCException( ESDCContentError, "Unknown parameter type in scalable item effect" );
}
AppendBytes( 1*2 );
WriteUint16( wcslen(aParameters[i].iName) ); // ParamNameLen
for( unsigned int b=0; b<wcslen(aParameters[i].iName); b++ )
{
AppendBytes( 1*2 );
WriteUint16( aParameters[i].iName[b] );
}
if( type == 0 || type == 3 ) // Number or named reference
{
AppendBytes( 1*4 );
WriteInt( aParameters[i].iNumber );
}
else if( type == 1 ) // String
{
AppendBytes( 1*2 );
WriteUint16( wcslen(aParameters[i].iString) );
for( unsigned int a=0; a<wcslen(aParameters[i].iString); a++ )
{
AppendBytes( 1*2 );
WriteUint16( aParameters[i].iString[a] );
}
}
else if( type == 2 ) // Graphics
{
AppendBytes( 3*4 );
WriteInt( aParameters[i].iBmpIndex );
WriteInt( aParameters[i].iMaskIndex );
if( aParameters[i].iBmpIndex>=16384 )
{
WriteInt( 1 ); // FilenameID
}
else
{
WriteInt( 0 ); // FilenameID
}
}
else if( type == 4 ) // Raw data
{
AppendBytes( 1*2 );
WriteUint16( aParameters[i].iRawDataCount );
for( int a=0; a<aParameters[i].iRawDataCount; a++ )
{
AppendBytes( 1*2 );
WriteUint16( aParameters[i].iString[a] );
}
}
paramPos.Go( this );
WriteUint16( paramPos.BackwardsDelta() );
paramPos.Back( this );
}
}
void CSDCBinOutput::PrepareEffectCommand( const TSDCEffectCommand& aCommand )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 17 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*4 );
WriteInt( aCommand.iUid );
AppendBytes( 6*1 );
WriteByte( (aCommand.iInputA&0xff00) >> 8 );
WriteByte( aCommand.iInputA&0xff );
WriteByte( (aCommand.iInputB&0xff00) >> 8 );
WriteByte( aCommand.iInputB&0xff );
WriteByte( (aCommand.iOutput&0xff00) >> 8 );
WriteByte( aCommand.iOutput&0xff );
AppendBytes( 1*2 );
WriteUint16( aCommand.iParameters.size() );
PrepareParamVector( aCommand.iParameters );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::PrepareAnimParamGroup( const TSDCAnimParamGroup& aParamGroup )
{
TPos startPos( this );
AppendBytes( 1*4 + 2*2 );
WriteUint( 0 ); // Length
WriteUint16( 20 ); // Type
WriteUint16( 1 ); // Version
AppendBytes( 1*4 );
WriteUint( aParamGroup.iValueA );
AppendBytes( 1*4 );
WriteUint( aParamGroup.iValueB );
AppendBytes( 1*2 );
WriteUint16( aParamGroup.iParameters.size() );
PrepareParamVector( aParamGroup.iParameters );
AppendBytes( 1*1 );
WriteByte( 0xf5 );
startPos.Go( this );
WriteUint( startPos.BackwardsDelta() );
startPos.Back( this );
}
void CSDCBinOutput::AppendBytes( const int aNumberOfBytes )
{
for( int i=0; i<aNumberOfBytes; i++ )
iOutputVector.push_back(0);
}
void CSDCBinOutput::WriteByte( const unsigned char aByte )
{
iOutputVector.at(iOutputPos++) = aByte;
}
void CSDCBinOutput::WriteInt( const int aInt )
{
WriteUint( (unsigned int)aInt );
}
void CSDCBinOutput::WriteUint( const unsigned int aUint )
{
unsigned char* p = (unsigned char*)(&aUint);
iOutputVector.at(iOutputPos++) = p[0];
iOutputVector.at(iOutputPos++) = p[1];
iOutputVector.at(iOutputPos++) = p[2];
iOutputVector.at(iOutputPos++) = p[3];
}
void CSDCBinOutput::WriteInt16( const short int aInt )
{
WriteUint16( (unsigned short int)aInt );
}
void CSDCBinOutput::WriteUint16( const short unsigned int aUint )
{
unsigned char* p = (unsigned char*)(&aUint);
iOutputVector.at(iOutputPos++) = p[0];
iOutputVector.at(iOutputPos++) = p[1];
}
// End of file