DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

SWF_Sprites.cpp (7703B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 #pragma hdrstop
     29 #include "../idlib/precompiled.h"
     30 
     31 /*
     32 ========================
     33 idSWFSprite::idSWFSprite
     34 ========================
     35 */
     36 idSWFSprite::idSWFSprite( idSWF * _swf ) :
     37 frameCount( 0 ),
     38 swf( _swf ),
     39 commandBuffer( NULL )
     40 {
     41 }
     42 
     43 /*
     44 ========================
     45 idSWFSprite::~idSWFSprite
     46 ========================
     47 */
     48 idSWFSprite::~idSWFSprite() {
     49 	Mem_Free( commandBuffer );
     50 }
     51 
     52 /*
     53 ========================
     54 idSWF::DefineSprite
     55 ========================
     56 */
     57 void idSWF::DefineSprite( idSWFBitStream & bitstream ) {
     58 	uint16 characterID = bitstream.ReadU16();
     59 	idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_SPRITE );
     60 	if ( entry == NULL ) {
     61 		return;
     62 	}
     63 	entry->sprite->Load( bitstream, false );
     64 }
     65 
     66 /*
     67 ========================
     68 idSWFSprite::Load
     69 ========================
     70 */
     71 void idSWFSprite::Load( idSWFBitStream & bitstream, bool parseDictionary ) {
     72 
     73 	frameCount = bitstream.ReadU16();
     74 
     75 	// run through the file once, building the dictionary and accumulating control tags
     76 	frameOffsets.SetNum( frameCount + 1 );
     77 	frameOffsets[0] = 0;
     78 
     79 	unsigned int currentFrame = 1;
     80 
     81 	while ( true ) {
     82 		uint16 codeAndLength = bitstream.ReadU16();
     83 		uint32 recordLength = ( codeAndLength & 0x3F );
     84 		if ( recordLength == 0x3F ) {
     85 			recordLength = bitstream.ReadU32();
     86 		}
     87 
     88 		idSWFBitStream tagStream( bitstream.ReadData( recordLength ), recordLength, false );
     89 
     90 		swfTag_t tag = (swfTag_t)( codeAndLength >> 6 );
     91 
     92 		// ----------------------
     93 		// Definition tags
     94 		// definition tags are only allowed in the main sprite
     95 		// ----------------------
     96 		if ( parseDictionary ) {
     97 			bool handled = true;
     98 			switch ( tag ) {
     99 #define HANDLE_SWF_TAG( x ) case Tag_##x: swf->x( tagStream ); break;
    100 			HANDLE_SWF_TAG( JPEGTables );
    101 			HANDLE_SWF_TAG( DefineBits );
    102 			HANDLE_SWF_TAG( DefineBitsJPEG2 );
    103 			HANDLE_SWF_TAG( DefineBitsJPEG3 );
    104 			HANDLE_SWF_TAG( DefineBitsLossless );
    105 			HANDLE_SWF_TAG( DefineBitsLossless2 );
    106 			HANDLE_SWF_TAG( DefineShape );
    107 			HANDLE_SWF_TAG( DefineShape2 );
    108 			HANDLE_SWF_TAG( DefineShape3 );
    109 			HANDLE_SWF_TAG( DefineShape4 );
    110 			HANDLE_SWF_TAG( DefineSprite );
    111 			HANDLE_SWF_TAG( DefineSound );
    112 			//HANDLE_SWF_TAG( DefineMorphShape ); // these don't work right
    113 			HANDLE_SWF_TAG( DefineFont2 );
    114 			HANDLE_SWF_TAG( DefineFont3 );
    115 			HANDLE_SWF_TAG( DefineText );
    116 			HANDLE_SWF_TAG( DefineText2 );
    117 			HANDLE_SWF_TAG( DefineEditText );
    118 #undef HANDLE_SWF_TAG
    119 			default: handled = false;
    120 			}
    121 			if ( handled ) {
    122 				continue;
    123 			}
    124 		}
    125 		// ----------------------
    126 		// Control tags
    127 		// control tags are stored off in the commands list and processed at run time
    128 		// except for a couple really special control tags like "End" and "FrameLabel"
    129 		// ----------------------
    130 		switch ( tag ) {
    131 		case Tag_End:
    132 			return;
    133 
    134 		case Tag_ShowFrame:
    135 			frameOffsets[ currentFrame ] = commands.Num();
    136 			currentFrame++;
    137 			break;
    138 
    139 		case Tag_FrameLabel: {
    140 				swfFrameLabel_t & label = frameLabels.Alloc();
    141 				label.frameNum = currentFrame;
    142 				label.frameLabel = tagStream.ReadString();
    143 			}
    144 			break;
    145 
    146 		case Tag_DoInitAction: {
    147 			tagStream.ReadU16();
    148 
    149 			idSWFBitStream &initaction = doInitActions.Alloc();
    150 			initaction.Load( tagStream.ReadData( recordLength - 2 ), recordLength - 2, true );
    151  		    }
    152 			break;
    153 
    154 		case Tag_DoAction:
    155 		case Tag_PlaceObject2:
    156 		case Tag_PlaceObject3:
    157 		case Tag_RemoveObject2: {
    158 				swfSpriteCommand_t & command = commands.Alloc();
    159 				command.tag = tag;
    160 				command.stream.Load( tagStream.ReadData( recordLength ), recordLength, true );
    161 			}
    162 			break;
    163 
    164 		default:
    165 			// We don't care, about sprite tags we don't support ... RobA
    166 			//idLib::Printf( "Load Sprite: Unhandled tag %s\n", idSWF::GetTagName( tag ) );
    167 			break;
    168 		}
    169 	}
    170 }
    171 
    172 /*
    173 ========================
    174 idSWFSprite::Read
    175 ========================
    176 */
    177 void idSWFSprite::Read( idFile * f ) {
    178 	int num = 0;
    179 	f->ReadBig( frameCount );
    180 	f->ReadBig( num ); frameOffsets.SetNum( num );
    181 	f->ReadBigArray( frameOffsets.Ptr(), frameOffsets.Num() );
    182 	f->ReadBig( num ); frameLabels.SetNum( num );
    183 	for ( int i = 0; i < frameLabels.Num(); i++ ) {
    184 		f->ReadBig( frameLabels[i].frameNum );
    185 		f->ReadString( frameLabels[i].frameLabel );
    186 	}
    187 
    188 	uint32 bufferSize;
    189 	f->ReadBig( bufferSize );
    190 
    191 	commandBuffer = (byte *)Mem_Alloc( bufferSize, TAG_SWF );
    192 	f->Read( commandBuffer, bufferSize );
    193 
    194 	byte * currentBuffer = commandBuffer;
    195 
    196 	f->ReadBig( num ); commands.SetNum( num );
    197 	for ( int i = 0; i < commands.Num(); i++ ) {
    198 		uint32 streamLength = 0;
    199 
    200 		f->ReadBig( commands[i].tag );
    201 		f->ReadBig( streamLength );
    202 
    203 		commands[i].stream.Load( currentBuffer, streamLength, false );
    204 		currentBuffer += streamLength;
    205 	}
    206 
    207 	uint32 doInitActionLength = 0;
    208 	f->ReadBig( num );
    209 	doInitActions.SetNum( num );
    210 	for ( int i = 0; i < num; i++ ) {
    211 		f->ReadBig( doInitActionLength );
    212 		idSWFBitStream &initaction = doInitActions[i];
    213 		initaction.Load( currentBuffer, doInitActionLength, true );
    214 		currentBuffer += doInitActionLength;
    215 	}
    216 }
    217 
    218 /*
    219 ========================
    220 idSWFSprite::Write
    221 ========================
    222 */
    223 void idSWFSprite::Write( idFile * f ) {
    224 	f->WriteBig( frameCount );
    225 	f->WriteBig( frameOffsets.Num() );
    226 	f->WriteBigArray( frameOffsets.Ptr(), frameOffsets.Num() );
    227 	f->WriteBig( frameLabels.Num() );
    228 	for ( int i = 0; i < frameLabels.Num(); i++ ) {
    229 		f->WriteBig( frameLabels[i].frameNum );
    230 		f->WriteString( frameLabels[i].frameLabel );
    231 	}
    232 	uint32 totalLength = 0;
    233 	for ( int i = 0; i < commands.Num(); i++ ) {
    234 		totalLength += commands[i].stream.Length();
    235 	}
    236 	for (int i = 0; i < doInitActions.Num(); i++ ) {
    237 		totalLength += doInitActions[i].Length();
    238 	}
    239 	f->WriteBig( totalLength );
    240 	for ( int i = 0; i < commands.Num(); i++ ) {
    241 		f->Write( commands[i].stream.Ptr(), commands[i].stream.Length() );
    242 	}
    243 	for ( int i = 0; i < doInitActions.Num(); i++ ){
    244 		f->Write( doInitActions[i].Ptr(), doInitActions[i].Length() );
    245 	}
    246 
    247 	f->WriteBig( commands.Num() ); 
    248 	for ( int i = 0; i < commands.Num(); i++ ) {
    249 		f->WriteBig( commands[i].tag );
    250 		f->WriteBig( commands[i].stream.Length() );
    251 	}
    252 
    253 	f->WriteBig( doInitActions.Num() );
    254 	for ( int i = 0; i < doInitActions.Num(); i++ ){
    255 		f->WriteBig( doInitActions[i].Length() ); 
    256 	}
    257 }